Howdy all,
I just ran into something really weird (and incredibly annoying) with
textures and alpha channels. In my game, I've been using my own module to
load a 3D model from an ASCII file and load a texture for this object with
PIL (specifying the correct mode). The new object has an "update" function
that pushes the matrix, does any translations, binds the object's texture,
calls the object's display list, and pushes the matrix, thusly:
glPushMatrix()
glTranslate(self.x, self.y, self.z)
glBindTexture(GL_TEXTURE_2D, self.model.texture)
glCallList(self.model.displaylist)
glPopMatrix()
self.model is where the actual loading of the model and texture takes place,
and functions as a holder for these.
I have two basic types of objects.........one is a building, which uses a PNG
file with no alpha channel (so loading it from PIL, I use the 'RGBA' mode).
The other is my "ship", which uses alpha textures (RGBX mode). In the
initialization of the game, I first call my "ship" object, which contains an
update function essentially the same as the buildings object (aside from
translations, the actual per-cycle OpenGL code is 100% identical). I then
create some instances of the building object, with a non-alpha texture. I
create several instances of this object at various locations.
The problem is that my ship is not displaying with the alpha channel, it's
just solid 100% opacity. However, if, after loading the building objects on
initialization, I load another object with an alpha image/RGBX mode, the ship
displays with the alpha texture as it should! I don't even have to ever use
the new alpha object, all I have to do is load an object with an alpha
texture some time after loading all the non-alpha textured objects.
It's like the non-alpha textures "override" the alpha textures. Everything
works if I load an alpha object last during the initialization, but this sure
seems silly. I could also load my ship object last, but I want to know why
this is acting this way in the first place. The way I see it, there's no
connections between these two objects and OpenGL shouldn't care what the last
texture that it loaded was because the texture loading code starts from
scratch when loading the new texture. Any ideas?
-Matt Bailey
PS: Here's how I'm handling alpha vs non-alpha textures in my texture loader:
if mode == 'RGBX':
glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE,
image)
glBlendFunc(GL_ONE, GL_ZERO)
elif mode == 'RGBA':
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA )
glEnable(GL_BLEND)
glTexImage2D(GL_TEXTURE_2D, 0, 4, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE,
image)
As you can see, I'm making the same calls, just with different parameters, so
nothing should be left "turned on/off" from the last texture call. "image"
is an image loaded with PIL.
|