Project

General

Profile

SO3Engine
SO3DeferredLightCompositionPass.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
27#include "SO3Renderer/SO3Root.h"
30#include "Ogre.h"
31
32namespace SO3
33{
34
35SDeferredLightRenderOperation::SDeferredLightRenderOperation(Ogre::CompositorInstance* instance, const Ogre::CompositionPass* pass)
36{
37 mViewport = instance->getChain()->getViewport();
38
39 // Reference to deferred light manager
40 deferredLightManager = SDeferredLightManager::getSingletonPtr();
41
42 //Get the names of the GBuffer textures
43 const Ogre::CompositionPass::InputTex& input0 = pass->getInput(0);
44 mTexName0 = instance->getTextureInstanceName(input0.name, input0.mrtIndex);
45 const Ogre::CompositionPass::InputTex& input1 = pass->getInput(1);
46 mTexName1 = instance->getTextureInstanceName(input1.name, input1.mrtIndex);
47
48 // Create the ambient light
49 ambientLight = new SDeferredLightAmbient(SDeferredLightManager::getSingleton().GetDeferredLightAmbientMaterialGenerator());
50 if(ambientLight)
51 {
52 const Ogre::MaterialPtr& mat = ambientLight->getMaterial();
53 mat->load();
54 }
55}
56
58{
59 SO3_SAFE_DELETE(ambientLight);
60}
61
62void injectTechnique(Ogre::SceneManager* sm, Ogre::Technique* tech, Ogre::Renderable* rend, const Ogre::LightList* lightList)
63{
64 for(unsigned short i=0; i<tech->getNumPasses(); ++i)
65 {
66 Ogre::Pass* pass = tech->getPass(i);
67 sm->_injectRenderWithPass(pass, rend, false, false, lightList);
68 }
69}
70
71void SDeferredLightRenderOperation::execute(Ogre::SceneManager* sm, Ogre::RenderSystem* rs)
72{
73 // Get the active camera
74 Ogre::Camera* cam = mViewport->getCamera();
75
76 // Updating ambiant light
77 if(ambientLight)
78 {
79 ambientLight->UpdateFromCamera(cam);
80 Ogre::Technique* tech = ambientLight->getMaterial()->getBestTechnique();
81 injectTechnique(sm, tech, ambientLight, 0);
82 }
83
84 // Updating all lights that affects the frustrum
85 const Ogre::LightList& lightList = sm->_getLightsAffectingFrustum();
86 for (Ogre::LightList::const_iterator it = lightList.begin(); it != lightList.end(); it++)
87 {
88 // Used by Ogre::SceneManager::_injectRenderWithPass
89 Ogre::LightList ll;
90 ll.push_back(*it);
91
92 // Do we need to create a new SDeferredLight for the OgreLight?
93 SDeferredLight* deferredLight = deferredLightManager->CreateOrRetrieve(*it);
94
95 // Update the light.
96 deferredLight->UpdateFromParent();
97 deferredLight->UpdateFromCamera(cam);
98 Ogre::SimpleRenderable* renderedGeometry = deferredLight->GetRenderable();
99 Ogre::Technique* tech = renderedGeometry->getMaterial()->getBestTechnique();
100
101 //Update shadow texture
102 if (deferredLight->GetCastShadows() && (tech->getNumPasses() > 0))
103 {
104 Ogre::Pass* pass = tech->getPass(0);
105 #if SO3_ENABLE_DEFERRED_CUSTOM_SHADOWS == 0
106 Ogre::SceneManager::RenderContext* context = sm->_pauseRendering();
107 sm->prepareShadowTextures(cam, mViewport, &ll);
108 sm->_resumeRendering(context);
109 const Ogre::TexturePtr& shadowTexture = sm->getShadowTexture(0);
110 #else
111 const Ogre::TexturePtr& shadowTexture = SDeferredShadowManager::getSingleton().PrepareShadowTexture(cam, mViewport, (*it), pass);
112 #endif
113
114 // Check that the tu is correctly binded
115 Ogre::TextureUnitState* tus = pass->getTextureUnitState("ShadowMap");
116 if(tus->_getTexturePtr() != shadowTexture)
117 tus->_setTexturePtr(shadowTexture);
118 }
119 injectTechnique(sm, tech, renderedGeometry, &ll);
120 }
121}
122
123Ogre::CompositorInstance::RenderSystemOperation* SDeferredLightCompositionPass::createOperation(Ogre::CompositorInstance* instance, const Ogre::CompositionPass* pass)
124{
125 return OGRE_NEW SDeferredLightRenderOperation(instance, pass);
126}
127
128}
virtual const Ogre::MaterialPtr & getMaterial() const
void UpdateFromCamera(Ogre::Camera *camera)
virtual Ogre::CompositorInstance::RenderSystemOperation * createOperation(Ogre::CompositorInstance *instance, const Ogre::CompositionPass *pass)
Ogre::SimpleRenderable * GetRenderable()
void UpdateFromCamera(Ogre::Camera *camera)
static SDeferredLightManager * getSingletonPtr()
static SDeferredLightManager & getSingleton()
SDeferredLight * CreateOrRetrieve(Ogre::Light *existingLight)
virtual void execute(Ogre::SceneManager *sm, Ogre::RenderSystem *rs)
SDeferredLightRenderOperation(Ogre::CompositorInstance *instance, const Ogre::CompositionPass *pass)
static SDeferredShadowManager & getSingleton()
Ogre::TexturePtr & PrepareShadowTexture(Ogre::Camera *ogreCamera, Ogre::Viewport *ogreViewport, const Ogre::Light *light, Ogre::Pass *ogrePass)
void injectTechnique(Ogre::SceneManager *sm, Ogre::Technique *tech, Ogre::Renderable *rend, const Ogre::LightList *lightList)