opengl 使用glDrawArrays()的Draw函数需要调用两次才能显示任何内容

aydmsdu9  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(261)

这是一个奇怪的问题。我有一个函数:

void drawLines(std::vector<GLfloat> lines) {
    glBindVertexArray(VAO2);

    //positions
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0);
    glEnableVertexAttribArray(0);

    //colors
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER, VBO2);
    glBufferData(GL_ARRAY_BUFFER, sizeof(lines[0]) * lines.size(), &lines[0], GL_STATIC_DRAW);

    glUseProgram(pShaderProgram);
    glDrawArrays(GL_TRIANGLES, 0, lines.size() / 6);
}

它绘制指定粗细的线(这内置在lines的数据中,lines包含三个位置浮点数和三个颜色浮点数,每个点超过200个点,用于标记行结束)。调用该函数一次不会产生任何结果,即使在随后调用SwapBuffers(HDC)glFlush()之后也是如此。但是,当我调用该函数两次时,然后一切都显示出来了。2我怀疑我在通过渲染管道推动缓冲区时遗漏了一些细微差别,可能是通过多次绑定缓冲区来激活的。3我不确定。4有什么想法吗?

qrjkbowd

qrjkbowd1#

glVertexAttribPointer需要一个绑定到GL_ARRAY_BUFFER绑定点的缓冲区,以便在通用顶点属性和缓冲区对象之间建立关联,从而从该缓冲区对象获取数据。
但是,在调用glVertexAttribPointer * 之后 * 将缓冲区与glBindBuffer(GL_ARRAY_BUFFER, VBO2)绑定。
这就是为什么您需要两次调用,因为第一次调用不会将任何缓冲区对象与通用顶点属性关联,因为之前可能没有绑定缓冲区。
然而,你使用VAO的方式是可疑的,因为你在这个方法/函数中所做的一切都已经被保存为VAO状态了。所以,你不需要每次都重新建立通用顶点属性和缓冲对象之间的关联,也不需要每次绘图时都启用通用顶点属性。
所有这些都可以在为 VAO 指定顶点时 * 一次 * 完成。

相关问题