SO3Engine
SO3Compositor.cpp
Go to the documentation of this file.
1
9
10namespace SO3
11{
12
13SCompositor::SCompositor(SViewPort* scolViewPort, const std::string& compositorName, const std::string& schemeName) : SData(compositorName)
14{
15 CommonConstructor(scolViewPort, schemeName, false, false);
16}
17
18SCompositor::SCompositor(SViewPort* scolViewPort, const std::string& compositorName, const bool& isActivated) : SData(compositorName)
19{
20 CommonConstructor(scolViewPort, "", true, isActivated);
21}
22
23SCompositor::SCompositor(const std::string& compositorName, const std::string& schemeName) : SData(compositorName)
24{
25 CommonConstructor(NULL, schemeName, false, false);
26}
27
28void SCompositor::CommonConstructor(SViewPort* scolViewPort, const std::string& schemeName, bool internalCompo, bool activateCompo)
29{
30 // SO3 internal compo, or loaded from script?
31 isInternal = internalCompo;
32 isEnable = activateCompo;
33 parent = scolViewPort;
34 mViewport = 0;
35
36 if (scolViewPort != 0)
37 mViewport = scolViewPort->GetOgreViewPortPointer();
38
39 // Store a reference to the compositor.
40 ogreCompositor = Ogre::CompositorManager::getSingleton().getByName(name);
41
42 // Assign a scheme?
43 if (schemeName.empty() || schemeName == "Default" || schemeName == "DefaultScheme" || schemeName == Ogre::Root::getSingleton().getRenderSystem()->_getDefaultViewportMaterialScheme())
44 scheme = Ogre::MSN_SHADERGEN;
45 else
46 scheme = schemeName;
47
48 if ((scheme != Ogre::MSN_SHADERGEN) && (scheme != "SO3_LEGACY"))
49 {
50 if (ogreCompositor)
51 {
52 // Iterate through compositor techniques
53 Ogre::Compositor::TechniqueIterator iCompositorTechnique = ogreCompositor->getTechniqueIterator();
54 while (iCompositorTechnique.hasMoreElements())
55 {
56 // Create SCompositorTechnique wrapper.
57 Ogre::CompositionTechnique* ogreCompositionTechnique = iCompositorTechnique.getNext();
58
59 Ogre::CompositionTechnique::TargetPasses passList = ogreCompositionTechnique->getTargetPasses();
60 for (unsigned int p = 0; p < passList.size(); p++)
61 {
62 // Create SCompositorPass wrapper.
63 Ogre::CompositionTargetPass* ogreCompositionTargetPass = passList[p];
64
65 ogreCompositionTargetPass->setMaterialScheme(scheme);
66 }
67 }
68 }
69
70 Ogre::MaterialPtr colorMat = Ogre::MaterialManager::getSingleton().getByName("SO3/Internal/DefaultColor");
71 if (colorMat)
72 {
73 mBlackMat = colorMat->clone("SO3/Internal/mSchemeBlack/" + name + "/" + scheme, Ogre::String("SO3/Internal"));
74 mBlackMat->getTechnique(0)->getPass(0)->setAmbient(0,0,0);
75 mBlackMat->getTechnique(0)->setFog(true, Ogre::FOG_NONE, Ogre::ColourValue::Black);
76 mBlackMat->getTechnique(0)->setSchemeName(scheme);
77
78 mBlackMatTrans = colorMat->clone("SO3/Internal/mSchemeBlackTrans/" + name + "/" + scheme, Ogre::String("SO3/Internal"));
79 mBlackMatTrans->getTechnique(0)->getPass(0)->setAmbient(0,0,0);
80 mBlackMatTrans->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
81 mBlackMatTrans->getTechnique(0)->setFog(true, Ogre::FOG_NONE, Ogre::ColourValue::Black);
82 mBlackMatTrans->getTechnique(0)->setSchemeName(scheme);
83 }
84 }
85
86 // Attach to a SViewport?
87 if(!isInternal && ogreCompositor)
88 {
89 if (mViewport != 0)
90 _AttachToParent();
91
92 // Iterate through compositor techniques, and map them to a SCompositorTechnique
93 Ogre::Compositor::TechniqueIterator iCompositorTechnique = ogreCompositor->getTechniqueIterator();
94 while(iCompositorTechnique.hasMoreElements())
95 {
96 // Create SCompositorTechnique wrapper.
97 Ogre::CompositionTechnique* ogreCompositionTechnique = iCompositorTechnique.getNext();
98 SCompositorTechnique* newCompositorTechnique = new SCompositorTechnique(this, ogreCompositionTechnique, compositorTechniquesByIndex.size());
99
100 // Store it.
101 compositorTechniquesIndexByName.insert(CompositorTechniquesIndexByName::value_type(newCompositorTechnique->GetName(), compositorTechniquesByIndex.size()));
102 compositorTechniquesByIndex.push_back(newCompositorTechnique);
103 }
104 }
105}
106
107SCompositor::SCompositor() : SData("")
108{
109 // Forbiden (private)
110}
111
113{
114 if (!isInternal)
115 {
116 // Detach from viewport
117 if (mViewport != 0)
118 _DetachFromParent();
119
120 const Ogre::RenderSystemCapabilities* caps = SRoot::getSingletonPtr()->GetOgreRenderSystem()->getCapabilities();
121 // Destroy default materials if they exists.
122 if(mBlackMat)
123 {
124 if (caps && caps->hasCapability(Ogre::RSC_FIXED_FUNCTION) == false)
125 Ogre::RTShader::ShaderGenerator::getSingletonPtr()->removeAllShaderBasedTechniques(mBlackMat->getName(), mBlackMat->getGroup());
126
127 Ogre::MaterialManager::getSingleton().remove(mBlackMat->getHandle());
128 mBlackMat.reset();
129 }
130 if(mBlackMatTrans)
131 {
132 if (caps && caps->hasCapability(Ogre::RSC_FIXED_FUNCTION) == false)
133 Ogre::RTShader::ShaderGenerator::getSingletonPtr()->removeAllShaderBasedTechniques(mBlackMatTrans->getName(), mBlackMatTrans->getGroup());
134
135 Ogre::MaterialManager::getSingleton().remove(mBlackMatTrans->getHandle());
136 mBlackMatTrans.reset();
137 }
138
139 // Destroy SCompositorTechnique wrappers.
140 CompositorTechniquesByIndex::iterator iCompositorTechnique = compositorTechniquesByIndex.begin();
141 while(iCompositorTechnique != compositorTechniquesByIndex.end())
142 {
143 delete(*iCompositorTechnique);
144 iCompositorTechnique++;
145 }
146 compositorTechniquesByIndex.clear();
147 compositorTechniquesIndexByName.clear();
148
149 // Release compositor pointer.
150 if (ogreCompositor)
151 {
152 ogreCompositor->unload();
153 //do not remove from the manager
154 //Ogre::CompositorManager::getSingletonPtr()->remove(ogreCompositor->getHandle());
155 ogreCompositor.reset();
156 }
157 }
158}
159
160void SCompositor::SetViewport(Ogre::Viewport* vp)
161{
162 bool state = isEnable;
163
164 if (state)
165 SetEnable(false);
166
167 if (mViewport != 0)
168 _DetachFromParent();
169
170 mViewport = vp;
171
172 if (mViewport != 0)
173 _AttachToParent();
174
175 SetEnable(state);
176}
177
178void SCompositor::_AttachToParent()
179{
180 if (mViewport == 0)
181 return;
182
183 if(!ogreCompositor->isLoaded())
184 ogreCompositor->load();
185
186 //unregister Stereo
187 bool hasStereo = false;
188
189 if (parent != 0)
190 {
191 hasStereo = parent->IsStereoViewportRegistered();
192 if (hasStereo)
193 parent->UnregisterStereoViewport();
194 }
195
196 //DoF or compositors with Depth must be assigned first
197 int pos = -1;
198 if (name == "DoF")
199 pos = 0;
200
201 // Compositor manager create a compositor chain since Ogre 1.7, so don't forget to delete it!
202 try
203 {
204 Ogre::CompositorManager::getSingleton().addCompositor(mViewport, name, pos);
205 }
206 catch (Ogre::Exception &e)
207 {
208 Ogre::LogManager::getSingletonPtr()->logMessage(e.getFullDescription(), Ogre::LML_WARNING, false);
209 return;
210 }
211
212 SetEnable(true);
213
214 //register Stereo
215 if ((parent != 0) && hasStereo)
216 parent->RegisterStereoViewport();
217}
218
219void SCompositor::_DetachFromParent()
220{
221 if (mViewport == 0)
222 return;
223
224 SetEnable(false);
225
226 //unregister Stereo
227 bool hasStereo = false;
228
229 if (parent != 0)
230 {
231 hasStereo = parent->IsStereoViewportRegistered();
232 if (hasStereo)
233 parent->UnregisterStereoViewport();
234 }
235
236// If our ogre is anterior to v1.7
237#if OGRE_VERSION < ((1 << 16) | (7 << 8) | 0)
238 // Ogre 1.6 method
239 Ogre::CompositorManager::getSingleton().removeCompositor(mViewport, name);
240#else
241 // New Ogre 1.7+ method
242 Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mViewport);
243 if(chain)
244 {
245 Ogre::CompositorInstance* compinst = chain->getCompositor(name);
246 if (compinst)
247 {
248 chain->_removeInstance(compinst);
249 chain->_markDirty();
250 }
251
252 // Destroy chain if needed.
253 if(chain->getCompositorInstances().empty())
254 Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport);
255 }
256#endif
257
258 //register Stereo
259 if ((parent != 0) && hasStereo)
260 parent->RegisterStereoViewport();
261}
262
264{
265 return parent;
266}
267
269{
270 return isEnable;
271}
272
273void SCompositor::SetEnable(const bool& enable)
274{
275 if (enable != isEnable)
276 {
277 if (enable)
278 {
279 if (scheme != "")
280 Ogre::MaterialManager::getSingleton().addListener(this, scheme);
281 }
282 else
283 {
284 Ogre::MaterialManager::getSingleton().removeListener(this, scheme);
285 }
286
287 try
288 {
289 // only enable compositor on main viewport if there is no stereo on it
290 if (((mViewport != 0) && (parent == 0)) || ((parent != 0) && !parent->UpdateStereoCompositorState(name, enable)))
291 Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, name, enable);
292 }
293 catch (Ogre::Exception &e)
294 {
295 Ogre::LogManager::getSingletonPtr()->logMessage(e.getFullDescription(), Ogre::LML_WARNING, false);
296 }
297
298 isEnable = enable;
299 }
300}
301
303{
304 return ogreCompositor->getNumTechniques();
305}
306
308{
309 if((technique >= 0) && (technique < compositorTechniquesByIndex.size()))
310 return compositorTechniquesByIndex.at(technique);
311 else
312 return 0;
313}
314
316{
317 CompositorTechniquesIndexByName::iterator iSearchedCompositorTechniqueIndex = compositorTechniquesIndexByName.find(techname);
318 if(iSearchedCompositorTechniqueIndex!= compositorTechniquesIndexByName.end())
319 return iSearchedCompositorTechniqueIndex->second;
320 else
321 return -1;
322}
323
324Ogre::Technique* SCompositor::handleSchemeNotFound(unsigned short schemeIndex, const Ogre::String& schemeName, Ogre::Material* originalMaterial, unsigned short lodIndex, const Ogre::Renderable* rend)
325{
326 if (!mBlackMatTrans || !mBlackMat)
327 return NULL;
328
329 if ((originalMaterial->getNumSupportedTechniques() > 0) && (originalMaterial->getSupportedTechnique(0)->getNumPasses() > 0) && (!originalMaterial->getSupportedTechnique(0)->getPass(0)->getDepthWriteEnabled()))
330 return mBlackMatTrans->getTechnique(0);
331 else
332 return mBlackMat->getTechnique(0);
333}
334
335}
virtual Ogre::Technique * handleSchemeNotFound(unsigned short schemeIndex, const Ogre::String &schemeName, Ogre::Material *originalMaterial, unsigned short lodIndex, const Ogre::Renderable *rend)
void SetEnable(const bool &enable)
void SetViewport(Ogre::Viewport *vp)
SViewPort * GetParentViewPort()
int GetCompositorTechniqueIndexByName(const std::string &techname)
SCompositorTechnique * GetCompositorTechnique(const unsigned int &technique)
std::string name
Definition SO3DataScol.h:44
Ogre::RenderSystem * GetOgreRenderSystem()
Definition SO3Root.cpp:865
static SRoot * getSingletonPtr()
Definition SO3Root.cpp:111
void RegisterStereoViewport()
void UnregisterStereoViewport()
bool IsStereoViewportRegistered()
Ogre::Viewport * GetOgreViewPortPointer()
bool UpdateStereoCompositorState(const Ogre::String compname, bool state)