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

mpe*_*pen 1 opengl glsl

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

基本上我有一个名为"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);
Run Code Online (Sandbox Code Playgroud)

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

当我用TexIndex我的GLSL着色器的最后一行用0,1或2这样的常量替换时,我的纹理很好,但是如果我把它留下来就好了,它们都会出现问题,所以一定有问题这个数字吧?但我不知道它出现了什么,所以很难调试.

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

还有什么呢?


请注意,我正在使用精灵地图纹理,其中每个图块都是16x16像素,但我的TexCoords在0-1范围内,所以我添加一个整数来选择哪个图块,然后将其除以16( map也是16x16 tile),把它放回到合适的范围内.我的想法是用最后一行代替

TexCoord0 = vec2(TexCoord.x+(TexIndex%16),TexCoord.y+(TexIndex/16))/16;
Run Code Online (Sandbox Code Playgroud)

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


如果我试试这个:

TexCoord0 = vec2(TexCoord.x+(TexIndex%16),TexCoord.y)/16;
Run Code Online (Sandbox Code Playgroud)

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

如果我这样做:

TexCoord0 = vec2(TexCoord.x+(TexIndex%16),TexCoord.y+(TexIndex/16))/16;
Run Code Online (Sandbox Code Playgroud)

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

Nic*_*las 6

layout (location = 4) in int TexIndex;
Run Code Online (Sandbox Code Playgroud)

这是你的问题.

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

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

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