ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/util.h
Revision: 1.55
Committed: Fri Oct 29 23:19:08 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.54: +24 -2 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #ifndef UTIL_H
2 #define UTIL_H
3
4 #include <cmath>
5 #include <cfloat>
6 #include <cstdlib>
7 #include <vector>
8 #include <string>
9
10 #include "opengl.h"
11
12 #include <SDL/SDL_image.h>
13
14 using namespace std;
15
16 typedef long long soffs; // 32 bit
17 typedef unsigned long long uoffs;
18 #define OFFS_BITS 63
19 #define SOFFS_MIN (soffs)-(1LL << (OFFS_BITS - 2))
20 #define SOFFS_MAX (soffs)+(1LL << (OFFS_BITS - 2))
21 #define MAXEXTENT (1ULL << (OFFS_BITS - 1))
22
23 #define ABS(n) ((n) < 0 ? -(n) : (n))
24
25 struct sector
26 {
27 soffs x, y, z;
28
29 sector (soffs x, soffs y, soffs z) : x(x), y(y), z(z) { };
30 sector (soffs xyz = 0) : x(xyz), y(xyz), z(xyz) { };
31
32 void offset (int subindex, uoffs extent)
33 {
34 if (subindex & 1) x += extent;
35 if (subindex & 2) y += extent;
36 if (subindex & 4) z += extent;
37 }
38 };
39
40 inline sector operator +(const sector &a, const sector &b)
41 {
42 return sector (a.x + b.x, a.y + b.y, a.z + b.z);
43 }
44
45 inline sector operator -(const sector &a, const sector &b)
46 {
47 return sector (a.x - b.x, a.y - b.y, a.z - b.z);
48 }
49
50 inline sector operator /(const sector &a, soffs b)
51 {
52 return sector (a.x / b, a.y / b, a.z / b);
53 }
54
55 inline sector operator >>(const sector &a, unsigned int b)
56 {
57 return sector (a.x >> b, a.y >> b, a.z >> b);
58 }
59
60 inline bool operator <=(const sector &a, const sector &b)
61 {
62 return a.x <= b.x && a.y <= b.y && a.z <= b.z;
63 }
64
65 inline soffs max (const sector &a)
66 {
67 return max (a.x, max (a.y, a.z));
68 }
69
70 inline sector translate (const sector &p, const sector &src, const sector &dst)
71 {
72 return p + (dst - src);
73 }
74
75 inline sector abs (const sector &s)
76 {
77 return sector (ABS (s.x), ABS (s.y), ABS (s.z));
78 }
79
80 struct vec2
81 {
82 GLfloat x, y;
83 vec2 () { };
84 vec2 (GLfloat s) : x(s), y(s) { };
85 vec2 (GLfloat x, GLfloat y) : x(x), y(y) { };
86 };
87
88 struct vec3
89 {
90 GLfloat x, y, z;
91 vec3 () { };
92 vec3 (GLfloat s) : x(s), y(s), z(s) { };
93 vec3 (GLfloat x, GLfloat y, GLfloat z) : x(x), y(y), z(z) { };
94 vec3 (const sector &s) : x(s.x), y(s.y), z(s.z) { };
95
96 const vec3 operator -() const
97 { return vec3 (-x, -y, -z); }
98 };
99
100 const vec3 normalize (const vec3 &v);
101 const vec3 cross (const vec3 &a, const vec3 &b);
102
103 inline const vec3 operator *(const vec3 &a, GLfloat s)
104 {
105 return vec3 (a.x * s, a.y * s, a.z * s);
106 }
107
108 inline const vec3 operator +(const vec3 &a, const vec3 &b)
109 {
110 return vec3 (a.x + b.x, a.y + b.y, a.z + b.z);
111 }
112
113 inline const vec3 operator -(const vec3 &a, const vec3 &b)
114 {
115 return vec3 (a.x - b.x, a.y - b.y, a.z - b.z);
116 }
117
118 inline GLfloat dot (const vec3 &a, const vec3 &b)
119 {
120 return a.x * b.x + a.y * b.y + a.z * b.z;
121 }
122
123 // squared length
124 inline const GLfloat length2 (const vec3 &v)
125 {
126 return dot (v, v);
127 }
128
129 inline const GLfloat length (const vec3 &v)
130 {
131 return sqrtf (length2 (v));
132 }
133
134 typedef vec3 point;
135
136 struct vec4
137 {
138 GLfloat x, y, z, w;
139 vec4 () { };
140 vec4 (GLfloat s) : x(s), y(s), z(s), w(s) { };
141 vec4 (GLfloat x, GLfloat y, GLfloat z, GLfloat w) : x(x), y(y), z(z), w(w) { };
142 vec4 (const vec3 &v, GLfloat w = 1.F) : x(v.x), y(v.y), z(v.z), w(w) { };
143 };
144
145 // a generic plane
146 struct plane
147 {
148 vec3 n;
149 GLfloat d;
150
151 plane () { };
152 plane (GLfloat a, GLfloat b, GLfloat c, GLfloat d);
153 };
154
155 inline GLfloat distance (const plane &a, const point &p)
156 {
157 return dot (a.n, p) + a.d;
158 }
159
160 struct sphere {
161 point p;
162 GLfloat r;
163
164 sphere () { };
165 sphere (const point &p, GLfloat r) : p(p), r(r) { };
166 };
167
168 inline bool overlap (const sphere &a, const sphere &b)
169 {
170 GLfloat d = a.r + b.r;
171
172 return length2 (a.p - b.p) <= d * d;
173 }
174
175 struct cone {
176 point p;
177 vec3 a; // axis
178 GLfloat f, fs1, fc2; // angle
179
180 cone () { };
181 cone (const point &p, const vec3 &a, GLfloat f)
182 : p(p), a(a), f(f)
183 {
184 fs1 = 1.F / sinf (f);
185 fc2 = cosf (f); fc2 *= fc2;
186 };
187 };
188
189 inline bool overlap (const cone &c, const sphere &s)
190 {
191 vec3 d = s.p - c.p + c.a * (s.r * c.fs1);
192 GLfloat dd = dot (c.a, d);
193 return dd > 0.F && dd * dd >= length2 (d) * c.fc2;
194 }
195
196 void renormalize (sector &s, point &p);
197
198 struct colour
199 {
200 GLubyte r, g, b, a;
201 colour (GLfloat r = 1., GLfloat g = 1., GLfloat b = 1., GLfloat a = 1.)
202 : r(GLubyte (r * 255.F + .5F))
203 , g(GLubyte (g * 255.F + .5F))
204 , b(GLubyte (b * 255.F + .5F))
205 , a(GLubyte (a * 255.F + .5F))
206 {
207 }
208 };
209
210 struct tex2
211 {
212 GLfloat s, t;
213 tex2 () { };
214 tex2 (GLfloat s, GLfloat t) : s(s), t(t) { };
215 };
216
217 template<typename unused> class gltype_traits { };
218
219 template<> struct gltype_traits<GLfloat > { static const GLenum gltype () { return GL_FLOAT; } };
220 template<> struct gltype_traits<GLdouble> { static const GLenum gltype () { return GL_DOUBLE; } };
221 template<> struct gltype_traits<GLint > { static const GLenum gltype () { return GL_INT; } };
222 template<> struct gltype_traits<GLuint > { static const GLenum gltype () { return GL_UNSIGNED_INT; } };
223 template<> struct gltype_traits<GLshort > { static const GLenum gltype () { return GL_SHORT; } };
224 template<> struct gltype_traits<GLushort> { static const GLenum gltype () { return GL_UNSIGNED_SHORT; } };
225 template<> struct gltype_traits<GLbyte > { static const GLenum gltype () { return GL_BYTE; } };
226 template<> struct gltype_traits<GLubyte > { static const GLenum gltype () { return GL_UNSIGNED_BYTE; } };
227
228 template<typename vectype> class vector_traits { };
229
230 template<>
231 struct vector_traits<vec2>
232 {
233 typedef GLfloat basetype;
234 static const int dimension () { return 2; }
235 };
236
237 template<>
238 struct vector_traits<vec3>
239 {
240 typedef GLfloat basetype;
241 static const int dimension () { return 3; }
242 };
243
244 template<>
245 struct vector_traits<vec4>
246 {
247 typedef GLfloat basetype;
248 static const int dimension () { return 4; }
249 };
250
251 template<>
252 struct vector_traits<tex2>
253 {
254 typedef GLfloat basetype;
255 static const int dimension () { return 2; }
256 };
257
258 template<>
259 struct vector_traits<colour>
260 {
261 typedef GLubyte basetype;
262 static const int dimension () { return 4; }
263 };
264
265 struct box
266 {
267 point a, b;
268
269 box() { };
270
271 void reset ()
272 {
273 a = point ( FLT_MAX, FLT_MAX, FLT_MAX);
274 b = point (-FLT_MAX, -FLT_MAX, -FLT_MAX);
275 }
276
277 void add (const box &o);
278 void add (const point &p);
279 };
280
281 struct entity;
282 struct geometry;
283 struct view;
284 struct octant;
285
286 extern struct timer
287 {
288 static double now;
289 static double diff;
290 static double fps;
291
292 static void frame ();
293 timer ();
294 } timer;
295
296 /*
297 #define MAX_EVENT_TYPES 10
298 enum event_type { TIMER_EV };
299 struct event
300 {
301 event_type type;
302 };
303
304 typedef callback1<void, event&> event_cb;
305
306 class skedjuhlar
307 {
308 public:
309 // only 10 types for now
310 private:
311 vector <list<event_cb> > event_lists;
312
313 public:
314 skedjuhlar () {
315 event_lists.resize (MAX_EVENT_TYPES, list<event_cb>());
316 }
317
318 void register_event_cb (const event_type &t, const event_cb &e) {
319 event_lists[t].push_back (e);
320 };
321 void send_event (event &e) {
322 list<event_cb> &l = event_lists[e.type];
323 for (list<event_cb>::iterator it = l.begin (); it != l.end (); it++) {
324 (*it)(e);
325 }
326 };
327 void check_events () {
328 while (!events.empty ()) {
329 event &e = events.pop_front ();
330 list<event_cb> &l = event_lists[e->name];
331 for (list<event_cb>::iterator it = l.begin (); it !+ l.end (); it++) {
332 (*it)(e);
333 }
334 delete e; // ugly slow? hai hai..... 183G
335 }
336 }
337 };
338
339 extern skedjuhlar main_scheduler;
340 */
341
342 namespace gl
343 {
344 #ifdef DEBUG
345 void errchk (const char *name, const char *args, const char *file, int line);
346 #endif
347
348 struct vertex_v3f
349 {
350 point p; // vertex
351
352 vertex_v3f () { };
353 vertex_v3f (point p) : p(p) { };
354
355 GLenum gl_format () const { return GL_V3F; }
356 };
357
358 struct vertex_t2f_n3f_v3f
359 {
360 tex2 t; // texture
361 vec3 n; // normal
362 point p; // vertex
363
364 vertex_t2f_n3f_v3f () { }
365 vertex_t2f_n3f_v3f (point p, vec3 n, tex2 t = tex2()) : p(p), n(n), t(t) { }
366
367 GLenum gl_format () const { return GL_T2F_N3F_V3F; }
368 };
369
370 GLsizei format_stride (GLenum format);
371 GLsizei format_offset_p (GLenum format);
372 GLsizei format_offset_n (GLenum format);
373 GLsizei format_offset_t (GLenum format);
374
375 struct index_ushort
376 {
377 GLushort i;
378
379 index_ushort () { }
380 index_ushort (GLushort i) : i(i) { }
381
382 GLenum gl_format () const { return GL_UNSIGNED_SHORT; }
383 };
384
385 struct matrix
386 {
387 GLfloat data[4][4];
388
389 const GLfloat operator ()(int i, int j) const { return data[j][i]; };
390 GLfloat &operator ()(int i, int j) { return data[j][i]; };
391
392 operator GLfloat *() { return &data[0][0]; }
393
394 void diagonal (GLfloat v);
395 void clear () { diagonal (0.F); };
396 void identity () { diagonal (1.F); };
397
398 void print (); // ugly
399
400 static matrix translation (const vec3 &v);
401 static matrix rotation (GLfloat degrees, const vec3 &axis);
402 static matrix scaling (GLfloat sx, GLfloat sy, GLfloat sz, GLfloat w = 1.F);
403
404 matrix () { };
405 matrix (GLfloat diag) { diagonal (diag); };
406 };
407
408 matrix operator *(const matrix &a, const matrix &b);
409 vec3 operator *(const matrix &a, const vec3 &v);
410
411 template<GLenum target>
412 struct vertex_buffer_object {
413 GLuint buffer;
414 GLenum format;
415 GLsizei count;
416
417 bool alloc ()
418 {
419 if (buffer)
420 return false;
421
422 glGenBuffersARB (1, &buffer);
423 return true;
424 }
425
426 void bind ()
427 {
428 glBindBufferARB (target, buffer);
429 }
430
431 template<class data>
432 void set (const data *d, GLsizei count, GLenum usage = GL_STATIC_DRAW_ARB)
433 {
434 alloc ();
435 format = d->gl_format ();
436 this->count = count;
437 vertex_buffer_object::bind ();
438 glBufferDataARB (target, count * sizeof (data), d, usage);
439 }
440
441 template<class data>
442 void set (const vector<data> &d, GLenum usage = GL_STATIC_DRAW_ARB)
443 {
444 set (&d[0], d.size (), usage);
445 }
446
447 void set (GLsizei bytes, GLenum usage = GL_DYNAMIC_DRAW_ARB)
448 {
449 alloc ();
450 format = GL_ZERO;
451 this->count = bytes;
452 vertex_buffer_object::bind ();
453 glBufferDataARB (target, count, 0, usage);
454 }
455
456 void *map (GLenum access = GL_WRITE_ONLY)
457 {
458 vertex_buffer_object::bind ();
459 return glMapBufferARB (target, access);
460 }
461
462 void unmap ()
463 {
464 vertex_buffer_object::bind ();
465 glUnmapBuffer (target);
466 }
467
468 vertex_buffer_object ()
469 : buffer(0)
470 {
471 }
472
473 ~vertex_buffer_object ()
474 {
475 if (buffer)
476 glDeleteBuffersARB (1, &buffer);
477 }
478
479 operator GLint ()
480 {
481 return buffer;
482 }
483 };
484
485 struct vertex_buffer : vertex_buffer_object<GL_ARRAY_BUFFER_ARB> {
486 void bind ()
487 {
488 vertex_buffer_object<GL_ARRAY_BUFFER_ARB>::bind ();
489 if (format)
490 glInterleavedArrays (format, 0, 0);
491 }
492
493 void draw (GLenum mode, GLint first, GLsizei count)
494 {
495 bind ();
496 glDrawArrays (mode, first, count);
497 }
498 };
499
500 struct index_buffer : vertex_buffer_object<GL_ELEMENT_ARRAY_BUFFER_ARB> {
501 void draw (GLenum mode, GLint first, GLsizei count)
502 {
503 bind ();
504 glDrawElements (mode, count, format, (GLushort*)0 + first); // only SHORT supported :( // first //D//TODO
505 }
506 };
507
508 void draw_bbox (const sector &a, const sector &b);
509
510 }
511
512 GLuint SDL_GL_LoadTexture (SDL_Surface *surface, GLfloat *texcoord);
513
514 #endif
515