OpenGL笔记七之顶点数据绘制命令和绘制模式

OpenGL笔记七之顶点数据绘制命令和绘制模式

—— 2024-07-07 杭州 下午

总结自bilibili赵新政老师的教程

code review!

文章目录

  • OpenGL笔记七之顶点数据绘制命令和绘制模式
    • 1.OpenGL版本号更改和编译更改
    • 2.GL_TRIANGLES模式绘制一个三角形、支持NFC坐标随窗口缩放
      • 2.1.三个点
      • 2.2.四个点从0号点开始数3个点
      • 2.3.四个点从1号点开始数3个点
      • 2.4.四个点从2号点开始数3个点
      • 2.5.六个点从0号点开始数6个点
      • 2.6.六个点从0号点开始数5个点
    • 3.GL_TRIANGLE_STRIP模式绘制三角形
    • 4.GL_TRIANGLES_FAN模式绘制三角形
    • 5.绘制直线:GL_LINES模式
    • 6.绘制直线:GL_LINES_STRIP模式
    • 7.其他代码文件
      • 7.1.主CMakeLists.txt
      • 7.2.application\CMakeLists.txt
      • 7.3.application\Application.h
      • 7.4.application\Application.cpp
      • 7.5.wrapper\CMakeLists.txt
      • 7.6.wrapper\checkError.h
      • 7.7.wrapper\checkError.cpp

1.OpenGL版本号更改和编译更改

"#version 330 core\n"
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

2.GL_TRIANGLES模式绘制一个三角形、支持NFC坐标随窗口缩放

2.1.三个点

运行
在这里插入图片描述

关键代码

prepareInterleavedBuffer();
// prepareVAOForGLTriangles();
glDrawArrays(GL_TRIANGLES, 0, 3);
// glDrawArrays(GL_LINE_STRIP, 0, 6);

main.cpp

#include <iostream>#define DEBUG//注意:glad头文件必须在glfw引用之前引用
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <string>
#include <assert.h>//断言
#include "wrapper/checkError.h"
#include "application/Application.h"/*
*┌────────────────────────────────────────────────┐
*│ 目	   标: 学习glDrawArrays进行绘制命令
*│ 讲    师: 赵新政(Carma Zhao)
*│ 拆分目标:
*│
*│ 		1  采用GL_TRANGLES进行绘制
*				** 这里大家可以缩放窗体,实验NDC坐标的作用*│ 		2  prepareVAOForGLTriangles:构建四个顶点的vao
*│ 		3  测试Triangle的三种mode:TRIANGLES  TRIANGLE_STRIP TRIANGLE_FAN
*│ 		4  测试Line的二种mode:LINES  LINE_STRIP
*└────────────────────────────────────────────────┘
*/GLuint vao, program;void OnResize(int width, int height) {GL_CALL(glViewport(0, 0, width, height));std::cout << "OnResize" << std::endl;
}void OnKey(int key, int action, int mods) {std::cout << key << std::endl;
}void prepareSingleBuffer() {//1 准备positions colors数据float positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f};float colors[] = {1.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f,0.0f,  0.0f, 1.0f};//2 使用数据生成两个vbo posVbo, colorVboGLuint posVbo, colorVbo;glGenBuffers(1, &posVbo);glGenBuffers(1, &colorVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);//3 生成vao并且绑定GLuint vao = 0;glGenVertexArrays(1, &vao);glBindVertexArray(vao);//4 分别将位置/颜色属性的描述信息加入vao当中//4.1描述位置属性glBindBuffer(GL_ARRAY_BUFFER, posVbo);//只有绑定了posVbo,下面的属性描述才会与此vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//4.2 描述颜色属性glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);
}void prepareInterleavedBuffer() {//1 准备好Interleaved数据(位置+颜色)float vertices[] = {-0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,0.0f,  0.5f, 0.0f,  0.0f,  0.0f, 1.0f};//2 创建唯一的vboGLuint vbo = 0;GL_CALL(glGenBuffers(1, &vbo));GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));//3 创建并绑定vaoGL_CALL(glGenVertexArrays(1, &vao));GL_CALL(glBindVertexArray(vao));GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));//4 为vao加入位置和颜色的描述信息//4.1 位置描述信息GL_CALL(glEnableVertexAttribArray(0));GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0));//4.2 颜色描述信息GL_CALL(glEnableVertexAttribArray(1));GL_CALL(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))));//5 扫尾工作:解绑当前vaoglBindVertexArray(0);
}void prepareVAOForGLTriangles() {//1 准备positionsfloat positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f,0.5f,  0.5f, 0.0f,0.8f,  0.8f, 0.0f,0.8f,  0.0f, 0.0f};//2  posVboGLuint posVbo;glGenBuffers(1, &posVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);//3 生成vao并且绑定glGenVertexArrays(1, &vao);glBindVertexArray(vao);//4 描述位置属性glBindBuffer(GL_ARRAY_BUFFER, posVbo);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);
}void prepareShader() {//1 完成vs与fs的源代码,并且装入字符串const char* vertexShaderSource ="#version 330 core\n""layout (location = 0) in vec3 aPos;\n""void main()\n""{\n""   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n""}\0";const char* fragmentShaderSource ="#version 330 core\n""out vec4 FragColor;\n""void main()\n""{\n""   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n""}\n\0";//2 创建Shader程序(vs、fs)GLuint vertex, fragment;vertex = glCreateShader(GL_VERTEX_SHADER);fragment = glCreateShader(GL_FRAGMENT_SHADER);//3 为shader程序输入shader代码glShaderSource(vertex, 1, &vertexShaderSource, NULL);glShaderSource(fragment, 1, &fragmentShaderSource, NULL);int success = 0;char infoLog[1024];//4 执行shader代码编译 glCompileShader(vertex);//检查vertex编译结果glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertex, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --VERTEX" << "\n" << infoLog << std::endl;}glCompileShader(fragment);//检查fragment编译结果glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(fragment, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --FRAGMENT" << "\n" << infoLog << std::endl;}//5 创建一个Program壳子program = glCreateProgram();//6 将vs与fs编译好的结果放到program这个壳子里glAttachShader(program, vertex);glAttachShader(program, fragment);//7 执行program的链接操作,形成最终可执行shader程序glLinkProgram(program);//检查链接错误glGetProgramiv(program, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(program, 1024, NULL, infoLog);std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl;}//清理glDeleteShader(vertex);glDeleteShader(fragment);
}void render() {//执行opengl画布清理操作GL_CALL(glClear(GL_COLOR_BUFFER_BIT));//1 绑定当前的programglUseProgram(program);//2 绑定当前的vaoglBindVertexArray(vao);//3 发出绘制指令glDrawArrays(GL_TRIANGLES, 0, 3);// glDrawArrays(GL_LINE_STRIP, 0, 6);
}int main() {if (!app->init(800, 600)) {return -1;}app->setResizeCallback(OnResize);app->setKeyBoardCallback(OnKey);//设置opengl视口以及清理颜色GL_CALL(glViewport(0, 0, 800, 600));GL_CALL(glClearColor(0.2f, 0.3f, 0.3f, 1.0f));prepareShader();prepareInterleavedBuffer();// prepareVAOForGLTriangles();while (app->update()) {render();}app->destroy();return 0;
}

