Engine design v0.3, classes and systems. thoughts?

Started by
17 comments, last by cozzie 7 years, 8 months ago

For example, where would you store a mesh's vtx buffer? In my case it's the Cd3dMesh class, because CMesh is API/ platform independent and just an IO/ data thing.
This depends where you want to draw a line through your code base between code that's implicitly cross-platform, and code that you will re-implement once per platform.

If you implement a "gpu buffer" (index buffers, vertex buffers, structured buffers are all the same) class once per platform (BufferD3D11, BufferVulkan, etc), then your Mesh class becomes portable. It can own a Buffer (which is a BufferD3D11/etc, hidden behind an interface).

Alternatively, Mesh can be an interface for MeshD3D11, MeshVulkan, etc, and you can implement the entire mesh class once per platform.

Personally, I like to create a low-level renderer that's implemented once per platform, and then build the high level renderer (meshes, materials, etc) on top of it (and without using any platform specific code).

Advertisement

Thanks guys, this sounds like a good opportunity to both reduce complexity and lines of code.

So let's see how that could work:

- I only have one per for the scene 'part's: i.e. mesh, mesh instancance, renderable, skybox etc.

-- in these classes I store their orientations etc, using directxmath (in my design so far those were part of the cd3d.... classes)

-- some of these classes get 1 or more objects of a new class CD3d11buffer (mesh has at least 2, vertex + index)

This would work and reduce complexity and code for sure.

The only thing is that the scene parts classes (mesh, mesh instance etc etc.) are no longer API independent. But then the question is, what are the advantages of having say 10 classes less, versus having 1 or 2 class members within the almost API independent other classes (for meshes, etc.).

Or did you mean a different approach then above?

Note; I'm aware that trying to be 100% platfom independent is for sure an illision, I just have to find a balance so I'm able to reuse components in the future, if I decide to go for another API for example.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

The only thing is that the scene parts classes (mesh, mesh instance etc etc.) are no longer API independent.

The point is that this does make mesh/etc API independent :wacko:

You have a cross platform interface (e.g. in C++ you could use an abstract base class, or compile time polymorphism) such as IBuffer, and hidden implementations of it, such as your CD3D11Buffer (which would inherit from the abstract base class IBuffer). This means that your mesh is completely platform agnostic.

p.s. implementing a pure interface is a good use of inheritance. Extending a concrete class (CAnything) is a code smell.

That's quick, I get it know.

- I have a scene in some format

- This is loaded in a cscene class object, which has cmesh class objects

- The cmesh class has one or more cbuffer class objects

- The cbuffer class has a ID3D11Buffer

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Voila, version 0.3.

Getting better by the day :cool:

Just some thoughts/ left questions:

1. I assume I have to prevent needing a d3ddevice or context outside the D3DRENDERER system/ namespace, correct?

(this sounds managable)

2. Would you split the CD3d11 class, resulting in a separate d3ddevice and devicecontext class?

(I've read that, but I'm not sure it'll bring me much)

3. Directxmath is all over the place, but other then the name I believe it's not API dependent (D3D).

If I would split that, the overview will become spaghetti :)

Always appreciate your thoughts.

crealysm11_design_v0.3.jpg

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

I want to be helpful, but it's difficult for me to reason about how the architecture works from a high-level graph like that. For instance, what information do your scenes contain? What constitutes a scene? Is your front menu a scene? How will the scenes be loaded/unloaded? Will you support dynamic, asynchronous loading of level fragments as the player plays through the level? Is each one of those fragments a scene? If not, how do you keep track of which assets are actually needed and which aren't? Some sort of usage counting? These are the sorts of questions that generally give rise to an overall architecture. However, these questions are usually not answerable from a high-level graph of class names alone.

I tend to have more success building up levels of abstraction from the bottom-up. I know how to draw a scene using low-level API calls, but that is tedious and painful. What tools and abstractions would be helpful here? Identify the biggest pain points and fix them first. For instance, there's so much that goes into just loading and initializing a texture with all of the right parameters (size, dimension, mip levels, etc.). You may even need a small constellation/hierarchy of classes to make this less painful while retaining the flexibility you need. And how much flexibility will you need, by the way? It's important to keep your design goals in mind. Are there any extreme optimizations you have in mind in order to reduce texture state changes? Atlasing? Placing multiple same-sized textures into one array? Sparse virtual texturing? You'll want to make sure that your low-level design doesn't preclude these options when you get to a higher level.

I don't know, maybe that's just me. I just find it hard to *start* with the highest-level abstractions. It seems like, once you start to get to the granularity of concrete, single-purpose objects, you may find that the boundaries you drew at the higher levels aren't going to work so well. It looks like you've designed some engines before, though, so maybe you just have some domain knowledge (even if that knowledge is just your usual way of doing things) that I don't have.



The input handler. Seems very, very thin for what would you expect (keyboard, mouse, button handling, analog input handling, etc). I have no idea what a "CTimer" is nor why its so important that you need it in the diagram.

What about event handling? If the player runs over a trigger, which system is in charge of calling that event handler? If a player runs over a metal plate how does the audio systems knows how to switch the step sounds?

Im not quite understanding the "Actor" thing. Is it supposed to be heavily WIP? Because I'm missing things like game logic, triggers, scripts, quests/missions, AI, etc.

Not sure in D3D land but at least in GL land I have a single GLSLShader class that can be vertex, geometry or fragment shader. The only difference is a type enum just to know what it is.

I *think* that if you want to do a high level design of an engine, you'll have to start smaller first. Try only with the renderer, since thats the most detailed part of the diagram, I guess thats the part you're most familiar with. Other parts (events, scripting, AI, more complex game logic) it looks like you'll have to discover on your own, and only after you learn more about them you'll be able to design for it.

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

Play nice, please. And stay on-topic.

This topic is closed to new replies.

Advertisement