I've got a scene and a renderer. In order to draw models, my scene iterates all its high-level models, materials, etc and compile it into a structure (my renderqueue) and is sent of to the renderer which draws it. It has all it needs to draw the scene.
struct RenderableMesh
{
MeshID mMeshID;
Mat4 mWVPMatrix;
Mat4 mWorldMatrix;
};
typedef std::vector<RenderableMesh> RenderableMeshes;
struct RenderableMaterial
{
TextureID mDiffuseTextureID;
TextureID mNormalTextureID;
float mSpecularFactor;
};
struct RenderableModel
{
RenderableMesh mMesh;
RenderableMaterial mMaterial;
float mTextureTilingFactor;
};
typedef std::vector<RenderableModel> RenderableModels;
struct RenderableCamera
{
Mat4 mCameraViewMatrix;
Mat4 mCameraProjectionMatrix;
Vec3 mCameraPosition;
float mFOV;
RenderableModels mModels;
};
struct RenderableDirLight
{
Vec4 mLightColor;
Vec3 mLightDirection;
RenderableMeshes mMeshes;
};
typedef std::vector<RenderableDirLight> RenderableDirLights;
struct RenderablePointLight
{
enum POINT_LIGHT_DIR
{
POINT_LIGHT_DIR_POS_X = 0,
POINT_LIGHT_DIR_NEG_X,
POINT_LIGHT_DIR_POS_Y,
POINT_LIGHT_DIR_NEG_Y,
POINT_LIGHT_DIR_NEG_Z,
POINT_LIGHT_DIR_POS_Z,
POINT_LIGHT_DIR_COUNT
};
Mat4 mWVPMatrix;
Vec4 mLightColor;
Vec3 mLightPosition;
float mLightIntensity;
float mMaxDistance;
std::array<RenderableMeshes, POINT_LIGHT_DIR::POINT_LIGHT_DIR_COUNT> mMeshes;
std::array<Mat4, POINT_LIGHT_DIR::POINT_LIGHT_DIR_COUNT> mFaceWVPMatrices;
};
typedef std::vector<RenderablePointLight> RenderablePointLights;
struct RenderQueue
{
void Clear();
Vec4 mAmbientLight;
RenderableCamera mCamera;
RenderableDirLights mDirectionalLights;
RenderablePointLights mPointLights;
};
I can identify the following problems:
- The renderqueue is quite big. The worst offenders are probably the transforms.
- vectors of vectors. Lots of different locations in memory.
- Duplication of data; the color of a light also exists in high-level scene objects.
I can think of a few alternatives, like keeping all the transforms regardless of node hierarchy in a contigous storage with stable indices and pass around just the indices instead.
I'm mostly just looking for ideas to improve it or different solutions. I'd like to keep the two systems as separate as possible with the bridge between them being the renderqueue.