Mail Archives: djgpp/1997/10/13/14:45:29
From: | dyad255 AT aol DOT com (Dyad255)
|
Newsgroups: | comp.os.msdos.djgpp
|
Subject: | Re: Plush with Allegro framebuffer -- "apex.c" (13kb)
|
Date: | 13 Oct 1997 09:48:20 GMT
|
Lines: | 437
|
Message-ID: | <19971013094801.FAA24711@ladder01.news.aol.com>
|
NNTP-Posting-Host: | ladder01.news.aol.com
|
Organization: | AOL http://www.aol.com
|
To: | djgpp AT delorie DOT com
|
DJ-Gateway: | from newsgroup comp.os.msdos.djgpp
|
Example program intended to demonstrate some use of the configurable Allegro
2.2 framebuffer by the Plush 1.1 3D rendering system. Hacked from someone to
Norman MacDonald to me. Offers command-line and run-time options ('apex -?'
describes them) for affecting various features. Might have used 3DS objects
like the Plush examples, but stuck with the tori. You can blame a little bad
code on me. 8)
// apex.c
// ********** INCLUDES **********
#include <float.h> // for _control87() when using DJGPP/Watcom
#include <stdio.h>
#include <conio.h> // getch()
#include <stdlib.h>
#include <string.h>
#include <allegro.h>
#include <plush.h>
// ********** DEFAULTS & DEFINES **********
#define GFX_MODE GFX_AUTODETECT // Allegro graphics mode (c.f.)
#define DEFAULT_WIDTH 320
#define DEFAULT_HEIGHT 200
#define NUM_OBJECTS 3
#define DEFAULT_TORI_STRIPS 8
#define DEFAULT_TORI_SECTIONS 8
#define DEFAULT_SHADING_MODE PL_SHADE_GOURAUD // Plush shading mode (c.f.)
#define DEFAULT_SPIN 6.0
#define DEFAULT_TRANSPARENCY 2
#define DEFAULT_SHININESS 8
// ********** GLOBAL VARIABLES **********
int counter = 0; // General counter
int done = 0; // General conditional
int wait_vsync = 1; // Wait for vsync?
BITMAP *temp; // Allegro, for blitting rendered scene to
pl_ZBuffer *zbuffer;
pl_Cam *Camera;
pl_Light *Light;
pl_Obj *Object[NUM_OBJECTS]; // Objects
pl_Mat *Material[NUM_OBJECTS]; // Materials (each for the corresponding Object)
// These can be set later (at startup) by command-line parameters
int vWidth = DEFAULT_WIDTH, vHeight = DEFAULT_HEIGHT;
pl_uInt AllToriiStrips = DEFAULT_TORI_STRIPS;
pl_uInt AllToriiSections = DEFAULT_TORI_SECTIONS;
// These can be altered later (at run-time) with keyboard commands
pl_uChar AllShadeType = DEFAULT_SHADING_MODE;
pl_uChar AllTransparency, GivenTransparency = DEFAULT_TRANSPARENCY;
pl_uInt AllShininess = DEFAULT_SHININESS;
int AllSpinRate = DEFAULT_SPIN;
// ********** FUNCTIONS **********
void SetupMaterials(); // Setup objects and map to palettes
void StartObjects(); // Create objects, render in loops until keypress
// ********** MAIN **********
int main(int argc, char **argv)
{
// For perspective correction to work?
#if defined(DJGPP) || defined(__WATCOMC__)
// Put the fpu in a low precision, no exception state
_control87(MCW_EM|PC_24, MCW_EM|MCW_PC);
#endif
// ********** COMMAND LINE PARSING BEGINS **********
// Check if user wants help
if ((argc > 1 && !stricmp(argv[1],"-?")) ||
(argc > 2 && !stricmp(argv[2],"-?")) ||
(argc > 3 && !stricmp(argv[3],"-?")) ||
(argc > 4 && !stricmp(argv[4],"-?")) ||
(argc > 5 && !stricmp(argv[5],"-?")) ||
(argc > 6 && !stricmp(argv[6],"-?")) ||
(argc > 7 && !stricmp(argv[7],"-?")) ||
(argc > 8 && !stricmp(argv[8],"-?")) ||
(argc > 9 && !stricmp(argv[9],"-?")) ||
(argc > 10 && !stricmp(argv[10],"-?")))
{
// If so:
allegro_exit(); // exit Allegro,
printf("\n"); // show command line options,
printf("APEx: Allegro 2.2+WIP and Plush 1.1 example\n");
printf("\n [command-line options]\n");
printf("-vsize WxH video size (default %dx%d)\n", DEFAULT_WIDTH,
DEFAULT_HEIGHT);
printf("-r n # tori strips (3-uInt) (default %d)\n",
DEFAULT_TORI_STRIPS);
printf("-c n # tori sections (3-uInt) (default %d)\n",
DEFAULT_TORI_SECTIONS);
printf("-t n global transparency (default %d)\n",
DEFAULT_TRANSPARENCY);
printf("-? this help text\n");
printf("\n [real-time keyboard commands]\n");
printf("[ESC] exit\n");
printf("-/= zoom out/in");
printf("g use gouraud shading (default)\n");
printf("f use flat shading\n");
printf("n use no shading\n");
printf("t toggles transparency (set above)\n");
printf("s/S -/+ 1 shininess (default %d)\n", DEFAULT_SHININESS);
printf("v toggle vsync (wait for screen refresh)\n");
printf("z toggle z-buffer/sort-whole-polygons\n");
exit(0); // and exit program with no errors
}
// Check if user has specified a video size
for (counter = 1; counter < argc - 1; counter++)
{
if (!stricmp(argv[counter], "-vsize")) // If user enters switch at current
argc
sscanf(argv[counter + 1], "%dx%d",&vWidth,&vHeight); // Take info from
current argc + 1
}
// Check if user supplied tori radial divisions (strips)
for (counter = 1; counter < argc - 1; counter++)
{
if (!stricmp(argv[counter], "-r")) // If user enters switch at current argc
sscanf(argv[counter + 1],"%d", &AllToriiStrips); // Take info from current
argc + 1
}
// Check if user supplied tori circumference divisions (sections)
for (counter = 1; counter < argc - 1; counter++)
{
if (!stricmp(argv[counter], "-c")) // If user enters switch at current argc
sscanf(argv[counter + 1],"%d", &AllToriiSections); // Take info from current
argc + 1
}
// Check if user supplied a global transparency
for (counter = 1; counter < argc - 1; counter++)
{
if (!stricmp(argv[counter], "-t")) // If user enters switch at current argc
{
sscanf(argv[counter + 1],"%d", &GivenTransparency); // Take info from
current argc + 1
AllTransparency = GivenTransparency;
}
}
allegro_init(); // Initializes Allegro
StartObjects(); // Big setup & looping routine
// Finishing up...
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); // Set screen mode to DOS text
allegro_exit(); // Exit Allegro
exit(0); // Exit with an error code of 0
}
// ********** BIG SETUP & LOOPING ROUTINE **********
void StartObjects()
{
// Setup the screen mode
if (set_gfx_mode(GFX_MODE, vWidth, vHeight, 0, 0))
{
// If it fails:
allegro_exit(); // exit Allegro,
printf("Graphics mode not supported.\n"); // print error message,
exit(1); // and exit program with an error
}
// Allocate the temporary screen bitmap
temp = create_bitmap(vWidth,vHeight);
// Allocate the zbuffer
zbuffer = (pl_ZBuffer *) malloc(sizeof(pl_ZBuffer)*vWidth*vHeight);
// Allocate as many materials as objects
for(counter = 0; counter < NUM_OBJECTS; counter++)
Material[counter] = plMatCreate();
// Setup the initial material properties and map them to palette
SetupMaterials();
// Create 3 tori objects from corresponding materials
Object[0] = plMakeTorus(70, 30, AllToriiSections, AllToriiStrips,
Material[0]);
Object[1] = plMakeTorus(90, 50, AllToriiSections, AllToriiStrips,
Material[1]);
Object[2] = plMakeTorus(110, 70, AllToriiSections, AllToriiStrips,
Material[2]);
// Create and setup the light
Light = plLightCreate();
plLightSet(Light, PL_LIGHT_VECTOR, 0, 0, 0, 1, 0);
// Create the camera
Camera = plCamCreate(vWidth,vHeight, vWidth*3.0/(vHeight*4.0),
80.0, temp->dat, zbuffer);
Camera->Sort = 0; // There is initially a zbuffer, so don't sort polygons
Camera->Z = -300; // Start back a fair distance
// Setup starting angles for the objects
Object[0]->Xa = 0.0;
Object[0]->Za -= 36.0;
Object[1]->Xa += 36.0;
Object[1]->Za = 0.0;
Object[2]->Xa -= 36.0;
Object[2]->Za = 0.0;
// Start the object movement
while (!done)
{
// Rotate the objects
Object[0]->Za += AllSpinRate;
Object[1]->Xa += AllSpinRate;
Object[2]->Ya += AllSpinRate;
// Clear the temp screen bitmap
clear(temp);
if (Camera->zBuffer) memset(Camera->zBuffer, 0, sizeof(pl_ZBuffer)*
Camera->ScreenWidth*Camera->ScreenHeight);
// Do the rendering
plRenderBegin(Camera); // Start render
plRenderLight(Light); // Render Light
// Render all the objects
for(counter = 0; counter < NUM_OBJECTS; counter++)
plRenderObj(Object[counter]);
plRenderEnd(); // Finish render
if (wait_vsync) vsync(); // Wait for vsync (Allegro)
// Write the temp screen bitmap to the screen
blit(temp, screen, 0, 0, 0, 0, Camera->ScreenWidth, Camera->ScreenHeight);
// Handle keyboard input
while (kbhit()) switch(getch())
{
// ESC = quit
case 27:
done++;
break;
// - is for zooming out
case '-':
Camera->Fov += 1.0; if (Camera->Fov > 179.0) Camera->Fov = 179.0;
break;
// = or + are for zooming in
case '=': case '+':
Camera->Fov -= 1.0; if (Camera->Fov < 1.0) Camera->Fov = 1.0;
break;
// g = gouraud shading
case 'g':
AllShadeType = PL_SHADE_GOURAUD; // set global shading mode
SetupMaterials();
break;
// f = flat shading
case 'f':
AllShadeType = PL_SHADE_FLAT; // set global shading mode
SetupMaterials();
break;
// n = no shading
case 'n':
AllShadeType = PL_SHADE_NONE; // set global shading mode
SetupMaterials();
break;
// s and S decrease and increase global shininess
case 's':
AllShininess += (AllShininess > 65534) ? 0 : 1;
SetupMaterials();
break;
case 'S':
AllShininess -= (AllShininess < 1) ? 0 : 1;
SetupMaterials();
break;
// t toggles global transparency
case 't':
AllTransparency = (AllTransparency == 0) ? GivenTransparency : 0;
SetupMaterials();
break;
// , and . decrease and increase global spin rate
case ',':
AllSpinRate -= 1;
break;
case '.':
AllSpinRate += 1;
break;
// v toggles vsync
case 'v':
wait_vsync ^= 1;
break;
// z toggles zbuffer
case 'z':
if (Camera->zBuffer) // If the camera is currently using the zbuffer,
{
Camera->zBuffer = 0; // make the camera ignore the zbuffer,
Camera->Sort = 1; // and sort the polygons instead
}
else // The camera's not using the zbuffer, so...
{
Camera->zBuffer = zbuffer; // point it to our zbuffer
Camera->Sort = 0; // and turn polygon sorting off
}
break;
}
}
// Close down world: Free up memory used by the Plush objects, Allegro
bitmaps, and zbuffer
for(counter = 0; counter < NUM_OBJECTS; counter++)
{
plObjDelete(Object[counter]);
plMatDelete(Material[counter]);
}
plLightDelete(Light);
plCamDelete(Camera);
free(zbuffer);
// Destroy the temporary Allegro bitmap
destroy_bitmap(temp);
}
// ********** SET UP MATERIALS AND PALETTES **********
void SetupMaterials()
{
// Local variables for setting palettes
pl_Mat *AllMaterials[NUM_OBJECTS + 1]; // Null-terminated list of materials
int x;
PALETTE pal; // Allegro palette (set below using Plush palette)
pl_uChar cpal[768]; // Plush palette
memset(cpal, 0, 768);
// Setup material properties
Material[0]->ShadeType = AllShadeType; // see defines and key commands
Material[0]->NumGradients = 96;
Material[0]->Ambient[0] = 200;
Material[0]->Ambient[1] = 0;
Material[0]->Ambient[2] = 0;
Material[0]->Diffuse[0] = 0;
Material[0]->Diffuse[1] = 200;
Material[0]->Diffuse[2] = 0;
Material[0]->Specular[0] = 0;
Material[0]->Specular[1] = 0;
Material[0]->Specular[2] = 200;
Material[0]->Shininess = AllShininess; // see defines and key commands
Material[0]->Transparent = AllTransparency; // see defines and key commands
Material[0]->Environment = NULL;
Material[0]->Texture = NULL;
Material[0]->PerspectiveCorrect = 0;
Material[0]->zBufferable = TRUE;
Material[0]->FadeDist = 0.0;
// Setup material properties
Material[1]->ShadeType = AllShadeType; // see defines and key commands
Material[1]->NumGradients = 96;
Material[1]->Ambient[0] = 0;
Material[1]->Ambient[1] = 200;
Material[1]->Ambient[2] = 0;
Material[1]->Diffuse[0] = 0;
Material[1]->Diffuse[1] = 0;
Material[1]->Diffuse[2] = 200;
Material[1]->Specular[0] = 200;
Material[1]->Specular[1] = 0;
Material[1]->Specular[2] = 0;
Material[1]->Shininess = AllShininess; // see defines and key commands
Material[1]->Transparent = AllTransparency; // see defines and key commands
Material[1]->Environment = NULL;
Material[1]->Texture = NULL;
Material[1]->PerspectiveCorrect = 0;
Material[1]->zBufferable = TRUE;
Material[1]->FadeDist = 0.0;
// Setup material properties
Material[2]->ShadeType = AllShadeType; // see defines and key commands
Material[2]->NumGradients = 96;
Material[2]->Ambient[0] = 0;
Material[2]->Ambient[1] = 0;
Material[2]->Ambient[2] = 200;
Material[2]->Diffuse[0] = 200;
Material[2]->Diffuse[1] = 0;
Material[2]->Diffuse[2] = 0;
Material[2]->Specular[0] = 0;
Material[2]->Specular[1] = 200;
Material[2]->Specular[2] = 0;
Material[2]->Shininess = AllShininess; // see defines and key commands
Material[2]->Transparent = AllTransparency; // see defines and key commands
Material[2]->Environment = NULL;
Material[2]->Texture = NULL;
Material[2]->PerspectiveCorrect = 0;
Material[2]->zBufferable = TRUE;
Material[2]->FadeDist = 0.0;
// Must initialize map materials and add to a list before mapping to palette
for(counter = 0; counter < NUM_OBJECTS; counter++)
{
plMatInit(Material[counter]);
AllMaterials[counter] = Material[counter];
}
AllMaterials[NUM_OBJECTS] = 0; // Null-terminate the list
// Generate an optimal palette from the list of materials
plMatMakeOptPal(cpal, 1, 255, AllMaterials); // Start at 1 instead of 0,
cpal[0] = cpal[1] = cpal[2] = 0; // because that's always black
// Now map the individual materials to the palette
for(counter = 0; counter < NUM_OBJECTS; counter++)
plMatMapToPal(Material[counter], cpal, 0, 255);
// Palette conversion for Allegro
for (x = 0; x < 256; x++)
{
pal[x].r = cpal[x*3+0] >> 2; // Convert red
pal[x].g = cpal[x*3+1] >> 2; // Convert green
pal[x].b = cpal[x*3+2] >> 2; // Convert blue
}
set_palette(pal); // Set The Palette
}
- Raw text -