Problems with Alpha Blending

Started by
1 comment, last by turel777 15 years, 4 months ago
Hi, I'm trying to create billboarded trees for an assignment and part of this is using textures with an alpha channel. I've created the billboard effect and textured the trees but for soem reason only objects drawn before the tree are visisble through the transparent sections. Does any one know why that might happen? Here's a picture of the effect: alpha problem As you can see the tree in the background isnt visible though the closer tree, although the track, floor, skydome etc are visible through it. Here's my draw method for my tree:

	glPushMatrix();
		
		if(Texture() != -1){
			Textures::ApplyTexture(Texture());	
			glEnable(GL_TEXTURE_2D);
		}

		CylindricalBillboard::billboardBegin();

		GraphicObject::Material().apply();

		glNormal3f(0,0,1);

		glEnable(GL_BLEND);
		glBegin(GL_TRIANGLE_STRIP);

		for(float i = 0.0f; i <= 4; i++){
			glTexCoord2d(0.0, i/4); glVertex3f(0.0f, i, 0.0f);   
			glTexCoord2d(1.0, i/4); glVertex3f(2.0f, i, 0.0f);    
		}
		glEnd();
		glDisable(GL_BLEND);

		if(Texture() != -1){
			glDisable(GL_TEXTURE_2D);
		}

		CylindricalBillboard::billboardEnd();

	glPopMatrix();
My textures class contains methods for generating my textures from images and then the apply method (which is called from my tree class)

void Textures::GenerateTextures()
{
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


	// load images
	_images[0].Load("trackpiece.bmp");
	_images[1].Load("tree.tga");
	//lots more textures edited out


	glGenTextures(15, &_textures[0]);


}


void Textures::ApplyTexture(int texture){

	glBindTexture(GL_TEXTURE_2D, _textures[texture]);
	_images[texture].gluBuild2DMipmaps();
	_images[texture].Free();
}

Any help would be much appreciated. This is my first time using OpenGL so I'm not very good at it. Thanks in advance!
Advertisement
Don't worry, this problem catches just about everyone when they're starting out. I'll assume you know how a depth buffer works. The tree in front is drawn first, and for every pixel drawn, no matter how opaque or transparent, the depth is written to the corresponding "pixel" in the depth buffer. Later, when the tree behind is drawn, the rasteriser will look at the depth buffer and see decide that there is already something in front so it will skip drawing the pixel of the rear tree entirely. I hope that made sense, otherwise I'm sure someone else can explain it better.

There are two simple ways to avoid this problem:

1) Read up on alpha testing. Before drawing the billboards switch alpha blending off and turn alpha testing on. This approach is very simple and robust way to get transparency without any depth buffer issues, but has the obvious drawback that without blending you don't get any partial transparency, which also means you lose any antialiasing in the texture. I suggest that you try this approach anyway, because you might find in this case that the loss of blending doesn't matter.

Alternatively

2) Depth-sorting. Leave blending on but when you draw the billboards figure out the distance of each one from the camera and make sure that the billboards are drawn in order from furthest to nearest.


The second approach takes a little more work than the first and will probably perform very slightly worse, but doesn't compromise the image quality. Certain cases might favour one approach over the other, but for your case either one should be just fine.
Thanks very much, I've swapped to alpha testing now and it all works fine.

Thanks again! :)

This topic is closed to new replies.

Advertisement