Sign in to follow this  

Scene Graph design help, need to bounce this idea off some people

This topic is 4379 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

I’ve got a working scene graph based on the composite design pattern. I seem to have made a mistake however with the way I’m sharing vertex data and this is causing a big problem now dealing with D3D and its need to destroy and reset the device on occasion. I’m thinking that a good design would be this. Have a Geometry object which is not part of the graph, basically a vertex data container. Have a Topology object which is not part of the graph, basically an index data container. Put these in a resource manager that will deal with D3D and its need to reset. Sharable GeometrySet leaf nodes will keep pairs of Attributes and Renderables. Attributes and Renderables can also be shared. Derive topology specific Renderables for Triangles, Tristrips, Quads, Lines, … Attach Geometry and Topology data to the derived Renderable objects, sharing where ever possible to set up the attribute subsets. D3D Vertex buffer data is attached to Geometry objects and D3D Index buffer data is attached to the topology nodes (the scene graph is API-independent but the attached data is not). This provides a one to one relation between the VB/Geometry and ID/Topology. Late binding of d3d data should doable because the vertex and index data is in its original form. Reconstruction when the D3D device is lost or destroyed can be done as well since we have the original data. Anyone see problems with this? Hope it’s at least understandable.

Share this post


Link to post
Share on other sites
so what you have is a tree
with a renderable that contains a link to a vertex buffer and an index buffer

this sounds fine

in my engine everything renderable is represented in a mesh class e.g.: class mesh

this class contains the vertex buffer ,the index buffer, the shader and texture information that are required to render it

this is passed to some sort of hierarchical tree with build in culling mechanisms

the only difference is that you reference your data buffers from somewhere else in memory but implementation wise this should behave identical


Just one thing i wonder about why s your data api dependent? i just use float arrays and unsigned short this makes it pretty api independent

the whole shader thing and texture code encapsulates its api dependent functionality

Share this post


Link to post
Share on other sites
Quote:
Original post by Basiror
Just one thing i wonder about why s your data api dependent? i just use float arrays and unsigned short this makes it pretty api independent

the whole shader thing and texture code encapsulates its api dependent functionality


The data in the geometry and topology is just a bunch of floats/ints. The textures are resource objects which are implemented differently depending on which API is in use, same for shaders and other attributes.

The API specific data (if any) is attached to the nodes through an attachment system, which is used by the renderer or any other external thing that wants to associate data with an element of the scene graph.

The more I think about this design the more I think I like it.

Anyone out there want to stop me before I code this [looksaround]

Share this post


Link to post
Share on other sites
I see no problems with your implementation but beware that you don t make things more complex than needed

I will also implement some sort of vertex buffer as a class to switch between VBOs and normal vertex arrays on the fly *i am using opengl*

Share this post


Link to post
Share on other sites
Hi,

My approach is the following : All the data that are device dependant (vertex / index buffers, textures, shaders, etc.) are handled by a resource manager.

When I want to create a vertex buffer, I simply have something like : CResourceManager::CreateVertexBuffer(.....); and the same goes for any type of device dependant resource.

Each resource is designed by a unique unsigned int ID. So, for example, I will have a geometry node in my scenegraph, and in this node, instead of having something like "IDirect3DVertexBuffer9 *m_pVB", I will have "unsigned int m_VB".
The advantage of using this method is that the resource manager handle the destroying / resetting of resources for you. The id of a resource doesn't change when it's resetted, so in the scenegraph, You don't have to care about device lost / destroyed anymore.

That even allow for a cross OpenGL / DirectX engine, since in the scenegraph you only handle unsigned ints and you could have a resource manager for OpenGL and one for DirectX ^^

Share this post


Link to post
Share on other sites
Quote:
Original post by paic
Each resource is designed by a unique unsigned int ID. So, for example, I will have a geometry node in my scenegraph, and in this node, instead of having something like "IDirect3DVertexBuffer9 *m_pVB", I will have "unsigned int m_VB".


Wouldn’t this also work using a shared pointer to the resource?

in the simplest form:

struct Resource
{
};

struct VBResource
{
VertexBuffer m_pVB;
};

struct IBResource
{
IndexBuffer m_pIB;
};
struct MyObject
{
shared_ptr<Resource> m_pVBResource;
shared_ptr<Resource> m_pIBResource;
};

MyObject myObject;

myObject.m_pVBResource = ResourceManager::CreateVB( ... );
myObject.m_pIBResource = ResourceManager::CreateIB( ... );





Should work the same as the ID but without the lookup.
The resource manager is free to change the data when needed.

Share this post


Link to post
Share on other sites
Yes, but if the buffer needs to be deleted and then re-created ? The pointer changes. That's the point with an ID : it doesn't change even if the resource was deleted and re-created.
And with a std::map, the lookup is pretty fast / simple to do.

Share this post


Link to post
Share on other sites
The resource object pointer doesn't change, just the internal VB or IB pointer.
Since the resource is shared, changing the internal pointers updates everything. The Resource pointer is like a handle providing double indirection.

Share this post


Link to post
Share on other sites

This topic is 4379 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.

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

Sign in to follow this