无法获取在GLSL 1.5中工作的整数顶点属性

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法获取在GLSL 1.5中工作的整数顶点属性相关的知识,希望对你有一定的参考价值。

我正在使用带有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 attrib的值设置为1,则在着色器中它是:

1065353216 = 0x3F800000 = 1.0 in floating point

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

1092616192 = 0x41200000 = 10.0 in floating point

因此看起来int attrib被转换为float,然后这些位在着色器中被解释为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将int转换为浮点数,然后将它们传递给着色器。这是我应该发生的事情,因为我没有使用I版本。

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

这是有效的,因为OpenGL 1)认为源数据是浮点形式,2)认为着色器输入也是浮点形式(它们实际上是int和int),因此不应用任何转换,将int保留为int(或浮动,如它认为的那样)。这有效,但它看起来非常h​​acky和不可靠,因为我认为没有保证CPU浮动到GPU浮动不需要转换(不是一些GPU使用16位浮点数?也许这只是pre-OpenGL 3但是仍然) - 它不在我的GPU上。

答案

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

我想你需要:

attribute int name;

数据转到顶点着色器,和

varying int name;

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

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


我在使用int属性时遇到了一些麻烦,但我发现的是type字段(传递给GL_INTGL_FLOATglVertexAttribPointer与传递给它的数据相匹配,而不是着色器中的数据类型)。所以我最终使用glVertexAttribPointerGL_INT将我的主机上的int转换为我的着色器中的float,这对我来说很好,因为我的属性是位置数据,无论如何都需要通过浮点vec2进行转换。

可能你需要glVertexAttribIPointerEXT来匹配你的着色器int属性,然后还需要GL_INT,如果主机提供数据作为int数组。

另一答案

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

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

这让我调试的时间太长了。

以上是关于无法获取在GLSL 1.5中工作的整数顶点属性的主要内容,如果未能解决你的问题,请参考以下文章

如何在 GLSL 中使用 4x4 矩阵作为顶点属性?

sdcc 在 keil 中工作的代码上给出语法错误

Applescript 无法在 Mountain Lion 中工作的路径

GLSL 1.5 无法获得颜色输入

无法获得在 Propel2 中工作的外键

使用无法在 Safari 中工作的图像转换 SVG