ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/entity.C
Revision: 1.69
Committed: Thu Aug 11 19:28:45 2005 UTC (18 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.68: +10 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.54 #include <cassert>
2     #include <cstdlib>
3 root 1.1 #include <algorithm>
4    
5     using namespace std;
6 root 1.42
7     #include "opengl.h"
8 root 1.1
9 root 1.28 #include "util.h"
10 root 1.1 #include "entity.h"
11 root 1.4 #include "oct.h"
12 root 1.13 #include "view.h"
13 root 1.1
14 root 1.21 /////////////////////////////////////////////////////////////////////////////
15    
16 root 1.38 geometry::~geometry ()
17 root 1.1 {
18 root 1.2 }
19    
20 root 1.38 template class geometry_opengl1d<GL_POINTS>;
21     template class geometry_opengl1d<GL_LINES>;
22     template class geometry_opengl1d<GL_LINE_STRIP>;
23     template class geometry_opengl1d<GL_LINE_LOOP>;
24     template class geometry_opengl2d<GL_TRIANGLES>;
25     template class geometry_opengl2d<GL_TRIANGLE_STRIP>;
26     template class geometry_opengl2d<GL_TRIANGLE_FAN>;
27     template class geometry_opengl2d<GL_QUADS>;
28     template class geometry_opengl2d<GL_QUAD_STRIP>;
29     template class geometry_opengl2d<GL_POLYGON>;
30 root 1.21
31 root 1.38 geometry_opengl::geometry_opengl ()
32 root 1.24 {
33     list = glGenLists (1);
34     }
35    
36 root 1.38 geometry_opengl::~geometry_opengl ()
37 root 1.24 {
38     glDeleteLists (list, 1);
39     }
40    
41 root 1.2 template<GLenum type>
42 root 1.46 void geometry_opengl1d<type>::set (const vector<vertex_v3f> &v)
43 root 1.2 {
44 root 1.38 clear ();
45     insert (end (), v.begin (), v.end ());
46    
47 root 1.6 bbox.reset ();
48    
49 root 1.38 for (const_iterator i = end (); i-- != begin (); )
50 root 1.54 bbox.add (i->v);
51 root 1.6
52 root 1.38 update ();
53 root 1.2 }
54    
55     template<GLenum type>
56 root 1.38 void geometry_opengl1d<type>::draw (view &ctx)
57 root 1.2 {
58     glBegin (type);
59    
60     for (iterator i = begin (); i < end (); ++i)
61 root 1.54 glVertex3fv ((GLfloat *)&i->v);
62 root 1.2
63     glEnd ();
64     }
65    
66     template<GLenum type>
67 root 1.46 void geometry_opengl2d<type>::set (const vector<vertex_t2f_n3f_v3f> &v)
68 root 1.2 {
69 root 1.24 bbox.reset ();
70    
71 root 1.46 for (vector<vertex_t2f_n3f_v3f>::const_iterator i = v.end (); i-- != v.begin (); )
72 root 1.54 bbox.add (i->v);
73 root 1.26
74 root 1.28 update ();
75 root 1.24
76     glNewList (list, GL_COMPILE);
77 root 1.14
78 root 1.20 #if 0
79 root 1.24 glBegin (type);
80    
81 root 1.46 for (vector<vertex_t2f_n3f_v3f>::const_iterator i = v.begin (); i < v.end (); ++i)
82 root 1.24 {
83     glTexCoord2fv ((GLfloat *)&i->t);
84     glNormal3fv ((GLfloat *)&i->n);
85 root 1.54 glVertex3fv ((GLfloat *)&i->v);
86 root 1.24 }
87 root 1.4
88 root 1.24 glEnd ();
89 root 1.19 #else
90 root 1.65 glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
91    
92 root 1.24 glEnableClientState (GL_VERTEX_ARRAY);
93     glEnableClientState (GL_NORMAL_ARRAY);
94     glEnableClientState (GL_TEXTURE_COORD_ARRAY);
95 root 1.46 glNormalPointer (GL_FLOAT, sizeof (vertex_t2f_n3f_v3f), (void *)&v.begin ()->n);
96     glTexCoordPointer (2, GL_FLOAT, sizeof (vertex_t2f_n3f_v3f), (void *)&v.begin ()->t);
97 root 1.67 glVertexPointer (3, GL_FLOAT, sizeof (vertex_t2f_n3f_v3f), (void *)&v.begin ()->v);
98 root 1.19
99 root 1.24 glDrawArrays (type, 0, v.size ());
100 root 1.46
101     glDisableClientState (GL_VERTEX_ARRAY);
102     glDisableClientState (GL_NORMAL_ARRAY);
103     glDisableClientState (GL_TEXTURE_COORD_ARRAY);
104 root 1.19 #endif
105 root 1.22
106 root 1.24 glEndList ();
107     }
108 root 1.2
109 root 1.24 template<GLenum type>
110 root 1.38 void geometry_opengl2d<type>::draw (view &ctx)
111 root 1.24 {
112 root 1.51 m->enable (ctx);
113 root 1.17 glCallList (list);
114 root 1.51 m->disable (ctx);
115 root 1.22 }
116    
117 root 1.44 void geometry_sphere::update ()
118     {
119     bbox.reset ();
120     bbox.add (-point (radius, radius, radius));
121     bbox.add ( point (radius, radius, radius));
122    
123     geometry::update ();
124     }
125    
126     void geometry_sphere::draw (view &ctx)
127     {
128 root 1.48 int n = min (100, max (15, (int)(ctx.pixfact * radius) / 10));
129 root 1.44
130 root 1.61 m->enable (ctx);
131 root 1.44 GLUquadric *quad = gluNewQuadric ();
132     gluQuadricTexture (quad, true);
133     gluSphere (quad, radius, n, n);
134     gluDeleteQuadric (quad);
135 root 1.61 m->disable (ctx);
136 root 1.44 }
137    
138 root 1.22 /////////////////////////////////////////////////////////////////////////////
139    
140 root 1.63 void geometry_indexed_2d::draw (view &ctx)
141     {
142     m->enable (ctx);
143     vb.bind ();
144     ib.draw (type, 0, ib.count);
145     m->disable (ctx);
146     }
147    
148     /////////////////////////////////////////////////////////////////////////////
149    
150 root 1.38 void geometry_transform::update ()
151 root 1.22 {
152 root 1.38 const box &sub = g->bbox;
153 root 1.27
154     bbox.reset ();
155     bbox.add (m * vec3 (sub.a.x, sub.a.y, sub.a.z));
156     bbox.add (m * vec3 (sub.b.x, sub.a.y, sub.a.z));
157     bbox.add (m * vec3 (sub.a.x, sub.b.y, sub.a.z));
158     bbox.add (m * vec3 (sub.b.x, sub.b.y, sub.a.z));
159     bbox.add (m * vec3 (sub.a.x, sub.a.y, sub.b.z));
160     bbox.add (m * vec3 (sub.b.x, sub.a.y, sub.b.z));
161     bbox.add (m * vec3 (sub.a.x, sub.b.y, sub.b.z));
162     bbox.add (m * vec3 (sub.b.x, sub.b.y, sub.b.z));
163 root 1.22
164 root 1.38 geometry::update ();
165 root 1.28 }
166    
167 root 1.38 #if 0
168     void geometry_transform::renormalize ()
169 root 1.28 {
170 root 1.34 point trans(m(0,3), m(1,3), m(2,3));
171     ::renormalize (e->orig, trans);
172     m(0,3) = trans.x; m(1,3) = trans.y; m(2,3) = trans.z;
173 root 1.38 }
174 root 1.28 #endif
175    
176 root 1.38 void geometry_transform::update (const matrix &xfrm)
177 root 1.28 {
178     m = m * xfrm;
179    
180     update ();
181     }
182    
183 root 1.38 void geometry_transform::set_matrix (const matrix &xfrm)
184 root 1.28 {
185     m = xfrm;
186    
187     update ();
188 root 1.22 }
189    
190 root 1.38 void geometry_transform::draw (view &ctx)
191 root 1.22 {
192 root 1.33 glPushMatrix ();
193     glMultMatrixf ((GLfloat *)&m);
194 root 1.38 g->draw (ctx);
195 root 1.33 glPopMatrix ();
196 root 1.2 }
197    
198 root 1.38 void geometry_anim::draw (view &ctx)
199 root 1.23 {
200 root 1.30 matrix save_m = m;
201 root 1.23
202 root 1.30 update (matrix::rotation (vx * timer.now, vec3 (1, 0, 0))
203     * matrix::rotation (vy * timer.now, vec3 (0, 1, 0))
204     * matrix::rotation (vz * timer.now, vec3 (0, 0, 1)));
205 root 1.28
206 root 1.38 geometry_transform::draw (ctx);
207 root 1.23
208     m = save_m;
209 root 1.38 }
210    
211     /////////////////////////////////////////////////////////////////////////////
212    
213     void geometry_filter::set (geometry *g)
214     {
215     this->g = g;
216    
217     if (g)
218     g->parent = this;
219    
220     update ();
221     }
222    
223     void geometry_filter::update ()
224     {
225     if (g)
226     {
227     bbox = g->bbox;
228     geometry::update ();
229     }
230     }
231    
232     void geometry_filter::draw (view &ctx)
233     {
234     g->draw (ctx);
235     }
236    
237     geometry_filter::~geometry_filter ()
238     {
239     delete g;
240     }
241    
242     /////////////////////////////////////////////////////////////////////////////
243    
244     void geometry_container::update ()
245     {
246     bbox.reset ();
247    
248     for (iterator i = end (); i-- != begin (); )
249     bbox.add ((*i)->bbox);
250    
251     geometry::update ();
252     }
253    
254     void geometry_container::add (geometry *g)
255     {
256     push_back (g);
257     g->parent = this;
258    
259     update ();
260     }
261    
262     void geometry_container::draw (view &ctx)
263     {
264     for (iterator i = end (); i-- != begin (); )
265     (*i)->draw (ctx);
266     }
267    
268     geometry_container::~geometry_container ()
269     {
270     for (iterator i = end (); i-- != begin (); )
271     delete *i;
272    
273     clear ();
274     }
275    
276 root 1.52 ///////////////////////////////////////////////////////////////////////////
277 root 1.38
278 root 1.39 static void nurbs_error (GLenum errorCode)
279     {
280     const GLubyte *estring;
281     estring = gluErrorString(errorCode);
282     fprintf (stderr, "Nurbs error: %s\n", estring);
283     }
284 root 1.40
285 root 1.39 void errorCallback(GLenum errorCode)
286     {
287     const GLubyte *estring;
288    
289     estring = gluErrorString(errorCode);
290     fprintf (stderr, "Tessellation Error: %s\n", estring);
291     exit (0);
292     }
293 root 1.54
294 root 1.41 void tcbBegin (GLenum prim)
295     {
296     glBegin (prim);
297     }
298 root 1.54
299 root 1.41 void tcbVertex (void *data)
300     {
301     glVertex3fv ((GLfloat *)data);
302     }
303 root 1.54
304 root 1.41 void tcbEnd ()
305     {
306     glEnd ();
307     }
308 root 1.54
309 root 1.39 void geometry_nurbs::set ()
310     {
311     // < XXX >: Testing CODE
312     int u, v;
313     for (u = 0; u < 4; u++) {
314     for (v = 0; v < 4; v++) {
315     ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5);
316     ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5);
317    
318     if ( (u == 1 || u == 2) && (v == 1 || v == 2))
319     ctlpoints[u][v][2] = 3.0;
320     else
321     ctlpoints[u][v][2] = -3.0;
322     }
323     }
324 root 1.41 tess = gluNewTess();
325 root 1.39 // </ XXX >
326 root 1.1
327 root 1.39 glEnable(GL_AUTO_NORMAL);
328     nurb = gluNewNurbsRenderer ();
329 root 1.41 gluNurbsProperty (nurb, GLU_AUTO_LOAD_MATRIX, GL_FALSE);
330     gluNurbsProperty (nurb, GLU_DISPLAY_MODE, GLU_FILL);
331     gluNurbsProperty (nurb, GLU_NURBS_MODE, GLU_NURBS_TESSELLATOR);
332     gluNurbsProperty (nurb, GLU_SAMPLING_METHOD, GLU_OBJECT_PATH_LENGTH);
333     gluNurbsProperty (nurb, GLU_SAMPLING_TOLERANCE, 1.0);
334 root 1.39 gluNurbsCallback (nurb, GLU_ERROR, (GLvoid (*)()) nurbs_error);
335 root 1.41 gluNurbsCallback (nurb, GLU_NURBS_BEGIN, (GLvoid(*)()) tcbBegin);
336     gluNurbsCallback (nurb, GLU_NURBS_VERTEX,(GLvoid(*)()) tcbVertex);
337     gluNurbsCallback (nurb, GLU_NURBS_END, tcbEnd);
338 root 1.39 glDisable(GL_AUTO_NORMAL);
339 root 1.41
340 root 1.39 }
341 root 1.40
342 root 1.39 void geometry_nurbs::draw (view &ctx)
343     {
344     GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
345    
346     GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
347     GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
348     GLfloat mat_shininess[] = { 100.0 };
349    
350     glClearColor (0.0, 0.0, 0.0, 0.0);
351     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
352     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
353     glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
354    
355    
356     glEnable(GL_AUTO_NORMAL);
357     gluBeginSurface (nurb);
358     gluNurbsSurface (nurb, 8, knots, 8, knots, 4 * 3, 3, &ctlpoints[0][0][0], 4, 4, GL_MAP2_VERTEX_3);
359 root 1.41 gluEndSurface (nurb);
360     /*
361     glEnable(GL_AUTO_NORMAL);
362     glPushMatrix();
363     GL_LG_DEBUG;
364     =======
365 root 1.39
366 root 1.40 gluEndSurface (nurb);
367 root 1.41 >>>>>>> 1.40
368 root 1.39 glDisable(GL_AUTO_NORMAL);
369 root 1.41 glPopMatrix();
370     glFlush();
371     */
372 root 1.39 }
373 root 1.52
374     /////////////////////////////////////////////////////////////////////////////
375    
376     entity::entity (geometry *g)
377     : geometry_filter(g)
378     , p(0,0,0)
379     {
380     update ();
381     }
382    
383     entity::~entity ()
384     {
385     hide ();
386     }
387    
388 root 1.69 visibility_base *entity::new_visibility ()
389     {
390     return new entity_visibility (*this);
391     }
392    
393     void entity::clear_visibility (visibility_base *vs)
394     {
395     ((entity_visibility *)vs)->clear ();
396     }
397    
398 root 1.52 void entity::move (const vec3 &v)
399     {
400     p = p + v;
401    
402     renormalize (orig, p);
403    
404     update ();
405     }
406    
407     void entity::show ()
408     {
409     if (!o.size ())
410     world.add (this);
411     }
412    
413     void entity::hide ()
414     {
415     for (vector<octant *>::iterator i = o.end (); i-- != o.begin (); )
416     (*i)->remove (this);
417    
418     o.clear ();
419     }
420    
421     void entity::update ()
422     {
423     if (!g)
424     return;
425    
426     bbox = g->bbox;
427    
428     a.x = orig.x + (soffs)floorf (bbox.a.x + p.x);
429     a.y = orig.y + (soffs)floorf (bbox.a.y + p.y);
430     a.z = orig.z + (soffs)floorf (bbox.a.z + p.z);
431     b.x = orig.x + (soffs)ceilf (bbox.b.x + p.x);
432     b.y = orig.y + (soffs)ceilf (bbox.b.y + p.y);
433     b.z = orig.z + (soffs)ceilf (bbox.b.z + p.z);
434    
435     if (o.size ())
436     {
437     hide ();
438     show ();
439     }
440     }
441    
442     void entity::draw (view &ctx)
443     {
444 root 1.57 ctx.eorig = orig - ctx.orig;
445 root 1.52
446     glPushMatrix ();
447 root 1.57 glTranslatef (p.x + ctx.eorig.x, p.y + ctx.eorig.y, p.z + ctx.eorig.z);
448 root 1.52 g->draw (ctx);
449     glPopMatrix ();
450     }
451    
452     /////////////////////////////////////////////////////////////////////////////
453     //
454    
455     #define SIZE 33
456    
457     struct geometry_heightfield::node
458     {
459 root 1.54 vertex_t2f_n3f_v3f vd[SIZE][SIZE];
460 root 1.52 gl::vertex_buffer vb;
461 root 1.53 GLushort *ibp;
462 root 1.54 GLfloat hvar;
463 root 1.58 GLfloat x, y, z, e;
464 root 1.53
465 root 1.54 // 23
466     // 01
467     struct geometry_heightfield::node *sub[4];
468    
469 root 1.56 void update_normals ();
470     void draw (view &ctx);
471    
472 root 1.54 node ();
473 root 1.52 };
474 root 1.53
475 root 1.54 geometry_heightfield::node::node ()
476 root 1.53 {
477 root 1.54 sub[0] = sub[1] = sub[2] = sub[3] = 0;
478     //vb.set (vd);
479 root 1.53 }
480 root 1.52
481 root 1.54 static index_buffer ib;
482     static GLushort *ibp;
483     static int icnt;
484    
485     geometry_heightfield::geometry_heightfield (GLfloat sx, GLfloat sy)
486 root 1.55 : sx(sx), sy(sy)
487     , sm (max (sx, sy))
488 root 1.52 {
489 root 1.54 if (!ib)
490     {
491 root 1.58 ib.set<GLushort> (SIZE * SIZE * 6, GL_STATIC_DRAW);
492 root 1.54 ibp = (GLushort *)ib.map ();
493    
494     GLushort *p = ibp;
495    
496     for (int x = 0; x < SIZE - 1; x++)
497     for (int y = 0; y < SIZE - 1; y++)
498     {
499     unsigned short a = (y + 0) * SIZE + (x + 0);
500     unsigned short b = (y + 0) * SIZE + (x + 1);
501     unsigned short c = (y + 1) * SIZE + (x + 1);
502     unsigned short d = (y + 1) * SIZE + (x + 0);
503    
504     *p++ = c; *p++ = b; *p++ = a;
505     *p++ = d; *p++ = c; *p++ = a;
506     }
507    
508     icnt = p - ibp;
509    
510     ib.unmap ();
511     }
512    
513 root 1.52 update ();
514 root 1.54
515     tree = new node;
516     tree->hvar = 0.01F * sx;
517     tree->x = tree->y = 0.F;
518 root 1.56 tree->e = sm;
519 root 1.54
520     for (int x = 0; x < SIZE; x++)
521     for (int y = 0; y < SIZE; y++)
522     {
523     vertex_t2f_n3f_v3f &v = tree->vd[y][x];
524    
525     v.t = tex2 ((GLfloat)x / (SIZE - 1), (GLfloat)y / (SIZE - 1));
526     v.v = vec3 (sx * x / (SIZE - 1), tree->hvar * rand () / RAND_MAX, sy * y / (SIZE - 1));
527 root 1.58 v.n = vec3 (0, 1, 0);
528 root 1.54 }
529    
530 root 1.56 tree->update_normals ();
531    
532 root 1.54 tree->vb.set (&tree->vd[0][0], SIZE * SIZE);
533    
534     bbox.reset ();
535     bbox.add (vec3 (0, 0, 0));
536     bbox.add (vec3 (sx, tree->hvar, sy));
537 root 1.52 }
538    
539     void geometry_heightfield::update ()
540     {
541     geometry::update ();
542     }
543    
544 root 1.58 static int maxcnt, thiscnt;
545     static GLfloat mine;
546 root 1.57
547 root 1.52 void geometry_heightfield::draw (view &ctx)
548     {
549 root 1.62 testmat->enable (ctx);
550 root 1.57 maxcnt = 10;
551 root 1.58 thiscnt = 0;
552     mine = 1e38;
553 root 1.56 tree->draw (ctx);
554 root 1.62 testmat->disable (ctx);
555 root 1.59 //printf (" TC %d mine %f\n", thiscnt, mine);
556 root 1.56 }
557    
558     void geometry_heightfield::node::update_normals ()
559     {
560 root 1.58 GLfloat az = 0.F;
561    
562 root 1.56 for (int x = 0; x < SIZE; x++)
563     for (int y = 0; y < SIZE; y++)
564     {
565     vertex_t2f_n3f_v3f &v = vd[y][x];
566    
567     if (x && y)
568     v.n = normalize (cross (vd[y-1][x].v - v.v, vd[y][x-1].v - v.v));
569 root 1.58
570     az += v.v.y;
571 root 1.56 }
572 root 1.58
573     z = az / (SIZE * SIZE);
574 root 1.56 }
575    
576     void geometry_heightfield::node::draw (view &ctx)
577     {
578 root 1.58 vec3 center = vec3 (ctx.eorig) + vec3 (x + e * .5F, z, y + e * .5F);
579     GLfloat d = length (center);
580 root 1.57
581     if (!overlap (ctx.frustum.c, sphere (center, e * 2)))
582     return;
583    
584 root 1.58 if (d > e * 2.F)
585 root 1.55 {
586 root 1.58 if (mine > e) mine = e; thiscnt++;
587 root 1.56 vb.bind ();
588 root 1.55 ib.draw (GL_TRIANGLES, 0, icnt);
589 root 1.56 }
590     else
591     {
592     for (int i = 0; i < 4; i++)
593     {
594     if (!sub[i])
595     {
596 root 1.57 if (!--maxcnt)
597     {
598     vb.bind ();
599     ib.draw (GL_TRIANGLES, 0, icnt);
600     }
601    
602 root 1.56 node *n = sub[i] = new node;
603    
604 root 1.57 n->hvar = hvar * 0.5;
605 root 1.56 n->x = x + (i & 1 ? e * .5F : 0.F);
606     n->y = y + (i & 2 ? e * .5F : 0.F);
607     n->e = e * .5F;
608    
609     for (int x = 0; x < SIZE; x++)
610     for (int y = 0; y < SIZE; y++)
611     n->vd[y][x] = vd[(y >> 1) + (i & 2 ? SIZE / 2 : 0)][(x >> 1) + (i & 1 ? SIZE / 2 : 0)];
612    
613 root 1.58 for (int x = 1; x < SIZE; x += 2)
614     for (int y = 0; y < SIZE; y += 2)
615     {
616     n->vd[y][x].t = (n->vd[y][x-1].t + n->vd[y][x+1].t) * 0.5F;
617     n->vd[y][x].v = (n->vd[y][x-1].v + n->vd[y][x+1].v) * 0.5F;
618 root 1.60 if (y && y < SIZE - 1)
619     n->vd[y][x].v.y += n->hvar * (GLfloat)rand () / RAND_MAX - n->hvar * .5F;
620 root 1.58 }
621 root 1.57
622 root 1.58 for (int x = 0; x < SIZE; x++)
623     for (int y = 1; y < SIZE; y += 2)
624 root 1.56 {
625 root 1.58 n->vd[y][x].t = (n->vd[y-1][x].t + n->vd[y+1][x].t) * 0.5F;
626 root 1.57 n->vd[y][x].v = (n->vd[y-1][x].v + n->vd[y+1][x].v) * 0.5F;
627 root 1.60 if (x && x < SIZE - 1)
628     n->vd[y][x].v.y += n->hvar * (GLfloat)rand () / RAND_MAX - n->hvar * .5F;
629 root 1.56 }
630    
631     n->update_normals ();
632    
633     n->vb.set (&n->vd[0][0], SIZE * SIZE);
634     }
635    
636     sub[i]->draw (ctx);
637     }
638 root 1.55 }
639 root 1.52 }
640    
641 root 1.66 void
642     entity_moveable::perform_step (double t)
643     {
644     vec3 vel = t * v;
645     move (vel);
646     }
647 root 1.68
648     /////////////////////////////////////////////////////////////////////////////
649    
650     skybox::skybox (
651     const char *left,
652     const char *front,
653     const char *right,
654     const char *back,
655     const char *top,
656     const char *bottom
657     )
658     {
659     tex [0] = new texture (left , texture::CLAMP);
660     tex [1] = new texture (front , texture::CLAMP);
661     tex [2] = new texture (right , texture::CLAMP);
662     tex [3] = new texture (back , texture::CLAMP);
663     tex [4] = new texture (top , texture::CLAMP);
664     tex [5] = new texture (bottom, texture::CLAMP);
665     }
666    
667     skybox::~skybox ()
668     {
669     for (int i = 6; i--; )
670     delete tex [i];
671     }
672    
673     void
674     skybox::draw (view &ctx)
675     {
676    
677     float x = ctx.p.x;
678     float y = ctx.p.y;
679     float z = ctx.p.z;
680    
681     float width = 1000.;
682     float height = 1000.;
683     float length = 1000.;
684    
685     x -= width * .5F;
686     y -= height * .5F;
687     z -= length * .5F;
688    
689     static skybox_material sm;
690    
691     sm.enable (ctx);
692    
693     // Draw Left side
694     sm.tex->name = tex [0]->name;
695     sm.tex->enable ();
696     glBegin (GL_QUADS);
697     glTexCoord2f (1.0f, 0.0f); glVertex3f (x, y + height, z);
698     glTexCoord2f (0.0f, 0.0f); glVertex3f (x, y + height, z + length);
699     glTexCoord2f (0.0f, 1.0f); glVertex3f (x, y, z + length);
700     glTexCoord2f (1.0f, 1.0f); glVertex3f (x, y, z);
701     glEnd ();
702     sm.tex->disable ();
703    
704     // Draw Front side
705     sm.tex->name = tex [1]->name;
706     sm.tex->enable ();
707     glBegin (GL_QUADS);
708     glTexCoord2f (1.0f, 1.0f); glVertex3f (x + width, y, z);
709     glTexCoord2f (1.0f, 0.0f); glVertex3f (x + width, y + height, z);
710     glTexCoord2f (0.0f, 0.0f); glVertex3f (x, y + height, z);
711     glTexCoord2f (0.0f, 1.0f); glVertex3f (x, y, z);
712     glEnd ();
713     sm.tex->disable ();
714    
715     // Draw Right side
716     sm.tex->name = tex [2]->name;
717     sm.tex->enable ();
718     glBegin (GL_QUADS);
719     glTexCoord2f (0.0f, 1.0f); glVertex3f (x + width, y, z);
720     glTexCoord2f (1.0f, 1.0f); glVertex3f (x + width, y, z + length);
721     glTexCoord2f (1.0f, 0.0f); glVertex3f (x + width, y + height, z + length);
722     glTexCoord2f (0.0f, 0.0f); glVertex3f (x + width, y + height, z);
723     glEnd ();
724     sm.tex->disable ();
725    
726     // Draw Back side
727     sm.tex->name = tex [3]->name;
728     sm.tex->enable ();
729     glBegin (GL_QUADS);
730     glTexCoord2f (1.0f, 1.0f); glVertex3f (x, y, z + length);
731     glTexCoord2f (1.0f, 0.0f); glVertex3f (x, y + height, z + length);
732     glTexCoord2f (0.0f, 0.0f); glVertex3f (x + width, y + height, z + length);
733     glTexCoord2f (0.0f, 1.0f); glVertex3f (x + width, y, z + length);
734     glEnd ();
735     sm.tex->disable ();
736    
737     // Draw Up side
738     sm.tex->name = tex [4]->name;
739     sm.tex->enable ();
740     glBegin (GL_QUADS);
741     glTexCoord2f (1.0f, 0.0f); glVertex3f (x, y, z);
742     glTexCoord2f (0.0f, 0.0f); glVertex3f (x, y, z + length);
743     glTexCoord2f (0.0f, 1.0f); glVertex3f (x + width, y, z + length);
744     glTexCoord2f (1.0f, 1.0f); glVertex3f (x + width, y, z);
745     glEnd ();
746     sm.tex->disable ();
747    
748     // Draw Down side
749     sm.tex->name = tex [5]->name;
750     sm.tex->enable ();
751     glBegin (GL_QUADS);
752     glTexCoord2f (1.0f, 0.0f); glVertex3f (x + width, y + height, z);
753     glTexCoord2f (0.0f, 0.0f); glVertex3f (x + width, y + height, z + length);
754     glTexCoord2f (0.0f, 1.0f); glVertex3f (x, y + height, z + length);
755     glTexCoord2f (1.0f, 1.0f); glVertex3f (x, y + height, z);
756     glEnd ();
757     sm.tex->disable ();
758    
759     sm.disable (ctx);
760     }
761