...因为浮标似乎很好,但是整数有问题。
基本上我有一个名为“BlockInstance”的结构,它包含vec3
和int
。我有一个这样的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的倍数。
答案 0 :(得分:6)
layout (location = 4) in int TexIndex;
有你的问题。
glVertexAttribPointer
用于发送将转换为浮点值的数据。它用于提供浮点属性。传递整数是可能的,但是这些整数被转换为浮点数,因为这是glVertexAttribPointer
的用途。
您需要的是glVertexAttribIPointer
(请注意我)。这用于提供有符号和无符号整数数据。
因此,如果您将顶点着色器输入声明为float
或某些非前缀vec
,则可以使用glVertexAttribPointer
来提供它。如果您将输入声明为int
,uint
,ivec
或uvec
,则使用glVertexAttribIPointer
。