OpenGL三角形网格渲染异常排查:仅显示一条线
问题排查与修复
1. 索引容器类型完全错误
你用std::vector<glm::vec3>存储索引,但EBO需要的是单个无符号整数索引,不是三维向量。这种错误会让OpenGL完全无法解析三角形的顶点关联关系,直接导致渲染异常。
修复代码:
int gridSideLength= 16; // any power of 2 unsigned int gridVBO, gridVAO, gridEBO; const uint32_t verticesCount = (gridSideLength + 1) * (gridSideLength + 1); // 每个四边形拆成2个三角形,每个三角形3个索引,修正总数计算 const uint32_t indicesCount = gridSideLength * gridSideLength * 2 * 3; std::vector<glm::vec3> vertices(verticesCount); // 把索引容器改成uint32_t类型 std::vector<uint32_t> indices(indicesCount); // 顶点填充逻辑不变 uint32_t idx = 0; for (float i = -(gridSideLength / 2); i <= (gridSideLength / 2); ++i) { for (float j = -(gridSideLength / 2); j <= (gridSideLength / 2); ++j) { vertices[idx] = glm::vec3((float)j, 0.0f, (float)i); idx++; } } // 修正索引填充逻辑,逐个存入单个索引值 idx = 0; for (int i = 0; i < gridSideLength; ++i) { int row1 = i * (gridSideLength + 1); int row2 = (i + 1) * (gridSideLength + 1); for (int j = 0; j < gridSideLength; ++j) { // 第一个三角形的三个索引 indices[idx++] = row1 + j; indices[idx++] = row1 + j + 1; indices[idx++] = row2 + j + 1; // 第二个三角形的三个索引 indices[idx++] = row1 + j; indices[idx++] = row2 + j + 1; indices[idx++] = row2 + j; } }
2. VAO与EBO绑定顺序错误
VAO会记录当前绑定的GL_ELEMENT_ARRAY_BUFFER,但你先创建VBO,再绑定VAO,最后才绑定EBO——这会导致VAO没有关联EBO,OpenGL找不到索引数据。
修复VAO/EBO初始化顺序:
// 先绑定VAO,后续的VBO/EBO操作都会被VAO记录 glGenVertexArrays(1, &gridVAO); glBindVertexArray(gridVAO); // 处理VBO glGenBuffers(1, &gridVBO); glBindBuffer(GL_ARRAY_BUFFER, gridVBO); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW); // 设置顶点属性指针 glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); // 处理EBO(此时VAO处于绑定状态,会自动关联EBO) glGenBuffers(1, &gridEBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gridEBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(indices[0]), &indices[0], GL_STATIC_DRAW);
3. 绘制时索引数量错误
修复索引容器类型后,indices直接存储每个索引值,所以绘制时的数量应该是indices.size(),不需要再乘以3:
while (glfwWindowShouldClose(window) == false) { // ... 矩阵计算逻辑不变 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.05f, 0.05f, 0.05f, 1.0f); // 修正变量名:m_GridVAO改为gridVAO,保持与定义一致 glBindVertexArray(gridVAO); // 修正索引数量参数 glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); }
额外检查点
- 确保开启深度测试:初始化时添加
glEnable(GL_DEPTH_TEST);,避免因遮挡导致的渲染异常。 - 检查相机位置:如果相机处于网格平面(y=0)内,会导致透视后看起来像一条线,建议设置相机位置为
glm::vec3(0, 15, 0),以俯视角度观察网格。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

