VRUT::ChcRenderer Class Reference

Ray Tracer module - implements recursive ray tracing. More...

#include <ChcRenderer.h>

Inheritance diagram for VRUT::ChcRenderer:

VRUT::RenderGlModule VRUT::RenderModule VRUT::SceneModule VRUT::Module

List of all members.

Public Member Functions

 ChcRenderer (const MODULE_ID &_id, const wxString &_name, EventHandler *msgSink)
 Class constructor - do not alter.
virtual ~ChcRenderer ()
 Class destructor - deinitialize your data.
virtual wxString GetDesc () const
 Always overload method giving description for your module.
virtual void Draw ()
virtual void Deinitialize ()
void DrawItems (BVH::ItemsList &itemsList)
 draw the geoemtry list obtained by culling the bvh
void DrawItemsReverse (BVH::BlendedList &itemsList)
void DrawNode (const GeometryNode *node)
 Draw a geometry node.
void RenderBox (const AABB &box)
 Render a bounding box.
void ProcessNode (NodeInfo &info, const VECTOR3 &cameraPos, const int planeMask, vector< const GeometryNode * > &blendedNodes, priority_queue< NodeInfo > &nodeStack)
void PullUpInvisibility (BVHNode *node)
void PullUpVisibility (BVHNode *node)

Protected Member Functions

virtual void processEvent (wxCommandEvent &evt)
 Overload this to process events you need.
virtual bool Initialize ()
 initialize Opengl

Protected Attributes

int var
 Add any variables.
Parameter::ParameterIdentificator varParamID
 Add var param identificator to register this as parameter.
int frame
 number of current frame
vector< ChcNodeInfonodeInfo
stack< OcclusionQuery * > occlusionQueries
 occlusion queries used by the CHC method
int renderedNodes
 number of nodes rendered in the current frame
int renderedBlendedNodes
 number of nodes rendered in the current frame
int queriedNodes
 number of queried nodes


Detailed Description

Ray Tracer module - implements recursive ray tracing.

Definition at line 64 of file ChcRenderer.h.


Constructor & Destructor Documentation

VRUT::ChcRenderer::ChcRenderer ( const MODULE_ID _id,
const wxString &  _name,
EventHandler msgSink 
) [inline]

Class constructor - do not alter.

Initialize your variables Do not change other than param name when initializing param identificators

Register your params - choose GUI type or just register w/o GUI

Definition at line 105 of file ChcRenderer.h.

00108               : RenderGlModule(_id, _name, msgSink),
00111                 varParamID(_name, wxT("var"), _id)
00112          {
00114               //            REGISTER_PARAM_GUI_SLIDER(varParamID, wxT("100"), 0, 200);
00115          }

virtual VRUT::ChcRenderer::~ChcRenderer (  )  [inline, virtual]

Class destructor - deinitialize your data.

Definition at line 118 of file ChcRenderer.h.

00119          {
00120          }


Member Function Documentation

virtual void VRUT::ChcRenderer::processEvent ( wxCommandEvent &  evt  )  [inline, protected, virtual]

Overload this to process events you need.

Always call base method

Remember to process registered param update events

Reimplemented from VRUT::RenderGlModule.

Definition at line 79 of file ChcRenderer.h.

00080          {
00082               RenderGlModule::processEvent(evt);
00083               
00084               switch (evt.GetEventType()) {
00086               case Event::EVT_PARAM_SET:
00087                 UPDATE_PARAM_FROM_EVENT_INT(varParamID, var, evt);
00088                 break;
00089               }
00090          }

bool ChcRenderer::Initialize (  )  [protected, virtual]

initialize Opengl

Using default (sphere) mapping for texture coordinates generation

Build texture

Init shaders

Resize arrays

Reimplemented from VRUT::RenderGlModule.

Definition at line 24 of file ChcRenderer.cpp.

00024                         {
00025 
00026   if (!initialized) {
00027        bool res = RenderGlModule::Initialize();
00028        
00029        GLenum err = glewInit();
00030        //  _assert(err == GLEW_OK, (char *)glewGetErrorString(err),
00031        //              "RendererWidget::initializeGL");
00032        
00033        //_assert(GLEW_VERSION_2_0 != 0, "OpenGL 2.0 required");
00034        
00035        if (res) {
00036          vector<OcclusionQuery *> queries;
00037          const int nq = 1000;
00038          OcclusionQuery::GenQueries(queries, nq);
00039          for (int i=0; i < nq; i++)
00040               occlusionQueries.push(queries[i]);
00041        }
00042        initialized = res;
00043   }
00044   
00045   return initialized;
00046 }

