Show exscn3d.c syntax highlighted
/*
* Example program for the Allegro library, by Bertrand Coconnier.
*
* This program demonstrates how to use scanline sorting algo in Allegro
* (al_create_scene, al_clear_scene, ... functions). It also provides an example
* of how to use the 3D clipping function.
*
*/
#include "allegro.h"
#define MAX_CUBES 4
typedef struct QUAD
{
int v[4];
} QUAD;
AL_V3D_F vertex[] =
{
{ -10., -10., -10., 0., 0., 72 },
{ -10., 10., -10., 0., 0., 80 },
{ 10., 10., -10., 0., 0., 95 },
{ 10., -10., -10., 0., 0., 88 },
{ -10., -10., 10., 0., 0., 72 },
{ -10., 10., 10., 0., 0., 80 },
{ 10., 10., 10., 0., 0., 95 },
{ 10., -10., 10., 0., 0., 88 }
};
QUAD cube[] =
{
{{ 2, 1, 0, 3 }},
{{ 4, 5, 6, 7 }},
{{ 0, 1, 5, 4 }},
{{ 2, 3, 7, 6 }},
{{ 4, 7, 3, 0 }},
{{ 1, 2, 6, 5 }}
};
AL_V3D_F v[4], vout[12], vtmp[12];
AL_V3D_F *pv[4], *pvout[12], *pvtmp[12];
volatile int t;
/* timer interrupt handler */
void tick(void)
{
t++;
}
AL_END_OF_FUNCTION(tick);
/* init_gfx:
* Set up graphics mode.
*/
int init_gfx(AL_PALETTE *pal)
{
int i;
int gfx_mode = AL_GFX_AUTODETECT;
int w, h ,bpp;
/* 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=2; 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;
}
/* 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(&gfx_mode, &w, &h, &bpp)) {
al_remove_system();
return 1;
}
al_set_color_depth(bpp);
if (al_set_gfx_mode(gfx_mode, 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;
}
return 0;
}
/* draw_cube:
* Translates, rotates, clips, projects, culls backfaces and draws a cube.
*/
void draw_cube(AL_BITMAP *buffer, AL_MATRIX_F *matrix, int num_poly)
{
int i, j, nv;
int out[12];
for (i=0; i<num_poly; i++) {
for (j=0; j<4; j++) {
v[j] = vertex[cube[i].v[j]];
al_apply_matrix_f(matrix, v[j].x, v[j].y, v[j].z,
&v[j].x, &v[j].y, &v[j].z);
}
/* nv: number of vertices after clipping is done */
nv = al_clip_3d_f(POLYTYPE_GCOL, 0.1, 1000., 4, (AL_CONST AL_V3D_F**)pv, pvout, pvtmp, out);
if (nv) {
for (j=0; j<nv; j++)
al_persp_project_f(vout[j].x, vout[j].y, vout[j].z, &vout[j].x, &vout[j].y);
if (al_polygon_z_normal_f(&vout[0], &vout[1], &vout[2]) > 0)
al_scene_polygon_3d_f(POLYTYPE_GCOL, NULL, nv, pvout);
}
}
}
int main(void)
{
AL_BITMAP *buffer;
AL_PALETTE pal;
AL_MATRIX_F matrix, matrix1, matrix2, matrix3;
int rx = 0, ry = 0, tz = 40;
int rot = 0, inc = 1;
int i, j, k;
int frame = 0;
float fps = 0.;
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));
/* set up graphics mode */
if (init_gfx(&pal))
return 1;
al_set_palette(pal);
/* initialize buffers and viewport */
buffer = al_create_bitmap(AL_SCREEN_W, AL_SCREEN_H);
al_create_scene(24*MAX_CUBES*MAX_CUBES*MAX_CUBES, 6*MAX_CUBES*MAX_CUBES*MAX_CUBES);
al_set_projection_viewport(0, 0, AL_SCREEN_W, AL_SCREEN_H);
al_text_mode(-1);
/* initialize pointers */
for (j=0; j<4; j++)
pv[j] = &v[j];
for (j=0; j<12; j++) {
pvtmp[j] = &vtmp[j];
pvout[j] = &vout[j];
}
while(!al_key[AL_KEY_ESC]) {
al_clear_bitmap(buffer);
al_clear_scene(buffer);
/* matrix2: rotates cube */
al_get_rotation_matrix_f(&matrix2, rx, ry, 0);
/* matrix3: turns head right/left */
al_get_rotation_matrix_f(&matrix3, 0, rot, 0);
for (k=MAX_CUBES-1; k>=0; k--)
for (j=0; j<MAX_CUBES; j++)
for (i=0; i<MAX_CUBES; i++) {
/* matrix1: locates cubes */
al_get_translation_matrix_f(&matrix1, j*40-MAX_CUBES*20+20, i*40-MAX_CUBES*20+20, tz+k*40);
/* matrix: rotates cube THEN locates cube THEN turns head right/left */
al_matrix_mul_f(&matrix2, &matrix1, &matrix);
al_matrix_mul_f(&matrix, &matrix3, &matrix);
/* cubes are just added to the scene.
* No sorting is done at this stage.
*/
draw_cube(buffer, &matrix, 6);
}
/* sorts and renders polys */
al_render_scene();
al_printf_text(buffer, al_font_8x8, 2, 2, al_palette_color[1], "(%.1f fps)", fps);
al_blit(buffer, al_screen, 0, 0, 0, 0, AL_SCREEN_W, AL_SCREEN_H);
frame++;
/* manage cubes movement */
tz -= 2;
if (!tz) tz = 40;
rx += 4;
ry += 4;
rot += inc;
if ((rot >= 25) || (rot <= -25)) inc = -inc;
/* computes fps */
if (t > 100) {
fps = (100. * frame) / t;
t = 0;
frame = 0;
}
}
al_destroy_bitmap(buffer);
al_destroy_scene();
return 0;
}
AL_END_OF_MAIN();
See more files for this project here