OpenGL灰度纹理作为浮动错误格式

Posted

技术标签:

【中文标题】OpenGL灰度纹理作为浮动错误格式【英文标题】:OpenGL grayscale texture as float wrong format 【发布时间】:2018-09-27 07:07:32 【问题描述】:

我得到了一个浮点值在 0.0 - 1.0 范围内的数组(高度图),但纹理返回黑色或只是红色我尝试了内部和源格式的多种组合,但似乎没有任何效果。我目前只给我一个红色纹理的代码是:

glGenTextures(1, &texure);
glBindTexture(GL_TEXTURE_2D, texure);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, w, h, 0, GL_RED, GL_FLOAT, data);

[编辑]图像输出: 有什么想法有什么问题吗?

【问题讨论】:

您是否尝试在每个命令后检查glGetError() 代码? 用上面的当前代码,没有没有错误。 但是您发布的图像看起来像一个高度图,您期望的输出到底是什么? 你在着色器代码中做了什么?如果您执行gl_FragColor = texture_color; 之类的操作,则绿色和蓝色通道将始终为0。您必须执行gl_FragColor = texture_color.rrra; 之类的操作您可以显示片段着色器吗? 【参考方案1】:

你必须设置texture swizzling参数,让OpenGL在查找纹理时从红色通道读取绿色和蓝色通道-见glTexParameteri

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED );

见OpenGL 4.6 API Compatibility Profile Specification; 16.1 Texture Environments and Texture Functions; page 595:

它们是通过计算 从过滤后的纹理值 Rt、Gt、Bt、At、Lt 和 It 中提取的基色 Cb 和 Ab 如表 16.1 所示,...

Texture Base Texture base color Internal Format    Cb              Ab
...
RED                                                (Rt, 0, 0)      1
RG                                                 (Rt, Gt, 0)     1
RGB                                                (Rt, Gt, Bt)    1
RGBA                                               (Rt, Gt, Bt)    At

表 16.1:过滤后的纹理组件与纹理基础组件的对应关系。

...然后混合 Cb 的组件,由纹理参数 TEXTURE_SWIZZLE_RTEXTURE_SWIZZLE_GTEXTURE_SWIZZLE_BTEXTURE_SWIZZLE_A 的值控制。如果TEXTURE_SWIZZLE_R的值用swizzler表示,则swizzling根据

计算Cs的第一个分量
if (swizzler == RED)
    Cs[0] = Cb[0];
else if (swizzler == GREEN)
    Cs[0] = Cb[1];
else if (swizzler == BLUE)
    Cs[0] = Cb[2];
else if (swizzler == ALPHA)
    Cs[0] = Ab;
else if (swizzler == ZERO)
    Cs[0] = 0;
else if (swizzler == ONE)
    Cs[0] = 1; // float or int depending on texture component type

如果您要使用着色器程序,则可以在片段着色器中执行类似的操作,Swizzling:

in vec3 uv;

out vec4 frag_color;

uniform sampler2D u_texture;

void main()

   frag_color = texture(u_texture, uv).rrra;

【讨论】:

谢谢。使用 swizzling 参数效果很好,因为我不想更改着色器代码,因为它是一个通用的纹理渲染着色器。【参考方案2】:

在 glTexImage2D 函数的第 7 次争论中,您假设设置图像的格式。您将其设置为 GL_RED。您应该将其设置为图片的格式,可能是 GL_RGB 或 GL_RGBA。

请阅读the documentation。

如果它不能与正确的纹理格式一起使用,则说明其他问题。虽然看不到其余代码是不可能的。

您确定您的数据加载正确吗? 您是否将正确的纹理坐标发送到片段着色器? 你记得设置活动纹理吗? 您是否将片段着色器中的 Sampler2D 设置为与活动着色器相同的值?

【讨论】:

我附加了一张图片来显示输出,但如果我使用 GL_RGB 或 GL_RGBA 会导致抛出异常。数据似乎正确,纹理坐标已标准化,活动纹理设置正确以进行渲染,着色器 2D 采样器也正确。 您是否尝试过使用不同的纹理。 JPG 图像往往是 RGB。请尝试为您知道确定为 RGB 的图像添加数据,看看它是否可以修复它。如果它引发“访问违规”,那么很可能是您没有使用正确的格式。

以上是关于OpenGL灰度纹理作为浮动错误格式的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL:当尺寸不能被 4 整除时,灰度纹理数据布局不匹配

为啥没有实现 OpenGL 灰度纹理性能增益?

将灰度 OpenCV 图像传递给 OpenGL 纹理

如何显示带有opengl纹理的灰度图像

opengl Framebuffer离屏到纹理,颜色错误

OpenGL中不用AUX库来加载BMP图片作为纹理