Visualization Library 2.1.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
EdgeRenderer.cpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
36 
37 using namespace vl;
38 
39 //-----------------------------------------------------------------------------
40 const RenderQueue* EdgeRenderer::render(const RenderQueue* render_queue, Camera* camera, real frame_clock)
41 {
42  // skip if renderer is disabled
43 
44  if (enableMask() == 0)
45  return render_queue;
46 
47  // enter/exit behavior contract
48 
49  class InOutContract
50  {
51  RendererAbstract* mRenderer;
52  public:
53  InOutContract(RendererAbstract* renderer, Camera* camera): mRenderer(renderer)
54  {
55  // increment the render tick.
56  mRenderer->incrementRenderTick();
57 
58  // render-target activation.
59  // note: an OpenGL context can have multiple rendering targets!
60  mRenderer->framebuffer()->activate();
61 
62  // viewport setup.
63  camera->viewport()->setClearFlags( mRenderer->clearFlags() );
64  camera->viewport()->activate();
65 
66  // dispatch the renderer-started event.
67  mRenderer->dispatchOnRendererStarted();
68 
69  // check user-generated errors.
70  VL_CHECK_OGL()
71  }
72 
73  ~InOutContract()
74  {
75  // dispatch the renderer-finished event
76  mRenderer->dispatchOnRendererFinished();
77 
78  // check user-generated errors.
79  VL_CHECK_OGL()
80  }
81  } contract(this, camera);
82 
83  // --------------- rendering ---------------
84 
85  // update actor cache
86 
87  mVisibleActors.clear();
88  for(int i=0; i<render_queue->size(); ++i)
89  {
90  if ( ! isEnabled(render_queue->at(i)->mActor) )
91  continue;
92  // fails for non-Geometry renderables
93  WFInfo* wfinfo = declareActor(render_queue->at(i)->mActor);
94  if (wfinfo)
95  {
96  mVisibleActors[render_queue->at(i)->mActor] = wfinfo;
97  }
98  }
99 
100  camera->applyProjMatrix();
101 
102  // solid
103  glEnable(GL_DEPTH_TEST);
104  glDepthFunc(GL_LEQUAL);
105  glEnable(GL_POLYGON_OFFSET_FILL);
106  glPolygonOffset( polygonOffsetFactor(), polygonOffsetUnits() );
107  glColorMask(0,0,0,0);
108  renderSolids(camera, frame_clock);
109  glDisable(GL_POLYGON_OFFSET_FILL);
110  glPolygonOffset( 0.0f, 0.0f );
111  glPolygonOffset(0,0);
112  glColorMask(1,1,1,1);
113 
114  // front wireframe
115  glLineWidth(mLineWidth);
116  if (smoothLines())
117  {
118  glEnable(GL_BLEND);
119  glEnable(GL_LINE_SMOOTH);
120  }
121  renderLines(camera);
122 
123  // back wireframe
124  glDisable(GL_DEPTH_TEST);
125  glLineWidth(mLineWidth > 2.0f ? mLineWidth / 2.0f : 1.0f);
126 #if defined(VL_OPENGL)
127  glLineStipple(1,0xF0F0);
128  glEnable(GL_LINE_STIPPLE);
129 #endif
130  if (showHiddenLines())
131  renderLines(camera);
132  glDisable(GL_LINE_SMOOTH);
133 #if defined(VL_OPENGL)
134  glDisable(GL_LINE_STIPPLE);
135 #endif
136  glDisable(GL_BLEND);
137  glLineWidth(1.0f);
138 
139  // was enabled by viewport
140  glDisable(GL_SCISSOR_TEST);
141 
142  // disable all vertex arrays
143  framebuffer()->openglContext()->bindVAS(NULL, false, true);
144 
145  VL_CHECK( !globalSettings()->checkOpenGLStates() || framebuffer()->openglContext()->isCleanState(true) );
146 
147  return render_queue;
148 }
149 //-----------------------------------------------------------------------------
150 void EdgeRenderer::renderSolids(Camera* camera, real frame_clock)
151 {
152  // transform
153  const Transform* cur_transform = NULL;
154  camera->applyViewMatrix();
155 
156  const mat4& view_matrix = camera->viewMatrix();
157 
158  for( std::map< ref<Actor>, ref<WFInfo> >::iterator it = mVisibleActors.begin(); it != mVisibleActors.end(); ++it)
159  {
160  ref<Actor> actor = it->first;
161  VL_CHECK(actor);
162  VL_CHECK(actor->lod(0));
163  WFInfo* wfinfo = it->second.get();
164  VL_CHECK(wfinfo);
165 
166  // --------------- transform ---------------
167 
168  // delta-setup for modelview matrix for the object
169  if ( actor->transform() != cur_transform )
170  {
171  cur_transform = actor->transform();
172 
173  if ( cur_transform )
174  {
175  #if 0
176  glMatrixMode(GL_MODELVIEW);
177  VL_glLoadMatrix( view_matrix.ptr() );
178  VL_glMultMatrix( cur_transform->worldMatrix().ptr() );
179  #else
180  // should guarantee better precision
181  glMatrixMode(GL_MODELVIEW);
182  VL_glLoadMatrix( (view_matrix * cur_transform->worldMatrix() ).ptr() );
183  #endif
184  }
185  else
186  {
187  glMatrixMode(GL_MODELVIEW);
188  VL_glLoadMatrix( view_matrix.ptr() );
189  }
190  }
191 
192  // note: the color is not important here
193  wfinfo->mEdgeCallback->setShowCreases(showCreases());
194  wfinfo->mEdgeCallback->onActorRenderStarted( actor.get(), frame_clock, camera, wfinfo->mGeometry.get(), NULL, 0 );
195  actor->lod(0)->render( actor.get(), NULL, camera, framebuffer()->openglContext() );
196  }
197 }
198 //-----------------------------------------------------------------------------
200 {
201  // transform
202  const Transform* cur_transform = NULL;
203  camera->applyViewMatrix();
204 
205  const mat4& view_matrix = camera->viewMatrix();
206 
207  for( std::map< ref<Actor>, ref<WFInfo> >::iterator it = mVisibleActors.begin(); it != mVisibleActors.end(); ++it)
208  {
209  ref<Actor> actor = it->first;
210  WFInfo* wfinfo = it->second.get();
211 
212  // --------------- transform ---------------
213 
214  // delta-setup for modelview matrix for the object
215  if ( actor->transform() != cur_transform )
216  {
217  cur_transform = actor->transform();
218 
219  if ( cur_transform )
220  {
221  #if 0
222  glMatrixMode(GL_MODELVIEW);
223  VL_glLoadMatrix( view_matrix.ptr() );
224  VL_glMultMatrix( cur_transform->worldMatrix().ptr() );
225  #else
226  // should guarantee better precision
227  glMatrixMode(GL_MODELVIEW);
228  VL_glLoadMatrix( (view_matrix * cur_transform->worldMatrix() ).ptr() );
229  #endif
230  }
231  else
232  {
233  glMatrixMode(GL_MODELVIEW);
234  VL_glLoadMatrix( view_matrix.ptr() );
235  }
236  }
237 
238  // note: no rendering callbacks here
239  glColor4fv( wfinfo->mColor.ptr() );
240  wfinfo->mGeometry->render( actor.get(), NULL, camera, framebuffer()->openglContext() );
241  }
242 }
243 //-----------------------------------------------------------------------------
244 EdgeRenderer::WFInfo* EdgeRenderer::declareActor(Actor* act, const fvec4& color)
245 {
246  std::map< ref<Actor>, ref<WFInfo> >::iterator it = mActorCache.find( act );
247  if (it!=mActorCache.end())
248  {
249  it->second->mColor = color;
250  return it->second.get();
251  }
252  else
253  {
254  ref<WFInfo> info = new WFInfo;
255  EdgeExtractor ee;
256  ee.setCreaseAngle( creaseAngle() );
257  if (ee.extractEdges(act))
258  {
259  info->mGeometry = ee.generateEdgeGeometry();
260  info->mEdgeCallback = new EdgeUpdateCallback(ee.edges());
261  if (info->mGeometry)
262  {
263  info->mColor = color;
264  mActorCache[act] = info;
265  return info.get();
266  }
267  }
268  }
269  return NULL;
270 }
271 //-----------------------------------------------------------------------------
272 EdgeRenderer::WFInfo* EdgeRenderer::declareActor(Actor* act)
273 {
274  std::map< ref<Actor>, ref<WFInfo> >::iterator it = mActorCache.find( act );
275  if (it!=mActorCache.end())
276  return it->second.get();
277  else
278  {
279  ref<WFInfo> info = new WFInfo;
280  EdgeExtractor ee;
281  ee.setCreaseAngle( creaseAngle() );
282  if (ee.extractEdges(act))
283  {
284  info->mGeometry = ee.generateEdgeGeometry();
285  info->mEdgeCallback = new EdgeUpdateCallback(ee.edges());
286  if (info->mGeometry)
287  {
288  info->mColor = mDefaultLineColor;
289  mActorCache[act] = info;
290  return info.get();
291  }
292  }
293  }
294  return NULL;
295 }
296 //-----------------------------------------------------------------------------
297 
Associates a Renderable object to an Effect and Transform.
Definition: Actor.hpp:130
const Renderable * lod(int lod_index) const
Returns the Renderable object representing the LOD level specifed by lod_index.
Definition: Actor.hpp:173
const mat4 & viewMatrix() const
Returns the Camera&#39;s view matrix (inverse of the modeling matrix).
Definition: Camera.hpp:160
Transform * transform()
Returns the Transform bound tho an Actor.
Definition: Actor.hpp:190
Implements a 4x4 matrix transform used to define the position and orientation of an Actor...
Definition: Transform.hpp:72
const T * get() const
Definition: Object.hpp:128
float creaseAngle() const
The minimum angle (in degrees) considered to generate crease-edges (default is 44 degrees)...
The EdgeExtractor class extracts the edges from one or more Geometry objects.
int size() const
Definition: RenderQueue.hpp:90
OpenGLContext * openglContext()
The OpenGLContext bound to a render target.
const FramebufferObject * framebuffer() const
The Framebuffer on which the rendering is performed.
Definition: Renderer.hpp:100
std::map< ref< Actor >, ref< WFInfo > > mVisibleActors
std::map< ref< Actor >, ref< WFInfo > > mActorCache
void extractEdges(Geometry *geom)
Extracts the edges from the given Geometry and appends them to edges().
float polygonOffsetFactor() const
Defines the factor parameter used to render the lines over the polygons. See also http://www...
bool showCreases() const
If set to true shows not only the edges that define the silhouette of an object but also the crease e...
float polygonOffsetUnits() const
Defines the units parameter used to render the lines over the polygons. See also http://www.opengl.org/sdk/docs/man/xhtml/glPolygonOffset.xml for more information.
void applyViewMatrix() const
Loads the GL_MODELVIEW matrix with the Camera&#39;s view matrix.
Definition: Camera.cpp:88
void dispatchOnRendererFinished()
Dispatches the onRendererFinished() event to the registered RenderEventCallback objects.
Viewport * viewport()
The viewport bound to a camera.
Definition: Camera.hpp:140
Visualization Library main namespace.
The EdgeUpdateCallback class updates at every frame the edges of an Actor for the purpose of edge-enh...
void activate() const
Definition: Viewport.cpp:72
const RenderQueue * render(const RenderQueue *in_render_queue, Camera *camera, real frame_clock)
Takes as input the render queue to render and returns a possibly filtered render queue for further pr...
bool smoothLines() const
If set to true the lines will be rendered using antialiasing.
void incrementRenderTick()
Increments the rendering tick count.
bool showHiddenLines() const
If set to true shows also the hidden lines with a dashed pattern.
Base class providing all the basic funtionalities of a Renderer.
void activate(EFramebufferBind target=FBB_FRAMEBUFFER)
Activates the FramebufferObject by calling bindFramebuffer() and bindDrawBuffers() ...
#define NULL
Definition: OpenGLDefs.hpp:81
const mat4 & worldMatrix() const
Returns the world matrix used for rendering.
Definition: Transform.hpp:168
bool isEnabled(unsigned int mask)
Definition: Renderer.hpp:93
void applyProjMatrix() const
Loads the GL_PROJECTION matrix with the Camera&#39;s projection matrix.
Definition: Camera.cpp:81
void render(const Actor *actor, const Shader *shader, const Camera *camera, OpenGLContext *gl_context)
Renders the Renderable and if necessary compiles the display list and updates the BufferObjects...
Definition: Renderable.hpp:80
void renderLines(Camera *camera)
The RenderQueue class collects a list of RenderToken objects to be sorted and rendered.
Definition: RenderQueue.hpp:45
void bindVAS(const IVertexAttribSet *vas, bool use_vbo, bool force)
Activates the specified vertex attribute set - For internal use only.
#define VL_CHECK_OGL()
Definition: OpenGL.hpp:156
const std::vector< Edge > & edges() const
T_Scalar * ptr()
Definition: Matrix4.hpp:345
void setCreaseAngle(float a)
The minimum angle (in degrees) considered to generate crease-edges.
const RenderToken * at(int i) const
Definition: RenderQueue.hpp:57
Represents a virtual camera defining, among other things, the point of view from which scenes can be ...
Definition: Camera.hpp:49
void renderSolids(Camera *camera, real frame_clock)
ref< Geometry > generateEdgeGeometry() const
virtual const FramebufferObject * framebuffer() const =0
The Framebuffer on which the rendering is performed.
#define VL_CHECK(expr)
Definition: checks.hpp:73
unsigned int enableMask() const
Enable mask used to enable/disable the rendering of matching Actors.
EClearFlags clearFlags() const
The clear flags used to clear the viewport.
void dispatchOnRendererStarted()
Dispatches the onRendererStarted() event to the registered RenderEventCallback objects.
VLCORE_EXPORT GlobalSettings * globalSettings()
Returns VisulizationLibrary&#39;s global settings.
Definition: pimpl.cpp:52
void setClearFlags(EClearFlags clear_flags)
Usually you want to use rather RendererAbstract::setClearFlags()
Definition: Viewport.hpp:98
WFInfo * declareActor(Actor *act, const fvec4 &color)
Generates and caches all the information needed to render the edges of the given Actor using the spec...