Show exzbuf.c syntax highlighted
/*
* Example program for the Allegro library, by Bertrand Coconnier.
*
* This program demonstrates how to use Z-buffered polygons and
* floating point 3D math routines. It also provides a simple way
* to compute fps (frames per second) using the interrupt handler.
*
*/
#include <stdio.h>
#include "allegro.h"
typedef struct FACE
{
int v1, v2, v3, v4;
} FACE;
AL_V3D_F cube1[] =
{
{ -32., -32., -32., 0., 0., 72},
{ -32., 32., -32., 0., 0., 80},
{ 32., 32., -32., 0., 0., 95},
{ 32., -32., -32., 0., 0., 88},
{ -32., -32., 32., 0., 0., 72},
{ -32., 32., 32., 0., 0., 80},
{ 32., 32., 32., 0., 0., 95},
{ 32., -32., 32., 0., 0., 88}
};
AL_V3D_F cube2[] =
{
{ -32., -32., -32., 0., 0., 104},
{ -32., 32., -32., 0., 0., 112},
{ 32., 32., -32., 0., 0., 127},
{ 32., -32., -32., 0., 0., 120},
{ -32., -32., 32., 0., 0., 104},
{ -32., 32., 32., 0., 0., 112},
{ 32., 32., 32., 0., 0., 127},
{ 32., -32., 32., 0., 0., 120}
};
FACE faces[] =
{
{ 2, 1, 0, 3 },
{ 4, 5, 6, 7 },
{ 0, 1, 5, 4 },
{ 2, 3, 7, 6 },
{ 4, 7, 3, 0 },
{ 1, 2, 6, 5 }
};
volatile int t;
/* timer interrupt handler */
void tick(void)
{
t++;
}
AL_END_OF_FUNCTION(tick);
/* update cube positions */
void anim_cube(AL_MATRIX_F* matrix1, AL_MATRIX_F* matrix2, AL_V3D_F x1[], AL_V3D_F x2[])
{
int i;
for (i=0; i<8; i++) {
al_apply_matrix_f(matrix1, cube1[i].x, cube1[i].y, cube1[i].z, &(x1[i].x), &(x1[i].y), &(x1[i].z));
al_apply_matrix_f(matrix2, cube2[i].x, cube2[i].y, cube2[i].z, &(x2[i].x), &(x2[i].y), &(x2[i].z));
al_persp_project_f(x1[i].x, x1[i].y, x1[i].z, &(x1[i].x), &(x1[i].y));
al_persp_project_f(x2[i].x, x2[i].y, x2[i].z, &(x2[i].x), &(x2[i].y));
}
}
/* cull backfaces and draw cubes */
void draw_cube(AL_BITMAP* buffer, AL_V3D_F x1[], AL_V3D_F x2[])
{
int i;
for (i=0; i<6; i++) {
AL_V3D_F vtx1, vtx2, vtx3, vtx4;
vtx1 = x1[faces[i].v1];
vtx2 = x1[faces[i].v2];
vtx3 = x1[faces[i].v3];
vtx4 = x1[faces[i].v4];
if (al_polygon_z_normal_f(&vtx1, &vtx2, &vtx3) > 0)
al_quad_3d_f(buffer, POLYTYPE_GCOL | POLYTYPE_ZBUF, NULL, &vtx1, &vtx2, &vtx3, &vtx4);
vtx1 = x2[faces[i].v1];
vtx2 = x2[faces[i].v2];
vtx3 = x2[faces[i].v3];
vtx4 = x2[faces[i].v4];
if (al_polygon_z_normal_f(&vtx1, &vtx2, &vtx3) > 0)
al_quad_3d_f(buffer, POLYTYPE_GCOL | POLYTYPE_ZBUF, NULL, &vtx1, &vtx2, &vtx3, &vtx4);
}
}
int main()
{
AL_ZBUFFER *zbuf;
AL_BITMAP *buffer;
AL_PALETTE pal;
AL_MATRIX_F matrix1, matrix2;
AL_V3D_F x1[8], x2[8];
int i;
int c = AL_GFX_AUTODETECT;
int w, h, bpp;
int frame = 0;
float fps = 0.;
float rx1, ry1, rz1; /* cube #1 rotations */
float drx1, dry1, drz1; /* cube #1 rotation speed */
float rx2, ry2, rz2; /* cube #2 rotations */
float drx2, dry2, drz2; /* cube #1 rotation speed */
float tx = 16.; /* x shift between cubes */
float tz1 = 100.; /* cube #1 z coordinate */
float tz2 = 105.; /* cube #2 z coordinate */
allegro_init();
al_install_keyboard();
al_install_mouse();
al_install_timer();
LOCK_VARIABLE(t);
LOCK_FUNCTION(tick);
al_create_timer(tick, MSEC_TO_TIMER(10));
/* color 0 = black */
pal[0].r = pal[0].g = pal[0].b = 0;
/* color 1 = red */
pal[1].r = 255;
pal[1].g = pal[1].b = 0;
/* copy the desktop palette */
for (i=1; i<64; i++)
pal[i] = al_desktop_palette[i];
/* make a blue gradient */
for (i=64; i<96; i++) {
pal[i].b = (i-64)*2;
pal[i].g = pal[i].r = 0;
}
/* make a green gradient */
for (i=96; i<128; i++) {
pal[i].g = (i-96)*2;
pal[i].r = pal[i].b = 0;
}
/* set the graphics mode */
if (al_set_gfx_mode(AL_GFX_SAFE, 320, 200, 0, 0) != 0) {
al_set_gfx_mode(AL_GFX_NONE, 0, 0, 0, 0);
al_show_message("Unable to set any graphic mode\n%s\n", al_error);
return 1;
}
al_set_palette(al_desktop_palette);
w = AL_SCREEN_W;
h = AL_SCREEN_H;
bpp = al_bitmap_color_depth(al_screen);
if (!al_select_gfx_mode(&c, &w, &h, &bpp)) {
al_remove_system();
return 1;
}
al_set_color_depth(bpp);
if (al_set_gfx_mode(c, w, h, 0, 0) != 0) {
al_set_gfx_mode(AL_GFX_NONE, 0, 0, 0, 0);
al_show_message("Error setting graphics mode\n%s\n", al_error);
return 1;
}
al_set_palette(pal);
/* double buffer the animation and create the Z-buffer */
buffer = al_create_bitmap(AL_SCREEN_W, AL_SCREEN_H);
zbuf = al_create_zbuffer(buffer);
al_set_zbuffer(zbuf);
/* set up the viewport for the perspective projection */
al_set_projection_viewport(0, 0, AL_SCREEN_W, AL_SCREEN_H);
/* compute rotations and speed rotation */
rx1 = ry1 = rz1 = 0.;
rx2 = ry2 = rz2 = 0.;
drx1 = ((rand() & 31) - 16) / 4.;
dry1 = ((rand() & 31) - 16) / 4.;
drz1 = ((rand() & 31) - 16) / 4.;
drx2 = ((rand() & 31) - 16) / 4.;
dry2 = ((rand() & 31) - 16) / 4.;
drz2 = ((rand() & 31) - 16) / 4.;
/* set the transformation matrices */
al_get_transformation_matrix_f(&matrix1, 1., rx1, ry1, rz1, tx, 0., tz1);
al_get_transformation_matrix_f(&matrix2, 1., rx2, ry2, rz2, -tx, 0., tz2);
/* set colors */
for (i=0; i<8; i++) {
x1[i].c = al_palette_color[cube1[i].c];
x2[i].c = al_palette_color[cube2[i].c];
}
/* main loop */
while(1) {
al_clear_bitmap(buffer);
al_clear_zbuffer(zbuf, 0.);
anim_cube(&matrix1, &matrix2, x1, x2);
draw_cube(buffer, x1, x2);
/* update transformation matrices */
rx1 += drx1;
ry1 += dry1;
rz1 += drz1;
rx2 += drx2;
ry2 += dry2;
rz2 += drz2;
al_get_transformation_matrix_f(&matrix1, 1., rx1, ry1, rz1, tx, 0., tz1);
al_get_transformation_matrix_f(&matrix2, 1., rx2, ry2, rz2, -tx, 0., tz2);
al_printf_text(buffer, al_font_8x8, 10, 1, al_palette_color[1], "Z-buffered polygons (%.1f fps)", fps);
al_vsync();
al_blit(buffer, al_screen, 0, 0, 0, 0, AL_SCREEN_W, AL_SCREEN_H);
frame++;
if (t > 100) {
fps = (100. * frame) / t;
t = 0;
frame = 0;
}
if (al_key_pressed()){
if ((al_read_key() & 0xFF) == 27)
break;
}
}
al_destroy_bitmap(buffer);
al_destroy_zbuffer(zbuf);
return 0;
}
AL_END_OF_MAIN();
See more files for this project here