00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "GUI/ViewPort.H"
00038 #include <math.h>
00039 #include <pthread.h>
00040 #include <sys/stat.h>
00041
00042
00043
00044 ViewPort::ViewPort(const char *winname,
00045 const char* ground, const char* sky, bool useFog,
00046 bool drawWorld,
00047 int w, int h,
00048 const double cameraParam[3][4] ) :
00049 itsWidth(w),
00050 itsHeight(h),
00051 run(0),
00052 display(0),
00053 visual(0),
00054 colormap(0),
00055 win(0),
00056 glx_context(0),
00057 last_key_pressed(0),
00058 wm_protocols_atom(0),
00059 wm_delete_window_atom(0),
00060 screen(0),
00061 sky_texture(0),
00062 ground_texture(0),
00063 wood_texture(0),
00064 tree_texture(0),
00065 other_texture(0),
00066 listnum(0),
00067 itsDrawWorld(drawWorld),
00068 itsUseFog(useFog),
00069 itsWireframe(false),
00070 itsZoomFactor(0.8)
00071 {
00072 createMainWindow (winname);
00073
00074 glXMakeCurrent (display,win,glx_context);
00075 startGraphics("./etc/textures/", ground, sky);
00076
00077 for(int i=0; i<4; i++)
00078 color[i] = 0;
00079 tnum = 0;
00080
00081 ground_scale = 1.0f/20.0f;
00082 ground_ofsx = 0.5;
00083 ground_ofsy = 0.5;
00084 sky_scale = 1.0f/4.0f;
00085 sky_height = 1.0f;
00086
00087 sphere_quality = 1;
00088 capped_cylinder_quality = 3;
00089
00090 if (itsDrawWorld)
00091 {
00092 use_textures=1;
00093 use_shadows=1;
00094 } else {
00095 use_textures=0;
00096 use_shadows=0;
00097 }
00098
00099
00100 initCamera();
00101
00102 if (cameraParam != NULL)
00103 buildProjectionMatrix(cameraParam, itsProjMatrix);
00104
00105 run = 1;
00106
00107
00108
00109
00110
00111 }
00112
00113 ViewPort::~ViewPort(){
00114 stopGraphics();
00115
00116 destroyMainWindow();
00117 }
00118
00119 void ViewPort::setTextures(bool val)
00120 {
00121 if (val)
00122 use_textures=1;
00123 else
00124 use_textures=0;
00125 }
00126
00127 void ViewPort::setShadows(bool val)
00128 {
00129 if (val)
00130 use_shadows=1;
00131 else
00132 use_shadows=0;
00133 }
00134
00135
00136 void ViewPort::createMainWindow (const char *winname){
00137
00138 display = XOpenDisplay (NULL);
00139 if (!display) LFATAL("can not open X11 display");
00140
00141 screen = DefaultScreen(display);
00142
00143
00144
00145 static int attribList[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE,16,
00146 GLX_RED_SIZE,4, GLX_GREEN_SIZE,4,
00147 GLX_BLUE_SIZE,4, None};
00148 visual = glXChooseVisual (display,screen,attribList);
00149 if (!visual) LFATAL("no good X11 visual found for OpenGL");
00150
00151
00152 colormap = XCreateColormap (display,RootWindow(display,screen),
00153 visual->visual,AllocNone);
00154
00155
00156 win = 0;
00157
00158 last_key_pressed = 0;
00159
00160 if (itsWidth < 1 || itsHeight < 1) LDEBUG ("bad window width or height");
00161
00162
00163 XSetWindowAttributes attributes;
00164 attributes.background_pixel = BlackPixel(display,screen);
00165 attributes.colormap = colormap;
00166 attributes.event_mask = ButtonPressMask | ButtonReleaseMask |
00167 KeyPressMask | KeyReleaseMask | ButtonMotionMask | PointerMotionHintMask |
00168 StructureNotifyMask;
00169 win = XCreateWindow (display,RootWindow(display,screen),50,50,itsWidth,itsHeight,
00170 0,visual->depth, InputOutput,visual->visual,
00171 CWBackPixel | CWColormap | CWEventMask,&attributes);
00172
00173
00174 glx_context = glXCreateContext (display,visual,0,GL_TRUE);
00175 if (!glx_context) LFATAL ("can't make an OpenGL context");
00176
00177
00178 XTextProperty window_name;
00179 window_name.value = (unsigned char *)winname;
00180 window_name.encoding = XA_STRING;
00181 window_name.format = 8;
00182 window_name.nitems = strlen((char *) window_name.value);
00183 XSetWMName (display,win,&window_name);
00184
00185
00186 wm_protocols_atom = XInternAtom (display,"WM_PROTOCOLS",False);
00187 wm_delete_window_atom = XInternAtom (display,"WM_DELETE_WINDOW",False);
00188 if (XSetWMProtocols (display,win,&wm_delete_window_atom,1)==0)
00189 LFATAL ("XSetWMProtocols() call failed");
00190
00191
00192 XMapWindow (display,win);
00193 XSync (display,win);
00194
00195 }
00196
00197 void ViewPort::destroyMainWindow()
00198 {
00199 glXDestroyContext (display,glx_context);
00200 XDestroyWindow (display,win);
00201 XSync (display,0);
00202 display = 0;
00203 win = 0;
00204 glx_context = NULL;
00205 }
00206
00207
00208 void ViewPort::startGraphics (const char *prefix, const char *ground, const char *sky){
00209
00210 char *s = new char[strlen(prefix) + 20];
00211
00212 strcpy (s,prefix);
00213 strcat (s,sky);
00214 sky_texture = new Texture (s);
00215
00216 strcpy (s,prefix);
00217 strcat (s,ground);
00218 ground_texture = new Texture (s);
00219
00220 strcpy (s,prefix);
00221 strcat (s,"wood.ppm");
00222 wood_texture = new Texture (s);
00223
00224 strcpy (s,prefix);
00225 strcat (s,"tree.ppm");
00226 tree_texture = new Texture (s);
00227 }
00228
00229 void ViewPort::stopGraphics()
00230 {
00231 if (sky_texture) delete sky_texture;
00232 if (ground_texture) delete ground_texture;
00233 if (wood_texture) delete wood_texture;
00234 if (tree_texture) delete tree_texture;
00235 if (other_texture) delete other_texture;
00236 sky_texture = 0;
00237 ground_texture = 0;
00238 tree_texture = 0;
00239 other_texture = 0;
00240 }
00241
00242 void ViewPort::handleEvent (XEvent &event)
00243 {
00244 static int mx=0,my=0;
00245 static int mode = 0;
00246
00247
00248
00249 switch (event.type) {
00250
00251 case ButtonPress: {
00252 if (event.xbutton.button == Button1) mode |= 1;
00253 if (event.xbutton.button == Button2) mode |= 2;
00254 if (event.xbutton.button == Button3) mode |= 4;
00255 mx = event.xbutton.x;
00256 my = event.xbutton.y;
00257 }
00258 return;
00259
00260 case ButtonRelease: {
00261 if (event.xbutton.button == Button1) mode &= (~1);
00262 if (event.xbutton.button == Button2) mode &= (~2);
00263 if (event.xbutton.button == Button3) mode &= (~4);
00264 mx = event.xbutton.x;
00265 my = event.xbutton.x;
00266 }
00267 return;
00268
00269 case MotionNotify: {
00270 if (event.xmotion.is_hint) {
00271 Window root,child;
00272 unsigned int mask;
00273 XQueryPointer (display,win,&root,&child,&event.xbutton.x_root,
00274 &event.xbutton.y_root,&event.xbutton.x,&event.xbutton.y,
00275 &mask);
00276 }
00277 dsMotion (mode, event.xmotion.x - mx, event.xmotion.y - my);
00278 mx = event.xmotion.x;
00279 my = event.xmotion.y;
00280 }
00281 return;
00282
00283 case ClientMessage:
00284 if (event.xclient.message_type == wm_protocols_atom &&
00285 event.xclient.format == 32 &&
00286 Atom(event.xclient.data.l[0]) == wm_delete_window_atom) {
00287 run = 0;
00288 return;
00289 }
00290 return;
00291
00292 case ConfigureNotify:
00293 itsWidth = event.xconfigure.width;
00294 itsHeight = event.xconfigure.height;
00295 return;
00296 }
00297 }
00298
00299 void ViewPort::initCamera()
00300 {
00301 view_xyz[0] = 0;
00302 view_xyz[1] = 5;
00303 view_xyz[2] = 5;
00304 view_hpr[0] = -100;
00305 view_hpr[1] = -30;
00306 view_hpr[2] = 0;
00307 }
00308
00309
00310
00311 XEvent ViewPort::initFrame(const double* cameraParam){
00312
00313
00314 XEvent event;
00315 while (run && XPending (display)) {
00316 XNextEvent (display,&event);
00317 handleEvent (event);
00318 }
00319
00320 dsDrawFrame (cameraParam);
00321
00322 return event;
00323 }
00324
00325
00326
00327 int ViewPort::updateFrame(){
00328
00329 glFlush();
00330 glXSwapBuffers (display,win);
00331 XSync (display,0);
00332
00333 return run;
00334
00335 }
00336
00337 void ViewPort::getFrame(unsigned char *img){
00338 glXMakeCurrent (display,win,glx_context);
00339 glPixelStorei(GL_PACK_ALIGNMENT,1);
00340 glReadBuffer(GL_BACK_LEFT);
00341 glReadPixels (0, 0, itsWidth, itsHeight, GL_RGB, GL_UNSIGNED_BYTE, img);
00342 }
00343
00344 Image<PixRGB<byte> > ViewPort::getFrame(){
00345
00346 Image<PixRGB<byte> > retImg(itsWidth, itsHeight, NO_INIT);
00347 glXMakeCurrent (display,win,glx_context);
00348 glPixelStorei(GL_PACK_ALIGNMENT,1);
00349 glReadBuffer(GL_BACK_LEFT);
00350 glReadPixels (0, 0, itsWidth, itsHeight, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char*)retImg.getArrayPtr());
00351
00352 return retImg;
00353 }
00354
00355 void ViewPort::mainWindowThread(void *data){
00356 ViewPort *vp = (ViewPort *)data;
00357 vp->run = 1;
00358 while(vp->run){
00359 XEvent event;
00360 while (vp->run && XPending (vp->display)) {
00361 XNextEvent (vp->display,&event);
00362 vp->handleEvent (event);
00363 }
00364
00365
00366
00367 glFlush();
00368 glXSwapBuffers (vp->display,vp->win);
00369 XSync (vp->display,0);
00370
00371
00372 if (vp->writeframes) {
00373
00374
00375 }
00376 }
00377
00378 }
00379
00380 inline double ViewPort::dDOT (const double *a, const double *b)
00381 { return ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2]); }
00382
00383
00384 void ViewPort::normalizeVector3 (float v[3])
00385 {
00386 double len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
00387 if (len <= 0.0f) {
00388 v[0] = 1;
00389 v[1] = 0;
00390 v[2] = 0;
00391 }
00392 else {
00393 len = 1.0f / (double)sqrt(len);
00394 v[0] *= len;
00395 v[1] *= len;
00396 v[2] *= len;
00397 }
00398 }
00399
00400
00401
00402
00403 void ViewPort::buildProjectionMatrix(const double cameraParam[3][4], double projMatrix[16])
00404 {
00405
00406
00407 double icpara[3][4];
00408 double trans[3][4];
00409 double p[3][3], q[4][4];
00410 int i, j;
00411 double gnear = 50;
00412 double gfar = 5000;
00413
00414 if( paramDecompMat(cameraParam, icpara, trans) < 0 )
00415 LFATAL("Camera Parameter error!!\n");
00416
00417 for( i = 0; i < 3; i++ ) {
00418 for( j = 0; j < 3; j++ ) {
00419 p[i][j] = icpara[i][j] / icpara[2][2];
00420 }
00421 }
00422 q[0][0] = (2.0 * p[0][0] / itsWidth);
00423 q[0][1] = (2.0 * p[0][1] / itsWidth);
00424 q[0][2] = ((2.0 * p[0][2] / itsWidth) - 1.0);
00425 q[0][3] = 0.0;
00426
00427 q[1][0] = 0.0;
00428 q[1][1] = (2.0 * p[1][1] / itsHeight);
00429 q[1][2] = ((2.0 * p[1][2] / itsHeight) - 1.0);
00430 q[1][3] = 0.0;
00431
00432 q[2][0] = 0.0;
00433 q[2][1] = 0.0;
00434 q[2][2] = (gfar + gnear)/(gfar - gnear);
00435 q[2][3] = -2.0 * gfar * gnear / (gfar - gnear);
00436
00437 q[3][0] = 0.0;
00438 q[3][1] = 0.0;
00439 q[3][2] = 1.0;
00440 q[3][3] = 0.0;
00441
00442 for( i = 0; i < 4; i++ ) {
00443 for( j = 0; j < 3; j++ ) {
00444 projMatrix[i+j*4] = q[i][0] * trans[0][j]
00445 + q[i][1] * trans[1][j]
00446 + q[i][2] * trans[2][j];
00447 }
00448 projMatrix[i+3*4] = q[i][0] * trans[0][3]
00449 + q[i][1] * trans[1][3]
00450 + q[i][2] * trans[2][3]
00451 + q[i][3];
00452 }
00453
00454 }
00455
00456 #define NORM(a,b,c) sqrt(a*a + b*b + c*c)
00457 #define DOT(a1,a2,a3,b1,b2,b3) (a1*b1 + a2*b2 + a3*b3)
00458
00459 int ViewPort::paramDecompMat(const double source[3][4], double cpara[3][4], double trans[3][4] )
00460 {
00461 int r, c;
00462 double Cpara[3][4];
00463 double rem1, rem2, rem3;
00464
00465 if( source[2][3] >= 0 ) {
00466 for( r = 0; r < 3; r++ ){
00467 for( c = 0; c < 4; c++ ){
00468 Cpara[r][c] = source[r][c];
00469 }
00470 }
00471 }
00472 else {
00473 for( r = 0; r < 3; r++ ){
00474 for( c = 0; c < 4; c++ ){
00475 Cpara[r][c] = -(source[r][c]);
00476 }
00477 }
00478 }
00479
00480 for( r = 0; r < 3; r++ ){
00481 for( c = 0; c < 4; c++ ){
00482 cpara[r][c] = 0.0;
00483 }
00484 }
00485 cpara[2][2] = NORM( Cpara[2][0], Cpara[2][1], Cpara[2][2] );
00486 trans[2][0] = Cpara[2][0] / cpara[2][2];
00487 trans[2][1] = Cpara[2][1] / cpara[2][2];
00488 trans[2][2] = Cpara[2][2] / cpara[2][2];
00489 trans[2][3] = Cpara[2][3] / cpara[2][2];
00490
00491 cpara[1][2] = DOT( trans[2][0], trans[2][1], trans[2][2],
00492 Cpara[1][0], Cpara[1][1], Cpara[1][2] );
00493 rem1 = Cpara[1][0] - cpara[1][2] * trans[2][0];
00494 rem2 = Cpara[1][1] - cpara[1][2] * trans[2][1];
00495 rem3 = Cpara[1][2] - cpara[1][2] * trans[2][2];
00496 cpara[1][1] = NORM( rem1, rem2, rem3 );
00497 trans[1][0] = rem1 / cpara[1][1];
00498 trans[1][1] = rem2 / cpara[1][1];
00499 trans[1][2] = rem3 / cpara[1][1];
00500
00501 cpara[0][2] = DOT( trans[2][0], trans[2][1], trans[2][2],
00502 Cpara[0][0], Cpara[0][1], Cpara[0][2] );
00503 cpara[0][1] = DOT( trans[1][0], trans[1][1], trans[1][2],
00504 Cpara[0][0], Cpara[0][1], Cpara[0][2] );
00505 rem1 = Cpara[0][0] - cpara[0][1]*trans[1][0] - cpara[0][2]*trans[2][0];
00506 rem2 = Cpara[0][1] - cpara[0][1]*trans[1][1] - cpara[0][2]*trans[2][1];
00507 rem3 = Cpara[0][2] - cpara[0][1]*trans[1][2] - cpara[0][2]*trans[2][2];
00508 cpara[0][0] = NORM( rem1, rem2, rem3 );
00509 trans[0][0] = rem1 / cpara[0][0];
00510 trans[0][1] = rem2 / cpara[0][0];
00511 trans[0][2] = rem3 / cpara[0][0];
00512
00513 trans[1][3] = (Cpara[1][3] - cpara[1][2]*trans[2][3]) / cpara[1][1];
00514 trans[0][3] = (Cpara[0][3] - cpara[0][1]*trans[1][3]
00515 - cpara[0][2]*trans[2][3]) / cpara[0][0];
00516
00517 for( r = 0; r < 3; r++ ){
00518 for( c = 0; c < 3; c++ ){
00519 cpara[r][c] /= cpara[2][2];
00520 }
00521 }
00522
00523 return 0;
00524 }
00525
00526
00527
00528 void ViewPort::setCamera (double x, double y, double z, double h, double p, double r)
00529 {
00530 glMatrixMode (GL_MODELVIEW);
00531 glLoadIdentity();
00532 glRotatef (90, 0,0,1);
00533 glRotatef (90, 0,1,0);
00534 glRotatef (r, 1,0,0);
00535 glRotatef (p, 0,1,0);
00536 glRotatef (-h, 0,0,1);
00537 glTranslatef (-x,-y,-z);
00538 }
00539
00540
00541
00542
00543 void ViewPort::setColor (double r, double g, double b, double alpha)
00544 {
00545 GLfloat light_ambient[4],light_diffuse[4],light_specular[4];
00546 light_ambient[0] = r*0.3f;
00547 light_ambient[1] = g*0.3f;
00548 light_ambient[2] = b*0.3f;
00549 light_ambient[3] = alpha;
00550 light_diffuse[0] = r*0.7f;
00551 light_diffuse[1] = g*0.7f;
00552 light_diffuse[2] = b*0.7f;
00553 light_diffuse[3] = alpha;
00554 light_specular[0] = r*0.2f;
00555 light_specular[1] = g*0.2f;
00556 light_specular[2] = b*0.2f;
00557 light_specular[3] = alpha;
00558 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, light_ambient);
00559 glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, light_diffuse);
00560 glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, light_specular);
00561 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 5.0f);
00562 }
00563
00564
00565 void ViewPort::setTransform (const double pos[3], const double R[12])
00566 {
00567 GLfloat matrix[16];
00568 matrix[0]=R[0];
00569 matrix[1]=R[4];
00570 matrix[2]=R[8];
00571 matrix[3]=0;
00572 matrix[4]=R[1];
00573 matrix[5]=R[5];
00574 matrix[6]=R[9];
00575 matrix[7]=0;
00576 matrix[8]=R[2];
00577 matrix[9]=R[6];
00578 matrix[10]=R[10];
00579 matrix[11]=0;
00580 matrix[12]=pos[0];
00581 matrix[13]=pos[1];
00582 matrix[14]=pos[2];
00583 matrix[15]=1;
00584 glPushMatrix();
00585 glMultMatrixf (matrix);
00586 }
00587
00588 void ViewPort::unProjectPoint(const int x, const int y, double objLoc[3])
00589 {
00590
00591
00592 GLint viewport[4];
00593 GLdouble modelview[16];
00594 GLdouble projection[16];
00595 GLfloat winX=0, winY=0, winZ=0;
00596 GLdouble posX=0, posY=0, posZ=0;
00597
00598 glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
00599 glGetDoublev( GL_PROJECTION_MATRIX, projection );
00600 glGetIntegerv( GL_VIEWPORT, viewport );
00601
00602 winX = (float)x;
00603 winY = (float)viewport[3] - (float)y;
00604 glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
00605
00606
00607 #ifdef INVT_HAVE_LIBGLUT
00608 gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
00609 #endif
00610
00611 objLoc[0] = posX;
00612 objLoc[1] = posY;
00613 objLoc[2] = posZ;
00614
00615 }
00616
00617
00618
00619 void ViewPort::setShadowTransform()
00620 {
00621 GLfloat matrix[16];
00622 for (int i=0; i<16; i++) matrix[i] = 0;
00623 matrix[0]=1;
00624 matrix[5]=1;
00625 matrix[8]=-LIGHTX;
00626 matrix[9]=-LIGHTY;
00627 matrix[15]=1;
00628 glPushMatrix();
00629 glMultMatrixf (matrix);
00630 }
00631
00632
00633 void ViewPort::drawBox (const double sides[3])
00634 {
00635 double lx = sides[0]*0.5f;
00636 double ly = sides[1]*0.5f;
00637 double lz = sides[2]*0.5f;
00638
00639 glBegin(GL_QUADS);
00640 glNormal3f(0,1,0);
00641 glVertex3f( lx, ly,-lz);
00642 glVertex3f(-lx, ly,-lz);
00643 glVertex3f(-lx, ly, lz);
00644 glVertex3f( lx, ly, lz);
00645
00646 glNormal3f(0,-1,0);
00647 glVertex3f( lx,-ly, lz);
00648 glVertex3f(-lx,-ly, lz);
00649 glVertex3f(-lx,-ly,-lz);
00650 glVertex3f( lx,-ly,-lz);
00651
00652 glNormal3f(0,0,1);
00653 glVertex3f( lx, ly, lz);
00654 glVertex3f(-lx, ly, lz);
00655 glVertex3f(-lx,-ly, lz);
00656 glVertex3f( lx,-ly, lz);
00657
00658 glNormal3f(0,0,-1);
00659 glVertex3f( lx,-ly,-lz);
00660 glVertex3f(-lx,-ly,-lz);
00661 glVertex3f(-lx, ly,-lz);
00662 glVertex3f( lx, ly,-lz);
00663
00664 glNormal3f(-1,0,0);
00665 glVertex3f(-lx, ly, lz);
00666 glVertex3f(-lx, ly,-lz);
00667 glVertex3f(-lx,-ly,-lz);
00668 glVertex3f(-lx,-ly, lz);
00669
00670 glNormal3f(1,0,0);
00671 glVertex3f( lx, ly,-lz);
00672 glVertex3f( lx, ly, lz);
00673 glVertex3f( lx,-ly, lz);
00674 glVertex3f( lx,-ly,-lz);
00675 glEnd();
00676
00677 }
00678
00679
00680
00681
00682
00683
00684
00685
00686 void ViewPort::drawPatch (double p1[3], double p2[3], double p3[3], int level)
00687 {
00688 int i;
00689 if (level > 0) {
00690 double q1[3],q2[3],q3[3];
00691 for (i=0; i<3; i++) {
00692 q1[i] = 0.5f*(p1[i]+p2[i]);
00693 q2[i] = 0.5f*(p2[i]+p3[i]);
00694 q3[i] = 0.5f*(p3[i]+p1[i]);
00695 }
00696 double length1 = (double)(1.0/sqrt(q1[0]*q1[0]+q1[1]*q1[1]+q1[2]*q1[2]));
00697 double length2 = (double)(1.0/sqrt(q2[0]*q2[0]+q2[1]*q2[1]+q2[2]*q2[2]));
00698 double length3 = (double)(1.0/sqrt(q3[0]*q3[0]+q3[1]*q3[1]+q3[2]*q3[2]));
00699 for (i=0; i<3; i++) {
00700 q1[i] *= length1;
00701 q2[i] *= length2;
00702 q3[i] *= length3;
00703 }
00704 drawPatch (p1,q1,q3,level-1);
00705 drawPatch (q1,p2,q2,level-1);
00706 drawPatch (q1,q2,q3,level-1);
00707 drawPatch (q3,q2,p3,level-1);
00708 }
00709 else {
00710 glNormal3f (p1[0],p1[1],p1[2]);
00711 glVertex3f (p1[0],p1[1],p1[2]);
00712 glNormal3f (p2[0],p2[1],p2[2]);
00713 glVertex3f (p2[0],p2[1],p2[2]);
00714 glNormal3f (p3[0],p3[1],p3[2]);
00715 glVertex3f (p3[0],p3[1],p3[2]);
00716 }
00717 }
00718
00719
00720
00721 void ViewPort::drawSphere()
00722 {
00723
00724 # define ICX 0.525731112119133606f
00725 # define ICZ 0.850650808352039932f
00726 static GLdouble idata[12][3] = {
00727 {-ICX, 0, ICZ},
00728 {ICX, 0, ICZ},
00729 {-ICX, 0, -ICZ},
00730 {ICX, 0, -ICZ},
00731 {0, ICZ, ICX},
00732 {0, ICZ, -ICX},
00733 {0, -ICZ, ICX},
00734 {0, -ICZ, -ICX},
00735 {ICZ, ICX, 0},
00736 {-ICZ, ICX, 0},
00737 {ICZ, -ICX, 0},
00738 {-ICZ, -ICX, 0}
00739 };
00740
00741 static int index[20][3] = {
00742 {0, 4, 1}, {0, 9, 4},
00743 {9, 5, 4}, {4, 5, 8},
00744 {4, 8, 1}, {8, 10, 1},
00745 {8, 3, 10}, {5, 3, 8},
00746 {5, 2, 3}, {2, 7, 3},
00747 {7, 10, 3}, {7, 6, 10},
00748 {7, 11, 6}, {11, 0, 6},
00749 {0, 1, 6}, {6, 1, 10},
00750 {9, 0, 11}, {9, 11, 2},
00751 {9, 2, 5}, {7, 2, 11},
00752 };
00753
00754 if (listnum==0) {
00755 listnum = glGenLists (1);
00756 glNewList (listnum,GL_COMPILE);
00757 glBegin (GL_TRIANGLES);
00758 for (int i=0; i<20; i++) {
00759 drawPatch (&idata[index[i][2]][0],&idata[index[i][1]][0],
00760 &idata[index[i][0]][0],sphere_quality);
00761 }
00762 glEnd();
00763 glEndList();
00764 }
00765 glCallList (listnum);
00766 }
00767
00768
00769
00770 void ViewPort::drawSphereShadow (double px, double py, double pz, double radius)
00771 {
00772
00773 static int init=0;
00774 static double len2,len1,scale;
00775 if (!init) {
00776 len2 = LIGHTX*LIGHTX + LIGHTY*LIGHTY;
00777 len1 = 1.0f/(double)sqrt(len2);
00778 scale = (double) sqrt(len2 + 1);
00779 init = 1;
00780 }
00781
00782
00783 px -= LIGHTX*pz;
00784 py -= LIGHTY*pz;
00785
00786 const double kx = 0.96592582628907f;
00787 const double ky = 0.25881904510252f;
00788 double x=radius, y=0;
00789
00790 glBegin (GL_TRIANGLE_FAN);
00791 for (int i=0; i<24; i++) {
00792
00793 double x2 = (LIGHTX*x*scale - LIGHTY*y)*len1 + px;
00794 double y2 = (LIGHTY*x*scale + LIGHTX*y)*len1 + py;
00795 glTexCoord2f (x2*ground_scale+ground_ofsx,y2*ground_scale+ground_ofsy);
00796 glVertex3f (x2,y2,0);
00797
00798
00799 double xtmp = kx*x - ky*y;
00800 y = ky*x + kx*y;
00801 x = xtmp;
00802 }
00803 glEnd();
00804 }
00805
00806
00807 void ViewPort::drawTriangle (const double *v0, const double *v1, const double *v2, int solid)
00808 {
00809 float u[3],v[3],normal[3];
00810 u[0] = v1[0] - v0[0];
00811 u[1] = v1[1] - v0[1];
00812 u[2] = v1[2] - v0[2];
00813 v[0] = v2[0] - v0[0];
00814 v[1] = v2[1] - v0[1];
00815 v[2] = v2[2] - v0[2];
00816
00817 normal[0] = (u[1]*v[2] - u[2]*v[1]);
00818 normal[1] = (u[2]*v[0] - u[0]*v[2]);
00819 normal[2] = (u[0]*v[1] - u[1]*v[0]);
00820
00821 normalizeVector3 (normal);
00822
00823 glBegin(solid ? GL_TRIANGLES : GL_LINE_STRIP);
00824 glNormal3fv (normal);
00825 glVertex3dv (v0);
00826 glVertex3dv (v1);
00827 glVertex3dv (v2);
00828 glEnd();
00829 }
00830
00831 void ViewPort::drawTriangleD (const double *v0, const double *v1, const double *v2, int solid)
00832 {
00833 float u[3],v[3],normal[3];
00834 u[0] = double( v1[0] - v0[0] );
00835 u[1] = double( v1[1] - v0[1] );
00836 u[2] = double( v1[2] - v0[2] );
00837 v[0] = double( v2[0] - v0[0] );
00838 v[1] = double( v2[1] - v0[1] );
00839 v[2] = double( v2[2] - v0[2] );
00840
00841 normal[0] = (u[1]*v[2] - u[2]*v[1]);
00842 normal[1] = (u[2]*v[0] - u[0]*v[2]);
00843 normal[2] = (u[0]*v[1] - u[1]*v[0]);
00844
00845 normalizeVector3 (normal);
00846
00847 glBegin(solid ? GL_TRIANGLES : GL_LINE_STRIP);
00848 glNormal3fv (normal);
00849 glVertex3dv (v0);
00850 glVertex3dv (v1);
00851 glVertex3dv (v2);
00852 glEnd();
00853 }
00854
00855
00856
00857
00858 void ViewPort::drawCappedCylinder (double l, double r)
00859 {
00860 int i,j;
00861 double tmp,nx,ny,nz,start_nx,start_ny,a,ca,sa;
00862
00863 const int n = capped_cylinder_quality*4;
00864
00865 l *= 0.5;
00866 a = double(M_PI*2.0)/double(n);
00867 sa = (double) sin(a);
00868 ca = (double) cos(a);
00869
00870
00871 ny=1; nz=0;
00872 glBegin (GL_TRIANGLE_STRIP);
00873 for (i=0; i<=n; i++) {
00874 glNormal3d (ny,nz,0);
00875 glVertex3d (ny*r,nz*r,l);
00876 glNormal3d (ny,nz,0);
00877 glVertex3d (ny*r,nz*r,-l);
00878
00879 tmp = ca*ny - sa*nz;
00880 nz = sa*ny + ca*nz;
00881 ny = tmp;
00882 }
00883 glEnd();
00884
00885
00886 start_nx = 0;
00887 start_ny = 1;
00888 for (j=0; j<(n/4); j++) {
00889
00890 double start_nx2 = ca*start_nx + sa*start_ny;
00891 double start_ny2 = -sa*start_nx + ca*start_ny;
00892
00893 nx = start_nx; ny = start_ny; nz = 0;
00894 double nx2 = start_nx2, ny2 = start_ny2, nz2 = 0;
00895 glBegin (GL_TRIANGLE_STRIP);
00896 for (i=0; i<=n; i++) {
00897 glNormal3d (ny2,nz2,nx2);
00898 glVertex3d (ny2*r,nz2*r,l+nx2*r);
00899 glNormal3d (ny,nz,nx);
00900 glVertex3d (ny*r,nz*r,l+nx*r);
00901
00902 tmp = ca*ny - sa*nz;
00903 nz = sa*ny + ca*nz;
00904 ny = tmp;
00905 tmp = ca*ny2- sa*nz2;
00906 nz2 = sa*ny2 + ca*nz2;
00907 ny2 = tmp;
00908 }
00909 glEnd();
00910 start_nx = start_nx2;
00911 start_ny = start_ny2;
00912 }
00913
00914
00915 start_nx = 0;
00916 start_ny = 1;
00917 for (j=0; j<(n/4); j++) {
00918
00919 double start_nx2 = ca*start_nx - sa*start_ny;
00920 double start_ny2 = sa*start_nx + ca*start_ny;
00921
00922 nx = start_nx; ny = start_ny; nz = 0;
00923 double nx2 = start_nx2, ny2 = start_ny2, nz2 = 0;
00924 glBegin (GL_TRIANGLE_STRIP);
00925 for (i=0; i<=n; i++) {
00926 glNormal3d (ny,nz,nx);
00927 glVertex3d (ny*r,nz*r,-l+nx*r);
00928 glNormal3d (ny2,nz2,nx2);
00929 glVertex3d (ny2*r,nz2*r,-l+nx2*r);
00930
00931 tmp = ca*ny - sa*nz;
00932 nz = sa*ny + ca*nz;
00933 ny = tmp;
00934 tmp = ca*ny2- sa*nz2;
00935 nz2 = sa*ny2 + ca*nz2;
00936 ny2 = tmp;
00937 }
00938 glEnd();
00939 start_nx = start_nx2;
00940 start_ny = start_ny2;
00941 }
00942
00943 glPopMatrix();
00944 }
00945
00946
00947
00948
00949 void ViewPort::drawCylinder (double l, double r, double zoffset)
00950 {
00951 int i;
00952 double tmp,ny,nz,a,ca,sa;
00953 const int n = 24;
00954
00955 l *= 0.5;
00956 a = double(M_PI*2.0)/double(n);
00957 sa = (double) sin(a);
00958 ca = (double) cos(a);
00959
00960
00961 ny=1; nz=0;
00962 glBegin (GL_TRIANGLE_STRIP);
00963 for (i=0; i<=n; i++) {
00964 glNormal3d (ny,nz,0);
00965 glVertex3d (ny*r,nz*r,l+zoffset);
00966 glNormal3d (ny,nz,0);
00967 glVertex3d (ny*r,nz*r,-l+zoffset);
00968
00969 tmp = ca*ny - sa*nz;
00970 nz = sa*ny + ca*nz;
00971 ny = tmp;
00972 }
00973 glEnd();
00974
00975
00976 glShadeModel (GL_FLAT);
00977 ny=1; nz=0;
00978 glBegin (GL_TRIANGLE_FAN);
00979 glNormal3d (0,0,1);
00980 glVertex3d (0,0,l+zoffset);
00981 for (i=0; i<=n; i++) {
00982 if (i==1 || i==n/2+1)
00983 setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]);
00984 glNormal3d (0,0,1);
00985 glVertex3d (ny*r,nz*r,l+zoffset);
00986 if (i==1 || i==n/2+1)
00987 setColor (color[0],color[1],color[2],color[3]);
00988
00989
00990 tmp = ca*ny - sa*nz;
00991 nz = sa*ny + ca*nz;
00992 ny = tmp;
00993 }
00994 glEnd();
00995
00996
00997 ny=1; nz=0;
00998 glBegin (GL_TRIANGLE_FAN);
00999 glNormal3d (0,0,-1);
01000 glVertex3d (0,0,-l+zoffset);
01001 for (i=0; i<=n; i++) {
01002 if (i==1 || i==n/2+1)
01003 setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]);
01004 glNormal3d (0,0,-1);
01005 glVertex3d (ny*r,nz*r,-l+zoffset);
01006 if (i==1 || i==n/2+1)
01007 setColor (color[0],color[1],color[2],color[3]);
01008
01009
01010 tmp = ca*ny + sa*nz;
01011 nz = -sa*ny + ca*nz;
01012 ny = tmp;
01013 }
01014 glEnd();
01015 }
01016
01017
01018
01019
01020
01021
01022 void ViewPort::initMotionModel()
01023 {
01024 view_xyz[0] = 2;
01025 view_xyz[1] = 0;
01026 view_xyz[2] = 1;
01027 view_hpr[0] = 180;
01028 view_hpr[1] = 0;
01029 view_hpr[2] = 0;
01030 }
01031
01032
01033 void ViewPort::wrapCameraAngles()
01034 {
01035 for (int i=0; i<3; i++) {
01036 while (view_hpr[i] > 180) view_hpr[i] -= 360;
01037 while (view_hpr[i] < -180) view_hpr[i] += 360;
01038 }
01039 }
01040
01041
01042
01043
01044
01045
01046 void ViewPort::dsMotion (int mode, int deltax, int deltay)
01047 {
01048 double side = 0.01f * double(deltax);
01049 double fwd = (mode==4) ? (0.01f * double(deltay)) : 0.0f;
01050 double s = (double) sin (view_hpr[0]*DEG_TO_RAD);
01051 double c = (double) cos (view_hpr[0]*DEG_TO_RAD);
01052
01053 LINFO("Movde %i", mode);
01054 switch(mode)
01055 {
01056 case 1:
01057 view_hpr[0] += double (deltax) * 0.5f;
01058 view_hpr[1] += double (deltay) * 0.5f;
01059 break;
01060 case 2:
01061 case 5:
01062 view_xyz[2] += 0.01f * double(deltay);
01063 view_hpr[2] += double (deltax) * 0.5f;
01064 break;
01065 case 4:
01066 view_xyz[0] += -s*side + c*fwd;
01067 view_xyz[1] += c*side + s*fwd;
01068 break;
01069
01070 }
01071 wrapCameraAngles();
01072
01073 LINFO("Camera pos:(%f,%f,%f) Rot:(%f,%f,%f)",
01074 view_xyz[0], view_xyz[1], view_xyz[2],
01075 view_hpr[0], view_hpr[1], view_hpr[2]);
01076
01077 }
01078
01079
01080
01081
01082 void ViewPort::drawSky (double view_xyz[3])
01083 {
01084 glDisable (GL_LIGHTING);
01085 if (use_textures && sky_texture->initialized()) {
01086 glEnable (GL_TEXTURE_2D);
01087 sky_texture->bind (0);
01088 }
01089 else {
01090 glDisable (GL_TEXTURE_2D);
01091 glColor3f (0,0.5,1.0);
01092 }
01093
01094
01095 glShadeModel (GL_FLAT);
01096 glEnable (GL_DEPTH_TEST);
01097 glDepthFunc (GL_LEQUAL);
01098 glDepthRange (1,1);
01099
01100 const double ssize = 1000.0f;
01101 static double offset = 0.0f;
01102
01103 double x = ssize*sky_scale;
01104 double z = view_xyz[2] + sky_height;
01105
01106 glBegin (GL_QUADS);
01107 glNormal3f (0,0,-1);
01108 glTexCoord2f (-x+offset,-x+offset);
01109 glVertex3f (-ssize+view_xyz[0],-ssize+view_xyz[1],z);
01110 glTexCoord2f (-x+offset,x+offset);
01111 glVertex3f (-ssize+view_xyz[0],ssize+view_xyz[1],z);
01112 glTexCoord2f (x+offset,x+offset);
01113 glVertex3f (ssize+view_xyz[0],ssize+view_xyz[1],z);
01114 glTexCoord2f (x+offset,-x+offset);
01115 glVertex3f (ssize+view_xyz[0],-ssize+view_xyz[1],z);
01116 glEnd();
01117
01118 offset = offset + 0.001f;
01119 if (offset > 1) offset -= 1;
01120
01121 glDepthFunc (GL_LESS);
01122 glDepthRange (0,1);
01123 }
01124
01125
01126 void ViewPort::drawGround()
01127 {
01128 glDisable (GL_LIGHTING);
01129 glShadeModel (GL_FLAT);
01130 glEnable (GL_DEPTH_TEST);
01131 glDepthFunc (GL_LESS);
01132
01133
01134 if (use_textures) {
01135 glEnable (GL_TEXTURE_2D);
01136 ground_texture->bind (0);
01137 }
01138 else {
01139 glDisable (GL_TEXTURE_2D);
01140 glColor3f (GROUND_R,GROUND_G,GROUND_B);
01141 }
01142
01143 if (itsUseFog)
01144 {
01145
01146
01147 GLfloat fogColor[4] = {0.0, 0.2, 0.1, 1};
01148 glEnable (GL_FOG);
01149 glFogi (GL_FOG_MODE, GL_LINEAR);
01150 glFogfv (GL_FOG_COLOR, fogColor);
01151 glFogf (GL_FOG_DENSITY, 0.07f);
01152 glHint (GL_FOG_HINT, GL_NICEST);
01153 glFogf (GL_FOG_START, 0.0);
01154 glFogf (GL_FOG_END, 10.0);
01155 }
01156
01157
01158 const double gsize = 100.0f;
01159 const double offset = 0;
01160
01161 glBegin (GL_QUADS);
01162 glNormal3f (0,0,1);
01163
01164 glTexCoord2f (-gsize*ground_scale + ground_ofsx,
01165 -gsize*ground_scale + ground_ofsy);
01166 glVertex3f (-gsize,-gsize,offset);
01167
01168 glTexCoord2f (gsize*ground_scale + ground_ofsx,
01169 -gsize*ground_scale + ground_ofsy);
01170 glVertex3f (gsize,-gsize,offset);
01171
01172 glTexCoord2f (gsize*ground_scale + ground_ofsx,
01173 gsize*ground_scale + ground_ofsy);
01174 glVertex3f (gsize,gsize,offset);
01175
01176 glTexCoord2f (-gsize*ground_scale + ground_ofsx,
01177 gsize*ground_scale + ground_ofsy);
01178 glVertex3f (-gsize,gsize,offset);
01179 glEnd();
01180
01181
01182
01183 }
01184
01185
01186 void ViewPort::drawPyramidGrid()
01187 {
01188
01189 glEnable (GL_LIGHTING);
01190 glDisable (GL_TEXTURE_2D);
01191 glShadeModel (GL_FLAT);
01192 glEnable (GL_DEPTH_TEST);
01193 glDepthFunc (GL_LESS);
01194
01195
01196 for (int i=-1; i<=1; i++) {
01197 for (int j=-1; j<=1; j++) {
01198 glPushMatrix();
01199 glTranslatef ((double)i,(double)j,(double)0);
01200 if (i==1 && j==0) setColor (1,0,0,1);
01201 else if (i==0 && j==1) setColor (0,0,1,1);
01202 else setColor (1,1,0,1);
01203 const double k = 0.03f;
01204 glBegin (GL_TRIANGLE_FAN);
01205 glNormal3f (0,-1,1);
01206 glVertex3f (0,0,k);
01207 glVertex3f (-k,-k,0);
01208 glVertex3f ( k,-k,0);
01209 glNormal3f (1,0,1);
01210 glVertex3f ( k, k,0);
01211 glNormal3f (0,1,1);
01212 glVertex3f (-k, k,0);
01213 glNormal3f (-1,0,1);
01214 glVertex3f (-k,-k,0);
01215 glEnd();
01216 glPopMatrix();
01217 }
01218 }
01219 }
01220
01221
01222 void ViewPort::dsDrawFrame (const double cameraParam[16])
01223 {
01224 glXMakeCurrent (display,win,glx_context);
01225
01226 glEnable (GL_LIGHTING);
01227 glEnable (GL_LIGHT0);
01228 glDisable (GL_TEXTURE_2D);
01229 glDisable (GL_TEXTURE_GEN_S);
01230 glDisable (GL_TEXTURE_GEN_T);
01231 glShadeModel (GL_FLAT);
01232 glEnable (GL_DEPTH_TEST);
01233 glDepthFunc (GL_LESS);
01234 glEnable (GL_CULL_FACE);
01235 glCullFace (GL_BACK);
01236 glFrontFace (GL_CCW);
01237
01238 if (itsWireframe)
01239 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
01240
01241
01242 glMatrixMode(GL_MODELVIEW);
01243 glLoadIdentity();
01244
01245 glViewport (0,0,itsWidth,itsHeight);
01246
01247 glMatrixMode (GL_PROJECTION);
01248
01249 if (itsProjMatrix==NULL)
01250 {
01251 glLoadIdentity();
01252 const double vnear = 50.1f;
01253 const double vfar = 5000.0f;
01254 const double k = itsZoomFactor;
01255
01256
01257 if (itsWidth >= itsHeight) {
01258 double k2 = double(itsHeight)/double(itsWidth);
01259 glFrustum (-vnear*k,vnear*k,-vnear*k*k2,vnear*k*k2,vnear,vfar);
01260 }
01261 else {
01262 double k2 = double(itsWidth)/double(itsHeight);
01263 glFrustum (-vnear*k*k2,vnear*k*k2,-vnear*k,vnear*k,vnear,vfar);
01264 }
01265 } else {
01266 glLoadMatrixd(itsProjMatrix);
01267 }
01268
01269
01270
01271
01272 static GLfloat light_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
01273 static GLfloat light_diffuse[] = { 0.0, 0.0, 0.0, 0.0 };
01274 static GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
01275 glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient);
01276 glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse);
01277 glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular);
01278 glColor3f (0.0, 0.0, 0.0);
01279
01280
01281 glClearColor (0.0,0.0,0.0,0);
01282 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01283
01284
01285 glMatrixMode (GL_MODELVIEW);
01286
01287 if (cameraParam==NULL)
01288 {
01289 glLoadIdentity();
01290 setCamera (view_xyz[0],view_xyz[1],view_xyz[2],
01291 view_hpr[0],view_hpr[1],view_hpr[2]);
01292 } else {
01293 glLoadMatrixd(cameraParam );
01294 }
01295
01296
01297
01298 static GLfloat light_position[] = { LIGHTX, LIGHTY, 5.0 };
01299 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light_position);
01300 glLightfv (GL_LIGHT0, GL_POSITION, light_position);
01301
01302
01303 if (itsDrawWorld)
01304 {
01305 drawSky (view_xyz);
01306 drawGround();
01307 }
01308
01309
01310
01311
01312
01313 glEnable (GL_LIGHTING);
01314 glDisable (GL_TEXTURE_2D);
01315 glShadeModel (GL_FLAT);
01316 glEnable (GL_DEPTH_TEST);
01317 glDepthFunc (GL_LESS);
01318 glColor3f (1,1,1);
01319 setColor (1,1,1,1);
01320
01321
01322 color[0] = 1;
01323 color[1] = 1;
01324 color[2] = 1;
01325 color[3] = 1;
01326 tnum = 0;
01327 }
01328
01329 int ViewPort::dsGetShadows()
01330 {
01331 return use_shadows;
01332 }
01333
01334
01335 void ViewPort::dsSetShadows (int a)
01336 {
01337 use_shadows = (a != 0);
01338 }
01339
01340
01341 int ViewPort::dsGetTextures()
01342 {
01343 return use_textures;
01344 }
01345
01346
01347 void ViewPort::dsSetTextures (int a)
01348 {
01349 use_textures = (a != 0);
01350 }
01351
01352
01353
01354
01355
01356 void ViewPort::setupDrawingMode()
01357 {
01358 glXMakeCurrent (display,win,glx_context);
01359
01360 glEnable (GL_LIGHTING);
01361 bool enableWrap = true;
01362 if (tnum) {
01363 if (use_textures) {
01364 glEnable (GL_TEXTURE_2D);
01365
01366 switch (tnum)
01367 {
01368 case SKY:
01369 sky_texture->bind (1);
01370 enableWrap = true;
01371 break;
01372 case GROUND:
01373 ground_texture->bind (1);
01374 enableWrap = true;
01375 break;
01376 case WOOD:
01377 wood_texture->bind (1);
01378 enableWrap = true;
01379 break;
01380 case TREE:
01381 tree_texture->bind (1);
01382 enableWrap = true;
01383 break;
01384 case OTHER:
01385 if (other_texture)
01386 other_texture->bind (1);
01387
01388
01389 enableWrap = false;
01390 break;
01391 default:
01392 LINFO("Unknown Texture %i", tnum);
01393 break;
01394 }
01395
01396 if (enableWrap)
01397 {
01398 glEnable (GL_TEXTURE_GEN_S);
01399 glEnable (GL_TEXTURE_GEN_T);
01400 glTexGeni (GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
01401 glTexGeni (GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
01402 static GLfloat s_params[4] = {1.0f,1.0f,0.0f,1};
01403 static GLfloat t_params[4] = {0.817f,-0.817f,0.817f,1};
01404 glTexGenfv (GL_S,GL_OBJECT_PLANE,s_params);
01405 glTexGenfv (GL_T,GL_OBJECT_PLANE,t_params);
01406 }
01407 }
01408 else {
01409 glDisable (GL_TEXTURE_2D);
01410 }
01411 }
01412 else {
01413 glDisable (GL_TEXTURE_2D);
01414 }
01415 setColor (color[0],color[1],color[2],color[3]);
01416
01417 if (color[3] < 1) {
01418 glEnable (GL_BLEND);
01419 glBlendFunc (GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
01420 }
01421 else {
01422 glDisable (GL_BLEND);
01423 }
01424 }
01425
01426
01427 void ViewPort::setShadowDrawingMode()
01428 {
01429 glDisable (GL_LIGHTING);
01430 if (use_textures) {
01431 glEnable (GL_TEXTURE_2D);
01432 ground_texture->bind (1);
01433 glColor3f (SHADOW_INTENSITY,SHADOW_INTENSITY,SHADOW_INTENSITY);
01434 glEnable (GL_TEXTURE_2D);
01435 glEnable (GL_TEXTURE_GEN_S);
01436 glEnable (GL_TEXTURE_GEN_T);
01437 glTexGeni (GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
01438 glTexGeni (GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
01439 static GLfloat s_params[4] = {(GLfloat)ground_scale,0,0,(GLfloat)ground_ofsx};
01440 static GLfloat t_params[4] = {0,(GLfloat)ground_scale,0,(GLfloat)ground_ofsy};
01441 glTexGenfv (GL_S,GL_EYE_PLANE,s_params);
01442 glTexGenfv (GL_T,GL_EYE_PLANE,t_params);
01443 }
01444 else {
01445 glDisable (GL_TEXTURE_2D);
01446 glColor3f (GROUND_R*SHADOW_INTENSITY,GROUND_G*SHADOW_INTENSITY,
01447 GROUND_B*SHADOW_INTENSITY);
01448 }
01449 glDepthRange (0,0.9999);
01450 }
01451
01452
01453 void ViewPort::dsSetViewpoint (double xyz[3], double hpr[3])
01454 {
01455 if (xyz) {
01456 view_xyz[0] = xyz[0];
01457 view_xyz[1] = xyz[1];
01458 view_xyz[2] = xyz[2];
01459 }
01460 if (hpr) {
01461 view_hpr[0] = hpr[0];
01462 view_hpr[1] = hpr[1];
01463 view_hpr[2] = hpr[2];
01464 wrapCameraAngles();
01465 }
01466 }
01467
01468
01469 void ViewPort::dsGetViewpoint (double xyz[3], double hpr[3])
01470 {
01471 if (xyz) {
01472 xyz[0] = view_xyz[0];
01473 xyz[1] = view_xyz[1];
01474 xyz[2] = view_xyz[2];
01475 }
01476 if (hpr) {
01477 hpr[0] = view_hpr[0];
01478 hpr[1] = view_hpr[1];
01479 hpr[2] = view_hpr[2];
01480 }
01481 }
01482
01483
01484 void ViewPort::dsSetTexture (TEXTURES texture_number, Texture* texturePtr)
01485 {
01486 tnum = texture_number;
01487 if (texturePtr)
01488 other_texture = texturePtr;
01489 }
01490
01491
01492 void ViewPort::dsSetColor (double red, double green, double blue)
01493 {
01494 color[0] = red;
01495 color[1] = green;
01496 color[2] = blue;
01497 color[3] = 1;
01498 }
01499
01500
01501 void ViewPort::dsSetColorAlpha (double red, double green, double blue,
01502 double alpha)
01503 {
01504 color[0] = red;
01505 color[1] = green;
01506 color[2] = blue;
01507 color[3] = alpha;
01508 }
01509
01510
01511 void ViewPort::dsDrawBox (const double pos[3], const double R[12],
01512 const double sides[3])
01513 {
01514
01515 setupDrawingMode();
01516 glShadeModel (GL_FLAT);
01517 setTransform (pos,R);
01518 drawBox (sides);
01519 glPopMatrix();
01520
01521 if (use_shadows) {
01522 setShadowDrawingMode();
01523 setShadowTransform();
01524 setTransform (pos,R);
01525 drawBox (sides);
01526 glPopMatrix();
01527 glPopMatrix();
01528 glDepthRange (0,1);
01529 }
01530 }
01531
01532
01533 void ViewPort::dsDrawSphere (const double pos[3], const double R[12],
01534 double radius)
01535 {
01536 setupDrawingMode();
01537 glEnable (GL_NORMALIZE);
01538 glShadeModel (GL_SMOOTH);
01539 setTransform (pos,R);
01540 glScaled (radius,radius,radius);
01541 drawSphere();
01542 glPopMatrix();
01543 glDisable (GL_NORMALIZE);
01544
01545
01546 if (use_shadows) {
01547 glDisable (GL_LIGHTING);
01548 if (use_textures) {
01549 ground_texture->bind (1);
01550 glEnable (GL_TEXTURE_2D);
01551 glDisable (GL_TEXTURE_GEN_S);
01552 glDisable (GL_TEXTURE_GEN_T);
01553 glColor3f (SHADOW_INTENSITY,SHADOW_INTENSITY,SHADOW_INTENSITY);
01554 }
01555 else {
01556 glDisable (GL_TEXTURE_2D);
01557 glColor3f (GROUND_R*SHADOW_INTENSITY,GROUND_G*SHADOW_INTENSITY,
01558 GROUND_B*SHADOW_INTENSITY);
01559 }
01560 glShadeModel (GL_FLAT);
01561 glDepthRange (0,0.9999);
01562 drawSphereShadow (pos[0],pos[1],pos[2],radius);
01563 glDepthRange (0,1);
01564 }
01565 }
01566
01567 void ViewPort::dsDrawTriangle (const double pos[3], const double R[12],
01568 const double *v0, const double *v1,
01569 const double *v2, int solid)
01570 {
01571 setupDrawingMode();
01572 glShadeModel (GL_FLAT);
01573 setTransform (pos,R);
01574 drawTriangle (v0, v1, v2, solid);
01575 glPopMatrix();
01576 }
01577
01578
01579 void ViewPort::dsDrawCylinder (const double pos[3], const double R[12],
01580 double length, double radius)
01581 {
01582 setupDrawingMode();
01583 glShadeModel (GL_SMOOTH);
01584 setTransform (pos,R);
01585 drawCylinder (length,radius,0);
01586 glPopMatrix();
01587
01588 if (use_shadows) {
01589 setShadowDrawingMode();
01590 setShadowTransform();
01591 setTransform (pos,R);
01592 drawCylinder (length,radius,0);
01593 glPopMatrix();
01594 glPopMatrix();
01595 glDepthRange (0,1);
01596 }
01597 }
01598
01599
01600 void ViewPort::dsDrawCappedCylinder (const double pos[3], const double R[12],
01601 double length, double radius)
01602 {
01603 setupDrawingMode();
01604 glShadeModel (GL_SMOOTH);
01605 setTransform (pos,R);
01606 drawCappedCylinder (length,radius);
01607 glPopMatrix();
01608
01609 if (use_shadows) {
01610 setShadowDrawingMode();
01611 setShadowTransform();
01612 setTransform (pos,R);
01613 drawCappedCylinder (length,radius);
01614 glPopMatrix();
01615 glPopMatrix();
01616 glDepthRange (0,1);
01617 }
01618 }
01619
01620
01621 void ViewPort::dsDrawLine (const double pos1[3], const double pos2[3])
01622 {
01623 setupDrawingMode();
01624 glColor3f (color[0],color[1],color[2]);
01625 glDisable (GL_LIGHTING);
01626 glLineWidth (2);
01627 glShadeModel (GL_FLAT);
01628 glBegin (GL_LINES);
01629 glVertex3f (pos1[0],pos1[1],pos1[2]);
01630 glVertex3f (pos2[0],pos2[1],pos2[2]);
01631 glVertex3f (pos1[0],pos1[1],pos1[2]);
01632 glVertex3f (pos2[0],pos2[1],pos2[2]);
01633 glEnd();
01634 }
01635
01636
01637 void ViewPort::dsDrawBoxD (const double pos[3], const double R[12],
01638 const double sides[3])
01639 {
01640 int i;
01641 double pos2[3],R2[12],fsides[3];
01642 for (i=0; i<3; i++) pos2[i]=(double)pos[i];
01643 for (i=0; i<12; i++) R2[i]=(double)R[i];
01644 for (i=0; i<3; i++) fsides[i]=(double)sides[i];
01645 dsDrawBox (pos2,R2,fsides);
01646 }
01647
01648
01649 void ViewPort::dsDrawSphereD (const double pos[3], const double R[12], double radius)
01650 {
01651 int i;
01652 double pos2[3],R2[12];
01653 for (i=0; i<3; i++) pos2[i]=(double)pos[i];
01654 for (i=0; i<12; i++) R2[i]=(double)R[i];
01655 dsDrawSphere (pos2,R2,radius);
01656 }
01657
01658
01659 void ViewPort::dsDrawTriangleD (const double pos[3], const double R[12],
01660 const double *v0, const double *v1,
01661 const double *v2, int solid)
01662 {
01663 int i;
01664 double pos2[3],R2[12];
01665 for (i=0; i<3; i++) pos2[i]=(double)pos[i];
01666 for (i=0; i<12; i++) R2[i]=(double)R[i];
01667
01668 setupDrawingMode();
01669 glShadeModel (GL_FLAT);
01670 setTransform (pos2,R2);
01671 drawTriangleD (v0, v1, v2, solid);
01672 glPopMatrix();
01673 }
01674
01675
01676 void ViewPort::dsDrawCylinderD (const double pos[3], const double R[12],
01677 double length, double radius)
01678 {
01679 int i;
01680 double pos2[3],R2[12];
01681 for (i=0; i<3; i++) pos2[i]=(double)pos[i];
01682 for (i=0; i<12; i++) R2[i]=(double)R[i];
01683 dsDrawCylinder (pos2,R2,length,radius);
01684 }
01685
01686
01687 void ViewPort::dsDrawCappedCylinderD (const double pos[3], const double R[12],
01688 double length, double radius)
01689 {
01690 int i;
01691 double pos2[3],R2[12];
01692 for (i=0; i<3; i++) pos2[i]=(double)pos[i];
01693 for (i=0; i<12; i++) R2[i]=(double)R[i];
01694 dsDrawCappedCylinder (pos2,R2,length,radius);
01695 }
01696
01697
01698 void ViewPort::dsDrawLineD (const double _pos1[3], const double _pos2[3])
01699 {
01700 int i;
01701 double pos1[3],pos2[3];
01702 for (i=0; i<3; i++) pos1[i]=(double)_pos1[i];
01703 for (i=0; i<3; i++) pos2[i]=(double)_pos2[i];
01704 dsDrawLine (pos1,pos2);
01705 }
01706
01707
01708 void ViewPort::dsSetSphereQuality (int n)
01709 {
01710 sphere_quality = n;
01711 }
01712
01713
01714 void ViewPort::dsSetCappedCylinderQuality (int n)
01715 {
01716 capped_cylinder_quality = n;
01717 }
01718
01719
01720
01721
01722 ViewPort::DSObject ViewPort::load3DSObject(const char*filename, const char* textureFile)
01723 {
01724
01725 DSObject p_object;
01726 int i;
01727
01728
01729 if (textureFile)
01730 {
01731 p_object.texture = new Texture(textureFile);
01732 } else {
01733 p_object.texture = NULL;
01734 }
01735
01736
01737
01738 FILE *l_file;
01739
01740 unsigned short l_chunk_id;
01741 unsigned int l_chunk_lenght;
01742
01743 unsigned char l_char;
01744 unsigned short l_qty;
01745
01746 unsigned short l_face_flags;
01747
01748 if ((l_file=fopen (filename, "rb"))== NULL)
01749 {
01750 LINFO("Can not open file %s", filename);
01751 return p_object;
01752 }
01753
01754
01755 struct stat buf;
01756 fstat(fileno(l_file), &buf);
01757 long filelength = buf.st_size;
01758
01759 while (ftell (l_file) < filelength)
01760 {
01761
01762
01763 if(fread (&l_chunk_id, 2, 1, l_file) != 1) LFATAL("fread failed");
01764
01765 if(fread (&l_chunk_lenght, 4, 1, l_file) != 1) LFATAL("fread failed");
01766
01767
01768 switch (l_chunk_id)
01769 {
01770
01771
01772
01773
01774
01775 case 0x4d4d:
01776 break;
01777
01778
01779
01780
01781
01782
01783 case 0x3d3d:
01784 break;
01785
01786
01787
01788
01789
01790
01791 case 0x4000:
01792 i=0;
01793 do
01794 {
01795 if(fread (&l_char, 1, 1, l_file) != 1) LFATAL("fread faile");
01796 p_object.name[i]=l_char;
01797 i++;
01798 }while(l_char != '\0' && i<20);
01799 break;
01800
01801
01802
01803
01804
01805
01806 case 0x4100:
01807 break;
01808
01809
01810
01811
01812
01813
01814
01815
01816 case 0x4110:
01817 if(fread (&l_qty, sizeof (unsigned short), 1, l_file) != 1) LFATAL("fread failed");
01818 p_object.vertices_qty = l_qty;
01819
01820 p_object.vertex.resize(l_qty);
01821 for (i=0; i<l_qty; i++)
01822 {
01823 if(fread (&p_object.vertex[i].x, sizeof(float), 1, l_file) != 1) LFATAL("fread failed");
01824
01825 if(fread (&p_object.vertex[i].y, sizeof(float), 1, l_file) != 1) LFATAL("fread failed");
01826
01827 if(fread (&p_object.vertex[i].z, sizeof(float), 1, l_file) != 1) LFATAL("fread failed");
01828
01829 }
01830 break;
01831
01832
01833
01834
01835
01836
01837
01838
01839 case 0x4120:
01840 if(fread (&l_qty, sizeof (unsigned short), 1, l_file) != 1) LFATAL("fread failed");
01841 p_object.polygons_qty = l_qty;
01842 p_object.polygon.resize(l_qty);
01843 printf("Number of polygons: %d\n",l_qty);
01844 for (i=0; i<l_qty; i++)
01845 {
01846 if(fread (&p_object.polygon[i].a, sizeof (unsigned short), 1, l_file) != 1) LFATAL("fread failed");
01847
01848 if(fread (&p_object.polygon[i].b, sizeof (unsigned short), 1, l_file) != 1) LFATAL("fread failed");
01849
01850 if(fread (&p_object.polygon[i].c, sizeof (unsigned short), 1, l_file) != 1) LFATAL("fread failed");
01851
01852 if(fread (&l_face_flags, sizeof (unsigned short), 1, l_file) != 1) LFATAL("fread failed");
01853
01854 }
01855 break;
01856
01857
01858
01859
01860
01861
01862
01863
01864 case 0x4140:
01865 if(fread (&l_qty, sizeof (unsigned short), 1, l_file) != 1) LFATAL("fread failed");
01866 p_object.mapcoord.resize(l_qty);
01867 for (i=0; i<l_qty; i++)
01868 {
01869 if(fread (&p_object.mapcoord[i].u, sizeof (float), 1, l_file) != 1) LFATAL("fread failed");
01870
01871 if(fread (&p_object.mapcoord[i].v, sizeof (float), 1, l_file) != 1) LFATAL("fread failed");
01872
01873 }
01874 break;
01875
01876
01877
01878
01879
01880
01881 default:
01882 fseek(l_file, l_chunk_lenght-6, SEEK_CUR);
01883 }
01884 }
01885 fclose (l_file);
01886
01887 return p_object;
01888 }
01889
01890
01891 int ViewPort::loadBitmap(const char*filename)
01892 {
01893 FILE * file;
01894 char temp;
01895 long i;
01896 int num_texture = 10;
01897
01898 BITMAPINFOHEADER infoheader;
01899
01900 if( (file = fopen(filename, "rb"))==NULL) return (-1);
01901
01902 fseek(file, 18, SEEK_CUR);
01903 if(fread(&infoheader.biWidth, sizeof(int), 1, file) != 1) LFATAL("fread failed");
01904
01905 if(fread(&infoheader.biHeight, sizeof(int), 1, file) != 1) LFATAL("fread failed");
01906
01907 if(fread(&infoheader.biPlanes, sizeof(short int), 1, file) != 1) LFATAL("fread failed");
01908 if (infoheader.biPlanes != 1) {
01909
01910 return 0;
01911 }
01912
01913
01914 if(fread(&infoheader.biBitCount, sizeof(unsigned short int), 1, file) != 1) LFATAL("fread failed");
01915 if (infoheader.biBitCount != 24) {
01916
01917 return 0;
01918 }
01919
01920 fseek(file, 24, SEEK_CUR);
01921
01922
01923 infoheader.data = (char *) malloc(infoheader.biWidth * infoheader.biHeight * 3);
01924 if (infoheader.data == NULL) {
01925
01926 return 0;
01927 }
01928
01929 if ((i = fread(infoheader.data, infoheader.biWidth * infoheader.biHeight * 3, 1, file)) != 1) {
01930
01931 return 0;
01932 }
01933
01934 for (i=0; i<(infoheader.biWidth * infoheader.biHeight * 3); i+=3) {
01935 temp = infoheader.data[i];
01936 infoheader.data[i] = infoheader.data[i+2];
01937 infoheader.data[i+2] = temp;
01938 }
01939
01940
01941 fclose(file);
01942
01943
01944 glBindTexture(GL_TEXTURE_2D, num_texture);
01945
01946
01947 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
01948 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
01949 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
01950 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
01951
01952 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
01953
01954
01955 glTexImage2D(GL_TEXTURE_2D, 0, 3, infoheader.biWidth, infoheader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, infoheader.data);
01956
01957
01958 #ifdef INVT_HAVE_LIBGLUT
01959 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, infoheader.biWidth, infoheader.biHeight, GL_RGB, GL_UNSIGNED_BYTE, infoheader.data);
01960 #endif
01961
01962 free(infoheader.data);
01963
01964 return (num_texture);
01965 }
01966
01967
01968 void ViewPort::dsDraw3DSObject(const double pos[3], const double R[12], DSObject& object)
01969 {
01970 if (object.texture != NULL)
01971 dsSetTexture (ViewPort::OTHER, object.texture);
01972
01973 setupDrawingMode();
01974 glEnable (GL_NORMALIZE);
01975 glShadeModel (GL_SMOOTH);
01976
01977 setTransform (pos,R);
01978 glScaled (object.scale,object.scale,object.scale);
01979 draw3dsObject(object);
01980 glPopMatrix();
01981 glDisable (GL_NORMALIZE);
01982
01983 }
01984
01985 void ViewPort::draw3dsObject(DSObject& object)
01986 {
01987 glBegin(GL_TRIANGLES);
01988
01989
01990 for (int l_index=0;l_index<object.polygons_qty;l_index++)
01991 {
01992
01993
01994 glTexCoord2f( object.mapcoord[ object.polygon[l_index].a ].u,
01995 object.mapcoord[ object.polygon[l_index].a ].v);
01996
01997 glVertex3f( object.vertex[ object.polygon[l_index].a ].x,
01998 object.vertex[ object.polygon[l_index].a ].y,
01999 object.vertex[ object.polygon[l_index].a ].z);
02000
02001
02002
02003 glTexCoord2f( object.mapcoord[ object.polygon[l_index].b ].u,
02004 object.mapcoord[ object.polygon[l_index].b ].v);
02005
02006 glVertex3f( object.vertex[ object.polygon[l_index].b ].x,
02007 object.vertex[ object.polygon[l_index].b ].y,
02008 object.vertex[ object.polygon[l_index].b ].z);
02009
02010
02011
02012 glTexCoord2f( object.mapcoord[ object.polygon[l_index].c ].u,
02013 object.mapcoord[ object.polygon[l_index].c ].v);
02014
02015 glVertex3f( object.vertex[ object.polygon[l_index].c ].x,
02016 object.vertex[ object.polygon[l_index].c ].y,
02017 object.vertex[ object.polygon[l_index].c ].z);
02018 }
02019 glEnd();
02020 glFlush();
02021
02022 }