如何在OpenGL中使纹理透明?

5

我试着在Google上研究了一下,但似乎没有任何连贯的简单答案。这是因为它不简单,还是因为我没有使用正确的关键词?

尽管如此,这是我迄今为止取得的进展。

  1. 创建了8个顶点以形成2个正方形。
  2. 创建了一个具有200位alpha值(大约80%透明)的纹理。
  3. 将相同的纹理分配给每个正方形,显示正确。
  4. 注意到当我使用255 alpha的纹理时,它看起来更亮。

初始化类似于以下内容:

glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);

glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, textureIds);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

int i, j;
GLubyte pixel;
for (i = 0; i < TEXTURE_HEIGHT; i++)
{
    for (j = 0; j < TEXTURE_WIDTH; j++)
    {
        pixel = ((((i & 0x8) == 0) ^ ((j & 0x8) == 0)) * 255);
        texture[i][j][0] = pixel;
        texture[i][j][1] = pixel;
        texture[i][j][2] = pixel;
        texture[i][j][3] = 200;
    }
}

glBindTexture(GL_TEXTURE_2D, textureIds[0]);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_RGBA,
    TEXTURE_WIDTH, TEXTURE_HEIGHT,
    0, GL_RGBA, GL_UNSIGNED_BYTE, texture);

这与书籍《OpenGL编程指南》417页的代码片段有些相似,可以创建一个检查图案。

然后,display函数包含...

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);

// Use model view so that rotation value is literal, not added.
glMatrixMode(GL_MODELVIEW);
glPushMatrix();

// ... translation, etc ...

glBindTexture(GL_TEXTURE_2D, textureIds[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, +1.0, 0.0); // top left
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0); // bottom left
glTexCoord2f(1.0, 1.0); glVertex3f(+1.0, -1.0, 0.0); // bottom right
glTexCoord2f(1.0, 0.0); glVertex3f(+1.0, +1.0, 0.0); // top right
glEnd();

    // not neccecary to repeat, just good practice
glBindTexture(GL_TEXTURE_2D, textureIds[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, +1.0, -1.0); // top left
glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, -1.0, -1.0); // bottom left
glTexCoord2f(1.0, 1.0); glVertex3f(+1.5, -1.0, -1.0); // bottom right
glTexCoord2f(1.0, 0.0); glVertex3f(+1.5, +1.0, -1.0); // top right
glEnd();

glFlush();
glDisable(GL_TEXTURE_2D);

glPopMatrix();

SwapBuffers();

所以,这在背景中呈现了第二个正方形;我可以看到这一点,但它看起来像它们与背景混合在一起(我假设这是因为它们的 alpha 值为 200 比特比 255 比特更暗),而不是纹理在后面...

Transparent textures not working

正如您所看到的,没有透明度... 我该怎么解决这个问题?


你在那个循环中两次使用了TEXTURE_HEIGHT而不是TEXTURE_WIDTH。 - shoosh
啊,谢谢,但这无关紧要,因为它们都是64。 - Nick Bolton
1个回答

9
通常,为了使alpha混合正常工作,您需要按照相机坐标系中的远近对对象进行排序。这就是为什么您的多边形与背景混合在一起的原因。您可以通过禁用深度测试来确认这确实是问题所在。没有深度测试,所有片段都会显示出来,您将能够看到alpha混合效果。
更多相关信息请参见此页面

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接