virtual wxString VRUT::ChcRenderer::GetDesc (  )  const [inline, virtual]

Always overload method giving description for your module.

Reimplemented from VRUT::RenderGlModule.

Definition at line 123 of file ChcRenderer.h.

00124          {
00125               return wxT("Advanced Renderer using occlusion culling");
00126          }

void ChcRenderer::Draw (  )  [virtual]

This is the most important method in any render module It is called by kernel with GL context properly set so any GL calls can be done here and nowhere else

Clear buffer even if nothing to render

Lock camera but don't block readers if not needed

Check for scene changes and reinitialize modified nodes

Set projection matrix

Fit camera if scene is being imported

Set view matrix

Camera not in node

Sphere - frustum first

AABB - frustum

Reimplemented from VRUT::RenderGlModule.

Definition at line 159 of file ChcRenderer.cpp.

00160 {
00161   frame++;
00162 
00164   glClearColor(0.4, 0.3, 0.6, 0.0);
00165   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00166   
00167   wxMutexLocker paramsLocker(paramsMutex);
00168   scene = GetSceneMgr()->GetScene(GetSceneID());
00169   if (!scene)
00170        return;
00171   
00172   // copy the camera node
00173   Camera *pcam = (Camera *)scene->GetNode(cameraID);
00174   //BVH should be updated, updating here could allocate memory on module's heap
00175   //which could cause problems if module is unloaded before deallocating
00176   BVH * bvh = scene->GetBVH();
00177   if (!pcam || !bvh || !Initialize())
00178        {
00179          scene = (Scene *)NULL;
00180          return;
00181        }
00182 
00184   bool wrLockNeeded = !pcam->IsValid();
00185 
00186   if (wrLockNeeded)
00187        pcam->WriteLock();
00188   else
00189        pcam->ReadLock();
00190 
00191   // copy the camera
00192   Camera camera = *pcam;
00193   
00194   if (wrLockNeeded)
00195        pcam->WriteUnlock();
00196   else
00197        pcam->ReadUnlock();
00198 
00199   vboRenderUpdated = false;
00201   ResetNodes();
00202   
00204   glMatrixMode(GL_PROJECTION);
00205   
00207   /*   if (sceneImportMode)
00208               {
00209               WriteLocker fitLock(*camera);
00210               scene->Fit(cameraID, false);
00211               }*/
00212   
00213   scene->UpdateTransformation(camera.GetID());
00214   unsigned w, h;
00215   camera.GetWidthHeight(&w, &h);
00216   glViewport(0, 0, w, h);
00217   glLoadMatrixf(camera.GetProjectionMatrix()->_m);
00219   glMatrixMode(GL_MODELVIEW);
00220   glLoadMatrixf(camera.GetWorldTransMatrix()->Inverse()._m);
00221   
00222   
00223   
00224   if (drawBVH) {
00225        LOG(wxString::Format(wxT("DraBVH: %i"), drawBVH));
00226        drawBVHHierarchy();
00227   }
00228 
00229   //Scene lights
00230   drawLights();
00231   
00232 
00233   if (nodeInfo.size() != bvh->numberOfNodes) {
00234        LOG(wxString::Format(wxT("Number of nodes: %i"), bvh->numberOfNodes));
00235        nodeInfo.resize(bvh->numberOfNodes);
00236        for (unsigned int i=0; i < nodeInfo.size(); i++)
00237          nodeInfo[i].lastVisibleFrame = 24390252;
00238   }
00239   
00240   
00241   vector<const GeometryNode *> blendedNodes;
00242   priority_queue< NodeInfo > nodeStack;
00243 
00244 
00245   
00246   queue<QueryInfo> queryQueue;
00247   
00248   nodeStack.push(NodeInfo(0, (BVHNode *)bvh->GetRoot(), 0.0f));
00249   VECTOR3 cameraPos = camera.GetWorldTransMatrix()->ExtractTranslation();
00250 
00251   renderedNodes = 0;
00252   renderedBlendedNodes = 0;
00253   queriedNodes = 0;
00254   while (!nodeStack.empty() || !queryQueue.empty()) {
00255        // process finished queries
00256        
00257        while (!queryQueue.empty() &&
00258                  queryQueue.front().query->ResultAvailable()) {
00259          QueryInfo *qi = &queryQueue.front();
00260          
00261          if (qi->query->GetQueryResult() != 0) {
00262               if (!qi->info.node->IsLeaf() ||
00263                      nodeInfo[qi->info.node->id].lastVisibleFrame != frame-1)
00264                 ProcessNode(qi->info, 
00265                                      cameraPos,
00266                                      qi->info.planeMask,
00267                                      blendedNodes,
00268                                      nodeStack);
00269               PullUpVisibility(qi->info.node);
00270          } else {
00271               // only update the visibility info
00272               // pull up invisibility
00273               //            PullUpInvisibility(qi->info.node);
00274          }
00275          
00276          queryQueue.pop();
00277          occlusionQueries.push(qi->query);
00278        }
00279 
00280        if (!nodeStack.empty()) {
00281          
00282          NodeInfo info = nodeStack.top();
00283          nodeStack.pop();
00284          //     LOG(wxString::Format(wxT("Process node: %i"), info.node->id));
00285 
00286          bvh->UpdateBV(info.node);
00287          Camera::VFC_RESULT result = Camera::INTERSECT;
00288          unsigned int planeMask = info.planeMask;
00290          
00291          if (!info.node->GetAABB()->PointIsIn(cameraPos)) {
00292               if (planeMask!=63) {
00293                 // if planeMask == 63 the box is completely inside
00295                 if (!info.node->GetBSphere()->Intersects(camera.GetBSphere()))
00296                      result = Camera::OUTSIDE;
00297                 else
00299                      result = camera.InFrustum(*info.node->GetAABB(),
00300                                                                  &info.node->LastOut(),
00301                                                                  &planeMask);
00302               }
00303               
00304               if (result != Camera::OUTSIDE) {
00305                 if (info.node->IsLeaf() ||
00306                        (nodeInfo[info.node->id].lastVisibleFrame != frame-1)
00307                        ) {
00308                      queriedNodes++;
00309                      // perform stop-and-wait occlusion culling
00310                      glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT);
00311                      
00312                      glDisable(GL_CULL_FACE);
00313                      glDepthMask(GL_FALSE);
00314                      glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
00315                      
00316                      OcclusionQuery *query = occlusionQueries.top();
00317                      occlusionQueries.pop();
00318                      
00319                      query->BeginQuery();
00320                      RenderBox(*info.node->GetAABB());
00321                      query->EndQuery();
00322                      
00323                      glPopAttrib();
00324                      
00325                      queryQueue.push(QueryInfo(query, info));
00326                      
00327                      //              if (query->GetQueryResult() == 0) {
00328                      //                   result = Camera::OUTSIDE;
00329                      //              }
00330 
00331                      if (info.node->IsLeaf() &&
00332                             nodeInfo[info.node->id].lastVisibleFrame == frame-1) {
00333                        // render previously visible leaves immediatelly
00334                        ProcessNode(info, cameraPos, planeMask, blendedNodes, nodeStack);
00335                      }
00336                 } else
00337                      ProcessNode(info, cameraPos, planeMask, blendedNodes, nodeStack);
00338               }
00339          } else 
00340               ProcessNode(info, cameraPos, planeMask, blendedNodes, nodeStack);
00341          
00342          
00343          //   if (result != Camera::OUTSIDE) {
00344          //     ProcessNode(info, cameraPos, planeMask, blendedNodes, nodeStack);
00345          //   }
00346        }
00347   }
00348   
00349   // now render the transparent objects
00350   if (blendedNodes.size()) {
00351        glEnable(GL_BLEND);
00352        for (int i = blendedNodes.size()-1; i >=0; i--) {
00353          renderedBlendedNodes++;
00354          //     LOG(wxString::Format(wxT("Render blended node")));
00355          DrawNode(blendedNodes[i]);
00356        }
00357        glDisable(GL_BLEND);
00358   }
00359   
00360   //  query->EndQuery();
00361   //  unsigned int pixelCount = query->GetQueryResult();
00362   LOG(wxString::Format(wxT("Opaque nodes: %i"), renderedNodes));
00363   LOG(wxString::Format(wxT("Blended nodes: %i"), renderedBlendedNodes));
00364   LOG(wxString::Format(wxT("Queried nodes: %i"), queriedNodes));
00365   
00366   
00367   scene = (Scene *)NULL;
00368 }

