• Advertisement
Sign in to follow this  
  • entries
    557
  • comments
    1237
  • views
    422730

Untitled

Sign in to follow this  

42 views

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...
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement