Advanced Render Queue API

Started by
30 comments, last by melbow 11 years, 3 months ago
Is the reason for storing StateGroups as a header and chunk of States that you make it more cache friendly due to locality?

Also, you say you store StateGroups in Resources. Am I correct in assuming some StateGroups must still be created at runtime, e.g. geometry instance transforms. And therefore RenderItems creation also cannot be done when the game object is initialized, but must be done every frame. Is this correct or am I completely off base?
Advertisement
First up, if you want to research this, the technique of loading your runtime data structures straight out of a file with no (or little) on-load processing is usually called "load-in-place" or "in-place memory", or something similar. There's a gamasutra article here.

For pointers within a particular asset (e.g. a pointer from a model header to an array of state-group pointers, to a state-group) I use the Offset (relative address) and Address (absolute address) classes in this header -- i.e. I don't use actual pointers.

I had heard of this technique before; I was more wondering about the specific case of state-groups, where it seems that a lot of states would need to store pointers. For example, pointers to shaders, textures, vertex buffers, index buffers, cbuffer data, etc. Your example of model assets cleared up my questions about this, though. I wasn't quite sure what the name for this technique was, however, so your suggestions for terms to research look helpful. I'll have a look at the article you linked as well.

So in general, the idea is to also store the actual data as well as the state groups, then in place of an actual pointer use an offset or address to the data, and then perform pointer-patching when loading.

Yeah, my states are variable size, and the group-header doesn't contain the actual offset of each state. Therefore to iterate through the group, you have to inspect each state in a linear order, and determine the current state's size to know how far to jump ahead to find the next state. The bitfield does allow you to halt this iteration early if you know that you've already inspected all of the 'interesting' states in the group though.

As an alternative, you could allocate an array of size numStates in/after the header and write the offset of each state into this array. If you then ordered the states by their ID value, you'd be able to quickly jump to a particular state that you're interested in without iterating through each one.

I think linear iteration would probably be fine for me as well. Using the bitfield to skip the rest of a state-group if possible sounds like a good idea.

So I think I've managed to go full circle from virtual Draw methods to a Render Command Queue back to virtual Draw methods. It just doesn't seem worth it to do all this work just for a unified renderer when you could have a virtual Draw method and call it a day. If renderable objects are managed and batched prior to being made into RenderItems then as far as I can tell, you could just give the batch a Draw method and enqueue the batch.

I guess I don't really see the point of the Commands.

I am at a loss because I want to do this the right way, but I have too little experience with coding rendering APIs to know what that is. And please don't say, "There is no 'right way.'"

Could anybody recommend a book that covers render queues similar to what has been described by Hodgman?

This topic is closed to new replies.

Advertisement