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 cam_theta, cam_phi = 20, cam_dist;
35 static cgm_vec3 cam_pan;
37 static struct goat3d *gscn;
41 static int ginit(void)
45 float *varr, *narr, *uvarr;
48 if(!(gscn = goat3d_create()) || goat3d_load(gscn, "data/level1.g3d")) {
52 dlist = glGenLists(1);
53 glNewList(dlist, GL_COMPILE);
54 num = goat3d_get_node_count(gscn);
55 for(i=0; i<num; i++) {
56 struct goat3d_node *node = goat3d_get_node(gscn, i);
57 if(match_prefix(goat3d_get_node_name(node), "portal_")) {
60 if(goat3d_get_node_type(node) == GOAT3D_NODE_MESH) {
61 struct goat3d_mesh *mesh = goat3d_get_node_object(node);
63 goat3d_get_node_matrix(node, xform);
67 varr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX);
68 narr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL);
69 uvarr = goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD);
71 glEnableClientState(GL_VERTEX_ARRAY);
72 glVertexPointer(3, GL_FLOAT, 0, varr);
75 glEnableClientState(GL_NORMAL_ARRAY);
76 glNormalPointer(GL_FLOAT, 0, narr);
79 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
80 glTexCoordPointer(2, GL_FLOAT, 0, uvarr);
83 nfaces = goat3d_get_mesh_face_count(mesh);
84 idxarr = goat3d_get_mesh_faces(mesh);
85 glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, idxarr);
87 glDisableClientState(GL_VERTEX_ARRAY);
88 glDisableClientState(GL_NORMAL_ARRAY);
89 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
99 static void gdestroy(void)
104 static int gstart(void)
106 float amb[] = {0.25, 0.25, 0.25, 1};
108 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
110 set_light_color(0, 1, 1, 1, 0.8);
112 set_light_color(1, 1, 0.6, 0.5, 0.2);
114 set_light_color(2, 0.5, 0.6, 1, 0.3);
119 static void gstop(void)
123 #define TSTEP (1.0f / 30.0f)
125 static void gupdate(void)
127 if(inpstate & INP_MOVE_BITS) {
129 float theta = cam_theta * M_PI / 180.0f;
130 float phi = cam_phi * M_PI / 180.0f;
132 float dx = 0, dy = 0;
134 fwd.x = -sin(theta) * cos(phi);
136 fwd.z = cos(theta) * cos(phi);
137 right.x = cos(theta);
139 right.z = sin(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 glMatrixMode(GL_MODELVIEW);
177 glTranslatef(0, 0, -cam_dist);
178 glRotatef(cam_phi, 1, 0, 0);
179 glRotatef(cam_theta, 0, 1, 0);
180 glTranslatef(cam_pan.x, cam_pan.y, cam_pan.z);
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)
193 static void gkeyb(int key, int press)
197 for(i=0; i<MAX_INPUTS; i++) {
198 if(inpmap[i].key == key) {
200 inpstate |= 1 << inpmap[i].inp;
202 inpstate &= ~(1 << inpmap[i].inp);
209 static void gmouse(int bn, int press, int x, int y)
213 static void gmotion(int x, int y)
215 int dx = x - mouse_x;
216 int dy = y - mouse_y;
218 if(!(dx | dy)) return;
221 cam_theta += dx * 0.5;
223 if(cam_phi < -90) cam_phi = -90;
224 if(cam_phi > 90) cam_phi = 90;
228 float up[3], right[3];
229 float theta = cam_theta * M_PI / 180.0f;
230 float phi = cam_phi * M_PI / 180.0f;
232 up[0] = -sin(theta) * sin(phi);
234 up[2] = cos(theta) * sin(phi);
235 right[0] = cos(theta);
237 right[2] = sin(theta);
239 cam_pan[0] += (right[0] * dx + up[0] * dy) * 0.01;
240 cam_pan[1] += up[1] * dy * 0.01;
241 cam_pan[2] += (right[2] * dx + up[2] * dy) * 0.01;
245 cam_dist += dy * 0.1;
246 if(cam_dist < 0) cam_dist = 0;
250 static void set_light_dir(int idx, float x, float y, float z)
257 glLightfv(GL_LIGHT0 + idx, GL_POSITION, pos);
260 static void set_light_color(int idx, float r, float g, float b, float s)
267 glLightfv(GL_LIGHT0 + idx, GL_DIFFUSE, color);
268 glLightfv(GL_LIGHT0 + idx, GL_SPECULAR, color);