1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org
6 
7 Copyright (c) 2000-2013 Torus Knot Software Ltd
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 THE SOFTWARE.
25 -----------------------------------------------------------------------------
26 */
27 #ifndef _ShaderGenerator_
28 #define _ShaderGenerator_
29 
30 #include "OgreShaderPrerequisites.h"
31 #include "OgreSingleton.h"
32 #include "OgreFileSystemLayer.h"
33 #include "OgreRenderObjectListener.h"
34 #include "OgreSceneManager.h"
35 #include "OgreShaderRenderState.h"
36 #include "OgreScriptTranslator.h"
37 #include "OgreShaderScriptTranslator.h"
38 
39 
40 namespace Ogre {
41 namespace RTShader {
42 
43 /** \addtogroup Core
44 *  @{
45 */
46 /** \addtogroup RTShader
47 *  @{
48 */
49 
50 /** Shader generator system main interface. This singleton based class
51 enables automatic generation of shader code based on existing material techniques.
52 */
53 class _OgreRTSSExport ShaderGenerator : public Singleton<ShaderGenerator>, public RTShaderSystemAlloc
54 {
55 // Interface.
56 public:
57 
58 	/**
59 	Initialize the Shader Generator System.
60 	Return true upon success.
61 	*/
62 	static bool initialize();
63 
64 	/**
65 	Destroy the Shader Generator instance.
66 	*/
67 	static void destroy();
68 
69 
70 	/** Override standard Singleton retrieval.
71 	@remarks
72 	Why do we do this? Well, it's because the Singleton
73 	implementation is in a .h file, which means it gets compiled
74 	into anybody who includes it. This is needed for the
75 	Singleton template to work, but we actually only want it
76 	compiled into the implementation of the class based on the
77 	Singleton, not all of them. If we don't change this, we get
78 	link errors when trying to use the Singleton-based class from
79 	an outside dll.
80 	@par
81 	This method just delegates to the template version anyway,
82 	but the implementation stays in this single compilation unit,
83 	preventing link errors.
84 	*/
85 	static ShaderGenerator& getSingleton();
86 
87 
88 	/** Override standard Singleton retrieval.
89 	@remarks
90 	Why do we do this? Well, it's because the Singleton
91 	implementation is in a .h file, which means it gets compiled
92 	into anybody who includes it. This is needed for the
93 	Singleton template to work, but we actually only want it
94 	compiled into the implementation of the class based on the
95 	Singleton, not all of them. If we don't change this, we get
96 	link errors when trying to use the Singleton-based class from
97 	an outside dll.
98 	@par
99 	This method just delegates to the template version anyway,
100 	but the implementation stays in this single compilation unit,
101 	preventing link errors.
102 	*/
103 	static ShaderGenerator* getSingletonPtr();
104 
105 	/**
106 	Add a scene manager to the shader generator scene managers list.
107 	@param sceneMgr The scene manager to add to the list.
108 	*/
109 	void addSceneManager(SceneManager* sceneMgr);
110 
111 	/**
112 	Remove a scene manager from the shader generator scene managers list.
113 	@param sceneMgr The scene manager to remove from the list.
114 	*/
115 	void removeSceneManager(SceneManager* sceneMgr);
116 
117 	/**
118 	Get the active scene manager that is doint the actual scene rendering.
119 	This attribute will be update on the call to preFindVisibleObjects.
120 	*/
121 	SceneManager* getActiveSceneManager();
122 
123 	/**
124 	Set the target shader language.
125 	@param shaderLanguage The output shader language to use.
126 	@remarks The default shader language is cg.
127 	*/
128 	void setTargetLanguage(const String& shaderLanguage);
129 
130 	/**
131 	Return the target shader language currently in use.
132 	*/
getTargetLanguage()133 	const String& getTargetLanguage() const { return mShaderLanguage; }
134 
135 	/**
136 	Set the output vertex shader target profiles.
137 	@param vertexShaderProfiles The target profiles for the vertex shader.
138 	*/
139 	void setVertexShaderProfiles(const String& vertexShaderProfiles);
140 
141 	/**
142 	Get the output vertex shader target profiles.
143 	*/
getVertexShaderProfiles()144 	const String& getVertexShaderProfiles() const { return mVertexShaderProfiles; }
145 
146 	/**
147 	Get the output vertex shader target profiles as list of strings.
148 	*/
getVertexShaderProfilesList()149 	const StringVector& getVertexShaderProfilesList() const { return mVertexShaderProfilesList; }
150 
151 
152 	/**
153 	Set the output fragment shader target profiles.
154 	@param fragmentShaderProfiles The target profiles for the fragment shader.
155 	*/
156 	void setFragmentShaderProfiles(const String& fragmentShaderProfiles);
157 
158 	/**
159 	Get the output fragment shader target profiles.
160 	*/
getFragmentShaderProfiles()161 	const String& getFragmentShaderProfiles() const { return mFragmentShaderProfiles; }
162 
163 	/**
164 	Get the output fragment shader target profiles as list of strings.
165 	*/
getFragmentShaderProfilesList()166 	const StringVector& getFragmentShaderProfilesList() const { return mFragmentShaderProfilesList; }
167 
168 	/**
169 	Set the output shader cache path. Generated shader code will be written to this path.
170 	In case of empty cache path shaders will be generated directly from system memory.
171 	@param cachePath The cache path of the shader.
172 	The default is empty cache path.
173 	*/
174 	void setShaderCachePath(const String& cachePath);
175 
176 	/**
177 	Get the output shader cache path.
178 	*/
getShaderCachePath()179 	const String& getShaderCachePath() const { return mShaderCachePath; }
180 
181 	/**
182 	Flush the shader cache. This operation will cause all active sachems to be invalidated and will
183 	destroy any CPU/GPU program that created by this shader generator.
184 	*/
185 	void flushShaderCache();
186 
187 	/**
188 	Return a global render state associated with the given scheme name.
189 	Modifying this render state will affect all techniques that belongs to that scheme.
190 	This is the best way to apply global changes to all techniques.
191 	After altering the render state one should call invalidateScheme method in order to
192 	regenerate shaders.
193 	@param schemeName The destination scheme name.
194 	*/
195 	RenderState* getRenderState(const String& schemeName);
196 
197 
198 	typedef std::pair<RenderState*, bool> RenderStateCreateOrRetrieveResult;
199 	/**
200 	Returns a requested render state. If the render state does not exist this function creates it.
201 	@param schemeName The scheme name to retrieve.
202 	*/
203 	RenderStateCreateOrRetrieveResult createOrRetrieveRenderState(const String& schemeName);
204 
205 
206 	/**
207 	Tells if a given render state exists
208 	@param schemeName The scheme name to check.
209 	*/
210 	bool hasRenderState(const String& schemeName) const;
211 
212 
213     /**
214 	Get render state of specific pass.
215 	Using this method allows the user to customize the behavior of a specific pass.
216 	@param schemeName The destination scheme name.
217 	@param materialName The specific material name.
218 	@param passIndex The pass index.
219 	*/
220 	RenderState* getRenderState(const String& schemeName, const String& materialName, unsigned short passIndex);
221 
222     /**
223      Get render state of specific pass.
224      Using this method allows the user to customize the behavior of a specific pass.
225      @param schemeName The destination scheme name.
226      @param materialName The specific material name.
227      @param groupName The specific material name.
228      @param passIndex The pass index.
229      */
230     RenderState* getRenderState(const String& schemeName, const String& materialName, const String& groupName, unsigned short passIndex);
231 
232 	/**
233 	Add sub render state factory. Plugins or 3d party applications may implement sub classes of
234 	SubRenderState interface. Add the matching factory will allow the application to create instances
235 	of these sub classes.
236 	@param factory The factory to add.
237 	*/
238 	void addSubRenderStateFactory(SubRenderStateFactory* factory);
239 
240 	/**
241 	Returns the number of existing factories
242 	*/
243 	size_t getNumSubRenderStateFactories() const;
244 
245 	/**
246 	Returns a sub render state factory by index
247 	@note index must be lower than the value returned by getNumSubRenderStateFactories()
248 	*/
249 	SubRenderStateFactory* getSubRenderStateFactory(size_t index);
250 
251 	/**
252 	Returns a sub render state factory by name
253 	*/
254 	SubRenderStateFactory* getSubRenderStateFactory(const String& type);
255 
256 	/**
257 	Remove sub render state factory.
258 	@param factory The factory to remove.
259 	*/
260 	void removeSubRenderStateFactory(SubRenderStateFactory* factory);
261 
262 	/**
263 	Create an instance of sub render state from a given type.
264 	@param type The type of sub render state to create.
265 	*/
266 	SubRenderState* createSubRenderState(const String& type);
267 
268 
269 	/**
270 	Destroy an instance of sub render state.
271 	@param subRenderState The instance to destroy.
272 	*/
273 	void destroySubRenderState(SubRenderState* subRenderState);
274 
275 
276     /**
277 	Checks if a shader based technique has been created for a given technique.
278 	Return true if exist. False if not.
279 	@param materialName The source material name.
280 	@param srcTechniqueSchemeName The source technique scheme name.
281 	@param dstTechniqueSchemeName The destination shader based technique scheme name.
282 	*/
283 	bool hasShaderBasedTechnique(const String& materialName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName) const;
284 
285     /**
286      Checks if a shader based technique has been created for a given technique.
287      Return true if exist. False if not.
288      @param materialName The source material name.
289      @param groupName The source group name.
290      @param srcTechniqueSchemeName The source technique scheme name.
291      @param dstTechniqueSchemeName The destination shader based technique scheme name.
292      */
293     bool hasShaderBasedTechnique(const String& materialName, const String& groupName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName) const;
294 
295     /**
296 	Create shader based technique from a given technique.
297 	Return true upon success. Failure may occur if the source technique is not FFP pure, or different
298 	source technique is mapped to the requested destination scheme.
299 	@param materialName The source material name.
300 	@param srcTechniqueSchemeName The source technique scheme name.
301 	@param dstTechniqueSchemeName The destination shader based technique scheme name.
302 	@param overProgrammable If true a shader will be created even if the material has shaders
303 	*/
304 	bool createShaderBasedTechnique(const String& materialName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName, bool overProgrammable = false);
305 
306     /**
307      Create shader based technique from a given technique.
308      Return true upon success. Failure may occur if the source technique is not FFP pure, or different
309      source technique is mapped to the requested destination scheme.
310      @param materialName The source material name.
311      @param groupName The source group name.
312      @param srcTechniqueSchemeName The source technique scheme name.
313      @param dstTechniqueSchemeName The destination shader based technique scheme name.
314      @param overProgrammable If true a shader will be created even if the material has shaders
315      */
316     bool createShaderBasedTechnique(const String& materialName, const String& groupName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName, bool overProgrammable = false);
317 
318 
319     /**
320 	Remove shader based technique from a given technique.
321 	Return true upon success. Failure may occur if the given source technique was not previously
322 	registered successfully using the createShaderBasedTechnique method.
323 	@param materialName The source material name.
324 	@param srcTechniqueSchemeName The source technique scheme name.
325 	@param dstTechniqueSchemeName The destination shader based technique scheme name.
326 	*/
327 	bool removeShaderBasedTechnique(const String& materialName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName);
328 
329     /**
330      Remove shader based technique from a given technique.
331      Return true upon success. Failure may occur if the given source technique was not previously
332      registered successfully using the createShaderBasedTechnique method.
333      @param materialName The source material name.
334      @param groupName The source group name.
335      @param srcTechniqueSchemeName The source technique scheme name.
336      @param dstTechniqueSchemeName The destination shader based technique scheme name.
337      */
338     bool removeShaderBasedTechnique(const String& materialName, const String& groupName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName);
339 
340 
341 	/**
342 	Remove all shader based techniques of the given material.
343 	Return true upon success.
344 	@param materialName The source material name.
345 	@param groupName The source group name.
346 	*/
347 	bool removeAllShaderBasedTechniques(const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
348 
349 	/**
350 	Clone all shader based techniques from one material to another.
351 	This function can be used in conjunction with the Material::clone() function to copy
352 	both material properties and RTSS state from one material to another.
353 	@param srcMaterialName The source material name.
354 	@param srcGroupName The source group name.
355 	@param dstMaterialName The destination material name.
356 	@param dstGroupName The destination group name.
357 	@return True if successful
358 	*/
359 	bool cloneShaderBasedTechniques(const String& srcMaterialName,
360 		const String& srcGroupName,	const String& dstMaterialName, const String& dstGroupName);
361 
362 	/**
363 	Remove all shader based techniques that created by this shader generator.
364 	*/
365 	void removeAllShaderBasedTechniques();
366 
367 	/**
368 	Create a scheme.
369 	@param schemeName The scheme name to create.
370 	*/
371 	void createScheme(const String& schemeName);
372 
373 	/**
374 	Invalidate a given scheme. This action will lead to shader regeneration of all techniques belongs to the
375 	given scheme name.
376 	@param schemeName The scheme to invalidate.
377 	*/
378 	void invalidateScheme(const String& schemeName);
379 
380 	/**
381 	Validate a given scheme. This action will generate shader programs for all techniques of the
382 	given scheme name.
383 	@param schemeName The scheme to validate.
384 	*/
385 	bool validateScheme(const String& schemeName);
386 
387 	/**
388 	Invalidate specific material scheme. This action will lead to shader regeneration of the technique belongs to the
389 	given scheme name.
390 	@param schemeName The scheme to invalidate.
391 	@param materialName The material to invalidate.
392 	@param groupName The source group name.
393 	*/
394 	void invalidateMaterial(const String& schemeName, const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
395 
396 	/**
397 	Validate specific material scheme. This action will generate shader programs for the technique of the
398 	given scheme name.
399 	@param schemeName The scheme to validate.
400 	@param materialName The material to validate.
401 	@param groupName The source group name.
402 	*/
403 	bool validateMaterial(const String& schemeName, const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
404 
405 
406 	/**
407 	Return custom material Serializer of the shader generator.
408 	This is useful when you'd like to export certain material that contains shader generator effects.
409 	I.E - when writing an exporter you may want mark your material as shader generated material
410 	so in the next time you will load it by your application it will automatically generate shaders with custom
411 	attributes you wanted. To do it you'll have to do the following steps:
412 	1. Create shader based technique for you material via the createShaderBasedTechnique() method.
413 	2. Create MaterialSerializer instance.
414 	3. Add the return instance of serializer listener to the MaterialSerializer.
415 	4. Call one of the export methods of MaterialSerializer.
416 	*/
417 	SGMaterialSerializerListener* getMaterialSerializerListener();
418 
419 
420 	/** Return the current number of generated vertex shaders. */
421 	size_t getVertexShaderCount() const;
422 
423 
424 	/** Return the current number of generated fragment shaders. */
425 	size_t getFragmentShaderCount() const;
426 
427 
428 
429 	/** Set the vertex shader outputs compaction policy.
430 	@see VSOutputCompactPolicy.
431 	@param policy The policy to set.
432 	*/
setVertexShaderOutputsCompactPolicy(VSOutputCompactPolicy policy)433 	void setVertexShaderOutputsCompactPolicy(VSOutputCompactPolicy policy)  { mVSOutputCompactPolicy = policy; }
434 
435 	/** Get the vertex shader outputs compaction policy.
436 	@see VSOutputCompactPolicy.
437 	*/
getVertexShaderOutputsCompactPolicy()438 	VSOutputCompactPolicy getVertexShaderOutputsCompactPolicy() const { return mVSOutputCompactPolicy; }
439 
440 
441 	/** Sets whether shaders are created for passes with shaders.
442 	Note that this only refers to when the system parses the materials itself.
443 	Not for when calling the createShaderBasedTechnique() function directly
444 	@param value The value to set this attribute pass.
445 	*/
setCreateShaderOverProgrammablePass(bool value)446 	void setCreateShaderOverProgrammablePass(bool value) { mCreateShaderOverProgrammablePass = value; }
447 
448 	/** Returns whether shaders are created for passes with shaders.
449 	@see setCreateShaderOverProgrammablePass().
450 	*/
getCreateShaderOverProgrammablePass()451 	bool getCreateShaderOverProgrammablePass() const { return mCreateShaderOverProgrammablePass; }
452 
453 
454 	/** Returns the amount of schemes used in the for RT shader generation
455 	*/
456 	size_t getRTShaderSchemeCount() const;
457 
458 	/** Returns the scheme name used in the for RT shader generation by index
459 	*/
460 	const String& getRTShaderScheme(size_t index) const;
461 
462 	/// Default material scheme of the shader generator.
463 	static String DEFAULT_SCHEME_NAME;
464 
465 // Protected types.
466 protected:
467 	class SGPass;
468 	class SGTechnique;
469 	class SGMaterial;
470 	class SGScheme;
471 
472 	typedef std::pair<String,String>				MatGroupPair;
473 	struct MatGroupPair_less
474 	{
475 		// ensure we arrange the list first by material name then by group name
operatorMatGroupPair_less476 		bool operator()(const MatGroupPair& p1, const MatGroupPair& p2) const
477 		{
478 			int cmpVal = strcmp(p1.first.c_str(),p2.first.c_str());
479 			return (cmpVal < 0) || ((cmpVal == 0) && (strcmp(p1.second.c_str(),p2.second.c_str()) < 0));
480 		}
481 	};
482 
483 	typedef vector<SGPass*>::type					SGPassList;
484 	typedef SGPassList::iterator					SGPassIterator;
485 	typedef SGPassList::const_iterator				SGPassConstIterator;
486 
487 	typedef vector<SGTechnique*>::type				SGTechniqueList;
488 	typedef SGTechniqueList::iterator				SGTechniqueIterator;
489 	typedef SGTechniqueList::const_iterator			SGTechniqueConstIterator;
490 
491 	typedef map<SGTechnique*, SGTechnique*>::type	SGTechniqueMap;
492 	typedef SGTechniqueMap::iterator				SGTechniqueMapIterator;
493 
494 	typedef map<MatGroupPair, SGMaterial*, MatGroupPair_less>::type	SGMaterialMap;
495 	typedef SGMaterialMap::iterator					SGMaterialIterator;
496 	typedef SGMaterialMap::const_iterator			SGMaterialConstIterator;
497 
498 	typedef map<String, SGScheme*>::type			SGSchemeMap;
499 	typedef SGSchemeMap::iterator					SGSchemeIterator;
500 	typedef SGSchemeMap::const_iterator				SGSchemeConstIterator;
501 
502 	typedef map<String, ScriptTranslator*>::type	SGScriptTranslatorMap;
503 	typedef SGScriptTranslatorMap::iterator			SGScriptTranslatorIterator;
504 	typedef SGScriptTranslatorMap::const_iterator	SGScriptTranslatorConstIterator;
505 
506 
507 
508 	/** Shader generator pass wrapper class. */
509 	class _OgreRTSSExport SGPass : public RTShaderSystemAlloc
510 	{
511 	public:
512 		SGPass(SGTechnique* parent, Pass* srcPass, Pass* dstPass);
513 		~SGPass();
514 
515 		/** Build the render state. */
516 		void buildTargetRenderState();
517 
518 		/** Acquire the CPU/GPU programs for this pass. */
519 		void acquirePrograms();
520 
521 		/** Release the CPU/GPU programs of this pass. */
522 		void releasePrograms();
523 
524 
525 		/** Called when a single object is about to be rendered. */
526 		void notifyRenderSingleObject(Renderable* rend, const AutoParamDataSource* source, const LightList* pLightList, bool suppressRenderStateChanges);
527 
528 		/** Get source pass. */
getSrcPass()529 		Pass* getSrcPass() { return mSrcPass; }
530 
531 		/** Get destination pass. */
getDstPass()532 		Pass* getDstPass() { return mDstPass; }
533 
534 		/** Get custom FPP sub state of this pass. */
535 		SubRenderState* getCustomFFPSubState(int subStateOrder);
536 
537 		/** Get custom render state of this pass. */
getCustomRenderState()538 		RenderState* getCustomRenderState() { return mCustomRenderState; }
539 
540 		/** Set the custom render state of this pass. */
setCustomRenderState(RenderState * customRenderState)541 		void setCustomRenderState(RenderState* customRenderState) { mCustomRenderState = customRenderState; }
542 
543 		// Key name for associating with a Pass instance.
544 		static String UserKey;
545 
546 	protected:
547 		SubRenderState* getCustomFFPSubState(int subStateOrder, const RenderState* renderState);
548 
549 	protected:
550 		// Parent technique.
551 		SGTechnique* mParent;
552 		// Source pass.
553 		Pass* mSrcPass;
554 		// Destination pass.
555 		Pass* mDstPass;
556 		// Custom render state.
557 		RenderState* mCustomRenderState;
558 		// The compiled render state.
559 		TargetRenderState* mTargetRenderState;
560 	};
561 
562 
563 	/** Shader generator technique wrapper class. */
564 	class _OgreRTSSExport SGTechnique : public RTShaderSystemAlloc
565 	{
566 	public:
567 		SGTechnique(SGMaterial* parent, Technique* srcTechnique, const String& dstTechniqueSchemeName);
568 		~SGTechnique();
569 
570 		/** Get the parent SGMaterial */
getParent()571 		const SGMaterial* getParent() const { return mParent; }
572 
573 		/** Get the source technique. */
getSourceTechnique()574 		Technique* getSourceTechnique() { return mSrcTechnique; }
575 
576 		/** Get the destination technique. */
getDestinationTechnique()577 		Technique* getDestinationTechnique() { return mDstTechnique; }
578 
579 		/** Get the destination technique scheme name. */
getDestinationTechniqueSchemeName()580 		const String& getDestinationTechniqueSchemeName() const { return mDstTechniqueSchemeName; }
581 
582 		/** Build the render state. */
583 		void buildTargetRenderState();
584 
585 		/** Acquire the CPU/GPU programs for this technique. */
586 		void acquirePrograms();
587 
588 		/** Release the CPU/GPU programs of this technique. */
589 		void releasePrograms();
590 
591 		/** Tells the technique that it needs to generate shader code. */
setBuildDestinationTechnique(bool buildTechnique)592 		void setBuildDestinationTechnique(bool buildTechnique)	{ mBuildDstTechnique = buildTechnique; }
593 
594 		/** Tells if the destination technique should be build. */
getBuildDestinationTechnique()595 		bool getBuildDestinationTechnique() const				{ return mBuildDstTechnique; }
596 
597 		/** Get render state of specific pass.
598 		@param passIndex The pass index.
599 		*/
600 		RenderState* getRenderState(unsigned short passIndex);
601 		/** Tells if a custom render state exists for the given pass. */
602 		bool hasRenderState(unsigned short passIndex);
603 
604 		// Key name for associating with a Technique instance.
605 		static String UserKey;
606 
607 	protected:
608 
609 		/** Create the passes entries. */
610 		void createSGPasses();
611 
612 		/** Destroy the passes entries. */
613 		void destroySGPasses();
614 
615 	protected:
616 		// Parent material.
617 		SGMaterial* mParent;
618 		// Source technique.
619 		Technique* mSrcTechnique;
620 		// Destination technique.
621 		Technique* mDstTechnique;
622 		// All passes entries.
623 		SGPassList mPassEntries;
624 		// The custom render states of all passes.
625 		RenderStateList mCustomRenderStates;
626 		// Flag that tells if destination technique should be build.
627 		bool mBuildDstTechnique;
628 		// Scheme name of destination technique.
629 		String mDstTechniqueSchemeName;
630     };
631 
632 
633 	/** Shader generator material wrapper class. */
634 	class _OgreRTSSExport SGMaterial : public RTShaderSystemAlloc
635 	{
636 
637 	public:
638 		/** Class constructor. */
SGMaterial(const String & materialName,const String & groupName)639 		SGMaterial(const String& materialName, const String& groupName)	: mName(materialName), mGroup(groupName)
640 		{
641 
642 		}
643 
644 		/** Get the material name. */
getMaterialName()645 		const String& getMaterialName() const	{ return mName; }
646 
647 		/** Get the group name. */
getGroupName()648 		const String& getGroupName() const	{ return mGroup; }
649 
650 		/** Get the const techniques list of this material. */
getTechniqueList()651 		const SGTechniqueList& getTechniqueList() const	 { return mTechniqueEntries; }
652 
653 		/** Get the techniques list of this material. */
getTechniqueList()654 		SGTechniqueList& getTechniqueList() 			 { return mTechniqueEntries; }
655 
656 	protected:
657 		// The material name.
658 		String mName;
659 		// The group name.
660 		String mGroup;
661 		// All passes entries.
662 		SGTechniqueList mTechniqueEntries;
663 	};
664 
665 
666 	/** Shader generator scheme class. */
667 	class _OgreRTSSExport SGScheme : public RTShaderSystemAlloc
668 	{
669 	public:
670 		SGScheme(const String& schemeName);
671 		~SGScheme();
672 
673 
674 		/** Return true if this scheme dose not contains any techniques.
675 		*/
empty()676 		bool empty() const  { return mTechniqueEntries.empty(); }
677 
678 		/** Invalidate the whole scheme.
679 		@see ShaderGenerator::invalidateScheme.
680 		*/
681 		void invalidate();
682 
683 		/** Validate the whole scheme.
684 		@see ShaderGenerator::validateScheme.
685 		*/
686 		void validate();
687 
688 		/** Invalidate specific material.
689 		@see ShaderGenerator::invalidateMaterial.
690 		*/
691 		void invalidate(const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
692 
693 		/** Validate specific material.
694 		@see ShaderGenerator::validateMaterial.
695 		*/
696 		bool validate(const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
697 
698 		/** Add a technique to current techniques list. */
699 		void addTechniqueEntry(SGTechnique* techEntry);
700 
701 		/** Remove a technique from the current techniques list. */
702 		void removeTechniqueEntry(SGTechnique* techEntry);
703 
704 
705 		/** Get global render state of this scheme.
706 		@see ShaderGenerator::getRenderState.
707 		*/
708 		RenderState* getRenderState();
709 
710 		/** Get specific pass render state.
711 		@see ShaderGenerator::getRenderState.
712 		*/
713 		RenderState* getRenderState(const String& materialName, const String& groupName, unsigned short passIndex);
714 
715 	protected:
716 		/** Synchronize the current light settings of this scheme with the current settings of the scene. */
717 		void synchronizeWithLightSettings();
718 
719 		/** Synchronize the fog settings of this scheme with the current settings of the scene. */
720 		void synchronizeWithFogSettings();
721 
722 
723 	protected:
724 		// Scheme name.
725 		String mName;
726 		// Technique entries.
727 		SGTechniqueList mTechniqueEntries;
728 		// Tells if this scheme is out of date.
729 		bool mOutOfDate;
730 		// The global render state of this scheme.
731 		RenderState* mRenderState;
732 		// Current fog mode.
733 		FogMode mFogMode;
734 	};
735 
736 
737 // Protected types.
738 protected:
739 
740 	/** Shader generator RenderObjectListener sub class. */
741 	class _OgreRTSSExport SGRenderObjectListener : public RenderObjectListener, public RTShaderSystemAlloc
742 	{
743 	public:
SGRenderObjectListener(ShaderGenerator * owner)744 		SGRenderObjectListener(ShaderGenerator* owner)
745 		{
746 			mOwner = owner;
747 		}
748 
749 		/**
750 		Listener overridden function notify the shader generator when rendering single object.
751 		*/
notifyRenderSingleObject(Renderable * rend,const Pass * pass,const AutoParamDataSource * source,const LightList * pLightList,bool suppressRenderStateChanges)752 		virtual void notifyRenderSingleObject(Renderable* rend, const Pass* pass,
753 			const AutoParamDataSource* source,
754 			const LightList* pLightList, bool suppressRenderStateChanges)
755 		{
756 			mOwner->notifyRenderSingleObject(rend, pass, source, pLightList, suppressRenderStateChanges);
757 		}
758 
759 	protected:
760 		ShaderGenerator* mOwner;
761 	};
762 
763 	/** Shader generator scene manager sub class. */
764 	class _OgreRTSSExport SGSceneManagerListener : public SceneManager::Listener, public RTShaderSystemAlloc
765 	{
766 	public:
SGSceneManagerListener(ShaderGenerator * owner)767 		SGSceneManagerListener(ShaderGenerator* owner)
768 		{
769 			mOwner = owner;
770 		}
771 
772 		/**
773 		Listener overridden function notify the shader generator when finding visible objects process started.
774 		*/
preFindVisibleObjects(SceneManager * source,SceneManager::IlluminationRenderStage irs,Viewport * v)775 		virtual void preFindVisibleObjects(SceneManager* source,
776 			SceneManager::IlluminationRenderStage irs, Viewport* v)
777 		{
778 			mOwner->preFindVisibleObjects(source, irs, v);
779 		}
780 
postFindVisibleObjects(SceneManager * source,SceneManager::IlluminationRenderStage irs,Viewport * v)781 		virtual void postFindVisibleObjects(SceneManager* source,
782 			SceneManager::IlluminationRenderStage irs, Viewport* v)
783 		{
784 
785 		}
786 
shadowTexturesUpdated(size_t numberOfShadowTextures)787 		virtual void shadowTexturesUpdated(size_t numberOfShadowTextures)
788 		{
789 
790 		}
791 
shadowTextureCasterPreViewProj(Light * light,Camera * camera,size_t iteration)792 		virtual void shadowTextureCasterPreViewProj(Light* light,
793 			Camera* camera, size_t iteration)
794 		{
795 
796 		}
797 
shadowTextureReceiverPreViewProj(Light * light,Frustum * frustum)798 		virtual void shadowTextureReceiverPreViewProj(Light* light,
799 			Frustum* frustum)
800 		{
801 
802 		}
803 
804 	protected:
805 		// The shader generator instance.
806 		ShaderGenerator* mOwner;
807 	};
808 
809 	/** Shader generator ScriptTranslatorManager sub class. */
810 	class _OgreRTSSExport SGScriptTranslatorManager : public ScriptTranslatorManager
811 	{
812 	public:
SGScriptTranslatorManager(ShaderGenerator * owner)813 		SGScriptTranslatorManager(ShaderGenerator* owner)
814 		{
815 			mOwner = owner;
816 		}
817 
818 		/// Returns the number of translators being managed
getNumTranslators()819 		virtual size_t getNumTranslators() const
820 		{
821 			return mOwner->getNumTranslators();
822 		}
823 
824 		/// Returns a manager for the given object abstract node, or null if it is not supported
getTranslator(const AbstractNodePtr & node)825 		virtual ScriptTranslator *getTranslator(const AbstractNodePtr& node)
826 		{
827 			return mOwner->getTranslator(node);
828 		}
829 
830 	protected:
831 		// The shader generator instance.
832 		ShaderGenerator* mOwner;
833 	};
834 
835 	//-----------------------------------------------------------------------------
836 	typedef map<String, SubRenderStateFactory*>::type 		SubRenderStateFactoryMap;
837 	typedef SubRenderStateFactoryMap::iterator 				SubRenderStateFactoryIterator;
838 	typedef SubRenderStateFactoryMap::const_iterator		SubRenderStateFactoryConstIterator;
839 
840 	//-----------------------------------------------------------------------------
841 	typedef map<String, SceneManager*>::type 				SceneManagerMap;
842 	typedef SceneManagerMap::iterator 						SceneManagerIterator;
843 	typedef SceneManagerMap::const_iterator					SceneManagerConstIterator;
844 
845 protected:
846 	/** Class default constructor */
847 	ShaderGenerator();
848 
849 	/** Class destructor */
850 	~ShaderGenerator();
851 
852 	/** Initialize the shader generator instance. */
853 	bool _initialize();
854 
855 	/** Destory the shader generator instance. */
856 	void _destroy();
857 
858 	/** Find source technique to generate shader based technique based on it. */
859 	Technique* findSourceTechnique(const String& materialName, const String& groupName, const String& srcTechniqueSchemeName, bool allowProgrammable);
860 
861 	/** Checks if a given technique has passes with shaders. */
862 	bool isProgrammable(Technique* tech) const;
863 
864 	/** Called from the sub class of the RenderObjectLister when single object is rendered. */
865 	void notifyRenderSingleObject(Renderable* rend, const Pass* pass,  const AutoParamDataSource* source, const LightList* pLightList, bool suppressRenderStateChanges);
866 
867 	/** Called from the sub class of the SceneManager::Listener when finding visible object process starts. */
868 	void preFindVisibleObjects(SceneManager* source, SceneManager::IlluminationRenderStage irs, Viewport* v);
869 
870 	/** Create sub render state core extensions factories */
871 	void createSubRenderStateExFactories();
872 
873 	/** Destroy sub render state core extensions factories */
874 	void destroySubRenderStateExFactories();
875 
876 	/** Create an instance of the SubRenderState based on script properties using the
877 	current sub render state factories.
878 	@see SubRenderStateFactory::createInstance
879 	@param compiler The compiler instance.
880 	@param prop The abstract property node.
881 	@param pass The pass that is the parent context of this node.
882 	@param translator The translator for the specific SubRenderState
883 	*/
884 	SubRenderState* createSubRenderState(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator);
885 
886 	/** Create an instance of the SubRenderState based on script properties using the
887 	current sub render state factories.
888 	@see SubRenderStateFactory::createInstance
889 	@param compiler The compiler instance.
890 	@param prop The abstract property node.
891 	@param texState The texture unit state that is the parent context of this node.
892 	@param translator The translator for the specific SubRenderState
893 	*/
894 	SubRenderState* createSubRenderState(ScriptCompiler* compiler, PropertyAbstractNode* prop, TextureUnitState* texState, SGScriptTranslator* translator);
895 
896 	/**
897 	Add custom script translator.
898 	Return true upon success.
899 	@param key The key name of the given translator.
900 	@param translator The translator to associate with the given key.
901 	*/
902 	bool addCustomScriptTranslator(const String& key, ScriptTranslator* translator);
903 
904 	/**
905 	Remove custom script translator.
906 	Return true upon success.
907 	@param key The key name of the translator to remove.
908 	*/
909 	bool removeCustomScriptTranslator(const String& key);
910 
911 	/** Return number of script translators. */
912 	size_t getNumTranslators() const;
913 
914 	/** Return a matching script translator. */
915 	ScriptTranslator* getTranslator(const AbstractNodePtr& node);
916 
917 
918 	/** This method called by instance of SGMaterialSerializerListener and
919 	serialize a given pass entry attributes.
920 	@param ser The material serializer.
921 	@param passEntry The SGPass instance.
922 	*/
923 	void serializePassAttributes(MaterialSerializer* ser, SGPass* passEntry);
924 
925 	/** This method called by instance of SGMaterialSerializerListener and
926 	serialize a given textureUnitState entry attributes.
927 	@param ser The material serializer.
928 	@param passEntry The SGPass instance.
929 	@param srcTextureUnit The TextureUnitState being serialized.
930 	*/
931 	void serializeTextureUnitStateAttributes(MaterialSerializer* ser, SGPass* passEntry, const TextureUnitState* srcTextureUnit);
932 
933 	/** Finds an entry iterator in the mMaterialEntriesMap map.
934 	This function is able to find materials with group specified as
935 	AUTODETECT_RESOURCE_GROUP_NAME
936 	*/
937 	SGMaterialIterator findMaterialEntryIt(const String& materialName, const String& groupName);
938 	SGMaterialConstIterator findMaterialEntryIt(const String& materialName, const String& groupName) const;
939 
940 
941 	typedef std::pair<SGScheme*, bool> SchemeCreateOrRetrieveResult;
942 	/**
943 	Returns a requested scheme. If the scheme does not exist this function creates it.
944 	@param schemeName The scheme name to retrieve.
945 	*/
946 	SchemeCreateOrRetrieveResult createOrRetrieveScheme(const String& schemeName);
947 
948     /** Used to check if finalizing */
949     bool getIsFinalizing() const;
950 protected:
951         // Auto mutex.
952         OGRE_AUTO_MUTEX;
953 	// The active scene manager.
954 	SceneManager* mActiveSceneMgr;
955 	// A map of all scene managers this generator is bound to.
956 	SceneManagerMap mSceneManagerMap;
957 	// Render object listener.
958 	SGRenderObjectListener* mRenderObjectListener;
959 	// Scene manager listener.
960 	SGSceneManagerListener* mSceneManagerListener;
961 	// Script translator manager.
962 	SGScriptTranslatorManager* mScriptTranslatorManager;
963 	// Custom material Serializer listener - allows exporting material that contains shader generated techniques.
964 	SGMaterialSerializerListener* mMaterialSerializerListener;
965 	// A map of the registered custom script translators.
966 	SGScriptTranslatorMap mScriptTranslatorsMap;
967 	// The core translator of the RT Shader System.
968 	SGScriptTranslator mCoreScriptTranslator;
969 	// The target shader language (currently only cg supported).
970 	String mShaderLanguage;
971 	// The target vertex shader profile. Will be used as argument for program compilation.
972 	String mVertexShaderProfiles;
973 	// List of target vertex shader profiles.
974 	StringVector mVertexShaderProfilesList;
975 	// The target fragment shader profile. Will be used as argument for program compilation.
976 	String mFragmentShaderProfiles;
977 	// List of target fragment shader profiles..
978 	StringVector mFragmentShaderProfilesList;
979 	// Path for caching the generated shaders.
980 	String mShaderCachePath;
981 	// Shader program manager.
982 	ProgramManager* mProgramManager;
983 	// Shader program writer manager.
984 	ProgramWriterManager* mProgramWriterManager;
985     // File system layer manager.
986 	FileSystemLayer* mFSLayer;
987 	// Fixed Function Render state builder.
988 	FFPRenderStateBuilder* mFFPRenderStateBuilder;
989 	// Material entries map.
990 	SGMaterialMap mMaterialEntriesMap;
991 	// Scheme entries map.
992 	SGSchemeMap mSchemeEntriesMap;
993 	// All technique entries map.
994 	SGTechniqueMap mTechniqueEntriesMap;
995 	// Sub render state registered factories.
996 	SubRenderStateFactoryMap mSubRenderStateFactories;
997 	// Sub render state core extension factories.
998 	SubRenderStateFactoryMap mSubRenderStateExFactories;
999 	// True if active view port use a valid SGScheme.
1000 	bool mActiveViewportValid;
1001 	// Light count per light type.
1002 	int mLightCount[3];
1003 	// Vertex shader outputs compact policy.
1004 	VSOutputCompactPolicy mVSOutputCompactPolicy;
1005 	// Tells whether shaders are created for passes with shaders
1006 	bool mCreateShaderOverProgrammablePass;
1007     // a flag to indicate finalizing
1008     bool mIsFinalizing;
1009 private:
1010 	friend class SGPass;
1011 	friend class FFPRenderStateBuilder;
1012 	friend class SGScriptTranslatorManager;
1013 	friend class SGScriptTranslator;
1014 	friend class SGMaterialSerializerListener;
1015 
1016 };
1017 
1018 /** @} */
1019 /** @} */
1020 
1021 }
1022 }
1023 
1024 #endif
1025 
1026