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

# Content
1 #include <cassert>
2 #include <cstdlib>
3 #include <algorithm>
4
5 using namespace std;
6
7 #include "opengl.h"
8
9 #include "util.h"
10 #include "entity.h"
11 #include "oct.h"
12 #include "view.h"
13
14 /////////////////////////////////////////////////////////////////////////////
15
16 geometry::~geometry ()
17 {
18 }
19
20 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
31 geometry_opengl::geometry_opengl ()
32 {
33 list = glGenLists (1);
34 }
35
36 geometry_opengl::~geometry_opengl ()
37 {
38 glDeleteLists (list, 1);
39 }
40
41 template<GLenum type>
42 void geometry_opengl1d<type>::set (const vector<vertex_v3f> &v)
43 {
44 clear ();
45 insert (end (), v.begin (), v.end ());
46
47 bbox.reset ();
48
49 for (const_iterator i = end (); i-- != begin (); )
50 bbox.add (i->v);
51
52 update ();
53 }
54
55 template<GLenum type>
56 void geometry_opengl1d<type>::draw (view &ctx)
57 {
58 glBegin (type);
59
60 for (iterator i = begin (); i < end (); ++i)
61 glVertex3fv ((GLfloat *)&i->v);
62
63 glEnd ();
64 }
65
66 template<GLenum type>
67 void geometry_opengl2d<type>::set (const vector<vertex_t2f_n3f_v3f> &v)
68 {
69 bbox.reset ();
70
71 for (vector<vertex_t2f_n3f_v3f>::const_iterator i = v.end (); i-- != v.begin (); )
72 bbox.add (i->v);
73
74 update ();
75
76 glNewList (list, GL_COMPILE);
77
78 #if 0
79 glBegin (type);
80
81 for (vector<vertex_t2f_n3f_v3f>::const_iterator i = v.begin (); i < v.end (); ++i)
82 {
83 glTexCoord2fv ((GLfloat *)&i->t);
84 glNormal3fv ((GLfloat *)&i->n);
85 glVertex3fv ((GLfloat *)&i->v);
86 }
87
88 glEnd ();
89 #else
90 glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0);
91
92 glEnableClientState (GL_VERTEX_ARRAY);
93 glEnableClientState (GL_NORMAL_ARRAY);
94 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
95 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 glVertexPointer (3, GL_FLOAT, sizeof (vertex_t2f_n3f_v3f), (void *)&v.begin ()->v);
98
99 glDrawArrays (type, 0, v.size ());
100
101 glDisableClientState (GL_VERTEX_ARRAY);
102 glDisableClientState (GL_NORMAL_ARRAY);
103 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
104 #endif
105
106 glEndList ();
107 }
108
109 template<GLenum type>
110 void geometry_opengl2d<type>::draw (view &ctx)
111 {
112 m->enable (ctx);
113 glCallList (list);
114 m->disable (ctx);
115 }
116
117 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 int n = min (100, max (15, (int)(ctx.pixfact * radius) / 10));
129
130 m->enable (ctx);
131 GLUquadric *quad = gluNewQuadric ();
132 gluQuadricTexture (quad, true);
133 gluSphere (quad, radius, n, n);
134 gluDeleteQuadric (quad);
135 m->disable (ctx);
136 }
137
138 /////////////////////////////////////////////////////////////////////////////
139
140 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 void geometry_transform::update ()
151 {
152 const box &sub = g->bbox;
153
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
164 geometry::update ();
165 }
166
167 #if 0
168 void geometry_transform::renormalize ()
169 {
170 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 }
174 #endif
175
176 void geometry_transform::update (const matrix &xfrm)
177 {
178 m = m * xfrm;
179
180 update ();
181 }
182
183 void geometry_transform::set_matrix (const matrix &xfrm)
184 {
185 m = xfrm;
186
187 update ();
188 }
189
190 void geometry_transform::draw (view &ctx)
191 {
192 glPushMatrix ();
193 glMultMatrixf ((GLfloat *)&m);
194 g->draw (ctx);
195 glPopMatrix ();
196 }
197
198 void geometry_anim::draw (view &ctx)
199 {
200 matrix save_m = m;
201
202 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
206 geometry_transform::draw (ctx);
207
208 m = save_m;
209 }
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 ///////////////////////////////////////////////////////////////////////////
277
278 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
285 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
294 void tcbBegin (GLenum prim)
295 {
296 glBegin (prim);
297 }
298
299 void tcbVertex (void *data)
300 {
301 glVertex3fv ((GLfloat *)data);
302 }
303
304 void tcbEnd ()
305 {
306 glEnd ();
307 }
308
309 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 tess = gluNewTess();
325 // </ XXX >
326
327 glEnable(GL_AUTO_NORMAL);
328 nurb = gluNewNurbsRenderer ();
329 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 gluNurbsCallback (nurb, GLU_ERROR, (GLvoid (*)()) nurbs_error);
335 gluNurbsCallback (nurb, GLU_NURBS_BEGIN, (GLvoid(*)()) tcbBegin);
336 gluNurbsCallback (nurb, GLU_NURBS_VERTEX,(GLvoid(*)()) tcbVertex);
337 gluNurbsCallback (nurb, GLU_NURBS_END, tcbEnd);
338 glDisable(GL_AUTO_NORMAL);
339
340 }
341
342 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 gluEndSurface (nurb);
360 /*
361 glEnable(GL_AUTO_NORMAL);
362 glPushMatrix();
363 GL_LG_DEBUG;
364 =======
365
366 gluEndSurface (nurb);
367 >>>>>>> 1.40
368 glDisable(GL_AUTO_NORMAL);
369 glPopMatrix();
370 glFlush();
371 */
372 }
373
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 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 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 ctx.eorig = orig - ctx.orig;
445
446 glPushMatrix ();
447 glTranslatef (p.x + ctx.eorig.x, p.y + ctx.eorig.y, p.z + ctx.eorig.z);
448 g->draw (ctx);
449 glPopMatrix ();
450 }
451
452 /////////////////////////////////////////////////////////////////////////////
453 //
454
455 #define SIZE 33
456
457 struct geometry_heightfield::node
458 {
459 vertex_t2f_n3f_v3f vd[SIZE][SIZE];
460 gl::vertex_buffer vb;
461 GLushort *ibp;
462 GLfloat hvar;
463 GLfloat x, y, z, e;
464
465 // 23
466 // 01
467 struct geometry_heightfield::node *sub[4];
468
469 void update_normals ();
470 void draw (view &ctx);
471
472 node ();
473 };
474
475 geometry_heightfield::node::node ()
476 {
477 sub[0] = sub[1] = sub[2] = sub[3] = 0;
478 //vb.set (vd);
479 }
480
481 static index_buffer ib;
482 static GLushort *ibp;
483 static int icnt;
484
485 geometry_heightfield::geometry_heightfield (GLfloat sx, GLfloat sy)
486 : sx(sx), sy(sy)
487 , sm (max (sx, sy))
488 {
489 if (!ib)
490 {
491 ib.set<GLushort> (SIZE * SIZE * 6, GL_STATIC_DRAW);
492 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 update ();
514
515 tree = new node;
516 tree->hvar = 0.01F * sx;
517 tree->x = tree->y = 0.F;
518 tree->e = sm;
519
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 v.n = vec3 (0, 1, 0);
528 }
529
530 tree->update_normals ();
531
532 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 }
538
539 void geometry_heightfield::update ()
540 {
541 geometry::update ();
542 }
543
544 static int maxcnt, thiscnt;
545 static GLfloat mine;
546
547 void geometry_heightfield::draw (view &ctx)
548 {
549 testmat->enable (ctx);
550 maxcnt = 10;
551 thiscnt = 0;
552 mine = 1e38;
553 tree->draw (ctx);
554 testmat->disable (ctx);
555 //printf (" TC %d mine %f\n", thiscnt, mine);
556 }
557
558 void geometry_heightfield::node::update_normals ()
559 {
560 GLfloat az = 0.F;
561
562 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
570 az += v.v.y;
571 }
572
573 z = az / (SIZE * SIZE);
574 }
575
576 void geometry_heightfield::node::draw (view &ctx)
577 {
578 vec3 center = vec3 (ctx.eorig) + vec3 (x + e * .5F, z, y + e * .5F);
579 GLfloat d = length (center);
580
581 if (!overlap (ctx.frustum.c, sphere (center, e * 2)))
582 return;
583
584 if (d > e * 2.F)
585 {
586 if (mine > e) mine = e; thiscnt++;
587 vb.bind ();
588 ib.draw (GL_TRIANGLES, 0, icnt);
589 }
590 else
591 {
592 for (int i = 0; i < 4; i++)
593 {
594 if (!sub[i])
595 {
596 if (!--maxcnt)
597 {
598 vb.bind ();
599 ib.draw (GL_TRIANGLES, 0, icnt);
600 }
601
602 node *n = sub[i] = new node;
603
604 n->hvar = hvar * 0.5;
605 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 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 if (y && y < SIZE - 1)
619 n->vd[y][x].v.y += n->hvar * (GLfloat)rand () / RAND_MAX - n->hvar * .5F;
620 }
621
622 for (int x = 0; x < SIZE; x++)
623 for (int y = 1; y < SIZE; y += 2)
624 {
625 n->vd[y][x].t = (n->vd[y-1][x].t + n->vd[y+1][x].t) * 0.5F;
626 n->vd[y][x].v = (n->vd[y-1][x].v + n->vd[y+1][x].v) * 0.5F;
627 if (x && x < SIZE - 1)
628 n->vd[y][x].v.y += n->hvar * (GLfloat)rand () / RAND_MAX - n->hvar * .5F;
629 }
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 }
639 }
640
641 void
642 entity_moveable::perform_step (double t)
643 {
644 vec3 vel = t * v;
645 move (vel);
646 }
647
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