Hopefully, I got it right this time.
Code below demostrates calling dbSync() at a user specific rendering rate( Note: can set anything at or lower then the moniter refresh rate ) and movement based on time itself. Hopefully, this will show smooth 3d movement and also frees up CPU time when expected.
I don't just check how long a single frame takes to then multiply that by movement. Instead, in general, when a movement action takes place, save the current time at start of movement and also save the current position and/or rotation state. Then as the movement action is taken place, we add or subtract the time difference from the saved "timestart", multiply the camera/object's speed to that. Add that result to the saved "starting position/rotation" and then apply that result to the dbPositionObject() and/or dbRotateObject ( or camera equivalent or whatever else equivalent... ). Do that until the movememt action stops. Once a movement action starts again, we do all of above again.
Ok, mabie I cant explain things well...
Code below should show ya what I did to abtain "smoother" 3d movement. I still think there is a slight "jittering" of movement. Though my eyes are getting tired right now... I could be seeing things.
If you indeed see annoying jittering, please do tell. IF you can make this any smoother, please do share.
Hopefully you likes, enjoy
#include "DarkGDK.h"
void DarkGDK ( void )
{
char txt[256];
// ----------------- time variables
double timeStart;
double timeCurrent;
double timeOld;
int timeTick;
double timeLastRenderElasped;
double timeFPS;
double framerate;
timeStart = (double)dbTimer()/1000.0;
timeCurrent = timeStart;
timeOld = (double)dbTimer()/1000.0;
timeTick = 0;
timeLastRenderElasped = 0.0;
timeFPS = 0.0;
framerate = (1000.0/60.0)/1000.0; // Target 60 Renders Per Second
// Currently, framerate can not go over monitor refresh rate! This is by the GDK's design.
// ----------------- number of displayed objects
int numofobjects;
numofobjects=200;
// ----------------- Variables to control time based movoment
// With the camera, we start movement action via up and down arrows
double cameraTimeStart=0.0;
double cameraSpeed=10;
int cameraUpKey=0;
int cameraDownKey=0;
double TimeCamPosZ=0.0;
double CamPosZ=0.0;
// With the rotating objects, we start movement action here as thier
// movement is constant for this demo...
double TimeObjAngleX=0.0;
double TimeObjAngleY=0.0;
double TimeObjAngleZ=0.0;
double ObjAngleX=0.0;
double ObjAngleY=0.0;
double ObjAngleZ=0.0;
double ObjAngleXTimeStart=(double)dbTimer()/1000.0;
double ObjAngleYTimeStart=(double)dbTimer()/1000.0;
double ObjAngleZTimeStart=(double)dbTimer()/1000.0;
// ----------------- setup window/graphics
dbRandomize ( dbTimer() );
dbSyncOff();
dbAutoCamOff( );
int Desktop_Width;
int Desktop_Height;
int Dekstop_Depth;
Desktop_Width=GetSystemMetrics(0);
Desktop_Height=GetSystemMetrics(1);
HDC hdc;
hdc=GetDC(0);
Dekstop_Depth=GetDeviceCaps(hdc,12);
ReleaseDC(0,hdc);
dbSetWindowPosition(0,0);
dbSetDisplayMode(Desktop_Width,Desktop_Height,Dekstop_Depth);
dbSetWindowOff();
dbMakeCamera( 1 );
dbColorBackdrop( 1, dbRGB(16,0,16) );
// make some 3D objects
for ( int i = 1; i < numofobjects; i++ )
{
// make a sphere
dbMakeObjectSphere ( i, 1 );
// position the object in a random location
dbPositionObject ( i, dbRnd ( 200 )-100, dbRnd ( 200 )-100, dbRnd ( 200 )-100 );
// adjust scaling
dbScaleObject ( i, 100 + dbRnd ( 1200 ), 100 + dbRnd ( 1200 ), 100 + dbRnd ( 1200 ) );
// give the object a color
dbColorObject ( i, dbRgb ( 255, dbRnd ( 255 ), 255 ) );
// increase specular power
dbSetObjectSpecularPower ( i, 255 );
// turn off ambient lighting for this object
dbSetObjectAmbient ( i, 0 );
}
// move our camera back so we can view the objects
dbPositionCamera ( 1, 10, 10, -20 );
// main loop
while ( LoopGDK ( ) )
{
timeTick++;
// move the camera forwards
if(dbUpKey() && cameraUpKey==0)
{
cameraUpKey=1;
cameraDownKey=0;
}
else // move the camera backwards
if(dbDownKey() && cameraDownKey==0)
cameraDownKey=1;
if(dbUpKey()==0 && cameraUpKey==2)
cameraUpKey=0;
else
if(dbDownKey()==0 && cameraDownKey==2)
cameraDownKey=0;
if(cameraUpKey>0)
{
if(cameraUpKey==1) // call this code only once while upkey is being pushed down
{
cameraUpKey=2;
cameraTimeStart=(double)dbTimer()/1000.0; // save the time when this camera movement action is started
TimeCamPosZ=dbCameraPositionZ(1); // save the camera's position when this movement action is started
}
// While up key is still being pushed,
// subtract current time from the saved time start of this movement action,
// then multiply camera's movement speed to that time difference
// then for the forward movment, ADD the result to the saved position from the start of this action,
// then apply the new camera position's result to the dbPositionCamera function.
CamPosZ=TimeCamPosZ+((((double)dbTimer()/1000.0)-cameraTimeStart)*cameraSpeed);
dbPositionCamera( 1, dbCameraPositionX(1),dbCameraPositionY(1),CamPosZ);
}
else
if(cameraDownKey>0)
{
if(cameraDownKey==1)// call this code only once while downkey is being pushed down
{
cameraDownKey=2;
cameraTimeStart=(double)dbTimer()/1000.0;
TimeCamPosZ=dbCameraPositionZ(1);
}
// Exact same method used here for keydown as upkey. Except for the backward movement,
// subtract the result from the saved position from the start of this action.
CamPosZ=TimeCamPosZ-((((double)dbTimer()/1000.0)-cameraTimeStart)*cameraSpeed);
dbPositionCamera( 1, dbCameraPositionX(1),dbCameraPositionY(1),CamPosZ );
}
// rotate all of our objects
for ( int i = 1; i < numofobjects; i++ )
{
// this demo we saved the object's rotation once before the main loop began.
// We probably should update the saved data at every full rotation, 360 degrees, hadn't tried it yet.
// As these objects have constant rotation movement during this demo,
// all we do is to update new rotation result to the dbRotateObject function.
// It's basically the same way as we did above with the camera positioning.
ObjAngleX=TimeObjAngleX+((((double)dbTimer()/1000.0)-ObjAngleXTimeStart)*10.0);
ObjAngleY=TimeObjAngleY+((((double)dbTimer()/1000.0)-ObjAngleYTimeStart)*20.0);
ObjAngleZ=TimeObjAngleZ+((((double)dbTimer()/1000.0)-ObjAngleZTimeStart)*30.0);
dbRotateObject ( i, ObjAngleX, ObjAngleY, ObjAngleZ );
}
// Here we render the at the chosen frame rate
// Note: I dont get exactly the frame rate desired, but it's real close.
// dont know why it cant peg the desired frame rate... ??
timeLastRenderElasped = ((double)dbTimer()/1000.0)-timeOld;
if (timeLastRenderElasped>=framerate)
{
timeOld=(double)dbTimer()/1000.0;
sprintf(txt,"RPS=%d FPS=%f, framerate=%f",dbScreenFPS(),timeFPS,framerate);
dbText(10,70,txt);
dbSync ( );
}
// Here we get the Frames Per Second ( or Loops Per Second )
timeCurrent = ((double)dbTimer()/1000.0)-timeStart;
if (timeCurrent >=1.0)
{
timeFPS = ((double)timeTick);
timeTick=0;
timeStart= (double)dbTimer()/1000.0;
}
}
// before quitting delete our objects
//for ( int i = 1; i < numofobjects; i++ )
//dbDeleteObject ( i );
return;
}
Inspirational Music: Descent ][ Redbook Audio CD Soundtrack