ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/util.C
Revision: 1.43
Committed: Sat Oct 30 15:59:20 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.42: +4 -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
94 void timer::frame ()
95 {
96 struct timeval tv;
97 double next;
98
99 gettimeofday (&tv, 0);
100
101 next = tv.tv_sec - base + tv.tv_usec / 1.e6;
102 diff = next - now;
103
104 fps = fps * 0.9 + (1. / diff) * 0.1;
105
106 if (diff < min_frame)
107 {
108 SDL_Delay ((unsigned int)((min_frame - diff) * 1000.));
109
110 gettimeofday (&tv, 0);
111
112 next = tv.tv_sec - base + tv.tv_usec / 1.e6;
113 diff = next - now;
114 }
115
116 now = next;
117 }
118
119 timer::timer ()
120 {
121 struct timeval tv;
122 gettimeofday (&tv, 0);
123 base = tv.tv_sec + tv.tv_usec / 1.e6;
124 }
125
126 void render_text (GLint x, GLint y, const char *str)
127 {
128 glRasterPos2i (x, y);
129
130 #if 0
131 while (!*str)
132 glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, *str++);
133 #endif
134 }
135
136 namespace gl {
137
138 void matrix::diagonal (GLfloat v)
139 {
140 for (int i = 4; i--; )
141 for (int j = 4; j--; )
142 data[i][j] = i == j ? v : 0.;
143 }
144
145 matrix operator *(const matrix &a, const matrix &b)
146 {
147 matrix r;
148
149 // taken from mesa
150 for (int i = 0; i < 4; i++)
151 {
152 const GLfloat ai0=a(i,0), ai1=a(i,1), ai2=a(i,2), ai3=a(i,3);
153
154 r(i,0) = ai0 * b(0,0) + ai1 * b(1,0) + ai2 * b(2,0) + ai3 * b(3,0);
155 r(i,1) = ai0 * b(0,1) + ai1 * b(1,1) + ai2 * b(2,1) + ai3 * b(3,1);
156 r(i,2) = ai0 * b(0,2) + ai1 * b(1,2) + ai2 * b(2,2) + ai3 * b(3,2);
157 r(i,3) = ai0 * b(0,3) + ai1 * b(1,3) + ai2 * b(2,3) + ai3 * b(3,3);
158 }
159
160 return r;
161 }
162
163 matrix matrix::rotation (GLfloat angle, const vec3 &axis)
164 {
165 GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c;
166
167 s = (GLfloat) sinf (angle * DEG2RAD);
168 c = (GLfloat) cosf (angle * DEG2RAD);
169
170 const GLfloat mag = length (axis);
171
172 if (mag <= 1.0e-4)
173 return matrix (1);
174
175 matrix m;
176 const vec3 n = axis * (1. / mag);
177
178 xx = n.x * n.x;
179 yy = n.y * n.y;
180 zz = n.z * n.z;
181 xy = n.x * n.y;
182 yz = n.y * n.z;
183 zx = n.z * n.x;
184 xs = n.x * s;
185 ys = n.y * s;
186 zs = n.z * s;
187 one_c = 1.0F - c;
188
189 m(0,0) = (one_c * xx) + c;
190 m(0,1) = (one_c * xy) - zs;
191 m(0,2) = (one_c * zx) + ys;
192 m(0,3) = 0;
193
194 m(1,0) = (one_c * xy) + zs;
195 m(1,1) = (one_c * yy) + c;
196 m(1,2) = (one_c * yz) - xs;
197 m(1,3) = 0;
198
199 m(2,0) = (one_c * zx) - ys;
200 m(2,1) = (one_c * yz) + xs;
201 m(2,2) = (one_c * zz) + c;
202 m(2,3) = 0;
203
204 m(3,0) = 0;
205 m(3,1) = 0;
206 m(3,2) = 0;
207 m(3,3) = 1;
208
209 return m;
210 }
211
212 matrix matrix::translation (const vec3 &v)
213 {
214 matrix m(1);
215
216 m(0,3) = v.x;
217 m(1,3) = v.y;
218 m(2,3) = v.z;
219
220 return m;
221 }
222
223 matrix matrix::scaling (GLfloat sx, GLfloat sy, GLfloat sz, GLfloat sw)
224 {
225 matrix m (1.F);
226
227 m(0,0) = sx;
228 m(1,1) = sy;
229 m(2,2) = sz;
230 m(3,3) = sw;
231
232 return m;
233 }
234
235 vec3 operator *(const matrix &a, const vec3 &v)
236 {
237 return vec3 (
238 a(0,0) * v.x + a(0,1) * v.y + a(0,2) * v.z + a(0,3),
239 a(1,0) * v.x + a(1,1) * v.y + a(1,2) * v.z + a(1,3),
240 a(2,0) * v.x + a(2,1) * v.y + a(2,2) * v.z + a(2,3)
241 );
242 }
243
244 void matrix::print ()
245 {
246 printf ("\n");
247 printf ("[ %f, %f, %f, %f ]\n", data[0][0], data[1][0], data[2][0], data[3][0]);
248 printf ("[ %f, %f, %f, %f ]\n", data[0][1], data[1][1], data[2][1], data[3][1]);
249 printf ("[ %f, %f, %f, %f ]\n", data[0][2], data[1][2], data[2][2], data[3][2]);
250 printf ("[ %f, %f, %f, %f ]\n", data[0][3], data[1][3], data[2][3], data[3][3]);
251 }
252
253 /////////////////////////////////////////////////////////////////////////////
254
255 void draw_bbox (const sector &a, const sector &b)
256 {
257 static vertex_buffer vb;
258 static index_buffer ib;
259
260 point pa(a), pb(b);
261
262 vertex_v3f vd[] = {
263 point (a.x, a.y, a.z),
264 point (b.x, a.y, a.z),
265 point (a.x, b.y, a.z),
266 point (b.x, b.y, a.z),
267 point (a.x, a.y, b.z),
268 point (b.x, a.y, b.z),
269 point (a.x, b.y, b.z),
270 point (b.x, b.y, b.z),
271 };
272
273 if (!ib)
274 {
275 static GLushort verts[4*6] = {
276 0, 4, 6, 2, // -x
277 1, 3, 7, 5, // +x
278 0, 1, 5, 4, // -y
279 7, 3, 2, 6, // +y
280 0, 2, 3, 1, // -z
281 4, 5, 7, 6, // +z
282 };
283
284 ib.set (verts, 4*6, GL_STATIC_DRAW_ARB);
285 }
286
287 vb.set (vd, 8, GL_STREAM_DRAW_ARB);
288 vb.bind ();
289 ib.draw (GL_QUADS, 0, 4*6);
290 }
291
292 /////////////////////////////////////////////////////////////////////////////
293
294 GLsizei format_stride (GLenum format)
295 {
296 switch (format)
297 {
298 case GL_V2F: abort ();
299 case GL_V3F: return sizeof (vertex_v3f);
300 case GL_C4UB_V2F: abort ();
301 case GL_C4UB_V3F: abort ();
302 case GL_C3F_V3F: abort ();
303 case GL_N3F_V3F: abort ();
304 case GL_C4F_N3F_V3F: abort ();
305 case GL_T2F_V3F: abort ();
306 case GL_T4F_V4F: abort ();
307 case GL_T2F_C4UB_V3F: abort ();
308 case GL_T2F_C3F_V3F: abort ();
309 case GL_T2F_N3F_V3F: return sizeof (vertex_t2f_n3f_v3f);
310 case GL_T2F_C4F_N3F_V3F: abort ();
311 case GL_T4F_C4F_N3F_V4F: abort ();
312 default:
313 abort ();
314 }
315 }
316
317 GLsizei format_offset_p (GLenum format)
318 {
319 switch (format)
320 {
321 case GL_V2F: abort ();
322 case GL_V3F: { vertex_v3f v; return (char *)&v.v - (char *)&v; }
323 case GL_C4UB_V2F: abort ();
324 case GL_C4UB_V3F: abort ();
325 case GL_C3F_V3F: abort ();
326 case GL_N3F_V3F: abort ();
327 case GL_C4F_N3F_V3F: abort ();
328 case GL_T2F_V3F: abort ();
329 case GL_T4F_V4F: abort ();
330 case GL_T2F_C4UB_V3F: abort ();
331 case GL_T2F_C3F_V3F: abort ();
332 case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.v - (char *)&v; }
333 case GL_T2F_C4F_N3F_V3F: abort ();
334 case GL_T4F_C4F_N3F_V4F: abort ();
335 default:
336 abort ();
337 }
338 }
339
340 GLsizei format_offset_n (GLenum format)
341 {
342 switch (format)
343 {
344 case GL_V2F: abort ();
345 case GL_V3F: abort ();
346 case GL_C4UB_V2F: abort ();
347 case GL_C4UB_V3F: abort ();
348 case GL_C3F_V3F: abort ();
349 case GL_N3F_V3F: abort ();
350 case GL_C4F_N3F_V3F: abort ();
351 case GL_T2F_V3F: abort ();
352 case GL_T4F_V4F: abort ();
353 case GL_T2F_C4UB_V3F: abort ();
354 case GL_T2F_C3F_V3F: abort ();
355 case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.n - (char *)&v; }
356 case GL_T2F_C4F_N3F_V3F: abort ();
357 case GL_T4F_C4F_N3F_V4F: abort ();
358 default:
359 abort ();
360 }
361 }
362
363 GLsizei format_offset_t (GLenum format)
364 {
365 switch (format)
366 {
367 case GL_V2F: abort ();
368 case GL_V3F: abort ();
369 case GL_C4UB_V2F: abort ();
370 case GL_C4UB_V3F: abort ();
371 case GL_C3F_V3F: abort ();
372 case GL_N3F_V3F: abort ();
373 case GL_C4F_N3F_V3F: abort ();
374 case GL_T2F_V3F: abort ();
375 case GL_T4F_V4F: abort ();
376 case GL_T2F_C4UB_V3F: abort ();
377 case GL_T2F_C3F_V3F: abort ();
378 case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.t - (char *)&v; }
379 case GL_T2F_C4F_N3F_V3F: abort ();
380 case GL_T4F_C4F_N3F_V4F: abort ();
381 default:
382 abort ();
383 }
384 }
385
386 /////////////////////////////////////////////////////////////////////////////
387
388 int nesting;
389
390 void errchk (const char *name, const char *args, const char *file, int line)
391 {
392 static int inbegin;
393
394 if (name[2] == 'B' && !strcmp (name, "glBegin"))
395 inbegin = 1;
396 else if (name[2] == 'E' && !strcmp (name, "glEnd"))
397 inbegin = 0;
398
399 if (inbegin)
400 return;
401
402 GLenum gl_derror = glGetError ();
403 if (gl_derror != GL_NO_ERROR)
404 {
405 fprintf (stderr, "%s:%d [GLERROR %d,%s] %s(%s)\n",
406 file, line, gl_derror, gluErrorString (gl_derror), name, args);
407 abort ();
408 }
409 }
410
411 }
412
413 //skedjuhlar main_scheduler;
414