【问题标题】:How to properly send 16 bit integers to GLSL Shaders via Buffer Texture如何通过缓冲区纹理将 16 位整数正确发送到 GLSL 着色器
【发布时间】:2016-08-24 19:30:07
【问题描述】:

我有 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);

在我的渲染循环开始时,我确保所有内容都已绑定:

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;
}

欢迎任何建议。

【问题讨论】:

    标签: c++ opengl glsl buffer


    【解决方案1】:

    GL_R16

    这是一个未签名的 normalized integer 格式。您的缓冲区采样器需要有符号的非规范化整数。

    correct image format 将是 GL_R16I

    当这是 int 时 Frag 着色器崩溃,为什么

    可能是因为您没有使用flat interpolation。插值不适用于非浮点值。

    而且它不会崩溃;它根本无法编译。您应该始终检查着色器中的编译错误。

    【讨论】:

    • 首先,你太棒了。其次,现在一切都说得通了!在链接的 wiki 页面上,我认为图像格式表中的“NORM”列会告诉我们驱动程序/硬件是否支持图像格式必须。现在我明白它的意思是规范化。另外,我完全错过了ushort 中的u,愚蠢的我。此外,您对着色器“崩溃”的看法是正确的,这只是一种简化。事实上,它只是不编译。我将研究平面插值,但是您链接的页面确实不包含任何信息。无论如何,非常感谢!
    猜你喜欢
    • 2013-05-06
    • 2016-08-06
    • 1970-01-01
    • 2013-06-13
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多