Thanks guys,
I'm nothing if not creative... I've got creativity flowing out my @$@#$. I just have trouble focusing it sometimes. These challenges are short enough for me to do some serious research without feeling like I'm working.
@RoarLee -- If you get something near to completion feel free to post it. Of course, if you were the only one besides me to post anything, you'd assume responsibility for keeping things going for a week until somebody else posted a winner.
Since this is the week of Christmas, most of us will be very busy. Rather than saying "no challenge this week" I'll make it super simple. This challenge will be to simply use multiple cameras. So put a simple scene together and use two, three or a million cameras to spice it up.
Out of curiosity, how many cameras can the GDK process?
I promise to post at least one sample this week, but with the holidays I'll be busy. All of you be safe, spend some time with your loved ones, pretend to be happy you got another fruitcake and have a Merry Christmas!
-Frank
[edit]
Ok, here's a minor modification of my submission from the last challenge. It's just a quick modification using two cameras to create an interesting effect. Dunno if I'll post another example for this challenge with the holidays and all.
#include "DarkGDK.h"
/******************************************************************************
* Constants
******************************************************************************/
// textures
const int g_texParticle = 1;
const int g_texMatrix = 2;
//**/ this was added for the camera demo
/**/ const int g_texScreen = 3;
// matrix information
const int g_objMatrix = 1;
const int g_size = 400;
const int g_border = g_size / 2;
// number of targets
const int g_numTargets = 50;
// available target numbers to use for the g_sun and g_moon objects
const int g_sun = g_numTargets + 1;
const int g_moon = g_numTargets + 2;
// universal target info
const int g_maxLife = 1000;
const int g_particleLife = 20;
// target object
struct sTarget {
int obj, cycle, counter;
float x, y, z, dx, dy, dz;
};
struct sTarget targets[g_numTargets];
// stuff for our "celestial bodies" and the light they emit
float g_sunAngle = 0;
float g_skyColor = 0.18;
float g_dAngle = 0.1;
float g_dColor = g_dAngle / 1000.0;
/******************************************************************************
* Function prototypes
******************************************************************************/
void init(void);
void makeTextures(void);
void makeWorld(void);
void makeTargets(void);
void makeLights(void);
void update(void);
void updateTargets(void);
void updateLights(void);
void semiRandomTile(int left, int top, int width, int height, int rMax, int gMax, int bMax);
//**/ this was added for the camera demo
/**/ void makeCameras(void);
/******************************************************************************
* the main entry point for the application is this function
******************************************************************************/
void DarkGDK(void) {
init();
// our main loop
while (LoopGDK()) {
dbControlCameraUsingArrowKeys(1, 1.0, 5.0);
// update the screen
update();
dbSync();
}
// return back to windows
return;
}
/******************************************************************************
* Perform all of our initialization stuff
******************************************************************************/
void init(void) {
// turn on sync rate and set maximum rate to 60 fps
dbSyncOn();
dbSyncRate(60);
// initialize the back buffer
dbSync();
// hide the mouse and turn off the autocam feature
dbHideMouse();
dbAutoCamOff();
// make the application fullscreen (method 1 -- this should usually work)
dbSetWindowOff();
// make the application fullscreen (method 2 -- use this when you have problems with method 1)
// dbSetWindowLayout(0, 0, 0);
// dbMaximizeWindow();
// initialize the relevant parts of the scene
makeTextures();
makeWorld();
makeTargets();
makeLights();
//**/ this was added for the camera demo
makeCameras();
}
/******************************************************************************
* Make all of our textures
******************************************************************************/
void makeTextures(void) {
//**/ this was modified for the camera demo
// create a temporary workspace bitmap
dbCreateBitmap(1, 640, 480);
// get our particle texture
dbInk(dbRGB(255, 255, 255), 0);
dbBox(2, 2, 3, 3);
dbGetImage(g_texParticle, 0, 0, 6, 6);
// get our matrix texture
semiRandomTile(0, 0, 256, 256, 32, 128, 64);
dbGetImage(g_texMatrix, 0, 0, 256, 256);
//**/ this was added for the camera demo
dbGetImage(g_texScreen, 0, 0, 640, 480);
// toggle all drawing operations back to the screen (bitmap #0)
dbSetCurrentBitmap(0);
// delete our workspace
dbDeleteBitmap(1);
}
/******************************************************************************
* Build our scene
******************************************************************************/
void makeWorld(void) {
// make floor using a matrix -- I haven't figured out how to properly light a large plane
dbMakeMatrix(g_objMatrix, g_size, g_size, 50, 50);
dbPrepareMatrixTexture(g_objMatrix, g_texMatrix, 1, 1);
dbSetMatrix(g_objMatrix, 0, 0, 1, 1, 1, 1, 1);
dbPositionMatrix(g_objMatrix, -(g_size / 2), 0, -(g_size / 2));
dbUpdateMatrix(g_objMatrix);
}
/******************************************************************************
* Make all of our target spheres and their related particle systems
******************************************************************************/
void makeTargets(void) {
int i, r, g, b;
for (i = 0; i < g_numTargets; i++) {
// set the target's color
r = (dbRnd(3) + 1) * 63;
g = (dbRnd(3) + 1) * 63;
b = (dbRnd(3) + 1) * 63;
// set the targets object number
targets[i].obj = i+1;
// set the cycle to the "sphere" cycle
targets[i].cycle = 1;
// set the target's lifetime for this cycle
targets[i].counter = dbRnd(g_maxLife);
// set the target's starting position
targets[i].x = dbRnd(g_size) - (g_border);
targets[i].y = dbRnd(10) + 10;
targets[i].z = dbRnd(g_size) - (g_border);
// set the targets direction, disallowing values of 0
targets[i].dx = dbRnd(1);
if (targets[i].dx == 0) { targets[i].dx = -1; }
targets[i].dy = (dbRnd(1)) / 10.0;
if (targets[i].dy == 0) { targets[i].dy = -0.1; }
targets[i].dz = dbRnd(1);
if (targets[i].dz == 0) { targets[i].dz = -1; }
// make the target sphere -- our visual cue as to where the targets are
dbMakeObjectSphere(targets[i].obj, 10.0);
dbPositionObject(targets[i].obj, targets[i].x, targets[i].y, targets[i].z);
dbColorObject(targets[i].obj, dbRGB(r, g, b));
// initialize the particle system for the target -- notice emissions is set to 0 for now
dbMakeParticles(targets[i].obj, 1, 10, 10);
dbSetParticleEmissions(targets[i].obj, 0);
dbSetParticleSpeed(targets[i].obj, 0.01);
dbSetParticleGravity(targets[i].obj, 2.0);
dbColorParticles(targets[i].obj, r, g, b);
dbPositionParticleEmissions(targets[i].obj, targets[i].x, targets[i].y, targets[i].z);
}
}
/******************************************************************************
* Initialize all of the lights for our scene
******************************************************************************/
void makeLights(void) {
int g_sunColor = dbRGB(255, 255, 192);
int g_moonColor = dbRGB(64, 64, 72);
// setting this to 0 lets us see the effects of our lights
dbSetAmbientLight(0);
// make the sun light (range chosen after a bit of tinkering)
dbSetPointLight(0, 0, g_size, 0);
dbColorLight(0, g_sunColor);
dbSetLightRange(0, g_size * 1000);
// make a sphere object for our sun
dbMakeObjectSphere(g_sun, 200);
// snag a copy of the mesh to use as the actual sun
dbMakeMeshFromObject(1, g_sun);
// add the mesh as a new limb and position it at "high noon"
dbAddLimb(g_sun, 1, 1);
dbOffsetLimb(g_sun, 1, 0, g_size*2, 0);
// delete the mesh
dbDeleteMesh(1);
// hide the base limb -- I don't know if there's a better way, but this worked
dbHideLimb(g_sun, 0);
// make the sun glow
dbSetObjectEmissive(g_sun, g_sunColor);
// dbGhostObjectOn(g_sun);
// make our moon light
dbMakeLight(1);
dbSetPointLight(1, 0, g_size, 0);
dbColorLight(1, g_moonColor);
dbSetLightRange(1, g_size * 2);
// make the moon object
dbMakeObjectSphere(g_moon, 100);
// snag a copy of the mesh to use as the actual moon
dbMakeMeshFromObject(1, g_moon);
// add the mesh from before as a new limb and position it at "high noon"
dbAddLimb(g_moon, 1, 1);
dbOffsetLimb(g_moon, 1, 0, g_size*2, 0);
// hide the base limb -- I don't know if there's a better way, but this worked
dbHideLimb(g_moon, 0);
// delete the mesh
dbDeleteMesh(1);
// make the moon glow
dbSetObjectEmissive(g_moon, g_moonColor);
dbGhostObjectOn(g_moon);
// make the player light (follows the camera)
dbMakeLight(2);
dbSetPointLight(2, 0, 10, 0);
dbColorLight(2, dbRGB(0, 64, 255));
dbSetLightRange(2, 40);
}
/******************************************************************************
* Calls the other update functions -- I just wrote this to clean up the
* game loop a bit -- for speed purposes, I would remove it in the future.
******************************************************************************/
void update(void) {
updateTargets();
updateLights();
}
/******************************************************************************
* Update the targets every cycle
******************************************************************************/
void updateTargets(void) {
int i;
float x, z, angle;
// update each one of the targets
for (i = 0; i < g_numTargets; i++) {
// modify the target's position based on the direction modifiers
targets[i].x += targets[i].dx;
targets[i].y += targets[i].dy;
targets[i].z += targets[i].dz;
// if the target is at the edge of our scene, reverse it's direction
if ((targets[i].x < -g_border) || (targets[i].x > g_border)) {
targets[i].dx *= -1;
}
if ((targets[i].y < 5) || (targets[i].y > 50)) {
targets[i].dy *= -1;
}
if ((targets[i].z < -g_border) || (targets[i].z > g_border)) {
targets[i].dz *= -1;
}
// decrement the cycle counter (sphere vs. particle)
targets[i].counter -= 1;
// check for when the current cycle is ended
if (targets[i].counter == 0) {
// if the "sphere" cycle just ended
if (targets[i].cycle == 1) {
// hide the target sphere
dbHideObject(targets[i].obj);
// tell the particle system to start emitting 10 particles per frame(?)
dbSetParticleEmissions(targets[i].obj, 10);
// set the cycle to last for 20 cycles
targets[i].counter = g_particleLife;
}
else { // otherwise the "particle" cycle has ended
// show the target sphere
dbShowObject(targets[i].obj);
// reposition the target at a random location
targets[i].x = dbRnd(g_size) - (g_border);
targets[i].y = dbRnd(10) + 10;
targets[i].z = dbRnd(g_size) - (g_border);
// tell the particle system to stop emitting
dbSetParticleEmissions(targets[i].obj, 0);
// set the cycle to last for a random number of cycles up to g_maxLife
targets[i].counter = dbRnd(g_maxLife);
}
// toggle between cycles (1 and -1)
targets[i].cycle *= -1;
}
// position the target elements
dbPositionObject(targets[i].obj, targets[i].x, targets[i].y, targets[i].z);
dbPositionParticleEmissions(targets[i].obj, targets[i].x, targets[i].y, targets[i].z);
}
}
/******************************************************************************
* Update the lights every cycle
******************************************************************************/
void updateLights(void) {
float x, y, z, color;
g_sunAngle = dbWrapValue(g_sunAngle + g_dAngle);
dbXRotateObject(g_sun, g_sunAngle);
dbXRotateObject(g_moon, dbWrapValue(g_sunAngle + 180));
x = dbLimbPositionX(g_sun, 1);
y = dbLimbPositionY(g_sun, 1);
z = dbLimbPositionZ(g_sun, 1);
dbPositionLight(0, x, y, z);
x = dbLimbPositionX(g_moon, 1);
y = dbLimbPositionY(g_moon, 1);
z = dbLimbPositionZ(g_moon, 1);
dbPositionLight(1, x, y, z);
// get the "live" camera's position
x = dbCameraPositionX(1);
z = dbCameraPositionZ(1);
dbPositionLight(2, x, 10, z);
if ((g_sunAngle > 0) && (g_sunAngle <= 180)) {
g_skyColor -= g_dColor;
} else {
g_skyColor += g_dColor;
}
dbColorBackdrop(1, dbRGB(255*g_skyColor, 255*g_skyColor*1.25, 255*g_skyColor*2));
}
/******************************************************************************
* This makes a tile at a specific location, in the specified color with
* variations in the saturation level.
******************************************************************************/
void semiRandomTile(int left, int top, int width, int height, int rMax, int gMax, int bMax) {
double red, green, blue;
int sat;
// convert all of our color values to a number between 0.0 and 1.0
red = rMax / 255.0;
green = gMax / 255.0;
blue = bMax / 255.0;
// locking the pixes speeds up most image functions
dbLockPixels();
// place dots of random saturation levels all throughout our tile
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// pick a saturation level between 50-100% (RGB values of 128-255)
sat = dbRnd(127) + 128;
dbInk(dbRGB(red * sat, green * sat, blue * sat), 0);
dbDot(x + left, y + top);
}
}
// unlock the pixels so we can get back to work
dbUnlockPixels();
}
void makeCameras(void){
int i, j;
// this is our "live" camera that responds to user input
dbMakeCamera(1);
dbPositionCamera(1, 0, 5, 0);
// render the "live" camera to a texture for our sprites
dbSetCameraToImage(1, g_texScreen, 640, 480);
// turn the backdrop on because otherwise the camera won't work right
dbBackdropOn(1);
dbColorBackdrop(1, 0);
// position our "view" camera under the scene (tucked away where we can't see it)
// I don't think this really matters considering that we're locking sprites to
// the camera, thus blocking this camera's view of the scene
dbPositionCamera(0, 0, -10, 0);
// make the uncolored sprite (upper left)
dbSprite(1, 0, 0, g_texScreen);
dbSizeSprite(1, 320, 240);
dbSetSpriteTextureCoord(1, 0, 0, 0);
dbSetSpriteTextureCoord(1, 1, 0.5, 0);
dbSetSpriteTextureCoord(1, 2, 0, 0.5);
dbSetSpriteTextureCoord(1, 3, 0.5, 0.5);
// make the red sprite (upper right)
dbSprite(2, 320, 0, g_texScreen);
dbSizeSprite(2, 320, 240);
dbSetSpriteTextureCoord(2, 0, 0.5, 0);
dbSetSpriteTextureCoord(2, 1, 1, 0);
dbSetSpriteTextureCoord(2, 2, 0.5, 0.5);
dbSetSpriteTextureCoord(2, 3, 1, 0.5);
dbSetSpriteDiffuse(2, 255, 0, 0);
// make the green sprite (lower left)
dbSprite(3, 0, 240, g_texScreen);
dbSizeSprite(3, 320, 240);
dbSetSpriteTextureCoord(3, 0, 0, 0.5);
dbSetSpriteTextureCoord(3, 1, 0.5, 0.5);
dbSetSpriteTextureCoord(3, 2, 0, 1);
dbSetSpriteTextureCoord(3, 3, 0.5, 1);
dbSetSpriteDiffuse(3, 0, 255, 0);
// make the blue sprite (lower right)
dbSprite(4, 320, 240, g_texScreen);
dbSizeSprite(4, 320, 240);
dbSetSpriteTextureCoord(4, 0, 0.5, 0.5);
dbSetSpriteTextureCoord(4, 1, 1, 0.5);
dbSetSpriteTextureCoord(4, 2, 0.5, 1);
dbSetSpriteTextureCoord(4, 3, 1, 1);
dbSetSpriteDiffuse(4, 0, 0, 255);
}
[/edit]