2.2.四个点从0号点开始数3个点

运行
在这里插入图片描述

关键代码

// prepareInterleavedBuffer();
prepareVAOForGLTriangles();
float positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f,0.5f,  0.5f, 0.0f,// 0.8f,  0.8f, 0.0f,// 0.8f,  0.0f, 0.0f
};

main.cpp

#include <iostream>#define DEBUG//注意:glad头文件必须在glfw引用之前引用
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <string>
#include <assert.h>//断言
#include "wrapper/checkError.h"
#include "application/Application.h"/*
*┌────────────────────────────────────────────────┐
*│ 目	   标: 学习glDrawArrays进行绘制命令
*│ 讲    师: 赵新政(Carma Zhao)
*│ 拆分目标:
*│
*│ 		1  采用GL_TRANGLES进行绘制
*				** 这里大家可以缩放窗体,实验NDC坐标的作用*│ 		2  prepareVAOForGLTriangles:构建四个顶点的vao
*│ 		3  测试Triangle的三种mode:TRIANGLES  TRIANGLE_STRIP TRIANGLE_FAN
*│ 		4  测试Line的二种mode:LINES  LINE_STRIP
*└────────────────────────────────────────────────┘
*/GLuint vao, program;void OnResize(int width, int height) {GL_CALL(glViewport(0, 0, width, height));std::cout << "OnResize" << std::endl;
}void OnKey(int key, int action, int mods) {std::cout << key << std::endl;
}void prepareSingleBuffer() {//1 准备positions colors数据float positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f};float colors[] = {1.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f,0.0f,  0.0f, 1.0f};//2 使用数据生成两个vbo posVbo, colorVboGLuint posVbo, colorVbo;glGenBuffers(1, &posVbo);glGenBuffers(1, &colorVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);//3 生成vao并且绑定GLuint vao = 0;glGenVertexArrays(1, &vao);glBindVertexArray(vao);//4 分别将位置/颜色属性的描述信息加入vao当中//4.1描述位置属性glBindBuffer(GL_ARRAY_BUFFER, posVbo);//只有绑定了posVbo,下面的属性描述才会与此vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//4.2 描述颜色属性glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);
}void prepareInterleavedBuffer() {//1 准备好Interleaved数据(位置+颜色)float vertices[] = {-0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,0.0f,  0.5f, 0.0f,  0.0f,  0.0f, 1.0f};//2 创建唯一的vboGLuint vbo = 0;GL_CALL(glGenBuffers(1, &vbo));GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));//3 创建并绑定vaoGL_CALL(glGenVertexArrays(1, &vao));GL_CALL(glBindVertexArray(vao));GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));//4 为vao加入位置和颜色的描述信息//4.1 位置描述信息GL_CALL(glEnableVertexAttribArray(0));GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0));//4.2 颜色描述信息GL_CALL(glEnableVertexAttribArray(1));GL_CALL(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))));//5 扫尾工作:解绑当前vaoglBindVertexArray(0);
}void prepareVAOForGLTriangles() {//1 准备positionsfloat positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f,0.5f,  0.5f, 0.0f,// 0.8f,  0.8f, 0.0f,// 0.8f,  0.0f, 0.0f};//2  posVboGLuint posVbo;glGenBuffers(1, &posVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);//3 生成vao并且绑定glGenVertexArrays(1, &vao);glBindVertexArray(vao);//4 描述位置属性glBindBuffer(GL_ARRAY_BUFFER, posVbo);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);
}void prepareShader() {//1 完成vs与fs的源代码,并且装入字符串const char* vertexShaderSource ="#version 330 core\n""layout (location = 0) in vec3 aPos;\n""void main()\n""{\n""   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n""}\0";const char* fragmentShaderSource ="#version 330 core\n""out vec4 FragColor;\n""void main()\n""{\n""   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n""}\n\0";//2 创建Shader程序(vs、fs)GLuint vertex, fragment;vertex = glCreateShader(GL_VERTEX_SHADER);fragment = glCreateShader(GL_FRAGMENT_SHADER);//3 为shader程序输入shader代码glShaderSource(vertex, 1, &vertexShaderSource, NULL);glShaderSource(fragment, 1, &fragmentShaderSource, NULL);int success = 0;char infoLog[1024];//4 执行shader代码编译 glCompileShader(vertex);//检查vertex编译结果glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertex, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --VERTEX" << "\n" << infoLog << std::endl;}glCompileShader(fragment);//检查fragment编译结果glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(fragment, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --FRAGMENT" << "\n" << infoLog << std::endl;}//5 创建一个Program壳子program = glCreateProgram();//6 将vs与fs编译好的结果放到program这个壳子里glAttachShader(program, vertex);glAttachShader(program, fragment);//7 执行program的链接操作,形成最终可执行shader程序glLinkProgram(program);//检查链接错误glGetProgramiv(program, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(program, 1024, NULL, infoLog);std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl;}//清理glDeleteShader(vertex);glDeleteShader(fragment);
}void render() {//执行opengl画布清理操作GL_CALL(glClear(GL_COLOR_BUFFER_BIT));//1 绑定当前的programglUseProgram(program);//2 绑定当前的vaoglBindVertexArray(vao);//3 发出绘制指令glDrawArrays(GL_TRIANGLES, 0, 3);// glDrawArrays(GL_LINE_STRIP, 0, 6);
}int main() {if (!app->init(800, 600)) {return -1;}app->setResizeCallback(OnResize);app->setKeyBoardCallback(OnKey);//设置opengl视口以及清理颜色GL_CALL(glViewport(0, 0, 800, 600));GL_CALL(glClearColor(0.2f, 0.3f, 0.3f, 1.0f));prepareShader();// prepareInterleavedBuffer();prepareVAOForGLTriangles();while (app->update()) {render();}app->destroy();return 0;
}

