The loadPNGTexture creates an unsigned char array that is width * height
* 4 (rgba) and creates the texture from that data. Can anyone tell me why
it is not displaying anything?
thanks,
William
// initialization:
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtex);
glFlush();
//----------------------------------------------------------
texid = loadPNGTexture ("texture.png");
glEnable( GL_BLEND );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, texid );
glBegin(GL_QUADS);
glTexCoord2f (0.0, 0.0);
glVertex3f (lr.left, lr.bottom, z);
glTexCoord2f (1.0, 0.0);
glVertex3f (lr.right, lr.bottom, z);
glTexCoord2f (1.0, 1.0);
glVertex3f (lr.right, lr.top, z);
glTexCoord2f (0.0, 1.0);
glVertex3f (lr.left, lr.top, z);
glEnd();
glDisable( GL_TEXTURE_2D );
glDisable( GL_BLEND );
1) check for errors! Is texid valid?
2) does loadPNGTexture make the texture a power-of-two ?
3) You enabled blending but haven't set the QUADS color & alpha. You
probably want solid & white to start with.
4) (0.0) and (1.1) aren't proper texture coordinates. You'll be pulling in
the border (which is undefined here). Texture coordinates are cell-centered,
you need to shift "inwards" by 1/(2*width) and 1/(2*height) to get the
texture coordinates to be on the centers of the 1st & last texels.
for a start.
jbw
I added color to the quad. This same code works with my bmp file loader
(no alpha). The only difference is that I'm loading a .png file with an
alpha channel. I've checked for errors and there aren't any. The texid IS
valid. The clear color is set to (1,1,1,1). This is the white behind the
large rounded blue rectangle. The .png file is NOT a power of two, but
the .bmp image wasn't either and that works.
I put the image here so you can see it:
http://sites.google.com/site/bobslf/home/temp/screen.jpg
This is a summary of the code that produced the part of the image that I
asking about. The problem is that the texture does not appear on the
rectangle with the gray gradient.
glEnable( GL_TEXTURE_2D );
texid = ogl->loadPNGTexture ("test.png");
glBindTexture( GL_TEXTURE_2D, texid );
glBegin(GL_QUADS);
glTexCoord2f (0.0, 0.0);
glColor4f(0.0f, 0.0f, 0.0f, .5f);
glVertex3f (left, bottom, z);
glTexCoord2f (1.0, 0.0);
glColor4f(0.0f, 0.0f, 0.0f, .5f);
glVertex3f (right, bottom, z);
glTexCoord2f (1.0, 1.0);
glColor4f(1.0f, 1.0f, 1.0f, .5f);
glVertex3f (right, top, z);
glTexCoord2f (0.0, 1.0);
glColor4f(1.0f, 1.0f, 1.0f, .5f);
glVertex3f (left, top, z);
glEnd();
glDisable( GL_TEXTURE_2D );
glDisable( GL_BLEND );
Here are the texture generation lines:
glGenTextures (1, &textureImage.id);
glBindTexture (GL_TEXTURE_2D, textureImage.id);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, 4, textureImage.width,
textureImage.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, png.rgba );
I've tried other settings in place GL_DECAL, but nothing seems to make a
difference.
thanks,
Bob
It's not valid to call glTexImage2D( GL_TEXTURE_2D, 0, 4,
textureImage.width,
textureImage.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, png.rgba );
with width and/or height not being a power of two. You won't get the texture
data to load.
jbw
I changed the .png image to 512 x 128 and the result is the same.
The .bmp image is not a power of 2 and that works.
Bob
If the exact same sequence works for another image, then the source png
probably has 0 for alpha, right ?
-jbw
> 4) (0.0) and (1.1) aren't proper texture coordinates. You'll be pulling
> in the border (which is undefined here). Texture coordinates are
> cell-centered, you need to shift "inwards" by 1/(2*width) and
> 1/(2*height) to get the texture coordinates to be on the centers of the
> 1st & last texels.
It was a dumb thing. When I block-copied some code I didn't copy the part
that sets up the width and height. Those were 0. It works now. I thought
that since I had a valid texture id I had a valid image size. Non-power
of 2 images work and I didn't have to do the 1/(2*width) thing, probably
because I have a newer video card. Thanks for your help.
One last question relating to this. The image is only transparent
relative to the current color, not to what is under the full image
rectangle. I can get around that by setting the current color to the same
as the underlying object. So, if I set the color to red I see a red
background around the image where the alpha is 0. Is this the way it is
supposed to work? What if you have a complex image behind the
'transparent' image?
Bob
Bob,
the "1/(2*width)" thing isn't a function of newness -- it's a function of
correctness. Your image is improperly stretched, if you really think about
it.
Transparency is OpenGL isn't simple. You need to draw all your opaque stuff
1st -- the stuff "behind" the transparent texture has to be there when you
draw it. You may also want an alphafunction to not write to Z buffer when
alpha==0;
-jbw