23

I'm having an OpenGL texture that is binded to a simple quad.

My problem is: My texture is 128x128 pixels image. I'm only filling up about 100x60 pixels on that image, the other pixels are transparent. I saved it in a .png file. When I'm drawing, the transparent part of the binded texture is white.

Let's say I have a background. When I draw this new quad on this background I can't see the through the transparent part of my texture.

Any suggestions?

Code:

// Init code...
gl.glEnable(gl.GL_TEXTURE_2D);
gl.glDisable(gl.GL_DITHER);
gl.glDisable(gl.GL_LIGHTING);   
gl.glDisable(gl.GL_DEPTH_TEST);

gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE); 

// Drawing code...
gl.glBegin(gl.GL_QUADS);
gl.glTexCoord2d(0.0, 0.0);
gl.glVertex3f(0.0f, 0.0f, 0.0f);
gl.glTexCoord2d(1.0, 0.0);
gl.glVertex3f(1.0f, 0.0f, 0.0f);
gl.glTexCoord2d(1.0, 1.0);
gl.glVertex3f(1.0f, 1.0f, 0.0f);
gl.glTexCoord2d(0.0, 1.0);
gl.glVertex3f(0.0f, 1.0f, 0.0f);
gl.glEnd();

I've tried almost everything, from enabling blending to change to GL_REPLACE, however I can't get it to work.

Edit:

// Texture. Have tested both gl.GL_RGBA and gl.GL_RGB8.
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, (int)gl.GL_RGBA, imgWidth, imgHeight,
            0, gl.GL_BGR_EXT, gl.GL_UNSIGNED_BYTE, bitmapdata.Scan0);
genpfault
  • 51,148
  • 11
  • 85
  • 139
Curtain
  • 1,972
  • 3
  • 30
  • 51

3 Answers3

45

Check that your texture is of RGBA format, and enable blending and set the blending func:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

And draw the texture. If your texture is not RGBA, then there is no alpha and blending won't do anything.

EDIT: Since you posted your code, i can a spot a serious error:

glTexImage2D(gl.GL_TEXTURE_2D, 0, (int)gl.GL_RGBA, imgWidth, imgHeight,  0, gl.GL_BGR_EXT, gl.GL_UNSIGNED_BYTE, bitmapdata.Scan0);

You're telling GL that the texture has internalFormat RGBA, but the bitmap data has BGR format, so, no alpha from your texture data. This assumes alpha = 1.0.

To correct it, load your PNG with RGBA format and use GL_RGBA as internalFormat and format parameters for glTexImage2D.

Dr. Snoopy
  • 55,122
  • 7
  • 121
  • 140
  • Thanks for answer. Althought, it doesn't work. I change to RGBA format when I was loading the texture and enabled blending. – Curtain Mar 05 '11 at 20:01
  • @Julian Post more code then. Are you sure that the PNG contains transparency? Is it being loaded with alpha information? – Dr. Snoopy Mar 05 '11 at 20:22
  • @Matias: Yepp, pretty sure. Will edit my question with more code. EDIT: Updated question. And yes, I'm sure the .png contains transparency - tested in Photoshop. – Curtain Mar 05 '11 at 20:23
  • @Matias: Thanks for helping. Now, when I'm trying this, the window open for about 1 second and shuts down after that. `gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, imgWidth, imgHeight, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, bitmapdata.Scan0);` – Curtain Mar 05 '11 at 21:19
  • @Julian That means your bitmap data is not RGBA, but RGB (or BGR), so it doesn't contains any alpha channel information. Again, are you sure your image contains alpha information (transparency) and it's being loaded as such? – Dr. Snoopy Mar 05 '11 at 21:26
  • @Matias: I assuming it contains an alpha channel. Made in Photoshop with transparent option and saved as .png 8 bits. Then it would? Or? – Curtain Mar 05 '11 at 21:37
  • @Julian It should be a 32-bit PNG. – Dr. Snoopy Mar 05 '11 at 22:25
1

Also, should you render to a frame buffer and copy the result into a texture, check that the frame buffer has alpha turned on. For example when using osgViewer this can be achived by (do this before calling setUpViewInWindow):

osg::DisplaySettings *pSet = myviewer.getDisplaySettings();
if(pSet == NULL)
   pSet = new osg::DisplaySettings();
pSet->setMinimumNumAlphaBits(8);
myviewer.setDisplaySettings(pSet);

and under qt it should work with (from http://forum.openscenegraph.org/viewtopic.php?t=6411):

QGLFormat f;
f.setAlpha( true ); //enables alpha channel for this format
QGLFormat::setDefaultFormat( f ); //set it as default before instantiations
setupUi(this); //instantiates QGLWidget (ViewerQT)

Normally it is better to render directly into a frame buffer but I came alonge this while preparing some legacy code and in the beginning it was very hard to find this.

Oliver Zendel
  • 2,695
  • 34
  • 29
0

When I'm drawing, the transparent part of the binded texture is white.

That means your PNG-parser converted transparent regions to the value of white. If you want to render transparent layers with OpenGL you dont typically depend on texture-files to hold the transparency but instead use the GLBlendFunc(). More information here:

http://www.opengl.org/resources/faq/technical/transparency.htm

Bernd Elkemann
  • 23,242
  • 4
  • 37
  • 66
  • What do you mean by PNG-parser? – Curtain Mar 05 '11 at 20:02
  • I mean this: OpenGL doesnt itself have the capability to load PNG's, you have some function linked in your program loading the PNG. That function probably stores in an RGB-array, not an RGBA-array; and even if it does store the alpha value, you still have to set up the GLBlendFunc(), see my link and linked sites there. – Bernd Elkemann Mar 05 '11 at 20:11
  • When I try the blending stuff (tried before asking this question and tried again now) the whole quad (inclusive my texture) get "blended". – Curtain Mar 05 '11 at 20:23