2.3.四个点从1号点开始数3个点

运行
在这里插入图片描述

关键代码

glDrawArrays(GL_TRIANGLES, 1, 3);

2.4.四个点从2号点开始数3个点

运行
在这里插入图片描述

关键代码

glDrawArrays(GL_TRIANGLES, 2, 3);

2.5.六个点从0号点开始数6个点

运行
在这里插入图片描述

关键代码

glDrawArrays(GL_TRIANGLES, 0, 6);
float positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f,0.5f,  0.5f, 0.0f,0.8f,  0.8f, 0.0f,0.8f,  0.0f, 0.0f
};

2.6.六个点从0号点开始数5个点

运行
在这里插入图片描述

关键代码

glDrawArrays(GL_TRIANGLES, 0, 5);

3.GL_TRIANGLE_STRIP模式绘制三角形

运行
在这里插入图片描述

关键代码

glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);

main.cpp

#include <iostream>#define DEBUG//注意:glad头文件必须在glfw引用之前引用
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <string>
#include <assert.h>//断言
#include "wrapper/checkError.h"
#include "application/Application.h"/*
*┌────────────────────────────────────────────────┐
*│ 目	   标: 学习glDrawArrays进行绘制命令
*│ 讲    师: 赵新政(Carma Zhao)
*│ 拆分目标:
*│
*│ 		1  采用GL_TRANGLES进行绘制
*				** 这里大家可以缩放窗体,实验NDC坐标的作用*│ 		2  prepareVAOForGLTriangles:构建四个顶点的vao
*│ 		3  测试Triangle的三种mode:TRIANGLES  TRIANGLE_STRIP TRIANGLE_FAN
*│ 		4  测试Line的二种mode:LINES  LINE_STRIP
*└────────────────────────────────────────────────┘
*/GLuint vao, program;void OnResize(int width, int height) {GL_CALL(glViewport(0, 0, width, height));std::cout << "OnResize" << std::endl;
}void OnKey(int key, int action, int mods) {std::cout << key << std::endl;
}void prepareSingleBuffer() {//1 准备positions colors数据float positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f};float colors[] = {1.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f,0.0f,  0.0f, 1.0f};//2 使用数据生成两个vbo posVbo, colorVboGLuint posVbo, colorVbo;glGenBuffers(1, &posVbo);glGenBuffers(1, &colorVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);//3 生成vao并且绑定GLuint vao = 0;glGenVertexArrays(1, &vao);glBindVertexArray(vao);//4 分别将位置/颜色属性的描述信息加入vao当中//4.1描述位置属性glBindBuffer(GL_ARRAY_BUFFER, posVbo);//只有绑定了posVbo,下面的属性描述才会与此vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//4.2 描述颜色属性glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);
}void prepareInterleavedBuffer() {//1 准备好Interleaved数据(位置+颜色)float vertices[] = {-0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,0.0f,  0.5f, 0.0f,  0.0f,  0.0f, 1.0f};//2 创建唯一的vboGLuint vbo = 0;GL_CALL(glGenBuffers(1, &vbo));GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));//3 创建并绑定vaoGL_CALL(glGenVertexArrays(1, &vao));GL_CALL(glBindVertexArray(vao));GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));//4 为vao加入位置和颜色的描述信息//4.1 位置描述信息GL_CALL(glEnableVertexAttribArray(0));GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0));//4.2 颜色描述信息GL_CALL(glEnableVertexAttribArray(1));GL_CALL(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))));//5 扫尾工作:解绑当前vaoglBindVertexArray(0);
}void prepareVAOForGLTriangles() {//1 准备positionsfloat positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f,0.5f,  0.5f, 0.0f,0.8f,  0.8f, 0.0f,0.8f,  0.0f, 0.0f};//2  posVboGLuint posVbo;glGenBuffers(1, &posVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);//3 生成vao并且绑定glGenVertexArrays(1, &vao);glBindVertexArray(vao);//4 描述位置属性glBindBuffer(GL_ARRAY_BUFFER, posVbo);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);
}void prepareShader() {//1 完成vs与fs的源代码,并且装入字符串const char* vertexShaderSource ="#version 330 core\n""layout (location = 0) in vec3 aPos;\n""void main()\n""{\n""   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n""}\0";const char* fragmentShaderSource ="#version 330 core\n""out vec4 FragColor;\n""void main()\n""{\n""   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n""}\n\0";//2 创建Shader程序(vs、fs)GLuint vertex, fragment;vertex = glCreateShader(GL_VERTEX_SHADER);fragment = glCreateShader(GL_FRAGMENT_SHADER);//3 为shader程序输入shader代码glShaderSource(vertex, 1, &vertexShaderSource, NULL);glShaderSource(fragment, 1, &fragmentShaderSource, NULL);int success = 0;char infoLog[1024];//4 执行shader代码编译 glCompileShader(vertex);//检查vertex编译结果glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertex, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --VERTEX" << "\n" << infoLog << std::endl;}glCompileShader(fragment);//检查fragment编译结果glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(fragment, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --FRAGMENT" << "\n" << infoLog << std::endl;}//5 创建一个Program壳子program = glCreateProgram();//6 将vs与fs编译好的结果放到program这个壳子里glAttachShader(program, vertex);glAttachShader(program, fragment);//7 执行program的链接操作,形成最终可执行shader程序glLinkProgram(program);//检查链接错误glGetProgramiv(program, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(program, 1024, NULL, infoLog);std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl;}//清理glDeleteShader(vertex);glDeleteShader(fragment);
}void render() {//执行opengl画布清理操作GL_CALL(glClear(GL_COLOR_BUFFER_BIT));//1 绑定当前的programglUseProgram(program);//2 绑定当前的vaoglBindVertexArray(vao);//3 发出绘制指令glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);// glDrawArrays(GL_TRIANGLES, 0, 6);// glDrawArrays(GL_LINE_STRIP, 0, 6);
}int main() {if (!app->init(800, 600)) {return -1;}app->setResizeCallback(OnResize);app->setKeyBoardCallback(OnKey);//设置opengl视口以及清理颜色GL_CALL(glViewport(0, 0, 800, 600));GL_CALL(glClearColor(0.2f, 0.3f, 0.3f, 1.0f));prepareShader();// prepareInterleavedBuffer();prepareVAOForGLTriangles();while (app->update()) {render();}app->destroy();return 0;
}

