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 | |
---|
9 | Permission is hereby granted, free of charge, to any person obtaining a copy |
---|
10 | of this software and associated documentation files (the "Software"), to deal |
---|
11 | in the Software without restriction, including without limitation the rights |
---|
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
---|
13 | copies of the Software, and to permit persons to whom the Software is |
---|
14 | furnished to do so, subject to the following conditions: |
---|
15 | |
---|
16 | The above copyright notice and this permission notice shall be included in |
---|
17 | all copies or substantial portions of the Software. |
---|
18 | |
---|
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
---|
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
---|
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
---|
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
---|
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
---|
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
---|
25 | THE SOFTWARE. |
---|
26 | ----------------------------------------------------------------------------- |
---|
27 | */ |
---|
28 | #ifndef __MaterialSerializer_H__ |
---|
29 | #define __MaterialSerializer_H__ |
---|
30 | |
---|
31 | #include "OgrePrerequisites.h" |
---|
32 | #include "OgreMaterial.h" |
---|
33 | #include "OgreBlendMode.h" |
---|
34 | #include "OgreTextureUnitState.h" |
---|
35 | #include "OgreGpuProgram.h" |
---|
36 | #include "OgreStringVector.h" |
---|
37 | #include "OgreHeaderPrefix.h" |
---|
38 | |
---|
39 | namespace Ogre { |
---|
40 | |
---|
41 | /** \addtogroup Core |
---|
42 | * @{ |
---|
43 | */ |
---|
44 | /** \addtogroup Materials |
---|
45 | * @{ |
---|
46 | */ |
---|
47 | /** Enum to identify material sections. */ |
---|
48 | enum MaterialScriptSection |
---|
49 | { |
---|
50 | MSS_NONE, |
---|
51 | MSS_MATERIAL, |
---|
52 | MSS_TECHNIQUE, |
---|
53 | MSS_PASS, |
---|
54 | MSS_TEXTUREUNIT, |
---|
55 | MSS_PROGRAM_REF, |
---|
56 | MSS_PROGRAM, |
---|
57 | MSS_DEFAULT_PARAMETERS, |
---|
58 | MSS_TEXTURESOURCE |
---|
59 | }; |
---|
60 | /** Struct for holding a program definition which is in progress. */ |
---|
61 | struct MaterialScriptProgramDefinition |
---|
62 | { |
---|
63 | String name; |
---|
64 | GpuProgramType progType; |
---|
65 | String language; |
---|
66 | String source; |
---|
67 | String syntax; |
---|
68 | bool supportsSkeletalAnimation; |
---|
69 | bool supportsMorphAnimation; |
---|
70 | ushort supportsPoseAnimation; // number of simultaneous poses supported |
---|
71 | bool usesVertexTextureFetch; |
---|
72 | vector<std::pair<String, String> >::type customParameters; |
---|
73 | }; |
---|
74 | /** Struct for holding the script context while parsing. */ |
---|
75 | struct MaterialScriptContext |
---|
76 | { |
---|
77 | MaterialScriptSection section; |
---|
78 | String groupName; |
---|
79 | MaterialPtr material; |
---|
80 | Technique* technique; |
---|
81 | Pass* pass; |
---|
82 | TextureUnitState* textureUnit; |
---|
83 | GpuProgramPtr program; /// Used when referencing a program, not when defining it |
---|
84 | bool isVertexProgramShadowCaster; /// When referencing, are we in context of shadow caster |
---|
85 | bool isFragmentProgramShadowCaster; /// When referencing, are we in context of shadow caster |
---|
86 | bool isVertexProgramShadowReceiver; /// When referencing, are we in context of shadow caster |
---|
87 | bool isFragmentProgramShadowReceiver; /// When referencing, are we in context of shadow caster |
---|
88 | GpuProgramParametersSharedPtr programParams; |
---|
89 | ushort numAnimationParametrics; |
---|
90 | MaterialScriptProgramDefinition* programDef; /// This is used while defining a program |
---|
91 | |
---|
92 | int techLev, //Keep track of what tech, pass, and state level we are in |
---|
93 | passLev, |
---|
94 | stateLev; |
---|
95 | StringVector defaultParamLines; |
---|
96 | |
---|
97 | /// Error reporting state |
---|
98 | size_t lineNo; |
---|
99 | String filename; |
---|
100 | AliasTextureNamePairList textureAliases; |
---|
101 | }; |
---|
102 | /// Function def for material attribute parser; return value determines if the next line should be { |
---|
103 | typedef bool (*ATTRIBUTE_PARSER)(String& params, MaterialScriptContext& context); |
---|
104 | |
---|
105 | /** Class for serializing Materials to / from a .material script.*/ |
---|
106 | class _OgreExport MaterialSerializer : public SerializerAlloc |
---|
107 | { |
---|
108 | public: |
---|
109 | |
---|
110 | // Material serialize event. |
---|
111 | enum SerializeEvent |
---|
112 | { |
---|
113 | MSE_PRE_WRITE, |
---|
114 | MSE_WRITE_BEGIN, |
---|
115 | MSE_WRITE_END, |
---|
116 | MSE_POST_WRITE |
---|
117 | }; |
---|
118 | |
---|
119 | /** Class that allows listening in on the various stages of material serialization process. |
---|
120 | Sub-classing it enable extending the attribute set of any part in the material. |
---|
121 | */ |
---|
122 | class Listener |
---|
123 | { |
---|
124 | public: |
---|
125 | virtual ~Listener() {} |
---|
126 | |
---|
127 | /** Called when material section event raised. |
---|
128 | @param ser The MaterialSerializer instance that writes the given material. |
---|
129 | @param event The current section writing stage. |
---|
130 | @param skip May set to true by sub-class instances in order to skip the following section write. |
---|
131 | This parameter relevant only when stage equals MSE_PRE_WRITE. |
---|
132 | @param mat The material that is being written. |
---|
133 | */ |
---|
134 | virtual void materialEventRaised(MaterialSerializer* ser, |
---|
135 | SerializeEvent event, bool& skip, const Material* mat) |
---|
136 | { (void)ser; (void)event; (void)skip; (void)mat; } |
---|
137 | |
---|
138 | /** Called when technique section event raised. |
---|
139 | @param ser The MaterialSerializer instance that writes the given material. |
---|
140 | @param event The current section writing stage. |
---|
141 | @param skip May set to true by sub-class instances in order to skip the following section write. |
---|
142 | This parameter relevant only when stage equals MSE_PRE_WRITE. |
---|
143 | @param tech The technique that is being written. |
---|
144 | */ |
---|
145 | virtual void techniqueEventRaised(MaterialSerializer* ser, |
---|
146 | SerializeEvent event, bool& skip, const Technique* tech) |
---|
147 | { (void)ser; (void)event; (void)skip; (void)tech; } |
---|
148 | |
---|
149 | /** Called when pass section event raised. |
---|
150 | @param ser The MaterialSerializer instance that writes the given material. |
---|
151 | @param event The current section writing stage. |
---|
152 | @param skip May set to true by sub-class instances in order to skip the following section write. |
---|
153 | This parameter relevant only when stage equals MSE_PRE_WRITE. |
---|
154 | @param pass The pass that is being written. |
---|
155 | */ |
---|
156 | virtual void passEventRaised(MaterialSerializer* ser, |
---|
157 | SerializeEvent event, bool& skip, const Pass* pass) |
---|
158 | { (void)ser; (void)event; (void)skip; (void)pass; } |
---|
159 | |
---|
160 | /** Called when GPU program reference section event raised. |
---|
161 | @param ser The MaterialSerializer instance that writes the given material. |
---|
162 | @param event The current section writing stage. |
---|
163 | @param skip May set to true by sub-class instances in order to skip the following section write. |
---|
164 | This parameter relevant only when stage equals MSE_PRE_WRITE. |
---|
165 | @param attrib The GPU program reference description (vertex_program_ref, fragment_program_ref, etc). |
---|
166 | @param program The program being written. |
---|
167 | @param params The program parameters. |
---|
168 | @param defaultParams The default program parameters. |
---|
169 | */ |
---|
170 | void gpuProgramRefEventRaised(MaterialSerializer* ser, |
---|
171 | SerializeEvent event, bool& skip, |
---|
172 | const String& attrib, |
---|
173 | const GpuProgramPtr& program, |
---|
174 | const GpuProgramParametersSharedPtr& params, |
---|
175 | GpuProgramParameters* defaultParams) |
---|
176 | { |
---|
177 | (void)ser; |
---|
178 | (void)event; |
---|
179 | (void)skip; |
---|
180 | (void)attrib; |
---|
181 | (void)program; |
---|
182 | (void)params; |
---|
183 | (void)defaultParams; |
---|
184 | } |
---|
185 | |
---|
186 | /** Called when texture unit state section event raised. |
---|
187 | @param ser The MaterialSerializer instance that writes the given material. |
---|
188 | @param event The current section writing stage. |
---|
189 | @param skip May set to true by sub-class instances in order to skip the following section write. |
---|
190 | This parameter relevant only when stage equals MSE_PRE_WRITE. |
---|
191 | @param textureUnit The texture unit state that is being written. |
---|
192 | */ |
---|
193 | virtual void textureUnitStateEventRaised(MaterialSerializer* ser, |
---|
194 | SerializeEvent event, bool& skip, const TextureUnitState* textureUnit) |
---|
195 | { |
---|
196 | (void)ser; |
---|
197 | (void)event; |
---|
198 | (void)skip; |
---|
199 | (void)textureUnit; |
---|
200 | } |
---|
201 | }; |
---|
202 | |
---|
203 | protected: |
---|
204 | /// Keyword-mapped attribute parsers. |
---|
205 | typedef map<String, ATTRIBUTE_PARSER>::type AttribParserList; |
---|
206 | |
---|
207 | MaterialScriptContext mScriptContext; |
---|
208 | |
---|
209 | /** internal method for parsing a material |
---|
210 | @return true if it expects the next line to be a { |
---|
211 | */ |
---|
212 | bool parseScriptLine(String& line); |
---|
213 | /** internal method for finding & invoking an attribute parser. */ |
---|
214 | bool invokeParser(String& line, AttribParserList& parsers); |
---|
215 | /** Internal method for saving a program definition which has been |
---|
216 | built up. |
---|
217 | */ |
---|
218 | void finishProgramDefinition(void); |
---|
219 | /// Parsers for the root of the material script |
---|
220 | AttribParserList mRootAttribParsers; |
---|
221 | /// Parsers for the material section of a script |
---|
222 | AttribParserList mMaterialAttribParsers; |
---|
223 | /// Parsers for the technique section of a script |
---|
224 | AttribParserList mTechniqueAttribParsers; |
---|
225 | /// Parsers for the pass section of a script |
---|
226 | AttribParserList mPassAttribParsers; |
---|
227 | /// Parsers for the texture unit section of a script |
---|
228 | AttribParserList mTextureUnitAttribParsers; |
---|
229 | /// Parsers for the program reference section of a script |
---|
230 | AttribParserList mProgramRefAttribParsers; |
---|
231 | /// Parsers for the program definition section of a script |
---|
232 | AttribParserList mProgramAttribParsers; |
---|
233 | /// Parsers for the program definition section of a script |
---|
234 | AttribParserList mProgramDefaultParamAttribParsers; |
---|
235 | |
---|
236 | /// Listeners list of this Serializer. |
---|
237 | typedef vector<Listener*>::type ListenerList; |
---|
238 | typedef ListenerList::iterator ListenerListIterator; |
---|
239 | typedef ListenerList::const_iterator ListenerListConstIterator; |
---|
240 | ListenerList mListeners; |
---|
241 | |
---|
242 | |
---|
243 | void writeMaterial(const MaterialPtr& pMat, const String& materialName = ""); |
---|
244 | void writeTechnique(const Technique* pTech); |
---|
245 | void writePass(const Pass* pPass); |
---|
246 | void writeVertexProgramRef(const Pass* pPass); |
---|
247 | void writeShadowCasterVertexProgramRef(const Pass* pPass); |
---|
248 | void writeShadowCasterFragmentProgramRef(const Pass* pPass); |
---|
249 | void writeShadowReceiverVertexProgramRef(const Pass* pPass); |
---|
250 | void writeShadowReceiverFragmentProgramRef(const Pass* pPass); |
---|
251 | void writeFragmentProgramRef(const Pass* pPass); |
---|
252 | void writeGpuProgramRef(const String& attrib, const GpuProgramPtr& program, const GpuProgramParametersSharedPtr& params); |
---|
253 | void writeGpuPrograms(void); |
---|
254 | void writeGPUProgramParameters(const GpuProgramParametersSharedPtr& params, GpuProgramParameters* defaultParams, |
---|
255 | const unsigned short level = 4, const bool useMainBuffer = true); |
---|
256 | void writeNamedGpuProgramParameters(const GpuProgramParametersSharedPtr& params, GpuProgramParameters* defaultParams, |
---|
257 | const unsigned short level = 4, const bool useMainBuffer = true); |
---|
258 | void writeLowLevelGpuProgramParameters(const GpuProgramParametersSharedPtr& params, GpuProgramParameters* defaultParams, |
---|
259 | const unsigned short level = 4, const bool useMainBuffer = true); |
---|
260 | void writeGpuProgramParameter( |
---|
261 | const String& commandName, const String& identifier, |
---|
262 | const GpuProgramParameters::AutoConstantEntry* autoEntry, |
---|
263 | const GpuProgramParameters::AutoConstantEntry* defaultAutoEntry, |
---|
264 | bool isFloat, bool isDouble, size_t physicalIndex, size_t physicalSize, |
---|
265 | const GpuProgramParametersSharedPtr& params, GpuProgramParameters* defaultParams, |
---|
266 | const unsigned short level, const bool useMainBuffer); |
---|
267 | void writeTextureUnit(const TextureUnitState *pTex); |
---|
268 | void writeSceneBlendFactor(const SceneBlendFactor c_src, const SceneBlendFactor c_dest, |
---|
269 | const SceneBlendFactor a_src, const SceneBlendFactor a_dest); |
---|
270 | void writeSceneBlendFactor(const SceneBlendFactor sbf_src, const SceneBlendFactor sbf_dest); |
---|
271 | void writeSceneBlendFactor(const SceneBlendFactor sbf); |
---|
272 | void writeCompareFunction(const CompareFunction cf); |
---|
273 | void writeColourValue(const ColourValue &colour, bool writeAlpha = false); |
---|
274 | void writeLayerBlendOperationEx(const LayerBlendOperationEx op); |
---|
275 | void writeLayerBlendSource(const LayerBlendSource lbs); |
---|
276 | |
---|
277 | typedef multimap<TextureUnitState::TextureEffectType, TextureUnitState::TextureEffect>::type EffectMap; |
---|
278 | |
---|
279 | void writeRotationEffect(const TextureUnitState::TextureEffect& effect, const TextureUnitState *pTex); |
---|
280 | void writeTransformEffect(const TextureUnitState::TextureEffect& effect, const TextureUnitState *pTex); |
---|
281 | void writeScrollEffect(const TextureUnitState::TextureEffect& effect, const TextureUnitState *pTex); |
---|
282 | void writeEnvironmentMapEffect(const TextureUnitState::TextureEffect& effect, const TextureUnitState *pTex); |
---|
283 | |
---|
284 | String convertFiltering(FilterOptions fo); |
---|
285 | |
---|
286 | |
---|
287 | /** Internal methods that invokes registered listeners callback. |
---|
288 | @see Listener::materialEventRaised. |
---|
289 | */ |
---|
290 | void fireMaterialEvent(SerializeEvent event, bool& skip, const Material* mat); |
---|
291 | |
---|
292 | /** Internal methods that invokes registered listeners callback. |
---|
293 | @see Listener::techniqueEventRaised. |
---|
294 | */ |
---|
295 | void fireTechniqueEvent(SerializeEvent event, bool& skip, const Technique* tech); |
---|
296 | |
---|
297 | /** Internal methods that invokes registered listeners callback. |
---|
298 | @see Listener::passEventRaised. |
---|
299 | */ |
---|
300 | void firePassEvent(SerializeEvent event, bool& skip, const Pass* pass); |
---|
301 | |
---|
302 | /** Internal methods that invokes registered listeners callback. |
---|
303 | @see Listener::gpuProgramRefEventRaised. |
---|
304 | */ |
---|
305 | void fireGpuProgramRefEvent(SerializeEvent event, bool& skip, |
---|
306 | const String& attrib, |
---|
307 | const GpuProgramPtr& program, |
---|
308 | const GpuProgramParametersSharedPtr& params, |
---|
309 | GpuProgramParameters* defaultParams); |
---|
310 | |
---|
311 | |
---|
312 | /** Internal methods that invokes registered listeners callback. |
---|
313 | @see Listener::textureUnitStateEventRaised. |
---|
314 | */ |
---|
315 | void fireTextureUnitStateEvent(SerializeEvent event, bool& skip, const TextureUnitState* textureUnit); |
---|
316 | |
---|
317 | public: |
---|
318 | /** default constructor*/ |
---|
319 | MaterialSerializer(); |
---|
320 | /** default destructor*/ |
---|
321 | virtual ~MaterialSerializer() {} |
---|
322 | |
---|
323 | /** Queue an in-memory Material to the internal buffer for export. |
---|
324 | @param pMat Material pointer |
---|
325 | @param clearQueued If true, any materials already queued will be removed |
---|
326 | @param exportDefaults If true, attributes which are defaulted will be |
---|
327 | included in the script exported, otherwise they will be omitted |
---|
328 | @param materialName Allow exporting the given material under a different name. |
---|
329 | In case of empty string the original material name will be used. |
---|
330 | */ |
---|
331 | void queueForExport(const MaterialPtr& pMat, bool clearQueued = false, |
---|
332 | bool exportDefaults = false, const String& materialName = ""); |
---|
333 | /** Exports queued material(s) to a named material script file. |
---|
334 | @param filename the file name of the material script to be exported |
---|
335 | @param includeProgDef If true, vertex program and fragment program |
---|
336 | definitions will be written at the top of the material script |
---|
337 | @param programFilename the file name of the vertex / fragment program |
---|
338 | script to be exported. This is only used if there are program definitions |
---|
339 | to be exported and includeProgDef is false |
---|
340 | when calling queueForExport. |
---|
341 | */ |
---|
342 | void exportQueued(const String& filename, const bool includeProgDef = false, const String& programFilename = ""); |
---|
343 | /** Exports a single in-memory Material to the named material script file. |
---|
344 | @param exportDefaults if true then exports all values including defaults |
---|
345 | @param includeProgDef if true includes Gpu shader program definitions in the |
---|
346 | export material script otherwise if false then program definitions will |
---|
347 | be exported to a separate file with name programFilename if |
---|
348 | programFilename is not empty |
---|
349 | @param programFilename the file name of the vertex / fragment program |
---|
350 | script to be exported. This is only used if includeProgDef is false. |
---|
351 | @param materialName Allow exporting the given material under a different name. |
---|
352 | In case of empty string the original material name will be used. |
---|
353 | */ |
---|
354 | void exportMaterial(const MaterialPtr& pMat, const String& filename, bool exportDefaults = false, |
---|
355 | const bool includeProgDef = false, const String& programFilename = "", |
---|
356 | const String& materialName = ""); |
---|
357 | /** Returns a string representing the parsed material(s) */ |
---|
358 | const String &getQueuedAsString() const; |
---|
359 | /** Clears the internal buffer */ |
---|
360 | void clearQueue(); |
---|
361 | |
---|
362 | /** Parses a Material script file passed as a stream. |
---|
363 | */ |
---|
364 | void parseScript(DataStreamPtr& stream, const String& groupName); |
---|
365 | |
---|
366 | /** Register a listener to this Serializer. |
---|
367 | @see MaterialSerializer::Listener |
---|
368 | */ |
---|
369 | void addListener(Listener* listener); |
---|
370 | |
---|
371 | /** Remove a listener from this Serializer. |
---|
372 | @see MaterialSerializer::Listener |
---|
373 | */ |
---|
374 | void removeListener(Listener* listener); |
---|
375 | |
---|
376 | private: |
---|
377 | String mBuffer; |
---|
378 | String mGpuProgramBuffer; |
---|
379 | typedef set<String>::type GpuProgramDefinitionContainer; |
---|
380 | typedef GpuProgramDefinitionContainer::iterator GpuProgramDefIterator; |
---|
381 | GpuProgramDefinitionContainer mGpuProgramDefinitionContainer; |
---|
382 | bool mDefaults; |
---|
383 | |
---|
384 | public: |
---|
385 | void beginSection(unsigned short level, const bool useMainBuffer = true) |
---|
386 | { |
---|
387 | String& buffer = (useMainBuffer ? mBuffer : mGpuProgramBuffer); |
---|
388 | buffer += "\n"; |
---|
389 | for (unsigned short i = 0; i < level; ++i) |
---|
390 | { |
---|
391 | buffer += "\t"; |
---|
392 | } |
---|
393 | buffer += "{"; |
---|
394 | } |
---|
395 | void endSection(unsigned short level, const bool useMainBuffer = true) |
---|
396 | { |
---|
397 | String& buffer = (useMainBuffer ? mBuffer : mGpuProgramBuffer); |
---|
398 | buffer += "\n"; |
---|
399 | for (unsigned short i = 0; i < level; ++i) |
---|
400 | { |
---|
401 | buffer += "\t"; |
---|
402 | } |
---|
403 | buffer += "}"; |
---|
404 | } |
---|
405 | |
---|
406 | void writeAttribute(unsigned short level, const String& att, const bool useMainBuffer = true) |
---|
407 | { |
---|
408 | String& buffer = (useMainBuffer ? mBuffer : mGpuProgramBuffer); |
---|
409 | buffer += "\n"; |
---|
410 | for (unsigned short i = 0; i < level; ++i) |
---|
411 | { |
---|
412 | buffer += "\t"; |
---|
413 | } |
---|
414 | buffer += att; |
---|
415 | } |
---|
416 | |
---|
417 | void writeValue(const String& val, const bool useMainBuffer = true) |
---|
418 | { |
---|
419 | String& buffer = (useMainBuffer ? mBuffer : mGpuProgramBuffer); |
---|
420 | buffer += (" " + val); |
---|
421 | } |
---|
422 | |
---|
423 | String quoteWord(const String& val) |
---|
424 | { |
---|
425 | if (val.find_first_of(" \t") != String::npos) |
---|
426 | return ("\"" + val + "\""); |
---|
427 | else return val; |
---|
428 | } |
---|
429 | |
---|
430 | |
---|
431 | void writeComment(unsigned short level, const String& comment, const bool useMainBuffer = true) |
---|
432 | { |
---|
433 | String& buffer = (useMainBuffer ? mBuffer : mGpuProgramBuffer); |
---|
434 | buffer += "\n"; |
---|
435 | for (unsigned short i = 0; i < level; ++i) |
---|
436 | { |
---|
437 | buffer += "\t"; |
---|
438 | } |
---|
439 | buffer += "// " + comment; |
---|
440 | } |
---|
441 | |
---|
442 | |
---|
443 | |
---|
444 | }; |
---|
445 | /** @} */ |
---|
446 | /** @} */ |
---|
447 | } |
---|
448 | |
---|
449 | #include "OgreHeaderSuffix.h" |
---|
450 | |
---|
451 | #endif |
---|