ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/util.C
Revision: 1.24
Committed: Sat Oct 9 22:43:31 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.23: +36 -27 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 <cmath>
8
9 #include <sys/time.h>
10 #include <time.h>
11
12 #include <GL/gl.h>
13 #include <GL/glut.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 = abs (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 void matrix::diagonal (GLfloat v)
54 {
55 for (int i = 4; i--; )
56 for (int j = 4; j--; )
57 data[i][j] = i == j ? v : 0.;
58 }
59
60 const matrix operator *(const matrix &a, const matrix &b)
61 {
62 matrix r;
63
64 // taken from mesa
65 for (int i = 0; i < 4; i++)
66 {
67 const GLfloat ai0=a(i,0), ai1=a(i,1), ai2=a(i,2), ai3=a(i,3);
68
69 r(i,0) = ai0 * b(0,0) + ai1 * b(1,0) + ai2 * b(2,0) + ai3 * b(3,0);
70 r(i,1) = ai0 * b(0,1) + ai1 * b(1,1) + ai2 * b(2,1) + ai3 * b(3,1);
71 r(i,2) = ai0 * b(0,2) + ai1 * b(1,2) + ai2 * b(2,2) + ai3 * b(3,2);
72 r(i,3) = ai0 * b(0,3) + ai1 * b(1,3) + ai2 * b(2,3) + ai3 * b(3,3);
73 }
74
75 return r;
76 }
77
78 const matrix matrix::rotation (GLfloat angle, const vec3 &axis)
79 {
80 GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c;
81
82 s = (GLfloat) sinf (angle * DEG2RAD);
83 c = (GLfloat) cosf (angle * DEG2RAD);
84
85 const GLfloat mag = abs (axis);
86
87 if (mag <= 1.0e-4)
88 return matrix (1);
89
90 matrix m;
91 const vec3 n = axis * (1. / mag);
92
93 xx = n.x * n.x;
94 yy = n.y * n.y;
95 zz = n.z * n.z;
96 xy = n.x * n.y;
97 yz = n.y * n.z;
98 zx = n.z * n.x;
99 xs = n.x * s;
100 ys = n.y * s;
101 zs = n.z * s;
102 one_c = 1.0F - c;
103
104 m(0,0) = (one_c * xx) + c;
105 m(0,1) = (one_c * xy) - zs;
106 m(0,2) = (one_c * zx) + ys;
107 m(0,3) = 0;
108
109 m(1,0) = (one_c * xy) + zs;
110 m(1,1) = (one_c * yy) + c;
111 m(1,2) = (one_c * yz) - xs;
112 m(1,3) = 0;
113
114 m(2,0) = (one_c * zx) - ys;
115 m(2,1) = (one_c * yz) + xs;
116 m(2,2) = (one_c * zz) + c;
117 m(2,3) = 0;
118
119 m(3,0) = 0;
120 m(3,1) = 0;
121 m(3,2) = 0;
122 m(3,3) = 1;
123
124 return m;
125 }
126
127 const vec3 operator *(const matrix &a, const vec3 &v)
128 {
129 return vec3 (
130 a(0,0) * v.x + a(0,1) * v.y + a(0,2) * v.z + a(0,3),
131 a(1,0) * v.x + a(1,1) * v.y + a(1,2) * v.z + a(1,3),
132 a(2,0) * v.x + a(2,1) * v.y + a(2,2) * v.z + a(2,3)
133 );
134 }
135
136 void matrix::print ()
137 {
138 printf ("\n");
139 printf ("[ %f, %f, %f, %f ]\n", data[0][0], data[1][0], data[2][0], data[3][0]);
140 printf ("[ %f, %f, %f, %f ]\n", data[0][1], data[1][1], data[2][1], data[3][1]);
141 printf ("[ %f, %f, %f, %f ]\n", data[0][2], data[1][2], data[2][2], data[3][2]);
142 printf ("[ %f, %f, %f, %f ]\n", data[0][3], data[1][3], data[2][3], data[3][3]);
143 }
144
145 const matrix matrix::translation (const vec3 &v)
146 {
147 matrix m(1);
148
149 m(0,3) = v.x;
150 m(1,3) = v.y;
151 m(2,3) = v.z;
152
153 return m;
154 }
155
156 /////////////////////////////////////////////////////////////////////////////
157
158 plane::plane (GLfloat a, GLfloat b, GLfloat c, GLfloat d)
159 : n (vec3 (a,b,c))
160 {
161 GLfloat s = 1. / abs (n);
162
163 n = n * s;
164 this->d = d * s;
165 }
166
167 /////////////////////////////////////////////////////////////////////////////
168
169 void box::add (const box &o)
170 {
171 a.x = min (a.x, o.a.x);
172 a.y = min (a.y, o.a.y);
173 a.z = min (a.z, o.a.z);
174 b.x = max (b.x, o.b.x);
175 b.y = max (b.y, o.b.y);
176 b.z = max (b.z, o.b.z);
177 }
178
179 void box::add (const point &p)
180 {
181 a.x = min (a.x, p.x);
182 a.y = min (a.y, p.y);
183 a.z = min (a.z, p.z);
184 b.x = max (b.x, p.x);
185 b.y = max (b.y, p.y);
186 b.z = max (b.z, p.z);
187 }
188
189 /////////////////////////////////////////////////////////////////////////////
190
191 struct timer timer;
192 static double base;
193 double timer::now = 0.;
194 double timer::diff;
195 //double min_frame = 1. / 60.;
196 double min_frame = 1. / 600.;
197
198 void timer::frame ()
199 {
200 struct timeval tv;
201 double next;
202
203 for (;;)
204 {
205 gettimeofday (&tv, 0);
206
207 next = tv.tv_sec - base + tv.tv_usec / 1.e6;
208 diff = next - now;
209
210 if (diff >= min_frame)
211 break;
212
213 SDL_Delay ((unsigned int)((min_frame - diff) * 1000.));
214 }
215
216 now = next;
217 }
218
219 timer::timer ()
220 {
221 struct timeval tv;
222 gettimeofday (&tv, 0);
223 base = tv.tv_sec + tv.tv_usec / 1.e6;
224 }
225
226 GLuint SDL_GL_LoadTexture (SDL_Surface * surface, GLfloat * texcoord)
227 {
228 GLuint texture;
229 int w, h;
230 SDL_Surface *image;
231 SDL_Rect area;
232 Uint32 saved_flags;
233 Uint8 saved_alpha;
234
235 /* Use the surface width and height expanded to powers of 2 */
236 //w = power_of_two (surface->w);
237 //h = power_of_two (surface->h);
238 w = power_of_two (surface->w);
239 h = power_of_two (surface->h);
240 texcoord[0] = 0.0f; /* Min X */
241 texcoord[1] = 0.0f; /* Min Y */
242 texcoord[2] = (GLfloat) surface->w / w; /* Max X */
243 texcoord[3] = (GLfloat) surface->h / h; /* Max Y */
244
245 image = SDL_CreateRGBSurface (SDL_SWSURFACE, w, h, 32,
246 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
247 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
248 #else
249 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
250 #endif
251 );
252 if (image == NULL)
253 {
254 return 0;
255 }
256
257 /* Save the alpha blending attributes */
258 saved_flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
259 saved_alpha = surface->format->alpha;
260 if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
261 {
262 SDL_SetAlpha (surface, 0, 0);
263 }
264
265 /* Copy the surface into the GL texture image */
266 area.x = 0;
267 area.y = 0;
268 area.w = surface->w;
269 area.h = surface->h;
270 SDL_BlitSurface (surface, &area, image, &area);
271
272 /* Restore the alpha blending attributes */
273 if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
274 {
275 SDL_SetAlpha (surface, saved_flags, saved_alpha);
276 }
277
278 /* Create an OpenGL texture for the image */
279 glGenTextures (1, &texture);
280 glBindTexture (GL_TEXTURE_2D, texture);
281 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
282 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
283 glTexImage2D (GL_TEXTURE_2D,
284 0,
285 GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
286 SDL_FreeSurface (image); /* No longer needed */
287
288 return texture;
289 }
290
291 void render_text (GLint x, GLint y, const char *str)
292 {
293 glRasterPos2i (x, y);
294
295 while (!*str)
296 glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, *str++);
297 }
298
299 namespace gl {
300
301 void draw_box (const view &ctx, const sector &a, const sector &b)
302 {
303 int i;
304 static GLint verts[] = {
305 0x8000, 0x8004, 0x8006, 0x8002, // -x
306 0x8001, 0x8003, 0x8007, 0x8005, // +x
307 0x8000, 0x8001, 0x8005, 0x8004, // -y
308 0x8007, 0x8003, 0x8002, 0x8006, // +y
309 0x8000, 0x8002, 0x8003, 0x8001, // -z
310 0x8004, 0x8005, 0x8007, 0x8006, // +z
311 0
312 };
313
314 glBegin (GL_QUADS);
315
316 for (GLint *v = verts; *v; v++)
317 {
318 GLint mask = *v;
319
320 glVertex3i (mask & 1 ? b.x : a.x,
321 mask & 2 ? b.y : a.y,
322 mask & 4 ? b.z : a.z);
323 }
324
325 glEnd ();
326 }
327
328 void errchk (const char *name, const char *args, const char *file, int line)
329 {
330 GLenum gl_derror = glGetError ();
331 if (gl_derror != GL_NO_ERROR)
332 fprintf (stderr, "%s:%d [GLERROR %d] %s(%s)\n",
333 file, line, gl_derror, name, args);
334 }
335
336 }
337
338 //skedjuhlar main_scheduler;
339