c++ - 如何通过缓冲区纹理正确地将 16 位整数发送到 GLSL 着色器

标签 c++ opengl glsl buffer

我有 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/

相关文章:

c - GLSL 布局属性编号

javascript - 这些顶点如何最终位于剪辑坐标(-1,1) 中?

javascript - 你如何在 glsl/webgl 中将一个 32 位的整数打包成 4 个、8 位的整数?

c++ - 如何在延迟着色系统中实现光遮挡?

c++ - 这是在 C 或 C++ 中生成随机字节数组的好方法吗?

c++ - 创建基本的 OpenGL 上下文

c++ - 使用单 channel 纹理(OpenGL 2)?

c++ - mac 中的 glTexParameteri 段错误

c++ - C++ 桌面应用程序中的 Google Analytics

c++ - 类指针本身有类成员吗?