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