From your code:
Code:
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
render();
...
This is probably the main issue. What you are doing is checking to see if there are any Windows messages and if there are you process them. But you do not render if there was a message. This means that if 50 messages come in succession you will not render for 50 frames.
Consider this:
Code:
while(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Update(timeDelta);
Render();
...
Update updates the scene and all objects that need to be updated. Render then will draw all the items. You are updating and rendering in one function.
Another suspect area is this:
Code:
createCamera(1.0f, 1000.0f); // near clip plane, far clip plane
Why are you re-computing the same exact projection matrix every frame? You are not changing the near or far plane so the matrix is not going to change. The only matrices that will change are the view matrix produced by the camera and the world matrices of the objects.
Also prefer not to use D3DTS_PROJECTION and D3DTS_VIEW and instead you can use D3DTS_WORLD and set it to the world * view * projection. After all the following equations yield the same result:
World = world matrix of object
View = view matrix of camera
Projection = projection matrix of camera
matWVP = World * View * Projection
World = World * View * Projection
View = Identity
Projection = Identity
matWVP = World * View * Projection
Prefer to set the projection and view matrices a minimum amount of times to render the scene. Setting these causes Direct3D to do a lot of internal housekeeping that will degrade performance.
Calling this function per frame is slow:
Code:
void createCamera(float nearClip, float farClip)
{
// Here we specify the field of view, aspect ratio and near and far clipping planes
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, float(WINSIZE_WIDTH)/WINSIZE_HEIGHT, nearClip, farClip);
pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}
- D3DX_PI /4 is invariant and does not change for the life of the application and is also equivalent to D3DX_PI * 0.25f
- WINSIZE_WIDTH / WINSIZE_HEIGHT is also invariant
- nearClip and farClip are invariant
- matProj is invariant
If you set your compiler optimizations in release builds it should optimize out this invariant code but I would not rely on that.
A couple of other items of interest:
- Create a proper camera class - your camera will not work in all orientations. The camera class should only re-compute the view matrix when the camera orientation has changed.
- Consider using quaternions for rotation instead of Euler angles or prefer to use axis-angle representation instead of the D3DXMatrixRotationX/Y/Z functions. If you concatenate these the resulting matrix can suffer from gimbal lock
- Consider making planet, sun, and moon objects and/or derive from a common base type and place them in a render list. This will allow for efficient frustum culling when you get to it.
- Consider using hierarchichal transforms for your system so that moon can orbit planet and planet and moon can orbit sun - Equation for transform is: Parent * World or Parent * Scale * Rotate * Translate. Parent of the moon is planet and parent of the planet is sun. One problem here is that when the sun rotates the entire system will rotate but you can solve that as well.