5 #include <cgmath/cgmath.h>
9 KEY_F1 = GLUT_KEY_F1 | 0x100,
10 KEY_F2 = GLUT_KEY_F2 | 0x100,
11 KEY_F3 = GLUT_KEY_F3 | 0x100,
12 KEY_F4 = GLUT_KEY_F4 | 0x100,
13 KEY_F5 = GLUT_KEY_F5 | 0x100,
14 KEY_F6 = GLUT_KEY_F6 | 0x100,
15 KEY_F7 = GLUT_KEY_F7 | 0x100,
16 KEY_F8 = GLUT_KEY_F8 | 0x100,
17 KEY_F9 = GLUT_KEY_F9 | 0x100,
18 KEY_F10 = GLUT_KEY_F10 | 0x100,
19 KEY_F11 = GLUT_KEY_F11 | 0x100,
20 KEY_F12 = GLUT_KEY_F12 | 0x100,
21 KEY_LEFT = GLUT_KEY_LEFT | 0x100,
22 KEY_UP = GLUT_KEY_UP | 0x100,
23 KEY_RIGHT = GLUT_KEY_RIGHT | 0x100,
24 KEY_DOWN = GLUT_KEY_DOWN | 0x100,
25 KEY_PGUP = GLUT_KEY_PAGE_UP | 0x100,
26 KEY_PGDN = GLUT_KEY_PAGE_DOWN | 0x100,
27 KEY_HOME = GLUT_KEY_HOME | 0x100,
28 KEY_END = GLUT_KEY_END | 0x100,
29 KEY_INS = GLUT_KEY_INSERT | 0x100
32 enum { INP_FWD, INP_BACK, INP_RIGHT, INP_LEFT, INP_FIRE, NUM_INPUTS };
34 static int init(void);
35 static void cleanup(void);
36 static void display(void);
37 static void idle(void);
38 static void reshape(int x, int y);
39 static void keydown(unsigned char key, int x, int y);
40 static void keyup(unsigned char key, int x, int y);
41 static void skeydown(int key, int x, int y);
42 static void skeyup(int key, int x, int y);
43 static void mouse(int bn, int st, int x, int y);
44 static void motion(int x, int y);
47 static long start_time;
49 static float cam_theta, cam_phi;
50 static cgm_vec3 cam_pos = {0, -1.6, 0};
51 static float pxform[16];
53 static int mouse_x, mouse_y;
54 static int bnstate[8];
56 static int inpstate[NUM_INPUTS];
58 static int keymap[NUM_INPUTS][2] = {
66 static struct mesh mesh;
68 int main(int argc, char **argv)
70 glutInit(&argc, argv);
71 glutInitWindowSize(1280, 800);
72 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
73 glutCreateWindow("cyberay");
75 glutDisplayFunc(display);
77 glutReshapeFunc(reshape);
78 glutKeyboardFunc(keydown);
79 glutKeyboardUpFunc(keyup);
80 glutSpecialFunc(skeydown);
81 glutSpecialUpFunc(skeyup);
83 glutMotionFunc(motion);
84 glutPassiveMotionFunc(motion);
97 glEnable(GL_CULL_FACE);
99 glEnable(GL_DEPTH_TEST);
100 glEnable(GL_LIGHTING);
103 if(load_mesh(&mesh, "data/testlvl.obj") == -1) {
107 start_time = glutGet(GLUT_ELAPSED_TIME);
111 static void cleanup(void)
116 #define WALK_SPEED 3.0f
117 static void update(void)
119 static unsigned int prev_upd;
121 float dt, vfwd, vright;
123 msec = glutGet(GLUT_ELAPSED_TIME) - start_time;
124 dt = (float)(msec - prev_upd) / 1000.0f;
129 if(inpstate[INP_FWD]) {
130 vfwd -= WALK_SPEED * dt;
132 if(inpstate[INP_BACK]) {
133 vfwd += WALK_SPEED * dt;
135 if(inpstate[INP_RIGHT]) {
136 vright -= WALK_SPEED * dt;
138 if(inpstate[INP_LEFT]) {
139 vright += WALK_SPEED * dt;
142 cam_pos.x += cos(cam_theta) * vright + sin(cam_theta) * vfwd;
143 cam_pos.z += sin(cam_theta) * vright - cos(cam_theta) * vfwd;
145 cgm_midentity(pxform);
146 cgm_mtranslate(pxform, cam_pos.x, cam_pos.y, cam_pos.z);
147 cgm_mrotate_y(pxform, cam_theta);
148 cgm_mrotate_x(pxform, cam_phi);
151 static void display(void)
155 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
157 glMatrixMode(GL_MODELVIEW);
158 glLoadMatrixf(pxform);
161 glutSolidTeapot(1.0);
167 assert(glGetError() == GL_NO_ERROR);
170 static void idle(void)
175 static void reshape(int x, int y)
177 glMatrixMode(GL_PROJECTION);
179 gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0);
182 static void keyb(int key, int press)
186 for(i=0; i<NUM_INPUTS; i++) {
187 if(keymap[i][0] == key || keymap[i][1] == key) {
193 static void keydown(unsigned char key, int x, int y)
195 if(key == 27) exit(0);
199 static void keyup(unsigned char key, int x, int y)
204 static void skeydown(int key, int x, int y)
206 keyb(key | 0x100, 1);
209 static void skeyup(int key, int x, int y)
211 keyb(key | 0x100, 0);
214 static void mouse(int bn, int st, int x, int y)
218 bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN ? 1 : 0;
221 static void motion(int x, int y)
223 int dx = x - mouse_x;
224 int dy = y - mouse_y;
228 if(!(dx | dy)) return;
231 cam_theta += dx * 0.01;
232 cam_phi += dy * 0.01;
234 if(cam_phi < -M_PI) cam_phi = -M_PI;
235 if(cam_phi > M_PI) cam_phi = M_PI;