00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "Renderer.h"
00018 #include "State.h"
00019 #include "Primitive.h"
00020 #include "PNGLoader.h"
00021 #include "SearchPaths.h"
00022 #include "PrimitiveIO.h"
00023 #include "ShaderCache.h"
00024 #include "Trace.h"
00025 #include <sys/time.h>
00026 #include <stdio.h>
00027 #include <unistd.h>
00028
00029 using namespace Fluxus;
00030
00031
00032
00033
00034 #ifndef GL_POLYGON_OFFSET
00035 #define GL_POLYGON_OFFSET GL_POLYGON_OFFSET_EXT
00036 #endif
00037
00038 static const int FRAMES_PER_TIME = 10;
00039 static int TimeCounter = 0;
00040 static timeval StartTime;
00041 static float FPS;
00042
00043 static const int MAXLIGHTS = 8;
00044
00045 Renderer::Renderer() :
00046 m_Initialised(false),
00047 m_InitLights(false),
00048 m_Width(640),
00049 m_Height(480),
00050 m_MotionBlur(false),
00051 m_Fade(0.02f),
00052 m_ShowAxis(false),
00053 m_Grabbed(NULL),
00054 m_ClearFrame(true),
00055 m_ClearZBuffer(true),
00056 m_ClearAccum(false),
00057 m_FogDensity(0),
00058 m_FogStart(0),
00059 m_FogEnd(100),
00060 m_ShadowLight(0),
00061 m_StereoMode(noStereo),
00062 m_MaskRed(true),
00063 m_MaskGreen(true),
00064 m_MaskBlue(true),
00065 m_MaskAlpha(true),
00066 m_Deadline(1/25.0f),
00067 m_FPSDisplay(false),
00068 m_Time(0),
00069 m_Delta(0)
00070 {
00071 Clear();
00072
00073
00074 m_LastTime.tv_sec=0;
00075 m_LastTime.tv_usec=0;
00076 }
00077
00078 Renderer::~Renderer()
00079 {
00080 TexturePainter::Shutdown();
00081 SearchPaths::Shutdown();
00082 }
00083
00085
00086 void Renderer::Clear()
00087 {
00088 m_World.Clear();
00089 m_StateStack.clear();
00090 m_CameraVec.clear();
00091 UnGrab();
00092 State InitialState;
00093 m_StateStack.push_back(InitialState);
00094
00095
00096 Camera cam;
00097 m_CameraVec.push_back(cam);
00098 }
00099
00100 void Renderer::Render()
00101 {
00102
00104 if (m_ClearFrame && !m_MotionBlur)
00105 {
00106 glClearColor(m_BGColour.r,m_BGColour.g,m_BGColour.b,m_BGColour.a);
00107 glClear(GL_COLOR_BUFFER_BIT);
00108 }
00109
00110 if (m_ClearZBuffer)
00111 {
00112 glClear(GL_DEPTH_BUFFER_BIT);
00113 }
00114
00115 if (m_ClearAccum)
00116 {
00117 glClear(GL_ACCUM_BUFFER_BIT);
00118 }
00119
00120 for (unsigned int cam=0; cam<m_CameraVec.size(); cam++)
00121 {
00122
00123 m_ShadowVolumeGen.Clear();
00124
00125 if (m_ShadowLight!=0)
00126 {
00127 RenderStencilShadows(cam);
00128 }
00129 else
00130 {
00131 PreRender(cam);
00132 m_World.Render(&m_ShadowVolumeGen,cam);
00133 m_ImmediateMode.Render(cam);
00134 m_ImmediateMode.Clear();
00135 PostRender();
00136 }
00137 }
00138
00139 timeval ThisTime;
00140
00141 ThisTime.tv_sec=0;
00142 ThisTime.tv_usec=0;
00143
00144 gettimeofday(&ThisTime,NULL);
00145 m_Delta=(ThisTime.tv_sec-m_LastTime.tv_sec)+
00146 (ThisTime.tv_usec-m_LastTime.tv_usec)*0.000001f;
00147
00148 if (m_Delta<m_Deadline)
00149 {
00150
00151 if(m_Deadline-m_Delta<1.0f)
00152 {
00153 usleep((int)((m_Deadline-m_Delta)*1000000.0f));
00154 }
00155 }
00156
00157 m_LastTime=ThisTime;
00158
00159 if (m_Delta>0.0f && m_Delta<100.0f) m_Time+=m_Delta;
00160 }
00161
00162 void Renderer::RenderStencilShadows(unsigned int CamIndex)
00163 {
00164 if (m_LightVec.size()>m_ShadowLight)
00165 {
00166 m_ShadowVolumeGen.SetLightPosition(m_LightVec[m_ShadowLight]->GetPosition());
00167 }
00168
00169 PreRender(CamIndex);
00170 glDisable(GL_LIGHT0+m_ShadowLight);
00171 m_World.Render(&m_ShadowVolumeGen,CamIndex);
00172 m_ImmediateMode.Render(CamIndex,&m_ShadowVolumeGen);
00173
00174 glClear(GL_STENCIL_BUFFER_BIT);
00175 glEnable(GL_STENCIL_TEST);
00176 glStencilFunc(GL_ALWAYS, 0, ~0);
00177 glEnable(GL_DEPTH_TEST);
00178 glDepthFunc(GL_LESS);
00179 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
00180 glDepthMask(GL_FALSE);
00181 glEnable(GL_CULL_FACE);
00182
00183 glCullFace(GL_BACK);
00184 glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
00185 m_ShadowVolumeGen.GetVolume()->Render();
00186
00187 glCullFace(GL_FRONT);
00188 glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
00189 m_ShadowVolumeGen.GetVolume()->Render();
00190
00191 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
00192 glDepthFunc(GL_EQUAL);
00193 glStencilFunc(GL_EQUAL, 0, ~0);
00194 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
00195
00196 glEnable(GL_BLEND);
00197 glBlendFunc(GL_ONE, GL_ONE);
00198 glCullFace(GL_BACK);
00199
00200 glEnable(GL_LIGHT0+m_ShadowLight);
00201
00202
00203
00204 m_World.Render(&m_ShadowVolumeGen,CamIndex);
00205 m_ImmediateMode.Render(CamIndex);
00206 m_ImmediateMode.Clear();
00207
00208 glDepthMask(GL_TRUE);
00209 glDepthFunc(GL_LEQUAL);
00210 glStencilFunc(GL_ALWAYS, 0, ~0);
00211
00212 if (m_ShadowVolumeGen.GetDebug())
00213 {
00214 m_ShadowVolumeGen.GetVolume()->GetState()->Hints=HINT_WIRE;
00215 m_ShadowVolumeGen.GetVolume()->Render();
00216 m_ShadowVolumeGen.GetVolume()->GetState()->Hints=HINT_SOLID;
00217 }
00218
00219 PostRender();
00220 }
00221
00222 void Renderer::PreRender(unsigned int CamIndex, bool PickMode)
00223 {
00224 Camera &Cam = m_CameraVec[CamIndex];
00225 if (!m_Initialised || PickMode || Cam.NeedsInit())
00226 {
00227 glViewport((int)(Cam.GetViewportX()*(float)m_Width),(int)(Cam.GetViewportY()*(float)m_Height),
00228 (int)(Cam.GetViewportWidth()*(float)m_Width),(int)(Cam.GetViewportHeight()*(float)m_Height));
00229
00230 glMatrixMode (GL_PROJECTION);
00231 glLoadIdentity();
00232
00233 if (PickMode)
00234 {
00235 GLint viewport[4]={0,0,m_Width,m_Height};
00236 gluPickMatrix(m_SelectInfo.x,m_Height-m_SelectInfo.y,
00237 m_SelectInfo.size,m_SelectInfo.size,viewport);
00238 }
00239
00240 Cam.DoProjection();
00241
00242 glEnable(GL_BLEND);
00243 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00244 glEnable(GL_LIGHTING);
00245
00246 glEnable(GL_CULL_FACE);
00247 glCullFace(GL_BACK);
00248 glFrontFace(GL_CCW);
00249
00250 glEnable(GL_RESCALE_NORMAL);
00251 glDisable(GL_COLOR_MATERIAL);
00252
00253 glEnableClientState(GL_VERTEX_ARRAY);
00254 glEnableClientState(GL_NORMAL_ARRAY);
00255 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00256 glEnableClientState(GL_COLOR_ARRAY);
00257 glEnable(GL_POLYGON_OFFSET);
00258
00259 if (m_FogDensity>0)
00260 {
00261 glEnable(GL_FOG);
00262 glFogf(GL_FOG_MODE, GL_EXP);
00263 glFogfv(GL_FOG_COLOR, m_FogColour.arr());
00264 glFogf(GL_FOG_DENSITY, m_FogDensity);
00265 glFogf(GL_FOG_HINT, GL_DONT_CARE);
00266 glFogf(GL_FOG_START, m_FogStart);
00267 glFogf(GL_FOG_END, m_FogEnd);
00268 }
00269 else
00270 {
00271 glDisable(GL_FOG);
00272 }
00273
00274 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
00275
00276 TexturePainter::Get()->Initialise();
00277
00278 m_Initialised=true;
00279 }
00280
00281 if (!m_InitLights)
00282 {
00283
00284 ClearLights();
00285 m_InitLights=true;
00286 }
00287
00288
00289 glMatrixMode (GL_MODELVIEW);
00290 glLoadIdentity();
00291
00292 PushState();
00293
00294 if (m_MotionBlur)
00295 {
00296 glEnable(GL_COLOR_MATERIAL);
00297 glPolygonMode(GL_FRONT,GL_FILL);
00298 glDisable(GL_DEPTH_TEST);
00299 glPushMatrix();
00300 glTranslatef(0,0,-10);
00301 glBegin(GL_QUADS);
00302 glColor4f(m_BGColour.r,m_BGColour.g,m_BGColour.b,m_Fade);
00303 glVertex3f(-10,-10,0);
00304 glVertex3f(10,-10,0);
00305 glVertex3f(10,10,0);
00306 glVertex3f(-10,10,0);
00307 glEnd();
00308 glPopMatrix();
00309 glEnable(GL_DEPTH_TEST);
00310 glDisable(GL_COLOR_MATERIAL);
00311 }
00312
00313 if (m_FPSDisplay && !PickMode)
00314 {
00315 PushState();
00316 GetState()->Transform.translate(Cam.GetUp(),Cam.GetLeft(),0);
00317 GetState()->Colour=dColour(0,0,1);
00318 char s[32];
00319 sprintf(s,"%f fps",FPS);
00320 DrawText(s);
00321 PopState();
00322 }
00323
00324 RenderLights(true);
00325 Cam.DoCamera();
00326 RenderLights(false);
00327
00328 glColorMask(m_MaskRed,m_MaskGreen,m_MaskBlue,m_MaskAlpha);
00329 }
00330
00331
00332 void Renderer::PostRender()
00333 {
00334
00335 glDisable(GL_TEXTURE_2D);
00336 glDisable(GL_TEXTURE_CUBE_MAP);
00337 GLSLShader::Unapply();
00338 glFrontFace(GL_CCW);
00339
00340 glDisable(GL_DEPTH_TEST);
00341 if (m_ShowAxis) Primitive::RenderAxes();
00342 glEnable(GL_DEPTH_TEST);
00343 glColorMask(true,true,true,true);
00344
00345 PopState();
00346
00347 if (m_FPSDisplay)
00348 {
00349 if (!(TimeCounter%FRAMES_PER_TIME))
00350 {
00351 timeval TimeNow;
00352 gettimeofday(&TimeNow,NULL);
00353 FPS = (TimeNow.tv_sec-StartTime.tv_sec)+(TimeNow.tv_usec-StartTime.tv_usec)*0.000001f;
00354 FPS/=(float)FRAMES_PER_TIME;
00355 FPS=1/FPS;
00356 gettimeofday(&StartTime,NULL);
00357 }
00358 TimeCounter++;
00359 }
00360
00361
00362
00363
00364
00365 }
00366
00367 void Renderer::RenderLights(bool camera)
00368 {
00369 int n=0;
00370 for (vector<Light*>::iterator i=m_LightVec.begin(); i!=m_LightVec.end(); i++)
00371 {
00372 if (n<MAXLIGHTS && (*i)->GetCameraLock()==camera)
00373 {
00374 (*i)->Render();
00375 }
00376 n++;
00377 }
00378 }
00379
00380 int Renderer::AddLight(Light *l)
00381 {
00382 l->SetIndex(m_LightVec.size());
00383 m_LightVec.push_back(l);
00384 return m_LightVec.size()-1;
00385 }
00386
00387 Light *Renderer::GetLight(int id)
00388 {
00389 if (id<(int)m_LightVec.size()) return m_LightVec[id];
00390 else return NULL;
00391 }
00392
00393 void Renderer::ClearLights()
00394 {
00395 for (unsigned int n=0; n<m_LightVec.size(); n++)
00396 {
00397 glDisable(GL_LIGHT0+n);
00398 }
00399
00400 m_LightVec.clear();
00401
00402
00403 Light *light=new Light;
00404 light->SetPosition(dVector(0,0,0));
00405 light->SetCameraLock(true);
00406 AddLight(light);
00407 }
00408
00409 int Renderer::Select(unsigned int CamIndex, int x, int y, int size)
00410 {
00411 static const int SELECT_SIZE=512;
00412 unsigned int IDs[SELECT_SIZE];
00413 memset(IDs,0,SELECT_SIZE);
00414 GLuint ID=0;
00415 glSelectBuffer(SELECT_SIZE,(GLuint*)IDs);
00416 glRenderMode(GL_SELECT);
00417 glInitNames();
00418
00419 m_SelectInfo.x=x;
00420 m_SelectInfo.y=y;
00421 m_SelectInfo.size=size;
00422
00423
00424
00425 PreRender(CamIndex,true);
00426
00427
00428 m_World.Render(&m_ShadowVolumeGen,SceneGraph::SELECT);
00429
00430 int hits=glRenderMode(GL_RENDER);
00431 unsigned int *ptr=IDs, numnames;
00432 float minz,maxz,closest=1000000;
00433
00434
00435 for (int n=0; n<hits; n++)
00436 {
00437 numnames=*ptr;
00438 ptr++;
00439 minz = (float) *ptr++/0x7fffffff;
00440 maxz = (float) *ptr++/0x7fffffff;
00441
00442
00443 if (closest>minz)
00444 {
00445 closest=minz;
00446 ID=*ptr;
00447 }
00448 for (unsigned int i=0; i<numnames; i++) *ptr++;
00449 }
00450
00451
00452
00453 m_Initialised=false;
00454 PreRender(CamIndex);
00455
00456 return ID;
00457 }
00458
00459 int Renderer::AddPrimitive(Primitive *Prim)
00460 {
00461 Prim->SetState(GetState());
00462 SceneNode *node = new SceneNode(Prim);
00463 return m_World.AddNode(GetState()->Parent,node);
00464 }
00465
00466 Primitive *Renderer::GetPrimitive(int ID)
00467 {
00468 SceneNode *node = (SceneNode*)m_World.FindNode(ID);
00469 if (node==NULL) return NULL;
00470 return node->Prim;
00471 }
00472
00473 void Renderer::RemovePrimitive(int ID)
00474 {
00475 SceneNode *node = (SceneNode*)m_World.FindNode(ID);
00476 if (node!=NULL)
00477 {
00478 if (node->Prim==m_Grabbed) UnGrab();
00479 m_World.RemoveNode(node);
00480 }
00481 }
00482
00483 void Renderer::DetachPrimitive(int ID)
00484 {
00485 SceneNode *node=(SceneNode*)m_World.FindNode(ID);
00486 if (node) m_World.Detach(node);
00487 }
00488
00489
00490 void Renderer::RenderPrimitive(Primitive *Prim)
00491 {
00492 m_ImmediateMode.Add(Prim,GetState());
00493 }
00494
00495 dMatrix Renderer::GetGlobalTransform(int ID)
00496 {
00497 dMatrix mat;
00498 SceneNode *node=(SceneNode*)m_World.FindNode(ID);
00499 if (node) mat=m_World.GetGlobalTransform(node);
00500 return mat;
00501 }
00502
00503 dBoundingBox Renderer::GetBoundingBox(int ID)
00504 {
00505 dBoundingBox bbox;
00506 SceneNode *node=(SceneNode*)m_World.FindNode(ID);
00507 if (node) m_World.GetBoundingBox(node,bbox);
00508 return bbox;
00509 }
00510
00512
00513 State *Renderer::GetState()
00514 {
00515 if (m_StateStack.empty())
00516 {
00517 Trace::Stream<<"Renderer::GetState : State stack is empty"<<endl;
00518 return NULL;
00519 }
00520
00521 return &(*m_StateStack.begin());
00522 }
00523
00524 void Renderer::ApplyState()
00525 {
00526 GetState()->Apply();
00527 }
00528
00529 void Renderer::PushState()
00530 {
00531 #ifdef DEBUG_TRACE
00532 Trace::Stream<<"Renderer::PushState"<<endl;
00533 #endif
00534
00535 m_StateStack.push_front(*GetState());
00536 }
00537
00538 void Renderer::PopState()
00539 {
00540 #ifdef DEBUG_TRACE
00541 Trace::Stream<<"Renderer::PopState"<<endl;
00542 #endif
00543
00544 if (m_StateStack.size()<2)
00545 {
00546 Trace::Stream<<"Renderer::PopState : only one state left, not popping"<<endl;
00547 }
00548 else
00549 {
00550 m_StateStack.pop_front();
00551 }
00552 }
00553
00554 void Renderer::Grab(int ID)
00555 {
00556 SceneNode *n=(SceneNode *)m_World.FindNode(ID);
00557 if (n)
00558 {
00559 Primitive *p=n->Prim;
00560 if (p)
00561 {
00562 m_Grabbed=p;
00563 }
00564 }
00565 }
00566
00567 void Renderer::UnGrab()
00568 {
00569 m_Grabbed=NULL;
00570 }
00571
00572
00573
00574
00575
00576
00577
00578 void Renderer::DrawText(const string &Text)
00579 {
00580 glPushMatrix();
00581 GetState()->Apply();
00582
00583 glDisable(GL_LIGHTING);
00584 glPushMatrix();
00585 glRasterPos3f(0.0, 0.0, -1.1);
00586 for (unsigned int n=0; n<Text.length(); n++)
00587 {
00588 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, Text.c_str()[n]);
00589 glTranslatef(1.0f,0.0f,0.0f);
00590 }
00591 glPopMatrix();
00592 glEnable(GL_LIGHTING);
00593
00594 glPopMatrix();
00595 }
00596
00597 void Renderer::ShowCursor(bool s)
00598 {
00599 if (s)
00600 {
00601 glutSetCursor(GLUT_CURSOR_INHERIT);
00602 }
00603 else
00604 {
00605 glutSetCursor(GLUT_CURSOR_NONE);
00606 }
00607
00608 }
00609
00610 void Renderer::DrawBuffer(GLenum mode)
00611 {
00612 glDrawBuffer(mode);
00613 }
00614
00615 void Renderer::ReadBuffer(GLenum mode)
00616 {
00617 glReadBuffer(mode);
00618 }
00619
00620 bool Renderer::SetStereoMode(stereo_mode_t mode)
00621 {
00622 GLboolean stereoWindowTest;
00623 switch(mode){
00624 case noStereo: m_StereoMode = noStereo;
00625 return true;
00626 case crystalEyes:
00627
00628 glGetBooleanv (GL_STEREO, &stereoWindowTest);
00629 if(stereoWindowTest){
00630 m_StereoMode = crystalEyes;
00631 return true;
00632 } else {
00633 m_StereoMode = noStereo;
00634 return false;
00635 }
00636 case colourStereo:
00637 m_StereoMode = colourStereo;
00638 return true;
00639 };
00640 return false;
00641 }
00642
00643 void Renderer::SetColourMask(bool inred, bool ingreen, bool inblue, bool inalpha)
00644 {
00645 m_MaskRed=inred;
00646 m_MaskGreen=ingreen;
00647 m_MaskBlue=inblue;
00648 m_MaskAlpha=inalpha;
00649 }
00650
00651 void Renderer::Accum(int mode, float factor)
00652 {
00653 glAccum(mode,factor);
00654 }
00655
00656 void Renderer::PrintInfo()
00657 {
00658 Trace::Stream<<"Fluxus Version "<<FLUXUS_MAJOR_VERSION<<"."<<FLUXUS_MINOR_VERSION<<endl;
00659 Trace::Stream<<"Textures Cached:"<<endl;
00660 TexturePainter::Get()->Dump();
00661 Trace::Stream<<"Primitives Cached:"<<endl;
00662 PrimitiveIO::Dump();
00663 Trace::Stream<<"Shaders cached:"<<endl;
00664 ShaderCache::Dump();
00665 Trace::Stream<<"Scenegraph:"<<endl;
00666 m_World.Dump();
00667 }