1 /*
2 * Copyright (C) 1998, 2000-2007, 2010, 2011, 2012, 2013 SINTEF ICT,
3 * Applied Mathematics, Norway.
4 *
5 * Contact information: E-mail: tor.dokken@sintef.no
6 * SINTEF ICT, Department of Applied Mathematics,
7 * P.O. Box 124 Blindern,
8 * 0314 Oslo, Norway.
9 *
10 * This file is part of SISL.
11 *
12 * SISL is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Affero General Public License as
14 * published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * SISL is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Affero General Public License for more details.
21 *
22 * You should have received a copy of the GNU Affero General Public
23 * License along with SISL. If not, see
24 * <http://www.gnu.org/licenses/>.
25 *
26 * In accordance with Section 7(b) of the GNU Affero General Public
27 * License, a covered work must retain the producer line in every data
28 * file that is created or manipulated using SISL.
29 *
30 * Other Usage
31 * You can be released from the requirements of the license by purchasing
32 * a commercial license. Buying such a license is mandatory as soon as you
33 * develop commercial activities involving the SISL library without
34 * disclosing the source code of your own applications.
35 *
36 * This file may be used in accordance with the terms contained in a
37 * written agreement between you and SINTEF ICT.
38 */
39
40 #include <math.h>
41 #include <stdlib.h>
42 #include <cstring>
43
44 #include "aux2.h"
45 #include "gl_aux.h"
46
47
48
49 #ifndef PI
50 # define PI 3.1415926536 // Where should it *really* be defined?
51 #endif
52
53
54 const int predefined_colours=24;
55 const double predef_col_table[3*predefined_colours]
56 ={1.0, 0.0, 0.0,
57 0.0, 1.0, 0.0,
58 0.0, 0.0, 1.0,
59 1.0, 1.0, 0.0,
60 0.0, 1.0, 1.0,
61 1.0, 0.0, 1.0,
62 0.7, 0.0, 0.0,
63 0.0, 0.7, 0.0,
64 0.0, 0.0, 0.7,
65 0.7, 0.7, 0.0,
66 0.0, 0.7, 0.7,
67 0.7, 0.0, 0.7,
68 0.3, 0.8, 0.8,
69 0.8, 0.3, 0.8,
70 0.8, 0.8, 0.3,
71 0.3, 0.3, 0.8,
72 0.8, 0.3, 0.3,
73 0.3, 0.8, 0.3,
74 0.5, 0.8, 0.8,
75 0.8, 0.5, 0.8,
76 0.8, 0.8, 0.5,
77 0.5, 0.5, 0.8,
78 0.8, 0.5, 0.5,
79 0.5, 0.8, 0.5};
80
81
82
83
84
85 //----------------------------------------------------------------------
86 //
87 // Drawing a cylinder, or possibly a cone.
88 //
89 //----------------------------------------------------------------------
90
draw_cylinder(double x0,double y0,double z0,double x1,double y1,double z1,double radius,double radius2,int n)91 void draw_cylinder(double x0, double y0, double z0,
92 double x1, double y1, double z1,
93 double radius, double radius2, int n)
94 {
95 int i;
96 double y, z, r;
97
98 glPushMatrix();
99 glTranslatef(x0, y0, z0);
100 /*
101 Now, we have to move P=(x1-x0, y1-y0, z1-z0) to (r, 0, 0) where
102 r=length(x1-x0, y1-y0, z1-z0). First, rotate P to Q in the xy-plane:
103 */
104 /* Hvorfor blir det ikke riktig med neg. rotasjon her? */
105 glRotatef(atan2(x1-x0, z1-z0)/PI*180.0-90.0,
106 0.0, 1.0, 0.0);
107 /* printf("%f %f %f\t",
108 x1-x0,
109 z1-z0,
110 atan2(x1-x0, z1-z0)/PI*180.0);*/
111 /*
112 Now, we have to move Q=(sqrt((x1-x0)^2+(z1-z0)^2), y1-y0, 0) to
113 (r, 0, 0).
114 */
115 r=sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0)+(z1-z0)*(z1-z0));
116 /* Hvorfor blir det ikke riktig med neg. rotasjon her? */
117 glRotatef(atan2(y1-y0, sqrt((x1-x0)*(x1-x0)+(z1-z0)*(z1-z0)))/PI*180.0,
118 0.0, 0.0, 1.0);
119 /* printf("%f %f %f\n",
120 y1-y0,
121 sqrt((x1-x0)*(x1-x0)+(z1-z0)*(z1-z0)),
122 atan2(y1-y0, sqrt((x1-x0)*(x1-x0)+(z1-z0)*(z1-z0)))/PI*180.0);*/
123 /*
124 The next step is to draw the cylinder. Or cone. Normals not perfect for
125 the cone. Impossible at pointy end with tri-fan?
126 */
127 if (radius==radius2)
128 {
129 glBegin(GL_QUAD_STRIP);
130 for (i=0; i<=n; i++)
131 {
132 y=radius*cos((2.0*PI*i)/n);
133 z=radius*sin((2.0*PI*i)/n);
134 glNormal3f(0.0, y, z);
135 glVertex3f(0.0, y, z);
136 glNormal3f(0.0, y, z);
137 glVertex3f( r, y, z);
138 }
139 glEnd();
140 }
141 else
142 {
143 glBegin(GL_TRIANGLE_FAN);
144 glNormal3f(1.0, 0.0, 0.0);
145 glVertex3f(r, 0.0, 0.0);
146 for (i=0; i<=n; i++)
147 {
148 y=radius*cos((2.0*PI*i)/n);
149 z=radius*sin((2.0*PI*i)/n);
150 glNormal3f(0.0, y, z);
151 glVertex3f(0.0, y, z);
152 }
153 glEnd();
154 }
155 /*
156 Finally, we restore the transformation stack.
157 */
158 glPopMatrix();
159 }
160
161
162
163
164
165
166 //----------------------------------------------------------------------
167 //
168 // Drawing a set of axes.
169 //
170 // 021203: Actually, this is newer. Fix!!!!
171 //
172 //----------------------------------------------------------------------
173
draw_gl_axes_old(int n,double r,double radius,double rim,double l)174 void draw_gl_axes_old(int n, double r, double radius, double rim, double l)
175 {
176 // int n=10;
177 // double r=0.7;
178 // double radius=0.01, rim=0.04, l=0.1;
179
180 const double vertex_red=1.0, vertex_green=1.0, vertex_blue=1.0;
181
182 glColor3f(vertex_red, vertex_green, vertex_blue);
183
184 draw_cylinder(0.0, 0.0, -r, 0.0, 0.0, r, radius, radius, n);
185 draw_cylinder(0.0, 0.0, r-0.1, 0.0, 0.0, r+0.3, rim, 0.0, n);
186 draw_cylinder(-0.5*l, l, r+0.3, 0.5*l, l, r+0.3,
187 radius, radius, n);
188 draw_cylinder(-0.5*l, l*2.0, r+0.3, 0.5*l, l*2.0, r+0.3,
189 radius, radius, n);
190 draw_cylinder(-0.5*l, l, r+0.3, 0.5*l, l*2.0, r+0.3,
191 radius, radius, n);
192
193 draw_cylinder(-r, 0.0, 0.0, r, 0.0, 0.0, radius, radius, n);
194 draw_cylinder(r-0.1, 0.0, 0.0, r+0.3, 0.0, 0.0, rim, 0.0, n);
195 draw_cylinder(r+0.3, l, 0.5*l, r+0.3, 2*l, -0.5*l,
196 radius, radius, n);
197 draw_cylinder(r+0.3, l, -0.5*l, r+0.3, 2*l, 0.5*l,
198 radius, radius, n);
199
200 draw_cylinder(0.0, -r, 0.0, 0.0, r, 0.0, radius, radius, n);
201 draw_cylinder(0.0, r-0.1, 0.0, 0.0, r+0.3, 0.0, rim, 0.0, n);
202 draw_cylinder(0.0, r+0.3, 2.0*l, 0.0, r+0.3, 1.5*l,
203 radius, radius, n);
204 draw_cylinder(0.0, r+0.3, 1.5*l, -0.5*l, r+0.3, l,
205 radius, radius, n);
206 draw_cylinder(0.0, r+0.3, 1.5*l, 0.5*l, r+0.3, l,
207 radius, radius, n);
208
209 glColor3f(1.0, 1.0, 1.0);
210 }
211
212
213
214
215
216
217 //----------------------------------------------------------------------
218 //
219 // Draw gridlines to visualize cells.
220 //
221 //----------------------------------------------------------------------
222
draw_grid(const int n1,const int n2,const int n3)223 void draw_grid(const int n1, const int n2, const int n3)
224 {
225 int i, j, k;
226
227 glBegin(GL_LINES);
228 for (i=0; i<n1; i++)
229 for (j=0; j<n2; j++)
230 {
231 const double x=2.0*(i/(n1-1.0)-0.5);
232 const double y=2.0*(j/(n2-1.0)-0.5);
233
234 glColor3f( 1.0, 0.0, 0.0);
235 glVertex3f( x, y, -1.0);
236 glColor3f( 1.0, 0.0, 0.0);
237 glVertex3f( x, y, 1.0);
238 }
239 for (j=0; j<n2; j++)
240 for (k=0; k<n3; k++)
241 {
242 const double y=2.0*(j/(n2-1.0)-0.5);
243 const double z=2.0*(k/(n3-1.0)-0.5);
244
245 glColor3f( 0.0, 1.0, 0.0);
246 glVertex3f(-1.0, y, z);
247 glColor3f( 0.0, 1.0, 0.0);
248 glVertex3f( 1.0, y, z);
249 }
250 for (k=0; k<n3; k++)
251 for (i=0; i<n1; i++)
252 {
253 const double z=2.0*(k/(n3-1.0)-0.5);
254 const double x=2.0*(i/(n1-1.0)-0.5);
255
256 glColor3f( 0.0, 0.0, 1.0);
257 glVertex3f( x, -1.0, z);
258 glColor3f( 0.0, 0.0, 1.0);
259 glVertex3f( x, 1.0, z);
260 }
261 glEnd();
262 }
263
264
265
266
267
268
269 //
270 // 020505: Adding transparent planes.
271 //
272
draw_grid_planes(const int n1,const int n2,const int n3)273 void draw_grid_planes(const int n1, const int n2, const int n3)
274 {
275 int i, j, k;
276
277 glDisable(GL_LIGHTING); // must be turned on by the caller...
278
279 glBlendFunc(GL_ONE, GL_ONE);
280 glEnable(GL_BLEND);
281 glDisable(GL_DEPTH_TEST);
282 glBegin(GL_QUADS);
283 for (k=0; k<n3; k++)
284 {
285 const double z=2.0*(k/(n3-1.0)-0.5);
286
287 glColor3f( 0.0, 0.0, 0.2);
288 glVertex3f(-1.0, -1.0, z);
289 glVertex3f( 1.0, -1.0, z);
290 glVertex3f( 1.0, 1.0, z);
291 glVertex3f(-1.0, 1.0, z);
292 }
293 for (j=0; j<n2; j++)
294 {
295 const double y=2.0*(j/(n2-1.0)-0.5);
296
297 glColor3f( 0.0, 0.2, 0.0);
298 glVertex3f(-1.0, y, -1.0);
299 glVertex3f( 1.0, y, -1.0);
300 glVertex3f( 1.0, y, 1.0);
301 glVertex3f(-1.0, y, 1.0);
302 }
303 for (i=0; i<n1; i++)
304 {
305 const double x=2.0*(i/(n1-1.0)-0.5);
306
307 glColor3f( 0.2, 0.0, 0.0);
308 glVertex3f( x, -1.0, -1.0);
309 glVertex3f( x, 1.0, -1.0);
310 glVertex3f( x, 1.0, 1.0);
311 glVertex3f( x, -1.0, 1.0);
312 }
313 glEnd();
314 glEnable(GL_DEPTH_TEST);
315 glDisable(GL_BLEND);
316 }
317
318
319
320
321
322
323 //----------------------------------------------------------------------
324 //
325 // Initializing glut and gl.
326 //
327 //----------------------------------------------------------------------
328
gl_init(int argc,char * argv[],const int xs,const int ys,const int x0,const int y0,const int doubleBuffer,const int two_sided,const int lighting,const int normalize,const int smooth,const double xtrans,const double ytrans,const double ztrans,const double xscale,const double yscale,const double zscale,int & tx,int & ty,const int texture_mode,const char * const texfile)329 void gl_init(int argc, char *argv[],
330 const int xs, const int ys,
331 const int x0, const int y0,
332 const int doubleBuffer,
333 const int two_sided,
334 const int lighting,
335 const int normalize,
336 const int smooth,
337 const double xtrans,
338 const double ytrans,
339 const double ztrans,
340 const double xscale,
341 const double yscale,
342 const double zscale,
343 int &tx,
344 int &ty,
345 const int texture_mode,
346 const char * const texfile /* =NULL */)
347 {
348 int i;
349 const int use_accum=0;
350
351 //
352 // 020430: NB! Note that the really confusing name 'GLUT_RGBA' hides the
353 // fact that this setting does not induce an alpha buffer being set
354 // up! One must in fact specify GLUT_ALPHA explicitly!
355 // (But I'm not sure how important this is... Perhaps this alpha is
356 // not actually needed for the *window* for OpenGL for instance to
357 // be able to do alpha blending?!)
358 // 020501: Seems that we get accum buffer even without specifying it?!
359 // 020502: GLUT_ALPHA seems not to be available on smaug.
360 // But we don't actually need it for alpha-blending, anyway. For
361 // that we only need alpha for the textures.
362 // Ok, it's there when we go to 24 bpp mode in X.
363 //
364 #ifndef QTMODE
365 glutInitDisplayMode(GLUT_RGBA | // GLUT_ALPHA |
366 (use_accum ? GLUT_ACCUM : 0) |
367 ((doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE) |
368 GLUT_DEPTH);
369 glutInitWindowSize(xs, ys);
370 glutInitWindowPosition(x0, y0);
371 glutInit(&argc, argv);
372 glutCreateWindow(argv[0]);
373 #endif
374
375 glClearColor(0.0, 0.0, 0.0, 0.0);
376 if (use_accum)
377 glClearAccum(0.0, 0.0, 0.0, 0.0);
378 if (smooth)
379 glShadeModel(GL_SMOOTH);
380 else
381 glShadeModel(GL_FLAT);
382 glEnable(GL_DEPTH_TEST);
383 glDepthFunc(GL_LESS); /* GL_LESS is default. */
384 /* glDepthRange(100.0, -100.0);*/ /* What is default value? */
385 /* glClearDepth(0.0); */ /* What is default value? */
386
387 /* Initialize materials */
388
389 {
390 static float ambient[] = {0.1, 0.1, 0.1, 1.0};
391 static float diffuse[] = {0.4, 0.4, 0.4, 1.0};
392
393 static float position0[] = { 5.0, 5.0, 200.0, 0.0};
394 static float position1[] = {-5.0, -5.0, 200.0, 0.0};
395
396 static float front_mat_shininess[] = {50.0};
397 // static float front_mat_specular[] = {0.9, 0.9, 0.9, 1.0};
398 static float front_mat_specular[] = {0.0, 0.0, 0.0, 1.0};
399 static float front_mat_diffuse[] = {0.7, 0.7, 0.7, 1.0};
400 // static float front_mat_diffuse[] = {0, 0, 0, 1.0};
401 static float front_mat_ambient[] = {0.3, 0.3, 0.3, 1.0};
402 static float front_mat_emission[] = {0.3, 0.0, 0.0, 1.0};
403
404 static float back_mat_shininess[] = {128.0};
405 // static float back_mat_specular[] = {0.4, 0.4, 0.4, 1.0};
406 static float back_mat_specular[] = {0.0, 0.0, 0.0, 1.0};
407 static float back_mat_diffuse[] = {0.7, 0.7, 0.7, 1.0};
408 static float back_mat_ambient[] = {0.3, 0.3, 0.3, 1.0};
409 static float back_mat_emission[] = {0.0, 0.3, 0.0, 1.0};
410
411 static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
412 static float lmodel_twoside[] = {GL_TRUE};
413
414 if (two_sided)
415 lmodel_twoside[0]=GL_TRUE;
416 else
417 lmodel_twoside[0]=GL_FALSE;
418
419 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
420 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
421 glLightfv(GL_LIGHT0, GL_POSITION, position0);
422
423 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
424 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
425 glLightfv(GL_LIGHT1, GL_POSITION, position1);
426
427 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
428 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
429
430 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
431
432 glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess);
433 glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
434 glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
435 glMaterialfv(GL_FRONT, GL_AMBIENT, front_mat_ambient);
436 glMaterialfv(GL_FRONT, GL_EMISSION, front_mat_emission);
437
438 glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess);
439 glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
440 glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
441 glMaterialfv(GL_BACK, GL_AMBIENT, back_mat_ambient);
442 glMaterialfv(GL_BACK, GL_EMISSION, back_mat_emission);
443
444 glEnable(GL_LIGHT0);
445 glEnable(GL_LIGHT1);
446 if (lighting)
447 glEnable(GL_LIGHTING);
448 else
449 glDisable(GL_LIGHTING);
450 if (normalize)
451 glEnable(GL_NORMALIZE);
452 else
453 glDisable(GL_NORMALIZE);
454 }
455
456 glMatrixMode(GL_PROJECTION);
457 glLoadIdentity();
458 /* glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 ); */
459 /* glFrustum( -1.0, 1.0, -1.0, 1.0, 2, 4 ); */
460 /* glFrustum( -1.0, 1.0, -1.0, 1.0, 100, 102 ); */
461 /* glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 7 );*/
462 /*
463 Note that the far clipping plane distance doesn't influence on
464 the projection, but that the distance between near and far should be
465 as close to one as possible to best utilise the z-buffer. Or something
466 like this...
467 */
468 //
469 // 000304: Was near=5, near clipping plane to far from viewer.
470 // 6-0.5*sqrt(3) should make a 1x1x1 cube never intersect the near
471 // plane regardless of rotation... Making it even closer will
472 // make it possible to expand things more before being clipped...
473 //
474 //glFrustum(-1.0, 1.0, -1.0, 1.0, 6-0.5*sqrt(3), 20);
475
476 //
477 // 020214: This one seems to be rather good, we can zoom in quite a lot
478 // without stuff hitting the near clipping plane.
479 //
480 glFrustum(-1.0, 1.0, -1.0, 1.0, 3, 20); // cmt out 020201
481
482 // 020410 experimenting
483 glLoadIdentity();
484 glFrustum(-1.0, 1.0, -1.0, 1.0, 3, 20);
485
486 //
487 // 020214: The next one let's us see inside more easily, because the near
488 // clipping plane is further away from us.
489 //
490 //glFrustum(-1.0, 1.0, -1.0, 1.0, 5, 20);
491
492 //
493 // 021206: Trying to get the near clipping plane closer to us.
494 // I've lost track of the actual numbers here...
495 // Should be dealt with...
496 //
497 glLoadIdentity();
498 glFrustum(-1.0, 1.0, -1.0, 1.0, 2.0, 20);
499
500 //
501 // 020627: Trying to reduce the "perspective" effect.
502 //
503 //glFrustum(-1.0, 1.0, -1.0, 1.0, 5+100, 20+100);
504
505 glMatrixMode(GL_MODELVIEW);
506 glLoadIdentity();
507 /* glTranslated( 0.0, 0.0, -6.0 ); */
508 /* glTranslated( 0.0, 0.0, -3.0 ); */
509 /* glTranslated( 0.0, 0.0, -101.0 ); */
510 glTranslated(xtrans, ytrans, ztrans);
511 glScaled(xscale, yscale, zscale);
512
513 /*
514 Why did I do this? To clear both buffers? Is this necessary here?
515 */
516 for (i=0; i<2; i++)
517 {
518 glDrawBuffer(GL_BACK);
519 glReadBuffer(GL_BACK);
520 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
521 glClear(GL_COLOR_BUFFER_BIT | (use_accum ? GL_ACCUM_BUFFER_BIT : 0));
522 #ifndef QTMODE
523 glutSwapBuffers();
524 #endif
525 }
526
527 //
528 // Note that after the texture has been inserted into the GL engine, it
529 // is lost/deallocated from the application.
530 // (But (for some reason) the size is returned...)
531 //
532 unsigned char *texture=NULL;
533 if (texfile==NULL)
534 {
535 if (tx!=ty)
536 CRIT_ERR(printf("tx=%d, ty=%d, not implemented.\n", tx, ty));
537
538 if ((texture=new unsigned char[3*SQR(tx)])==NULL)
539 CRIT_ERR(puts("Couldn't allocate space for texture."));
540
541 int i;
542 const unsigned char a=255, b=0;
543
544 for (i=0; i<3*SQR(tx); i++)
545 texture[i]=a;
546 for (i=0; i<tx; i++)
547 {
548 texture[3*(i*tx+0)+0]=b;
549 texture[3*(i*tx+0)+1]=b;
550 texture[3*(i*tx+0)+2]=b;
551 texture[3*(i*tx+(tx-1))+0]=b;
552 texture[3*(i*tx+(tx-1))+1]=b;
553 texture[3*(i*tx+(tx-1))+2]=b;
554 texture[3*(0*tx+i)+0]=b;
555 texture[3*(0*tx+i)+1]=b;
556 texture[3*(0*tx+i)+2]=b;
557 texture[3*((tx-1)*tx+i)+0]=b;
558 texture[3*((tx-1)*tx+i)+1]=b;
559 texture[3*((tx-1)*tx+i)+2]=b;
560 }
561 }
562 else
563 //
564 // Read texture from file...
565 //
566 {
567 puts("texture code not compiled in!");
568 exit(0);
569 #if 0
570 unsigned char *texture_tmp=read_ppm_file(texfile, &tx, &ty);
571 puts("Leste pgm-fil.");
572 if (tx!=ty)
573 CRIT_ERR(puts("Not implemented."));
574 if ((tx!=1) && (tx!=2) && (tx!=4) && (tx!=8) && (tx!=16) && (tx!=32) &&
575 (tx!=64) && (tx!=128) && (tx!=256) && (tx!=512) && (tx!=1024) &&
576 (tx!=2048) && (tx!=4096))
577 CRIT_ERR(puts("Texture size not ok."));
578
579 printf("Texture size is %dx%d.\n", tx, ty);
580
581 if ((texture=new unsigned char[3*SQR(tx)])==NULL)
582 CRIT_ERR(puts("Couldn't allocate space for texture."));
583
584 int i;
585
586 for (i=0; i<SQR(tx); i++)
587 {
588 texture[3*i+0]=texture_tmp[i];
589 texture[3*i+1]=texture_tmp[i];
590 texture[3*i+2]=texture_tmp[i];
591 // printf("%5d - %3d %3d %3d\n", i,
592 // texture[i+0], texture[i+1], texture[i+2]);
593 }
594
595 delete texture_tmp;
596 #endif
597 }
598
599 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tx, ty,
600 0, GL_RGB, GL_UNSIGNED_BYTE, texture);
601 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texture_mode);
602 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
603 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
604 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
605 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
606
607 delete texture;
608
609 //glPolygonOffset(0.0, 20.0);
610 //
611 // 020430: PolygonOffset(factor, units) produces an offset o, where
612 // o = max depth slope * factor + impl. dep. const. r * units.
613 // 0.0, 20.0 worked just perfect for GeForce 2 and Matrox Mystique,
614 // but not for GeForce 3.
615 // Perhaps it was strange that it worked? Or maybe it enough now
616 // just use a factor slightly greater than 0.0?
617 // A good idea would perhaps be to make a tool to adjust these
618 // empirically during runtime?!
619 // Seems that it is not enough to just increase factor slightly,
620 // perhaps the GF3 has another definition for 'units'? Increasing
621 // it somewhat seems to make the problem go away...
622 // Don't want to increase it too much though.
623 // Perhaps a way to do this: Increase the 'factor' until very
624 // slanted surfaces turns out ok, and increase 'units' until
625 // flat (parallel to near plane) surfaces are ok?! Will do it
626 // like this but opposite order.
627 // Hmm!!! (1.0, 1.0) seems to be just fine!
628 //
629 glPolygonOffset(1.0, 1.0);
630 glEnable(GL_POLYGON_OFFSET_POINT);
631 glEnable(GL_POLYGON_OFFSET_LINE);
632 glEnable(GL_POLYGON_OFFSET_FILL);
633
634 }
635
636
637
638
639
640
transpose_matrix(double * const d)641 void transpose_matrix(double * const d)
642 {
643 int i, j;
644
645 for (i=0; i<4; i++)
646 for (j=0; j<i; j++)
647 {
648 double tmp=d[i*4+j];
649 d[i*4+j]=d[j*4+i];
650 d[j*4+i]=tmp;
651 }
652 }
653
654
655
656
657
658
print_gl_matrix(const int m)659 void print_gl_matrix(const int m)
660 {
661 int i;
662 double p[16], p2[16];
663
664 switch (m)
665 {
666 case GL_PROJECTION_MATRIX:
667
668 case GL_MODELVIEW_MATRIX:
669 glGetDoublev((GLenum)m, p);
670 break;
671
672 #if 0
673 case GL_MODELVIEW_MATRIX + GL_PROJECTION_MATRIX:
674 glMatrixMode(GL_MODELVIEW);
675 glPushMatrix();
676 glGetDoublev(GL_PROJECTION_MATRIX, p);
677 glMultMatrixd(p);
678 glGetDoublev(GL_MODELVIEW_MATRIX, p);
679 glPopMatrix();
680 break;
681 #endif
682
683 case GL_MODELVIEW_MATRIX + GL_PROJECTION_MATRIX:
684 glMatrixMode(GL_MODELVIEW);
685 glGetDoublev(GL_MODELVIEW_MATRIX, p2);
686 glPushMatrix();
687 glLoadIdentity();
688 glGetDoublev(GL_PROJECTION_MATRIX, p);
689 glMultMatrixd(p);
690 glMultMatrixd(p2);
691 glGetDoublev(GL_MODELVIEW_MATRIX, p);
692 glPopMatrix();
693 break;
694 }
695
696 //
697 // 000320: BUG was here! GL uses column-order...
698 //
699 transpose_matrix(p);
700
701 printf("{");
702 for (i=0; i<15; )
703 {
704 printf("%g, ", p[i]);
705 i++;
706 if (i%4==0)
707 printf("\n");
708 }
709 printf("%g}\n\n", p[15]);
710
711 printf("For Mathematica:\n\n");
712 printf("{");
713 for (i=0; i<15; )
714 {
715 if (i%4==0)
716 printf("{");
717 printf("%f", p[i]);
718 i++;
719 if (i%4==0)
720 printf("}, ");
721 else
722 printf(", ");
723 }
724 printf("%f}}\n\n", p[15]);
725
726
727 }
728
729
730
731
732
733
734
735 //----------------------------------------------------------------------
736 //
737 // This callback is called when the window is reshaped.
738 //
739 //----------------------------------------------------------------------
740
reshape_window(int width,int height)741 void reshape_window(int width, int height)
742 {
743 glViewport(0, 0, (GLint)width, (GLint)height);
744 /*
745 glutPostRedisplay();
746 */
747 }
748
749
750
751
752
753
754 //----------------------------------------------------------------------
755 //
756 // Writing and reading the GL transformation matrices to and from
757 // files.
758 //
759 //----------------------------------------------------------------------
760
write_gl_matrices(FILE * f)761 void write_gl_matrices(FILE *f)
762 {
763 int i, current_mode;
764 double p[16];
765
766 glGetIntegerv(GL_MATRIX_MODE, ¤t_mode);
767
768 fprintf(f, "GL_PROJECTION_MATRIX\n");
769 glGetDoublev(GL_PROJECTION_MATRIX, p);
770 for (i=0; i<16; i++)
771 fprintf(f, "%.15e\n", p[i]);
772
773 fprintf(f, "GL_MODELVIEW_MATRIX\n");
774 glGetDoublev(GL_MODELVIEW_MATRIX, p);
775 for (i=0; i<16; i++)
776 fprintf(f, "%.15e\n", p[i]);
777
778 glMatrixMode(current_mode);
779 }
780
read_gl_matrices(FILE * f)781 void read_gl_matrices(FILE *f)
782 {
783 int i, current_mode;
784 double p[16];
785 char s[1000];
786
787 glGetIntegerv(GL_MATRIX_MODE, ¤t_mode);
788
789 fgets(s, 1000, f);
790 if (strcmp(s, "GL_PROJECTION_MATRIX\n")!=0)
791 CRIT_ERR(printf("Corrupt file contents? Read '%s'.\n", s));
792 for (i=0; i<16; i++)
793 fscanf(f, "%lf\n", p+i);
794 glMatrixMode(GL_PROJECTION_MATRIX);
795 glLoadMatrixd(p);
796
797 fgets(s, 1000, f);
798 if (strcmp(s, "GL_MODELVIEW_MATRIX\n")!=0)
799 CRIT_ERR(printf("Corrupt file contents? Read '%s'.\n", s));
800 for (i=0; i<16; i++)
801 fscanf(f, "%lf\n", p+i);
802 glMatrixMode(GL_MODELVIEW_MATRIX);
803 glLoadMatrixd(p);
804
805 glMatrixMode(current_mode);
806 }
807