Drawing multiple textures in layers

Started by
10 comments, last by jezham 15 years, 9 months ago
I've been drawing textures like this:

            glBindTexture(GL_TEXTURE_2D, this.textureId);
            glBegin(GL_QUADS);
            glTexCoord2f(0, heightRatio);
            glVertex2f(locationX, locationY);
            glTexCoord2f(widthRatio, heightRatio);
            glVertex2f(locationX + width, locationY);
            glTexCoord2f(widthRatio, 0);
            glVertex2f(locationX + width, locationY + height);
            glTexCoord2f(0, 0);
            glVertex2f(locationX, locationY + height);
            glEnd();



but I'm looking for a way to draw textures on top of textures. I'm trying to make it so you can see through the top texture(which is semi-transparent, with transparent parts) to the bottom texture. Obviously, drawing a solid quad on top of the bottom texture doesn't help(perhaps there is a way to make a transparent Quad?). So how would I draw a texture on top of an another texture? or is there some other method I can use to get the results i want? btw, this is 2D mode.
Advertisement
You should use an image format that supports alpha channels (TGA and PNG for example). Then you can paint in photoshop sections of the texture you want to be transparent and opaque. OpenGL blending will take care of the rest for you.

In terms of drawing multiple textures on top of each other, you may wish to look into using the multitexturing extension, as it's much faster than drawing a whole bunch of quads on top of each other (1 draw call as opposed to 2 or 3).
[size="1"]
Thanks for your reply.
The image I'm using already contains transparent, semi-transparent areas. That is the reason I see the white quad under the texture(otherwise i would see greenish-blue).

As for the multi-texturing extension, it seems not all hardware can use multi-texturing. It wouldn't matter anyway. I need more then just 1 or 2 texturing and I might need to texture different orders and times.
If 2D, then just use the alpha channel in your RGBA8 texture.

If the Z-coord is to be the same as where you want to splat the texture, then "glEnable(GL_POLYGON_OFFSET_FILL)", and adjust with "glPolygonOffset(-value0, -value1)" I'm currently using -7.0f, -1.0f with a close near clip. That will allow you to avoid z-fighting.
Are you saying that...if my image is transparent, then the Quad should also be transparent?

Because its not.
Take a look at Lesson22 over at NeHe. Scroll down to "// Load The Logo-Bitmaps", here a bitmap's red channel is copied in to your texture's alpha channel (together with the texture's RGB components = 32bits).

Btw, there doesn't seem any mention of "glBlendFunc" in this thread (you will in the link though)...guess we should have asked if you have GL_BLEND experience?
Thank you for your reply :).
First, I'm using SDL.Net, i should have mentioned before.

The blend i use is this:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

and to load the texture:
glTexImage2D(GL_TEXTURE_2D, 0, textureSurface.BytesPerPixel, textureWidth, textureHeight, 0, Gl.GL_RGBA, GL_UNSIGNED_BYTE, textureSurface.Pixels);

*textureSurface is an SDL surface

I don't think I'm explaining the problem clearly.
Here is the problem:

The surface is rendered on the Quad as it should. The surface it self keeps its transparency, meaning, I can see the white quad on the background, everything works fine.

However, when I render a second texture, I don't want the quad to show. Here is a screenshot of the problem:
http://img261.imageshack.us/my.php?image=opengltextestzs9.png (sorry don't know how to make a link).

The first texture is at (0,0), the second is at (32,32). I want it to so i can see through the second texture's transparent parts(which is all white).
I'm still not clear where you are storing the alpha data?

For example, in this image...
barrel + alpha
The alpha image to the right (just the red channel would be used if this was in Lesson22) will blend where the grey is, replace where white is, and ignore where black is.

The above method uses the same blendFunc as you. I don't use SDL, does textureSurface.Pixels contain RGBA?


As for links/tags...:)
Edit:
I researched more into the topic. From what I see, most people use color key to set the alpha.

Code:
        for( i = 0, j = 0; i < imageSize_RGB; i += 3, j += 4 )        {            // Does the current pixel match the selected color key?            if( pImage_RGB->data   == g_keyColor[0] &&                pImage_RGB->data[i+1] == g_keyColor[1] &&                pImage_RGB->data[i+2] == g_keyColor[2] )            {                pImage_RGBA[j+3] = 0;   // If so, set alpha to fully transparent.            }            else            {                pImage_RGBA[j+3] = 255; // If not, set alpha to fully opaque.            }            pImage_RGBA[j]   = pImage_RGB->data;            pImage_RGBA[j+1] = pImage_RGB->data[i+1];            pImage_RGBA[j+2] = pImage_RGB->data[i+2];        }


Here I see that it looks for the color, and if the current pixel is the colorkey, then makes it fully transparent. And then:

        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, pImage_RGB->sizeX, pImage_RGB->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, pImage_RGBA );


is used to create the texture with alpha.

So, at first, I also thought the problem was most likely texture.Pixels. However, then I tested by using byes instead of .Pixels. I created a byte array(which is a equivalent of "unsigned char" in C++) and used the byte array instead, like in the above code. I came up with the same results as i did before. Then I changed the alpha to 0 for all the pixels and tried again and I got just the white QUADS, on a black screen. Shouldn't the quads be transparent in this case?

I also made the whole image full solid(255), and it showed the original image:
Free Image Hosting at www.ImageShack.us

So from this, we can determine that it doesn't not have to do with texture.Pixels.

Perhaps.. I'm doing something wrong in the blending part >.<
Here is how i enable 2D drawing.
                    glPushAttrib(GL_ENABLE_BIT);                    glDisable(GL_DEPTH_TEST);                    glDisable(GL_CULL_FACE);                    glEnable(GL_TEXTURE_2D);                    /* This allows alpha blending of 2D textures with the scene */                    glEnable(GL_BLEND);                    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);                    glViewport(0, 0, Video.Screen.Width, Video.Screen.Height);                    glMatrixMode(GL_PROJECTION);                    glPushMatrix();                    glLoadIdentity();                    glOrtho(0.0, (double)Video.Screen.Width, (double)Video.Screen.Height, 0.0, 0.0, 1.0);                    glMatrixMode(GL_MODELVIEW);                    glPushMatrix();                    glLoadIdentity();                    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);


I've looked at many examples and I can't see a thing wrong.

btw, I know use:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, c);


where c is the byte array.

[Edited by - mr_mo on July 1, 2008 5:15:50 PM]
A couple of things are different than how I do it:

//remove this line
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

also
//change to this (note the added "8")
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, pImage_RGB->sizeX, pImage_RGB->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, pImage_RGBA );

This topic is closed to new replies.

Advertisement