OpenGL alpha 值使纹理更白?

mpe*_*pen 5 opengl textures

我正在尝试加载具有 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);
Run Code Online (Sandbox Code Playgroud)

截屏: 那个褪色的点图像应该是半透明的。黑色部分应该是完全透明的。正如您所看到的,它后面有一个图像没有显示出来。

生成该纹理的代码相当冗长,因此我将描述我所做的事情。这是一个 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);
}
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)

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

mpe*_*pen 5

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

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

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _w, _h, GL_RGBA, GL_UNSIGNED_BYTE, data);
Run Code Online (Sandbox Code Playgroud)

我将 GL_RGB 传递给这个函数

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
Run Code Online (Sandbox Code Playgroud)

其中需要指定正确的字节数(四)。根据我的理解,您不能对 SubImage 使用不同的字节数,尽管我认为如果它确实具有相同的字节数,您可以GL_RGB使用不同的格式(即混合和GL_BGA可以,但不能使用GL_RGBGL_RGBA)。