4.GL_TRIANGLES_FAN模式绘制三角形

运行
在这里插入图片描述

关键代码

glDrawArrays(GL_TRIANGLE_FAN, 0, 6);

main.cpp

#include <iostream>#define DEBUG//注意:glad头文件必须在glfw引用之前引用
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <string>
#include <assert.h>//断言
#include "wrapper/checkError.h"
#include "application/Application.h"/*
*┌────────────────────────────────────────────────┐
*│ 目	   标: 学习glDrawArrays进行绘制命令
*│ 讲    师: 赵新政(Carma Zhao)
*│ 拆分目标:
*│
*│ 		1  采用GL_TRANGLES进行绘制
*				** 这里大家可以缩放窗体,实验NDC坐标的作用*│ 		2  prepareVAOForGLTriangles:构建四个顶点的vao
*│ 		3  测试Triangle的三种mode:TRIANGLES  TRIANGLE_STRIP TRIANGLE_FAN
*│ 		4  测试Line的二种mode:LINES  LINE_STRIP
*└────────────────────────────────────────────────┘
*/GLuint vao, program;void OnResize(int width, int height) {GL_CALL(glViewport(0, 0, width, height));std::cout << "OnResize" << std::endl;
}void OnKey(int key, int action, int mods) {std::cout << key << std::endl;
}void prepareSingleBuffer() {//1 准备positions colors数据float positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f};float colors[] = {1.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f,0.0f,  0.0f, 1.0f};//2 使用数据生成两个vbo posVbo, colorVboGLuint posVbo, colorVbo;glGenBuffers(1, &posVbo);glGenBuffers(1, &colorVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);//3 生成vao并且绑定GLuint vao = 0;glGenVertexArrays(1, &vao);glBindVertexArray(vao);//4 分别将位置/颜色属性的描述信息加入vao当中//4.1描述位置属性glBindBuffer(GL_ARRAY_BUFFER, posVbo);//只有绑定了posVbo,下面的属性描述才会与此vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//4.2 描述颜色属性glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);
}void prepareInterleavedBuffer() {//1 准备好Interleaved数据(位置+颜色)float vertices[] = {-0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,0.0f,  0.5f, 0.0f,  0.0f,  0.0f, 1.0f};//2 创建唯一的vboGLuint vbo = 0;GL_CALL(glGenBuffers(1, &vbo));GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));//3 创建并绑定vaoGL_CALL(glGenVertexArrays(1, &vao));GL_CALL(glBindVertexArray(vao));GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));//4 为vao加入位置和颜色的描述信息//4.1 位置描述信息GL_CALL(glEnableVertexAttribArray(0));GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0));//4.2 颜色描述信息GL_CALL(glEnableVertexAttribArray(1));GL_CALL(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))));//5 扫尾工作:解绑当前vaoglBindVertexArray(0);
}void prepareVAOForGLTriangles() {//1 准备positionsfloat positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f,0.5f,  0.5f, 0.0f,0.8f,  0.8f, 0.0f,0.8f,  0.0f, 0.0f};//2  posVboGLuint posVbo;glGenBuffers(1, &posVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);//3 生成vao并且绑定glGenVertexArrays(1, &vao);glBindVertexArray(vao);//4 描述位置属性glBindBuffer(GL_ARRAY_BUFFER, posVbo);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);
}void prepareShader() {//1 完成vs与fs的源代码,并且装入字符串const char* vertexShaderSource ="#version 330 core\n""layout (location = 0) in vec3 aPos;\n""void main()\n""{\n""   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n""}\0";const char* fragmentShaderSource ="#version 330 core\n""out vec4 FragColor;\n""void main()\n""{\n""   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n""}\n\0";//2 创建Shader程序(vs、fs)GLuint vertex, fragment;vertex = glCreateShader(GL_VERTEX_SHADER);fragment = glCreateShader(GL_FRAGMENT_SHADER);//3 为shader程序输入shader代码glShaderSource(vertex, 1, &vertexShaderSource, NULL);glShaderSource(fragment, 1, &fragmentShaderSource, NULL);int success = 0;char infoLog[1024];//4 执行shader代码编译 glCompileShader(vertex);//检查vertex编译结果glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertex, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --VERTEX" << "\n" << infoLog << std::endl;}glCompileShader(fragment);//检查fragment编译结果glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(fragment, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --FRAGMENT" << "\n" << infoLog << std::endl;}//5 创建一个Program壳子program = glCreateProgram();//6 将vs与fs编译好的结果放到program这个壳子里glAttachShader(program, vertex);glAttachShader(program, fragment);//7 执行program的链接操作,形成最终可执行shader程序glLinkProgram(program);//检查链接错误glGetProgramiv(program, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(program, 1024, NULL, infoLog);std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl;}//清理glDeleteShader(vertex);glDeleteShader(fragment);
}void render() {//执行opengl画布清理操作GL_CALL(glClear(GL_COLOR_BUFFER_BIT));//1 绑定当前的programglUseProgram(program);//2 绑定当前的vaoglBindVertexArray(vao);//3 发出绘制指令glDrawArrays(GL_TRIANGLE_FAN, 0, 6);// glDrawArrays(GL_TRIANGLES, 0, 6);// glDrawArrays(GL_LINE_STRIP, 0, 6);
}int main() {if (!app->init(800, 600)) {return -1;}app->setResizeCallback(OnResize);app->setKeyBoardCallback(OnKey);//设置opengl视口以及清理颜色GL_CALL(glViewport(0, 0, 800, 600));GL_CALL(glClearColor(0.2f, 0.3f, 0.3f, 1.0f));prepareShader();// prepareInterleavedBuffer();prepareVAOForGLTriangles();while (app->update()) {render();}app->destroy();return 0;
}

