#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <SDL/SDL.h>
#include "mini3d.h"
#if defined(__unix__) || defined(unix)
#include <unistd.h>
#else
#include <windows.h>
#define usleep(x) Sleep(x)
#endif
int init(void);
void update_gfx(void);
void clean_up(void);
void parse_cmdline(int argc, char **argv);
int xsz = 640;
int ysz = 480;
SDL_Surface *fbsurf;
#define MESH_NVERT 5535
#define MESH_NNORM 29124
#define MESH_NFACE 9708
extern float vertices[MESH_NVERT][3];
extern float normals[MESH_NNORM][3];
extern int triangles[MESH_NFACE][3];
int main(int argc, char **argv) {
parse_cmdline(argc, argv);
if(init() == -1) {
return EXIT_FAILURE;
}
for(;;) {
SDL_Event event;
if(SDL_PollEvent(&event)) {
if(event.type == SDL_KEYDOWN && event.key.keysym.sym == 27) {
break;
}
} else {
const static unsigned int frame_interval = 33;
static int prev_time;
int frame_time, cur_time;
update_gfx();
frame_time = (cur_time = SDL_GetTicks()) - prev_time;
if(frame_time < frame_interval) {
usleep((frame_interval - frame_time) * 1000);
}
prev_time = cur_time;
}
}
clean_up();
return 0;
}
int init(void) {
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
if(!(fbsurf = SDL_SetVideoMode(xsz, ysz, 32, SDL_SWSURFACE))) {
fputs("SDL init failed\n", stderr);
return -1;
}
m3d_init();
m3d_viewport(0, 0, xsz, ysz);
m3d_clear_color(0, 0, 0, 0);
m3d_clear_depth(1);
m3d_enable(M3D_DEPTH_TEST);
m3d_enable(M3D_LIGHTING);
m3d_enable(M3D_LIGHT0);
m3d_matrix_mode(M3D_PROJECTION);
m3d_load_identity();
m3d_perspective(45.0, 1.33333, 100.0, 1000.0);
{
float dif[] = {0.2, 0.4, 1.0, 1.0};
float spec[] = {1, 1, 1, 1};
m3d_materialv(M3D_DIFFUSE, dif);
m3d_materialv(M3D_SPECULAR, spec);
m3d_material(M3D_SHININESS, 60.0f);
}
return 0;
}
void update_gfx(void) {
int i, j;
uint32_t *pixels;
float t = (float)SDL_GetTicks() / 10.0f;
m3d_clear(M3D_COLOR_BUFFER_BIT | M3D_DEPTH_BUFFER_BIT);
m3d_matrix_mode(M3D_MODELVIEW);
m3d_load_identity();
m3d_translate(0, 0, 870);
m3d_rotate(t, 0, 1, 0);
m3d_begin(M3D_TRIANGLES);
for(i=0; i<MESH_NFACE; i++) {
for(j=2; j>=0; j--) {
int nidx = i * 3 + j;
int vidx = triangles[i][j];
m3d_normal(normals[nidx][0], normals[nidx][1], normals[nidx][2]);
m3d_vertex(vertices[vidx][0], vertices[vidx][1], vertices[vidx][2]);
}
}
m3d_end();
pixels = m3d_get_pixel_data();
SDL_LockSurface(fbsurf);
memcpy(fbsurf->pixels, pixels, xsz * ysz * 4);
SDL_UnlockSurface(fbsurf);
SDL_Flip(fbsurf);
}
void clean_up(void) {
m3d_destroy();
SDL_Quit();
}
void parse_cmdline(int argc, char **argv) {
int i;
char *sep;
for(i=1; i<argc; i++) {
if(argv[i][0] == '-' && argv[i][2] == 0) {
switch(argv[i][1]) {
case 's':
if(!isdigit(argv[++i][0]) || !(sep = strchr(argv[i], 'x')) || !isdigit(*(sep+1))) {
fprintf(stderr, "malformed -s argument: \"%s\"\n", argv[i]);
exit(EXIT_FAILURE);
}
xsz = atoi(argv[i]);
ysz = atoi(sep + 1);
break;
case 'h':
default:
fprintf(stderr, "usage: example [-s WxH]\n");
exit(argv[i][1] == 'h' ? 0 : EXIT_FAILURE);
}
} else {
fprintf(stderr, "unrecognized argument: %s\n", argv[i]);
exit(EXIT_FAILURE);
}
}
}