2009-04-17 169 views
4

我试图加载RGBA值的纹理,但阿尔法值似乎使纹理更白,不调整透明度。我已经听说过关于3D场景的这个问题,但我只是使用OpenGL for 2D。无论如何,我可以解决这个问题吗?OpenGL Alpha值使纹理更白?

我初始化的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); 

截图: 那洗出疯疯癫癫的形象应该是半透明的。黑色的位应该是完全透明的。正如你所看到的那样,背后有一张未透露的图像。

生成该纹理的代码相当长,所以我将描述我所做的。它是一个类型为unsigned char的40 * 30 * 4数组。每第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字节vs 4字节)? GL_BGR即使在初始化时也能正常工作...

+0

对于包含截图的+1,在OpenGL问题中应该是必须的。 :) – unwind 2009-04-17 08:05:02

+0

是的,它现在变得更容易回答。 (我编辑了我的帖子,顺便说一句) – aib 2009-04-17 13:48:54

回答

4

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

的问题是,虽然我的装载功能是正确的,

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); 

其中需要指定正确的字节数(4 )。从我的理解你不能使用不同的字节数的SubImage,虽然我认为你可以使用不同的格式,如果它确实有相同数量的字节(即混合GL_RGBGL_BGA是好的,但不是GL_RGBGL_RGBA)。

1

在场景中是否有重叠的基元?

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

如果您可以张贴屏幕截图或以其他方式描述发生了什么,比如说绘制具有相同颜色和不同字母的两个图元时可能会有所帮助。事实上,任何代码都可以帮助解决问题。

编辑:

我想像,使用TexImage与GL_RGB(用于internalformat,第三个参数)创建了一个3分量的质感与隐式初始化到1没有alpha或α值,不管是什么样的您提供的像素数据。

GL_BGR对于这个参数不是一个有效的值,它可能是欺骗你的实现使用一个完整的4字节内部格式? (或按照GL_LUMINANCE_ALPHA的2字节)或者你的意思是通过GL_BGR你的Texture :: Load()函数,这应该不是真的不同于传递GL_RGB

0

我认为这应该有效,但它假定图像有一个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); 
}