Visualization Library 2.0.0

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

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
Rendering.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 
32 #include <vlGraphics/Rendering.hpp>
34 #include <vlGraphics/Renderer.hpp>
37 #include <vlGraphics/GLSL.hpp>
38 #include <vlCore/Log.hpp>
39 #include <vlCore/Say.hpp>
40 
41 using namespace vl;
42 
43 //------------------------------------------------------------------------------
45  mAutomaticResourceInit(true),
46  mCullingEnabled(true),
47  mEvaluateLOD(true),
48  mShaderAnimationEnabled(true),
49  mNearFarClippingPlanesOptimized(false)
50 {
51  VL_DEBUG_SET_OBJECT_NAME()
56  mCamera = new Camera;
57  mTransform = new Transform;
58  mRenderers.push_back( new Renderer );
59 }
60 //------------------------------------------------------------------------------
62 {
63  super::operator=(other);
64 
65  mEnableMask = other.mEnableMask;
68  mEvaluateLOD = other.mEvaluateLOD;
71 
73  /*mActorQueue = other.mActorQueue;*/
74  /*mRenderQueue = other.mRenderQueue;*/
76  mRenderers = other.mRenderers;
77  mCamera = other.mCamera;
78  mTransform = other.mTransform;
79 
80  return *this;
81 }
82 //------------------------------------------------------------------------------
84 {
85  VL_CHECK(camera());
86  VL_CHECK(camera()->viewport());
87 
88  // if rendering is disabled skip all.
89 
90  if ( enableMask() == 0 )
91  return;
92 
93  // enter/exit behavior contract
94 
95  class InOutContract
96  {
97  Rendering* mRendering;
98  OpenGLContext* mOpenGLContext;
99 
100  public:
101  InOutContract(Rendering* rendering): mRendering(rendering)
102  {
103  VL_CHECK(mRendering->renderers().size());
104  VL_CHECK(mRendering->renderers()[0]->framebuffer());
105  VL_CHECK(mRendering->renderers()[0]->framebuffer()->openglContext());
106 
107  // as stated in the documentation all the renderers must target the same OpenGLContext
108  mOpenGLContext = mRendering->renderers()[0]->framebuffer()->openglContext();
109 
110  // activate OpenGL context
111  mOpenGLContext->makeCurrent();
112  VL_CHECK_OGL(); // the first check must be done when the context is active!
113 
114  // render states ]shield[
115  mOpenGLContext->resetContextStates(RCS_RenderingStarted);
116 
117  // pre rendering callback
118  mRendering->dispatchOnRenderingStarted();
119 
120  // check user-generated errors.
121  VL_CHECK_OGL()
122  }
123 
124  ~InOutContract()
125  {
126  // post rendering callback
127  mRendering->dispatchOnRenderingFinished();
128 
129  // release rendered Actors
130  mRendering->actorQueue()->resize(0);
131 
132  // check user-generated errors.
133  VL_CHECK_OGL()
134 
135  // render states ]shield[
136  mOpenGLContext->resetContextStates(RCS_RenderingFinished);
137  }
138  } contract(this);
139 
140  // --------------- rendering ---------------
141 
142  if (renderers().empty())
143  {
144  vl::Log::error("Rendering::render(): no Renderer specified for this Rendering!\n");
145  VL_TRAP();
146  return;
147  }
148 
149  if (!renderers()[0]->framebuffer())
150  {
151  vl::Log::error("Rendering::render(): no RendererTarget specified for Renderer #0!\n");
152  VL_TRAP();
153  return;
154  }
155 
156  if (!renderers()[0]->framebuffer()->openglContext())
157  {
158  vl::Log::error("Rendering::render(): invalid Framebuffer for Renderer #0, OpenGLContext is NULL!\n");
159  VL_TRAP();
160  return;
161  }
162 
163  if (sceneManagers()->empty())
164  return;
165 
166  if (!camera())
167  return;
168 
169  if (!camera()->viewport())
170  return;
171 
172  // transform
173 
174  if (transform() != NULL)
176 
177  // camera transform update (can be redundant)
178 
179  if (camera()->boundTransform())
180  camera()->setModelingMatrix( camera()->boundTransform()->worldMatrix() );
181 
182  VL_CHECK_OGL()
183 
184  // culling & actor queue filling
185 
187 
188  // if near/far clipping planes optimization is enabled don't perform far-culling
190  {
191  // perform only near culling with plane at distance 0
192  camera()->frustum().planes().resize(5);
193  camera()->frustum().planes()[4] = Plane( camera()->modelingMatrix().getT(),
194  camera()->modelingMatrix().getZ());
195  }
196 
197  actorQueue()->clear();
198  for(int i = 0; i < sceneManagers()->size(); ++i )
199  {
200  if ( isEnabled( sceneManagers()->at(i)->enableMask() ) )
201  {
202  if ( cullingEnabled() && sceneManagers()->at(i)->cullingEnabled() )
203  {
204  if ( sceneManagers()->at(i)->boundsDirty() ) {
205  sceneManagers()->at(i)->computeBounds();
206  }
207 
208  // try to cull the scene with both bsphere and bbox
209  if ( camera()->frustum().cull( sceneManagers()->at(i)->boundingSphere() ) ||
210  camera()->frustum().cull( sceneManagers()->at(i)->boundingBox() ) ) {
211  continue;
212  } else {
213  sceneManagers()->at(i)->extractVisibleActors( *actorQueue(), camera() );
214  }
215  }
216  else {
217  sceneManagers()->at(i)->extractVisibleActors( *actorQueue(), NULL );
218  }
219  }
220  }
221 
222  // collect near/far clipping planes optimization information
224  {
225  Sphere world_bounding_sphere;
226  for(int i=0; i<actorQueue()->size(); ++i)
227  world_bounding_sphere += actorQueue()->at(i)->boundingSphere();
228 
229  // compute the optimized
230  camera()->computeNearFarOptimizedProjMatrix(world_bounding_sphere);
231 
232  // recompute frustum planes to account for new near/far values
234  }
235 
236  // render queue filling
237 
238  renderQueue()->clear();
240 
241  // sort the rendering queue according to this renderer sorting algorithm
242 
243  if (renderQueueSorter())
245 
246  // --- RENDER THE QUEUE: loop through the renderers, feeding the output of one as input for the next ---
247 
248  const RenderQueue* render_queue = renderQueue();
249  for(int i=0; i<renderers().size(); ++i)
250  {
251  if (renderers()[i])
252  {
253  if (renderers()[i]->framebuffer() == NULL)
254  {
255  vl::Log::error( Say("Rendering::render(): no RendererTarget specified for Renderer #%n!\n") << i );
256  VL_TRAP();
257  continue;
258  }
259 
260  if (renderers()[i]->framebuffer()->openglContext() == NULL)
261  {
262  vl::Log::error( Say("Rendering::render(): invalid Framebuffer for Renderer #%n, OpenGLContext is NULL!\n") << i );
263  VL_TRAP();
264  continue;
265  }
266 
267  // loop the rendering
268  render_queue = renderers()[i]->render( render_queue, camera(), frameClock() );
269  }
270  }
271 
272  VL_CHECK_OGL()
273 }
274 //------------------------------------------------------------------------------
276 {
277  if (actor_list == NULL)
278  return;
279 
280  if (actor_list->empty())
281  return;
282 
283  if (camera() == NULL)
284  return;
285 
286  if (enableMask() == 0)
287  return;
288 
289  RenderQueue* list = renderQueue();
290  std::set<Shader*> shader_set;
291 
292  // iterate actor list
293 
294  for(int iactor=0; iactor < actor_list->size(); iactor++)
295  {
296  Actor* actor = actor_list->at(iactor);
297 
298  VL_CHECK(actor->lod(0))
299 
300  if ( ! isEnabled(actor) )
301  continue;
302 
303  // update the Actor's bounds
304  actor->computeBounds();
305 
306  Effect* effect = actor->effect();
307  VL_CHECK(effect)
308 
309  // effect override: select the first that matches
310 
311  for( std::map< unsigned int, ref<Effect> >::iterator eom_it = mEffectOverrideMask.begin();
312  eom_it != mEffectOverrideMask.end();
313  ++eom_it )
314  {
315  if (eom_it->first & actor->enableMask())
316  {
317  effect = eom_it->second.get();
318  break;
319  }
320  }
321 
322  if ( !isEnabled(effect->enableMask()) )
323  continue;
324 
325  // --------------- LOD evaluation ---------------
326 
327  int effect_lod = effect->evaluateLOD( actor, camera() );
328 
329  int geometry_lod = 0;
330  if ( evaluateLOD() )
331  geometry_lod = actor->evaluateLOD( camera() );
332 
333  // --------------- M U L T I P A S S I N G ---------------
334 
335  RenderToken* prev_pass = NULL;
336  const int pass_count = effect->lod(effect_lod)->size();
337  for(int ipass=0; ipass<pass_count; ++ipass)
338  {
339  // setup the shader to be used for this pass
340 
341  Shader* shader = effect->lod(effect_lod)->at(ipass);
342 
343  // --------------- fill render token ---------------
344 
345  // create a render token
346  RenderToken* tok = list->newToken(prev_pass != NULL);
347 
348  // multipass chain: implemented as a linked list
349  if ( prev_pass != NULL )
350  prev_pass->mNextPass = tok;
351  prev_pass = tok;
352  tok->mNextPass = NULL;
353  // track the current state
354  tok->mActor = actor;
355  tok->mRenderable = actor->lod(geometry_lod);
356  // set the shader used (multipassing shader or effect->shader())
357  tok->mShader = shader;
358 
359  if ( shaderAnimationEnabled() )
360  {
361  VL_CHECK(frameClock() >= 0)
362  if( frameClock() >= 0 )
363  {
364  // note that the condition is != as opposed to <
365  if ( shader->lastUpdateTime() != frameClock() && shader->shaderAnimator() && shader->shaderAnimator()->isEnabled() )
366  {
367  // update
368  shader->shaderAnimator()->updateShader( shader, camera(), frameClock() );
369 
370  // note that we update this after
371  shader->setLastUpdateTime( frameClock() );
372  }
373  }
374  }
375 
376  if ( automaticResourceInit() && shader_set.find(shader) == shader_set.end() )
377  {
378  shader_set.insert(shader);
379 
380  // link GLSLProgram
381  if ( shader->glslProgram() && ! shader->glslProgram()->linked() )
382  {
383  shader->glslProgram()->linkProgram();
384  // VL_CHECK( shader->glslProgram()->linked() );
385  }
386 
387  // lazy texture creation
388  if ( shader->gocRenderStateSet() )
389  {
390  size_t count = shader->gocRenderStateSet()->renderStatesCount();
391  RenderStateSlot* states = shader->gocRenderStateSet()->renderStates();
392  for( size_t i=0; i<count; ++i )
393  {
394  if (states[i].mRS->type() == RS_TextureSampler)
395  {
396  TextureSampler* tex_unit = static_cast<TextureSampler*>( states[i].mRS.get() );
397  VL_CHECK(tex_unit);
398  if (tex_unit)
399  {
400  if (tex_unit->texture() && tex_unit->texture()->setupParams() && ! tex_unit->texture()->handle() ) {
401  tex_unit->texture()->createTexture();
402  }
403  }
404  }
405  }
406  }
407  }
408 
409  tok->mEffectRenderRank = effect->renderRank();
410  }
411  }
412 }
413 //------------------------------------------------------------------------------
Associates a Renderable object to an Effect and Transform.
Definition: Actor.hpp:130
ref< RenderQueueSorter > mRenderQueueSorter
Definition: Rendering.hpp:215
const Renderable * lod(int lod_index) const
Returns the Renderable object representing the LOD level specifed by lod_index.
Definition: Actor.hpp:173
const T * at(int i) const
Definition: Collection.hpp:100
void setLastUpdateTime(real time)
Used internally.
Definition: Shader.hpp:2333
unsigned int handle() const
OpenGL texture handle as returned by glGenTextures().
Definition: Texture.hpp:678
void resetContextStates(EResetContextStates start_or_finish)
Resets the OpenGL states necessary to begin and finish a rendering. - For internal use only...
void resize(int size)
Definition: Collection.hpp:80
const Transform * transform() const
The root of the Transform tree updated at every rendering frame.
Definition: Rendering.hpp:148
int evaluateLOD(Camera *camera)
Definition: Actor.cpp:55
Implements a 4x4 matrix transform used to define the position and orientation of an Actor...
Definition: Transform.hpp:72
bool mAutomaticResourceInit
Definition: Rendering.hpp:224
RenderStateSet * gocRenderStateSet()
Definition: Shader.hpp:2233
size_t renderStatesCount() const
The Renderer class executes the actual rendering on the given RenderQueue.
Definition: Renderer.hpp:48
A simple String formatting class.
Definition: Say.hpp:124
The Plane class defines a plane using a normal and an origin.
Definition: Plane.hpp:49
Rendering()
Constructor.
Definition: Rendering.cpp:44
void sort(RenderQueueSorter *sorter, Camera *camera)
Definition: RenderQueue.hpp:95
int size() const
Definition: Collection.hpp:82
std::vector< Plane > & planes()
Definition: Frustum.hpp:54
ShaderAnimator * shaderAnimator()
Returns the ShaderAnimator used to update/animate a Shader (see vl::ShaderAnimator documentation)...
Definition: Shader.hpp:2324
bool linked() const
Returns true if the program has been succesfully linked.
Definition: GLSL.hpp:288
void dispatchOnRenderingStarted()
Calls the RenderEventCallback::onRenderingStarted() method of all the active callback objects...
const SetupParams * setupParams() const
See SetupParams.
Definition: Texture.hpp:731
Renderable * mRenderable
Definition: RenderToken.hpp:59
Represents an OpenGL context, possibly a widget or a pbuffer, which can also respond to keyboard...
RenderQueueSorter * renderQueueSorter()
The RenderQueueSorter used to perform the sorting of the objects to be rendered, if NULL no sorting i...
Definition: Rendering.hpp:90
ref< ActorCollection > mActorQueue
Definition: Rendering.hpp:216
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
Definition: Log.cpp:165
virtual void render()
Executes the rendering.
Definition: Rendering.cpp:83
bool createTexture()
Creates a texture using the parameters specified by the last prepareTexture*() called.
Definition: Texture.cpp:1083
const Camera * camera() const
The Camera that defines the point of view and viewport to be used when rendering the scene...
Definition: Rendering.hpp:131
Texture * texture()
The texture sampler by a texture unit.
Definition: Shader.hpp:1768
const Sphere & boundingSphere() const
Returns the bounding sphere (not guaranteed to be up to date) that contains this Actor.
Definition: Actor.hpp:208
bool isEnabled() const
Whether the ShaderAnimator is enabled or not.
Definition: Shader.hpp:1810
bool nearFarClippingPlanesOptimized() const
Returns whether near/far planes optimization is enabled.
Definition: Rendering.hpp:185
bool automaticResourceInit() const
Whether OpenGL resources such as textures and GLSL programs should be automatically initialized befor...
Definition: Rendering.hpp:182
Internally used by the rendering engine.
Definition: RenderToken.hpp:47
ref< Camera > mCamera
Definition: Rendering.hpp:219
unsigned int enableMask() const
The enable mask of an Actor is usually used to defines whether the actor should be rendered or not de...
Definition: Actor.hpp:270
Visualization Library main namespace.
int evaluateLOD(Actor *actor, Camera *camera)
If a LODEvaluator is installed computes the effect LOD to be used otherwise returns 0...
Definition: Effect.cpp:44
Rendering & operator=(const Rendering &other)
Assignment operator.
Definition: Rendering.cpp:61
const Frustum & frustum() const
The view frustum of the camera used to perform frustum culling.
Definition: Camera.hpp:132
Implements the default RenderQueueSorter.
bool linkProgram(bool force_relink=false)
Links the GLSLProgram calling glLinkProgram(handle()) only if the program needs to be linked...
Definition: GLSL.cpp:446
void computeFrustumPlanes()
Computes the Camera&#39;s frustum planes in world space.
Definition: Camera.cpp:172
void computeNearFarOptimizedProjMatrix(const Sphere &scene_bounding_sphere)
The near and far clipping planes are adjusted to fit the provided scene_bounding_sphere.
Definition: Camera.cpp:100
unsigned int enableMask() const
The enable mask of the Rendering, used to define wheter the rendering is enabled or not...
#define VL_TRAP()
Definition: checks.hpp:70
Collection< Renderer > mRenderers
Definition: Rendering.hpp:218
real frameClock() const
The update time of the current rendering frame.
const Shader * mShader
Definition: RenderToken.hpp:60
ActorCollection * actorQueue()
Definition: Rendering.hpp:212
The TextureSampler class associates a Texture object to an OpenGL texture unit.
Definition: Shader.hpp:1747
virtual void updateShader(Shader *shader, Camera *camera, real cur_time)=0
Reimplement this function to update/animate a Shader.
std::map< unsigned int, ref< Effect > > mEffectOverrideMask
Definition: Rendering.hpp:222
void computeWorldMatrixRecursive(Camera *camera=NULL)
Computes the world matrix by concatenating the parent&#39;s world matrix with its local matrix...
Definition: Transform.hpp:214
void setModelingMatrix(const mat4 &mat)
Sets the Camera&#39;s modelingMatrix() (inverse of the view matrix).
Definition: Camera.hpp:165
bool shaderAnimationEnabled() const
Whether Shader::shaderAnimator()->updateShader() should be called or not.
Definition: Rendering.hpp:168
#define NULL
Definition: OpenGLDefs.hpp:81
int renderRank() const
Returns the rendering rank of an Effect.
Definition: Effect.hpp:167
Manages most of the OpenGL rendering states responsible of the final aspect of the rendered objects...
Definition: Shader.hpp:1830
The Sphere class defines a sphere using a center and a radius using vl::real precision.
Definition: Sphere.hpp:43
The Rendering class collects all the information to perform the rendering of a scene.
Definition: Rendering.hpp:69
unsigned int enableMask() const
The enable mask of an Actor&#39;s Effect defines whether the actor should be rendered or not depending on...
Definition: Effect.hpp:203
bool cullingEnabled() const
Whether the installed SceneManager[s] should perform Actor culling or not in order to maximize the re...
Definition: Rendering.hpp:174
ref< RenderQueue > mRenderQueue
Definition: Rendering.hpp:217
RenderToken * newToken(bool multipass)
Definition: RenderQueue.hpp:61
Defines the sequence of Shader objects used to render an Actor.
Definition: Effect.hpp:91
The RenderQueue class collects a list of RenderToken objects to be sorted and rendered.
Definition: RenderQueue.hpp:45
Effect * effect()
Returns the Effect bound to an Actor.
Definition: Actor.hpp:199
#define VL_CHECK_OGL()
Definition: OpenGL.hpp:156
Defined as a simple subclass of Collection<Actor>, see Collection for more information.
Definition: Actor.hpp:479
void dispatchOnRenderingFinished()
Calls the RenderEventCallback::onRenderingFinished() method of all the active callback objects...
ref< Collection< SceneManager > > mSceneManagers
Definition: Rendering.hpp:221
bool mCullingEnabled
Definition: Rendering.hpp:225
It&#39;s basically an std::vector for Objects that is itself an Object so it can be reference counted and...
Definition: Collection.hpp:49
void computeBounds()
Computes the bounding box and bounding sphere of an Actor if boundsDirty().
Definition: Actor.cpp:95
ref< Transform > mTransform
Definition: Rendering.hpp:220
bool empty() const
Definition: Collection.hpp:84
ERenderState type() const
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
bool mShaderAnimationEnabled
Definition: Rendering.hpp:227
void fillRenderQueue(ActorCollection *actor_list)
Definition: Rendering.cpp:275
Represents a virtual camera defining, among other things, the point of view from which scenes can be ...
Definition: Camera.hpp:50
const GLSLProgram * glslProgram() const
Returns the GLSLProgram associated to a Shader (if any)
Definition: Shader.hpp:2194
bool evaluateLOD() const
Whether the Level-Of-Detail should be evaluated or not.
Definition: Rendering.hpp:158
bool mNearFarClippingPlanesOptimized
Definition: Rendering.hpp:228
const RenderStateSlot * renderStates() const
RenderQueue * renderQueue()
Definition: Rendering.hpp:211
real lastUpdateTime() const
Last time this Actor was animated/updated using a shaderAnimator().
Definition: Shader.hpp:2330
const RenderToken * mNextPass
Definition: RenderToken.hpp:56
const Collection< Renderer > & renderers() const
The list of Renderers used to perform the rendering.
Definition: Rendering.hpp:95
#define VL_CHECK(expr)
Definition: checks.hpp:73
Collection< SceneManager > * sceneManagers()
Returns the list of SceneManager[s] containing the Actor[s] to be rendered.
Definition: Rendering.hpp:137
ref< RenderState > mRS
bool isEnabled(unsigned int mask)
const ref< ShaderPasses > & lod(int lod_level) const
Returns the ShaderPasses representing the specified LOD level.
Definition: Effect.hpp:171