Jump to content
  • Advertisement
Sign in to follow this  

Why not blend your whole scene?

This topic is 4562 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, When I was trying to optimize my render::Scene function of my 3d engine, I was thinking. Why not render every object with glBlending enabled. Is it an option to include an alpha layer to every texture you use, and use the textures that are not transparent to draw the non transparent objects? What will give better performance/reliability? (it would mean that there are no separate loops for transparent and non-transparent materials, and you wouldn't need to enable/disable blending) Doing this would mean you'd have to sort all objects by Z value, to make sure objects don't mess up eachother. What I'm doing now is make a list of objects per material, then draw the objects with that material (material includes texture id). After rendering all non transparent object I turn on blending and render the transparent objects from back to front sorted. Will the performance winning when not enabling/disabling glBlend and not having extra loops do any good? All suggestions to my renderscene function are welcome ;-) Here's my current renderscene function:
int GLscene::Render(int width, int height)
{
	static int mc, oc;
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();						

	xTrans = -cam->pos.x;
	yTrans = -cam->pos.y;
	zTrans = -cam->pos.z;
	sceneRoty = 360 - cam->rot.y;
	sceneRotx = 360 - cam->rot.x;

	glRotatef(sceneRotx, 1, 0, 0);
	glRotatef(sceneRoty, 0, 1, 0);
	glTranslatef(xTrans, yTrans, zTrans);

	frustum.CalculateFrustum();

	glPushMatrix();
	for(c=0;c<nr_lights;c++)
	{
		glLightfv(lights[c].id, GL_POSITION, lights[c].pos);
		if(lights[c].spot) glLightfv(lights[c].id, GL_SPOT_DIRECTION, lights[c].spotDirection);
	}

	glPopMatrix();

	for(mc=0;mc<m_trans;mc++)
	{
		materials[matIndex[mc]].Select(textures.texture);
		for(oc=0;oc<materials[matIndex[mc]].nr_objects;oc++)
		{
			if(frustum.ObjectInFrustum(
				objects[materials[matIndex[mc]].objectIndex[oc]].pos.x,
				objects[materials[matIndex[mc]].objectIndex[oc]].pos.y,
				objects[materials[matIndex[mc]].objectIndex[oc]].pos.z,
				objects[materials[matIndex[mc]].objectIndex[oc]].radius))
			{
				glPushMatrix();
				glTranslatef(objects[materials[matIndex[mc]].objectIndex[oc]].pos.x, 
					         objects[materials[matIndex[mc]].objectIndex[oc]].pos.y, 
							 objects[materials[matIndex[mc]].objectIndex[oc]].pos.z);

				glRotatef(objects[materials[matIndex[mc]].objectIndex[oc]].rot.x, 1, 0, 0);
				glRotatef(objects[materials[matIndex[mc]].objectIndex[oc]].rot.y, 0, 1, 0);
				glRotatef(objects[materials[matIndex[mc]].objectIndex[oc]].rot.z, 0, 0, 1);

				glVertexPointer(3,GL_FLOAT,0, (float *)objects[materials[matIndex[mc]].objectIndex[oc]].vertices);
				glTexCoordPointer(2,GL_FLOAT,0, (float *)objects[materials[matIndex[mc]].objectIndex[oc]].texCoords);
				glNormalPointer(GL_FLOAT,0, (float *)objects[materials[matIndex[mc]].objectIndex[oc]].normals);

				glDrawElements(GL_TRIANGLES, 
							   objects[materials[matIndex[mc]].objectIndex[oc]].nr_faces*3,
							   GL_UNSIGNED_INT,
							   (unsigned int *)objects[materials[matIndex[mc]].objectIndex[oc]].faces);

				glPopMatrix();
			}
		}
	}

//	transparant material groups

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

	for(mc=m_trans;mc<nr_materials;mc++)
	{
		materials[matIndex[mc]].Select(textures.texture);
		for(oc=0;oc<materials[matIndex[mc]].nr_objects;oc++)
		{
			if(frustum.ObjectInFrustum(
				objects[materials[matIndex[mc]].objectIndex[oc]].pos.x,
				objects[materials[matIndex[mc]].objectIndex[oc]].pos.y,
				objects[materials[matIndex[mc]].objectIndex[oc]].pos.z,
				objects[materials[matIndex[mc]].objectIndex[oc]].radius))
			{
				glPushMatrix();
				glTranslatef(objects[materials[matIndex[mc]].objectIndex[oc]].pos.x, 
						     objects[materials[matIndex[mc]].objectIndex[oc]].pos.y, 
							 objects[materials[matIndex[mc]].objectIndex[oc]].pos.z);

				glRotatef(objects[materials[matIndex[mc]].objectIndex[oc]].rot.x, 1, 0, 0);
				glRotatef(objects[materials[matIndex[mc]].objectIndex[oc]].rot.y, 0, 1, 0);
				glRotatef(objects[materials[matIndex[mc]].objectIndex[oc]].rot.z, 0, 0, 1);

				glVertexPointer(3,GL_FLOAT,0, (float *)objects[materials[matIndex[mc]].objectIndex[oc]].vertices);
				glTexCoordPointer(2,GL_FLOAT,0, (float *)objects[materials[matIndex[mc]].objectIndex[oc]].texCoords);
				glNormalPointer(GL_FLOAT,0, (float *)objects[materials[matIndex[mc]].objectIndex[oc]].normals);

				glDrawElements(GL_TRIANGLES, 
							   objects[materials[matIndex[mc]].objectIndex[oc]].nr_faces*3,
							   GL_UNSIGNED_INT,
							   (unsigned int *)objects[materials[matIndex[mc]].objectIndex[oc]].faces);

				glPopMatrix();
			}
		}
	}
	glDepthMask(GL_TRUE);
	return true;
}

Share this post


Link to post
Share on other sites
Advertisement
With blending enabled, every pixel you write would be accompanied with an extra read from the framebuffer. Depending on how many pixels are actually written and overdrawn, it could (and probably will) really kill your bandwidth.

Share this post


Link to post
Share on other sites
Well actually, that will most likely kill your fillrate, since every pixel is drawn(because you would have to draw back to front, and any pixel could be translucent). A gl state switch is far less expensive than drawing everything blended. If you want to optimize your engine look into sorting by state. Here is a decent article on delphi3D. There are better ones just search gamedev articles.

Share this post


Link to post
Share on other sites
Sounds like my wild idea aint gonna speed up my rendering ;-)
Thanks for clearing up.

Any suggestions to the way I'm rendering my scene now?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!