【问题标题】:Rendering a grayscale texture with glBlitFramebuffer使用 glBlitFramebuffer 渲染灰度纹理
【发布时间】:2026-01-13 16:45:01
【问题描述】:

我想在屏幕上渲染一个纹理。对于 RGB 和 RGBA 图像 以下代码工作正常:

GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_data); // or GL_RGBA for RGBA images
glGenerateMipmap(GL_TEXTURE_2D);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
GLuint fboId = 0;
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboId);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, width, height, 0, height, width, 0,  GL_COLOR_BUFFER_BIT, GL_NEAREST);

这工作正常,图像按预期呈现。 但是,如果我想渲染灰度图像,我已经尝试过调配:

...
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, image_data);
GLint swizzleMask[] = {GL_RED, GL_RED, GL_RED, GL_RED};
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);

但是渲染的纹理总是红色的。是不是我做错了什么?

【问题讨论】:

    标签: c++ opengl rendering


    【解决方案1】:

    Swizzles 在返回到着色器之前应用于纹素的组件。这意味着它会在查找纹理时应用于纹素(例如查看texture)。但是,glBlitFramebuffer 是一个复制操作。 Swizzles 不适用于复制操作。

    【讨论】:

    • 有没有办法绕过它来显示灰度图像?
    • @Anima Blitting 不是“渲染”。如果要渲染,请使用 GL 绘制调用。您通常希望在片段着色器中绘制一个四边形并从纹理中采样。