ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/util.C
Revision: 1.22
Committed: Sat Oct 9 16:36:31 2004 UTC (19 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.21: +1 -1 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
196 void timer::frame ()
197 {
198 struct timeval tv;
199 gettimeofday (&tv, 0);
200
201 double next = tv.tv_sec - base + tv.tv_usec / 1.e6;
202
203 diff = next - now;
204 now = next;
205 }
206
207 timer::timer ()
208 {
209 struct timeval tv;
210 gettimeofday (&tv, 0);
211 base = tv.tv_sec + tv.tv_usec / 1.e6;
212 }
213
214 GLuint SDL_GL_LoadTexture (SDL_Surface * surface, GLfloat * texcoord)
215 {
216 GLuint texture;
217 int w, h;
218 SDL_Surface *image;
219 SDL_Rect area;
220 Uint32 saved_flags;
221 Uint8 saved_alpha;
222
223 /* Use the surface width and height expanded to powers of 2 */
224 //w = power_of_two (surface->w);
225 //h = power_of_two (surface->h);
226 w = power_of_two (surface->w);
227 h = power_of_two (surface->h);
228 texcoord[0] = 0.0f; /* Min X */
229 texcoord[1] = 0.0f; /* Min Y */
230 texcoord[2] = (GLfloat) surface->w / w; /* Max X */
231 texcoord[3] = (GLfloat) surface->h / h; /* Max Y */
232
233 image = SDL_CreateRGBSurface (SDL_SWSURFACE, w, h, 32,
234 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
235 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
236 #else
237 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
238 #endif
239 );
240 if (image == NULL)
241 {
242 return 0;
243 }
244
245 /* Save the alpha blending attributes */
246 saved_flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
247 saved_alpha = surface->format->alpha;
248 if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
249 {
250 SDL_SetAlpha (surface, 0, 0);
251 }
252
253 /* Copy the surface into the GL texture image */
254 area.x = 0;
255 area.y = 0;
256 area.w = surface->w;
257 area.h = surface->h;
258 SDL_BlitSurface (surface, &area, image, &area);
259
260 /* Restore the alpha blending attributes */
261 if ((saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA)
262 {
263 SDL_SetAlpha (surface, saved_flags, saved_alpha);
264 }
265
266 /* Create an OpenGL texture for the image */
267 glGenTextures (1, &texture);
268 glBindTexture (GL_TEXTURE_2D, texture);
269 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
270 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
271 glTexImage2D (GL_TEXTURE_2D,
272 0,
273 GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
274 SDL_FreeSurface (image); /* No longer needed */
275
276 return texture;
277 }
278
279 void render_text (GLint x, GLint y, const char *str)
280 {
281 glRasterPos2i (x, y);
282
283 while (!*str)
284 glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, *str++);
285 }
286
287 namespace gl {
288
289 void draw_box (const view &ctx, const sector &a, const sector &b)
290 {
291 int i;
292 static GLint verts[] = {
293 0x8000, 0x8004, 0x8006, 0x8002, // -x
294 0x8001, 0x8003, 0x8007, 0x8005, // +x
295 0x8000, 0x8001, 0x8005, 0x8004, // -y
296 0x8007, 0x8003, 0x8002, 0x8006, // +y
297 0x8000, 0x8002, 0x8003, 0x8001, // -z
298 0x8004, 0x8005, 0x8007, 0x8006, // +z
299 0
300 };
301
302 glBegin (GL_QUADS);
303
304 for (GLint *v = verts; *v; v++)
305 {
306 GLint mask = *v;
307
308 glVertex3i (mask & 1 ? b.x : a.x,
309 mask & 2 ? b.y : a.y,
310 mask & 4 ? b.z : a.z);
311 }
312
313 glEnd ();
314 }
315
316 }
317
318 //skedjuhlar main_scheduler;
319