In my rendering system each manager is responsible for rendering it's own objects and building the final render list utilizing frustum culling and so forth.
...
Comments? I'd be interested in how you are managing all of this Bob. I've got a headache from figuring this out on paper and then attempting to code it. Just for a release of tension I must say Resources suck
In all honesty, I think that you can appreciate many aspects of how I do things but that you wouldn't really like my layout. Keep in mind my renderer (I have a class called GLRenderer) is not as sophisticated as yours, so with respect to specifically a renderer, I simply cannot help you. I have not ventured into anything but fixed pipeline GL rendering.
I don't have a class for managing things such as a spaceship, but in creating an object, say a hovertank, I use basically the same principles as you.
I don't do anything silly with memory, I always allocate memory with these macros which check for allocation errors:
Code:
#ifndef MEM_MAN_H
#define MEM_MAN_H
#include <assert.h>
#include <crtdbg.h>
#define NT_SAFE_ALLOC(dest,type,size) dest = new type[size]; _ASSERTE(_CrtCheckMemory());
#define NT_SAFE_DELETE(array) if(array){delete[] array; array = NULL;}
#define NT_ZERO_MEM(array,struct_type,num) memset(array,0,sizeof(struct_type)*num);
#endif
Here's how I make some textures:
Code:
gSkySphere.texture = gpTextureManager->CreateTexture("sphericalsky03.jpg");
...
//this is an alpha texture but it is handled automatically
ParticleTexture = gpTextureManager->CreateTexture("particle.tga");
Here's how I allocate a new hovertank:
Code:
NT_SAFE_ALLOC(pTest_Hovertank,Hovertank,1)
The hovertank class has a static model. There is only one model that is actually loaded, this is the master copy, I count the number of hovertanks in existance, and I create the master model when the first hovertank is made (in the constructor), and I delete the master copy when none are left. Each child hovertank simply reuses the master copy. This is how I manage models! The model is an internal format, NT_MODEL, which is optimized for rendering.
The physics manager holds a list of rigid bodies. In the main source file I setup the properties for all of the rigid bodies, then I simply add them to the physics manager, e.g.:
Code:
pTest_Hovertank->mStaticFriction = .1f;
pTest_Hovertank->mDynamicFriction = .1f;
pTest_Hovertank->mStiffness = .35f;
pTest_Hovertank->SetMass( 250.0f ); //automatically sets up inertia matrix for sphere
pTest_Hovertank->mAirCushion = Air_Cushion::Air_Cushion(pTest_Hovertank->GetMass(),pTest_Hovertank->mRadius,
170.0f,pTest_Hovertank->mRadius + 35.0f,5.0f,5.0f,10);
gpPhysicsManager->ADD_RIGID_BODY(pTest_Hovertank);
Here is how my main cycle loop looks:
If enough time has passed:
{
-Gather inputs
-Update framerate
-Reset the physics time buffer
-Update all objects AI before physics is run
-Render all physics frames (run the physics manager)
-Run each object's render hook. Each object adds itself to the GLRenderer, the objects do not render themselves. A hovertank simply adds an NT_MODEL to the GLRenderer, but only if the sphere is in the frustum. If debug mode is on, I can also add a wireframe sphere around the hovertank, or debug lines, or anything else I want, because the rendering does actually happen until the next step. I am thinking that when I want to incorporate shaders I will write a shader manager, and attach shaders to each type of object. This will get tricky when dealing with the order of rendering, juggling textures, lights, etc (which is exactly the probs you are having, lol)
-Render the scene (including text)
}
else
{
Add the time passed to the physics time buffer
}
Physics runs at 100.0f FPS, the graphics runs at 100.0f FPS or less. If the rendering is for some reason going only at 50.0f FPS then the physics time buffer notices it has enough to run 2 physics frames, so it goes ahead and runs 2 physics frames (the delta time per physics frame is constant, which assists in keeping numerical stability).
I can't really think of anything else to say that could really give you any insight. I think that you have engineered your resource management more than I have, but I'm afraid that you may be over engineering it to the point that it's getting too cumbersome to be useful in some regards. I mean, there are all sorts of clever ways to sort objects based on what objects share the same texture on the first texture pass, and clever culling algorithms, etc, but I made this VERY simple:
-Every type of thing that I can possibly draw has a data type
-Each object culls itself, the RENDERER knows nothing about CULLING. The renderer *just* draws anything given to it, it's a hungry hungry drawing machine and cares about nothing else in its existence.
I don't have to specify which objects are renderable or not, there's no 'renderable' baseclass or anything like that. If something wants to be drawn, it just needs to add stuff to the renderer, then the stuff it added will get drawn later on.