C++ OpenGL 4.5 程序无法正常显示绘制的三角形对象,求助排查
OpenGL三角形不渲染问题修复说明
- 顶点缓冲区大小参数错误
原代码中glBufferData(GL_ARRAY_BUFFER, 6, Points, GL_STATIC_DRAW);第二个参数单位为字节,6仅为顶点元素个数,实际总数据大小应为6 * sizeof(float),错误的大小导致仅上传了前6字节的顶点数据,无法构成有效三角形。 - 帧交换顺序错误
渲染循环中glfwSwapBuffers(window)被放在绘制逻辑最前面,该函数作用是将后台已完成绘制的帧交换到屏幕显示,放在开头会导致所有绘制结果永远停留在后台,不会展示到窗口,需要移到所有绘制指令的末尾。 - 顶点属性设置顺序不规范(非致命但存在隐患)
glVertexAttribPointer需要读取当前绑定的GL_ARRAY_BUFFER的元信息,需要先执行glBufferData上传顶点数据,再设置顶点属性指针,原代码顺序相反。 - 冗余操作(不影响运行但不符合规范)
glEnableVertexAttribArray的状态会被VAO存储,仅需在初始化VAO时调用一次即可,无需每次渲染循环重复调用。
修正后的完整代码:
#include <glad/glad.h> #include <GLFW/glfw3.h> #include <glm.hpp> int width = 800, height = 600; int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow* window = glfwCreateWindow(width, height, "engine", NULL, NULL); glfwMakeContextCurrent(window); gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); glViewport(0, 0, width, height); const char* VertexShaderData = "#version 450 core\n" "layout(location = 0) in vec2 pos;\n" "void main(){\n" "gl_Position = vec4(pos, 0, 1);\n" "}\0"; GLuint VertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(VertexShader, 1, &VertexShaderData, NULL); glCompileShader(VertexShader); const char* FragmentShaderData = "#version 450 core\n" "out vec4 Color;\n" "void main(){\n" "Color = vec4(0.25, 0.8, 0.65, 1);\n" "}\0"; GLuint FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(FragmentShader, 1, &FragmentShaderData, NULL); glCompileShader(FragmentShader); GLuint ShaderProgram = glCreateProgram(); glAttachShader(ShaderProgram, VertexShader); glAttachShader(ShaderProgram, FragmentShader); glLinkProgram(ShaderProgram); float Points[] = { -1, -1, 0, 1, 1, -1 }; GLuint VAO, VBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); // 修正:先上传数据,再设置顶点属性,同时修正缓冲区大小参数 glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), Points, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0); // 修正:初始化时启用顶点属性,无需每次循环调用 glEnableVertexAttribArray(0); glClearColor(0.3, 0.5, 0.7, 1); while (!glfwWindowShouldClose(window)) { glClear(GL_COLOR_BUFFER_BIT); glUseProgram(ShaderProgram); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 3); // 修正:交换帧放到所有绘制操作之后,新增事件轮询避免窗口无响应 glfwSwapBuffers(window); glfwPollEvents(); } // 新增资源释放逻辑 glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteProgram(ShaderProgram); glDeleteShader(VertexShader); glDeleteShader(FragmentShader); glfwTerminate(); return 0; }
内容的提问来源于stack exchange,提问作者Normal Name
相关产品推荐
相关产品推荐

