rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@0
|
3 #include <math.h>
|
nuclear@11
|
4 #include <assert.h>
|
nuclear@25
|
5 #include <algorithm>
|
nuclear@0
|
6 #include "opengl.h"
|
nuclear@0
|
7 #include "game.h"
|
nuclear@7
|
8 #include "camera.h"
|
nuclear@11
|
9 #include "sanegl.h"
|
nuclear@17
|
10 #include "texture.h"
|
nuclear@21
|
11 #include "shader.h"
|
nuclear@22
|
12 #include "text.h"
|
nuclear@24
|
13 #include "vmath/vmath.h"
|
nuclear@25
|
14 #include "mesh.h"
|
nuclear@25
|
15 #include "meshgen.h"
|
nuclear@7
|
16
|
nuclear@21
|
17 static void draw_quad(float hsz, float vsz);
|
nuclear@25
|
18 static void draw_rotation_gizmo();
|
nuclear@25
|
19 static void draw_disc_wedge(float start, float end, int subdiv);
|
nuclear@0
|
20
|
nuclear@22
|
21 int win_width, win_height;
|
nuclear@22
|
22
|
nuclear@9
|
23 static float win_aspect;
|
nuclear@9
|
24 static int video_width, video_height;
|
nuclear@9
|
25 static float video_aspect;
|
nuclear@17
|
26 static struct texture *test_tex;
|
nuclear@17
|
27
|
nuclear@25
|
28 static SdrProg *sdr_tex, *sdr_color, *sdr_debug;
|
nuclear@0
|
29
|
nuclear@25
|
30 static Quaternion last_rot;
|
nuclear@25
|
31 static Vector3 last_trans;
|
nuclear@25
|
32
|
nuclear@25
|
33 static Quaternion rot;
|
nuclear@25
|
34 static Vector3 rot_euler;
|
nuclear@25
|
35
|
nuclear@25
|
36 static Mesh *mesh;
|
nuclear@24
|
37
|
nuclear@20
|
38 extern "C" int game_init(void)
|
nuclear@0
|
39 {
|
nuclear@27
|
40 glEnable(GL_DEPTH_TEST);
|
nuclear@27
|
41 glEnable(GL_CULL_FACE);
|
nuclear@0
|
42
|
nuclear@0
|
43 glClearColor(0.4, 0.4, 0.4, 1);
|
nuclear@8
|
44
|
nuclear@25
|
45 if(!(sdr_tex = get_sdrprog("sdr/vertex.glsl", "sdr/tex.p.glsl"))) {
|
nuclear@10
|
46 return -1;
|
nuclear@10
|
47 }
|
nuclear@25
|
48 if(!(sdr_color = get_sdrprog("sdr/vertex.glsl", "sdr/color.p.glsl"))) {
|
nuclear@25
|
49 return -1;
|
nuclear@25
|
50 }
|
nuclear@25
|
51 if(!(sdr_debug = get_sdrprog("sdr/vertex.glsl", "sdr/normvis.p.glsl"))) {
|
nuclear@17
|
52 return -1;
|
nuclear@17
|
53 }
|
nuclear@17
|
54
|
nuclear@17
|
55 if(!(test_tex = get_texture("data/opengl.png"))) {
|
nuclear@17
|
56 return -1;
|
nuclear@17
|
57 }
|
nuclear@10
|
58
|
nuclear@25
|
59 mesh = new Mesh;
|
nuclear@25
|
60 gen_cylinder(mesh, 0.2, 1.0, 16, 1);
|
nuclear@25
|
61
|
nuclear@8
|
62 cam_start_video();
|
nuclear@9
|
63 cam_video_size(&video_width, &video_height);
|
nuclear@9
|
64 if(video_height) {
|
nuclear@9
|
65 video_aspect = (float)video_width / (float)video_height;
|
nuclear@9
|
66 } else {
|
nuclear@9
|
67 video_aspect = 1.0;
|
nuclear@9
|
68 }
|
nuclear@9
|
69
|
nuclear@9
|
70 printf("started video %dx%d (aspect: %g)\n", video_width, video_height, video_aspect);
|
nuclear@0
|
71 return 0;
|
nuclear@0
|
72 }
|
nuclear@0
|
73
|
nuclear@20
|
74 extern "C" void game_shutdown(void)
|
nuclear@0
|
75 {
|
nuclear@8
|
76 cam_shutdown();
|
nuclear@21
|
77 delete sdr_tex;
|
nuclear@0
|
78 }
|
nuclear@0
|
79
|
nuclear@20
|
80 extern "C" void game_display(unsigned long msec)
|
nuclear@0
|
81 {
|
nuclear@9
|
82 unsigned int tex;
|
nuclear@9
|
83 float xscale, yscale;
|
nuclear@9
|
84
|
nuclear@8
|
85 cam_update();
|
nuclear@9
|
86 tex = cam_texture();
|
nuclear@7
|
87
|
nuclear@4
|
88 //float tsec = (float)msec / 1000.0f;
|
nuclear@0
|
89
|
nuclear@0
|
90 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
nuclear@0
|
91
|
nuclear@27
|
92 glDisable(GL_DEPTH_TEST);
|
nuclear@27
|
93
|
nuclear@25
|
94 // draw video preview frame
|
nuclear@25
|
95 gl_matrix_mode(GL_PROJECTION);
|
nuclear@25
|
96 gl_push_matrix();
|
nuclear@25
|
97 gl_load_identity();
|
nuclear@25
|
98 gl_scalef((float)win_height / (float)win_width, 1, 1);
|
nuclear@11
|
99 gl_matrix_mode(GL_MODELVIEW);
|
nuclear@11
|
100 gl_load_identity();
|
nuclear@7
|
101
|
nuclear@9
|
102 if(video_aspect > win_aspect) {
|
nuclear@9
|
103 xscale = 1.0;
|
nuclear@9
|
104 yscale = 1.0 / video_aspect;
|
nuclear@9
|
105 } else {
|
nuclear@9
|
106 xscale = video_aspect;
|
nuclear@9
|
107 yscale = 1.0;
|
nuclear@9
|
108 }
|
nuclear@25
|
109 gl_scalef(xscale, yscale, 1);
|
nuclear@17
|
110
|
nuclear@25
|
111 cam_draw_preview();
|
nuclear@25
|
112
|
nuclear@25
|
113 gl_matrix_mode(GL_PROJECTION);
|
nuclear@25
|
114 gl_pop_matrix();
|
nuclear@25
|
115 // done drawing preview
|
nuclear@25
|
116
|
nuclear@27
|
117 glEnable(GL_DEPTH_TEST);
|
nuclear@25
|
118
|
nuclear@17
|
119 gl_matrix_mode(GL_MODELVIEW);
|
nuclear@17
|
120 gl_load_identity();
|
nuclear@25
|
121 gl_translatef(0, 0, -6);
|
nuclear@17
|
122
|
nuclear@25
|
123 draw_rotation_gizmo();
|
nuclear@22
|
124
|
nuclear@24
|
125 // print the rotation quaternion
|
nuclear@22
|
126 text_color(1, 1, 1, 1);
|
nuclear@24
|
127 text_position(0, 0);
|
nuclear@25
|
128 text_printf("translation (% .3f, % .3f, % .3f)", last_trans.x, last_trans.y, last_trans.z);
|
nuclear@24
|
129 text_position(0, 1);
|
nuclear@25
|
130 text_printf("Rotation quat ([% 1.3f, % 1.3f, % 1.3f], % 1.3f)", last_rot.v.x, last_rot.v.y, last_rot.v.z, last_rot.s);
|
nuclear@7
|
131 }
|
nuclear@7
|
132
|
nuclear@21
|
133 static void draw_quad(float hsz, float vsz)
|
nuclear@7
|
134 {
|
nuclear@7
|
135 static const float varr[] = {-1, -1, 1, -1, 1, 1, -1, 1};
|
nuclear@9
|
136 static const float tcarr[] = {0, 0, 1, 0, 1, 1, 0, 1};
|
nuclear@7
|
137
|
nuclear@11
|
138 gl_matrix_mode(GL_MODELVIEW);
|
nuclear@11
|
139 gl_push_matrix();
|
nuclear@11
|
140 gl_scalef(hsz, vsz, 1);
|
nuclear@11
|
141
|
nuclear@21
|
142 if(SdrProg::active) {
|
nuclear@21
|
143 gl_apply_xform(SdrProg::active->get_globj());
|
nuclear@21
|
144 }
|
nuclear@7
|
145
|
nuclear@21
|
146 glEnableVertexAttribArray(SDR_ATTR_VERTEX);
|
nuclear@21
|
147 glEnableVertexAttribArray(SDR_ATTR_TEXCOORD);
|
nuclear@21
|
148 glVertexAttribPointer(SDR_ATTR_VERTEX, 2, GL_FLOAT, 0, 0, varr);
|
nuclear@21
|
149 glVertexAttribPointer(SDR_ATTR_TEXCOORD, 2, GL_FLOAT, 0, 0, tcarr);
|
nuclear@7
|
150
|
nuclear@8
|
151 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
nuclear@7
|
152
|
nuclear@21
|
153 glDisableVertexAttribArray(SDR_ATTR_VERTEX);
|
nuclear@21
|
154 glDisableVertexAttribArray(SDR_ATTR_TEXCOORD);
|
nuclear@11
|
155
|
nuclear@11
|
156 gl_pop_matrix();
|
nuclear@0
|
157 }
|
nuclear@0
|
158
|
nuclear@25
|
159 static void draw_rotation_gizmo()
|
nuclear@25
|
160 {
|
nuclear@25
|
161 /*static const float axis[][3] = {
|
nuclear@25
|
162 {1, 0, 0}, {0, 1, 0}, {0, 0, 1}
|
nuclear@25
|
163 };*/
|
nuclear@25
|
164
|
nuclear@25
|
165 last_rot.normalize();
|
nuclear@25
|
166 Matrix4x4 rmat = last_rot.get_rotation_matrix().transposed();
|
nuclear@25
|
167 gl_matrix_mode(GL_MODELVIEW);
|
nuclear@25
|
168 gl_push_matrix();
|
nuclear@25
|
169 gl_mult_matrixf(rmat[0]);
|
nuclear@25
|
170
|
nuclear@25
|
171 sdr_debug->bind();
|
nuclear@26
|
172 gl_apply_xform(sdr_debug->get_globj());
|
nuclear@25
|
173
|
nuclear@25
|
174 mesh->draw();
|
nuclear@25
|
175
|
nuclear@25
|
176 gl_pop_matrix();
|
nuclear@25
|
177 }
|
nuclear@25
|
178
|
nuclear@25
|
179 static void draw_disc_wedge(float start, float end, int subdiv)
|
nuclear@25
|
180 {
|
nuclear@25
|
181 if(start > end) {
|
nuclear@25
|
182 float tmp = start;
|
nuclear@25
|
183 start = end;
|
nuclear@25
|
184 end = tmp;
|
nuclear@25
|
185 }
|
nuclear@25
|
186
|
nuclear@25
|
187 float arc_size = end - start;
|
nuclear@25
|
188 subdiv = std::max<int>(subdiv * arc_size, 1);
|
nuclear@25
|
189 int nverts = subdiv + 2;
|
nuclear@25
|
190
|
nuclear@25
|
191 float *varr = (float*)alloca(nverts * 3 * sizeof *varr);
|
nuclear@25
|
192 float *vptr = varr;
|
nuclear@25
|
193
|
nuclear@25
|
194 // start with the center vertex
|
nuclear@25
|
195 vptr[0] = vptr[1] = vptr[2] = 0;
|
nuclear@25
|
196 vptr += 3;
|
nuclear@25
|
197
|
nuclear@25
|
198 // then add the arc vertices in sequence
|
nuclear@25
|
199 float u = start;
|
nuclear@25
|
200 float du = arc_size / (float)subdiv;
|
nuclear@25
|
201 for(int i=0; i<subdiv + 1; i++) {
|
nuclear@25
|
202 float angle = u * M_PI * 2.0;
|
nuclear@25
|
203 vptr[0] = sin(angle);
|
nuclear@25
|
204 vptr[1] = cos(angle);
|
nuclear@25
|
205 vptr[2] = 0.0;
|
nuclear@25
|
206 vptr += 3;
|
nuclear@25
|
207 u += du;
|
nuclear@25
|
208 }
|
nuclear@25
|
209
|
nuclear@25
|
210 glEnableVertexAttribArray(SDR_ATTR_VERTEX);
|
nuclear@25
|
211 glVertexAttribPointer(SDR_ATTR_VERTEX, 3, GL_FLOAT, 0, 0, varr);
|
nuclear@25
|
212
|
nuclear@25
|
213 glDrawArrays(GL_TRIANGLE_FAN, 0, nverts);
|
nuclear@25
|
214
|
nuclear@25
|
215 glDisableVertexAttribArray(SDR_ATTR_VERTEX);
|
nuclear@25
|
216 }
|
nuclear@25
|
217
|
nuclear@20
|
218 extern "C" void game_reshape(int x, int y)
|
nuclear@0
|
219 {
|
nuclear@0
|
220 win_width = x;
|
nuclear@0
|
221 win_height = y;
|
nuclear@9
|
222 win_aspect = y ? (float)x / (float)y : 1.0;
|
nuclear@0
|
223 glViewport(0, 0, x, y);
|
nuclear@0
|
224
|
nuclear@11
|
225 gl_matrix_mode(GL_PROJECTION);
|
nuclear@25
|
226 glu_perspective(50.0, win_aspect, 0.5, 500.0);
|
nuclear@0
|
227 }
|
nuclear@0
|
228
|
nuclear@20
|
229 extern "C" void game_keyboard(int key, int pressed)
|
nuclear@0
|
230 {
|
nuclear@0
|
231 if(!pressed) return;
|
nuclear@0
|
232
|
nuclear@0
|
233 switch(key) {
|
nuclear@0
|
234 case 27:
|
nuclear@0
|
235 exit(0);
|
nuclear@0
|
236
|
nuclear@0
|
237 default:
|
nuclear@0
|
238 break;
|
nuclear@0
|
239 }
|
nuclear@0
|
240 }
|
nuclear@0
|
241
|
nuclear@0
|
242 #define MAX_TOUCH_IDS 16
|
nuclear@0
|
243 static struct {
|
nuclear@0
|
244 int bnstate[8];
|
nuclear@0
|
245 int prev_x, prev_y;
|
nuclear@0
|
246 } mstate[MAX_TOUCH_IDS];
|
nuclear@0
|
247
|
nuclear@20
|
248 extern "C" void game_mouse_button(int id, int bn, int pressed, int x, int y)
|
nuclear@0
|
249 {
|
nuclear@0
|
250 if(id >= MAX_TOUCH_IDS) return;
|
nuclear@0
|
251
|
nuclear@0
|
252 mstate[id].prev_x = x;
|
nuclear@0
|
253 mstate[id].prev_y = y;
|
nuclear@0
|
254 mstate[id].bnstate[bn] = pressed;
|
nuclear@0
|
255 }
|
nuclear@0
|
256
|
nuclear@20
|
257 extern "C" void game_mouse_motion(int id, int x, int y)
|
nuclear@0
|
258 {
|
nuclear@0
|
259 /*
|
nuclear@0
|
260 int dx, dy, cx, cy;
|
nuclear@0
|
261
|
nuclear@0
|
262 if(id >= MAX_TOUCH_IDS) return;
|
nuclear@0
|
263
|
nuclear@0
|
264 cx = win_width / 2;
|
nuclear@0
|
265 cy = win_height / 2;
|
nuclear@0
|
266
|
nuclear@0
|
267 dx = x - mstate[id].prev_x;
|
nuclear@0
|
268 dy = y - mstate[id].prev_y;
|
nuclear@0
|
269 mstate[id].prev_x = x;
|
nuclear@0
|
270 mstate[id].prev_y = y;
|
nuclear@0
|
271
|
nuclear@0
|
272 if(!dx && !dy) return;
|
nuclear@0
|
273
|
nuclear@0
|
274 if(mouselook || mstate[id].bnstate[0]) {
|
nuclear@0
|
275 player_turn(&player, dx * 0.5, dy * 0.5);
|
nuclear@0
|
276 }
|
nuclear@0
|
277 if(mstate[id].bnstate[2]) {
|
nuclear@0
|
278 dbg_cam_dist += 0.1 * dy;
|
nuclear@0
|
279 if(dbg_cam_dist < 0.0) dbg_cam_dist = 0.0;
|
nuclear@0
|
280 }
|
nuclear@0
|
281
|
nuclear@0
|
282 if(mouselook) {
|
nuclear@0
|
283 warping_mouse = 1;
|
nuclear@0
|
284 set_mouse_pos(cx, cy);
|
nuclear@0
|
285 mstate[id].prev_x = cx;
|
nuclear@0
|
286 mstate[id].prev_y = cy;
|
nuclear@0
|
287 }
|
nuclear@0
|
288 */
|
nuclear@0
|
289 }
|
nuclear@0
|
290
|
nuclear@24
|
291 void game_6dof_translation(float dx, float dy, float dz)
|
nuclear@24
|
292 {
|
nuclear@25
|
293 last_trans.x = dx;
|
nuclear@25
|
294 last_trans.y = dy;
|
nuclear@25
|
295 last_trans.z = dz;
|
nuclear@24
|
296 }
|
nuclear@24
|
297
|
nuclear@24
|
298 void game_6dof_rotation(float qx, float qy, float qz, float qw)
|
nuclear@24
|
299 {
|
nuclear@25
|
300 last_rot.v.x = qx;
|
nuclear@25
|
301 last_rot.v.y = qy;
|
nuclear@25
|
302 last_rot.v.z = qz;
|
nuclear@25
|
303 last_rot.s = qw;
|
nuclear@25
|
304
|
nuclear@25
|
305 rot.rotate(last_rot);
|
nuclear@24
|
306 }
|