ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/libgender/util.C
Revision: 1.51
Committed: Thu Aug 11 23:26:24 2005 UTC (21 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.50: +26 -0 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     {
123     static int fps = 0;
124     /* GLX_SGI_video_sync */
125     GLuint frame;
126     glXGetVideoSyncSGI (&frame);
127     if (now - vsync_start > 2.)
128     {
129     if (vsync_start)
130     {
131     fps = int ((frame - vsync_count) / (now - vsync_start) + .5F);
132    
133     if (fps > 30)
134     min_frame = 1. / fps;
135     }
136    
137     vsync_start = now;
138     vsync_count = frame;
139     }
140    
141     printf ("%d fps ", fps);
142     }
143 root 1.4 }
144    
145     timer::timer ()
146     {
147     struct timeval tv;
148     gettimeofday (&tv, 0);
149     base = tv.tv_sec + tv.tv_usec / 1.e6;
150     }
151    
152 root 1.20 void render_text (GLint x, GLint y, const char *str)
153     {
154     glRasterPos2i (x, y);
155    
156 root 1.29 #if 0
157 root 1.20 while (!*str)
158     glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, *str++);
159 root 1.29 #endif
160 root 1.15 }
161 root 1.13
162 root 1.21 namespace gl {
163 root 1.33
164     void matrix::diagonal (GLfloat v)
165     {
166     for (int i = 4; i--; )
167     for (int j = 4; j--; )
168     data[i][j] = i == j ? v : 0.;
169     }
170    
171 root 1.42 matrix operator *(const matrix &a, const matrix &b)
172 root 1.33 {
173     matrix r;
174    
175     // taken from mesa
176     for (int i = 0; i < 4; i++)
177     {
178     const GLfloat ai0=a(i,0), ai1=a(i,1), ai2=a(i,2), ai3=a(i,3);
179    
180     r(i,0) = ai0 * b(0,0) + ai1 * b(1,0) + ai2 * b(2,0) + ai3 * b(3,0);
181     r(i,1) = ai0 * b(0,1) + ai1 * b(1,1) + ai2 * b(2,1) + ai3 * b(3,1);
182     r(i,2) = ai0 * b(0,2) + ai1 * b(1,2) + ai2 * b(2,2) + ai3 * b(3,2);
183     r(i,3) = ai0 * b(0,3) + ai1 * b(1,3) + ai2 * b(2,3) + ai3 * b(3,3);
184     }
185    
186     return r;
187     }
188    
189 root 1.42 matrix matrix::rotation (GLfloat angle, const vec3 &axis)
190 root 1.33 {
191     GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c;
192    
193     s = (GLfloat) sinf (angle * DEG2RAD);
194     c = (GLfloat) cosf (angle * DEG2RAD);
195    
196 root 1.37 const GLfloat mag = length (axis);
197 root 1.33
198     if (mag <= 1.0e-4)
199     return matrix (1);
200    
201     matrix m;
202     const vec3 n = axis * (1. / mag);
203    
204     xx = n.x * n.x;
205     yy = n.y * n.y;
206     zz = n.z * n.z;
207     xy = n.x * n.y;
208     yz = n.y * n.z;
209     zx = n.z * n.x;
210     xs = n.x * s;
211     ys = n.y * s;
212     zs = n.z * s;
213     one_c = 1.0F - c;
214    
215     m(0,0) = (one_c * xx) + c;
216     m(0,1) = (one_c * xy) - zs;
217     m(0,2) = (one_c * zx) + ys;
218     m(0,3) = 0;
219    
220     m(1,0) = (one_c * xy) + zs;
221     m(1,1) = (one_c * yy) + c;
222     m(1,2) = (one_c * yz) - xs;
223     m(1,3) = 0;
224    
225     m(2,0) = (one_c * zx) - ys;
226     m(2,1) = (one_c * yz) + xs;
227     m(2,2) = (one_c * zz) + c;
228     m(2,3) = 0;
229    
230     m(3,0) = 0;
231     m(3,1) = 0;
232     m(3,2) = 0;
233     m(3,3) = 1;
234    
235     return m;
236     }
237    
238 root 1.42 matrix matrix::translation (const vec3 &v)
239     {
240     matrix m(1);
241    
242     m(0,3) = v.x;
243     m(1,3) = v.y;
244     m(2,3) = v.z;
245    
246     return m;
247     }
248    
249     matrix matrix::scaling (GLfloat sx, GLfloat sy, GLfloat sz, GLfloat sw)
250     {
251     matrix m (1.F);
252    
253     m(0,0) = sx;
254     m(1,1) = sy;
255     m(2,2) = sz;
256     m(3,3) = sw;
257    
258     return m;
259     }
260    
261     vec3 operator *(const matrix &a, const vec3 &v)
262 root 1.33 {
263     return vec3 (
264     a(0,0) * v.x + a(0,1) * v.y + a(0,2) * v.z + a(0,3),
265     a(1,0) * v.x + a(1,1) * v.y + a(1,2) * v.z + a(1,3),
266     a(2,0) * v.x + a(2,1) * v.y + a(2,2) * v.z + a(2,3)
267     );
268     }
269    
270     void matrix::print ()
271     {
272     printf ("\n");
273     printf ("[ %f, %f, %f, %f ]\n", data[0][0], data[1][0], data[2][0], data[3][0]);
274     printf ("[ %f, %f, %f, %f ]\n", data[0][1], data[1][1], data[2][1], data[3][1]);
275     printf ("[ %f, %f, %f, %f ]\n", data[0][2], data[1][2], data[2][2], data[3][2]);
276     printf ("[ %f, %f, %f, %f ]\n", data[0][3], data[1][3], data[2][3], data[3][3]);
277     }
278    
279     /////////////////////////////////////////////////////////////////////////////
280 root 1.21
281 root 1.38 void draw_bbox (const sector &a, const sector &b)
282 root 1.24 {
283 root 1.42 static vertex_buffer vb;
284     static index_buffer ib;
285 root 1.24
286 root 1.38 vertex_v3f vd[] = {
287     point (a.x, a.y, a.z),
288     point (b.x, a.y, a.z),
289     point (a.x, b.y, a.z),
290     point (b.x, b.y, a.z),
291     point (a.x, a.y, b.z),
292     point (b.x, a.y, b.z),
293     point (a.x, b.y, b.z),
294     point (b.x, b.y, b.z),
295     };
296 root 1.32
297 root 1.38 if (!ib)
298 root 1.24 {
299 root 1.43 static GLushort verts[4*6] = {
300 root 1.38 0, 4, 6, 2, // -x
301     1, 3, 7, 5, // +x
302     0, 1, 5, 4, // -y
303     7, 3, 2, 6, // +y
304     0, 2, 3, 1, // -z
305     4, 5, 7, 6, // +z
306     };
307 root 1.24
308 root 1.38 ib.set (verts, 4*6, GL_STATIC_DRAW_ARB);
309 root 1.24 }
310    
311 root 1.38 vb.set (vd, 8, GL_STREAM_DRAW_ARB);
312     vb.bind ();
313 root 1.43 ib.draw (GL_QUADS, 0, 4*6);
314 root 1.24 }
315    
316 root 1.39 /////////////////////////////////////////////////////////////////////////////
317    
318     GLsizei format_stride (GLenum format)
319     {
320     switch (format)
321     {
322     case GL_V2F: abort ();
323     case GL_V3F: return sizeof (vertex_v3f);
324     case GL_C4UB_V2F: abort ();
325     case GL_C4UB_V3F: abort ();
326     case GL_C3F_V3F: abort ();
327     case GL_N3F_V3F: abort ();
328     case GL_C4F_N3F_V3F: abort ();
329     case GL_T2F_V3F: abort ();
330     case GL_T4F_V4F: abort ();
331     case GL_T2F_C4UB_V3F: abort ();
332     case GL_T2F_C3F_V3F: abort ();
333     case GL_T2F_N3F_V3F: return sizeof (vertex_t2f_n3f_v3f);
334     case GL_T2F_C4F_N3F_V3F: abort ();
335     case GL_T4F_C4F_N3F_V4F: abort ();
336     default:
337     abort ();
338     }
339     }
340    
341     GLsizei format_offset_p (GLenum format)
342     {
343     switch (format)
344     {
345     case GL_V2F: abort ();
346 root 1.43 case GL_V3F: { vertex_v3f v; return (char *)&v.v - (char *)&v; }
347 root 1.39 case GL_C4UB_V2F: abort ();
348     case GL_C4UB_V3F: abort ();
349     case GL_C3F_V3F: abort ();
350     case GL_N3F_V3F: abort ();
351     case GL_C4F_N3F_V3F: abort ();
352     case GL_T2F_V3F: abort ();
353     case GL_T4F_V4F: abort ();
354     case GL_T2F_C4UB_V3F: abort ();
355     case GL_T2F_C3F_V3F: abort ();
356 root 1.43 case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.v - (char *)&v; }
357 root 1.39 case GL_T2F_C4F_N3F_V3F: abort ();
358     case GL_T4F_C4F_N3F_V4F: abort ();
359     default:
360     abort ();
361     }
362     }
363    
364     GLsizei format_offset_n (GLenum format)
365     {
366     switch (format)
367     {
368     case GL_V2F: abort ();
369     case GL_V3F: abort ();
370     case GL_C4UB_V2F: abort ();
371     case GL_C4UB_V3F: abort ();
372     case GL_C3F_V3F: abort ();
373     case GL_N3F_V3F: abort ();
374     case GL_C4F_N3F_V3F: abort ();
375     case GL_T2F_V3F: abort ();
376     case GL_T4F_V4F: abort ();
377     case GL_T2F_C4UB_V3F: abort ();
378     case GL_T2F_C3F_V3F: abort ();
379     case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.n - (char *)&v; }
380     case GL_T2F_C4F_N3F_V3F: abort ();
381     case GL_T4F_C4F_N3F_V4F: abort ();
382     default:
383     abort ();
384     }
385     }
386    
387     GLsizei format_offset_t (GLenum format)
388     {
389     switch (format)
390     {
391     case GL_V2F: abort ();
392     case GL_V3F: abort ();
393     case GL_C4UB_V2F: abort ();
394     case GL_C4UB_V3F: abort ();
395     case GL_C3F_V3F: abort ();
396     case GL_N3F_V3F: abort ();
397     case GL_C4F_N3F_V3F: abort ();
398     case GL_T2F_V3F: abort ();
399     case GL_T4F_V4F: abort ();
400     case GL_T2F_C4UB_V3F: abort ();
401     case GL_T2F_C3F_V3F: abort ();
402     case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.t - (char *)&v; }
403     case GL_T2F_C4F_N3F_V3F: abort ();
404     case GL_T4F_C4F_N3F_V4F: abort ();
405     default:
406     abort ();
407     }
408     }
409    
410     /////////////////////////////////////////////////////////////////////////////
411    
412 root 1.25 int nesting;
413    
414 root 1.24 void errchk (const char *name, const char *args, const char *file, int line)
415     {
416 root 1.25 static int inbegin;
417    
418     if (name[2] == 'B' && !strcmp (name, "glBegin"))
419     inbegin = 1;
420     else if (name[2] == 'E' && !strcmp (name, "glEnd"))
421     inbegin = 0;
422    
423     if (inbegin)
424     return;
425    
426 root 1.24 GLenum gl_derror = glGetError ();
427     if (gl_derror != GL_NO_ERROR)
428 root 1.32 {
429     fprintf (stderr, "%s:%d [GLERROR %d,%s] %s(%s)\n",
430     file, line, gl_derror, gluErrorString (gl_derror), name, args);
431     abort ();
432     }
433 root 1.24 }
434 root 1.21
435     }
436    
437 root 1.47 template<typename idtype>
438     idpool<idtype>::idpool ()
439 root 1.46 : next (0)
440     {
441     }
442 root 1.17
443 root 1.47 template<typename idtype>
444     idtype idpool<idtype>::get ()
445 root 1.46 {
446 root 1.47 idtype ret;
447 root 1.46
448 root 1.47 if (free.size ())
449 root 1.46 {
450 root 1.47 ret = *(free.end () - 1);
451 root 1.49 //freeid.pop_back ();
452 root 1.46 }
453     else
454 root 1.47 ret = ++next;
455 root 1.46
456     return ret;
457     }
458    
459 root 1.47 template<typename idtype>
460     void idpool<idtype>::put (idtype &i)
461 root 1.46 {
462 root 1.47 free.push_back (i);
463 root 1.46 }