virtual void VRUT::ChcRenderer::Deinitialize (  )  [inline, virtual]

Use this to deinitialize and release render data It is also called by kernel with GL context set so you can use anything like glDelete* etc.

Reimplemented from VRUT::RenderGlModule.

Definition at line 135 of file ChcRenderer.h.

00136          {
00137          }

void ChcRenderer::DrawItems ( BVH::ItemsList itemsList  ) 

draw the geoemtry list obtained by culling the bvh

Draw node

Definition at line 68 of file ChcRenderer.cpp.

00069 {
00070   //Draw the geometry list
00071   for (BVH::ItemsList::const_iterator nodeIt = itemsList.begin();
00072           nodeIt != itemsList.end();
00073           nodeIt++)
00074        {
00075          const GeometryNode * node = (const GeometryNode *)scene->GetNode(*nodeIt);
00076          if (!node->IsActive())
00077               continue;
00078          
00079          glPushMatrix();
00080          glMultMatrixf(node->GetWorldTransMatrix()->_m);
00081          
00083          if (useVBO && vboSupported)
00084               drawVBO(node);
00085          else
00086               drawDispList(node);
00087          
00088          glPopMatrix();
00089        }
00090 }

void ChcRenderer::DrawItemsReverse ( BVH::BlendedList itemsList  ) 

