5

我正在尝试在着色器中上传带有未签名短裤的纹理,但它不起作用。

我尝试了以下方法:

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 获得的深度信息做一些操作并显示出来。

4

1 回答 1

11

你的论点glTexImage2D不一致。第 3 个参数 ( 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。(根据安东的建议添加的段落)

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

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

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

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

于 2014-05-01T15:14:45.953 回答