5.绘制直线:GL_LINES模式

运行
在这里插入图片描述

关键代码

glDrawArrays(GL_LINES, 0, 6);

6.绘制直线:GL_LINES_STRIP模式

运行
在这里插入图片描述

关键代码

glDrawArrays(GL_LINE_STRIP, 0, 6);

main.cpp

#include <iostream>#define DEBUG//注意:glad头文件必须在glfw引用之前引用
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <string>
#include <assert.h>//断言
#include "wrapper/checkError.h"
#include "application/Application.h"/*
*┌────────────────────────────────────────────────┐
*│ 目	   标: 学习glDrawArrays进行绘制命令
*│ 讲    师: 赵新政(Carma Zhao)
*│ 拆分目标:
*│
*│ 		1  采用GL_TRANGLES进行绘制
*				** 这里大家可以缩放窗体,实验NDC坐标的作用*│ 		2  prepareVAOForGLTriangles:构建四个顶点的vao
*│ 		3  测试Triangle的三种mode:TRIANGLES  TRIANGLE_STRIP TRIANGLE_FAN
*│ 		4  测试Line的二种mode:LINES  LINE_STRIP
*└────────────────────────────────────────────────┘
*/GLuint vao, program;void OnResize(int width, int height) {GL_CALL(glViewport(0, 0, width, height));std::cout << "OnResize" << std::endl;
}void OnKey(int key, int action, int mods) {std::cout << key << std::endl;
}void prepareSingleBuffer() {//1 准备positions colors数据float positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f};float colors[] = {1.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f,0.0f,  0.0f, 1.0f};//2 使用数据生成两个vbo posVbo, colorVboGLuint posVbo, colorVbo;glGenBuffers(1, &posVbo);glGenBuffers(1, &colorVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);//3 生成vao并且绑定GLuint vao = 0;glGenVertexArrays(1, &vao);glBindVertexArray(vao);//4 分别将位置/颜色属性的描述信息加入vao当中//4.1描述位置属性glBindBuffer(GL_ARRAY_BUFFER, posVbo);//只有绑定了posVbo,下面的属性描述才会与此vbo相关glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//4.2 描述颜色属性glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);
}void prepareInterleavedBuffer() {//1 准备好Interleaved数据(位置+颜色)float vertices[] = {-0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,0.0f,  0.5f, 0.0f,  0.0f,  0.0f, 1.0f};//2 创建唯一的vboGLuint vbo = 0;GL_CALL(glGenBuffers(1, &vbo));GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));//3 创建并绑定vaoGL_CALL(glGenVertexArrays(1, &vao));GL_CALL(glBindVertexArray(vao));GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vbo));//4 为vao加入位置和颜色的描述信息//4.1 位置描述信息GL_CALL(glEnableVertexAttribArray(0));GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0));//4.2 颜色描述信息GL_CALL(glEnableVertexAttribArray(1));GL_CALL(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))));//5 扫尾工作:解绑当前vaoglBindVertexArray(0);
}void prepareVAOForGLTriangles() {//1 准备positionsfloat positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f,0.5f,  0.5f, 0.0f,0.8f,  0.8f, 0.0f,0.8f,  0.0f, 0.0f};//2  posVboGLuint posVbo;glGenBuffers(1, &posVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);//3 生成vao并且绑定glGenVertexArrays(1, &vao);glBindVertexArray(vao);//4 描述位置属性glBindBuffer(GL_ARRAY_BUFFER, posVbo);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glBindVertexArray(0);
}void prepareShader() {//1 完成vs与fs的源代码,并且装入字符串const char* vertexShaderSource ="#version 330 core\n""layout (location = 0) in vec3 aPos;\n""void main()\n""{\n""   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n""}\0";const char* fragmentShaderSource ="#version 330 core\n""out vec4 FragColor;\n""void main()\n""{\n""   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n""}\n\0";//2 创建Shader程序(vs、fs)GLuint vertex, fragment;vertex = glCreateShader(GL_VERTEX_SHADER);fragment = glCreateShader(GL_FRAGMENT_SHADER);//3 为shader程序输入shader代码glShaderSource(vertex, 1, &vertexShaderSource, NULL);glShaderSource(fragment, 1, &fragmentShaderSource, NULL);int success = 0;char infoLog[1024];//4 执行shader代码编译 glCompileShader(vertex);//检查vertex编译结果glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertex, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --VERTEX" << "\n" << infoLog << std::endl;}glCompileShader(fragment);//检查fragment编译结果glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(fragment, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --FRAGMENT" << "\n" << infoLog << std::endl;}//5 创建一个Program壳子program = glCreateProgram();//6 将vs与fs编译好的结果放到program这个壳子里glAttachShader(program, vertex);glAttachShader(program, fragment);//7 执行program的链接操作,形成最终可执行shader程序glLinkProgram(program);//检查链接错误glGetProgramiv(program, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(program, 1024, NULL, infoLog);std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl;}//清理glDeleteShader(vertex);glDeleteShader(fragment);
}void render() {//执行opengl画布清理操作GL_CALL(glClear(GL_COLOR_BUFFER_BIT));//1 绑定当前的programglUseProgram(program);//2 绑定当前的vaoglBindVertexArray(vao);//3 发出绘制指令glDrawArrays(GL_LINE_STRIP, 0, 6);// glDrawArrays(GL_TRIANGLES, 0, 6);// glDrawArrays(GL_LINE_STRIP, 0, 6);
}int main() {if (!app->init(800, 600)) {return -1;}app->setResizeCallback(OnResize);app->setKeyBoardCallback(OnKey);//设置opengl视口以及清理颜色GL_CALL(glViewport(0, 0, 800, 600));GL_CALL(glClearColor(0.2f, 0.3f, 0.3f, 1.0f));prepareShader();// prepareInterleavedBuffer();prepareVAOForGLTriangles();while (app->update()) {render();}app->destroy();return 0;
}

