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 (20 years, 7 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

# User Rev Content
1 root 1.3 /*
2     * math support
3     * most of the more complicated code is taken from mesa.
4     */
5    
6 root 1.2 #include <cstdio> // ugly
7 root 1.25 #include <cstring>
8 root 1.1 #include <cmath>
9    
10 root 1.4 #include <sys/time.h>
11     #include <time.h>
12 root 1.20
13 root 1.27 #include "opengl.h"
14 root 1.2
15 root 1.1 #include "util.h"
16 root 1.15 #include "entity.h"
17 root 1.1
18 root 1.3 #define DEG2RAD (M_PI / 180.)
19    
20 root 1.6 void renormalize (sector &s, point &p)
21     {
22     float i;
23    
24 root 1.11 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 root 1.6 }
28    
29 root 1.7 /////////////////////////////////////////////////////////////////////////////
30    
31 root 1.1 const vec3 normalize (const vec3 &v)
32     {
33 root 1.37 GLfloat s = length (v);
34 root 1.3
35     if (!s)
36     return v;
37 root 1.1
38 root 1.3 s = 1. / s;
39 root 1.1 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 root 1.3 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 root 1.2 }
50    
51 root 1.7 /////////////////////////////////////////////////////////////////////////////
52    
53     plane::plane (GLfloat a, GLfloat b, GLfloat c, GLfloat d)
54 root 1.9 : n (vec3 (a,b,c))
55 root 1.7 {
56 root 1.37 GLfloat s = 1. / length (n);
57 root 1.7
58     n = n * s;
59 root 1.9 this->d = d * s;
60 root 1.7 }
61    
62     /////////////////////////////////////////////////////////////////////////////
63    
64 root 1.1 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 root 1.19 void box::add (const point &p)
75 root 1.1 {
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 root 1.5 }
83    
84 root 1.7 /////////////////////////////////////////////////////////////////////////////
85 root 1.4
86     struct timer timer;
87     static double base;
88     double timer::now = 0.;
89     double timer::diff;
90 root 1.41 double timer::fps = 1.;
91 root 1.44 //double min_frame = 1. / 85.;
92 root 1.50 double min_frame = 1. / 1000.;
93 root 1.51 double vsync_start;
94     GLuint vsync_count;
95    
96     extern "C" int glXGetVideoSyncSGI (GLuint *count);
97 root 1.4
98     void timer::frame ()
99     {
100     struct timeval tv;
101 root 1.23 double next;
102 root 1.4
103 root 1.34 gettimeofday (&tv, 0);
104    
105     next = tv.tv_sec - base + tv.tv_usec / 1.e6;
106     diff = next - now;
107    
108 root 1.45 fps = fps * 0.96 + (1. / diff) * 0.04;
109 root 1.34
110     if (diff < min_frame)
111 root 1.23 {
112 root 1.34 SDL_Delay ((unsigned int)((min_frame - diff) * 1000.));
113    
114 root 1.23 gettimeofday (&tv, 0);
115    
116     next = tv.tv_sec - base + tv.tv_usec / 1.e6;
117     diff = next - now;
118     }
119 root 1.4
120     now = next;
121 root 1.51
122 root 1.52 // working code using GLX_SGI_video_sync. estimates the real vsync
123     // frequency every 2 seconds. should use a better statistical method.
124 root 1.51 {
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 root 1.52 // works, off for debugging
134     // if (fps > 30)
135     // min_frame = 1. / fps;
136 root 1.51 }
137    
138     vsync_start = now;
139     vsync_count = frame;
140     }
141    
142     printf ("%d fps ", fps);
143     }
144 root 1.4 }
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 root 1.20 void render_text (GLint x, GLint y, const char *str)
154     {
155     glRasterPos2i (x, y);
156    
157 root 1.29 #if 0
158 root 1.20 while (!*str)
159     glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, *str++);
160 root 1.29 #endif
161 root 1.15 }
162 root 1.13
163 root 1.21 namespace gl {
164 root 1.33
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 root 1.42 matrix operator *(const matrix &a, const matrix &b)
173 root 1.33 {
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 root 1.42 matrix matrix::rotation (GLfloat angle, const vec3 &axis)
191 root 1.33 {
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 root 1.37 const GLfloat mag = length (axis);
198 root 1.33
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 root 1.42 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 root 1.33 {
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 root 1.21
282 root 1.38 void draw_bbox (const sector &a, const sector &b)
283 root 1.24 {
284 root 1.42 static vertex_buffer vb;
285     static index_buffer ib;
286 root 1.24
287 root 1.38 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 root 1.32
298 root 1.38 if (!ib)
299 root 1.24 {
300 root 1.43 static GLushort verts[4*6] = {
301 root 1.38 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 root 1.24
309 root 1.38 ib.set (verts, 4*6, GL_STATIC_DRAW_ARB);
310 root 1.24 }
311    
312 root 1.38 vb.set (vd, 8, GL_STREAM_DRAW_ARB);
313     vb.bind ();
314 root 1.43 ib.draw (GL_QUADS, 0, 4*6);
315 root 1.24 }
316    
317 root 1.39 /////////////////////////////////////////////////////////////////////////////
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 root 1.43 case GL_V3F: { vertex_v3f v; return (char *)&v.v - (char *)&v; }
348 root 1.39 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 root 1.43 case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.v - (char *)&v; }
358 root 1.39 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 root 1.25 int nesting;
414    
415 root 1.24 void errchk (const char *name, const char *args, const char *file, int line)
416     {
417 root 1.25 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 root 1.24 GLenum gl_derror = glGetError ();
428     if (gl_derror != GL_NO_ERROR)
429 root 1.32 {
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 root 1.24 }
435 root 1.21
436     }
437    
438 root 1.47 template<typename idtype>
439     idpool<idtype>::idpool ()
440 root 1.46 : next (0)
441     {
442     }
443 root 1.17
444 root 1.47 template<typename idtype>
445     idtype idpool<idtype>::get ()
446 root 1.46 {
447 root 1.47 idtype ret;
448 root 1.46
449 root 1.47 if (free.size ())
450 root 1.46 {
451 root 1.47 ret = *(free.end () - 1);
452 root 1.49 //freeid.pop_back ();
453 root 1.46 }
454     else
455 root 1.47 ret = ++next;
456 root 1.46
457     return ret;
458     }
459    
460 root 1.47 template<typename idtype>
461     void idpool<idtype>::put (idtype &i)
462 root 1.46 {
463 root 1.47 free.push_back (i);
464 root 1.46 }