draw the geoemtry list in the reverse order obtained by culling the bvh

Draw node

Definition at line 93 of file ChcRenderer.cpp.

00094 {
00095   //Draw the geometry list
00096   for (BVH::BlendedList::const_reverse_iterator nodeIt = itemsList.rbegin();
00097           nodeIt != itemsList.rend();
00098           nodeIt++)
00099        {
00100               const GeometryNode * node = (const GeometryNode *)scene->GetNode(nodeIt->second);
00101               if (!node->IsActive())
00102                      continue;
00103 
00104               glPushMatrix();
00105               glMultMatrixf(node->GetWorldTransMatrix()->_m);
00106 
00108               if (useVBO && vboSupported)
00109                      drawVBO(node);
00110               else
00111                      drawDispList(node);
00112 
00113               glPopMatrix();
00114        }
00115 }

void ChcRenderer::DrawNode ( const GeometryNode node  ) 

Draw a geometry node.

Draw node

Definition at line 50 of file ChcRenderer.cpp.

00051 {
00052   if (!node->IsActive())
00053        return;
00054   
00055   glPushMatrix();
00056   glMultMatrixf(node->GetWorldTransMatrix()->_m);
00057   
00059   if (useVBO && vboSupported)
00060        drawVBO(node);
00061   else
00062        drawDispList(node);
00063   
00064   glPopMatrix();
00065 }

void ChcRenderer::RenderBox ( const AABB box  ) 

Render a bounding box.

Definition at line 120 of file ChcRenderer.cpp.

00121 {
00122   
00123   glBegin(GL_QUADS);
00124   glVertex3d(box.MinBound.x, box.MaxBound.y, box.MinBound.z );
00125   glVertex3d(box.MaxBound.x, box.MaxBound.y, box.MinBound.z );
00126   glVertex3d(box.MaxBound.x, box.MinBound.y, box.MinBound.z );
00127   glVertex3d(box.MinBound.x, box.MinBound.y, box.MinBound.z );
00128 
00129   glVertex3d(box.MinBound.x, box.MinBound.y, box.MaxBound.z );
00130   glVertex3d(box.MaxBound.x, box.MinBound.y, box.MaxBound.z );
00131   glVertex3d(box.MaxBound.x, box.MaxBound.y, box.MaxBound.z );
00132   glVertex3d(box.MinBound.x, box.MaxBound.y, box.MaxBound.z );
00133 
00134   glVertex3d(box.MaxBound.x, box.MinBound.y, box.MinBound.z );
00135   glVertex3d(box.MaxBound.x, box.MinBound.y, box.MaxBound.z );
00136   glVertex3d(box.MaxBound.x, box.MaxBound.y, box.MaxBound.z );
00137   glVertex3d(box.MaxBound.x, box.MaxBound.y, box.MinBound.z );
00138 
00139   glVertex3d(box.MinBound.x, box.MinBound.y, box.MinBound.z );
00140   glVertex3d(box.MinBound.x, box.MinBound.y, box.MaxBound.z );
00141   glVertex3d(box.MinBound.x, box.MaxBound.y, box.MaxBound.z );
00142   glVertex3d(box.MinBound.x, box.MaxBound.y, box.MinBound.z );
00143   
00144   glVertex3d(box.MinBound.x, box.MinBound.y, box.MinBound.z );
00145   glVertex3d(box.MaxBound.x, box.MinBound.y, box.MinBound.z );
00146   glVertex3d(box.MaxBound.x, box.MinBound.y, box.MaxBound.z );
00147   glVertex3d(box.MinBound.x, box.MinBound.y, box.MaxBound.z );
00148 
00149   glVertex3d(box.MinBound.x, box.MaxBound.y, box.MinBound.z );
00150   glVertex3d(box.MaxBound.x, box.MaxBound.y, box.MinBound.z );
00151   glVertex3d(box.MaxBound.x, box.MaxBound.y, box.MaxBound.z );
00152   glVertex3d(box.MinBound.x, box.MaxBound.y, box.MaxBound.z );
00153   
00154   glEnd();
00155 }

