ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/util.h
Revision: 1.60
Committed: Fri Nov 12 01:18:42 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.59: +69 -1 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
33 inline sector operator +(const sector &a, const sector &b)
34 {
35 return sector (a.x + b.x, a.y + b.y, a.z + b.z);
36 }
37
38 inline sector operator -(const sector &a, const sector &b)
39 {
40 return sector (a.x - b.x, a.y - b.y, a.z - b.z);
41 }
42
43 inline sector operator /(const sector &a, soffs b)
44 {
45 return sector (a.x / b, a.y / b, a.z / b);
46 }
47
48 inline sector operator >>(const sector &a, unsigned int b)
49 {
50 return sector (a.x >> b, a.y >> b, a.z >> b);
51 }
52
53 inline bool operator <=(const sector &a, const sector &b)
54 {
55 return a.x <= b.x && a.y <= b.y && a.z <= b.z;
56 }
57
58 inline soffs max (const sector &a)
59 {
60 return max (a.x, max (a.y, a.z));
61 }
62
63 inline sector translate (const sector &p, const sector &src, const sector &dst)
64 {
65 return p + (dst - src);
66 }
67
68 inline sector abs (const sector &s)
69 {
70 return sector (ABS (s.x), ABS (s.y), ABS (s.z));
71 }
72
73 struct vec2
74 {
75 GLfloat x, y;
76 vec2 () { };
77 vec2 (GLfloat s) : x(s), y(s) { };
78 vec2 (GLfloat x, GLfloat y) : x(x), y(y) { };
79 };
80
81 inline const vec2 operator +(const vec2 &a, const vec2 &b)
82 {
83 return vec2 (a.x + b.x, a.y + b.y);
84 }
85
86 inline const vec2 operator -(const vec2 &a, const vec2 &b)
87 {
88 return vec2 (a.x - b.x, a.y - b.y);
89 }
90
91 struct vec3
92 {
93 GLfloat x, y, z;
94 vec3 () { };
95 vec3 (GLfloat s) : x(s), y(s), z(s) { };
96 vec3 (GLfloat x, GLfloat y, GLfloat z) : x(x), y(y), z(z) { };
97 vec3 (const sector &s) : x(s.x), y(s.y), z(s.z) { };
98
99 const vec3 operator -() const
100 { return vec3 (-x, -y, -z); }
101 };
102
103 const vec3 normalize (const vec3 &v);
104 const vec3 cross (const vec3 &a, const vec3 &b);
105
106 inline const vec3 operator *(const vec3 &a, GLfloat s)
107 {
108 return vec3 (a.x * s, a.y * s, a.z * s);
109 }
110
111 inline const vec3 operator +(const vec3 &a, const vec3 &b)
112 {
113 return vec3 (a.x + b.x, a.y + b.y, a.z + b.z);
114 }
115
116 inline const vec3 operator -(const vec3 &a, const vec3 &b)
117 {
118 return vec3 (a.x - b.x, a.y - b.y, a.z - b.z);
119 }
120
121 inline GLfloat dot (const vec3 &a, const vec3 &b)
122 {
123 return a.x * b.x + a.y * b.y + a.z * b.z;
124 }
125
126 // squared length
127 inline const GLfloat length2 (const vec3 &v)
128 {
129 return dot (v, v);
130 }
131
132 inline const GLfloat length (const vec3 &v)
133 {
134 return sqrtf (length2 (v));
135 }
136
137 typedef vec3 point;
138
139 struct vec4
140 {
141 GLfloat x, y, z, w;
142 vec4 () { };
143 vec4 (GLfloat s) : x(s), y(s), z(s), w(s) { };
144 vec4 (GLfloat x, GLfloat y, GLfloat z, GLfloat w) : x(x), y(y), z(z), w(w) { };
145 vec4 (const vec3 &v, GLfloat w = 1.F) : x(v.x), y(v.y), z(v.z), w(w) { };
146 };
147
148 // a generic plane
149 struct plane
150 {
151 vec3 n;
152 GLfloat d;
153
154 plane () { };
155 plane (GLfloat a, GLfloat b, GLfloat c, GLfloat d);
156 };
157
158 inline GLfloat distance (const plane &a, const point &p)
159 {
160 return dot (a.n, p) + a.d;
161 }
162
163 struct sphere {
164 point p;
165 GLfloat r;
166
167 sphere () { };
168 sphere (const point &p, GLfloat r) : p(p), r(r) { };
169 };
170
171 inline bool overlap (const sphere &a, const sphere &b)
172 {
173 GLfloat d = a.r + b.r;
174
175 return length2 (a.p - b.p) <= d * d;
176 }
177
178 struct cone {
179 point p;
180 vec3 a; // axis
181 GLfloat f, fs1, fc2; // angle
182
183 cone () { };
184 cone (const point &p, const vec3 &a, GLfloat f)
185 : p(p), a(a), f(f)
186 {
187 fs1 = 1.F / sinf (f);
188 fc2 = cosf (f); fc2 *= fc2;
189 };
190 };
191
192 inline bool overlap (const cone &c, const sphere &s)
193 {
194 vec3 d = s.p - c.p + c.a * (s.r * c.fs1);
195 GLfloat dd = dot (c.a, d);
196 return dd > 0.F && dd * dd >= length2 (d) * c.fc2;
197 }
198
199 void renormalize (sector &s, point &p);
200
201 struct colour
202 {
203 GLubyte r, g, b, a;
204 colour (GLfloat r = 1., GLfloat g = 1., GLfloat b = 1., GLfloat a = 1.)
205 : r(GLubyte (r * 255.F + .5F))
206 , g(GLubyte (g * 255.F + .5F))
207 , b(GLubyte (b * 255.F + .5F))
208 , a(GLubyte (a * 255.F + .5F))
209 {
210 }
211 };
212
213 struct tex2
214 {
215 GLfloat s, t;
216 tex2 () { };
217 tex2 (GLfloat s, GLfloat t) : s(s), t(t) { };
218 };
219
220 inline const tex2 operator +(const tex2 &a, const tex2 &b)
221 {
222 return tex2 (a.s + b.s, a.t + b.t);
223 }
224
225 inline const tex2 operator -(const tex2 &a, const tex2 &b)
226 {
227 return tex2 (a.s - b.s, a.t - b.t);
228 }
229
230 inline const tex2 operator *(const tex2 &a, GLfloat s)
231 {
232 return tex2 (a.s * s, a.t * s);
233 }
234
235 template<typename vectype> class vector_traits { };
236
237 template<>
238 struct vector_traits<vec2>
239 {
240 typedef GLfloat basetype;
241 static const int dimension () { return 2; }
242 };
243
244 template<>
245 struct vector_traits<vec3>
246 {
247 typedef GLfloat basetype;
248 static const int dimension () { return 3; }
249 };
250
251 template<>
252 struct vector_traits<vec4>
253 {
254 typedef GLfloat basetype;
255 static const int dimension () { return 4; }
256 };
257
258 template<>
259 struct vector_traits<tex2>
260 {
261 typedef GLfloat basetype;
262 static const int dimension () { return 2; }
263 };
264
265 template<>
266 struct vector_traits<colour>
267 {
268 typedef GLubyte basetype;
269 static const int dimension () { return 4; }
270 };
271
272 struct box
273 {
274 point a, b;
275
276 box() { };
277
278 void reset ()
279 {
280 a = point ( FLT_MAX, FLT_MAX, FLT_MAX);
281 b = point (-FLT_MAX, -FLT_MAX, -FLT_MAX);
282 }
283
284 void add (const box &o);
285 void add (const point &p);
286 };
287
288 struct entity;
289 struct geometry;
290 struct view;
291 struct octant;
292
293 extern struct timer
294 {
295 static double now;
296 static double diff;
297 static double fps;
298
299 static void frame ();
300 timer ();
301 } timer;
302
303 /*
304 #define MAX_EVENT_TYPES 10
305 enum event_type { TIMER_EV };
306 struct event
307 {
308 event_type type;
309 };
310
311 typedef callback1<void, event&> event_cb;
312
313 class skedjuhlar
314 {
315 public:
316 // only 10 types for now
317 private:
318 vector <list<event_cb> > event_lists;
319
320 public:
321 skedjuhlar () {
322 event_lists.resize (MAX_EVENT_TYPES, list<event_cb>());
323 }
324
325 void register_event_cb (const event_type &t, const event_cb &e) {
326 event_lists[t].push_back (e);
327 };
328 void send_event (event &e) {
329 list<event_cb> &l = event_lists[e.type];
330 for (list<event_cb>::iterator it = l.begin (); it != l.end (); it++) {
331 (*it)(e);
332 }
333 };
334 void check_events () {
335 while (!events.empty ()) {
336 event &e = events.pop_front ();
337 list<event_cb> &l = event_lists[e->name];
338 for (list<event_cb>::iterator it = l.begin (); it !+ l.end (); it++) {
339 (*it)(e);
340 }
341 delete e; // ugly slow? hai hai..... 183G
342 }
343 }
344 };
345
346 extern skedjuhlar main_scheduler;
347 */
348
349 namespace gl
350 {
351 #ifdef DEBUG
352 void errchk (const char *name, const char *args, const char *file, int line);
353 #endif
354
355 struct vertex_v3f
356 {
357 point v; // vertex
358
359 vertex_v3f () { };
360 vertex_v3f (point v) : v(v) { };
361 };
362
363 struct vertex_t2f_n3f_v3f
364 {
365 tex2 t; // texture
366 vec3 n; // normal
367 point v; // vertex
368
369 vertex_t2f_n3f_v3f () { }
370 vertex_t2f_n3f_v3f (point v, vec3 n, tex2 t = tex2()) : v(v), n(n), t(t) { }
371 };
372
373 template<typename unused> class type_traits { };
374
375 template<> struct type_traits<GLfloat > { static const GLenum glenum () { return GL_FLOAT; } };
376 template<> struct type_traits<GLdouble> { static const GLenum glenum () { return GL_DOUBLE; } };
377 template<> struct type_traits<GLint > { static const GLenum glenum () { return GL_INT; } };
378 template<> struct type_traits<GLuint > { static const GLenum glenum () { return GL_UNSIGNED_INT; } };
379 template<> struct type_traits<GLshort > { static const GLenum glenum () { return GL_SHORT; } };
380 template<> struct type_traits<GLushort> { static const GLenum glenum () { return GL_UNSIGNED_SHORT; } };
381 template<> struct type_traits<GLbyte > { static const GLenum glenum () { return GL_BYTE; } };
382 template<> struct type_traits<GLubyte > { static const GLenum glenum () { return GL_UNSIGNED_BYTE; } };
383 template<> struct type_traits<vertex_v3f > { static const GLenum glenum () { return GL_V3F; } };
384 template<> struct type_traits<vertex_t2f_n3f_v3f> { static const GLenum glenum () { return GL_T2F_N3F_V3F; } };
385
386 template<GLenum unused> class enum_traits { };
387
388 template<> struct enum_traits<GL_FLOAT > { typedef GLfloat type; };
389 template<> struct enum_traits<GL_DOUBLE > { typedef GLdouble type; };
390 template<> struct enum_traits<GL_INT > { typedef GLint type; };
391 template<> struct enum_traits<GL_UNSIGNED_INT > { typedef GLuint type; };
392 template<> struct enum_traits<GL_SHORT > { typedef GLshort type; };
393 template<> struct enum_traits<GL_UNSIGNED_SHORT> { typedef GLushort type; };
394 template<> struct enum_traits<GL_BYTE > { typedef GLbyte type; };
395 template<> struct enum_traits<GL_UNSIGNED_BYTE > { typedef GLubyte type; };
396 template<> struct enum_traits<GL_V3F > { typedef vertex_v3f type; };
397 template<> struct enum_traits<GL_T2F_N3F_V3F > { typedef vertex_t2f_n3f_v3f type; };
398
399 // deprecated:
400 GLsizei format_stride (GLenum format);
401 GLsizei format_offset_p (GLenum format);
402 GLsizei format_offset_n (GLenum format);
403 GLsizei format_offset_t (GLenum format);
404
405 struct matrix
406 {
407 GLfloat data[4][4];
408
409 const GLfloat operator ()(int i, int j) const { return data[j][i]; };
410 GLfloat &operator ()(int i, int j) { return data[j][i]; };
411
412 operator GLfloat *() { return &data[0][0]; }
413
414 void diagonal (GLfloat v);
415 void clear () { diagonal (0.F); };
416 void identity () { diagonal (1.F); };
417
418 void print (); // ugly
419
420 static matrix translation (const vec3 &v);
421 static matrix rotation (GLfloat degrees, const vec3 &axis);
422 static matrix scaling (GLfloat sx, GLfloat sy, GLfloat sz, GLfloat w = 1.F);
423
424 matrix () { };
425 matrix (GLfloat diag) { diagonal (diag); };
426 };
427
428 matrix operator *(const matrix &a, const matrix &b);
429 vec3 operator *(const matrix &a, const vec3 &v);
430
431 template<GLenum target>
432 struct vertex_buffer_object
433 {
434 GLuint buffer;
435 GLenum format;
436 GLsizei count;
437 GLsizei size;
438
439 bool alloc ()
440 {
441 if (buffer)
442 return false;
443
444 glGenBuffersARB (1, &buffer);
445 return true;
446 }
447
448 void bind ()
449 {
450 glBindBufferARB (target, buffer);
451 }
452
453 template<class basetype>
454 void set (const basetype *d, GLsizei count, GLenum usage = GL_STATIC_DRAW_ARB)
455 {
456 alloc ();
457 format = type_traits<basetype>::glenum ();
458 this->count = count;
459 size = sizeof (basetype);
460 vertex_buffer_object::bind ();
461 glBufferDataARB (target, count * this->size, d, usage);
462 }
463
464 template<class data>
465 void set (const vector<data> &d, GLenum usage = GL_STATIC_DRAW_ARB)
466 {
467 set (&d[0], d.size (), usage);
468 }
469
470 template<typename basetype>
471 void set (GLsizei count, GLenum usage = GL_DYNAMIC_DRAW_ARB)
472 {
473 alloc ();
474 format = type_traits<basetype>::glenum ();
475 this->count = count;
476 size = sizeof (basetype);
477 vertex_buffer_object::bind ();
478 glBufferDataARB (target, this->count * size, 0, usage);
479 }
480
481 void *map (GLenum access = GL_WRITE_ONLY)
482 {
483 vertex_buffer_object::bind ();
484 return glMapBufferARB (target, access);
485 }
486
487 void unmap ()
488 {
489 vertex_buffer_object::bind ();
490 glUnmapBuffer (target);
491 }
492
493 vertex_buffer_object ()
494 : buffer(0)
495 {
496 }
497
498 ~vertex_buffer_object ()
499 {
500 if (buffer)
501 glDeleteBuffersARB (1, &buffer);
502 }
503
504 operator GLint ()
505 {
506 return buffer;
507 }
508 };
509
510 struct vertex_buffer : vertex_buffer_object<GL_ARRAY_BUFFER_ARB>
511 {
512 void bind ()
513 {
514 vertex_buffer_object<GL_ARRAY_BUFFER_ARB>::bind ();
515 glInterleavedArrays (format, 0, 0);
516 }
517
518 void draw (GLenum mode, GLint first, GLsizei count)
519 {
520 bind ();
521 glDrawArrays (mode, first, count);
522 }
523 };
524
525 struct index_buffer : vertex_buffer_object<GL_ELEMENT_ARRAY_BUFFER_ARB>
526 {
527 void draw (GLenum mode, GLint first, GLsizei count)
528 {
529 bind ();
530 glDrawElements (mode, count, format, (GLvoid *)((char *)0 + first * size)); // only SHORT supported :( // first //D//TODO
531 }
532 };
533
534 void draw_bbox (const sector &a, const sector &b);
535
536 GLuint load_texture (SDL_Surface *surface, GLfloat *texcoord);
537 }
538
539 template<typename value>
540 struct idmappable
541 {
542 struct idptr
543 {
544 value *p;
545 unsigned int gen;
546
547 idptr () : p(0) { };
548 };
549
550 vector<idptr> idmap;
551 };
552
553 struct idmap_context
554 {
555 struct id
556 {
557 unsigned int idx;
558 unsigned int gen;
559 };
560
561 vector<id> freeid;
562
563 unsigned int next;
564
565 idmap_context ();
566 id get ();
567 void put (id &i);
568 };
569
570 template<class value>
571 struct idmap
572 {
573 typedef idmappable<value> base;
574 typedef typename idmappable<value>::idptr idptr;
575
576 idmap_context &ctx;
577 idmap_context::id id;
578
579 idmap (idmap_context &ctx)
580 : ctx (ctx)
581 , id (ctx.get ())
582 {
583 }
584
585 ~idmap ()
586 {
587 ctx.put (id);
588 }
589
590 value *&operator [](const base &k)
591 {
592 if (k.idmap.size () <= id.idx)
593 k.idmap.resize (id.idx + 1);
594
595 idptr &p = k.idmap [id.idx];
596
597 if (p.gen != id.gen)
598 {
599 delete p.p;
600 p.p = 0;
601 p.gen = id.gen;
602 }
603
604 return p.p;
605 }
606 };
607
608 #endif
609