Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

graphicmanager.cpp

00001 /***************************************************************************
00002                             graphicmanager.cpp  -  description
00003                                 -------------------
00004     begin                : dim sep 21 2003
00005     copyright            : (C) 2003-2006 by Duong-Khang NGUYEN
00006     email                : neoneurone @ users sourceforge net
00007     
00008     $Id: graphicmanager.cpp 63 2006-10-17 20:45:12Z neoneurone $
00009  ***************************************************************************/
00010 
00011 /***************************************************************************
00012  *                                                                         *
00013  *   This program is free software; you can redistribute it and/or modify  *
00014  *   it under the terms of the GNU General Public License as published by  *
00015  *   the Free Software Foundation; either version 2 of the License, or     *
00016  *   any later version.                                                    *
00017  *                                                                         *
00018  ***************************************************************************/
00019 
00020 #include "graphicmanager.h"
00021 #include "structure.h"
00022 #include "model.h"
00023 #include "modelloader.h"
00024 #include "movement.h"
00025 #include "agent.h"
00026 #include "conf.h"               // Parser for .conf file
00027 
00028 #include "globalvar.h"
00029 extern GlobalVar gVars;
00030 
00031 #include <cmath>                // For floorf
00032 #include <sstream>              // We use std::stringstream for data conversion
00033 
00034 
00035 static GLfloat red, green, blue;
00036 
00037 
00038    /*======================================================================*/
00039 GraphicManager::GraphicManager()
00040 {
00041     int i;                  // Used in for loop
00042 
00043     OPENCITY_DEBUG( "GraphicManager ctor" );
00044 
00045 // Initialize the model table
00046     for (i = 0; i < OC_GRAPHIC_CODE_MAX; i++ ) {
00047         tabpModel[i] = NULL;
00048     }
00049 
00050 
00051 // Load all the specified models
00052     Conf* pConf = new Conf();
00053     if (pConf->Open( ocHomeDirPrefix(OC_GRAPHISM_FILE_FILENAME) ) == OC_ERR_FREE) {
00054         string strPath;
00055         std::stringstream ss;
00056 
00057         for (i = 0; i < OC_GRAPHIC_CODE_MAX; i++ ) {
00058             ss.str("");
00059             ss << i;
00060             strPath = pConf->GetValue( ss.str() );
00061             if (strPath != "") {
00062                 tabpModel[i] = ModelLoader::Load( ocHomeDirPrefix(strPath) );
00063                 if (tabpModel[i] == NULL) {
00064                     cerr << "FATAL: Error in graphism config file, could not load file, see below: "     << endl
00065                          << ocHomeDirPrefix(strPath) << endl;
00066                     abort();
00067                 }
00068             }
00069         } // for
00070     }
00071     else {
00072         cerr << "FATAL: Error opening graphism config file. " << endl;
00073         abort();
00074     }
00075     delete pConf;
00076 }
00077 
00078 
00079    /*======================================================================*/
00080 GraphicManager::~GraphicManager()
00081 {
00082     OPENCITY_DEBUG( "GraphicManager dtor" );
00083 
00084     for (int i = 0; i < OC_GRAPHIC_CODE_MAX; i++ ) {
00085         delete tabpModel[i];    // delete NULL won't hurt
00086         tabpModel[i] = NULL;    // safe
00087     }
00088 }
00089 
00090 
00091    /*======================================================================*/
00092 const uint
00093 GraphicManager::GetSelection(
00094     const uint & rcuiWinX,
00095     const uint & rcuiWinY ) const
00096 {
00097     static GLubyte rgbTab[3];
00098     static GLshort uiValue = 0;
00099     static GLfloat fValue = .0;
00100 
00101 //---- read the back buffer, double-buffering must be supported !
00102 //  glReadBuffer( GL_BACK );
00103 // 32 bits
00104     glReadPixels( rcuiWinX, rcuiWinY, 1, 1, GL_RGB, GL_FLOAT, &fValue );
00105     glReadPixels( rcuiWinX, rcuiWinY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, rgbTab );
00106     glReadPixels( rcuiWinX, rcuiWinY, 1, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, &uiValue );
00107 
00108 //debug begins
00109     cout << "WinX: " << rcuiWinX << "/ WinY: " << rcuiWinY << endl;
00110     cout << "RGB got: " << (int)rgbTab[0] << "/" << (int)rgbTab[1] << "/" << (int)rgbTab[2]
00111          << "/ Float code: " << fValue
00112          << "/ Uint code: " << uiValue;
00113     if (glGetError() != GL_NO_ERROR) {
00114         cout << "OMG: bug !" << endl;
00115     }
00116 
00117 //debug ends
00118 
00119 // 32 bpp
00120     return ((rgbTab[0] << 16) + (rgbTab[1] << 8) + rgbTab[2]);
00121 // 16 bpp
00122 //  return ((rgbTab[0] << 11) + (rgbTab[1] << 5) + rgbTab[2]);
00123 //  return uiValue;
00124 }
00125 
00126 
00127    /*======================================================================*/
00128 void
00129 GraphicManager::DisplayTerrain(
00130     const uint & rcuiW,
00131     const uint & rcuiL ) const
00132 {
00133     static OC_BYTE tabH [4];
00134     static GLfloat ax, ay, az;
00135     static GLfloat bx, by, bz;
00136     static GLfloat nx, ny, nz;
00137 
00138     gVars.gpMapMgr->GetSquareHeight( rcuiW, rcuiL, tabH );
00139 
00140 //debug begin
00141 /*
00142 cout << (int)tabH[0] << ":"
00143      << (int)tabH[1] << ":"
00144      << (int)tabH[2] << ":"
00145      << (int)tabH[3] << ":"
00146      << endl;
00147 */
00148 //debug end
00149 
00150 //WARNING: GL_COLOR_MATERIAL is enabled
00151     glColor3f( .25, .2, .15 );
00152 
00153 // do we need to calculate the new normal ?
00154     if ((tabH[0] == tabH[1]) && (tabH[1] == tabH[2]) && (tabH[2] == tabH[3])) {
00155         glVertex3i( rcuiW,   tabH[0], rcuiL );
00156         glVertex3i( rcuiW,   tabH[1], rcuiL+1 );
00157         glVertex3i( rcuiW+1, tabH[2], rcuiL+1 );
00158         glVertex3i( rcuiW+1, tabH[3], rcuiL );
00159     }
00160     else {
00161     // calculate the new normal (the cross product)
00162         ax = .0; ay = (GLfloat)tabH[2]; az = 1.;
00163         bx = 1.; by = (GLfloat)tabH[1]; bz = .0;
00164 
00165         nx = by;
00166         ny = 1.;
00167         nz = ay;
00168         glNormal3f( nx, ny, nz );
00169 /*
00170         cx = ay * bz - by * az;
00171         cy = bx * az - ax * bz;
00172         cz = ax * by - bx * ay;
00173 */
00174 
00175     // draw the stuff
00176         glVertex3i( rcuiW,   tabH[0], rcuiL );
00177         glVertex3i( rcuiW,   tabH[1], rcuiL+1 );
00178         glVertex3i( rcuiW+1, tabH[2], rcuiL+1 );
00179         glVertex3i( rcuiW+1, tabH[3], rcuiL );
00180 
00181     // then restore the default normal
00182         glNormal3f( 0., 0., 1. );
00183     }
00184 }
00185 
00186 
00187    /*======================================================================*/
00188 void
00189 GraphicManager::DisplayStructure(
00190     const Structure* pcStructure,
00191     const uint & rcuiW,
00192     const uint & rcuiL ) const
00193 {
00194     static OPENCITY_GRAPHIC_CODE enumGC;
00195     static OC_BYTE tabH [4];
00196     static GLfloat delta;
00197 
00198 //NOTE: avoid segfault
00199     assert( pcStructure != NULL );
00200 
00201 // Get the heights from the map manager
00202     gVars.gpMapMgr->GetSquareHeight( rcuiW, rcuiL, tabH );
00203 
00204 // get the level of the structure
00205     delta = (GLfloat)(pcStructure->GetLevel() + 1) / 20;
00206 
00207 /* debug test for the electricity conductivity
00208     if (pcStructure->IsSet( OC_STRUCTURE_E ))
00209         redE = .15; //20
00210     else
00211         redE = .0;
00212 */
00213 
00214 
00215 // Get the graphic code
00216     enumGC = pcStructure->GetGraphicCode();
00217     
00218 //NOTE: null pointer can lead to SIGSEGV
00219     assert( (enumGC == OC_EMPTY) || (tabpModel[enumGC] != NULL) );
00220 
00221 //NOTE: the "switch" instruction will be removed once we have enough models
00222     switch (enumGC) {
00223         case OC_RES_ZONE0:
00224         case OC_RES_ZONE1:
00225         case OC_RES_ZONE2:
00226         case OC_RES_ZONE3:
00227         case OC_RES_ZONE4:
00228         case OC_RES_ZONE5:
00229         case OC_RES_ZONE6:
00230         case OC_RES_ZONE7:
00231         case OC_RES_ZONE8:
00232         case OC_RES_ZONE9:
00233 
00234         case OC_COM_ZONE0:
00235         case OC_COM_ZONE1:
00236         case OC_COM_ZONE2:
00237         case OC_COM_ZONE3:
00238         case OC_COM_ZONE4:
00239         case OC_COM_ZONE5:
00240         case OC_COM_ZONE6:
00241         case OC_COM_ZONE7:
00242         case OC_COM_ZONE8:
00243         case OC_COM_ZONE9:
00244 
00245         case OC_IND_ZONE0:
00246         case OC_IND_ZONE1:
00247         case OC_IND_ZONE2:
00248         case OC_IND_ZONE3:
00249         case OC_IND_ZONE4:
00250         case OC_IND_ZONE5:
00251         case OC_IND_ZONE6:
00252         case OC_IND_ZONE7:
00253         case OC_IND_ZONE8:
00254         case OC_IND_ZONE9:
00255 
00256         case OC_PARK0:
00257         case OC_TREE_FIR:
00258         case OC_TREE_007:
00259         case OC_TREE_PEKINGWILLOW:
00260         case OC_TREE_PINE1:
00261         case OC_TREE_PINE2:
00262             tabpModel[enumGC]->DisplayList( rcuiW, rcuiL, tabH );
00263             break;
00264 
00265     // Road part
00266         case OC_ROAD_O_N:
00267         case OC_ROAD_O_E:
00268         case OC_ROAD_O_S:
00269         case OC_ROAD_O_W:
00270         case OC_ROAD_S_N:
00271         case OC_ROAD_W_E:
00272         case OC_ROAD_N_E:
00273         case OC_ROAD_N_W:
00274         case OC_ROAD_S_E:
00275         case OC_ROAD_S_W:
00276         case OC_ROAD_S_N_E:
00277         case OC_ROAD_S_W_E:
00278         case OC_ROAD_S_N_W:
00279         case OC_ROAD_N_W_E:
00280         case OC_ROAD_S_N_W_E:
00281             tabpModel[enumGC]->Display2( rcuiW, rcuiL, tabH );
00282 //          tabpModel[enumGC]->DisplayList( rcuiW, rcuiL, tabH );
00283             break;
00284 
00285     // Electric lines part
00286         case OC_ELINE_O_N:
00287         case OC_ELINE_O_E:
00288         case OC_ELINE_O_S:
00289         case OC_ELINE_O_W:
00290         case OC_ELINE_S_N:
00291         case OC_ELINE_W_E:
00292         case OC_ELINE_N_E:
00293         case OC_ELINE_N_W:
00294         case OC_ELINE_S_E:
00295         case OC_ELINE_S_W:
00296         case OC_ELINE_S_N_E:
00297         case OC_ELINE_S_W_E:
00298         case OC_ELINE_S_N_W:
00299         case OC_ELINE_N_W_E:
00300         case OC_ELINE_S_N_W_E:
00301             tabpModel[enumGC]->DisplayList( rcuiW, rcuiL, tabH );
00302             break;
00303 
00304         case OC_EPLANT_COAL_BOX:
00305         case OC_FIRE_DEPT:
00306         case OC_POLICE_DEPT:
00307         case OC_HOSPITAL_DEPT:
00308         case OC_EDUCATION_DEPT:
00309             tabpModel[enumGC]->DisplayList( rcuiW, rcuiL, tabH );
00310             break;
00311 
00312         case OC_EMPTY:
00313 //debug cout << "empty" << endl;
00314             break;
00315 
00316         // Test codes used by graphists
00317         case OC_TEST_BUILDING:
00318             if (tabpModel[OC_TEST_BUILDING] != NULL) {
00319                 tabpModel[OC_TEST_BUILDING]->DisplayList( rcuiW, rcuiL, tabH );
00320             }
00321             break;
00322 
00323         default:
00324             red = .0; green = .0; blue = .0;
00325         // Display_draw_polygon:
00326             glBegin( GL_QUADS );
00327                 glColor3f( red, green, blue );
00328                 glVertex3i( rcuiW, tabH[0], rcuiL  );
00329                 glVertex3i( rcuiW , tabH[1], (rcuiL+1)   );
00330                 glVertex3i( rcuiW+1  , tabH[2], (rcuiL+1)   );
00331                 glVertex3i( rcuiW+1  , tabH[3], rcuiL  );
00332             glEnd();
00333             break;
00334     }
00335 }
00336 
00337 
00338    /*======================================================================*/
00339 void
00340 GraphicManager::DisplayGC(
00341     const OPENCITY_GRAPHIC_CODE & enumGC,
00342     const uint & rcuiW,
00343     const uint & rcuiL ) const
00344 {
00345     static OC_BYTE tabH [4];
00346 
00347 // Get the heights from the map manager
00348     gVars.gpMapMgr->GetSquareHeight( rcuiW, rcuiL, tabH );
00349 
00350 //NOTE: null pointer can lead to SIGSEGV
00351     assert( (enumGC == OC_EMPTY) || (tabpModel[enumGC] != NULL) );
00352 
00353     tabpModel[enumGC]->DisplayList( rcuiW, rcuiL, tabH );
00354 }
00355 
00356 
00357    /*======================================================================*/
00358 void
00359 GraphicManager::DisplayTerrainHighlight(
00360     const uint & rcuiW,
00361     const uint & rcuiL,
00362     const OPENCITY_TOOL_CODE & enumTool ) const
00363 {
00364     OC_BYTE tabH [4];
00365 
00366 // warning: see warning in DisplayTerrain
00367     gVars.gpMapMgr->GetSquareHeight( rcuiW, rcuiL, tabH );
00368 
00369 // compare the tool code
00370     switch (enumTool) {
00371         case OC_ZONE_RES:
00372             red = .2; green = .5; blue = .2;
00373             break;
00374 
00375         case OC_ZONE_COM:
00376             red = .2; green = .2; blue = .5;
00377             break;
00378 
00379         case OC_ZONE_IND:
00380             red = .5; green = .5; blue = .2;
00381             break;
00382 
00383         case OC_BUILD_ROAD:
00384             red = .5; green = .65; blue = .5;
00385             break;
00386 
00387         case OC_BUILD_ELINE:
00388             red = .55; green = .55; blue = .45;
00389             break;
00390 
00391         default:
00392             red = .1; green = .1; blue = .1;
00393     }
00394 
00395 
00396     glBegin( GL_QUADS );
00397         glColor3f( red, green, blue );
00398         glVertex3f( .1 + rcuiW, tabH[0], 0.1 + rcuiL);
00399         glVertex3f( .1 + rcuiW, tabH[1], 0.9 + rcuiL );
00400         glVertex3f( .9 + rcuiW, tabH[2], 0.9 + rcuiL );
00401         glVertex3f( .9 + rcuiW, tabH[3], 0.1 + rcuiL);
00402     glEnd();
00403 }
00404 
00405 
00406    /*======================================================================*/
00407 void
00408 GraphicManager::DisplayStructureHighlight(
00409     const Structure* pcStructure,
00410     const uint & rcuiW,
00411     const uint & rcuiL,
00412     const OPENCITY_TOOL_CODE & enumTool ) const
00413 {
00414 //TODO: check the pcStructure graphic code
00415     DisplayTerrainHighlight(
00416         rcuiW,
00417         rcuiL,
00418         enumTool );
00419 }
00420 
00421 
00422   /*======================================================================*/
00423 void
00424 GraphicManager::DisplayTerrainSelection(
00425     const uint & rcuiW,
00426     const uint & rcuiL,
00427     const uint & rcuiID ) const
00428 {
00429     static OC_BYTE tabH [4];
00430 
00431 // warning: we draw the polygon counter-clock wise
00432 //          however, the polygon OY heights are
00433 //          stored as the left,right heights of the first line
00434 //          then left, right heights of the second line
00435     gVars.gpMapMgr->GetSquareHeight( rcuiW, rcuiL, tabH );
00436 
00437     glLoadName( rcuiID );
00438     glBegin( GL_QUADS );
00439         glVertex3i( rcuiW,   tabH[0], rcuiL);
00440         glVertex3i( rcuiW,   tabH[1], rcuiL+1 );
00441         glVertex3i( rcuiW+1, tabH[2], rcuiL+1 );
00442         glVertex3i( rcuiW+1, tabH[3], rcuiL);
00443     glEnd();
00444 }
00445 
00446 
00447    /*======================================================================*/
00448 /* TOKILL, old version, kept for future reference, nov 2nd 05
00449 void
00450 GraphicManager::DisplayTerrainSelection(
00451     const uint & rcuiW,
00452     const uint & rcuiL,
00453     const uint & rcuiID ) const
00454 {
00455     static OC_BYTE tabH [4];
00456 // this is suitable for up to 256^3 = 16777216 objects
00457     static uint red;
00458     static uint green;
00459     static uint blue;
00460 
00461 // warning: we draw the polygon counter-clock wise
00462 //          however, the polygon OY heights are
00463 //          stored as the left,right heights of the first line
00464 //          then left, right heights of the second line
00465     gVars.gpMapMgr->GetSquareHeight( rcuiW, rcuiL, tabH );
00466 
00467     red =   (rcuiID & 0x00FF0000) >> 16;
00468     green = (rcuiID & 0x0000FF00) >> 8;
00469     blue =   rcuiID & 0x000000FF;
00470 
00471 // 16bits
00472 //  red =   (rcuiID & 0x0000F800) >> 11;
00473 //  green = (rcuiID & 0x000007E0) >> 5;
00474 //  blue =   rcuiID & 0x0000001F;
00475 
00476 
00477     glColor4ub( red, green, blue, 0xFF );
00478 
00479 //NOTE: we are already in GL_QUADS mode
00480 //  glBegin( GL_QUADS );
00481         glVertex3i( rcuiW,   tabH[0], rcuiL);
00482         glVertex3i( rcuiW,   tabH[1], rcuiL+1 );
00483         glVertex3i( rcuiW+1, tabH[2], rcuiL+1 );
00484         glVertex3i( rcuiW+1, tabH[3], rcuiL);
00485 //  glEnd();
00486 }
00487 */
00488 
00489 
00490    /*======================================================================*/
00491 void
00492 GraphicManager::DisplayStructureSelection(
00493     const Structure* pcStructure,
00494     const uint & rcuiW,
00495     const uint & rcuiL,
00496     const uint & rcuiID ) const
00497 {
00498     glLoadName( rcuiID );
00499 
00500     this->DisplayStructure( pcStructure, rcuiW, rcuiL );
00501 }
00502 
00503 
00504    /*======================================================================*/
00505 /* TOKILL, old version, kept for reference, nov 2nd 05.
00506 void
00507 GraphicManager::DisplayStructureSelection(
00508         const Structure* pcStructure,
00509         const uint & rcuiW,
00510         const uint & rcuiL,
00511         const uint & rcuiID ) const
00512 {
00513 //FIXME: do a correct display for structure
00514     DisplayTerrainSelection(
00515         rcuiW,
00516         rcuiL,
00517         rcuiID );
00518 }
00519 */
00520 
00521 
00522    /*======================================================================*/
00523 void
00524 GraphicManager::Display(
00525     const OC_FLOAT & rcfW,
00526     const OC_FLOAT & rcfL,
00527     const OC_FLOAT & rcfH,
00528     const Movement* const pm ) const
00529 {
00530     assert( pm != NULL );
00531 //  static OC_BYTE tabH [4];
00532 
00533 // warning: see warning in DisplayTerrain
00534 //  gVars.gpMapMgr->GetSquareHeight( (uint)floorf(rcfW), (uint)floorf(rcfH), tabH );
00535 
00536     glPushMatrix();
00537 // Rotation translation compensation
00538 // The 0.05 value is the display translation vector of the other structures
00539     glTranslatef( rcfW+pm->_fTX, rcfH+pm->_fTY+0.05, rcfL+pm->_fTZ );
00540     glRotatef( pm->_fRY, 0, 1, 0 );         // Model rotation
00541     glRotatef( pm->_fRX, 1, 0, 0 );         // Slope
00542     glRotatef( pm->_fRZ, 0, 0, 1 );
00543     tabpModel[pm->GetGraphicCode()]->DisplayList();
00544     glPopMatrix();
00545 
00546 /*
00547 // FIXME: testing new AC3D vehicle models
00548     if (pm->GetGraphicCode() == OC_VEHICLE_STD) {
00549         tabpModel[OC_VEHICLE_STD]->DisplayPoly( rcfW, rcfH, tabH );
00550     }
00551     else {
00552         tabpModel[pm->GetGraphicCode()]->Display( rcfW, rcfH, tabH[0] );
00553     }
00554 */
00555 }
00556 
00557 
00558    /*======================================================================*/
00559 
00560 /* WARNING: this is a special function used for agent rendering */
00561 void
00562 GraphicManager::DisplayAgent(float x, float y, const Agent* const pAgent) const
00563  {
00564     static OC_BYTE tabH [4];
00565 
00566     assert(pAgent != NULL);
00567 
00568 // warning: see warning in DisplayTerrain
00569     gVars.gpMapMgr->GetSquareHeight( (uint)floorf(x), (uint)floorf(y), tabH );
00570     tabpModel[pAgent->GetGraphicCode()]->DisplayList( x, y, tabH );
00571  }
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579 
00580 
00581 
00582 
00583 
00584 
00585 
00586 

Generated on Sat Nov 11 10:21:10 2006 for OpenCity by  doxygen 1.4.2