ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/util.C
Revision: 1.41
Committed: Thu Oct 28 23:24:49 2004 UTC (19 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.40: +2 -2 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 const 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 const 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 const vec3 operator *(const matrix &a, const vec3 &v)
213 {
214 return vec3 (
215 a(0,0) * v.x + a(0,1) * v.y + a(0,2) * v.z + a(0,3),
216 a(1,0) * v.x + a(1,1) * v.y + a(1,2) * v.z + a(1,3),
217 a(2,0) * v.x + a(2,1) * v.y + a(2,2) * v.z + a(2,3)
218 );
219 }
220
221 void matrix::print ()
222 {
223 printf ("\n");
224 printf ("[ %f, %f, %f, %f ]\n", data[0][0], data[1][0], data[2][0], data[3][0]);
225 printf ("[ %f, %f, %f, %f ]\n", data[0][1], data[1][1], data[2][1], data[3][1]);
226 printf ("[ %f, %f, %f, %f ]\n", data[0][2], data[1][2], data[2][2], data[3][2]);
227 printf ("[ %f, %f, %f, %f ]\n", data[0][3], data[1][3], data[2][3], data[3][3]);
228 }
229
230 const matrix matrix::translation (const vec3 &v)
231 {
232 matrix m(1);
233
234 m(0,3) = v.x;
235 m(1,3) = v.y;
236 m(2,3) = v.z;
237
238 return m;
239 }
240
241 /////////////////////////////////////////////////////////////////////////////
242
243 void draw_bbox (const sector &a, const sector &b)
244 {
245 static vertex_buffer_object vb;
246 static index_buffer_object ib;
247
248 point pa(a), pb(b);
249
250 vertex_v3f vd[] = {
251 point (a.x, a.y, a.z),
252 point (b.x, a.y, a.z),
253 point (a.x, b.y, a.z),
254 point (b.x, b.y, a.z),
255 point (a.x, a.y, b.z),
256 point (b.x, a.y, b.z),
257 point (a.x, b.y, b.z),
258 point (b.x, b.y, b.z),
259 };
260
261 if (!ib)
262 {
263 static index_ushort verts[4*6] = {
264 0, 4, 6, 2, // -x
265 1, 3, 7, 5, // +x
266 0, 1, 5, 4, // -y
267 7, 3, 2, 6, // +y
268 0, 2, 3, 1, // -z
269 4, 5, 7, 6, // +z
270 };
271
272 ib.set (verts, 4*6, GL_STATIC_DRAW_ARB);
273 }
274
275 vb.set (vd, 8, GL_STREAM_DRAW_ARB);
276 vb.bind ();
277 ib.draw (GL_QUADS, 0, 6*4);
278 }
279
280 /////////////////////////////////////////////////////////////////////////////
281
282 GLsizei format_stride (GLenum format)
283 {
284 switch (format)
285 {
286 case GL_V2F: abort ();
287 case GL_V3F: return sizeof (vertex_v3f);
288 case GL_C4UB_V2F: abort ();
289 case GL_C4UB_V3F: abort ();
290 case GL_C3F_V3F: abort ();
291 case GL_N3F_V3F: abort ();
292 case GL_C4F_N3F_V3F: abort ();
293 case GL_T2F_V3F: abort ();
294 case GL_T4F_V4F: abort ();
295 case GL_T2F_C4UB_V3F: abort ();
296 case GL_T2F_C3F_V3F: abort ();
297 case GL_T2F_N3F_V3F: return sizeof (vertex_t2f_n3f_v3f);
298 case GL_T2F_C4F_N3F_V3F: abort ();
299 case GL_T4F_C4F_N3F_V4F: abort ();
300 default:
301 abort ();
302 }
303 }
304
305 GLsizei format_offset_p (GLenum format)
306 {
307 switch (format)
308 {
309 case GL_V2F: abort ();
310 case GL_V3F: { vertex_v3f v; return (char *)&v.p - (char *)&v; }
311 case GL_C4UB_V2F: abort ();
312 case GL_C4UB_V3F: abort ();
313 case GL_C3F_V3F: abort ();
314 case GL_N3F_V3F: abort ();
315 case GL_C4F_N3F_V3F: abort ();
316 case GL_T2F_V3F: abort ();
317 case GL_T4F_V4F: abort ();
318 case GL_T2F_C4UB_V3F: abort ();
319 case GL_T2F_C3F_V3F: abort ();
320 case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.p - (char *)&v; }
321 case GL_T2F_C4F_N3F_V3F: abort ();
322 case GL_T4F_C4F_N3F_V4F: abort ();
323 default:
324 abort ();
325 }
326 }
327
328 GLsizei format_offset_n (GLenum format)
329 {
330 switch (format)
331 {
332 case GL_V2F: abort ();
333 case GL_V3F: abort ();
334 case GL_C4UB_V2F: abort ();
335 case GL_C4UB_V3F: abort ();
336 case GL_C3F_V3F: abort ();
337 case GL_N3F_V3F: abort ();
338 case GL_C4F_N3F_V3F: abort ();
339 case GL_T2F_V3F: abort ();
340 case GL_T4F_V4F: abort ();
341 case GL_T2F_C4UB_V3F: abort ();
342 case GL_T2F_C3F_V3F: abort ();
343 case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.n - (char *)&v; }
344 case GL_T2F_C4F_N3F_V3F: abort ();
345 case GL_T4F_C4F_N3F_V4F: abort ();
346 default:
347 abort ();
348 }
349 }
350
351 GLsizei format_offset_t (GLenum format)
352 {
353 switch (format)
354 {
355 case GL_V2F: abort ();
356 case GL_V3F: abort ();
357 case GL_C4UB_V2F: abort ();
358 case GL_C4UB_V3F: abort ();
359 case GL_C3F_V3F: abort ();
360 case GL_N3F_V3F: abort ();
361 case GL_C4F_N3F_V3F: abort ();
362 case GL_T2F_V3F: abort ();
363 case GL_T4F_V4F: abort ();
364 case GL_T2F_C4UB_V3F: abort ();
365 case GL_T2F_C3F_V3F: abort ();
366 case GL_T2F_N3F_V3F: { vertex_t2f_n3f_v3f v; return (char *)&v.t - (char *)&v; }
367 case GL_T2F_C4F_N3F_V3F: abort ();
368 case GL_T4F_C4F_N3F_V4F: abort ();
369 default:
370 abort ();
371 }
372 }
373
374 /////////////////////////////////////////////////////////////////////////////
375
376 int nesting;
377
378 void errchk (const char *name, const char *args, const char *file, int line)
379 {
380 static int inbegin;
381
382 if (name[2] == 'B' && !strcmp (name, "glBegin"))
383 inbegin = 1;
384 else if (name[2] == 'E' && !strcmp (name, "glEnd"))
385 inbegin = 0;
386
387 if (inbegin)
388 return;
389
390 GLenum gl_derror = glGetError ();
391 if (gl_derror != GL_NO_ERROR)
392 {
393 fprintf (stderr, "%s:%d [GLERROR %d,%s] %s(%s)\n",
394 file, line, gl_derror, gluErrorString (gl_derror), name, args);
395 abort ();
396 }
397 }
398
399 }
400
401 //skedjuhlar main_scheduler;
402