Jump to content
  • Advertisement
Sign in to follow this  
SeiryuEnder

Graphics Module Architecture

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

This thread is in reference to a personal project with the potential to later become an open-source, I am doing it more for educational purposes than anything practical.

I'm currently writing a set of general purpose modules.
The modules are split into 3 sections: Game, Render, and Utility.
This thread is in respect to the Render module and it's general architecture.

Rendering is highly complex and may need to fulfill many functions.
The key goal of this thread is to establish the best possible architecture for speed, expansion, and ease of use.

The current (and very incomplete) architecture is simply:

Game
|_ Facade Interface Layer
--|_ RenderDX
----|_Mesh Manager
----|_Shader Manager
----|_Texture Manager


This graph does not necessarily imply composition, but instead the order of access.
All RenderDX subsystems maintain a pointer to their parent system, though interdependence should be kept to a minimum.

Some important limitations to note would be:
All memory is either statically declared or drawn from a memory pool (excluded memory allocated on the gfx card [VBOs, etc])
No reliance on any one render method, I should be able to create a fully capable GL renderer


There are a lot of features I have yet to implement (such as animation, lighting, culling, etc).
This is because I want to have a very solid and maintainable structure before I start these things.


If there is any more information I can provide that will help, please don't hesitate to ask.

TL;DR: You should probably read the thread to get a clear idea of the goal here, but generally speaking what is the best structure of a render system that you have encountered? PROS/CONS?


I appreciate your time and expertise,
Tom W. Brooks II

Share this post


Link to post
Share on other sites
Advertisement
It isn't exactly clear to me what you're looking for, but I'll give a few general tips that I hope apply.

- Separate the module into two layers: low-level device abstraction, and implementation of graphical techniques. For example, implementing textures or draw-calls is a lower-level task, wheras implementing lighting, shading, post-processing, etc are higher-level tasks, which should be built on top of the lower-layer. The lower layer should have no knowledge at all of the higher level tasks, in order to keep it generic.

- Think about the (cross platform) API that the user (i.e. graphics programmer) will be using. Is this API any easier than using D3D/GL, or is it just a wrapper around D3D/GL?

- Prefer stateless designs. In D3D/GL, the behaviour of a draw-call depends on all of the state-changes that have come before it.
This means that, for example, if you see a line of code that says [font=courier new,courier,monospace]DrawIndexedPrimitive[/font], you do not immediately know how that primitive will be drawn. To find out, you've got to back track the flow of the code, and look at each state-setting function that was called.
This makes it extremely hard to reason about the state of a D3D/GL device at any point in time -- is blending on or off, which textures are bound, what shader params are set, etc...?
In the lower level module, you should make sure that there's only a single place where each state can be changed, so you can keep track of the state of the device.
However, at the higher-level, the user should not be concerned with this problem at all. IMO the best way to achieve this is to provide an API where there is no global state between draw calls (i.e. they cannot "leave on" a state). I've rambled about these kinds of designs a lot before in this thread. If done correctly, this can give great performance improvements, as well as usability improvements.

- Think very carefully about how shader parameters are set, this can be the most performance-critical part (every object can have multiple draw-calls, every draw call will have a lot of shader parameters). I've used at least 3 different commercial game engines where the single biggest performance bottleneck was the setting of shader parameters... In the worst case of this that I've seen, a console game shipped with shader-parmater-setting taking up ~30% of it's total CPU time.

Share this post


Link to post
Share on other sites
Hodgeman,

I suppose I wasn't able to clarify what I was asking for, but all of these tips are greatly helpful and what I was hoping to get from this thread.

Right now I'm looking for any critical errors with my current architecture so that I can correct it before it gets and further, and potentially even change the architecture completely in favor of something more effective.

The alternate reason for this thread is to find common bottlenecks and some of the features I may have overlooked, so that I can circumvent then problems in the design phase.

In both of these respects, you've given me quite a bit to think about. Exactly the sort of information I'm looking for. =)

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!