我有一个强度值的 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 编号*