OpenGL - 正确地将 VAO 定义与 VBO 和其他缓冲区创建分开
Posted
技术标签:
【中文标题】OpenGL - 正确地将 VAO 定义与 VBO 和其他缓冲区创建分开【英文标题】:OpenGL - Properly separating VAO definition from VBO and other buffers creation 【发布时间】:2015-07-11 13:38:14 【问题描述】:运行一个非常简单的绘制三角形示例,我试图找出哪些线专门引用了 VAO 定义,哪些线可以分开。
目前我正在使用此代码:
缓冲区创建和填充:
TriangleVertices = new float[9]
0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
;
TriangleColors = new float[12]
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
;
glGenBuffers(1, &VertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
glBufferData(GL_ARRAY_BUFFER, 9*sizeof(float), TriangleVertices, GL_STATIC_DRAW);
glGenBuffers(1, &ColorsBuffer);
glBindBuffer(GL_ARRAY_BUFFER, ColorsBuffer);
glBufferData(GL_ARRAY_BUFFER, 12*sizeof(float), TriangleColors, GL_STATIC_DRAW);
glGenVertexArrays(1, &VAOID);
VAO 定义:
glBindVertexArray(VAOID);
glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, ColorsBuffer);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
绘图循环
glBindVertexArray(VAOID);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
如果在绘图循环中我每帧都包含 VAO 定义,该示例运行良好,但如果我在开始绘制之前只定义一次 VAO,它就不起作用,所以我猜 VAO 定义缺少一些代码。
我错过了什么?
【问题讨论】:
【参考方案1】:编辑:问题中的代码是正确的。问题来自与我认为我没有运行的其他 OpenGL 调用的冲突。
下面描述的代码只是情境性的。正如@derhass 评论的那样,在进行绘图调用时无需启用或禁用 VertexAttribArray。
...
旧答案:
在不再需要时取消绑定和禁用每个元素可以解决问题,但我不知道这个解决方案是否可以广泛使用,或者它仅适用于我的环境。
缓冲区创建和填充:
TriangleVertices = new float[9]
0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
;
TriangleColors = new float[12]
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
;
glGenBuffers(1, &VertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
glBufferData(GL_ARRAY_BUFFER, 9*sizeof(float), TriangleVertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &ColorsBuffer);
glBindBuffer(GL_ARRAY_BUFFER, ColorsBuffer);
glBufferData(GL_ARRAY_BUFFER, 12*sizeof(float), TriangleColors, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenVertexArrays(1, &VAOID);
VAO 定义:
glBindVertexArray(VAOID);
glBindBuffer(GL_ARRAY_BUFFER, VertexBuffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, ColorsBuffer);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
绘图循环
glBindVertexArray(VAOID);
glEnableVertexAttribArray(0);//not needed
glEnableVertexAttribArray(1);//not needed
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);//not needed
glDisableVertexAttribArray(1);//not needed
glBindVertexArray(0);
【讨论】:
这不是 VAO 应该如何工作的。每个属性数组的启用状态是 VAO 状态的一部分。目前尚不清楚您的程序中正在执行什么操作。 @derhass 你是对的。我以为我只运行了三角形示例,但我有另一个绘图调用显然与这个碰撞。我会编辑答案。以上是关于OpenGL - 正确地将 VAO 定义与 VBO 和其他缓冲区创建分开的主要内容,如果未能解决你的问题,请参考以下文章