我可以将浮动和整数打包到同一个数组缓冲区吗?

时间:2012-02-04 23:12:08

标签: opengl glsl

...因为浮标似乎很好,但是整数有问题。

基本上我有一个名为“BlockInstance”的结构,它包含vec3int。我有一个这样的BlockInstances数组,我这样缓冲(为了清晰起见,从C#转换为C):

glBindBuffer(GL_ARRAY_BUFFER, bufferHandle);
glBufferData(GL_ARRAY_BUFFER, sizeof(BlockInstance)*numBlocks, blockData, GL_DYNAMIC_DRAW);
glVertexAttribPointer(3,3,GL_FLOAT,false,16,0);
glVertexAttribPointer(4,1,GL_INT,false,16,12);
glVertexAttribDivisor(3,1);
glVertexAttribDivisor(4,1);

我的顶点着色器看起来像这样:

#version 330

layout (location = 0) in vec3 Position;
layout (location = 1) in vec2 TexCoord;
layout (location = 2) in vec3 Normal;
layout (location = 3) in vec3 Translation;
layout (location = 4) in int TexIndex;

uniform mat4 ProjectionMatrix;

out vec2 TexCoord0;

void main()
{
    mat4 trans = mat4(
        1,0,0,0,
        0,1,0,0,
        0,0,1,0,
        Translation.x,Translation.y,Translation.z,1);
    gl_Position = ProjectionMatrix * trans * vec4(Position, 1.0);
    TexCoord0 = vec2(TexCoord.x+TexIndex,TexCoord.y)/16;
}

当我用我的GLSL着色器的最后一行上的TexIndex替换为0,1或2这样的常量时,我​​的纹理很好,但是如果我把它留下来就像它一样,它们会全部被破坏,所以这个数字一定有问题吧?但是我不知道它会发生什么,所以很难调试。

我查看了我的BlockInstances数组,它们都被设置为1,2或19,所以我认为我的输入不对...

还有什么呢?


请注意,我正在使用精灵地图纹理,其中每个图块都是16x16像素,但我的TexCoords在0-1范围内,所以我添加一个整数来选择哪个图块,然后将其除以16(地图也是16x16瓷砖)将其放回适当的范围。我的想法是用

替换最后一行
TexCoord0 = vec2(TexCoord.x+(TexIndex%16),TexCoord.y+(TexIndex/16))/16;

- GLSL做整数数学,对吧? int除以int将作为整数出现?


如果我试试这个:

TexCoord0 = vec2(TexCoord.x+(TexIndex%16),TexCoord.y)/16;

纹理看起来很好,但它没有使用正确的精灵。 (看起来正在使用第一个精灵)

如果我这样做:

TexCoord0 = vec2(TexCoord.x+(TexIndex%16),TexCoord.y+(TexIndex/16))/16;

全白了。这让我相信TexIndex是一个非常大的数字(无论如何都大于256),并且它可能是16的倍数。

1 个答案:

答案 0 :(得分:6)

layout (location = 4) in int TexIndex;

有你的问题。

glVertexAttribPointer用于发送将转换为浮点值的数据。它用于提供浮点属性。传递整数是可能的,但是这些整数被转换为浮点数,因为这是glVertexAttribPointer的用途。

您需要的是glVertexAttribIPointer(请注意)。这用于提供有符号和无符号整数数据。

因此,如果您将顶点着色器输入声明为float或某些非前缀vec,则可以使用glVertexAttribPointer来提供它。如果您将输入声明为intuintivecuvec,则使用glVertexAttribIPointer