7.其他代码文件

7.1.主CMakeLists.txt

# 指定 CMake 最低版本
cmake_minimum_required(VERSION 3.12)# 项目名称
project(OpenGL_Lecture)# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)# 包含头文件目录
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/include/usr/include
)# 包含库文件目录
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdParty/lib/usr/lib/x86_64-linux-gnu
)# 设置 CMAKE_PREFIX_PATH 以找到 GLFW
set(CMAKE_PREFIX_PATH "/usr/local/lib/cmake/glfw3")
set(GLFW_DIR "/usr/local/lib/cmake/glfw3")# 查找 GLFW3 库
find_package(glfw3 REQUIRED CONFIG)add_subdirectory(wrapper)
add_subdirectory(application)# 添加可执行文件
add_executable(openglStudy "main.cpp" "glad.c")# 链接库
target_link_libraries(openglStudy glfw wrapper app)

7.2.application\CMakeLists.txt

#递归将本文件夹下所有cpp放到FUNCS中
file(GLOB_RECURSE APP ./  *.cpp)#将FUNCS中所有cpp编译为funcs这个lib库
add_library(app ${APP} )target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(app PRIVATE glfw)

7.3.application\Application.h

#pragma once /*
*┌────────────────────────────────────────────────┐
*│ 目	   标: 封装Application(表示了当前应用程序本身)
*│ 讲    师: 赵新政(Carma Zhao)
*│ 拆分目标:
*│
*│ 		1	单例类(全局唯一实例)
*│ 		2	成员变量 + 成员函数
*				2.1 成员函数-init(初始化)
*				2.2 成员函数-update(每一帧执行)
*				2.3 成员函数-destroy(结尾执行)
*│ 		3	响应回调函数(Resize)
*				3.1 声明一个函数指针ResizeCallback
*				3.2 声明一个ResizeCallback类型的成员变量
*				3.3 声明一个SetResizeCallback的函数 ,设置窗体变化响应回调函数
*				3.4 声明一个static的静态函数,用于响应glfw窗体变化
*				3.5 将静态函数设置到glfw的监听Resize监听当中
*				3.6 * 学会使用glfw的UserPointer
*│ 		4	响应键盘消息函数(KeyBoard)
*				3.1 声明一个static的静态函数,用于响应glfw的键盘事件
*				3.2 将静态函数设置到glfw的监听KeyCallback监听当中
*				3.3 声明一个函数指针KeyBoardCallback
*				3.4 声明一个KeyBoardCallback类型的成员变量
*				3.5 声明一个SetKeyBoardCallback的函数 ,设置键盘响应回调函数
*				3.6 * 学会使用glfw的UserPointer
*└────────────────────────────────────────────────┘
*/
#include <iostream>#define app Application::getInstance()class GLFWwindow;using ResizeCallback = void(*)(int width, int height);
using KeyBoardCallback = void(*)(int key, int action, int mods);class Application {
public:~Application();//用于访问实例的静态函数static Application* getInstance();bool init(const int& width = 800, const int& height = 600);bool update();void destroy();uint32_t getWidth()const { return mWidth; }uint32_t getHeight()const { return mHeight; }void setResizeCallback(ResizeCallback callback) { mResizeCallback = callback; }void setKeyBoardCallback(KeyBoardCallback callback) { mKeyBoardCallback = callback; }private://C++类内函数指针static void frameBufferSizeCallback(GLFWwindow* window, int width, int height);static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);private://全局唯一的静态变量实例static Application* mInstance;uint32_t mWidth{ 0 };uint32_t mHeight{ 0 };GLFWwindow* mWindow{ nullptr };ResizeCallback mResizeCallback{ nullptr };KeyBoardCallback mKeyBoardCallback{ nullptr };Application();
};

