ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/entity.C
Revision: 1.54
Committed: Sat Oct 30 15:59:20 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.53: +78 -22 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 glEnableClientState (GL_VERTEX_ARRAY);
91 glEnableClientState (GL_NORMAL_ARRAY);
92 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
93 glVertexPointer (3, GL_FLOAT, sizeof (vertex_t2f_n3f_v3f), (void *)&v.begin ()->v);
94 glNormalPointer (GL_FLOAT, sizeof (vertex_t2f_n3f_v3f), (void *)&v.begin ()->n);
95 glTexCoordPointer (2, GL_FLOAT, sizeof (vertex_t2f_n3f_v3f), (void *)&v.begin ()->t);
96
97 glDrawArrays (type, 0, v.size ());
98
99 glDisableClientState (GL_VERTEX_ARRAY);
100 glDisableClientState (GL_NORMAL_ARRAY);
101 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
102 #endif
103
104 glEndList ();
105 }
106
107 template<GLenum type>
108 void geometry_opengl2d<type>::draw (view &ctx)
109 {
110 m->enable (ctx);
111 glCallList (list);
112 m->disable (ctx);
113 }
114
115 void geometry_sphere::update ()
116 {
117 bbox.reset ();
118 bbox.add (-point (radius, radius, radius));
119 bbox.add ( point (radius, radius, radius));
120
121 geometry::update ();
122 }
123
124 void geometry_sphere::draw (view &ctx)
125 {
126 int n = min (100, max (15, (int)(ctx.pixfact * radius) / 10));
127
128 GLUquadric *quad = gluNewQuadric ();
129 gluQuadricTexture (quad, true);
130 gluSphere (quad, radius, n, n);
131 gluDeleteQuadric (quad);
132 }
133
134 /////////////////////////////////////////////////////////////////////////////
135
136 void geometry_transform::update ()
137 {
138 const box &sub = g->bbox;
139
140 bbox.reset ();
141 bbox.add (m * vec3 (sub.a.x, sub.a.y, sub.a.z));
142 bbox.add (m * vec3 (sub.b.x, sub.a.y, sub.a.z));
143 bbox.add (m * vec3 (sub.a.x, sub.b.y, sub.a.z));
144 bbox.add (m * vec3 (sub.b.x, sub.b.y, sub.a.z));
145 bbox.add (m * vec3 (sub.a.x, sub.a.y, sub.b.z));
146 bbox.add (m * vec3 (sub.b.x, sub.a.y, sub.b.z));
147 bbox.add (m * vec3 (sub.a.x, sub.b.y, sub.b.z));
148 bbox.add (m * vec3 (sub.b.x, sub.b.y, sub.b.z));
149
150 geometry::update ();
151 }
152
153 #if 0
154 void geometry_transform::renormalize ()
155 {
156 point trans(m(0,3), m(1,3), m(2,3));
157 ::renormalize (e->orig, trans);
158 m(0,3) = trans.x; m(1,3) = trans.y; m(2,3) = trans.z;
159 }
160 #endif
161
162 void geometry_transform::update (const matrix &xfrm)
163 {
164 m = m * xfrm;
165
166 update ();
167 }
168
169 void geometry_transform::set_matrix (const matrix &xfrm)
170 {
171 m = xfrm;
172
173 update ();
174 }
175
176 void geometry_transform::draw (view &ctx)
177 {
178 glPushMatrix ();
179 glMultMatrixf ((GLfloat *)&m);
180 g->draw (ctx);
181 glPopMatrix ();
182 }
183
184 void geometry_anim::draw (view &ctx)
185 {
186 matrix save_m = m;
187
188 update (matrix::rotation (vx * timer.now, vec3 (1, 0, 0))
189 * matrix::rotation (vy * timer.now, vec3 (0, 1, 0))
190 * matrix::rotation (vz * timer.now, vec3 (0, 0, 1)));
191
192 geometry_transform::draw (ctx);
193
194 m = save_m;
195 }
196
197 /////////////////////////////////////////////////////////////////////////////
198
199 void geometry_filter::set (geometry *g)
200 {
201 this->g = g;
202
203 if (g)
204 g->parent = this;
205
206 update ();
207 }
208
209 void geometry_filter::update ()
210 {
211 if (g)
212 {
213 bbox = g->bbox;
214 geometry::update ();
215 }
216 }
217
218 void geometry_filter::draw (view &ctx)
219 {
220 g->draw (ctx);
221 }
222
223 geometry_filter::~geometry_filter ()
224 {
225 delete g;
226 }
227
228 /////////////////////////////////////////////////////////////////////////////
229
230 void geometry_container::update ()
231 {
232 bbox.reset ();
233
234 for (iterator i = end (); i-- != begin (); )
235 bbox.add ((*i)->bbox);
236
237 geometry::update ();
238 }
239
240 void geometry_container::add (geometry *g)
241 {
242 push_back (g);
243 g->parent = this;
244
245 update ();
246 }
247
248 void geometry_container::draw (view &ctx)
249 {
250 for (iterator i = end (); i-- != begin (); )
251 (*i)->draw (ctx);
252 }
253
254 geometry_container::~geometry_container ()
255 {
256 for (iterator i = end (); i-- != begin (); )
257 delete *i;
258
259 clear ();
260 }
261
262 ///////////////////////////////////////////////////////////////////////////
263
264 static void nurbs_error (GLenum errorCode)
265 {
266 const GLubyte *estring;
267 estring = gluErrorString(errorCode);
268 fprintf (stderr, "Nurbs error: %s\n", estring);
269 }
270
271 void errorCallback(GLenum errorCode)
272 {
273 const GLubyte *estring;
274
275 estring = gluErrorString(errorCode);
276 fprintf (stderr, "Tessellation Error: %s\n", estring);
277 exit (0);
278 }
279
280 void tcbBegin (GLenum prim)
281 {
282 glBegin (prim);
283 }
284
285 void tcbVertex (void *data)
286 {
287 glVertex3fv ((GLfloat *)data);
288 }
289
290 void tcbEnd ()
291 {
292 glEnd ();
293 }
294
295 void geometry_nurbs::set ()
296 {
297 // < XXX >: Testing CODE
298 int u, v;
299 for (u = 0; u < 4; u++) {
300 for (v = 0; v < 4; v++) {
301 ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5);
302 ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5);
303
304 if ( (u == 1 || u == 2) && (v == 1 || v == 2))
305 ctlpoints[u][v][2] = 3.0;
306 else
307 ctlpoints[u][v][2] = -3.0;
308 }
309 }
310 tess = gluNewTess();
311 // </ XXX >
312
313 glEnable(GL_AUTO_NORMAL);
314 nurb = gluNewNurbsRenderer ();
315 gluNurbsProperty (nurb, GLU_AUTO_LOAD_MATRIX, GL_FALSE);
316 gluNurbsProperty (nurb, GLU_DISPLAY_MODE, GLU_FILL);
317 gluNurbsProperty (nurb, GLU_NURBS_MODE, GLU_NURBS_TESSELLATOR);
318 gluNurbsProperty (nurb, GLU_SAMPLING_METHOD, GLU_OBJECT_PATH_LENGTH);
319 gluNurbsProperty (nurb, GLU_SAMPLING_TOLERANCE, 1.0);
320 gluNurbsCallback (nurb, GLU_ERROR, (GLvoid (*)()) nurbs_error);
321 gluNurbsCallback (nurb, GLU_NURBS_BEGIN, (GLvoid(*)()) tcbBegin);
322 gluNurbsCallback (nurb, GLU_NURBS_VERTEX,(GLvoid(*)()) tcbVertex);
323 gluNurbsCallback (nurb, GLU_NURBS_END, tcbEnd);
324 glDisable(GL_AUTO_NORMAL);
325
326 }
327
328 void geometry_nurbs::draw (view &ctx)
329 {
330 GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
331
332 GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
333 GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
334 GLfloat mat_shininess[] = { 100.0 };
335
336 glClearColor (0.0, 0.0, 0.0, 0.0);
337 glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
338 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
339 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
340
341
342 glEnable(GL_AUTO_NORMAL);
343 gluBeginSurface (nurb);
344 gluNurbsSurface (nurb, 8, knots, 8, knots, 4 * 3, 3, &ctlpoints[0][0][0], 4, 4, GL_MAP2_VERTEX_3);
345 gluEndSurface (nurb);
346 /*
347 glEnable(GL_AUTO_NORMAL);
348 glPushMatrix();
349 GL_LG_DEBUG;
350 =======
351
352 gluEndSurface (nurb);
353 >>>>>>> 1.40
354 glDisable(GL_AUTO_NORMAL);
355 glPopMatrix();
356 glFlush();
357 */
358 }
359
360 /////////////////////////////////////////////////////////////////////////////
361
362 entity::entity (geometry *g)
363 : geometry_filter(g)
364 , p(0,0,0)
365 {
366 update ();
367 }
368
369 entity::~entity ()
370 {
371 hide ();
372 }
373
374 void entity::move (const vec3 &v)
375 {
376 p = p + v;
377
378 renormalize (orig, p);
379
380 update ();
381 }
382
383 void entity::show ()
384 {
385 if (!o.size ())
386 world.add (this);
387 }
388
389 void entity::hide ()
390 {
391 for (vector<octant *>::iterator i = o.end (); i-- != o.begin (); )
392 (*i)->remove (this);
393
394 o.clear ();
395 }
396
397 void entity::update ()
398 {
399 if (!g)
400 return;
401
402 bbox = g->bbox;
403
404 a.x = orig.x + (soffs)floorf (bbox.a.x + p.x);
405 a.y = orig.y + (soffs)floorf (bbox.a.y + p.y);
406 a.z = orig.z + (soffs)floorf (bbox.a.z + p.z);
407 b.x = orig.x + (soffs)ceilf (bbox.b.x + p.x);
408 b.y = orig.y + (soffs)ceilf (bbox.b.y + p.y);
409 b.z = orig.z + (soffs)ceilf (bbox.b.z + p.z);
410
411 if (o.size ())
412 {
413 hide ();
414 show ();
415 }
416 }
417
418 void entity::draw (view &ctx)
419 {
420 sector diff = orig - ctx.orig;
421
422 glPushMatrix ();
423 glTranslatef (diff.x + p.x, diff.y + p.y, diff.z + p.z);
424 g->draw (ctx);
425 glPopMatrix ();
426 }
427
428 /////////////////////////////////////////////////////////////////////////////
429 //
430
431 #define SIZE 33
432
433 struct geometry_heightfield::node
434 {
435 vertex_t2f_n3f_v3f vd[SIZE][SIZE];
436 gl::vertex_buffer vb;
437 GLushort *ibp;
438 GLfloat hvar;
439 GLfloat x, y, e;
440
441 // 23
442 // 01
443 struct geometry_heightfield::node *sub[4];
444
445 node ();
446 };
447
448 geometry_heightfield::node::node ()
449 {
450 sub[0] = sub[1] = sub[2] = sub[3] = 0;
451 //vb.set (vd);
452 }
453
454 static index_buffer ib;
455 static GLushort *ibp;
456 static int icnt;
457
458 geometry_heightfield::geometry_heightfield (GLfloat sx, GLfloat sy)
459 {
460 if (!ib)
461 {
462 ib.set<GLushort> (SIZE * SIZE * 6, GL_DYNAMIC_DRAW);
463 ibp = (GLushort *)ib.map ();
464
465 GLushort *p = ibp;
466
467 for (int x = 0; x < SIZE - 1; x++)
468 for (int y = 0; y < SIZE - 1; y++)
469 {
470 unsigned short a = (y + 0) * SIZE + (x + 0);
471 unsigned short b = (y + 0) * SIZE + (x + 1);
472 unsigned short c = (y + 1) * SIZE + (x + 1);
473 unsigned short d = (y + 1) * SIZE + (x + 0);
474
475 *p++ = c; *p++ = b; *p++ = a;
476 *p++ = d; *p++ = c; *p++ = a;
477 }
478
479 icnt = p - ibp;
480
481 ib.unmap ();
482 }
483
484 update ();
485
486 tree = new node;
487 tree->hvar = 0.01F * sx;
488 tree->x = tree->y = 0.F;
489 tree->e = 1.F;
490
491 for (int x = 0; x < SIZE; x++)
492 for (int y = 0; y < SIZE; y++)
493 {
494 vertex_t2f_n3f_v3f &v = tree->vd[y][x];
495
496 v.t = tex2 ((GLfloat)x / (SIZE - 1), (GLfloat)y / (SIZE - 1));
497 v.v = vec3 (sx * x / (SIZE - 1), tree->hvar * rand () / RAND_MAX, sy * y / (SIZE - 1));
498
499 if (x && y)
500 v.n = normalize (cross (tree->vd[y-1][x].v - v.v, tree->vd[y][x-1].v - v.v));
501 else
502 v.n = vec3 (0, 1, 0);
503 }
504
505 tree->vb.set (&tree->vd[0][0], SIZE * SIZE);
506
507 bbox.reset ();
508 bbox.add (vec3 (0, 0, 0));
509 bbox.add (vec3 (sx, tree->hvar, sy));
510 }
511
512 void geometry_heightfield::update ()
513 {
514 geometry::update ();
515 }
516
517 void geometry_heightfield::draw (view &ctx)
518 {
519 tree->vb.bind ();
520 ib.draw (GL_TRIANGLES, 0, icnt);
521 }
522