Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://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