7.4.application\Application.cpp

#include "Application.h"
#include<glad/glad.h>
#include<GLFW/glfw3.h>//初始化Application的静态变量
Application* Application::mInstance = nullptr;
Application* Application::getInstance() {//如果mInstance已经实例化了(new出来了),就直接返回//否则需要先new出来,再返回if (mInstance == nullptr) {mInstance = new Application();}return mInstance;
}Application::Application() {}Application::~Application() {}bool Application::init(const int& width, const int& height) {mWidth = width;mHeight = height;//1 初始化GLFW基本环境glfwInit();//1.1 设置OpenGL主版本号、次版本号glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//1.2 设置OpenGL启用核心模式(非立即渲染模式)glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//2 创建窗体对象mWindow = glfwCreateWindow(mWidth, mHeight, "OpenGLStudy", NULL, NULL);if (mWindow == NULL) {return false;}//**设置当前窗体对象为OpenGL的绘制舞台glfwMakeContextCurrent(mWindow);if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "Failed to initialize GLAD" << std::endl;return false;}glfwSetFramebufferSizeCallback(mWindow, frameBufferSizeCallback);//this就是当前全局唯一的Application对象glfwSetWindowUserPointer(mWindow, this);//键盘响应glfwSetKeyCallback(mWindow, keyCallback);return true;
}bool Application::update() {if (glfwWindowShouldClose(mWindow)) {return false;}//接收并分发窗体消息//检查消息队列是否有需要处理的鼠标、键盘等消息//如果有的话就将消息批量处理,清空队列glfwPollEvents();//切换双缓存glfwSwapBuffers(mWindow);return true;
}void Application::destroy() {//退出程序前做相关清理glfwTerminate();
}void Application::frameBufferSizeCallback(GLFWwindow* window, int width, int height) {std::cout << "Resize" << std::endl;Application* self = (Application*)glfwGetWindowUserPointer(window);if (self->mResizeCallback != nullptr) {self->mResizeCallback(width, height);}//if (Application::getInstance()->mResizeCallback != nullptr) {//	Application::getInstance()->mResizeCallback(width, height);//}
}void Application::keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {Application* self = (Application*)glfwGetWindowUserPointer(window);if (self->mKeyBoardCallback != nullptr) {self->mKeyBoardCallback(key, action, mods);}
}

7.5.wrapper\CMakeLists.txt

