C++ DirectX Renderer Design

Started by
5 comments, last by Alex B. 10 years, 2 months ago

Hi there,

maybe somebody could help me with some thinhgs I don't understand yet.

I've read the book Practical Rendering & Computation with Direct3D11 and read the source code that belongs to the book.

http://hieroglyph3.codeplex.com/SourceControl/latest#trunk/Hieroglyph3/

I pretty much understand what he does. But there are some questions where I'm not sure:

-Is it common to wrap up everything in that way it is done there? Cause I looked over other source codes and I couldn't find another renderer that is split up that heavy. (Maybe performance?)

- I've read very often that it's not a good idea to let the models render them selves, but there we got Entities that got a render method. That methods loads the pipeline with the instructions and let it draw it. Is this now how it should be done or not?

- There are more apps (for ex deffered rendering or ambient occlusion) that inherit from the base app. If I would do a framework and use it in a game: I wpould have for example do a deffered renderer that inherits from it and send my render queue to it? or even a forward renderer and so on?

- Everytime he inherits the app there is pretty much to do again. Is it the way it would be done, or is it more common to get the initialization somehow together that works somehow generic? so i just would have a call like

for(i < rq.length; i++)

{

rq.render(); //here are some renderables in.

}

thank you!

Alex

Advertisement

What functionality do you want from a renderer? Well you want to give it a Scene and render it to the screen right? You also want it to handle the game window so that you can change resolution and toggle windowed mode and fullscreen mode.

Another thing you want from the renderer (atleast DX9) is to create textures/surfaces and buffers for you.

Here is some of my Dx9Device class:


class Dx9Device
{
public:
	Dx9Device(void);
	~Dx9Device(void);

	bool CreateGameWindowAndInit(HINSTANCE hInstance, int nCmdShow, LPVOID *pInput);
	void ChangeDisplaySettings(DisplaySettings &NewSettings);
	void BuildManagedResources(std::shared_ptr<GameResource> &spResource);
	void Render(GameScene &Scene);
	void GetSettings(DisplaySettings &Settings);

.
.
.
}

The Scene data structure contain all the information necessary to draw one frame to the screen.

Okay, so that way you do it, you give a scene to the renderer. I think in the scene there are objects that for example inherit from a renderable interface?

So the renderables got a function render() that makes the renderer to draw them?

As you said the renderer is the system that gives me the device and resources. In the book I wrote all the resources are wrapped up. Is this a good idea or just overkill?

Thats what i wanted to describe with the problem I've read, its not a good idea to render the objects themselves.

http://gamedev.stackexchange.com/questions/14133/should-actors-in-a-game-be-responsible-for-drawing-themselves

How you implement the Renderer can be from very simple, to very complex depending on your needs.

The Scene you give the renderer has everything from skeletons to camera matrices already computed. All you have to do is push the Scene through your pipeline.

It's wise to think of batching before passing Scene to the renderer. For example, the Scene struct can contain an array of Texture objects. Each texture object has an array of mesh objects, and each mesh object has an instance buffer.

Something like this:


struct InstanceObject
{
	D3DXMATRIX matWorld;
}

struct MeshObject
{
	Mesh pMesh;
	std::vector<InstanceObject> Instances;
}

struct TextureObject
{
	Texture pTex;
	std::vector<*MeshObject> Meshes;
}

struct GameScene
{
	std::vector<*TextureObject> Textures;
}

Then the renderer can nest 3 for loops and loop through what to draw.

Okay, so if I want a renderer that covers the most of the stuff directX can do its a good decision to do it the way its done in this source I think :) (what I don't understand is the performance decrease. How much does this cost if I wrap a resource in a class?)

If I understood it right the pipeline has to be designed that way you just put data in and get the transformed data out. That data should be prepared as good as possible before (culling and that stuff I think)

Thanks :)

Actually you dont push the whole scene through the render pipeline,the renderer should only see the infromation it needs, like vbs, ibs, shaders, constants and render state changes. Most scene graphs get culled heavily and only the objects that are visible will have the data needed to display them sent to the renderer.

My scene doesn't even touch the renderer all I do in the update of my game objects is tell them to add there renderable data to a list, this list is then fed to a renderer to display.

The renderer is the only one that knows how to submit a render command to the GPU, the objects only submit the data needed to create the render command.

Most games don't even have scene graphs in the update code they only contain a link to a model or something like that, the model can contain a scnegraph but doesnt have to, my current game doesnt use scene graphs just models which consist of meshgroups, and it is the mesh group that contains links or data to all relevant data to be able to render the mesh group.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

Yep, therefore I wanted to do a rendermanager that culls and sorts all of the stuff in the scene and calls the renderer to do all the work :)

This topic is closed to new replies.

Advertisement