我有 3072 个 std::int16_t
类型的值(16 位整数),对应于 GLshort
。我想将它们发送到我的 GLSL 着色器。我读了 Buffer Textures并尝试实现该方法。但是,一旦数据到达着色器,数据似乎就不再完整了。我还不确定,但看起来这些值都是 0
或已最大化。我做错了什么?
我的初始化代码如下所示(排除一些不相关的内容):
// 1: Get the data - array of GLshort:
GLshort tboData[3072];
for (size_t i = 0; i < 3072; ++i)
{
// cdb.getSprite() returns std::int16_t
tboData[i] = (GLshort) cbd.getSprite(i);
}
// 2: Make sure the Shader Program is being used:
sp->use(); // sp is a wrapper class for GL Shader Programs
// 3: Generate the GL_TEXTURE_BUFFER, bind it and send the data:
GLuint tbo;
glGenBuffers(1, &tbo);
glBindBuffer(GL_TEXTURE_BUFFER, tbo);
glBufferData(GL_TEXTURE_BUFFER, sizeof(tboData), tboData, GL_STATIC_DRAW);
// 4: Generate the Buffer Texture, activate and bind it:
GLuint tboTex;
glGenTextures(1, &tboTex);
glActiveTexture(GL_TEXTURE1); // GL_TEXTURE0 is a spritesheet
glBindTexture(GL_TEXTURE_BUFFER, tboTex);
// 5: Associate them using `GL_R16` to match the 16 bit integer array:
glTexBuffer(GL_TEXTURE_BUFFER, GL_R16, tbo);
// 6: Make the connection within the Shader:
glUniform1i(sp->getUniformLocation("tbo"), 1);
glBindBuffer(GL_TEXTURE_BUFFER, 0);
在我的渲染循环开始时,我确保一切都已绑定(bind):
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, spriteSheet);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER, tboTex);
在我的渲染循环中,我设置了一个将用于索引 TBO 的制服:
glUniform1i(sp->getUniformLocation("tboIndex"), tboIndex);
现在,顶点着色器的重要部分:
#version 140
// other ins, outs, uniforms ...
uniform int tboIndex;
uniform isamplerBuffer tbo;
out float pass_Sprite; // Frag shader crashes when this is int, why?
void main()
{
// gl_Position, matrices, etc ...
pass_Sprite = texelFetch(tbo, tboIndex).r;
}
欢迎提出任何建议。
最佳答案
GL_R16
这是一个未签名的 normalized integer 格式。您的缓冲区采样器需要带符号的非规范化整数。
correct image format将是 GL_R16I
。
Frag shader crashes when this is int, why
可能是因为您没有使用 flat
interpolation .插值不适用于非浮点值。
而且它不会崩溃;它根本无法编译。您应该始终检查着色器中的编译错误。
关于c++ - 如何通过缓冲区纹理正确地将 16 位整数发送到 GLSL 着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39131610/