这篇博客主要是记录在学习LearnOpenGL过程中遇到的函数,以及流程问题,越学到后面越感觉混乱,因此做个记录。由于本博客的特殊性,不会有详细说明,如果想了解更多可以阅读LearnOpenGL或者在博客下方评论,也可以私信博主。
此外为了督促,博主决定一周至少更新一小章,如果本文有幸被各位看到,欢迎各位催更!
glfwInit:初始化GLFW,放在最开始
glfwWindowHint:用于配置GLFW
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); // 用户不可修改窗口大小
MAC系统需要添加下面的语句:
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwCreateWindow:创建窗口对象
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);
if (window == nullptr)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent:设置上下文
glfwMakeContextCurrent(window);
初始化GLEW需要再调用OpenGL函数前
glewInit:初始化GLEW
glewExperimental = GL_TRUE; // 让GLEW用更多现代化技术
if (glewInit() != GLEW_OK)
{
std::cout << "Failed to initialize GLEW" << std::endl;
return -1;
}
glfwGetFramebufferSize:获取窗口的维度保存在第二和三个参数中:
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport:设置窗口的维度
glViewport(0, 0, width, height);
glfwWindowShouldClose :检查一次GLFW是否被要求退出
glfwWindowShouldClose(window)
glfwPollEvents:检查有没有触发什么事件(比如键盘输入、鼠标移动等)
glfwPollEvents();
glfwSwapBuffers:交换颜色缓冲
glfwSwapBuffers(window);
glfwTerminate:清理所有的资源并正确地退出应用程序
glfwTerminate();
glGenBuffers:生成一个VBO对象(VAO,EBO代码同)
GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer:创建的缓冲绑定到各种缓冲上
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData:把之前定义的顶点数据复制到缓冲内存
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GL_STATIC_DRAW :数据不会或几乎不会改变。
GL_DYNAMIC_DRAW:数据会被改变很多。
GL_STREAM_DRAW :数据每次绘制时都会改变。
glCreateShader:创建着色器对象
GLuint vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource:将着色器源码附加到着色器对象上
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader:编译着色器
glCompileShader(vertexShader);
glGetShaderiv:检查是否编译成功
GLint success;
GLchar infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
glGetShaderInfoLog:打印失败信息
if(!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
glCreateProgram:创建着色器程序
GLuint shaderProgram;
shaderProgram = glCreateProgram();
glAttachShader:编译的着色器附加到程序对象
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram:链接着色器程序
glLinkProgram(shaderProgram);
glGetProgramiv、glGetProgramInfoLog:检查编译是否失败并打印失败信息
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if(!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
...
}
glUseProgram:激活程序对象
glUseProgram(shaderProgram);
glDeleteShader:删除着色器对象
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glVertexAttribPointer:告诉OpenGL如何解析顶点数据(应用到逐个顶点属性上)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray:启用顶点属性
glEnableVertexAttribArray(0);
生成代码同VBO
glBindVertexArray:绑定VAO
glBindVertexArray(VAO);
VAO的绑定与使用
// ..:: 初始化代码(只运行一次 (除非你的物体频繁改变)) :: ..
// 1. 绑定VAO
glBindVertexArray(VAO);
// 2. 把顶点数组复制到缓冲中供OpenGL使用
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
//4. 解绑VAO
glBindVertexArray(0);
[...]
// ..:: 绘制代(游戏循环中) :: ..
// 5. 绘制物体
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
someOpenGLFunctionThatDrawsOurTriangle();
glBindVertexArray(0);
glDrawElements:EBO中的渲染
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
EAO的绑定与使用
// ..:: 初始化代码 :: ..
// 1. 绑定顶点数组对象
glBindVertexArray(VAO);
// 2. 把我们的顶点数组复制到一个顶点缓冲中,供OpenGL使用
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. 复制我们的索引数组到一个索引缓冲中,供OpenGL使用,就是多了这里
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// 3. 设定顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
// 4. 解绑VAO(不是EBO!)
glBindVertexArray(0);
[...]
// ..:: 绘制代码(游戏循环中) :: ..
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
glBindVertexArray(0);
glPolygonMode:绘制图元的方式
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
glGetUniformLocation:查询unifrom变量的位置值
GLint vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
glUniform4f:设置uniform的值。
GLfloat timeValue = glfwGetTime();
GLfloat greenValue = (sin(timeValue) / 2) + 0.5;
GLint vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
glUseProgram(shaderProgram);
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
注意:在调用glUniform4f更新之前必须使用程序glUseProgram。