Why are black pixels in my texture displayed as transparent?

The texture I’m using has some black lines on it. They are displayed as transparent when I want them to be opaque.

The texture is loaded using:

        url = c1.getResource( "com/thinkastronomy/galaxyin3d/Globular3D.png" );
        globularTexture = TextureIO.newTexture( url, false, "png" );
        globularTexture.bind();
        gl.glTexEnvi( GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE );

That last line was an attempt get the transparency eliminated. Didn’t work.

This is how things are set up in the init() method:

     gl.glShadeModel( GL.GL_SMOOTH );
    // Set the background / clear color.
    gl.glClearColor( 0.0F, 0.0F, 0.0F, 1.0F );
    // Clear the depth
    gl.glClearDepth( 1.0 );
    // Disable depth testing.
    gl.glDisable( GL.GL_DEPTH_TEST );
    // Enable blending and specify blending function.
    gl.glEnable( GL.GL_BLEND );
    gl.glBlendFunc( GL.GL_SRC_ALPHA, GL.GL_ONE );
    // Get nice perspective calculations.
    gl.glHint( GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST );
    // Nice point smoothing.
    gl.glHint( GL.GL_POINT_SMOOTH_HINT, GL.GL_NICEST );
    // Enable texture mapping.
    gl.glEnable( GL.GL_TEXTURE_2D );

    gl.glDepthMask( false );

What am I missing here? Thanks.

Bill

As a followup, I did find that if I set

gl.glBlendFunc( GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA );

rather than

gl.glBlendFunc( GL.GL_SRC_ALPHA, GL.GL_ONE );

Then my black pixels are drawn black. However this messes up some other drawing, so I need to set and restore this mode in various places. Still not sure I understand why this would be necessary. The src alpha for the black pixels is 1.0.

At the point where you’re drawing your texture, do you really need the blending? Does the texture have transparant parts? If not, I think it would actually improve performance if you disabled blending. I believe the most common way to handle transparency, is to draw all opaque textures first (with blending disabled), and then draw your transparent surfaces, ordered from back to front.

What happens inside your TextureIO.newTexture() method ? Maybe you specify your texture as having a funky alpha channel?

Yes, there are transparent parts. In this case, the object is a type of non-rectangular sprite. The .png image has the pixels outside the true displayed pixels set to transparent.

I thought transparency was a type of blending? Can you display an image with transparent parts without using blending?

I have seen this back to front drawing recommendation several places. I thought this was what OpenGL was supposed to do for you.

Let me explain a bit about what I’m doing. This is for a visualization of out Galaxy and obects around it. The image of the galaxy is created by texture mapping a circle. It should be partially transparent. The objects are globular clusters (balls of stars) but I just use a stylized representation using a non-rectangular sprite. The sprite itself is opaque other than the transparent pixes that make it non-rectangular.

As the galaxy is rotated the clusters behind it should partially show through. The one’s in front should, of course, be fully visible.

Following an example in a particle system I found, I have turned off depth testing. This probably explains why all the globulars are currently drawn in front of the galactic image. I did try enabling depth testing, but the galactic image wasn’t drawn correctly then. As you rotated if you would get all sorts of black patches on it. These were unrelated to the locations of the clusters.

[quote]What happens inside your TextureIO.newTexture() method ? Maybe you specify your texture as having a funky alpha channel?
[/quote]
The TextureIO.newTexture() method is a JOGL method. I’m not doing anything funky since it is not my code.

First off, let me start by saying I’m not very good in OpenGL myself. My only blending experiment dates 6 years back ::slight_smile:

Ah, so you’re set on displaying your galaxy as solid geometry, with a transparent texture? :slight_smile:
Maybe you’ll find this tutorial useful. On the webpage, all explanation is done for C++, but you can also find JOGL code at the end.

http://nehe.gamedev.net/lesson.asp?index=02

look for the chapter about “blending”. But personally, I would recommend you to take a good hard look at the next chapter, about moving bitmaps in 3D space. I think your galaxy will look more realistic that way.

PS: the reason you have to draw the “opaque” textures first, in any order, is because they require depth testing to be enabled, and depth writing should be enabled as well.
The reason you have to draw the transparent textures afterwards, ordered by distance, is exactly because depth testing is still enabled, but depth writing should be disabled. This means openGL will no longer do (some of) the work for you.

bahuman,

I’ve previously looked at those pages. Doesn’t look like there is much there I haven’t already figured out. I already billboard the images as suggested in lesson 10. Thanks for the sggestions though.

I’ve been experimenting with turning depth testing on to draw the galaxy. I got rid of the weird garbage when rendering the the galactic image at non-zero rotations. I did this by changed from texturing a circle using gluDisk() to texturing a quad. However now the image doesn’t display at all at certain angles (just all black). Not sure if this is some bug in JOGL or something about Mac OS X. Anyway, I’m rapidly becoming frustrated .

FWIW, I figured out why my textured quads where displaying improperly when rotated. Out of pure desperation I changed

    glu.gluPerspective( 20.0, ratio, 0.0, 100000.0 );

to

    glu.gluPerspective( 20.0, ratio, 0.1, 100000.0 );

and it started working . Not sure why having a “nearest” parameter of 0 causes it to glitch out, but it does.

Generally, you want your “near” plane to be as far from you as possible, and your “far” plane as near as possible. I’m surprised a near plane at 0.0 even works :o

Some of the other garbage might be a result from your HUGE frustrum as well. Try pushing the near plane even further, and bring the far plane a LOT closer. See if that helps. If you like a stronger perspective distortion, you could also make your view angle a bit bigger. Say, 60.0 instead of 20.0. This will make everything look “further away”, because your zoom is less strong. It may allow you to bring your camera a little closer to the object, and move your far plane closer as well. Also try to figure out the size of your depth test buffer. Is it a 12, 16, 32 bit depth test buffer?