https://learnopengl-cn.readthedocs.io/zh/latest/01%20Getting%20started/04%20Hello%20Triangle/
#include
#define GLEW_STATIC
#include
#include
using namespace std;
//着色器源码
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\0";
const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
GLuint VBO; //顶点缓冲对象 vertex buffer object
GLuint VAO; //顶点数组对象 vertex array object
GLuint EBO; //索引缓冲对象 element buffer object
GLuint shaderProgram;
GLfloat vertexes[] = {
0.5f, 0.5f, 0.0f, // Top Right
0.5f, -0.5f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, // Bottom Left
-0.5f, 0.5f, 0.0f // Top Left
};
GLuint indexes[] = {
0,1,3,
1,2,3,
};
void key_exit(GLFWwindow* window, int key, int scancode, int action, int mode) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
glfwSetWindowShouldClose(window, GL_TRUE);
}
void initWindow(GLFWwindow* window) {
if (window == nullptr) {
cout << "failed to create window" << endl;
glfwTerminate();
}
glfwMakeContextCurrent(window);
int w, h;
glfwGetFramebufferSize(window, &w, &h); //不直接使用800,600,是为了使之能在高DPI屏幕运行
glViewport(0, 0, w, h);
}
void initGLFW() {
glfwInit(); //初始化窗口
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //设置主版本号为3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); //设置次版本号为3
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //启用核心模式
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); //禁止调整窗口大小
}
void initGLEW() {
glewExperimental = GL_TRUE; //开启现代OpenGL功能
if (glewInit() != GLEW_OK)
cout << "failed to initialize glew!" << endl;
}
void initShader() {
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); //创建顶点着色器
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); //加载顶点着色器代码
glCompileShader(vertexShader); //编译顶点着色器代码
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); //创建片段着色器
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); //加载片段着色器代码
glCompileShader(fragmentShader); //编译片段着色器代码
shaderProgram = glCreateProgram(); //创建着色器程序
glAttachShader(shaderProgram, vertexShader); //添加着色器
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram); //链接程序
glDeleteShader(vertexShader); //销毁着色器
glDeleteShader(fragmentShader);
}
void initData() {
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO); //给VBO分配一个单位的缓冲对象,VBO会被赋值一个对象id,每调用一次glGenBuffer,这个id会加1
glGenBuffers(1, &EBO);
glBindVertexArray(VAO); //绑定VAO,之后所有的顶点属性调用都会存储到VAO中
glBindBuffer(GL_ARRAY_BUFFER, VBO); //指定array buffer的操作对象为VBO
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), vertexes, GL_STATIC_DRAW); //导入顶点数据,gl static draw采用静态的数据处理方式(当数据不会变动时使用)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexes), indexes, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL); //设置顶点解析格式
glEnableVertexAttribArray(0); //以顶点属性位置值作为参数,启用顶点属性
glBindBuffer(GL_ARRAY_BUFFER, 0); // 解绑VBO
glBindVertexArray(0); // 解绑VAO
}
int main(){
initGLFW(); //初始化GLFW
GLFWwindow* window= glfwCreateWindow(800, 600, "hello GL!", nullptr, nullptr);
initWindow(window); //初始化窗口
glfwSetKeyCallback(window, key_exit); //设置键盘回调函数
initGLEW(); //初始化GLEW
initShader(); //初始化着色器
initData(); //初始化顶点数据
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); //设置清屏颜色
while (!glfwWindowShouldClose(window)) { //图像绘制
glfwPollEvents(); //检查并处理事件
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram); //设置着色程序
glBindVertexArray(VAO); //绑定VAO
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); //解析顶点数据
glBindVertexArray(0); //解绑VAO
glfwSwapBuffers(window); //交换缓冲
}
glDeleteVertexArrays(1, &VAO); //销毁对象
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glfwTerminate();
return 0;
}