Ok guys let me add my two cents here and that's probably what it will be worth.
First
This design is already so complicated that you cannot even discuss it correctly.
Therefore - scrap it. It won't add to speed, graphics, gameplay, or even manage objects well. What it will do as evidenced by this thread is confuse the hell out of ya.
Scrap it.
Using one function as an overall function for rendering is a great idea, however, you are approaching it incorrectly.
Now pay attention because this is what Dae and CornedBee and Bob and all of us are saying. The ONLY common portion of any graphical object to be rendered are:
Vertex data
Texture data
Physics data
Here is my suggestion. Throw templates out the window and throw the class inheritance virtual function thingy out the window. Too complicated. The problem with C++ inheritance is that when you look at your code you cannot tell at a glance what is happening because the inheritance is so deep.
Get my drift here. I don't like virtual functions because they obfuscate the code quite easily with more than 1 derivation w/o adding that much flexibility to the engine.
I don't like this:
Code:
class Base
{
virtual void Render()=0;
}
class Derived1:public Object
{
void Render();
}
class Derived2:public Object
{
void Render();
}
class Derived3:public Object
{
void Render();
}
Way too many renders for something that can be done in one function.
Here is what I do like:
1. Each object allocates it's vertex memory from a huge pool.
2. The pool manager will return a starting index and an ending index for the data.
3. Texture coord data is contained within the pool.
4. Physics data is contained within the pool.
Like this - ALL objects will have the following information, but not ALL objects will use every field in the structures. Texture coord data is contained in the VertexData struct I'll show this using vectors for now, later you would change to a static array IF your framerates suffered. I doubt they will.
Code:
struct PhysicsData
{
};
class PhysicsContainer
{
}
struct VertexData
{
};
class VertexContainer
{
};
struct PositionData
{
};
class PositionContainer
{
};
class MatrixData
{
};
class MatrixContainer
{
};
class TextureData
{
};
class TextureContainer
{
};
struct ObjectInfo
{
DWORD dwStartIndex;
DWORD dwEndIndex;
DWORD dwID;
DWORD *dwTextureIDs;
};
class Object
{
ObjectInfo ObjectData;
//One object may have more matrices
//This is for transformation
MatrixContainer Matrices;
};
class ResourceCache
{
PhysicsContainer Physics;
VertexContainer Vertices;
PositionContainer Positions;
TextureContainer Textures;
};
class RenderList
{
ResourceCache *RenderData;
std::vector<DWORD> ObjectIDs;
};
So now all the main areas of information are encapsulated for each object and the rendering list simply has a vector that can be added to in order to create the render list. I would try to use a static array but the render list is built every frame so it's a bit tedious and time consuming.
The final render list simply holds a list of IDs that are indices into the other containers for that object. So.
Everything is based on IDs. The final result is that everything amounts to:
1 function call, 1 lookup.
If you make the arrays or vectors public in the container classes, then you don't even have to do the function call.
This is a bit complex, but in the end it is very easy to use - it's just hard to setup.
Sounds would use the same idea. All sounds reside in a sound container and can be accessed via their ID number.
The final render list is simply a huge list of IDs of the objects that are visible in the current frame. The transformation engine then just iterates through this list, grabs the vertex and position information for that ID, grabs the matrix stack (if applicable) from the object, and transforms the object. Then the renderer will grab the texture data, etc, etc.
This is a work in progress so there is still stuff to work out, but I hope you get what I'm saying here.