【问题标题】:OpenGL alpha value makes texture whiter?OpenGL alpha值使纹理更白?
【发布时间】:2009-04-17 00:56:20
【问题描述】:

我正在尝试加载具有 RGBA 值的纹理,但 alpha 值似乎只是使纹理更白,而不是调整透明度。我听说过 3D 场景存在这个问题,但我只是将 OpenGL 用于 2D。无论如何我可以解决这个问题吗?

我正在用

初始化 OpenGL
glViewport(0, 0, winWidth, winHeight);
glDisable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, winWidth, 0, winHeight); // set origin to bottom left corner
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(1, 1, 1);

截图: 那个褪色的点状图像应该是半透明的。黑色位应该是完全透明的。如您所见,它背后有一个图像没有显示出来。

生成该纹理的代码相当长,所以我将描述我所做的。它是一个 40*30*4 类型的 unsigned char 数组。每 4 个字符设置为 128(应该是 50% 透明,对吧?)。

然后我将它传递给这个函数,将数据加载到纹理中:

void Texture::Load(unsigned char* data, GLenum format) {
    glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, _texID);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _w, _h, format, GL_UNSIGNED_BYTE, data);
    glDisable(GL_TEXTURE_2D);
}

而且...我想我刚刚发现了问题。正在使用以下代码初始化全尺寸纹理:

glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, _texID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glDisable(GL_TEXTURE_2D);

但我猜 glTexImage2D 也需要是 GL_RGBA 吗?我不能使用两种不同的内部格式?或者至少不是不同大小的(3字节对4字节)? GL_BGR 即使像这样初始化也能正常工作...

【问题讨论】:

  • +1 包括屏幕截图,在 OpenGL 问题中应该是必须的。 :)
  • 是的,现在回答起来容易多了。 (顺便说一句,我已经编辑了我的帖子。)

标签: opengl textures


【解决方案1】:

为了他人的利益,我在这里发布我的解决方案。

问题是虽然我的Load函数是正确的,

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _w, _h, GL_RGBA, GL_UNSIGNED_BYTE, data);

我将 GL_RGB 传递给这个函数

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);

其中需要指定正确的字节数(四个)。据我了解,您不能为 SubImage 使用不同数量的字节,尽管我认为如果它确实具有相同的字节数(即混合 GL_RGB 和 @ 987654324@ 可以,但GL_RGBGL_RGBA 不行。

【讨论】:

    【解决方案2】:

    您的场景中是否有任何重叠的图元?

    您知道您正在调用 glColor 的 3 参数版本,它将 alpha 设置为 1.0,对吧?

    如果您可以发布屏幕截图或以其他方式描述会发生什么,例如,当您绘制两个具有相同颜色和不同 alpha 的图元时,这可能会有所帮助。事实上,任何演示该问题的代码都会有所帮助。

    编辑:

    我想使用带有GL_RGB 的 TexImage(对于 internalformat,第 3 个参数)会创建一个没有 alpha 或 alpha 值隐式初始化为 1 的 3 分量纹理,无论哪种类型您提供的像素数据。

    GL_BGR 不是此参数的有效值,也许它会欺骗您的实现使用完整的 4 字节内部格式? (或者一个 2 字节的字节,根据 GL_LUMINANCE_ALPHA)或者您的意思是将 GL_BGR 传递给您的 Texture::Load() 函数,这与传递 GL_RGB 应该没有什么不同?

    【讨论】:

    • 如果它诱骗它使用 4 字节的内部格式,那就没有问题了。我认为我最初使用 GL_RGB 的问题只是将其设置为 3 字节的内部格式,而我确实需要 4。我的意思是 GL_BGR 在我的加载函数中工作,即使我在 glTexImage2D 中使用 GL_RGB 也是如此。我认为只有将正确的字节数传递给 glTexImage2D 才重要。如果我只是通过了“4”,可能就不会那么模棱两可了。
    【解决方案3】:

    我认为这应该可行,但它假设图像具有 Alpha 通道。如果您尝试加载没有 alpha 通道的图像,您将收到异常或您的应用程序可能会崩溃。对于非 Alpha 通道图像,在设置 GL_UNSIGNED_BYTE 之前,在第二个参数上使用 GL_RGB 而不是 GL_RGBA

    void Texture::Load(unsigned char* data) {
      glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, _texID);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
      glDisable(GL_TEXTURE_2D);
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-08
      • 2011-01-11
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多