(九)绘制彩色三角形

时间:2024-07-05 07:01:55
#include <glad/glad.h>//glad必须在glfw头文件之前包含 #include <GLFW/glfw3.h> #include <iostream> void frameBufferSizeCallbakc(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } void glfwKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { } GLuint program = 0; GLuint vao = 0; void prepareVAO() { //positions 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 }; //索引 unsigned int indices[] = { 0, 1, 2, }; //2 VBO创建 GLuint posVbo = 0; GLuint colorVbo = 0; glGenBuffers(1, &posVbo); glBindBuffer(GL_ARRAY_BUFFER, posVbo); glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW); glGenBuffers(1, &colorVbo); glBindBuffer(GL_ARRAY_BUFFER, colorVbo); glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); //3 EBO创建 GLuint ebo = 0; glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); //4 VAO创建 vao = 0; glGenVertexArrays(1, &vao); glBindVertexArray(vao); //5 绑定vbo ebo 加入属性描述信息 //5.1 加入位置属性描述信息 glBindBuffer(GL_ARRAY_BUFFER, posVbo); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); //5.2 加入颜色属性描述信息 glBindBuffer(GL_ARRAY_BUFFER, colorVbo); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); //5.2 加入ebo到当前的vao glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBindVertexArray(0); } void prepareShader() { //1 完成vs与fs的源代码,并且装入字符串 const char* vertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" "layout (location = 1) in vec3 aColor;\n" "out vec3 color;\n" "void main()\n" "{\n" " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" " color = aColor;\n" "}\0"; const char* fragmentShaderSource = "#version 330 core\n" "out vec4 FragColor;\n" "in vec3 color;\n" "void main()\n" "{\n" " FragColor = vec4(color, 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画布清理操作 glClear(GL_COLOR_BUFFER_BIT); //1.绑定当前的program glUseProgram(program); //2 绑定当前的vao glBindVertexArray(vao); //3 发出绘制指令 //glDrawArrays(GL_TRIANGLE_STRIP, 0, 6); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0); } int main() { //初始化glfw环境 glfwInit(); //设置opengl主版本号 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //设置opengl次版本号 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); //设置opengl启用核心模式 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //创建窗体对象 GLFWwindow* window = glfwCreateWindow(800, 600, "lenarnOpenGL", nullptr, nullptr); //设置当前窗体对象为opengl的绘制舞台 glfwMakeContextCurrent(window); //窗体大小回调 glfwSetFramebufferSizeCallback(window, frameBufferSizeCallbakc); //键盘相应回调 glfwSetKeyCallback(window, glfwKeyCallback); //使用glad加载所有当前版本opengl的函数 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "初始化glad失败" << std::endl; return -1; } ; //设置opengl视口大小和清理颜色 glViewport(0, 0, 800, 600); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); //着色器 prepareShader(); //vao prepareVAO(); //执行窗体循环 while (!glfwWindowShouldClose(window)) { //接受并分发窗体消息 //检查消息队列是否有需要处理的鼠标、键盘等消息 //如果有的话就将消息批量处理,清空队列 glfwPollEvents(); //渲染操作 render(); //切换双缓存 glfwSwapBuffers(window); } //推出程序前做相关清理 glfwTerminate(); return 0; }