Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlGraphics/EdgeRenderer.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #include <vlCore/GlobalSettings.hpp>
00033 #include <vlGraphics/EdgeRenderer.hpp>
00034 #include <vlGraphics/RenderQueue.hpp>
00035 #include <vlGraphics/OpenGLContext.hpp>
00036 
00037 using namespace vl;
00038 
00039 //-----------------------------------------------------------------------------
00040 const RenderQueue* EdgeRenderer::render(const RenderQueue* render_queue, Camera* camera, real frame_clock)
00041 {
00042   // skip if renderer is disabled
00043 
00044   if (enableMask() == 0)
00045     return render_queue;
00046 
00047   // enter/exit behavior contract
00048 
00049   class InOutContract 
00050   {
00051     RendererAbstract* mRenderer;
00052   public:
00053     InOutContract(RendererAbstract* renderer, Camera* camera): mRenderer(renderer)
00054     {
00055       // increment the render tick.
00056       mRenderer->incrementRenderTick();
00057 
00058       // render-target activation.
00059       // note: an OpenGL context can have multiple rendering targets!
00060       mRenderer->framebuffer()->activate();
00061 
00062       // viewport setup.
00063       camera->viewport()->setClearFlags( mRenderer->clearFlags() );
00064       camera->viewport()->activate();
00065 
00066       // dispatch the renderer-started event.
00067       mRenderer->dispatchOnRendererStarted();
00068 
00069       // check user-generated errors.
00070       VL_CHECK_OGL()
00071     }
00072 
00073     ~InOutContract()
00074     {
00075       // dispatch the renderer-finished event
00076       mRenderer->dispatchOnRendererFinished();
00077 
00078       // check user-generated errors.
00079       VL_CHECK_OGL()
00080     }
00081   } contract(this, camera);
00082 
00083   // --------------- rendering --------------- 
00084 
00085   // update actor cache
00086 
00087   mVisibleActors.clear();
00088   for(int i=0; i<render_queue->size(); ++i)
00089   {
00090     if ( !isEnabled(render_queue->at(i)->mActor->enableMask()) )
00091       continue;
00092     // fails for non-Geometry renderables
00093     WFInfo* wfinfo = declareActor(render_queue->at(i)->mActor);
00094     if (wfinfo)
00095     {
00096       mVisibleActors[render_queue->at(i)->mActor] = wfinfo;
00097     }
00098   }
00099 
00100   camera->applyProjMatrix();
00101 
00102   // solid
00103   glEnable(GL_DEPTH_TEST);
00104   glDepthFunc(GL_LEQUAL);
00105   glEnable(GL_POLYGON_OFFSET_FILL);
00106   glPolygonOffset( polygonOffsetFactor(), polygonOffsetUnits() );
00107   glColorMask(0,0,0,0);
00108     renderSolids(camera, frame_clock);
00109   glDisable(GL_POLYGON_OFFSET_FILL);
00110   glPolygonOffset( 0.0f, 0.0f );
00111   glPolygonOffset(0,0);
00112   glColorMask(1,1,1,1);
00113 
00114   // front wireframe
00115   glLineWidth(mLineWidth);
00116   if (smoothLines())
00117   {
00118     glEnable(GL_BLEND);
00119     glEnable(GL_LINE_SMOOTH);
00120   }
00121   renderLines(camera);
00122 
00123   // back wireframe
00124   glDisable(GL_DEPTH_TEST);
00125   glLineWidth(mLineWidth > 2.0f ? mLineWidth / 2.0f : 1.0f);
00126 #if defined(VL_OPENGL)
00127   glLineStipple(1,0xF0F0);
00128   glEnable(GL_LINE_STIPPLE);
00129 #endif
00130   if (showHiddenLines()) 
00131     renderLines(camera);
00132   glDisable(GL_LINE_SMOOTH);
00133 #if defined(VL_OPENGL)
00134   glDisable(GL_LINE_STIPPLE);
00135 #endif
00136   glDisable(GL_BLEND);
00137   glLineWidth(1.0f);
00138 
00139   // was enabled by viewport
00140   glDisable(GL_SCISSOR_TEST);
00141 
00142   // disable all vertex arrays
00143   framebuffer()->openglContext()->bindVAS(NULL, false, true);
00144 
00145   VL_CHECK( !globalSettings()->checkOpenGLStates() || framebuffer()->openglContext()->isCleanState(true) );
00146 
00147   return render_queue;
00148 }
00149 //-----------------------------------------------------------------------------
00150 void EdgeRenderer::renderSolids(Camera* camera, real frame_clock)
00151 {
00152   // transform
00153   const Transform* cur_transform = NULL;
00154   camera->applyViewMatrix();
00155 
00156   const mat4& view_matrix = camera->viewMatrix();
00157 
00158   for( std::map< ref<Actor>, ref<WFInfo> >::iterator it = mVisibleActors.begin(); it != mVisibleActors.end(); ++it)
00159   {
00160     ref<Actor> actor = it->first;
00161     VL_CHECK(actor);
00162     VL_CHECK(actor->lod(0));
00163     WFInfo* wfinfo = it->second.get();
00164     VL_CHECK(wfinfo);
00165 
00166     // --------------- transform ---------------
00167 
00168     // delta-setup for modelview matrix for the object
00169     if ( actor->transform() != cur_transform )
00170     {
00171       cur_transform = actor->transform();
00172 
00173       if ( cur_transform )
00174       {
00175         #if 0
00176           glMatrixMode(GL_MODELVIEW);
00177           VL_glLoadMatrix( view_matrix.ptr() );
00178           VL_glMultMatrix( cur_transform->worldMatrix().ptr() );
00179         #else
00180           // should guarantee better precision
00181           glMatrixMode(GL_MODELVIEW);
00182           VL_glLoadMatrix( (view_matrix * cur_transform->worldMatrix() ).ptr() );
00183         #endif
00184       }
00185       else
00186       {
00187         glMatrixMode(GL_MODELVIEW);
00188         VL_glLoadMatrix( view_matrix.ptr() );
00189       }
00190     }
00191 
00192     // note: the color is not important here
00193     wfinfo->mEdgeCallback->setShowCreases(showCreases());
00194     wfinfo->mEdgeCallback->onActorRenderStarted( actor.get(), frame_clock, camera, wfinfo->mGeometry.get(), NULL, 0 );
00195     actor->lod(0)->render( actor.get(), NULL, camera, framebuffer()->openglContext() );
00196   }
00197 }
00198 //-----------------------------------------------------------------------------
00199 void EdgeRenderer::renderLines(Camera* camera)
00200 {
00201   // transform
00202   const Transform* cur_transform = NULL;
00203   camera->applyViewMatrix();
00204 
00205   const mat4& view_matrix = camera->viewMatrix();
00206 
00207   for( std::map< ref<Actor>, ref<WFInfo> >::iterator it = mVisibleActors.begin(); it != mVisibleActors.end(); ++it)
00208   {
00209     ref<Actor> actor = it->first;
00210     WFInfo* wfinfo = it->second.get();
00211 
00212     // --------------- transform ---------------
00213 
00214     // delta-setup for modelview matrix for the object
00215     if ( actor->transform() != cur_transform )
00216     {
00217       cur_transform = actor->transform();
00218 
00219       if ( cur_transform )
00220       {
00221         #if 0
00222           glMatrixMode(GL_MODELVIEW);
00223           VL_glLoadMatrix( view_matrix.ptr() );
00224           VL_glMultMatrix( cur_transform->worldMatrix().ptr() );
00225         #else
00226           // should guarantee better precision
00227           glMatrixMode(GL_MODELVIEW);
00228           VL_glLoadMatrix( (view_matrix * cur_transform->worldMatrix() ).ptr() );
00229         #endif
00230       }
00231       else
00232       {
00233         glMatrixMode(GL_MODELVIEW);
00234         VL_glLoadMatrix( view_matrix.ptr() );
00235       }
00236     }
00237 
00238     // note: no rendering callbacks here
00239     glColor4fv( wfinfo->mColor.ptr() );
00240     wfinfo->mGeometry->render( actor.get(), NULL, camera, framebuffer()->openglContext() );
00241   }
00242 }
00243 //-----------------------------------------------------------------------------
00244 EdgeRenderer::WFInfo* EdgeRenderer::declareActor(Actor* act, const fvec4& color)
00245 {
00246   std::map< ref<Actor>, ref<WFInfo> >::iterator it = mActorCache.find( act );
00247   if (it!=mActorCache.end())
00248   {
00249     it->second->mColor = color;
00250     return it->second.get();
00251   }
00252   else
00253   {
00254     ref<WFInfo> info = new WFInfo;
00255     EdgeExtractor ee;
00256     ee.setCreaseAngle( creaseAngle() );
00257     if (ee.extractEdges(act))
00258     {
00259       info->mGeometry = ee.generateEdgeGeometry();
00260       info->mEdgeCallback = new EdgeUpdateCallback(ee.edges());
00261       if (info->mGeometry)
00262       {
00263         info->mColor = color;
00264         mActorCache[act] = info;
00265         return info.get();
00266       }
00267     }
00268   }
00269   return NULL;
00270 }
00271 //-----------------------------------------------------------------------------
00272 EdgeRenderer::WFInfo* EdgeRenderer::declareActor(Actor* act)
00273 {
00274   std::map< ref<Actor>, ref<WFInfo> >::iterator it = mActorCache.find( act );
00275   if (it!=mActorCache.end())
00276     return it->second.get();
00277   else
00278   {
00279     ref<WFInfo> info = new WFInfo;
00280     EdgeExtractor ee;
00281     ee.setCreaseAngle( creaseAngle() );
00282     if (ee.extractEdges(act))
00283     {
00284       info->mGeometry = ee.generateEdgeGeometry();
00285       info->mEdgeCallback = new EdgeUpdateCallback(ee.edges());
00286       if (info->mGeometry)
00287       {
00288         info->mColor = mDefaultLineColor;
00289         mActorCache[act] = info;
00290         return info.get();
00291       }
00292     }
00293   }
00294   return NULL;
00295 }
00296 //-----------------------------------------------------------------------------
00297 

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:36.
Permission is granted to use this page to write and publish articles regarding Visualization Library.