//=========================================================================== // SISL - SINTEF Spline Library, version 4.5.0. // Definition and interrogation of NURBS curves and surfaces. // // Copyright (C) 2000-2005, 2010 SINTEF ICT, Applied Mathematics, Norway. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., // 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // // Contact information: E-mail: tor.dokken@sintef.no // SINTEF ICT, Department of Applied Mathematics, // P.O. Box 124 Blindern, // 0314 Oslo, Norway. // // Other licenses are also available for this software, notably licenses // for: // - Building commercial software. // - Building software whose source code you wish to keep private. //=========================================================================== 00037 #ifndef PI 00038 # define PI 3.1415926536 // Where should it *really* be defined? 00039 #endif 00040 00041 00042 const int predefined_colours=24; 00043 const double predef_col_table[3*predefined_colours] 00044 ={1.0, 0.0, 0.0, 00045 0.0, 1.0, 0.0, 00046 0.0, 0.0, 1.0, 00047 1.0, 1.0, 0.0, 00048 0.0, 1.0, 1.0, 00049 1.0, 0.0, 1.0, 00050 0.7, 0.0, 0.0, 00051 0.0, 0.7, 0.0, 00052 0.0, 0.0, 0.7, 00053 0.7, 0.7, 0.0, 00054 0.0, 0.7, 0.7, 00055 0.7, 0.0, 0.7, 00056 0.3, 0.8, 0.8, 00057 0.8, 0.3, 0.8, 00058 0.8, 0.8, 0.3, 00059 0.3, 0.3, 0.8, 00060 0.8, 0.3, 0.3, 00061 0.3, 0.8, 0.3, 00062 0.5, 0.8, 0.8, 00063 0.8, 0.5, 0.8, 00064 0.8, 0.8, 0.5, 00065 0.5, 0.5, 0.8, 00066 0.8, 0.5, 0.5, 00067 0.5, 0.8, 0.5}; 00068 00069 00070 00071 00072 00073 //---------------------------------------------------------------------- 00074 // 00075 // Drawing a cylinder, or possibly a cone. 00076 // 00077 //---------------------------------------------------------------------- 00078 00079 void draw_cylinder(double x0, double y0, double z0, 00080 double x1, double y1, double z1, 00081 double radius, double radius2, int n) 00082 { 00083 int i; 00084 double y, z, r; 00085 00086 glPushMatrix(); 00087 glTranslatef(x0, y0, z0); 00088 /* 00089 Now, we have to move P=(x1-x0, y1-y0, z1-z0) to (r, 0, 0) where 00090 r=length(x1-x0, y1-y0, z1-z0). First, rotate P to Q in the xy-plane: 00091 */ 00092 /* Hvorfor blir det ikke riktig med neg. rotasjon her? */ 00093 glRotatef(atan2(x1-x0, z1-z0)/PI*180.0-90.0, 00094 0.0, 1.0, 0.0); 00095 /* printf("%f %f %f\t", 00096 x1-x0, 00097 z1-z0, 00098 atan2(x1-x0, z1-z0)/PI*180.0);*/ 00099 /* 00100 Now, we have to move Q=(sqrt((x1-x0)^2+(z1-z0)^2), y1-y0, 0) to 00101 (r, 0, 0). 00102 */ 00103 r=sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0)+(z1-z0)*(z1-z0)); 00104 /* Hvorfor blir det ikke riktig med neg. rotasjon her? */ 00105 glRotatef(atan2(y1-y0, sqrt((x1-x0)*(x1-x0)+(z1-z0)*(z1-z0)))/PI*180.0, 00106 0.0, 0.0, 1.0); 00107 /* printf("%f %f %f\n", 00108 y1-y0, 00109 sqrt((x1-x0)*(x1-x0)+(z1-z0)*(z1-z0)), 00110 atan2(y1-y0, sqrt((x1-x0)*(x1-x0)+(z1-z0)*(z1-z0)))/PI*180.0);*/ 00111 /* 00112 The next step is to draw the cylinder. Or cone. Normals not perfect for 00113 the cone. Impossible at pointy end with tri-fan? 00114 */ 00115 if (radius==radius2) 00116 { 00117 glBegin(GL_QUAD_STRIP); 00118 for (i=0; i<=n; i++) 00119 { 00120 y=radius*cos((2.0*PI*i)/n); 00121 z=radius*sin((2.0*PI*i)/n); 00122 glNormal3f(0.0, y, z); 00123 glVertex3f(0.0, y, z); 00124 glNormal3f(0.0, y, z); 00125 glVertex3f( r, y, z); 00126 } 00127 glEnd(); 00128 } 00129 else 00130 { 00131 glBegin(GL_TRIANGLE_FAN); 00132 glNormal3f(1.0, 0.0, 0.0); 00133 glVertex3f(r, 0.0, 0.0); 00134 for (i=0; i<=n; i++) 00135 { 00136 y=radius*cos((2.0*PI*i)/n); 00137 z=radius*sin((2.0*PI*i)/n); 00138 glNormal3f(0.0, y, z); 00139 glVertex3f(0.0, y, z); 00140 } 00141 glEnd(); 00142 } 00143 /* 00144 Finally, we restore the transformation stack. 00145 */ 00146 glPopMatrix(); 00147 } 00148 00149 00150 00151 00152 00153 00154 //---------------------------------------------------------------------- 00155 // 00156 // Drawing a set of axes. 00157 // 00158 // 021203: Actually, this is newer. Fix!!!! 00159 // 00160 //---------------------------------------------------------------------- 00161 00162 void draw_gl_axes_old(int n, double r, double radius, double rim, double l) 00163 { 00164 // int n=10; 00165 // double r=0.7; 00166 // double radius=0.01, rim=0.04, l=0.1; 00167 00168 const double vertex_red=1.0, vertex_green=1.0, vertex_blue=1.0; 00169 00170 glColor3f(vertex_red, vertex_green, vertex_blue); 00171 00172 draw_cylinder(0.0, 0.0, -r, 0.0, 0.0, r, radius, radius, n); 00173 draw_cylinder(0.0, 0.0, r-0.1, 0.0, 0.0, r+0.3, rim, 0.0, n); 00174 draw_cylinder(-0.5*l, l, r+0.3, 0.5*l, l, r+0.3, 00175 radius, radius, n); 00176 draw_cylinder(-0.5*l, l*2.0, r+0.3, 0.5*l, l*2.0, r+0.3, 00177 radius, radius, n); 00178 draw_cylinder(-0.5*l, l, r+0.3, 0.5*l, l*2.0, r+0.3, 00179 radius, radius, n); 00180 00181 draw_cylinder(-r, 0.0, 0.0, r, 0.0, 0.0, radius, radius, n); 00182 draw_cylinder(r-0.1, 0.0, 0.0, r+0.3, 0.0, 0.0, rim, 0.0, n); 00183 draw_cylinder(r+0.3, l, 0.5*l, r+0.3, 2*l, -0.5*l, 00184 radius, radius, n); 00185 draw_cylinder(r+0.3, l, -0.5*l, r+0.3, 2*l, 0.5*l, 00186 radius, radius, n); 00187 00188 draw_cylinder(0.0, -r, 0.0, 0.0, r, 0.0, radius, radius, n); 00189 draw_cylinder(0.0, r-0.1, 0.0, 0.0, r+0.3, 0.0, rim, 0.0, n); 00190 draw_cylinder(0.0, r+0.3, 2.0*l, 0.0, r+0.3, 1.5*l, 00191 radius, radius, n); 00192 draw_cylinder(0.0, r+0.3, 1.5*l, -0.5*l, r+0.3, l, 00193 radius, radius, n); 00194 draw_cylinder(0.0, r+0.3, 1.5*l, 0.5*l, r+0.3, l, 00195 radius, radius, n); 00196 00197 glColor3f(1.0, 1.0, 1.0); 00198 } 00199 00200 00201 00202 00203 00204 00205 //---------------------------------------------------------------------- 00206 // 00207 // Draw gridlines to visualize cells. 00208 // 00209 //---------------------------------------------------------------------- 00210 00211 void draw_grid(const int n1, const int n2, const int n3) 00212 { 00213 int i, j, k; 00214 00215 glBegin(GL_LINES); 00216 for (i=0; i<n1; i++) 00217 for (j=0; j<n2; j++) 00218 { 00219 const double x=2.0*(i/(n1-1.0)-0.5); 00220 const double y=2.0*(j/(n2-1.0)-0.5); 00221 00222 glColor3f( 1.0, 0.0, 0.0); 00223 glVertex3f( x, y, -1.0); 00224 glColor3f( 1.0, 0.0, 0.0); 00225 glVertex3f( x, y, 1.0); 00226 } 00227 for (j=0; j<n2; j++) 00228 for (k=0; k<n3; k++) 00229 { 00230 const double y=2.0*(j/(n2-1.0)-0.5); 00231 const double z=2.0*(k/(n3-1.0)-0.5); 00232 00233 glColor3f( 0.0, 1.0, 0.0); 00234 glVertex3f(-1.0, y, z); 00235 glColor3f( 0.0, 1.0, 0.0); 00236 glVertex3f( 1.0, y, z); 00237 } 00238 for (k=0; k<n3; k++) 00239 for (i=0; i<n1; i++) 00240 { 00241 const double z=2.0*(k/(n3-1.0)-0.5); 00242 const double x=2.0*(i/(n1-1.0)-0.5); 00243 00244 glColor3f( 0.0, 0.0, 1.0); 00245 glVertex3f( x, -1.0, z); 00246 glColor3f( 0.0, 0.0, 1.0); 00247 glVertex3f( x, 1.0, z); 00248 } 00249 glEnd(); 00250 } 00251 00252 00253 00254 00255 00256 00257 // 00258 // 020505: Adding transparent planes. 00259 // 00260 00261 void draw_grid_planes(const int n1, const int n2, const int n3) 00262 { 00263 int i, j, k; 00264 00265 glDisable(GL_LIGHTING); // must be turned on by the caller... 00266 00267 glBlendFunc(GL_ONE, GL_ONE); 00268 glEnable(GL_BLEND); 00269 glDisable(GL_DEPTH_TEST); 00270 glBegin(GL_QUADS); 00271 for (k=0; k<n3; k++) 00272 { 00273 const double z=2.0*(k/(n3-1.0)-0.5); 00274 00275 glColor3f( 0.0, 0.0, 0.2); 00276 glVertex3f(-1.0, -1.0, z); 00277 glVertex3f( 1.0, -1.0, z); 00278 glVertex3f( 1.0, 1.0, z); 00279 glVertex3f(-1.0, 1.0, z); 00280 } 00281 for (j=0; j<n2; j++) 00282 { 00283 const double y=2.0*(j/(n2-1.0)-0.5); 00284 00285 glColor3f( 0.0, 0.2, 0.0); 00286 glVertex3f(-1.0, y, -1.0); 00287 glVertex3f( 1.0, y, -1.0); 00288 glVertex3f( 1.0, y, 1.0); 00289 glVertex3f(-1.0, y, 1.0); 00290 } 00291 for (i=0; i<n1; i++) 00292 { 00293 const double x=2.0*(i/(n1-1.0)-0.5); 00294 00295 glColor3f( 0.2, 0.0, 0.0); 00296 glVertex3f( x, -1.0, -1.0); 00297 glVertex3f( x, 1.0, -1.0); 00298 glVertex3f( x, 1.0, 1.0); 00299 glVertex3f( x, -1.0, 1.0); 00300 } 00301 glEnd(); 00302 glEnable(GL_DEPTH_TEST); 00303 glDisable(GL_BLEND); 00304 } 00305 00306 00307 00308 00309 00310 00311 //---------------------------------------------------------------------- 00312 // 00313 // Initializing glut and gl. 00314 // 00315 //---------------------------------------------------------------------- 00316 00317 void gl_init(int argc, char *argv[], 00318 const int xs, const int ys, 00319 const int x0, const int y0, 00320 const int doubleBuffer, 00321 const int two_sided, 00322 const int lighting, 00323 const int normalize, 00324 const int smooth, 00325 const double xtrans, 00326 const double ytrans, 00327 const double ztrans, 00328 const double xscale, 00329 const double yscale, 00330 const double zscale, 00331 int &tx, 00332 int &ty, 00333 const int texture_mode, 00334 const char * const texfile /* =NULL */) 00335 { 00336 int i; 00337 const int use_accum=0; 00338 00339 // 00340 // 020430: NB! Note that the really confusing name 'GLUT_RGBA' hides the 00341 // fact that this setting does not induce an alpha buffer being set 00342 // up! One must in fact specify GLUT_ALPHA explicitly! 00343 // (But I'm not sure how important this is... Perhaps this alpha is 00344 // not actually needed for the *window* for OpenGL for instance to 00345 // be able to do alpha blending?!) 00346 // 020501: Seems that we get accum buffer even without specifying it?! 00347 // 020502: GLUT_ALPHA seems not to be available on smaug. 00348 // But we don't actually need it for alpha-blending, anyway. For 00349 // that we only need alpha for the textures. 00350 // Ok, it's there when we go to 24 bpp mode in X. 00351 // 00352 #ifndef QTMODE 00353 glutInitDisplayMode(GLUT_RGBA | // GLUT_ALPHA | 00354 (use_accum ? GLUT_ACCUM : 0) | 00355 ((doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE) | 00356 GLUT_DEPTH); 00357 glutInitWindowSize(xs, ys); 00358 glutInitWindowPosition(x0, y0); 00359 glutInit(&argc, argv); 00360 glutCreateWindow(argv[0]); 00361 #endif 00362 00363 glClearColor(0.0, 0.0, 0.0, 0.0); 00364 if (use_accum) 00365 glClearAccum(0.0, 0.0, 0.0, 0.0); 00366 if (smooth) 00367 glShadeModel(GL_SMOOTH); 00368 else 00369 glShadeModel(GL_FLAT); 00370 glEnable(GL_DEPTH_TEST); 00371 glDepthFunc(GL_LESS); /* GL_LESS is default. */ 00372 /* glDepthRange(100.0, -100.0);*/ /* What is default value? */ 00373 /* glClearDepth(0.0); */ /* What is default value? */ 00374 00375 /* Initialize materials */ 00376 00377 { 00378 static float ambient[] = {0.1, 0.1, 0.1, 1.0}; 00379 static float diffuse[] = {0.4, 0.4, 0.4, 1.0}; 00380 00381 static float position0[] = { 5.0, 5.0, 200.0, 0.0}; 00382 static float position1[] = {-5.0, -5.0, 200.0, 0.0}; 00383 00384 static float front_mat_shininess[] = {50.0}; 00385 // static float front_mat_specular[] = {0.9, 0.9, 0.9, 1.0}; 00386 static float front_mat_specular[] = {0.0, 0.0, 0.0, 1.0}; 00387 static float front_mat_diffuse[] = {0.7, 0.7, 0.7, 1.0}; 00388 // static float front_mat_diffuse[] = {0, 0, 0, 1.0}; 00389 static float front_mat_ambient[] = {0.3, 0.3, 0.3, 1.0}; 00390 static float front_mat_emission[] = {0.3, 0.0, 0.0, 1.0}; 00391 00392 static float back_mat_shininess[] = {128.0}; 00393 // static float back_mat_specular[] = {0.4, 0.4, 0.4, 1.0}; 00394 static float back_mat_specular[] = {0.0, 0.0, 0.0, 1.0}; 00395 static float back_mat_diffuse[] = {0.7, 0.7, 0.7, 1.0}; 00396 static float back_mat_ambient[] = {0.3, 0.3, 0.3, 1.0}; 00397 static float back_mat_emission[] = {0.0, 0.3, 0.0, 1.0}; 00398 00399 static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0}; 00400 static float lmodel_twoside[] = {GL_TRUE}; 00401 00402 if (two_sided) 00403 lmodel_twoside[0]=GL_TRUE; 00404 else 00405 lmodel_twoside[0]=GL_FALSE; 00406 00407 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); 00408 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); 00409 glLightfv(GL_LIGHT0, GL_POSITION, position0); 00410 00411 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); 00412 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); 00413 glLightfv(GL_LIGHT1, GL_POSITION, position1); 00414 00415 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); 00416 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); 00417 00418 // glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); 00419 00420 glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess); 00421 glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular); 00422 glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse); 00423 glMaterialfv(GL_FRONT, GL_AMBIENT, front_mat_ambient); 00424 glMaterialfv(GL_FRONT, GL_EMISSION, front_mat_emission); 00425 00426 glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess); 00427 glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular); 00428 glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse); 00429 glMaterialfv(GL_BACK, GL_AMBIENT, back_mat_ambient); 00430 glMaterialfv(GL_BACK, GL_EMISSION, back_mat_emission); 00431 00432 glEnable(GL_LIGHT0); 00433 glEnable(GL_LIGHT1); 00434 if (lighting) 00435 glEnable(GL_LIGHTING); 00436 else 00437 glDisable(GL_LIGHTING); 00438 if (normalize) 00439 glEnable(GL_NORMALIZE); 00440 else 00441 glDisable(GL_NORMALIZE); 00442 } 00443 00444 glMatrixMode(GL_PROJECTION); 00445 glLoadIdentity(); 00446 /* glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 ); */ 00447 /* glFrustum( -1.0, 1.0, -1.0, 1.0, 2, 4 ); */ 00448 /* glFrustum( -1.0, 1.0, -1.0, 1.0, 100, 102 ); */ 00449 /* glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 7 );*/ 00450 /* 00451 Note that the far clipping plane distance doesn't influence on 00452 the projection, but that the distance between near and far should be 00453 as close to one as possible to best utilise the z-buffer. Or something 00454 like this... 00455 */ 00456 // 00457 // 000304: Was near=5, near clipping plane to far from viewer. 00458 // 6-0.5*sqrt(3) should make a 1x1x1 cube never intersect the near 00459 // plane regardless of rotation... Making it even closer will 00460 // make it possible to expand things more before being clipped... 00461 // 00462 //glFrustum(-1.0, 1.0, -1.0, 1.0, 6-0.5*sqrt(3), 20); 00463 00464 // 00465 // 020214: This one seems to be rather good, we can zoom in quite a lot 00466 // without stuff hitting the near clipping plane. 00467 // 00468 glFrustum(-1.0, 1.0, -1.0, 1.0, 3, 20); // cmt out 020201 00469 00470 // 020410 experimenting 00471 glLoadIdentity(); 00472 glFrustum(-1.0, 1.0, -1.0, 1.0, 3, 20); 00473 00474 // 00475 // 020214: The next one let's us see inside more easily, because the near 00476 // clipping plane is further away from us. 00477 // 00478 //glFrustum(-1.0, 1.0, -1.0, 1.0, 5, 20); 00479 00480 // 00481 // 021206: Trying to get the near clipping plane closer to us. 00482 // I've lost track of the actual numbers here... 00483 // Should be dealt with... 00484 // 00485 glLoadIdentity(); 00486 glFrustum(-1.0, 1.0, -1.0, 1.0, 2.0, 20); 00487 00488 // 00489 // 020627: Trying to reduce the "perspective" effect. 00490 // 00491 //glFrustum(-1.0, 1.0, -1.0, 1.0, 5+100, 20+100); 00492 00493 glMatrixMode(GL_MODELVIEW); 00494 glLoadIdentity(); 00495 /* glTranslated( 0.0, 0.0, -6.0 ); */ 00496 /* glTranslated( 0.0, 0.0, -3.0 ); */ 00497 /* glTranslated( 0.0, 0.0, -101.0 ); */ 00498 glTranslated(xtrans, ytrans, ztrans); 00499 glScaled(xscale, yscale, zscale); 00500 00501 /* 00502 Why did I do this? To clear both buffers? Is this necessary here? 00503 */ 00504 for (i=0; i<2; i++) 00505 { 00506 glDrawBuffer(GL_BACK); 00507 glReadBuffer(GL_BACK); 00508 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 00509 glClear(GL_COLOR_BUFFER_BIT | (use_accum ? GL_ACCUM_BUFFER_BIT : 0)); 00510 #ifndef QTMODE 00511 glutSwapBuffers(); 00512 #endif 00513 } 00514 00515 // 00516 // Note that after the texture has been inserted into the GL engine, it 00517 // is lost/deallocated from the application. 00518 // (But (for some reason) the size is returned...) 00519 // 00520 unsigned char *texture=NULL; 00521 if (texfile==NULL) 00522 { 00523 if (tx!=ty) 00524 CRIT_ERR(printf("tx=%d, ty=%d, not implemented.\n", tx, ty)); 00525 00526 if ((texture=new unsigned char[3*SQR(tx)])==NULL) 00527 CRIT_ERR(puts("Couldn't allocate space for texture.")); 00528 00529 int i; 00530 const unsigned char a=255, b=0; 00531 00532 for (i=0; i<3*SQR(tx); i++) 00533 texture[i]=a; 00534 for (i=0; i<tx; i++) 00535 { 00536 texture[3*(i*tx+0)+0]=b; 00537 texture[3*(i*tx+0)+1]=b; 00538 texture[3*(i*tx+0)+2]=b; 00539 texture[3*(i*tx+(tx-1))+0]=b; 00540 texture[3*(i*tx+(tx-1))+1]=b; 00541 texture[3*(i*tx+(tx-1))+2]=b; 00542 texture[3*(0*tx+i)+0]=b; 00543 texture[3*(0*tx+i)+1]=b; 00544 texture[3*(0*tx+i)+2]=b; 00545 texture[3*((tx-1)*tx+i)+0]=b; 00546 texture[3*((tx-1)*tx+i)+1]=b; 00547 texture[3*((tx-1)*tx+i)+2]=b; 00548 } 00549 } 00550 else 00551 // 00552 // Read texture from file... 00553 // 00554 { 00555 puts("texture code not compiled in!"); 00556 exit(0); 00557 #if 0 00558 unsigned char *texture_tmp=read_ppm_file(texfile, &tx, &ty); 00559 puts("Leste pgm-fil."); 00560 if (tx!=ty) 00561 CRIT_ERR(puts("Not implemented.")); 00562 if ((tx!=1) && (tx!=2) && (tx!=4) && (tx!=8) && (tx!=16) && (tx!=32) && 00563 (tx!=64) && (tx!=128) && (tx!=256) && (tx!=512) && (tx!=1024) && 00564 (tx!=2048) && (tx!=4096)) 00565 CRIT_ERR(puts("Texture size not ok.")); 00566 00567 printf("Texture size is %dx%d.\n", tx, ty); 00568 00569 if ((texture=new unsigned char[3*SQR(tx)])==NULL) 00570 CRIT_ERR(puts("Couldn't allocate space for texture.")); 00571 00572 int i; 00573 00574 for (i=0; i<SQR(tx); i++) 00575 { 00576 texture[3*i+0]=texture_tmp[i]; 00577 texture[3*i+1]=texture_tmp[i]; 00578 texture[3*i+2]=texture_tmp[i]; 00579 // printf("%5d - %3d %3d %3d\n", i, 00580 // texture[i+0], texture[i+1], texture[i+2]); 00581 } 00582 00583 delete texture_tmp; 00584 #endif 00585 } 00586 00587 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tx, ty, 00588 0, GL_RGB, GL_UNSIGNED_BYTE, texture); 00589 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texture_mode); 00590 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 00591 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 00592 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 00593 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 00594 00595 delete texture; 00596 00597 //glPolygonOffset(0.0, 20.0); 00598 // 00599 // 020430: PolygonOffset(factor, units) produces an offset o, where 00600 // o = max depth slope * factor + impl. dep. const. r * units. 00601 // 0.0, 20.0 worked just perfect for GeForce 2 and Matrox Mystique, 00602 // but not for GeForce 3. 00603 // Perhaps it was strange that it worked? Or maybe it enough now 00604 // just use a factor slightly greater than 0.0? 00605 // A good idea would perhaps be to make a tool to adjust these 00606 // empirically during runtime?! 00607 // Seems that it is not enough to just increase factor slightly, 00608 // perhaps the GF3 has another definition for 'units'? Increasing 00609 // it somewhat seems to make the problem go away... 00610 // Don't want to increase it too much though. 00611 // Perhaps a way to do this: Increase the 'factor' until very 00612 // slanted surfaces turns out ok, and increase 'units' until 00613 // flat (parallel to near plane) surfaces are ok?! Will do it 00614 // like this but opposite order. 00615 // Hmm!!! (1.0, 1.0) seems to be just fine! 00616 // 00617 glPolygonOffset(1.0, 1.0); 00618 glEnable(GL_POLYGON_OFFSET_POINT); 00619 glEnable(GL_POLYGON_OFFSET_LINE); 00620 glEnable(GL_POLYGON_OFFSET_FILL); 00621 00622 } 00623 00624 00625 00626 00627 00628 00629 void transpose_matrix(double * const d) 00630 { 00631 int i, j; 00632 00633 for (i=0; i<4; i++) 00634 for (j=0; j<i; j++) 00635 { 00636 double tmp=d[i*4+j]; 00637 d[i*4+j]=d[j*4+i]; 00638 d[j*4+i]=tmp; 00639 } 00640 } 00641 00642 00643 00644 00645 00646 00647 void print_gl_matrix(const int m) 00648 { 00649 int i; 00650 double p[16], p2[16]; 00651 00652 switch (m) 00653 { 00654 case GL_PROJECTION_MATRIX: 00655 00656 case GL_MODELVIEW_MATRIX: 00657 glGetDoublev((GLenum)m, p); 00658 break; 00659 00660 #if 0 00661 case GL_MODELVIEW_MATRIX + GL_PROJECTION_MATRIX: 00662 glMatrixMode(GL_MODELVIEW); 00663 glPushMatrix(); 00664 glGetDoublev(GL_PROJECTION_MATRIX, p); 00665 glMultMatrixd(p); 00666 glGetDoublev(GL_MODELVIEW_MATRIX, p); 00667 glPopMatrix(); 00668 break; 00669 #endif 00670 00671 case GL_MODELVIEW_MATRIX + GL_PROJECTION_MATRIX: 00672 glMatrixMode(GL_MODELVIEW); 00673 glGetDoublev(GL_MODELVIEW_MATRIX, p2); 00674 glPushMatrix(); 00675 glLoadIdentity(); 00676 glGetDoublev(GL_PROJECTION_MATRIX, p); 00677 glMultMatrixd(p); 00678 glMultMatrixd(p2); 00679 glGetDoublev(GL_MODELVIEW_MATRIX, p); 00680 glPopMatrix(); 00681 break; 00682 } 00683 00684 // 00685 // 000320: BUG was here! GL uses column-order... 00686 // 00687 transpose_matrix(p); 00688 00689 printf("{"); 00690 for (i=0; i<15; ) 00691 { 00692 printf("%g, ", p[i]); 00693 i++; 00694 if (i%4==0) 00695 printf("\n"); 00696 } 00697 printf("%g}\n\n", p[15]); 00698 00699 printf("For Mathematica:\n\n"); 00700 printf("{"); 00701 for (i=0; i<15; ) 00702 { 00703 if (i%4==0) 00704 printf("{"); 00705 printf("%f", p[i]); 00706 i++; 00707 if (i%4==0) 00708 printf("}, "); 00709 else 00710 printf(", "); 00711 } 00712 printf("%f}}\n\n", p[15]); 00713 00714 00715 } 00716 00717 00718 00719 00720 00721 00722 00723 //---------------------------------------------------------------------- 00724 // 00725 // This callback is called when the window is reshaped. 00726 // 00727 //---------------------------------------------------------------------- 00728 00729 void reshape_window(int width, int height) 00730 { 00731 glViewport(0, 0, (GLint)width, (GLint)height); 00732 /* 00733 glutPostRedisplay(); 00734 */ 00735 } 00736 00737 00738 00739 00740 00741 00742 //---------------------------------------------------------------------- 00743 // 00744 // Writing and reading the GL transformation matrices to and from 00745 // files. 00746 // 00747 //---------------------------------------------------------------------- 00748 00749 void write_gl_matrices(FILE *f) 00750 { 00751 int i, current_mode; 00752 double p[16]; 00753 00754 glGetIntegerv(GL_MATRIX_MODE, ¤t_mode); 00755 00756 fprintf(f, "GL_PROJECTION_MATRIX\n"); 00757 glGetDoublev(GL_PROJECTION_MATRIX, p); 00758 for (i=0; i<16; i++) 00759 fprintf(f, "%.15e\n", p[i]); 00760 00761 fprintf(f, "GL_MODELVIEW_MATRIX\n"); 00762 glGetDoublev(GL_MODELVIEW_MATRIX, p); 00763 for (i=0; i<16; i++) 00764 fprintf(f, "%.15e\n", p[i]); 00765 00766 glMatrixMode(current_mode); 00767 } 00768 00769 void read_gl_matrices(FILE *f) 00770 { 00771 int i, current_mode; 00772 double p[16]; 00773 char s[1000]; 00774 00775 glGetIntegerv(GL_MATRIX_MODE, ¤t_mode); 00776 00777 fgets(s, 1000, f); 00778 if (strcmp(s, "GL_PROJECTION_MATRIX\n")!=0) 00779 CRIT_ERR(printf("Corrupt file contents? Read '%s'.\n", s)); 00780 for (i=0; i<16; i++) 00781 fscanf(f, "%lf\n", p+i); 00782 glMatrixMode(GL_PROJECTION_MATRIX); 00783 glLoadMatrixd(p); 00784 00785 fgets(s, 1000, f); 00786 if (strcmp(s, "GL_MODELVIEW_MATRIX\n")!=0) 00787 CRIT_ERR(printf("Corrupt file contents? Read '%s'.\n", s)); 00788 for (i=0; i<16; i++) 00789 fscanf(f, "%lf\n", p+i); 00790 glMatrixMode(GL_MODELVIEW_MATRIX); 00791 glLoadMatrixd(p); 00792 00793 glMatrixMode(current_mode); 00794 }
1.6.3