32位(int)缓冲区到OpenGL中的灰度/彩色映射图像,单通道32位纹理还是TBO?

时间:2014-11-06 11:21:49

标签: opengl textures sharpgl

我有一个强度值的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(总是很有趣)并添加正确的常数*

1 个答案:

答案 0 :(得分: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采样器的重载。纹理和texelFetch之间的区别在于使用的坐标系(纹理的[0,1]和texelFetch的像素坐标),并且texelFetch不考虑任何插值/ mipmap。