0

我有一个强度值的 int 缓冲区,我想在 OpenGL 中将其显示为灰度/颜色映射图像。

实现这一目标的最佳方法是什么?

标准纹理?

我可以通过标准的 glTexture 来做到这一点,比如:

gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_R32f, width, height, 0, OpenGL.GL_RED_INTEGER, OpenGL.GL_UNSIGNED_INT, pixels);

在着色器中,我的印象是我会像使用任何其他纹理一样使用它,除了我会使用 usampler2D 而不是 sampler2D,此时我会得到真正的整数值(即不是 0-1 范围)。

TBO?

或者通过 TBO 实现并执行以下操作会更好:

gl.TexBuffer(OpenGL.GL_TEXTURE_BUFFER, OpenGL.GL_R32F, bufferID);

就着色器而言,我实际上很困惑。我见过像 g = texelFetch(u_tbo_tex, offset + 1).r 这样的东西。. 所以我猜我必须将纹理坐标转换为偏移量,例如:

int offset = tex_coord.s + (tex_coord.t * imageWidth);

但随后 texelFetch 实际上返回一个 vec4,所以大概我会使用:

int intensity = texelFetch( buffer,  offset).r 

但是由于 tex_coord.s & t 在 0-1 中,这意味着需要:

int offset = tex_coord.s*imageHeight + ((tex_coord.t * imageWidth) * imageWidth);

其他缓冲区

我对缓冲区对象的经验很少,我觉得我所做的只是在 GL 中使用缓冲区……所以我确实觉得我把它复杂化了,我错过了“一分钱一滴”。

重要笔记

  • 为什么是 Int?:在某些情况下,我会在转换成颜色之前对数据进行一些操作,并且更愿意以 32 位精度执行此操作以避免潜在的精度错误。可以说它可能不会有所作为,因为它最终会成为屏幕颜色......
  • 数据更新频率:强度数据偶尔由用户事件更新,但肯定不是每帧多次更新(所以我假设在这种情况下STATIC比DYNAMIC更合适?)
  • 用途:数据主要用于 GL 所以 _DRAW 应用程序可能会利用 GL 为其计算一些值,但在这种情况下我可能会创建一个单独的 READ 缓冲区
  • 到目前为止,我看到的最高整数值是“90,000”,所以我知道它超出了 16 位整数范围。

注意:我通过 SharpGL 执行此操作,目前无法测试,因为它没有 GL_R32f 的定义,所以我必须在我的 Windows 平台上找到 gl.h(总是很有趣)并添加正确的 const 编号*

4

1 回答 1

1

您可以使用具有整数/无符号整数格式的普通纹理:

 gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_R32UI, width, height, 0, OpenGL.GL_RED_INTEGER, OpenGL.GL_UNSIGNED_INT, pixels);

在着色器中,您可以使用 usampler2D,因为纹理函数对此有重载,您可以直接获取整数值:

 uniform usampler myUTexture;
 uint value = texture(myUTexture, texCoord).r;

编辑:只是为了完整性:texelFetch 也有所有类型的 2d-sampler 的重载。纹理和 texelFetch 之间的区别在于使用的坐标系([0,1] 用于纹理和 texelFetch 的像素坐标),并且 texelFetch 不考虑任何插值/mipmap。

于 2014-11-06T12:15:25.183 回答