OpenGL顶点属性指针奇怪的行为
Posted
技术标签:
【中文标题】OpenGL顶点属性指针奇怪的行为【英文标题】:OpenGl Vertex Attrib Pointer strange behavior 【发布时间】:2020-09-17 11:32:42 【问题描述】:在将显卡从 AMD 更改为 AMD 后,我遇到了一些非常奇怪的行为。我在我的着色器程序中使用了两个单独的顶点属性布局。我有一个:
layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec3 inNormal;
layout (location = 2) in vec2 inTexCoords;
我将属性指针设置为:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)nullptr);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
然后我在着色器中有另一个顶点属性布局,如下所示:
layout (location = 0) in vec4 inPosAndCoords;
layout (location = 1) in int inColour;
我将属性指针设置为:
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)nullptr);
glEnableVertexAttribArray(0);
glVertexAttribIPointer(1, 1, GL_INT, 5 * sizeof(float), (void*) (4 * sizeof(float)));
glEnableVertexAttribArray(1);
所以问题是,在我的 nVidia GTX 980 和英特尔集成显卡上,我会从 3 属性布局切换到 2 属性布局,就像上面一样,一切正常。但是,由于我安装了 Radeon RX570,我在 atio6axx.dll 处抛出异常,访问冲突读取位置...
有几种方法可以解决这个问题。我可以这样做:
glDisableVertexAttribArray(2);
或者将索引 2(第三个属性)的 VertexAttribPointer 设置为似乎无关紧要的值,例如:
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
由于从 3 属性布局切换到 2 属性布局时似乎适用于 nVidia 和 Intel,而不适用于这张 Radeon 卡,我认为这种行为是这张卡的一个怪癖。
我使用的是同一个 VAO,我绑定了一个不同的 VBO,然后我设置了 glVertexAttribPointer 和 glEnableVertexAttribArray。
在这里问了一个类似的问题,"Is it important to call glDisableVertexAttribArray()?",但在我的情况下,如果我不禁用第三个属性(索引 2),只要我为索引 2 调用 glVertexAttribPointer,它就可以工作。我很困惑正确的流程是什么。
【问题讨论】:
如果这些对象使用这种不同的顶点格式,那么它们应该使用不同的 VAO。 【参考方案1】:由于从 3 属性布局切换到 2 属性布局时似乎适用于 nVidia 和 Intel,而不适用于这张 Radeon 卡,我认为这种行为是这张卡的一个怪癖。
OpenGL 规范不支持该结论。如果您访问i
-th 顶点索引,GL 可能会访问每个启用的顶点数组的i
-th 元素。如果它没有指向有效的位置,你会得到未定义的行为。它恰好适用于 Nvidia 和 Intel 并没有改变这一切。只需为您未提供有效数据的属性禁用顶点属性数组即可。
【讨论】:
以上是关于OpenGL顶点属性指针奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章