🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Untitled

posted in DruinkJournal
Published March 13, 2007
Advertisement
Ok ok, my server is up, order is restored.

I've started getting my scene graph class working. Here's a random example class diagram:
ESceneObject -(has a)-> ESceneObjectContext      |                          |      |                 PSceneObjectContext      |                          |     / |                        / |    /   |                      /   |ESprite EMesh       PSpriteContext PMeshContext
Each ESceneObject (Engine-level object, P* is a platform level (D3D) object) has a ESceneObjectContext context class pointer as a member. I'm still not 100% sure where to create that pointer, since I'd like to be able to create ESprite's for instance in the game code, and I don't really want to expose the PSprite layer to ESprite. But I might have to.
Anyway, every ESceneObjectContext is actually a PSceneObjectContext in disguise, and the renderer calls the pure virtual functions BeginBatchRender(), EndBatchRender() and Render(). BeginBatchRender() and EndBatchRender() are used as effectively static functions; all they do is optionally set up the D3D state for rendering this object type. For instance, PSpriteContext::BeginBatchRender() would call ID3DXSprite::Begin() (or rather my sprite layer equivalent), PSpriteContext::EndBatchRender() would call ID3DXSprite::End(), and PSpriteContext::Render() would call ID3DXSprite::Draw(), passing in the details for the owner of the context.

The reason I've made the context class instead of making a PSprite class is that I want the engine and game code to be able to create an ESprite by doing ESprite* pSprite = new ESprite; and not have to go through the graphics class to create a PSprite internally. Unfortunately, as I said above, I'm not quite sure where to create the context. I might have a factory method in my renderer (Although I'd rather not, that drags in all context headers to my main graphics class), I could have a factory method in PSceneObjectContext (Which is looking most feasable), or I could create the relevant context in the ESprite / EMesh / EWhatever constructor, which I don't like because it brings a platform header into engine code.

And while I'm here, here's my ideal render loop (Which is how it is at the moment, but we'll see how long that lasts:
void PGraphics::RenderSceneGraph(const ESceneMgr::ObjectList& objects){	ESceneObject::Type eCurrType = ESceneObject::TYPE_Count;	PSceneObjectContext* pLastContext = NULL;	for(ESceneMgr::ObjectListConstIter it=objects.begin(); it!=objects.end(); ++it)	{		ESceneObject::Type eType = (*it)->GetType();		if(eCurrType != eType)		{			// Setup batch rendering			if(pLastContext)				pLastContext->FinishBatchRender();			pLastContext = (PSceneObjectContext*)(*it)->GetContext();			if(!pLastContext)				pLastContext = ConstructContextForObject(**it);			if(pLastContext->BeginBatchRender())			{				eCurrType = eType;			}			else			{				// Batch render begin failed, skip this object				Assert(false, "PSceneObjectContext::BeginBatchRender failed");				continue;			}		}		// Render		PSceneObjectContext* pContext = (PSceneObjectContext*)(*it)->GetContext();		pContext->Render();	}	if(pLastContext)		pLastContext->FinishBatchRender();}

I'd like to get rid of that ConstructContextForObject() call, but it might just have to stay there. I doubt it'll be that big a deal. I can always have a TouchScene() function or whatever, which will go and create the contexts of all objects in the scene.
Ideally I should be able to destroy a context and cause D3D resources to be destroyed, so resetting the device could be as simple as destroying all contexts. As it is, I have a std::vector of PGraphicsObject pointers, and every graphics object (Like textures, ID3DXSprites, vertex buffers, etc) should inherit from that class. I then have a common interface to reset everything. Again, in theory I should be able to Release() it all too, but that's not going to be very worthwhile, and will cause headaches.

Anyway. It's 10am, I should get some work done...

EDIT: Sodding code tags don't like backslashes...
Previous Entry Untitled
Next Entry Untitled
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement
Advertisement