【问题标题】:Can't get integer vertex attributes working in GLSL 1.5无法获得在 GLSL 1.5 中工作的整数顶点属性
【发布时间】:2011-07-05 04:43:41
【问题描述】:

我在 GLSL 1.5 中使用 OpenGL 3.2 上下文,出于某种原因,整数属性(int、uint、ivecX 或 uvecX 类型)在顶点着色器中总是被读取为 0。我使用以下方式声明它们:

in int name;

我使用 glVertexAttribIPointer 绑定属性(注意 I),而不是 glVertexAttribPointer (但那个也不起作用)。如果我将它们更改为浮点数,它们可以正常工作——唯一的代码区别是顶点结构中的类型、GLSL 中的类型以及 IPointer 函数调用,而不仅仅是指针。我没有得到任何错误或任何东西,它们都只是 0。如果我硬编码整数值,它可以正常工作,整数制服也可以正常工作。此外,像 gl_VertexID 这样的内置整数可以完美运行,而自定义整数则不能。我正在运行 ATI Mobility Radeon HD 5870。我在另一台具有不同 GPU 的计算机上进行了尝试(不幸的是,我不确定是什么 GPU,但它与我的不同),结果相同。任何想法为什么会这样?谢谢。

编辑:实际上它们看起来不是 0,更有可能它们是随机的大型未初始化值......很难说,因为我找不到任何调试 GLSL 着色器的方法。无论如何,一些更多的信息。这是我的顶点结构:

struct TileVertex {
    float pos[2];
    float uv[2];
    float width;
    float pad;
    int animFrames;
    int animFrameLength;
};

animFrames 和 animFrameLength 是我试图发送到着色器的两个整数值。我对 animFrames 的 glVertexAttribIPointer 的调用如下:

glVertexAttribIPointer( attribute.location, attribute.typeSize, attribute.baseType, (GLsizei)stride, bufferOffset( bufOffset + attribOffset ) );

地点:

attribute.location = 1 (as determined by OpenGL)
attribute.typeSize = 1 (since it's a single int, not a vector)
attribute.baseType = 5124, which is GL_INT
stride = 32, which is sizeof( TileVertex )
bufferOffset() converts to a void pointer relative to NULL
bufOffset = 0 (my vertices start at the beginning of the VBO), and
attribOffset = 24, which is the offset of animFrames in the TileVertex struct

编辑:感谢到目前为止的帮助。所以我尝试使用变换反馈,现在事情变得更有意义了。如果我将 int 属性的值设置为 1,在着色器中它是:

1065353216 = 0x3F800000 = 1.0 in floating point

如果我将它设置为 10,在着色器中我会得到:

1092616192 = 0x41200000 = 10.0 in floating point

所以看起来 int 属性被转换为浮点数,然后这些位在着色器中被解释为 int,即使我指定 GL_INT 并使用 IPointer 而不是 Pointer!据我了解,IPointer 应该只是将数据保留为整数形式,而不是将其转换为浮点数。

编辑:

这里还有一些测试。对于每个测试,我都尝试将整数值 1 传递给着色器中的整数输入:

glVertexAttribIPointer with GL_INT: shader values are 0x3F800000, which is 1.0 in floating point

似乎表明整数 1 被转换为浮点 1.0,然后被解释为整数。这意味着 OpenGL 要么认为源数据是浮点形式(实际上是整数形式),要么认为着色器输入是浮点形式(实际上是整数形式)。

glVertexAttribIPointer with GL_FLOAT: shader values are valid but weird floating point values, such as 0.0, 1.0, 4.0, 36.0... what the hell!?

不知道这意味着什么。我传递的唯一值是整数 1,所以我无法弄清楚为什么每个值会不同,或者为什么它们会是有效的浮点数!我尝试这样做的逻辑是,如果 OpenGL 将整数转换为浮点数,也许告诉它它们已经是浮点数会避免这种情况,但显然不是。

glVertexAttribPointer with GL_INT: same result as glVertexAttribIPointer with GL_INT

这是预期的结果。 OpenGL 将整数转换为浮点数,然后将它们传递给着色器。这是应该发生的,因为我没有使用 I 版本。

glVertexAttribPointer with GL_FLOAT: integer values 1 (the correct result)

这是因为 OpenGL 1) 认为源数据是浮点形式,2) 认为着色器输入也是浮点形式(它们实际上是 int 和 int),因此不应用任何转换,留下 int作为 int (或像它认为的那样浮动)。这行得通,但它似乎非常笨拙且不可靠,因为我认为不能保证 CPU 浮点到 GPU 浮点不需要转换(有些 GPU 不是使用 16 位浮点数吗?也许这只是 OpenGL 3 之前的版本,但是仍然) - 它只是不在我的 GPU 上。

