如何在opengl着色器中使用unsigned short?

时间:2014-05-01 12:52:29

标签: c opengl glsl glteximage2d

我尝试在着色器中上传带有未签名短片的纹理,但它无效。

我尝试了以下内容:

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, vbt[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 640, 480, 0, GL_RED, GL_UNSIGNED_SHORT, kinect_depth);
glUniform1i(ptexture1, 1);
GLenum ErrorCheckValue = glGetError();

我知道我正确地绑定了纹理,因为我使用

得到了一些结果
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, vbt[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 640, 480, 0,
    GL_RG, GL_UNSIGNED_BYTE, kinect_depth);
glUniform1i(ptexture1, 1);
GLenum ErrorCheckValue = glGetError();

特别是,我在红色通道中获得了部分值。我想将纹理上传为无符号字节或浮点数。但是,我没有设法正确地获得glTexImage2D调用。此外,是否可以使用深度纹理类似的东西?我想对从kinect获得的深度信息进行一些操作并显示它。

1 个答案:

答案 0 :(得分:9)

您对glTexImage2D的论点不一致。第三个参数(GL_RGB)表明你想要一个3组件纹理,第7个(GL_RED)表示单组件纹理。然后你的另一次尝试使用GL_RG,这表示有2个组件。

您需要使用存储无符号短裤的内部纹理格式,例如GL_RGB16UI

如果您想要一个组件,您的通话将如下所示:

glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, 640, 480, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, kinect_depth);

如果您需要三个组件:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 640, 480, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, kinect_depth);

您还需要确保着色器中用于采样纹理的类型与纹理中存储的数据类型相匹配。在此示例中,由于您使用包含无符号整数值的2D纹理,因此您的采样器类型应为usampler2D,并且您希望存储采样操作的结果(着色器中texture()调用的结果)在uvec4类型的变量中。 (根据Andon的建议添加的段落)

关于glTexImage2D的格式/类型参数的更多背景知识,因为这是相当频繁的误解的来源:

第三个参数( internalFormat )是OpenGL实现将在纹理中存储的数据格式(或者如果硬件不支持确切的格式,则至少是最接近的数据),以及从纹理中采样时将使用的。

最后3个参数(格式类型数据)属于一起。 格式类型描述了数据中的内容,即它们描述了您传递到glTexImage2D来电的数据。

保持两种格式匹配是一个好主意。与此情况类似,您传入的数据为GL_UNSIGNED_SHORT,内部格式GL_R16UI包含无符号短值。在OpenGL ES中,内部格式需要匹配格式/类型。完整的OpenGL会在必要时进行转换,出于性能原因这是不合需要的,而且通常也不是你想要的,因为纹理中数据的精度与原始数据的精度不一样。