PCMOpenGLRenderingEngine.cpp

Go to the documentation of this file.
00001 
00002 //
00003 // This source file is a part of ParCompMark
00004 // Parallel Compositing Benchmark Framework
00005 //
00006 // for latest info see http://parcompmark.sourceforge.net
00007 
00008 //
00009 // Copyright (C) 2006 IT2 ParCompMark Dev. Team
00010 // 
00011 // This program is free software; you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License
00013 // as published by the Free Software Foundation; either version 2
00014 // of the License, or (at your option) any later version.
00015 // 
00016 // This program is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 // GNU General Public License for more details.
00020 // 
00021 // You should have received a copy of the GNU General Public License
00022 // along with this program; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00024 
00025 //
00026 // Inner includes
00027 //
00028 
00029 #include "../include/PCMOpenGLRenderingEngine.h"
00030 
00031 #include "../include/PCMPluginManager.h"
00032 
00033 #include "../include/PCMRendererPlugin.h"
00034 
00035 #include "../include/PCMRenderer.h"
00036 
00037 #include "../include/PCMStringConverter.h"
00038 
00039 #include "../include/PCMProcess.h"
00040 
00041 //
00042 // Outer includes
00043 //
00044 
00045 #include <algorithm>
00046 #include <GL/glew.h>
00047 #include <GL/glx.h>
00048 #include <GL/glu.h>
00049 #include <GL/glut.h>
00050 
00051 namespace ParCompMark
00052 {
00053 
00054   //
00055   // Constructors & destructor
00056   //
00057 
00058   OpenGLRenderingEngine::OpenGLRenderingEngine()
00059         // You have to initialize the following attributes:
00060         // - mParent
00061         // - mCamera
00062         // - mDrawStyle
00063         // - mRenderers
00064         // - mAutoRenderingQueue
00065         // - mObjectData
00066         // - mDisplayLists
00067         // - mCurrentDisplayList
00068         // - mLightCount
00069   {
00070         Except(INVALID_OPERATION_ERROR, "OpenGLRenderingEngine::OpenGLRenderingEngine()",
00071            "Default constructor for Squirrel compatibility. Calling this constructor always raises an exception.");
00072   }
00073 
00074  /*----------------------------------------------------------------------*/
00075 
00076   OpenGLRenderingEngine::OpenGLRenderingEngine(Process * parent):
00077         // Initialize parent process 
00078    mParent(parent               /* Parent process */
00079         )
00080         // You have to initialize the following attributes:
00081         // - mParent
00082         // - mCamera
00083         // - mDrawStyle
00084         // - mRenderers
00085         // - mAutoRenderingQueue
00086         // - mObjectData
00087         // - mDisplayLists
00088         // - mCurrentDisplayList
00089         // - mLightCount
00090   {
00091         // Do not hurt the camera (plugins might be angry :))
00092         mDrawStyle = FILL;
00093 
00094         mCurrentDisplayList = 0;
00095         mLightCount = 0;
00096 
00097         // For some OpenGL implementations, texture coordinates generated during rasterization 
00098         // aren't perspective correct. However, you can usually make them perspective correct 
00099         // by calling the following function:
00100         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00101 
00102         Logger::getInstance()->log(Logger::NOTICE,
00103                                  "Rendering engine has been created for process `" + parent->getName() + "\'.");
00104   }
00105 
00106  /*----------------------------------------------------------------------*/
00107 
00108   OpenGLRenderingEngine::~OpenGLRenderingEngine()
00109   {
00110         // Cleaning up display lists
00111         for(std::vector < DisplayList * >::iterator i = mDisplayLists.begin(); i != mDisplayLists.end(); i++)
00112          glDeleteLists((*i)->handle, 1);
00113 
00114         // Cleaning up object data
00115         for(std::vector < ObjectData >::iterator i = mObjectData.begin(); i != mObjectData.end(); i++)
00116         {
00117          if(i->vertexCoordinates)
00118                 delete[]i->vertexCoordinates;
00119          if(i->texCoordinates)
00120                 delete[]i->texCoordinates;
00121          if(i->normals)
00122                 delete[]i->normals;
00123         }
00124 
00125         Logger::getInstance()->log(Logger::NOTICE,
00126                                  "Rendering engine of process `" + mParent->getName() + "\' has been destroyed.");
00127   }
00128 
00129  /*----------------------------------------------------------------------*/
00130 
00131   //
00132   // Class methods
00133   //
00134 
00135   OpenGLRenderingEngine *OpenGLRenderingEngine::create(const char *stringPtr)
00136   {
00137         void *p = StringConverter::parsePointer(stringPtr);
00138 
00139         return static_cast < OpenGLRenderingEngine * >(p);
00140   }
00141 
00142  /*----------------------------------------------------------------------*/
00143 
00144   //
00145   // Methods
00146   //
00147 
00148   Renderer *OpenGLRenderingEngine::createCustomRenderer(const char *rendererName)
00149   {
00150         // Get plugin
00151         Plugin::Pointer plugin(PluginManager::getInstance()->getPlugin(rendererName));
00152         Assert(plugin->getPluginType() == Plugin::RENDERER_PLUGIN, INVALID_CLASS_ERROR,
00153            "OpenGLRenderingEngine::createCustomRenderer");
00154 
00155         // Cast plugin to renderer plugin
00156         RendererPlugin *rPlugin = dynamic_cast < RendererPlugin * >(plugin.getPtr());
00157 
00158         Assert(rPlugin, INVALID_CLASS_ERROR, "OpenGLRenderingEngine::createCustomRenderer()");
00159 
00160         // Create renderer
00161         Renderer *renderer = rPlugin->createRenderer(mParent->getRenderWindow(), this);
00162 
00163         // Register this renderer on this rendering engine 
00164         // (for later operations, for example canvas resizing)
00165         _registerRenderer(renderer);
00166 
00167         return renderer;
00168   }
00169 
00170  /*----------------------------------------------------------------------*/
00171 
00172   void OpenGLRenderingEngine::resizeRenderers(const u32 width, const u32 height)
00173   {
00174         for(std::set < Renderer * >::iterator i = mRenderers.begin(); i != mRenderers.end(); i++)
00175         {
00176          (*i)->resize(width, height);
00177         }
00178   }
00179 
00180  /*----------------------------------------------------------------------*/
00181 
00182   s32 OpenGLRenderingEngine::getSortOrderFromRenderers()
00183   {
00184         int order = -1;
00185 
00186         for(std::set < Renderer * >::iterator i = mRenderers.begin(); i != mRenderers.end(); i++)
00187         {
00188          int _order = (*i)->getSortOrder();
00189 
00190          if(_order != -1)
00191          {
00192                 if(order != -1 && order != _order)
00193                  Except(INVALID_VALUE_ERROR, "OpenGLRenderingEngine::getSortOrderFromRenderers()",
00194                          "Conflicting sort order retrieved from renderer plugins on the same rendering engine");
00195 
00196                 order = _order;
00197          }
00198         }
00199 
00200         return order;
00201   }
00202 
00203  /*----------------------------------------------------------------------*/
00204 
00205   void OpenGLRenderingEngine::setAutoRenderOrder(const Renderer * renderer, const s32 & order)
00206   {
00207         // Test whether the specified renderer is added to the rendering engine or not
00208         Assert(mRenderers.find((Renderer *) renderer) != mRenderers.end(), INVALID_OBJECT_ERROR,
00209            "OpenGLRenderingEngine::setAutoRenderOrder");
00210 
00211         // Remove from queue if the renderer is in it
00212         std::vector < Renderer * >::iterator i =
00213          std::find(mAutoRenderingQueue.begin(), mAutoRenderingQueue.end(), (Renderer *) renderer);
00214 
00215         if(i != mAutoRenderingQueue.end())
00216          mAutoRenderingQueue.erase(i);
00217 
00218         // Removing so jump out
00219         if(order == Renderer::NOAUTORENDERING)
00220          return;
00221 
00222         // Insert into the queue
00223         for(i = mAutoRenderingQueue.begin(); i != mAutoRenderingQueue.end(); i++)
00224          if((*i)->getAutoRenderOrder() > order)
00225                 break;
00226 
00227         mAutoRenderingQueue.insert(i, (Renderer *) renderer);
00228   }
00229 
00230  /*----------------------------------------------------------------------*/
00231 
00232   void OpenGLRenderingEngine::doAutoRendering()
00233   {
00234         for(std::vector < Renderer * >::iterator i = mAutoRenderingQueue.begin(); i != mAutoRenderingQueue.end(); i++)
00235          (*i)->render();
00236   }
00237 
00238  /*----------------------------------------------------------------------*/
00239 
00240   void OpenGLRenderingEngine::perspective(const double fovy, const double zNear, const double zFar)
00241   {
00242         glMatrixMode(GL_PROJECTION);
00243         glLoadIdentity();
00244         gluPerspective(fovy,
00245                    (double) mParent->getRenderWindow()->getWidth() /
00246                    (double) mParent->getRenderWindow()->getHeight(), zNear, zFar);
00247   }
00248 
00249  /*----------------------------------------------------------------------*/
00250 
00251   void OpenGLRenderingEngine::ortho2D(const double left, const double right, const double bottom,
00252                                         const double top)
00253   {
00254         glMatrixMode(GL_PROJECTION);
00255         glLoadIdentity();
00256         gluOrtho2D(left, right, bottom, top);
00257   }
00258 
00259  /*----------------------------------------------------------------------*/
00260 
00261   void OpenGLRenderingEngine::viewport(const double left, const double top, const double width,
00262                                          const double height)
00263   {
00264         double winWidth = mParent->getRenderWindow()->getWidth();
00265         double winHeight = mParent->getRenderWindow()->getHeight();
00266 
00267         // TODO: Not works!!!
00268         //glViewport((GLint) (left * winWidth), (GLint) (top * winHeight), (GLsizei) (width * winWidth), (GLsizei) (height * winHeight));
00269         glViewport(0, 0, winWidth, winHeight);
00270   }
00271 
00272  /*----------------------------------------------------------------------*/
00273 
00274   void OpenGLRenderingEngine::pushModelView()
00275   {
00276         glMatrixMode(GL_MODELVIEW);
00277         glPushMatrix();
00278   }
00279 
00280  /*----------------------------------------------------------------------*/
00281 
00282   void OpenGLRenderingEngine::popModelView()
00283   {
00284         glMatrixMode(GL_MODELVIEW);
00285         glPopMatrix();
00286   }
00287 
00288  /*----------------------------------------------------------------------*/
00289 
00290   void OpenGLRenderingEngine::translate(const double x, const double y, const double z)
00291   {
00292         glMatrixMode(GL_MODELVIEW);
00293         glTranslated(x, y, z);
00294   }
00295 
00296  /*----------------------------------------------------------------------*/
00297 
00298   void OpenGLRenderingEngine::rotate(const double angle, const double x, const double y,
00299                                    const double z)
00300   {
00301         glMatrixMode(GL_MODELVIEW);
00302         glRotated(angle, x, y, z);
00303   }
00304 
00305  /*----------------------------------------------------------------------*/
00306 
00307   void OpenGLRenderingEngine::scale(const double x, const double y, const double z)
00308   {
00309         glMatrixMode(GL_MODELVIEW);
00310         glScaled(x, y, z);
00311   }
00312 
00313  /*----------------------------------------------------------------------*/
00314 
00315   void OpenGLRenderingEngine::setCameraPosition(const double eyeX, const double eyeY,
00316                                                 const double eyeZ)
00317   {
00318         mCamera.position[0] = eyeX;
00319         mCamera.position[1] = eyeY;
00320         mCamera.position[2] = eyeZ;
00321         _refreshCamera();
00322   }
00323 
00324  /*----------------------------------------------------------------------*/
00325 
00326   void OpenGLRenderingEngine::setCameraTarget(const double centerX, const double centerY,
00327                                                 const double centerZ)
00328   {
00329         mCamera.target[0] = centerX;
00330         mCamera.target[1] = centerY;
00331         mCamera.target[2] = centerZ;
00332         _refreshCamera();
00333   }
00334 
00335  /*----------------------------------------------------------------------*/
00336 
00337   void OpenGLRenderingEngine::setCameraUpVector(const double upX, const double upY,
00338                                                 const double upZ)
00339   {
00340         mCamera.upVector[0] = upX;
00341         mCamera.upVector[1] = upY;
00342         mCamera.upVector[2] = upZ;
00343         _refreshCamera();
00344   }
00345 
00346  /*----------------------------------------------------------------------*/
00347 
00348   void OpenGLRenderingEngine::setColor(const double red, const double green, const double blue,
00349                                          const double alpha)
00350   {
00351         glColor4d(red, green, blue, alpha);
00352   }
00353 
00354  /*----------------------------------------------------------------------*/
00355 
00356   void OpenGLRenderingEngine::setAmbientMaterial(const double red, const double green,
00357                                                  const double blue, const double alpha)
00358   {
00359         GLfloat params[] = { red, green, blue, alpha };
00360         glMaterialfv(GL_FRONT, GL_AMBIENT, params);
00361   }
00362 
00363  /*----------------------------------------------------------------------*/
00364 
00365   void OpenGLRenderingEngine::setDiffuseMaterial(const double red, const double green,
00366                                                  const double blue, const double alpha)
00367   {
00368         GLfloat params[] = { red, green, blue, alpha };
00369         glMaterialfv(GL_FRONT, GL_DIFFUSE, params);
00370   }
00371 
00372  /*----------------------------------------------------------------------*/
00373 
00374   void OpenGLRenderingEngine::setSpecularMaterial(const double red, const double green,
00375                                                  const double blue, const double alpha,
00376                                                  const int shininess)
00377   {
00378         GLfloat params[] = { red, green, blue, alpha };
00379         glMaterialfv(GL_FRONT, GL_SPECULAR, params);
00380         glMateriali(GL_FRONT, GL_SHININESS, shininess);
00381   }
00382 
00383  /*----------------------------------------------------------------------*/
00384 
00385   void OpenGLRenderingEngine::setDrawStyle(const unsigned drawStyle)
00386   {
00387         mDrawStyle = DrawStyle(drawStyle);
00388   }
00389 
00390  /*----------------------------------------------------------------------*/
00391 
00392   void OpenGLRenderingEngine::setBackCulling(const bool isBackCulling)
00393   {
00394         if(isBackCulling)
00395         {
00396          glEnable(GL_CULL_FACE);
00397          glCullFace(GL_BACK);
00398         } else
00399          glDisable(GL_CULL_FACE);
00400   }
00401 
00402  /*----------------------------------------------------------------------*/
00403 
00404   void OpenGLRenderingEngine::setBlending(const bool isOn)
00405   {
00406         if(isOn)
00407         {
00408          glEnable(GL_BLEND);
00409          glDisable(GL_DEPTH_TEST);
00410          glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00411         } else
00412         {
00413          glDisable(GL_BLEND);
00414          glEnable(GL_DEPTH_TEST);
00415         }
00416   }
00417 
00418  /*----------------------------------------------------------------------*/
00419 
00420   void OpenGLRenderingEngine::drawTriangle()
00421   {
00422         glBegin(GL_TRIANGLES);
00423         glVertex2f(1.0, 0.0);
00424         glVertex2f(0.0, 0.0);
00425         glVertex2f(0.0, 1.0);
00426         glEnd();
00427 
00428         _reportTriangles(1);
00429   }
00430 
00431  /*----------------------------------------------------------------------*/
00432 
00433   int OpenGLRenderingEngine::generateRandomTriangles(const int dimension, const int count)
00434   {
00435         Assert(dimension == 2
00436            || dimension == 3, INVALID_VALUE_ERROR, "OpenGLRenderingEngine::generateRandomTriangles()");
00437 
00438         // Allocate memory for data
00439         ObjectData data;
00440 
00441         data.vertexCount = 3 * count;
00442         data.vertexSize = dimension;
00443         data.texSize = 0;
00444         data.vertexCoordinates = new float[dimension * data.vertexCount];
00445 
00446         data.texCoordinates = 0;
00447         data.normals = new float[dimension * data.vertexCount];
00448 
00449         // Generate random triangles
00450         srand((unsigned int) (Timer::getSystemTime() * 1e6));
00451         for(float *vp = data.vertexCoordinates, *vpEnd = data.vertexCoordinates + dimension * data.vertexCount;
00452          vp != vpEnd; vp++)
00453         {
00454          *vp = (double) rand() / ((double) (RAND_MAX) + (double) (1));
00455         }
00456 
00457         // Calculate normals
00458         if(dimension == 3)
00459         {
00460          for(float *vp = data.vertexCoordinates, *vpEnd =
00461                 data.vertexCoordinates + dimension * data.vertexCount, *normals = data.normals; vp != vpEnd;
00462                 vp += 9, normals += 9)
00463          {
00464                 float *v1 = vp,
00465                  *v2 = vp + 3,
00466                  *v3 = vp + 6;
00467                 float a[3],
00468                 b[3],
00469                 n[3];
00470 
00471                 a[0] = v2[0] - v1[0];
00472                 a[1] = v2[1] - v1[1];
00473                 a[2] = v2[2] - v1[2];
00474                 b[0] = v3[0] - v1[0];
00475                 b[1] = v3[1] - v1[1];
00476                 b[2] = v3[2] - v1[2];
00477 
00478                 n[0] = a[1] * b[2] - b[1] * a[2];
00479                 n[1] = -(a[0] * b[2] - b[0] * a[2]);
00480                 n[2] = a[0] * b[1] - b[0] * a[1];
00481 
00482                 normals[0] = normals[3] = normals[6] = n[0];
00483                 normals[1] = normals[4] = normals[7] = n[1];
00484                 normals[2] = normals[6] = normals[8] = n[2];
00485          }
00486         }
00487 
00488         return _registerObject(data);
00489   }
00490 
00491  /*----------------------------------------------------------------------*/
00492 
00493   void OpenGLRenderingEngine::renderObject(const u32 handle, const bool useVertexArrays)
00494   {
00495         ObjectData & data = mObjectData[handle];
00496 
00497         _renderObject(handle, useVertexArrays, data.vertexCount);
00498   }
00499 
00500  /*----------------------------------------------------------------------*/
00501 
00502   void OpenGLRenderingEngine::renderObjectTriangles(const u32 handle, const bool useVertexArrays,
00503                                                   const u32 triangleCount)
00504   {
00505         _renderObject(handle, useVertexArrays, triangleCount * 3);
00506   }
00507 
00508  /*----------------------------------------------------------------------*/
00509 
00510   void OpenGLRenderingEngine::setAmbientLight(const double red, const double green,
00511                                                 const double blue, const double alpha)
00512   {
00513         glEnable(GL_LIGHTING);
00514 
00515         GLfloat params[] = { red, green, blue, alpha };
00516         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, params);
00517   }
00518 
00519  /*----------------------------------------------------------------------*/
00520 
00521   void OpenGLRenderingEngine::removeLightSources()
00522   {
00523         glDisable(GL_LIGHTING);
00524         for(u32 i = 0; i < mLightCount; i--)
00525          glDisable(GL_LIGHT0 + i);
00526 
00527         mLightCount = 0;
00528   }
00529 
00530  /*----------------------------------------------------------------------*/
00531 
00532   int OpenGLRenderingEngine::addLightSource()
00533   {
00534         glEnable(GL_LIGHTING);
00535 
00536         int newLight = mLightCount++;
00537 
00538         glEnable(GL_LIGHT0 + newLight);
00539         setLightSourcePosition(newLight, 0.0, 0.0, 0.0);
00540         setLightSourceDiffuse(newLight, 1.0, 1.0, 1.0, 1.0);
00541         setLightSourceSpecular(newLight, 1.0, 1.0, 1.0, 1.0);
00542 
00543         return newLight;
00544   }
00545 
00546  /*----------------------------------------------------------------------*/
00547 
00548   void OpenGLRenderingEngine::setLightSourcePosition(const int light, const double x,
00549                                                    const double y, const double z)
00550   {
00551         GLfloat params[] = { x, y, z };
00552         glEnable(GL_LIGHT0 + light);
00553         glLightfv(GL_LIGHT0 + light, GL_POSITION, params);
00554   }
00555 
00556  /*----------------------------------------------------------------------*/
00557 
00558   void OpenGLRenderingEngine::setLightSourceDiffuse(const int light, const double red,
00559                                                   const double green, const double blue,
00560                                                   const double alpha)
00561   {
00562         GLfloat params[] = { red, green, blue, alpha };
00563         glLightfv(GL_LIGHT0 + light, GL_DIFFUSE, params);
00564   }
00565 
00566  /*----------------------------------------------------------------------*/
00567 
00568   void OpenGLRenderingEngine::setLightSourceSpecular(const int light, const double red,
00569                                                    const double green, const double blue,
00570                                                    const double alpha)
00571   {
00572         GLfloat params[] = { red, green, blue, alpha };
00573         glLightfv(GL_LIGHT0 + light, GL_SPECULAR, params);
00574   }
00575 
00576  /*----------------------------------------------------------------------*/
00577 
00578   u32 OpenGLRenderingEngine::createDisplayList()
00579   {
00580         mCurrentDisplayList = new DisplayList();
00581 
00582         // Create list
00583         mCurrentDisplayList->handle = glGenLists(1);
00584 
00585         mDisplayLists.insert(mDisplayLists.begin(), mCurrentDisplayList);
00586 
00587         // Start list
00588         glNewList(mCurrentDisplayList->handle, GL_COMPILE);
00589 
00590         return mDisplayLists.size() - 1;
00591   }
00592 
00593  /*----------------------------------------------------------------------*/
00594 
00595   void OpenGLRenderingEngine::finishDisplayList()
00596   {
00597         glEndList();
00598         mCurrentDisplayList = 0;
00599   }
00600 
00601  /*----------------------------------------------------------------------*/
00602 
00603   void OpenGLRenderingEngine::executeDisplayList(const u32 displayList)
00604   {
00605         Assert(displayList < mDisplayLists.size(), INVALID_OBJECT_ERROR, "OpenGLRenderingEngine::executeDisplayList()");
00606         glCallList(mDisplayLists[displayList]->handle);
00607 
00608         // Report rendered triangles 
00609         mParent->getRenderWindow()->reportTriangles(mDisplayLists[displayList]->triangleCount);
00610   }
00611 
00612  /*----------------------------------------------------------------------*/
00613 
00614   void OpenGLRenderingEngine::drawSphere(const double radius, const int slices, const int stacks)
00615   {
00616         GLUquadricObj *sphere = gluNewQuadric();
00617 
00618         if(_setGLUDrawStyle(sphere))
00619          gluSphere(sphere, radius, slices, stacks);
00620 
00621         gluDeleteQuadric(sphere);
00622   }
00623 
00624  /*----------------------------------------------------------------------*/
00625 
00626   void OpenGLRenderingEngine::drawCylinder(const double baseRadius, const double topRadius,
00627                                           const double height, const int slices, const int stacks)
00628   {
00629         GLUquadricObj *cylinder = gluNewQuadric();
00630 
00631         if(_setGLUDrawStyle(cylinder))
00632          gluCylinder(cylinder, baseRadius, topRadius, height, slices, stacks);
00633 
00634         gluDeleteQuadric(cylinder);
00635   }
00636 
00637  /*----------------------------------------------------------------------*/
00638 
00639   void OpenGLRenderingEngine::drawDisk(const double innerRadius, const double outerRadius,
00640                                          const int slices, const int loops)
00641   {
00642         GLUquadricObj *disk = gluNewQuadric();
00643 
00644         if(_setGLUDrawStyle(disk))
00645          gluDisk(disk, innerRadius, outerRadius, slices, loops);
00646 
00647         gluDeleteQuadric(disk);
00648   }
00649 
00650  /*----------------------------------------------------------------------*/
00651 
00652   void OpenGLRenderingEngine::drawTeapot(const double size)
00653   {
00654 #if defined(HAVE_GL_GLUT_H) && defined(HAVE_LIBGLUT)
00655         switch (mDrawStyle)
00656         {
00657          case WIRE:
00658                 glutWireTeapot(size);
00659                 break;
00660          case FILL:
00661                 glutSolidTeapot(size);
00662                 break;
00663          default:
00664                 break;
00665         }
00666 #else
00667         Except(OPERATION_NOT_SUPPORTED_ERROR, "OpenGLRenderingEngine::drawTeapot()",
00668            "GLUT library does not present on your system.");
00669 #endif
00670   }
00671 
00672  /*----------------------------------------------------------------------*/
00673 
00674   void OpenGLRenderingEngine::drawCube(const double size)
00675   {
00676 #if defined(HAVE_GL_GLUT_H) && defined(HAVE_LIBGLUT)
00677         switch (mDrawStyle)
00678         {
00679          case WIRE:
00680                 glutWireCube(size);
00681                 break;
00682          case FILL:
00683                 glutSolidCube(size);
00684                 _reportTriangles(6 * 2);
00685                 break;
00686          default:
00687                 break;
00688         }
00689 #else
00690         Except(OPERATION_NOT_SUPPORTED_ERROR, "OpenGLRenderingEngine::drawCube()",
00691            "GLUT library does not present on your system.");
00692 #endif
00693   }
00694 
00695  /*----------------------------------------------------------------------*/
00696 
00697   void OpenGLRenderingEngine::drawTorus(const double innerRadius, const double outerRadius,
00698                                         const int nsides, const int rings)
00699   {
00700 #if defined(HAVE_GL_GLUT_H) && defined(HAVE_LIBGLUT)
00701         switch (mDrawStyle)
00702         {
00703          case WIRE:
00704                 glutWireTorus(innerRadius, outerRadius, nsides, rings);
00705                 break;
00706          case FILL:
00707                 glutSolidTorus(innerRadius, outerRadius, nsides, rings);
00708                 break;
00709          default:
00710                 break;
00711         }
00712 #else
00713         Except(OPERATION_NOT_SUPPORTED_ERROR, "OpenGLRenderingEngine::drawTorus()",
00714            "GLUT library does not present on your system.");
00715 #endif
00716   }
00717 
00718  /*----------------------------------------------------------------------*/
00719 
00720   void OpenGLRenderingEngine::drawDodecahedron(const double size)
00721   {
00722 #if defined(HAVE_GL_GLUT_H) && defined(HAVE_LIBGLUT)
00723         pushModelView();
00724         Real ratio = size /::sqrt(3);
00725 
00726         scale(ratio, ratio, ratio);
00727         switch (mDrawStyle)
00728         {
00729          case WIRE:
00730                 glutWireDodecahedron();
00731                 break;
00732          case FILL:
00733                 glutSolidDodecahedron();
00734                 _reportTriangles(12 * 5);
00735                 break;
00736          default:
00737                 break;
00738         }
00739         popModelView();
00740 #else
00741         Except(OPERATION_NOT_SUPPORTED_ERROR, "OpenGLRenderingEngine::drawDodecahedron()",
00742            "GLUT library does not present on your system.");
00743 #endif
00744   }
00745 
00746  /*----------------------------------------------------------------------*/
00747 
00748   void OpenGLRenderingEngine::drawOctahedron(const double size)
00749   {
00750 #if defined(HAVE_GL_GLUT_H) && defined(HAVE_LIBGLUT)
00751         pushModelView();
00752         scale(size, size, size);
00753         switch (mDrawStyle)
00754         {
00755          case WIRE:
00756                 glutWireOctahedron();
00757                 break;
00758          case FILL:
00759                 glutSolidOctahedron();
00760                 _reportTriangles(8);
00761                 break;
00762          default:
00763                 break;
00764         }
00765         popModelView();
00766 #else
00767         Except(OPERATION_NOT_SUPPORTED_ERROR, "OpenGLRenderingEngine::drawOctahedron()",
00768            "GLUT library does not present on your system.");
00769 #endif
00770   }
00771 
00772  /*----------------------------------------------------------------------*/
00773 
00774   void OpenGLRenderingEngine::drawTetrahedron(const double size)
00775   {
00776 #if defined(HAVE_GL_GLUT_H) && defined(HAVE_LIBGLUT)
00777         pushModelView();
00778         Real ratio = size /::sqrt(3);
00779 
00780         scale(ratio, ratio, ratio);
00781         switch (mDrawStyle)
00782         {
00783          case WIRE:
00784                 glutWireTetrahedron();
00785                 break;
00786          case FILL:
00787                 glutSolidTetrahedron();
00788                 _reportTriangles(4);
00789                 break;
00790          default:
00791                 break;
00792         }
00793         popModelView();
00794 #else
00795         Except(OPERATION_NOT_SUPPORTED_ERROR, "OpenGLRenderingEngine::drawTetrahedron()",
00796            "GLUT library does not present on your system.");
00797 #endif
00798   }
00799 
00800  /*----------------------------------------------------------------------*/
00801 
00802   void OpenGLRenderingEngine::drawIcosahedron(const double size)
00803   {
00804 #if defined(HAVE_GL_GLUT_H) && defined(HAVE_LIBGLUT)
00805         pushModelView();
00806         scale(size, size, size);
00807         switch (mDrawStyle)
00808         {
00809          case WIRE:
00810                 glutWireIcosahedron();
00811                 break;
00812          case FILL:
00813                 glutSolidIcosahedron();
00814                 _reportTriangles(20);
00815                 break;
00816          default:
00817                 break;
00818         }
00819         popModelView();
00820 #else
00821         Except(OPERATION_NOT_SUPPORTED_ERROR, "OpenGLRenderingEngine::drawIcosahedron()",
00822            "GLUT library does not present on your system.");
00823 #endif
00824   }
00825 
00826  /*----------------------------------------------------------------------*/
00827 
00828   void OpenGLRenderingEngine::_registerRenderer(Renderer * renderer)
00829   {
00830         Assert(mRenderers.find(renderer) == mRenderers.end(), INVALID_OBJECT_ERROR,
00831            "OpenGLRenderingEngine::_registerRenderer()");
00832         mRenderers.insert(renderer);
00833   }
00834 
00835  /*----------------------------------------------------------------------*/
00836 
00837   u32 OpenGLRenderingEngine::_registerObject(ObjectData objectData)
00838   {
00839         mObjectData.insert(mObjectData.begin(), objectData);
00840 
00841         return mObjectData.size() - 1;
00842   }
00843 
00844  /*----------------------------------------------------------------------*/
00845 
00846   void OpenGLRenderingEngine::_renderObject(const u32 handle, const bool useVertexArrays,
00847                                           const u32 vertexCount)
00848   {
00849         Assert(handle < mObjectData.size(), INVALID_VALUE_ERROR, "OpenGLRenderingEngine::_renderObject()");
00850 
00851         ObjectData & data = mObjectData[handle];
00852 
00853         Assert(vertexCount <= data.vertexCount, INVALID_VALUE_ERROR, "OpenGLRenderingEngine::_renderObject()");
00854 
00855         // Use the vertex array for rendering
00856         if(useVertexArrays)
00857         {
00858          glEnableClientState(GL_VERTEX_ARRAY);
00859          glEnableClientState(GL_NORMAL_ARRAY);
00860          glNormalPointer(GL_FLOAT, 0, data.normals);
00861          glVertexPointer(data.vertexSize, GL_FLOAT, 0, data.vertexCoordinates);
00862          glDrawArrays(GL_TRIANGLES, 0, vertexCount);
00863          glDisableClientState(GL_VERTEX_ARRAY);
00864         }
00865         // Use for-loops for rendering (slower)
00866         else
00867         {
00868          glEnable(GL_NORMALIZE);
00869          glBegin(GL_TRIANGLES);
00870          // 2D triangles
00871          if(data.vertexSize == 2)
00872                 for(float *vp = data.vertexCoordinates, *vpEnd = data.vertexCoordinates + data.vertexSize * vertexCount;
00873                  vp != vpEnd; vp += 2)
00874                  glVertex2fv(vp);
00875          // 3D triangles
00876          else
00877                 for(float *vp = data.vertexCoordinates, *vpEnd =
00878                  data.vertexCoordinates + data.vertexSize * vertexCount, *normals = data.normals; vp != vpEnd;
00879                  vp += 3, normals += 3)
00880                 {
00881                  glNormal3fv(normals);
00882                  glVertex3fv(vp);
00883                 }
00884          glEnd();
00885         }
00886 
00887         _reportTriangles(vertexCount / 3);
00888   }
00889 
00890  /*----------------------------------------------------------------------*/
00891 
00892   void OpenGLRenderingEngine::_refreshCamera()
00893   {
00894         glMatrixMode(GL_MODELVIEW);
00895         glLoadIdentity();
00896         gluLookAt(mCamera.position[0], mCamera.position[1], mCamera.position[2], mCamera.target[0], mCamera.target[1],
00897                 mCamera.target[3], mCamera.upVector[0], mCamera.upVector[1], mCamera.upVector[2]);
00898   }
00899 
00900  /*----------------------------------------------------------------------*/
00901 
00902   bool OpenGLRenderingEngine::_setGLUDrawStyle(const void *quadratic)
00903   {
00904         switch (mDrawStyle)
00905         {
00906          case POINT:
00907                 gluQuadricDrawStyle((GLUquadricObj *) quadratic, GLU_POINT);
00908                 break;
00909          case WIRE:
00910                 gluQuadricDrawStyle((GLUquadricObj *) quadratic, GLU_LINE);
00911                 break;
00912          case FILL:
00913                 gluQuadricDrawStyle((GLUquadricObj *) quadratic, GLU_FILL);
00914                 break;
00915          default:
00916                 return false;
00917         }
00918 
00919         return true;
00920   }
00921 
00922  /*----------------------------------------------------------------------*/
00923 
00924   void OpenGLRenderingEngine::_reportTriangles(const u32 & triangleCount)
00925   {
00926         // Direct rendering
00927         if(!mCurrentDisplayList)
00928          mParent->getRenderWindow()->reportTriangles(triangleCount);
00929 
00930         // Display list compiling
00931         else
00932          mCurrentDisplayList->triangleCount += triangleCount;
00933   }
00934 
00935  /*----------------------------------------------------------------------*/
00936 
00937 }