Ok gang,
I started this but I wanted to get some feedback before I went any further. My goal was to eventually work through all of the Dark GDK commands using simple programs that are excessively commented like what I've included here. The aim would be to provide a very clear understanding of the functions to newcomers as well as point out some of the common pitfalls.
I'm not an expert on Dark GDK but this seems like something that might help the community. It's a ton of work though so I want to make sure there is ample interest before I dig too far. The following is the first program and is an example of the excessive commenting style I would be using. Also, if anyone else is interested in helping with this I'd appreciate it.
-Frank
These are the specifice Dark GDK commands used. Some of these commands have multiple methods of being called but only the methods below were used in this example:
dbAutoCamOff()
dbHideMouse()
dbMakeObjectCube(int object, float size)
dbMakeObjectSphere(int object, float size)
dbPositionCamera(float x, float y, float z)
dbPositionObject(int object, float x, float y, float z)
dbSetWindowOff()
dbSync()
dbSyncOn()
dbSyncRate(int rate)
dbText(int x, int y, char* string)
dbWrapValue(float value)
dbYRotateObject(int object, float angle)
And here is the code example:
//=============================================================================
// Learning Dark GDK Tutorial Series
// by Frank Taylor (forum username pharoseer)
//
// This series is designed to eventually show SIMPLE examples of every command
// in the Dark GDK to help a new user to more quickly get on their feet. I'll
// try to showcase all of the possible ways a function can be called as well
// as bugs and/or features that were missed in the documentation. I'm not an
// expert by any means so I'm sure I'll miss things from time to time. If I do
// just let me know and I'll set out to correct the example(s) in question as
// quickly as possible.
//=============================================================================
//=============================================================================
// This example shows the effects of some of the sync commands. These commands
// dictate how often the screen gets redrawn and ultimately how often we see
// changes in our scene. You could spin a cube forever, but without updating
// the screen we'd never know it.
//
// This can me very important. Suppose that we have to make more than one
// change to more than one object every frame. By default, DGDK will update
// the screen after each change. Another important thing to note is that if
// our program is running in Windowed mode (the default for DGDK) then our
// framerate is restricted by the desktop settings.
//=============================================================================
#include "DarkGDK.h"
//-----------------------------------------------------------------------------
// Let's declare a global integer variable for our framerate.
//-----------------------------------------------------------------------------
int g_syncRate = 30;
//-----------------------------------------------------------------------------
// Function prototypes -- this is a C++ convention and is not specific to DGDK
// This simply allows us to call functions in our DarkGDK() function that
// are written later in the file. If this doesn't make sense to you, I would
// recommend finding some C/C++ tutorials/resources on the web. It's what I
// had to do. :)
//-----------------------------------------------------------------------------
void initScene(void);
float updateScene(float angle);
//=============================================================================
// the main entry point for the application is this function
//=============================================================================
void DarkGDK(void) {
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// This angle is used to update our scene so that we can see the effects
// of changing our sync options.
//-------------------------------------------------------------------------
float angle = 0.0;
//-------------------------------------------------------------------------
// Until we call the dbSyncOn() command the application handles the screen
// refresh on its own.
//-------------------------------------------------------------------------
dbSyncOn();
//-------------------------------------------------------------------------
// dbSyncRate() is used to specify a desired frame rate to update the
// screen. This is not absolute and will fluctuate based on the computer's
// ability. Think of it more as a speed limit than anything. We can go as
// fast as this, but no faster (well, maybe a little). Setting dbSyncRate()
// to 0 (zero) allows the computer to run as fast as it can.
//-------------------------------------------------------------------------
dbSyncRate(g_syncRate);
// set up our simple scene -- see the function below
initScene();
// our main loop
while (LoopGDK()) {
// update our simple scene -- see the function below
angle = updateScene(angle);
//---------------------------------------------------------------------
// After calling dbSyncOn() the screen is NEVER updated unless we
// specifically tell it to. So that we can see our changes, let's
// call dbSync() to update the screen.
//---------------------------------------------------------------------
dbSync();
}
// return back to windows
return;
}
//=============================================================================
// This function initializes the scene. It creates the objects, hides the
// mouse cursor, goes into fullscreen mode and positions the camera.
//=============================================================================
void initScene(void) {
//-------------------------------------------------------------------------
// Calling this tells the camera not to move unless we tell it to. By
// default the camera repositions itself so that any newly created object
// is centered in our view. This is seldom desired and forgetting to turn
// this behavior off can result in very strange problems. I would
// recommend calling this before creating any objects.
//-------------------------------------------------------------------------
dbAutoCamOff();
//-------------------------------------------------------------------------
// Hide the mouse cursor. You can still respond to the mouse, but the
// system will not provide you with a visual indicator of where it is.
// This is useful if you simply want the cursor hidden for a demo, or if
// you want to make a custom cursor using a sprite (I'll talk about this
// another time).
//-------------------------------------------------------------------------
dbHideMouse();
//-------------------------------------------------------------------------
// By default Dark GDK runs in a window. Calling this sets the application
// to fullscreen mode using the default resolution of 640x480. I think
// that the color depth is set to the highest number of colors allowed.
//-------------------------------------------------------------------------
dbSetWindowOff();
//-------------------------------------------------------------------------
// Make a simple cube object. It's object number is 1, it's size is 1.0
// and it is centered at the origin (0, 0, 0). The object number can be
// used to perform operations on the object. The size is the length of an
// edge of the cube.
//-------------------------------------------------------------------------
dbMakeObjectCube(1, 1.0);
//-------------------------------------------------------------------------
// Make a simple sphere object with a diameter (NOT radius) of 1.0. See
// the explanation on making a cube above for more detail.
//-------------------------------------------------------------------------
dbMakeObjectSphere(2, 1.0);
//-------------------------------------------------------------------------
// This positions an object within the world. The first parameter is the
// object number. If you review the two previous commands to make objects
// you will notice that dbMakeObjectSphere() uses an object number of 2.
// This matches the following command so we will be positioning our sphere
// at the (X,Y,Z) coordinates given. The following is a basic description
// of the X, Y, and Z coordinates and the effect they will have on an
// object.
//
// X - left to right axis (positive X moves object right)
// Y - up and down axis (positive Y moves object up)
// Z - forward and back axis (positive Z moves object forward)
//-------------------------------------------------------------------------
dbPositionObject(2, 0, 0.5, 0);
//-------------------------------------------------------------------------
// Position the camera back far enough that we can see everything. There
// are three variations of this function. The version shown here uses the
// currently selected camera. By default camera 0 (zero) is assumed if
// none is specified. If you had multiple cameras (for example camera 0
// and camera 1) you could position a specific camera as follows:
//
// dbPositionCamera(cameraNumber, X, Y, Z);
//
// where cameraNumber is the camera you want to move and X, Y, Z represents
// the location you want to move the camera to.
//
// The other method would be to pass X, Y and Z in as a vector. I will
// try to explain that at another time.
//-------------------------------------------------------------------------
dbPositionCamera(0, 0, -5);
}
//=============================================================================
// This function updates the scene. It rotates the cube object and displays
// some information on screen regarding our desired and actual frame rates.
//=============================================================================
float updateScene(float angle) {
// create a variable to hold our text messages
char strTemp[256];
//-------------------------------------------------------------------------
// Rotate object 1 (our cube object) by the angle specified. It is
// important to notice that constantly calling this function with the same
// value will not cause a rotation. You are rotating TO a specific angle,
// not BY the angle.
//-------------------------------------------------------------------------
dbYRotateObject(1, angle);
//-------------------------------------------------------------------------
// Update our angle so that we can achieve rotation. The command
// dbWrapValue() restricts the angle to the range of [0-360]. If angle
// exceeds either amount it is "wrapped" around to the other end. For
// example when angle = 360 and the following is run, angle + 1.0 will
// equal 361. This isn't allowed by dbWrapValue() so it "wraps" the value
// back to 1.
//-------------------------------------------------------------------------
angle = dbWrapValue(angle + 1.0);
//-------------------------------------------------------------------------
// This should be at least mildly familiar to anyone with C/C++ experience.
// If this command bewilders you, I would advise searching the web or your
// local library/bookstore for a decent C/C++ programming guide.
//-------------------------------------------------------------------------
sprintf(strTemp, "Sync Rate Set To : %d", g_syncRate);
//-------------------------------------------------------------------------
// This command takes our newly made string, strTemp, and displays it in
// the current drawing color (the default is white) at the 2D coordinates
// specified. These coordinates are not related to the 3D coordinates we
// used to make our objects but are rather the actual pixel coordinates.
//-------------------------------------------------------------------------
dbText(10, 10, strTemp);
//-------------------------------------------------------------------------
// See the previous explanations
//-------------------------------------------------------------------------
sprintf(strTemp, "Actual Frame Rate : %d", dbScreenFPS());
dbText(10, 30, strTemp);
//-------------------------------------------------------------------------
// By returning our modified angle we can keep track of it between calls to
// this function. Without returning it, it wouldn't change between calls.
//-------------------------------------------------------------------------
return angle;
}
[edit]
I have a habit of checking my posts after submitting to proofread them. Anyway, I noticed that the code example was pretty much unreadable without the syntax coloring in Visual Studio. Would it be a good idea to have versions with and without the comments?
[/edit]