学一下OpenGL吧。
推荐教程:
我就在这记下笔记和代码吧~
1.4 Hello Triangle
// main.cpp
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
using std::cout;
using std::endl;
using std::string;
void frameBufferSizeCallback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow* window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
string readShader(const char* name) {
static const int SIZE = 1024 * 10;
static char data[SIZE];
FILE* fio;
string res;
if (fopen_s(&fio, name, "r")) {
return res;
}
for (int len = fread(data, sizeof(char), SIZE, fio); len; len = fread(data, sizeof(char), SIZE, fio)) {
res.append(data, len);
}
return res;
}
GLuint creatShader(GLenum type, const char* name) {
GLuint shader = glCreateShader(type);
int success;
string src = readShader(name);
const char* str = src.c_str();
glShaderSource(shader, 1, &str, NULL);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
char infoLog[512];
glGetShaderInfoLog(shader, 512, NULL, infoLog);
cout << "Compiling shader from \"" << name << "\" has been FAILED:\n" << infoLog << endl;
}
return shader;
}
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "gl1", NULL, NULL);
if (window == NULL) {
cout << "failed 1" << endl;
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
cout << "failed 2" << endl;
return -1;
}
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, frameBufferSizeCallback);
// === shader ===
GLuint vertexShader = creatShader(GL_VERTEX_SHADER, "basic.vert");
GLuint fragmentShader = creatShader(GL_FRAGMENT_SHADER, "basic.frag");
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glUseProgram(shaderProgram);
// === vertex ===
GLfloat vertices[] = {
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0.5, 0.5, 0.0,
-0.5, 0.5, 0.0
};
GLuint indices[] = {
0, 1, 2,
0, 2, 3
};
GLuint VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(0);
while (!glfwWindowShouldClose(window)) {
processInput(window);
glClearColor(0.5, 0.5, 0.5, 1);
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
// glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
glfwTerminate();
return 0;
}
// basic.vert
#version 330 core
layout (location = 0) in vec3 aPos;
void main() {
gl_Position = vec4(aPos, 1.0);
}
//basic.frag
#version 330 core
out vec4 FragColor;
void main() {
FragColor = vec4(0.5, 0.0, 0.0, 1.0);
}
1.5 Shaders
1.5.1
// main.cpp
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
using std::cout;
using std::endl;
using std::string;
void frameBufferSizeCallback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow* window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
string readShader(const char* name) {
static const int SIZE = 1024 * 10;
static char data[SIZE];
FILE* fio;
string res;
if (fopen_s(&fio, name, "r")) {
return res;
}
for (int len = fread(data, sizeof(char), SIZE, fio); len; len = fread(data, sizeof(char), SIZE, fio)) {
res.append(data, len);
}
return res;
}
GLuint creatShader(GLenum type, const char* name) {
GLuint shader = glCreateShader(type);
int success;
string src = readShader(name);
const char* str = src.c_str();
glShaderSource(shader, 1, &str, NULL);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
char infoLog[512];
glGetShaderInfoLog(shader, 512, NULL, infoLog);
cout << "Compiling shader from \"" << name << "\" has been FAILED:\n" << infoLog << endl;
}
return shader;
}
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "gl1", NULL, NULL);
if (window == NULL) {
cout << "failed 1" << endl;
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
cout << "failed 2" << endl;
return -1;
}
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, frameBufferSizeCallback);
// === shader ===
GLuint vertexShader = creatShader(GL_VERTEX_SHADER, "basic.vert");
GLuint fragmentShader = creatShader(GL_FRAGMENT_SHADER, "basic.frag");
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glUseProgram(shaderProgram);
// === vertex ===
GLfloat vertices[] = {
-0.5, -0.5, 0.0, 1.0, 0.0, 0.0,
0.5, -0.5, 0.0, 0.0, 1.0, 0.0,
0.0, 0.5, 0.0, 0.0, 0.0, 1.0
};
GLuint VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
while (!glfwWindowShouldClose(window)) {
processInput(window);
glClearColor(0.5, 0.5, 0.5, 1);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
glfwTerminate();
return 0;
}
// basic.vert
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aCol;
out vec3 ourColor;
void main() {
gl_Position = vec4(aPos, 1.0);
ourColor = aCol;
}
// basic.frag
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
void main() {
FragColor = vec4(ourColor, 1.0);
}
1.5.2
// Shader.h
#pragma once
#include <glad/glad.h>
#include <cstdlib>
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
class Shader {
public:
Shader(const char* vertexShaderName, const char* fragmentShaderName);
~Shader();
void use();
private:
GLuint shaderProgram;
std::string readShader(const char* name);
GLuint creatShader(GLenum type, const char* name);
};
// Shader.cpp
#include "Shader.h"
Shader::Shader(const char * vertexShaderName, const char * fragmentShaderName) {
GLuint vertexShader = creatShader(GL_VERTEX_SHADER, vertexShaderName);
GLuint fragmentShader = creatShader(GL_FRAGMENT_SHADER, fragmentShaderName);
shaderProgram = glCreateProgram();
GLint success;
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
char infoLog[512];
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "Program linking FAILED:\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
Shader::~Shader() {
}
void Shader::use() {
glUseProgram(shaderProgram);
}
std::string Shader::readShader(const char* name) {
static const int SIZE = 1024 * 10;
static char data[SIZE];
FILE* fio;
std::string res;
if (fopen_s(&fio, name, "r")) {
return res;
}
for (int len = fread(data, sizeof(char), SIZE, fio); len; len = fread(data, sizeof(char), SIZE, fio)) {
res.append(data, len);
}
return res;
}
GLuint Shader::creatShader(GLenum type, const char* name) {
GLuint shader = glCreateShader(type);
GLint success;
std::string src = readShader(name);
const char* str = src.c_str();
glShaderSource(shader, 1, &str, NULL);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
char infoLog[512];
glGetShaderInfoLog(shader, 512, NULL, infoLog);
std::cout << "Compiling shader from \"" << name << "\" has been FAILED:\n" << infoLog << std::endl;
}
return shader;
}