• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Chapa

Best way to sort draw calls?

11 posts in this topic

Hello, before anything, sorry for my english, since it is not my native language i am not really good on it, but here i go...
 
Im new to DirectX and i been thinking on the best way to manage the draw calls i will be doing, so i can get the best performance i can, i now understand a good way is sorting the meshes on a way that i make the less state changes possible, for example sorting by shader, then materials, etc, and i been trying to approach this, but also thinking in the future when i will be needing to get control of a certain mesh, or test collisions, etc, and i been trying to search for this info, but no one talks about models having more than one mesh, and managing all those meshes together, etc...
 
So this are the 2 ways i think i could do it, but cant decide which one is best or which one to choose...
 
Lets say i have a material, mesh and model class and each mesh has a link to the material it uses...
 
So the first idea would be loading all the materials and meshes on a list, and on the model class only saving a list of pointers to them, so i can modify or check something if needed, for example changing the world matrix of all the meshes on the model, the benefit of this idea is that i will be able to sort all of the meshes in the scene, ignoring to what model it belongs, and render them by material, saving material state changes even if two or more different models uses the same material, but the bad part is that i will be updating the matrix buffer on each mesh, to be able to move different meshes to the same place, ignoring their place on the list.
 
My second idea would be loading the materials and meshes inside the model class and by that way only having one world matrix for the whole model, in this case i will be rendering by model, and inside it, rendering by material anyway, and the benefit would be only updating the matrix buffer once per model, instead of once per mesh, but the bad part here is that if i have the same material on different meshes between models, i will need to update the material again on the other model or models.
 
So this are my 2 ideas and i still cant decide which one to choose, i really would appreciate any advice thank you.
0

Share this post


Link to post
Share on other sites

you should order primarily by:

1- shaders (then)

2- textures (then)

3- vertex buffers

 

You can create a binding manager that always tryies to bind a resource mindlessly but in its internal managing refuses to do so if resource is already gpu avtive-provided. With this technique - after sorted by priorities mentioned upper is done- the manager will simply minimize all gpu expensive commands.

 

All this should be less prior than drawing by distance from camera and so on and so on

2

Share this post


Link to post
Share on other sites

Thank you very much for your answers, im actually also new to programming, im still in college and never saw programming before, and since we see alot of stuff at the same time we do not really learn everything so deeply...

 

But i like to do my own research and learn by myself, so i did it, and i just learned what a handle is, and a little bit of bitwise operators, and i managed to do an example code, making handles and sorting them, just as kauna told me, it is amazing, i guess the handlers, will be the index number of my object on their own list,  and i will just walk thru the vector, and change the states when needed, looks like some nested fors or whiles with some ifs, and thats it, pretty cool and easy.

 

About JohnnyCode advises, i was already planning to do a kind of resourece manager that does all this kind of stuff, thank you for making me sure of doing it, and im already using frustrum culling before all this rendering...

 

But i still have some doubts about defining models and meshes that i cant get straight on my head, i still do not import any animations, so i dont manage skinning, i actually dont know how to yet, im actually importing static models from obj and mtl files, i decided to always divide the meshes by material, so each mesh has only 1 material assigned of course, so having everything divided as kauna told me, everything will fit cool with this method...

 

But i still keep thinking, what if i make a model class with its own materials and meshes, this still will make me only have one world matrix per model and also one vertex buffer, and i wont need to send that many world matrix changes to shader or vertex buffer changes... for example lets say in my sorted vector with handlers, my last handle is the matrices transformations, if i sort by material for example, probably all of the meshes that has the same transformations will be all far away from another, so i will need to update the transformations almost each iteration, and doing it the way i think it will happen a lot of less times, since all the meshes in the model will be rendered in order, and i guess i can also do this by putting the matrices transformations handler at the beggining on my vector, or also using a vertex buffer handler, but i dont know if its the correct thing to do, i dont really know what is more expensive to do, sending material info or sending matrices info, since both are just constant buffers and material buffer adds some texture sends, this confuses me alot lol..

 

Also doing this, i would probably only check if the whole model is inside the frustrum, and not each of the meshes, or also when testing collisions, this has nothing to do with rendering, but i guess it will save some cpu cycles also...

 

I would really appreciate if you guys can help me get this clear for me, thank you.

Edited by Chapa
0

Share this post


Link to post
Share on other sites

 

Thank you very much for your answers, im actually also new to programming, im still in college and never saw programming before, and since we see alot of stuff at the same time we do not really learn everything so deeply...

You do not need to manage things to be extremly effective, a program can run without this in mind. Yet if you wonder how to optimze calibrate stuff it is matter of realy extensive knowledge about - nothing in general - but the provider you run over and its extensivity,

1

Share this post


Link to post
Share on other sites

I can explain how this works in my engine currently.

 

Only considering relevance to model rendering, my resource manager manages vertex shaders, pixel shaders, models, materials and textures.

 

A model is a collection of 1-to-many meshes. Each mesh is a subset of the model, with 1 material only. Each mesh contains a vertex buffer, index buffer, material handle and render type.

 

