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