【问题讨论】:

  • 给我们更多信息。向我们展示对 glVertexAttribIPointer 的调用,并向我们展示您尝试传递的数据。
  • 您可以通过使用变换反馈并将目标缓冲区读回主内存来调试顶点 GLSL 着色器。
  • 你的属性索引是 0 吗?您传递给 glVertexAttribIPointer 的第一个值?如果您手动将其分配给不同的值会发生什么?另外,如果您更新驱动程序会发生什么?你的卡支持 3.3(ATI 有驱动程序),但你得到的是 3.2,这表明它们已经过时了。
  • 我实际上传递了两个整数属性,因此其中至少一个不是索引 0。此外,使用 ATI HD 4870 的人告诉我他们遇到了同样的问题。现在我正在设置一个 3.2 的上下文,但我会在 3.3 中尝试它(无论如何,对于 3.2 没有特别的原因)。在更新驱动程序方面,这很可能是问题所在。不幸的是,每次我尝试更新时都会收到 BSOD 和锁定 - 有时甚至在安装过程中! >:(但这完全是一个不同的问题,我读到我必须先更新 VBIOS(这听起来真的很可怕)。我会再试一次并报告。
  • 天啊,我不是唯一一个......看到完全相同的东西:将假定的 int 值表示为浮点数的十六进制数字。

标签: opengl attributes integer glsl


【解决方案1】:

对于其中一个着色器(不记得是哪个),您需要使用varying 关键字。或者可能是 attribute 关键字。更高版本的 GLSL 使用 inout 代替。

我认为你需要:

attribute int name;

用于进入顶点着色器的数据,并且

varying int name;

用于从顶点着色器到片段着色器的数据。

还要确保使用glEnableVertexAttribArray 启用着色器属性。


我在让int 属性也工作时遇到了一些麻烦,但我发现type 字段(GL_INTGL_FLOAT 传递给glVertexAttribPointer 匹配传递给它的数据,而不是数据输入着色器)。所以我最终使用了glVertexAttribPointerGL_INT,它们将我主机上的int 转换为我的着色器中的float,这对我来说很好,因为我的属性是位置数据并且需要通过浮点转换@ 987654338@反正。

您可能需要glVertexAttribIPointerEXT 来匹配您的着色器int 属性,如果主机以int 数组的形式提供数据,则还需要GL_INT

【讨论】:

  • In-Out 由 glsl 1.5 引入,而属性已从 glsl 1.5 中弃用。
  • @Luca:谢谢,我使用的版本几乎不能直截了当,更不用说所有旧版本了。
  • @Luca:它们是在 1.30 中引入的。
  • Ops...确实如此(总是混淆这两个版本,叹息)
  • 我遇到了一个类似的问题,改成 glvertexattribIpointer 解决了这个问题。即使 normalize 参数为 GL_FALSE,GL_INT 也已标准化。 (Radeon 7850,深红色)
【解决方案2】:

我知道这个问题很老,但也许这些信息仍然有用:

GLintdefined 的大小为 32 位, 但是您在 C 中的 int 也可能是 64 位。

这让我调试太久了。

【讨论】:

    【解决方案3】:

    tl;博士:

    https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glVertexAttribPointer.xhtml

    glVertexAttribPointer 会将您的输入转换为浮点数,即使 normalized 参数是 false

    glVertexAttribIPointer 将只接受整数,并且没有 normalized 参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多