void ChcRenderer::ProcessNode ( NodeInfo info,
const VECTOR3 cameraPos,
const int  planeMask,
vector< const GeometryNode * > &  blendedNodes,
priority_queue< NodeInfo > &  nodeStack 
)

Definition at line 372 of file ChcRenderer.cpp.

00378 {
00379 
00380   //  if (info.node->id < nodeInfo.size())
00381   //   nodeInfo[info.node->id].lastVisibleFrame = frame;
00382   
00383   if (info.node->IsLeaf()) {
00384        const GeometryNode * sceneNode =
00385          (const GeometryNode *)scene->GetNode(info.node->GetSceneNodeID());
00386        
00387        const Material * material =
00388          scene->GetMaterial(sceneNode->GetMaterialID());
00389        
00390        if (material && material->flags & Material::BLENDED)
00391          blendedNodes.push_back(sceneNode);
00392        else {
00393          renderedNodes++;
00394          //     LOG(wxString::Format(wxT("Render node: %i"), info.node->id));
00395          DrawNode(sceneNode);
00396        }
00397        
00398   } else {
00399        nodeStack.push( NodeInfo(planeMask,
00400                                                   (BVHNode *)info.node->GetLChild(),
00401                                                   -SqrDistance(cameraPos,
00402                                                                         info.node->GetLChild()->GetAABB()->Center())));
00403        nodeStack.push( NodeInfo(planeMask,
00404                                                   (BVHNode *)info.node->GetRChild(),
00405                                                   -SqrDistance(cameraPos,
00406                                                                         info.node->GetRChild()->GetAABB()->Center())));
00407   }
00408 }

void ChcRenderer::PullUpInvisibility ( BVHNode node  ) 

Definition at line 420 of file ChcRenderer.cpp.

00421 {
00422   nodeInfo[node->id].lastVisibleFrame = frame-1;
00423   BVHNode *n = node->GetParent();
00424   while (n) {
00425        if (nodeInfo[n->GetLChild()->id].lastVisibleFrame != frame &&
00426               nodeInfo[n->GetRChild()->id].lastVisibleFrame != frame
00427               )
00428          nodeInfo[n->id].lastVisibleFrame = frame-1;
00429        else
00430          break;
00431        n = n->GetParent();
00432   }
00433 }

void ChcRenderer::PullUpVisibility ( BVHNode node  ) 

Definition at line 411 of file ChcRenderer.cpp.

00412 {
00413   while (node && nodeInfo[node->id].lastVisibleFrame != frame) {
00414        nodeInfo[node->id].lastVisibleFrame = frame;
00415        node = node->GetParent();
00416   }
00417 }


Member Data Documentation

int VRUT::ChcRenderer::var [protected]

Add any variables.

Definition at line 68 of file ChcRenderer.h.

Add var param identificator to register this as parameter.

Definition at line 71 of file ChcRenderer.h.

int VRUT::ChcRenderer::frame [protected]

number of current frame

Definition at line 74 of file ChcRenderer.h.

Definition at line 76 of file ChcRenderer.h.

occlusion queries used by the CHC method

Definition at line 95 of file ChcRenderer.h.

number of nodes rendered in the current frame

Definition at line 97 of file ChcRenderer.h.

number of nodes rendered in the current frame

Definition at line 99 of file ChcRenderer.h.

number of queried nodes

Definition at line 101 of file ChcRenderer.h.


The documentation for this class was generated from the following files:

Generated on Tue Mar 10 14:41:46 2009 for VRUT by  doxygen 1.5.5