Jump to content
  • Advertisement
Sign in to follow this  
Klarre

Scene graph render function design feedback

This topic is 4155 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! I am currently trying to figure out how to design my scene graph, and need some advices. I do have a Node class and a RenderObject class, where RenderObjects are attached to Nodes. A Node keeps the transformation of the RenderObject. To iterate through the scene graph and simply push and pop the nodes in the hierarchy for render is no problem. The problems arises when I want to sort the render objects depending on their materials since it is pretty expensive to change textures and shaders. I have come up with one type of solution to this, but I think it needs some feedback from more experienced people than myself. Is this a good thought or should I rethink my solution with another approach? Any tips, ideas or links are welcome! Thanks for your time! /Klarre
 // Note: This is just pseudo code and may not be compilable
void RenderManager::render()
{
	// Calculate a Matrix4x4 (worldtransformation matrix) for every visible nodes.
	// Nodes are decided visible by the camera.
	mSceneGraph->calculateMatrixOnVisibleNodes(mCamera);

	// Get a list of all visible nodes (the same ones that got a matrix calulated
	// on the above row).
	std::vector<Node*> visibleNodes = mSceneGraph->getVisibleNodes();

	// Get all render objects from all visible nodes (pseudo code).
	std::list<RenderObject*> renderObjects = visibleNodes->getRenderObjects();

	// Sort all render objects depending on their materials.
	renderObjects.sort();

	// Iterate through all sorted render objects and draw them.
	for(std::list<RenderObject*>::iterator i = renderObjects.begin(); i != renderObjects.end(); ++i)
	{
		mRenderer->pushModelviewMatrix();

		// Multiply the modelview matrix with the world transformation of the node that
		// the drawn render object is attached to.
		mRenderer->multModelviewMatrix((*i)->getNodeAttachedTo()->getWorldtansformationMatrix());

		// Render the object and change material if needed.
		renderObject(*i);
		mRenderer->popModelviewMatrix();
	}
}

Share this post


Link to post
Share on other sites
Advertisement
When you iterate through all the objects to be rendered you push and pop the world matrix for every object.

Since you use the camera to calculate the visible nodes why don't you take the camera matrix into account when calculating the modelview matrix on a per node base. (Maybe you do it already, if so never mind.)

Then before iterating through the objects push the current matrix, merely load each object's modelview matrix (with what would you multiply it anyway?) and finally pop the stored modelview matrix.

This would save you a push, multiply and pop operation per object at the cost of one additional push/pop pair outside the loop.

So, for 1000 objects you'd save 999 pushes, 999 pops and 1000 multiplies (well, you might not save those multiplies since you'd just move them to the calculateMatrixOnVisibleNodes function).

Share this post


Link to post
Share on other sites
Hi,

The way I did it was in two steps:

1- compute visible nodes and register them in a display list
2- sort all nodes in display list so as to minimize the number of texture and state switch.

Of course I imposed a restriction so that the display list really minimizes the number of switch: elements in a display list always have a single texture, a single material and a single mesh. So if you have a character mesh using two materials, it is decomposed into two objects using the same mesh and a single material each.

Be aware that your display sorting function will quickly become more complicated when you will add to your scenegraph lights, blended objects, environmental objects (fog and skybox for example).

Hope that helps.

Ghostly yours,
Red.

Share this post


Link to post
Share on other sites
Hello,

Seems like you are off to the right start though some things may need improvement and further consideration. In a graphics engine I wrote I used an approach similar to what Red Ghost mentioned. That is - Traverse the scene graph (collapse the matrices where necessary), determine visible nodes. Now the next part I used a hash table (really a map of multimaps) where the first index was the ShaderID, this minimized shader changes, next in each sub group of the map I used the MaterialID as the key. The idea here being that if they have the same shader and the same material they will have the same texture (When are you going to see the same brickwall with different spec highlights?). Of course you will need a fork in your pipeline for alphablended objects. As far as the scene graph it never made much sense to me to keep things like lights etc in there. The nature of the scene graph can change especially if you are using or want to use a spatial partitioning scheme. To handle this I had scene manager which held onto current lights and camera's active in the scene as well as a scengraph that cared about nothing but actual renderables. This way you can abstract the scenegraph to accomodate for things like quadtree or whatever suits you for your game. Partitioning static geometry in this way is going to be faster. Then you just iterate over the scenegraph and build the drawlist which is passed onto the render manager. Hope this helps - Richard

Share this post


Link to post
Share on other sites
you might check out Tom Forsyth website, that explains why most games do not use a scenegraph and what the reasons for these are.
His article is "Scene Graphs - just say no" and you can find it on

http://home.comcast.net/~tom_forsyth/blog.wiki.html

If you want a scenegraph I would design it around what Tom said :-)

- Wolfgang

Share this post


Link to post
Share on other sites
@wolf
Interesting reading...

So what would you recommend using instead of SceneGraphs?? or what do most console games use??? I'm asking because I was just about to start designing a SG for my game, but if there are any other cool structures that give better results I'm up for learning :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Elefagente_Secreto
@wolf
Interesting reading...

So what would you recommend using instead of SceneGraphs?? or what do most console games use??? I'm asking because I was just about to start designing a SG for my game, but if there are any other cool structures that give better results I'm up for learning :)


Have you had a looky at this?

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!