5b9f4bf4edac5e3f261c65ba84ec3f269fb41c79
[deeprace] / src / scr_game.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <GL/gl.h>
5 #include "miniglut.h"
6 #include "game.h"
7 #include "util.h"
8 #include "goat3d.h"
9
10 static int ginit(void);
11 static void gdestroy(void);
12 static int gstart(void);
13 static void gstop(void);
14 static void gdisplay(void);
15 static void greshape(int x, int y);
16 static void gkeyb(int key, int press);
17 static void gmouse(int bn, int press, int x, int y);
18 static void gmotion(int x, int y);
19
20 struct game_screen scr_game = {
21         "game",
22         ginit, gdestroy,
23         gstart, gstop,
24         gdisplay, greshape,
25         gkeyb, gmouse, gmotion
26 };
27
28 static float cam_theta, cam_phi = 20, cam_dist = 10;
29 static float cam_pan[3];
30
31 static struct goat3d *gscn;
32 static int dlist;
33
34
35 static int ginit(void)
36 {
37         int i, num, nfaces;
38
39         if(!(gscn = goat3d_create()) || goat3d_load(gscn, "data/track1.g3d")) {
40                 return -1;
41         }
42
43         dlist = glGenLists(1);
44         glNewList(dlist, GL_COMPILE);
45         num = goat3d_get_node_count(gscn);
46         for(i=0; i<num; i++) {
47                 struct goat3d_node *node = goat3d_get_node(gscn, i);
48                 if(goat3d_get_node_type(node) == GOAT3D_NODE_MESH) {
49                         struct goat3d_mesh *mesh = goat3d_get_node_object(node);
50
51                         glEnableClientState(GL_VERTEX_ARRAY);
52                         glVertexPointer(3, GL_FLOAT, 0, goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX));
53
54                         if(goat3d_get_mesh_attrib_count(mesh, GOAT3D_MESH_ATTR_NORMAL)) {
55                                 glEnableClientState(GL_NORMAL_ARRAY);
56                                 glNormalPointer(GL_FLOAT, 0, goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL));
57                         }
58                         if(goat3d_get_mesh_attrib_count(mesh, GOAT3D_MESH_ATTR_TEXCOORD)) {
59                                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
60                                 glTexCoordPointer(2, GL_FLOAT, 0, goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD));
61                         }
62
63                         nfaces = goat3d_get_mesh_face_count(mesh) / 3;
64                         glDrawElements(GL_TRIANGLES, nfaces * 3, GL_UNSIGNED_INT, goat3d_get_mesh_faces(mesh));
65
66                         glDisableClientState(GL_VERTEX_ARRAY);
67                         glDisableClientState(GL_NORMAL_ARRAY);
68                         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
69                 }
70         }
71         glEndList();
72
73         return 0;
74 }
75
76 static void gdestroy(void)
77 {
78         goat3d_free(gscn);
79 }
80
81 static int gstart(void)
82 {
83         return 0;
84 }
85
86 static void gstop(void)
87 {
88 }
89
90 static void gdisplay(void)
91 {
92         glMatrixMode(GL_MODELVIEW);
93         glLoadIdentity();
94         glTranslatef(0, 0, -cam_dist);
95         glRotatef(cam_phi, 1, 0, 0);
96         glRotatef(cam_theta, 0, 1, 0);
97         glTranslatef(cam_pan[0], cam_pan[1], cam_pan[2]);
98
99         glCallList(dlist);
100 }
101
102 static void greshape(int x, int y)
103 {
104 }
105
106 static void gkeyb(int key, int press)
107 {
108 }
109
110 static void gmouse(int bn, int press, int x, int y)
111 {
112 }
113
114 static void gmotion(int x, int y)
115 {
116         int dx = x - mouse_x;
117         int dy = y - mouse_y;
118
119         if(!(dx | dy)) return;
120
121         if(mouse_state[0]) {
122                 cam_theta += dx * 0.5;
123                 cam_phi += dy * 0.5;
124                 if(cam_phi < -90) cam_phi = -90;
125                 if(cam_phi > 90) cam_phi = 90;
126         }
127         if(mouse_state[1]) {
128                 float up[3], right[3];
129                 float theta = cam_theta * M_PI / 180.0f;
130                 float phi = cam_phi * M_PI / 180.0f;
131
132                 up[0] = -sin(theta) * sin(phi);
133                 up[1] = -cos(phi);
134                 up[2] = cos(theta) * sin(phi);
135                 right[0] = cos(theta);
136                 right[1] = 0;
137                 right[2] = sin(theta);
138
139                 cam_pan[0] += (right[0] * dx + up[0] * dy) * 0.01;
140                 cam_pan[1] += up[1] * dy * 0.01;
141                 cam_pan[2] += (right[2] * dx + up[2] * dy) * 0.01;
142         }
143         if(mouse_state[2]) {
144                 cam_dist += dy * 0.1;
145                 if(cam_dist < 0) cam_dist = 0;
146         }
147 }