The render type will instruct the render queue how to render the mesh. The most common render type set is opaque- opaque meshes will end up on the standard forward or deferred rendering path. It could also be alpha-clipped, semi-transparent or an overlay, which are also sorted to be rendered last, always via forward rendering.

 

My scene is a collection of entities. Entities may contain other entities. Each entity is a collection of 1-to-many components. One type of component is a model component. When rendering the scene, the model component handles the OnRender event by constructing a render command for each mesh within the model. The render command contains the render type, material handle, depth (of the model from the camera), model handle, mesh index and a pointer to the owning component (and therefore indirectly entity). This render command is submitted to the render queue.

 

Once the entire visibility-culled scene has had a chance to add render commands to the render queue, the render queue is instructed to quick sort the queue. It does this by having all relevant render command information tightly packed (1 byte packing) into 3 uint32_t's.

 

The structure looks like this:

 

 

#pragma pack(1)

 

union

{

    struct

    {

        uint32_t SortValueA;

        uint32_t SortValueB;

        uint32_t SortValueC;

    };

 

    struct

    {

        // Packed into SortValueA in reverse priority order.

        uint16_t MaterialID;

        uint16_t RenderType;

 

        // Packed into SortValueB in reverse priority order.

        uint16_t MeshIndex;

        uint16_t ModelID;

 

        // Packed into SortValueC in reverse priority order.

        float Depth;

    };

};

 

#pragma pack() 

 

So the queue sorts by the priority of: Render Type - MaterialID - Model ID - MeshIndex - Depth.

 

When rendering the queue:

 

A change in render type instructs the render queue to activate the appropriate vertex and pixel shaders.

 

A change in material instructs the mesh to set the material parameters in the per-material constant buffer and set the material textures.

 

A change in model instructs the mesh to set the model parameters in the per-model constant buffer (e.g. transformation matrices).

 

A change in mesh index instructs the mesh to activate the mesh vertex and index buffers.

 

The mesh is then ready to render.

1

Share this post


Link to post
Share on other sites

Thank you L. Spiro and JMab, that was very useful,

 

So let me see if i understood how it should be, L. Spiro,  

 

- Model will have only pointers to its meshes, i guess this will help in the future to know which meshes are related.

- Mesh will have the physics helpers (BB or BS, etc) and a list of sub-meshes, i guess this is what i would call a "group" lika a head for example, which would be part of a model.

- Sub-Mesh will be the one having all the info like vertex/index buffers, shaders and material IDs, matrices transformations, etc, and this one would represent for example, the eyes, or the mouth, etc.

 

If this is correct, i think it is pretty clear now then, after having this i think i will first loop thru all meshes to check which one is inside frustrum, but since the sub-meshes will be sorted by material i would need to activate a bool or something like that, and then go thru all the sub-meshes on the scene, and render the ones that are inside the frustrum by reading the bool i modified.

 

Am i near now? this has been very helpfull, thank you everyone for the answers. 

0

Share this post


Link to post
Share on other sites

I should add on the Model/Mesh/SubMesh debate, I don't think my current structure is future proof, as it doesn't consider Level of Detail (LOD). This structure makes sense to me, but each to their own:

 

Model - A collection of Meshes. Linked to by the actor/gameObject/entity.

 

Mesh - A collection of SubMeshes. Each Mesh represents a different LOD level of the Model.

 

SubMesh - A shaders/material/vertex buffer/index buffer set for a particular LOD level.

0

Share this post


Link to post
Share on other sites


Only the mesh needs a vertex buffer. Sub-meshes can do with an index buffer and an offset into the shared vertex buffer.
If you "collapsed" all the sub meshes into a single vertex buffer, why don't go all the way and "collapse" all sub mesh index buffers into a single one? Unless I'm missing something you'd only need to append each index buffer into a single one and it would work.

 

Then again, you'd need to store an offset (and size) into the index buffer then, so when setting parameters per submesh you can draw only the submesh rather than the whole buffer.

1

Share this post


Link to post
Share on other sites

Thank you L. Spiro, with this information it is really clear for me now how to save the data, you have been very helpfull, and i really appreciate the time you are taking to answer me, but i still cant get the whole idea, i understood how to structure the info and also i understood how i could manage the physics and even i got the LOD idea, its pretty simple when using this structure...

 

But i still cant get, how am i going to put this kind of structure into a render queue, the only idea i get for rendering this, is just having a render method in the model, which is going thru all meshes, and then each mesh is going thru all submeshes, and of course activating what needed on each stage, and finally getting the render of a single model,... the benefits i see on this way is that i will only update constant buffer on each mesh, if its different of course, and i can share the vertexbuffer, even the indexbuffer, just using an offset on the drawcall and knowing the size, but i still will change the material and probably texture for each submesh, which is what everyone tries to avoid, thats what i have been reading everywhere, of course after sorting by rendertype and shaders, this still confuses me...

 

And again, i am sorry for my english, may be you already tried to explain me this before or gave me an idea about it, but sometimes when reading a whole sentence its just hard for me to understand everything you are trying to tell me.

 

Thanks again smile.png

Edited by Chapa
0

Share this post


Link to post
Share on other sites

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  
Followers 0