ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/util.C
Revision: 1.52
Committed: Wed Jan 25 22:48:02 2006 UTC (18 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.51: +5 -4 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 * math support
3 * most of the more complicated code is taken from mesa.
4 */
5
6 #include <cstdio> // ugly
7 #include <cstring>
8 #include <cmath>
9
10 #include <sys/time.h>
11 #include <time.h>
12
13 #include "opengl.h"
14
15 #include "util.h"
16 #include "entity.h"
17
18 #define DEG2RAD (M_PI / 180.)
19
20 void renormalize (sector &s, point &p)
21 {
22 float i;
23
24 p.x = modff (p.x, &i); s.x += (soffs)i;
25 p.y = modff (p.y, &i); s.y += (soffs)i;
26 p.z = modff (p.z, &i); s.z += (soffs)i;
27 }
28
29 /////////////////////////////////////////////////////////////////////////////
30
31 const vec3 normalize (const vec3 &v)
32 {
33 GLfloat s = length (v);
34
35 if (!s)
36 return v;
37
38 s = 1. / s;
39 return vec3 (v.x * s, v.y * s, v.z * s);
40 }
41
42 const vec3 cross (const vec3 &a, const vec3 &b)
43 {
44 return vec3 (
45 a.y * b.z - a.z * b.y,
46 a.z * b.x - a.x * b.z,
47 a.x * b.y - a.y * b.x
48 );
49 }
50
51 /////////////////////////////////////////////////////////////////////////////
52
53 plane::plane (GLfloat a, GLfloat b, GLfloat c, GLfloat d)
54 : n (vec3 (a,b,c))
55 {
56 GLfloat s = 1. / length (n);
57
58 n = n * s;
59 this->d = d * s;
60 }
61
62 /////////////////////////////////////////////////////////////////////////////
63
64 void box::add (const box &o)
65 {
66 a.x = min (a.x, o.a.x);
67 a.y = min (a.y, o.a.y);
68 a.z = min (a.z, o.a.z);
69 b.x = max (b.x, o.b.x);
70 b.y = max (b.y, o.b.y);
71 b.z = max (b.z, o.b.z);
72 }
73
74 void box::add (const point &p)
75 {
76 a.x = min (a.x, p.x);
77 a.y = min (a.y, p.y);
78 a.z = min (a.z, p.z);
79 b.x = max (b.x, p.x);
80 b.y = max (b.y, p.y);
81 b.z = max (b.z, p.z);
82 }
83
84 /////////////////////////////////////////////////////////////////////////////
85
86 struct timer timer;
87 static double base;
88 double timer::now = 0.;
89 double timer::diff;
90 double timer::fps = 1.;
91 //double min_frame = 1. / 85.;
92 double min_frame = 1. / 1000.;
93 double vsync_start;
94 GLuint vsync_count;
95
96 extern "C" int glXGetVideoSyncSGI (GLuint *count);
97
98 void timer::frame ()
99 {
100 struct timeval tv;
101 double next;
102
103 gettimeofday (&tv, 0);
104
105 next = tv.tv_sec - base + tv.tv_usec / 1.e6;
106 diff = next - now;
107
108 fps = fps * 0.96 + (1. / diff) * 0.04;
109
110 if (diff < min_frame)
111 {
112 SDL_Delay ((unsigned int)((min_frame - diff) * 1000.));
113
114 gettimeofday (&tv, 0);
115
116 next = tv.tv_sec - base + tv.tv_usec / 1.e6;
117 diff = next - now;
118 }
119
120 now = next;
121
122 // working code using GLX_SGI_video_sync. estimates the real vsync
123 // frequency every 2 seconds. should use a better statistical method.
124 {
125 static int fps = 0;
126 GLuint frame;
127 glXGetVideoSyncSGI (&frame);
128 if (now - vsync_start > 2.)
129 {
130 if (vsync_start)
131 {
132 fps = int ((frame - vsync_count) / (now - vsync_start) + .5F);
133 // works, off for debugging
134 // if (fps > 30)
135 // min_frame = 1. / fps;
136 }
137
138 vsync_start = now;
139 vsync_count = frame;
140 }
141
142 printf ("%d fps ", fps);
143 }
144 }
145
146 timer::timer ()
147 {
148 struct timeval tv;
149 gettimeofday (&tv, 0);
150 base = tv.tv_sec + tv.tv_usec / 1.e6;
151 }
152
153 void render_text (GLint x, GLint y, const char *str)
154 {
155 glRasterPos2i (x, y);
156
157 #if 0
158 while (!*str)
159 glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, *str++);
160 #endif
161 }
162
163 namespace gl {
164
165 void matrix::diagonal (GLfloat v)
166 {
167 for (int i = 4; i--; )
168 for (int j = 4; j--; )
169 data[i][j] = i == j ? v : 0.;
170 }
171
172 matrix operator *(const matrix &a, const matrix &b)
173 {
174 matrix r;
175
176 // taken from mesa
177 for (int i = 0; i < 4; i++)
178 {
179 const GLfloat ai0=a(i,0), ai1=a(i,1), ai2=a(i,2), ai3=a(i,3);
180
181 r(i,0) = ai0 * b(0,0) + ai1 * b(1,0) + ai2 * b(2,0) + ai3 * b(3,0);
182 r(i,1) = ai0 * b(0,1) + ai1 * b(1,1) + ai2 * b(2,1) + ai3 * b(3,1);
183 r(i,2) = ai0 * b(0,2) + ai1 * b(1,2) + ai2 * b(2,2) + ai3 * b(3,2);
184 r(i,3) = ai0 * b(0,3) + ai1 * b(1,3) + ai2 * b(2,3) + ai3 * b(3,3);
185 }
186
187 return r;
188 }
189
190 matrix matrix::rotation (GLfloat angle, const vec3 &axis)
191 {
192 GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c;
193
194 s = (GLfloat) sinf (angle * DEG2RAD);
195 c = (GLfloat) cosf (angle * DEG2RAD);
196
197 const GLfloat mag = length (axis);
198
199 if (mag <= 1.0e-4)
200 return matrix (1);
201
202 matrix m;
203 const vec3 n = axis * (1. / mag);
204
205 xx = n.x * n.x;
206 yy = n.y * n.y;
207 zz = n.z * n.z;
208 xy = n.x * n.y;
209 yz = n.y * n.z;
210 zx = n.z * n.x;
211 xs = n.x * s;
212 ys = n.y * s;
213 zs = n.z * s;
214 one_c = 1.0F - c;
215
216 m(0,0) = (one_c * xx) + c;
217 m(0,1) = (one_c * xy) - zs;
218 m(0,2) = (one_c * zx) + ys;
219 m(0,3) = 0;
220
221 m(1,0) = (one_c * xy) + zs;
222 m(1,1) = (one_c * yy) + c;
223 m(1,2) = (one_c * yz) - xs;
224 m(1,3) = 0;
225
226 m(2,0) = (one_c * zx) - ys;
227 m(2,1) = (one_c * yz) + xs;
228 m(2,2) = (one_c * zz) + c;
229 m(2,3) = 0;
230
231 m(3,0) = 0;
232 m(3,1) = 0;
233 m(3,2) = 0;
234 m(3,3) = 1;
235
236 return m;
237 }
238
239 matrix matrix::translation (const vec3 &v)
240 {
241 matrix m(1);
242
243 m(0,3) = v.x;
244 m(1,3) = v.y;
245 m(2,3) = v.z;
246
247 return m;
248 }
249
250 matrix matrix::scaling (GLfloat sx, GLfloat sy, GLfloat sz, GLfloat sw)
251 {
252 matrix m (1.F);
253
254 m(0,0) = sx;
255 m(1,1) = sy;
256 m(2,2) = sz;
257 m(3,3) = sw;
258
259 return m;
260 }
261
262 vec3 operator *(const matrix &a, const vec3 &v)
263 {
264 return vec3 (
265 a(0,0) * v.x + a(0,1) * v.y + a(0,2) * v.z + a(0,3),
266 a(1,0) * v.x + a(1,1) * v.y + a(1,2) * v.z + a(1,3),
267 a(2,0) * v.x + a(2,1) * v.y + a(2,2) * v.z + a(2,3)
268 );
269 }
270
271 void matrix::print ()
272 {
273 printf ("\n");
274 printf ("[ %f, %f, %f, %f ]\n", data[0][0], data[1][0], data[2][0], data[3][0]);
275 printf ("[ %f, %f, %f, %f ]\n", data[0][1], data[1][1], data[2][1], data[3][1]);
276 printf ("[ %f, %f, %f, %f ]\n", data[0][2], data[1][2], data[2][2], data[3][2]);
277 printf ("[ %f, %f, %f, %f ]\n", data[0][3], data[1][3], data[2][3], data[3][3]);
278 }
279
280 /////////////////////////////////////////////////////////////////////////////
281
282 void draw_bbox (const sector &a, const sector &b)
283 {
284 static vertex_buffer vb;
285 static index_buffer ib;
286
287 vertex_v3f vd[] = {
288 point (a.x, a.y, a.z),
289 point (b.x, a.y, a.z),
290 point (a.x, b.y, a.z),
291 point (b.x, b.y, a.z),
292 point (a.x, a.y, b.z),
293 point (b.x, a.y, b.z),
294 point (a.x, b.y, b.z),
295 point (b.x, b.y, b.z),
296 };
297
298 if (!ib)
299 {
300 static GLushort verts[4*6] = {
301 0, 4, 6, 2, // -x
302 1, 3, 7, 5, // +x
303 0, 1, 5, 4, // -y
304 7, 3, 2, 6, // +y
305 0, 2, 3, 1, // -z
306 4, 5, 7, 6, // +z
307 };
308
309 ib.set (verts, 4*6, GL_STATIC_DRAW_ARB);
310 }
311
312 vb.set (vd, 8, GL_STREAM_DRAW_ARB);
313 vb.bind ();
314 ib.draw (GL_QUADS, 0, 4*6);
315 }
316
317 /////////////////////////////////////////////////////////////////////////////
318
319 GLsizei format_stride (GLenum format)
320 {
321 switch (format)
322 {
323 case GL_V2F: abort ();
324 case GL_V3F: return sizeof (vertex_v3f);
325 case GL_C4UB_V2F: abort ();
326 case GL_C4UB_V3F: abort ();
327 case GL_C3F_V3F: abort ();
328 case GL_N3F_V3F: abort ();
329 case GL_C4F_N3F_V3F: abort ();
330 case GL_T2F_V3F: abort ();
331 case GL_T4F_V4F: abort ();
332 case GL_T2F_C4UB_V3F: abort ();
333 case GL_T2F_C3F_V3F: abort ();
334 case GL_T2F_N3F_V3F: return sizeof (vertex_t2f_n3f_v3f);
335 case GL_T2F_C4F_N3F_V3F: abort ();
336 case GL_T4F_C4F_N3F_V4F: abort ();
337 default:
338 abort ();
339 }
340 }
341
342 GLsizei format_offset_p (GLenum format)
343 {
344 switch (format)
345 {
346 case GL_V2F: abort ();
347 case GL_V3F: { vertex_v3f v; return (char *)&v.v - (char *)&v; }
348 case GL_C4UB_V2F: abort ();
349 case GL_C4UB_V3F: abort ();
350 case GL_C3F_V3F: abort ();
351 case GL_N3F_V3F: abort ();
352 case GL_C4F_N3F_V3F: abort ();
353 case GL_T2F_V3F: abort ();
354 case GL_T4F_V4F: abort ();
355 case GL_T2F_C4UB_V3F: abort ();
356 case GL_T2F_C3F_V3F: abort ();
357 case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.v - (char *)&v; }
358 case GL_T2F_C4F_N3F_V3F: abort ();
359 case GL_T4F_C4F_N3F_V4F: abort ();
360 default:
361 abort ();
362 }
363 }
364
365 GLsizei format_offset_n (GLenum format)
366 {
367 switch (format)
368 {
369 case GL_V2F: abort ();
370 case GL_V3F: abort ();
371 case GL_C4UB_V2F: abort ();
372 case GL_C4UB_V3F: abort ();
373 case GL_C3F_V3F: abort ();
374 case GL_N3F_V3F: abort ();
375 case GL_C4F_N3F_V3F: abort ();
376 case GL_T2F_V3F: abort ();
377 case GL_T4F_V4F: abort ();
378 case GL_T2F_C4UB_V3F: abort ();
379 case GL_T2F_C3F_V3F: abort ();
380 case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.n - (char *)&v; }
381 case GL_T2F_C4F_N3F_V3F: abort ();
382 case GL_T4F_C4F_N3F_V4F: abort ();
383 default:
384 abort ();
385 }
386 }
387
388 GLsizei format_offset_t (GLenum format)
389 {
390 switch (format)
391 {
392 case GL_V2F: abort ();
393 case GL_V3F: abort ();
394 case GL_C4UB_V2F: abort ();
395 case GL_C4UB_V3F: abort ();
396 case GL_C3F_V3F: abort ();
397 case GL_N3F_V3F: abort ();
398 case GL_C4F_N3F_V3F: abort ();
399 case GL_T2F_V3F: abort ();
400 case GL_T4F_V4F: abort ();
401 case GL_T2F_C4UB_V3F: abort ();
402 case GL_T2F_C3F_V3F: abort ();
403 case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.t - (char *)&v; }
404 case GL_T2F_C4F_N3F_V3F: abort ();
405 case GL_T4F_C4F_N3F_V4F: abort ();
406 default:
407 abort ();
408 }
409 }
410
411 /////////////////////////////////////////////////////////////////////////////
412
413 int nesting;
414
415 void errchk (const char *name, const char *args, const char *file, int line)
416 {
417 static int inbegin;
418
419 if (name[2] == 'B' && !strcmp (name, "glBegin"))
420 inbegin = 1;
421 else if (name[2] == 'E' && !strcmp (name, "glEnd"))
422 inbegin = 0;
423
424 if (inbegin)
425 return;
426
427 GLenum gl_derror = glGetError ();
428 if (gl_derror != GL_NO_ERROR)
429 {
430 fprintf (stderr, "%s:%d [GLERROR %d,%s] %s(%s)\n",
431 file, line, gl_derror, gluErrorString (gl_derror), name, args);
432 abort ();
433 }
434 }
435
436 }
437
438 template<typename idtype>
439 idpool<idtype>::idpool ()
440 : next (0)
441 {
442 }
443
444 template<typename idtype>
445 idtype idpool<idtype>::get ()
446 {
447 idtype ret;
448
449 if (free.size ())
450 {
451 ret = *(free.end () - 1);
452 //freeid.pop_back ();
453 }
454 else
455 ret = ++next;
456
457 return ret;
458 }
459
460 template<typename idtype>
461 void idpool<idtype>::put (idtype &i)
462 {
463 free.push_back (i);
464 }