#递归将本文件夹下所有cpp放到FUNCS中
file(GLOB_RECURSE WRAPPER ./  *.cpp)#将FUNCS中所有cpp编译为funcs这个lib库
add_library(wrapper ${WRAPPER} )target_include_directories(wrapper PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(wrapper PRIVATE glfw)

7.6.wrapper\checkError.h

#pragma once //预编译宏
#ifdef DEBUG
#define GL_CALL(func)  func;checkError();
#else
#define GL_CALL(func) 
#endif void checkError();

7.7.wrapper\checkError.cpp

#include "checkError.h"
#include <glad/glad.h>
#include <string>
#include <iostream>
#include <assert.h>void checkError() {GLenum errorCode = glGetError();std::string error = "";if (errorCode != GL_NO_ERROR) {switch (errorCode){case GL_INVALID_ENUM: error = "INVALID_ENUM"; break;case GL_INVALID_VALUE:  error = "INVALID_VALUE"; break;case GL_INVALID_OPERATION: error = "INVALID_OPERATION"; break;case GL_OUT_OF_MEMORY: error = "OUT OF MEMORY"; break;default:error = "UNKNOWN";break;}std::cout << error << std::endl;//assert会根据传入的bool值,来决定程序是否停止//true:程序顺利运行//false:程序会断死assert(false);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/42702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第二周:李宏毅机器学习笔记

第二周学习周报 摘要Abstract一、深度学习1.Backpropagation&#xff08;反向传播&#xff09;1.1 链式法则1.2 Forward pass&#xff08;前向传播&#xff09;1.3 Backward pass&#xff08;向后传播&#xff09;1.4 总结 2. Regression&#xff08;神奇宝贝案例&#xff09;2…

Redis常用命令——Set、Zset篇

文章目录 一、Set相关命令操作 SADD SMEMBERS SISMEMBER SCARD SPOP SMOVE SREM SINTER 与 SINTERSTORE SUNION 与 SUNIONSTORE SDIFF 与 SDIFFSTORE Set命令小结 二、Zset 相关命令操作 ZADD ZCARD ZCOUNT ZRANGE ZREVRANGE ZPOPMAX BZPOPMAX ZPOPMIN 与 BZPOPMIN ZRANK 与 …

MySQL事务隔离

MySQL事务隔离 前言锁共享锁&#xff08;Shared Lock&#xff09;排他锁&#xff08;Exclusive Lock&#xff09;行级锁&#xff08;Row-Level Lock&#xff09;表级锁&#xff08;Table-Level Lock&#xff09;快照读和当前读查看锁 事务事务的四个特性事务的并发问题事务的隔…

《Windows API每日一练》8.5 listbox控件

列表框是将一批文本字符串显示在一个具有滚动功能的方框中的控件。通过发送消息到列表框的窗口过程&#xff0c;程序可以添加或删除列表中的字符串。当列表框中的一个项目被选中时&#xff0c;列表框控件便发送 WM_COMMAND消息到其父窗口。然后父窗口确定哪个项目被选中。 本节…

J024_打印电影的全部信息

一、需求描述 展示多部电影的信息。 电影信息包括&#xff1a;电影名称、电影得分、电影票价格。 二、代码实现 2.1 Movie类 package com.itheima.collection;public class Movie {//电影名称private String name;//电影得分private int score;//电影票价格private double…

【Unity 3D角色移动】

【Unity 3D角色移动】 在Unity 3D中实现角色移动通常涉及到几个关键步骤&#xff0c;包括设置角色的物理属性、处理输入、更新角色的位置以及动画同步。下面是实现基本3D角色移动的步骤和示例代码&#xff1a; 步骤1&#xff1a;设置角色的物理属性 角色通常使用Character Co…

OpenCV杂记(4):OpenCV之色彩映射(伪彩applyColorMap)

1. 简述 我们在开发基于热成像&#xff08;红外&#xff09;或者做深度估计应用时&#xff0c;为了便于直观的观察&#xff0c;常常将检测结果进行色彩上的映射&#xff0c;这样便可以很直观的看出哪里温度高&#xff0c;哪里温度低&#xff0c;或者哪里深度更深或更浅。 我们将…

数列结构(3.9)——队列应用

树的层次遍历 树的层次遍历&#xff0c;也称为树的广度优先遍历&#xff0c;是一种按照树的层次顺序&#xff0c;从上到下、从左到右遍历树中所有节点的算法。在二叉树中&#xff0c;这种遍历方式通常使用队列来实现。下面是层次遍历的基本步骤&#xff1a; 创建一个空队列&a…

Golang | Leetcode Golang题解之第220题存在重复元素III

题目&#xff1a; 题解&#xff1a; func getID(x, w int) int {if x > 0 {return x / w}return (x1)/w - 1 }func containsNearbyAlmostDuplicate(nums []int, k, t int) bool {mp : map[int]int{}for i, x : range nums {id : getID(x, t1)if _, has : mp[id]; has {retu…

java中反射(Reflection)的4个作用

java中反射&#xff08;Reflection&#xff09;的4个作用 作用1、在运行时判断任意一个对象所属的类作用2、在运行时构造任意一个类的对象作用3、在运行时判断任意一个类所具有的成员变量和方法作用4、在运行时调用任意一个对象的方法总结 &#x1f496;The Begin&#x1f496;…

【Android】自定义换肤框架05之Skinner框架集成

引入依赖 api("io.github.hellogoogle2000:android-skinner:1.0.0")初始化Skinner 在所有功能前调用即可&#xff0c;建议在Application中初始化 SkinnerKit.init(application)安装皮肤包 在应用该皮肤包前安装即可&#xff0c;建议预安装&#xff0c;或应用皮肤…

扩散模型笔记2

Ref:扩散模型的原理及实现&#xff08;Pytorch&#xff09; 在扩散模型中&#xff0c;每一步添加的噪声并不是完全一样的。具体来说&#xff0c;噪声的添加方式和量在每一步是根据特定的规则或公式变化的。这里我们详细解释每一步添加噪声的过程。 正向过程中的噪声添加&…

vb.netcad二开自学笔记9:界面之ribbon

一个成熟的软件怎么能没有ribbon呢&#xff0c;在前面的框架基础上再加个命令AddRibbon <CommandMethod("AddRibbon")> Public Sub AddRibbon() Dim ribbonControl As RibbonControl ComponentManager.Ribbon Dim tab As RibbonTab New RibbonTab() tab.Tit…

初中化学知识点总结(人教版)

第一单元 走进化学世界 一 物质的变化和性质 1物理变化&#xff1a;没有生成其它物质的变化叫做物理变化。 化学变化&#xff1a;生成其他物质的变化叫做化学变化&#xff0c;又叫化学反应。 物理变化和化学变化的区别&#xff1a;是否有其他物质生产。 2化学变化的基本特…

Python - 自动化办公,将yml根据转换规则转换成‘‘ = ‘‘

文章目录 前言## Python - 自动化办公&#xff0c;将yml根据转换规则转换成 1. 准备工作2. demo3. 测试 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会…

【教程】新的Selenium!整合了隐藏浏览器指纹等功能

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 前景提要 driver Driver() 常用driver 接口 最后的话 前景提要 新的selenium&#xff0c;整合了隐藏浏览器指纹&#xff0c;非常好用&#x…

算法库应用--KMP算法解决串匹配问题

学习来源 学习贺利坚老师博客 数据结构例程——串的模式匹配&#xff08;KMP算法&#xff09;_数据结构模式匹配例题-CSDN博客 本人引导博客 串的匹配 (KPM算法由来引导)_kpm匹配失败-CSDN博客 转载大佬sofu博客 https://www.cnblogs.com/dusf/p/kmp.html 本人详细思路引导b战…

代码随想录算法训练营第四十九天| 300.最长递增子序列 , 674. 最长连续递增序列 , 718. 最长重复子数组

300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int lengthOfLIS(int[] nums) {int[] dp new int[nums.length];dp[0] 1;for(int i1;i<nums.length;i){for(int j0;j<i;j){if(nums[i] > nums[j]){dp[i] Math.max(dp[j],dp[i])…

【Spring Boot】关系映射开发(三):多对多映射

《JPA 从入门到精通》系列包含以下文章&#xff1a; Java 持久层 API&#xff1a;JPA认识 JPA 的接口JPA 的查询方式基于 JPA 开发的文章管理系统&#xff08;CRUD&#xff09;关系映射开发&#xff08;一&#xff09;&#xff1a;一对一映射关系映射开发&#xff08;二&#…