/* * Copyright (C) 2009 Tilman Sauerbeck (tilman at code-monkey de) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* Renders Archimedean Dynasty (aka Schleichfahrt) model files (*.MOD) * in wireframe mode. * * Probably quite horrible. I suck at OpenGL. */ #include #include #include #include #include #include #include typedef struct { uint32_t id; float x; float y; float z; } ModelVertex; static struct { float x; float y; float z; } camera; static int window; static ModelVertex model_vertices[255]; static int num_vertices; static int cmp_model_vertex (const void *a, const void *b) { const ModelVertex *aa = a; const ModelVertex *bb = b; if (aa->id < bb->id) return -1; else if (aa->id > bb->id) return +1; else return 0; } static void read_file (const char *filename) { FILE *f; int i; f = fopen (filename, "rb"); if (!f) { fprintf (stderr, "cannot open %s\n", filename); exit (EXIT_FAILURE); } fseek (f, 10, SEEK_SET); fread (&num_vertices, 4, 1, f); fseek (f, 18, SEEK_SET); for (i = 0; i < num_vertices; i++) { ModelVertex *vertex = &model_vertices[i]; fread (&vertex->id, 4, 1, f); fread (&vertex->x, 4, 1, f); fread (&vertex->y, 4, 1, f); fread (&vertex->z, 4, 1, f); } fclose (f); #if 0 // sort vertices by id qsort (model_vertices, num_vertices, sizeof (ModelVertex *), cmp_model_vertex); #endif } static void reset_matrix (int width, int height) { glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (45.0f, (GLfloat) width / (GLfloat) height, 0.1f, 100.0f); glMatrixMode (GL_MODELVIEW); } static void init_gl (int width, int height) { glClearColor (0.0f, 0.0f, 0.0f, 0.0f); glClearDepth (1.0); glDepthFunc (GL_LESS); glEnable (GL_DEPTH_TEST); glShadeModel (GL_SMOOTH); reset_matrix (width, height); } static void draw_gl_scene (void) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity (); // Move Left 1.5 Units And Into The Screen 90.0 float into_the_screen = -90.0f; //glTranslatef (-1.5f, 0.0f, into_the_screen); //glTranslatef (0.0f, 0.0f, -120.0f); glTranslatef (camera.x, camera.y, camera.z); // Rotate the triangle on the X axis //glRotatef (-45.0, 1.0f, 0.0f, 0.0f); // Draw wireframe glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); #if 0 glBegin (GL_POLYGON); { int i; for (i = 0; i < 122; i++) { ModelVertex *vertex = &model_vertices[i]; glVertex3f (vertex->x, vertex->y, vertex->z); } } glEnd (); #else glBegin (GL_TRIANGLE_STRIP); { int i; for (i = 0; i < 122; i++) { ModelVertex *vertex = &model_vertices[i]; if (i == 50) glColor3f (1.0, 0.0, 0.0); else glColor3f (0.0, 0.0, 1.0); glVertex3f (vertex->x, vertex->y, vertex->z); } } glEnd (); #endif glutSwapBuffers (); } static void resize_gl_scene (int width, int height) { glViewport (0, 0, width, height); reset_matrix (width, height); } static void key_pressed (unsigned char key, int x, int y) { usleep (100); switch (key) { case 27: glutDestroyWindow (window); exit (0); case 'h': camera.x += 1.0f; break; case 'l': camera.x -= 1.0f; break; case 'j': camera.y += 1.0f; break; case 'k': camera.y -= 1.0f; break; case 'a': camera.z += 1.0f; break; case 'z': camera.z -= 1.0f; break; default: printf("%i\n", key); break; } } int main (int argc, char **argv) { /* Read the MOD file. */ read_file (argv[1]); camera.x = 0.0f; camera.y = 0.0f; camera.z = 0.0f; glutInit (&argc, argv); glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH); glutInitWindowSize (640, 480); window = glutCreateWindow ("foo"); glutDisplayFunc (draw_gl_scene); glutIdleFunc (draw_gl_scene); glutReshapeFunc (resize_gl_scene); glutKeyboardFunc (key_pressed); init_gl (640, 480); glutMainLoop (); return EXIT_SUCCESS; }