Thanks a million. I've not designed my own COM objects yet but that info is extremely useful.
The point I'm making about games here is probably only relevant to those that require a lot of processing power for the graphics and game content. I've noticed extreme performance degradation as a result of copying structures during the main render loop, calling my own virtual functions within a render loop, and of course accessing anything on disk during the main render loop.
So to circumvent the problem I've decided that since the only difference between objects is usually:
- Their orientation in 3 space - translation, rotation, scaling, etc. - essentially their world transformation matrix
- Their texture(s) - these should be maximized so as to wrap around the object - thus using 1 texture for a mesh.
- Their primitive type info (some objects have multiple primitive types)
- Their texture blend states and texture addressing modes
- Their vertex type and/or FVF
Because most objects only differ by these properties (there are probably more you can think of) it makes sense that one render function could be used to render the entire scene.
This approach is much different than having a virtual render for objects or having a render function for each object. This method results in virtually no outside calls being made which results in faster renders.
Look at your rendering code and you will see that most of them in Direct3D will look something like this:
Code:
void Object::Render(float fFrameTimeDelta)
{
D3DXMATRIX World,Translation,Rotation,Scaling;
D3DXMatrixRotationYawPitchRoll(&Rotation,Object.Rot.x,Object.Rot.y,Object.Rot.z);
D3DXMatrixScaling(&Scaling,Object.Scale.x,Object.Scale.y,Object.Scale.z);
World=Scaling*Rotation;
World._41=Object.Pos.x;
World._42=Object.Pos.y;
World._43=Object.Pos.z;
Device->SetTransform(D3DTS_WORLD,&World);
//Setup render/texture stage states for this object
//...
//Set texture
//Draw Object
}
You can clearly see that nearly every object will follow this except for special effects which might also need to use the view matrix to invert it, etc. But for the most part objects all follow the same rendering path. Because of this it seems to me that one could place the information inside of what I would call object state blocks that would tell the renderer all the pertinent information relating to the current object.
Also since most objects fall into similar categories (billboards, sprites, 3D objects, etc) it seems to me that they should be rendered in batches. As well since all objects must have a vertex buffer it seems plausible to use one huge vertex buffer and specify an index range in the object state block so the renderer knows which indexes in the master vertex buffer to use for this object. Primtive type could also be stored in this section as well or you could setup a structure that could handle multiple primitive types throughout a range of indexes.
Textures would simply be an ID within the class stating which texture the object uses. The actual IDirect3DTexture9 interface would reside in the global list for the currenttly loaded level in memory. This means that any texture can be used on any number of objects but yet still only reside in memory exactly one time. The same holds true for sound effects, etc. I can see a great benefit to storing the actual texture in a list instead of creating a new IDirect3DTexture9 object relative to the object class. You would also be assured of the same texture only existing once and only being destroyed once....you could effectively destroy the list of textures at any time you wanted to and be assured that no other instances of the interface were lurking around in your code. Nice and centralized.
I really think looking this stuff up based on indexes and using an incremental rendering approach with one huge vertex buffer would be much faster than calling virtual render functions for each type of object that has been derived from a base object. I could be wrong but I don't think I am.