Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <vlCore/GlobalSettings.hpp>
00033 #include <vlGraphics/Renderer.hpp>
00034 #include <vlGraphics/OpenGLContext.hpp>
00035 #include <vlGraphics/GLSL.hpp>
00036 #include <vlGraphics/RenderQueue.hpp>
00037 #include <vlCore/Log.hpp>
00038
00039 using namespace vl;
00040
00041
00042
00043
00044 Renderer::Renderer()
00045 {
00046 VL_DEBUG_SET_OBJECT_NAME()
00047
00048 mProjViewTransfCallback = new ProjViewTransfCallback;
00049
00050 mDummyEnables = new EnableSet;
00051 mDummyStateSet = new RenderStateSet;
00052 }
00053
00054 namespace
00055 {
00056 struct GLSLProgState
00057 {
00058 public:
00059 GLSLProgState(): mCamera(NULL), mTransform(NULL), mGLSLProgUniformSet(NULL), mShaderUniformSet(NULL), mActorUniformSet(NULL) {}
00060
00061 bool operator<(const GLSLProgState& other) const
00062 {
00063 if ( mCamera != other.mCamera )
00064 return mCamera < other.mCamera;
00065 else
00066 if ( mTransform != other.mTransform )
00067 return mTransform < other.mTransform;
00068 else
00069 if ( mGLSLProgUniformSet != other.mGLSLProgUniformSet )
00070 return mGLSLProgUniformSet < other.mGLSLProgUniformSet;
00071 else
00072 if ( mShaderUniformSet != other.mShaderUniformSet )
00073 return mShaderUniformSet < other.mShaderUniformSet;
00074 else
00075 return mActorUniformSet < other.mActorUniformSet;
00076 }
00077
00078 const Camera* mCamera;
00079 const Transform* mTransform;
00080 const UniformSet* mGLSLProgUniformSet;
00081 const UniformSet* mShaderUniformSet;
00082 const UniformSet* mActorUniformSet;
00083 };
00084 }
00085
00086 const RenderQueue* Renderer::render(const RenderQueue* render_queue, Camera* cur_camera, real frame_clock)
00087 {
00088 VL_CHECK_OGL()
00089
00090
00091
00092 if (enableMask() == 0)
00093 return render_queue;
00094
00095
00096
00097 class InOutContract
00098 {
00099 Renderer* mRenderer;
00100 public:
00101 InOutContract(Renderer* renderer, Camera* camera): mRenderer(renderer)
00102 {
00103
00104 mRenderer->mRenderTick++;
00105
00106
00107
00108 mRenderer->framebuffer()->activate();
00109
00110
00111 camera->viewport()->setClearFlags( mRenderer->clearFlags() );
00112 camera->viewport()->activate();
00113
00114
00115 mRenderer->dispatchOnRendererStarted();
00116
00117
00118 VL_CHECK_OGL()
00119 }
00120
00121 ~InOutContract()
00122 {
00123
00124 mRenderer->dispatchOnRendererFinished();
00125
00126
00127 VL_CHECK_OGL()
00128
00129
00130 }
00131 } contract(this, cur_camera);
00132
00133
00134
00135 std::map<const GLSLProgram*, GLSLProgState> glslprogram_map;
00136
00137 OpenGLContext* opengl_context = framebuffer()->openglContext();
00138
00139
00140
00141
00142 const RenderStateSet* cur_render_state_set = NULL;
00143 const EnableSet* cur_enable_set = NULL;
00144 const Scissor* cur_scissor = NULL;
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 for(int itok=0; itok < render_queue->size(); ++itok)
00156 {
00157 const RenderToken* tok = render_queue->at(itok); VL_CHECK(tok);
00158 Actor* actor = tok->mActor; VL_CHECK(actor);
00159
00160 if ( !isEnabled(actor->enableMask()) )
00161 continue;
00162
00163
00164
00165
00166
00167
00168
00169 const Scissor* scissor = actor->scissor() ? actor->scissor() : tok->mShader->scissor();
00170 if (cur_scissor != scissor)
00171 {
00172 cur_scissor = scissor;
00173 if (cur_scissor)
00174 {
00175 cur_scissor->enable(cur_camera->viewport());
00176 }
00177 else
00178 {
00179
00180 VL_CHECK(glIsEnabled(GL_SCISSOR_TEST))
00181 glScissor(cur_camera->viewport()->x(), cur_camera->viewport()->y(), cur_camera->viewport()->width(), cur_camera->viewport()->height());
00182 }
00183 }
00184
00185
00186 for( int ipass=0; tok != NULL; tok = tok->mNextPass, ++ipass )
00187 {
00188 VL_CHECK_OGL()
00189
00190
00191
00192 const Shader* shader = tok->mShader;
00193
00194
00195
00196 for( std::map< unsigned int, ref<Shader> >::const_iterator eom_it = mShaderOverrideMask.begin();
00197 eom_it != mShaderOverrideMask.end();
00198 ++eom_it )
00199 {
00200 if ( eom_it->first & actor->enableMask() )
00201 {
00202 shader = eom_it->second.get();
00203 break;
00204 }
00205 }
00206
00207
00208
00209 if ( cur_render_state_set != shader->getRenderStateSet() )
00210 {
00211 opengl_context->applyRenderStates( shader->getRenderStateSet(), cur_camera );
00212 cur_render_state_set = shader->getRenderStateSet();
00213 }
00214
00215 VL_CHECK_OGL()
00216
00217
00218
00219 if ( cur_enable_set != shader->getEnableSet() )
00220 {
00221 opengl_context->applyEnables( shader->getEnableSet() );
00222 cur_enable_set = shader->getEnableSet();
00223 }
00224
00225 #ifndef NDEBUG
00226 if (glGetError() != GL_NO_ERROR)
00227 {
00228 Log::error("An unsupported OpenGL glEnable/glDisable capability has been enabled!\n");
00229 VL_TRAP()
00230 }
00231 #endif
00232
00233
00234
00235
00236
00237 actor->dispatchOnActorRenderStarted( frame_clock, cur_camera, tok->mRenderable, shader, ipass );
00238
00239 VL_CHECK_OGL()
00240
00241
00242
00243 VL_CHECK( !shader->glslProgram() || shader->glslProgram()->linked() );
00244
00245 VL_CHECK_OGL()
00246
00247
00248 const Transform* cur_transform = actor->transform();
00249 const GLSLProgram* cur_glsl_program = NULL;
00250 const UniformSet* cur_glsl_prog_uniform_set = NULL;
00251 const UniformSet* cur_shader_uniform_set = NULL;
00252 const UniformSet* cur_actor_uniform_set = NULL;
00253
00254
00255 if (shader->glslProgram() && shader->glslProgram()->handle())
00256 {
00257 cur_glsl_program = shader->glslProgram();
00258
00259
00260 if (cur_glsl_program->getUniformSet() && !cur_glsl_program->getUniformSet()->uniforms().empty())
00261 cur_glsl_prog_uniform_set = cur_glsl_program->getUniformSet();
00262
00263 if (shader->getUniformSet() && !shader->getUniformSet()->uniforms().empty())
00264 cur_shader_uniform_set = shader->getUniformSet();
00265
00266 if (actor->getUniformSet() && !actor->getUniformSet() ->uniforms().empty())
00267 cur_actor_uniform_set = actor->getUniformSet();
00268 }
00269
00270 bool update_cm = false;
00271 bool update_tr = false;
00272 bool update_pu = false;
00273 bool update_su = false;
00274 bool update_au = false;
00275 GLSLProgState* glsl_state = NULL;
00276
00277
00278 std::map<const GLSLProgram*, GLSLProgState>::iterator glsl_state_it = glslprogram_map.find(cur_glsl_program);
00279
00280 if ( glsl_state_it == glslprogram_map.end() )
00281 {
00282
00283
00284
00285
00286
00287 glsl_state = &glslprogram_map[cur_glsl_program];
00288 update_cm = true;
00289 update_tr = true;
00290 update_pu = cur_glsl_prog_uniform_set != NULL;
00291 update_su = cur_shader_uniform_set != NULL;
00292 update_au = cur_actor_uniform_set != NULL;
00293 }
00294 else
00295 {
00296
00297
00298
00299
00300 glsl_state = &glsl_state_it->second;
00301
00302 update_cm = glsl_state->mCamera != cur_camera;
00303 update_tr = glsl_state->mTransform != cur_transform;
00304 update_pu = glsl_state->mGLSLProgUniformSet != cur_glsl_prog_uniform_set && cur_glsl_prog_uniform_set != NULL;
00305 update_su = glsl_state->mShaderUniformSet != cur_shader_uniform_set && cur_shader_uniform_set != NULL;
00306 update_au = glsl_state->mActorUniformSet != cur_actor_uniform_set && cur_actor_uniform_set != NULL;
00307 }
00308
00309
00310 glsl_state->mCamera = cur_camera;
00311 glsl_state->mTransform = cur_transform;
00312 glsl_state->mGLSLProgUniformSet = cur_glsl_prog_uniform_set;
00313 glsl_state->mShaderUniformSet = cur_shader_uniform_set;
00314 glsl_state->mActorUniformSet = cur_actor_uniform_set;
00315
00316
00317
00318 VL_CHECK_OGL()
00319
00320 if (update_cm || update_tr)
00321 projViewTransfCallback()->updateMatrices( update_cm, update_tr, cur_glsl_program, cur_camera, cur_transform );
00322
00323 VL_CHECK_OGL()
00324
00325
00326
00327
00328 VL_CHECK( !opengl_context->areUniformsColliding(cur_shader_uniform_set, cur_actor_uniform_set) );
00329 VL_CHECK( !opengl_context->areUniformsColliding(cur_shader_uniform_set, cur_glsl_prog_uniform_set ) );
00330 VL_CHECK( !opengl_context->areUniformsColliding(cur_actor_uniform_set, cur_glsl_prog_uniform_set ) );
00331
00332 VL_CHECK_OGL()
00333
00334
00335 if (update_pu)
00336 {
00337 VL_CHECK( cur_glsl_prog_uniform_set && cur_glsl_prog_uniform_set->uniforms().size() );
00338 VL_CHECK( shader->getRenderStateSet()->glslProgram() && shader->getRenderStateSet()->glslProgram()->handle() )
00339 cur_glsl_program->applyUniformSet( cur_glsl_prog_uniform_set );
00340 }
00341
00342 VL_CHECK_OGL()
00343
00344
00345 if ( update_su )
00346 {
00347 VL_CHECK( cur_shader_uniform_set && cur_shader_uniform_set->uniforms().size() );
00348 VL_CHECK( shader->getRenderStateSet()->glslProgram() && shader->getRenderStateSet()->glslProgram()->handle() )
00349 cur_glsl_program->applyUniformSet( cur_shader_uniform_set );
00350 }
00351
00352 VL_CHECK_OGL()
00353
00354
00355 if ( update_au )
00356 {
00357 VL_CHECK( cur_actor_uniform_set && cur_actor_uniform_set->uniforms().size() );
00358 VL_CHECK( shader->getRenderStateSet()->glslProgram() && shader->getRenderStateSet()->glslProgram()->handle() )
00359 cur_glsl_program->applyUniformSet( cur_actor_uniform_set );
00360 }
00361
00362 VL_CHECK_OGL()
00363
00364
00365
00366
00367 tok->mRenderable->render( actor, shader, cur_camera, opengl_context );
00368
00369 VL_CHECK_OGL()
00370
00371
00372 if (shader != tok->mShader)
00373 break;
00374 }
00375 }
00376
00377
00378 opengl_context->applyEnables( mDummyEnables.get() ); VL_CHECK_OGL();
00379
00380
00381 opengl_context->applyRenderStates( mDummyStateSet.get(), cur_camera ); VL_CHECK_OGL();
00382
00383
00384 VL_glActiveTexture( GL_TEXTURE0 ); VL_CHECK_OGL();
00385 if (Has_Fixed_Function_Pipeline)
00386 VL_glClientActiveTexture( GL_TEXTURE0 ); VL_CHECK_OGL();
00387
00388
00389 glDisable(GL_SCISSOR_TEST); VL_CHECK_OGL();
00390
00391
00392 opengl_context->bindVAS(NULL, false, false); VL_CHECK_OGL();
00393
00394 VL_CHECK( !globalSettings()->checkOpenGLStates() || framebuffer()->openglContext()->isCleanState(true) );
00395
00396 return render_queue;
00397 }
00398