Jump to content
  • Advertisement
Sign in to follow this  
induster

Where to include the render() function?

This topic is 3882 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'm a week into directx and limited with c++ header organization. I have a directx class and a sphere class. Where is the normal placement of the render function? Right now I'm passing my sphere information into a directx::render() function to display the sphere. My question is should the render() stay in a directx class or be included in every object class that needs to be rendered?

Share this post


Link to post
Share on other sites
Advertisement
People have argued it either way, so there are pro's and con's however you choose to look at it.

From an OOP perspective then render() should probably exist as a member function - a sphere knows how to render itself, whereas the 'owner' class shouldn't really know this information (ignoring the fact that a sphere is very simple).

The flipside is that passing a IDirect3DDevice9 pointer to your Sphere::Render() method can expose the sphere implementation to a lot of global states and starts to break down loose coupling as it could, potentially, interfere with other parts of the application. Remedying this could see the 'owner' assume more control over how the object is rendered which can start to go against my previous statement and break encapsulation.

It is common to optimize state changes for a D3D9 application and the context required for this tends to be at the global/manager level which would mean that this global rendering manager needs to have some control over the low-level implementation details of rendering each object. For example, it could better arrange rendering of 20 spheres due to knowing that you don't need redundant state changes yet each of those 20 instances shouldn't really know about each other and if written correctly would re-configure the device each time.

A possible way around this is to have some sort of 'display list' where each object can append commands to a buffer that your manager can then go and re-order as it sees fit.

It's a fun problem to solve [grin]

Jack

Share this post


Link to post
Share on other sites
Thanks for the reply :)

I decided to build a class to manage all the rendering. The more I imagine this I think each sphere should be able to render itself. Where it breaks down in my mind is when you'd want to render multiple spheres to the screen. If each one does it's own render sequence, I get flickering on the screen because it's wanting to do seperate windows over and over. How would you solve that issue?

Share this post


Link to post
Share on other sites
I'd put the render() function in the sphere class. The renderer doesn't need (or want) to know how to render a sphere or any other object. All the renderer does is expose methods to draw different stuff - for example a DrawMesh() function.

It would be the sphere's responsibility to generate/load a mesh, and submit that mesh with the correct radius to the renderer. This way, the sphere knows nothing about the internals of the renderer, and the renderer knows nothing about the internals of the sphere. All that's needed is that the sphere keeps a reference or a pointer to the renderer, so that it can submit the necessary draw calls.

Share this post


Link to post
Share on other sites
Quote:

I get flickering on the screen because it's wanting to do seperate windows over and over. How would you solve that issue?


Huh? You should do all your "drawning" then flip the screen. Not sure how you get flickering unless you have vsync off or something.

I don't pass in the IDirect3DDevice9 pointer but I do allow the object to query for it when its created using the engines internal messaging system.

Share this post


Link to post
Share on other sites
The flicker was from me drawing more than one scene in the same loop. Each object had it's own begin and end scene sequence. Would you mind expanding on how to query the device pointer when an object is created?

Share this post


Link to post
Share on other sites
I would have 3 classes:

One is the Sphere class, it is concerned with all that is spherical. It has a method like getStateForRendering() which returns another class, call it a RenderOp.

A RenderOp is concerned with the storage of renderable data. It has attributes for pointing to vertices, indicies, textures, etc.

The Renderer is concerned with using data from RenderOps to draw the scene. A renderer might have a method like: void render(RenderOp& op).

A simple render sequence for spheres might look like this:
for (int i = 0; i < numSpheres; i++)
{
myRenderer.render( spheres.getStateForRendering() );
}

So what's so good about that?

Well now you can add another class, call it a RenderQueue. This class is concerned with collecting RenderOps and sorting them to minimise the state-changes and optimise the ordering of RenderOps.
The Renderer's render method can now be changed to: render(RenderQueue& ops)

With this new class the render process is a little more sophisticated:
for (int i = 0; i < numVisibleSpheres; i++)
{
renderQueue.addRenderOp( spheres.getStateForRendering() );
}

renderQueue.sort();
myRenderer.render( renderQueue );

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!