GLFW环境下OpenGL三角形首个顶点未按指定坐标渲染问题
OpenGL渲染三角形顶点位置错误问题
问题描述
跟随YouTube上The Cherno的OpenGL教程学习着色器,用C++实现后,渲染三角形时第一个顶点未显示在指定的(-0.5f, 0.5f)坐标,而是出现在(0.0f, 0.0f)。曾怀疑是着色器未正确处理顶点数据,但排查后排除该可能。
错误渲染效果:
使用的GLFW版本为4.6.0 - Build 31.0.101.2111,代码如下:
#include <iostream> #include <GL/glew.h> #include <GLFW/glfw3.h> static unsigned int CompileShader(unsigned int type, const std::string& source) { unsigned int id = glCreateShader(type); const char* src = source.c_str(); glShaderSource(id, 1, &src, nullptr); glCompileShader(id); int result; glGetShaderiv(id, GL_COMPILE_STATUS, &result); if (!result) { int length; glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length); char* message = (char*) alloca(length * sizeof(char)); glGetShaderInfoLog(id, length, &length, message); std::cerr << "Failed to compile " << (type == GL_VERTEX_SHADER ? "vertex" : type == GL_FRAGMENT_SHADER ? "fragment" : "") << " shader!" << '\n'; std::cerr << message << '\n'; glDeleteShader(id); return 0; } return id; } static unsigned int CreateShader(const std::string& vertexShader, const std::string& fragmentShader) { unsigned int program = glCreateProgram(); unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader); unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader); glAttachShader(program, vs); glAttachShader(program, fs); glLinkProgram(program); glValidateProgram(program); glDeleteShader(vs); glDeleteShader(fs); return program; } int main(void) { GLFWwindow* window; if (!glfwInit()) return -1; window = glfwCreateWindow(840, 680, "Window", NULL, NULL); if (!window) { glfwTerminate(); return -1; } glfwMakeContextCurrent(window); if (glewInit() != GLEW_OK) return -1; std::cout << glGetString(GL_VERSION) << '\n'; float positions[6] = { -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, -0.5f }; unsigned int buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0); std::string vertexShader = R"( #version 330 core layout(location = 0) in vec4 position; void main() { gl_Position = position; } )"; std::string fragmentShader =R"( #version 330 core layout(location = 0) out vec4 color; void main() { color = vec4(1.0, 0.0, 0.0, 1.0); } )"; unsigned int shader = CreateShader(vertexShader, fragmentShader); glUseProgram(shader); while (!glfwWindowShouldClose(window)) { glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 1, 3); glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; }
问题原因与解决方法
问题出在glDrawArrays的调用参数:
glDrawArrays(GL_TRIANGLES, 1, 3);
第二个参数是起始顶点索引,第三个是要绘制的顶点数量。你的顶点数组只有3个有效顶点(索引0、1、2),从索引1开始取3个顶点时,第三个顶点属于越界访问,OpenGL会用默认的(0.0f, 0.0f, 0.0f, 1.0f)填充这个无效顶点,这就是出现(0,0)顶点的原因。
只需修改glDrawArrays的参数,从索引0开始取3个顶点即可:
glDrawArrays(GL_TRIANGLES, 0, 3);
修改后,OpenGL会正确使用你定义的三个顶点,三角形就能按预期渲染在指定坐标上。
内容的提问来源于stack exchange,提问作者Konstei
相关产品推荐
相关产品推荐

