You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:43:16