10 #include "cgmath/cgmath.h"
12 static int ginit(void);
13 static void gdestroy(void);
14 static int gstart(void);
15 static void gstop(void);
16 static void gdisplay(void);
17 static void greshape(int x, int y);
18 static void gkeyb(int key, int press);
19 static void gmouse(int bn, int press, int x, int y);
20 static void gmotion(int x, int y);
22 static void set_light_dir(int idx, float x, float y, float z);
23 static void set_light_color(int idx, float r, float g, float b, float s);
26 struct game_screen scr_game = {
31 gkeyb, gmouse, gmotion
34 static float view_mat[16], proj_mat[16];
36 static float cam_theta, cam_phi, cam_dist;
37 static cgm_vec3 cam_pan;
39 static struct goat3d *gscn;
43 static int ginit(void)
47 float *varr, *narr, *uvarr;
50 if(!(gscn = goat3d_create()) || goat3d_load(gscn, "data/level1.g3d")) {
54 dlist = glGenLists(1);
55 glNewList(dlist, GL_COMPILE);
56 num = goat3d_get_node_count(gscn);
57 for(i=0; i<num; i++) {
58 struct goat3d_node *node = goat3d_get_node(gscn, i);
59 if(match_prefix(goat3d_get_node_name(node), "portal_")) {
62 if(goat3d_get_node_type(node) == GOAT3D_NODE_MESH) {
63 struct goat3d_mesh *mesh = goat3d_get_node_object(node);
65 goat3d_get_node_matrix(node, xform);
69 varr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX);
70 narr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL);
71 uvarr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD);
73 glEnableClientState(GL_VERTEX_ARRAY);
74 glVertexPointer(3, GL_FLOAT, 0, varr);
77 glEnableClientState(GL_NORMAL_ARRAY);
78 glNormalPointer(GL_FLOAT, 0, narr);
81 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
82 glTexCoordPointer(2, GL_FLOAT, 0, uvarr);
85 nfaces = goat3d_get_mesh_face_count(mesh);
86 idxarr = goat3d_get_mesh_faces(mesh);
87 glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, idxarr);
89 glDisableClientState(GL_VERTEX_ARRAY);
90 glDisableClientState(GL_NORMAL_ARRAY);
91 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
101 static void gdestroy(void)
106 static int gstart(void)
108 float amb[] = {0.25, 0.25, 0.25, 1};
110 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
112 set_light_color(0, 1, 1, 1, 0.8);
114 set_light_color(1, 1, 0.6, 0.5, 0.2);
116 set_light_color(2, 0.5, 0.6, 1, 0.3);
121 static void gstop(void)
125 #define TSTEP (1.0f / 30.0f)
127 static void gupdate(void)
129 if(inpstate & INP_MOVE_BITS) {
132 float dx = 0, dy = 0;
134 fwd.x = -sin(cam_theta) * cos(cam_phi);
135 fwd.y = sin(cam_phi);
136 fwd.z = cos(cam_theta) * cos(cam_phi);
137 right.x = cos(cam_theta);
139 right.z = sin(cam_theta);
141 if(inpstate & INP_FWD_BIT) {
144 if(inpstate & INP_BACK_BIT) {
147 if(inpstate & INP_RIGHT_BIT) {
150 if(inpstate & INP_LEFT_BIT) {
154 cam_pan.x += right.x * dx + fwd.x * dy;
155 cam_pan.y += fwd.y * dy;
156 cam_pan.z += right.z * dx + fwd.z * dy;
160 static void gdisplay(void)
162 static long prev_msec;
166 msec = glutGet(GLUT_ELAPSED_TIME);
167 tm_acc += (float)(msec - prev_msec) / 1000.0f;
170 while(tm_acc >= TSTEP) {
175 cgm_mtranslation(view_mat, 0, 0, -cam_dist);
176 cgm_mprerotate(view_mat, cam_phi, 1, 0, 0);
177 cgm_mprerotate(view_mat, cam_theta, 0, 1, 0);
178 cgm_mpretranslate(view_mat, cam_pan.x, cam_pan.y, cam_pan.z);
179 glMatrixMode(GL_MODELVIEW);
180 glLoadMatrixf(view_mat);
182 set_light_dir(0, -1, 1, 5);
183 set_light_dir(1, 5, 0, 3);
184 set_light_dir(2, -0.5, -2, -3);
189 static void greshape(int x, int y)
191 cgm_mperspective(proj_mat, cgm_deg_to_rad(60), win_aspect, 0.1, 100);
192 glMatrixMode(GL_PROJECTION);
193 glLoadMatrixf(proj_mat);
196 static void gkeyb(int key, int press)
200 for(i=0; i<MAX_INPUTS; i++) {
201 if(inpmap[i].key == key) {
203 inpstate |= 1 << inpmap[i].inp;
205 inpstate &= ~(1 << inpmap[i].inp);
215 game_grabmouse(-1); /* toggle */
222 static void gmouse(int bn, int press, int x, int y)
226 #define PIHALF (M_PI / 2.0)
228 static void gmotion(int x, int y)
233 dx = x - win_width / 2;
234 dy = y - win_height / 2;
240 if(!(dx | dy)) return;
242 if(mouse_state[0] || mouse_grabbed) {
243 cam_theta += dx * 0.01;
244 cam_phi += dy * 0.01;
245 if(cam_phi < -PIHALF) cam_phi = -PIHALF;
246 if(cam_phi > PIHALF) cam_phi = PIHALF;
250 float up[3], right[3];
251 float theta = cam_theta * M_PI / 180.0f;
252 float phi = cam_phi * M_PI / 180.0f;
254 up[0] = -sin(theta) * sin(phi);
256 up[2] = cos(theta) * sin(phi);
257 right[0] = cos(theta);
259 right[2] = sin(theta);
261 cam_pan[0] += (right[0] * dx + up[0] * dy) * 0.01;
262 cam_pan[1] += up[1] * dy * 0.01;
263 cam_pan[2] += (right[2] * dx + up[2] * dy) * 0.01;
267 cam_dist += dy * 0.1;
268 if(cam_dist < 0) cam_dist = 0;
272 static void set_light_dir(int idx, float x, float y, float z)
279 glLightfv(GL_LIGHT0 + idx, GL_POSITION, pos);
282 static void set_light_color(int idx, float r, float g, float b, float s)
289 glLightfv(GL_LIGHT0 + idx, GL_DIFFUSE, color);
290 glLightfv(GL_LIGHT0 + idx, GL_SPECULAR, color);