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顶点属性指针奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL顶点属性未启用

OpenGL:为啥我不能将单个浮点数从顶点着色器传递到片段着色器?

OpenGL实例化数组奇怪的顶点位置

初识OpenGL (-)VAO顶点数组对象

初识OpenGL (-)VAO顶点数组对象

初识OpenGL (-)VAO顶点数组对象