MaterialLoader.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <anki/util/StringList.h>
  7. #include <anki/Gr.h>
  8. #include <anki/resource/Common.h>
  9. #include <anki/resource/Material.h>
  10. namespace anki
  11. {
  12. // Forward
  13. class XmlElement;
  14. /// Material loader variable. It's the information on whatever is inside
  15. /// \<input\>
  16. class MaterialLoaderInputVariable : public NonCopyable
  17. {
  18. public:
  19. GenericMemoryPoolAllocator<U8> m_alloc;
  20. String m_name;
  21. StringList m_value;
  22. String m_line;
  23. ShaderVariableDataType m_type = ShaderVariableDataType::NONE;
  24. BuiltinMaterialVariableId m_builtin = BuiltinMaterialVariableId::NONE;
  25. // Flags
  26. class Flags
  27. {
  28. public:
  29. Bool8 m_inBlock = false;
  30. Bool8 m_texture = false;
  31. Bool8 m_builtin = false;
  32. Bool8 m_const = false;
  33. Bool8 m_instanced = false;
  34. Bool8 m_inShadow = false;
  35. Bool8 m_specialBuiltin = false;
  36. Bool operator==(const Flags& b) const
  37. {
  38. return memcmp(this, &b, sizeof(*this)) == 0;
  39. }
  40. } m_flags;
  41. I16 m_binding = -1; ///< Texture unit
  42. I16 m_index = -1;
  43. ShaderVariableBlockInfo m_blockInfo;
  44. ShaderTypeBit m_shaderDefinedMask = ShaderTypeBit::NONE; ///< Defined in
  45. ShaderTypeBit m_shaderReferencedMask = ShaderTypeBit::NONE; ///< Referenced
  46. MaterialLoaderInputVariable()
  47. {
  48. }
  49. MaterialLoaderInputVariable(MaterialLoaderInputVariable&& b)
  50. {
  51. move(b);
  52. }
  53. ~MaterialLoaderInputVariable()
  54. {
  55. m_name.destroy(m_alloc);
  56. m_value.destroy(m_alloc);
  57. m_line.destroy(m_alloc);
  58. }
  59. MaterialLoaderInputVariable& operator=(MaterialLoaderInputVariable&& b)
  60. {
  61. move(b);
  62. return *this;
  63. }
  64. void move(MaterialLoaderInputVariable& b);
  65. Bool duplicate(const MaterialLoaderInputVariable& b) const
  66. {
  67. return b.m_name == m_name && b.m_value == m_value && b.m_type == m_type
  68. && b.m_builtin == m_builtin && b.m_flags == m_flags;
  69. }
  70. CString typeStr() const;
  71. };
  72. /// Creator of shader programs. This class parses between
  73. /// @code <material></material> @endcode and creates the source of a custom
  74. /// program.
  75. ///
  76. /// @note Be carefull when you change the methods. Some change may create more
  77. /// unique shaders and this is never good.
  78. class MaterialLoader
  79. {
  80. public:
  81. using Input = MaterialLoaderInputVariable;
  82. explicit MaterialLoader(GenericMemoryPoolAllocator<U8> alloc);
  83. ~MaterialLoader();
  84. ANKI_USE_RESULT Error parseXmlDocument(const XmlDocument& doc);
  85. /// Get the shader source code
  86. const String& getShaderSource(ShaderType shaderType_) const
  87. {
  88. U shaderType = enumToType(shaderType_);
  89. ANKI_ASSERT(!m_sourceBaked[shaderType].isEmpty());
  90. return m_sourceBaked[shaderType];
  91. }
  92. /// After parsing the program mutate the sources for a specific use case.
  93. void mutate(const RenderingKey& key);
  94. /// Iterate all the variables.
  95. template<typename TFunc>
  96. ANKI_USE_RESULT Error iterateAllInputVariables(TFunc func) const
  97. {
  98. for(const Input& in : m_inputs)
  99. {
  100. if(!in.m_flags.m_const && !in.m_flags.m_specialBuiltin)
  101. {
  102. ANKI_CHECK(func(in));
  103. }
  104. }
  105. return ErrorCode::NONE;
  106. }
  107. Bool getTessellationEnabled() const
  108. {
  109. return m_tessellation;
  110. }
  111. U32 getUniformBlockSize() const
  112. {
  113. return m_blockSize;
  114. }
  115. Bool isInstanced() const
  116. {
  117. return m_instanced;
  118. }
  119. U getLodCount() const
  120. {
  121. return m_lodCount;
  122. }
  123. Bool getShadowEnabled() const
  124. {
  125. return m_shadow;
  126. }
  127. Bool isForwardShading() const
  128. {
  129. return m_forwardShading;
  130. }
  131. private:
  132. GenericMemoryPoolAllocator<char> m_alloc;
  133. Array<StringList, 5> m_source; ///< Shader program final source
  134. Array<String, 5> m_sourceBaked; ///< Final source baked
  135. List<Input> m_inputs;
  136. ShaderTypeBit m_uniformBlockReferencedMask = ShaderTypeBit::NONE;
  137. U32 m_blockSize = 0;
  138. Bool8 m_instanced = false;
  139. U32 m_texBinding = 0;
  140. ShaderTypeBit m_instanceIdMask = ShaderTypeBit::NONE;
  141. Bool8 m_tessellation = false;
  142. U8 m_lodCount = 0;
  143. Bool8 m_shadow = true;
  144. Bool8 m_forwardShading = false;
  145. U32 m_nextIndex = 0;
  146. /// Parse what is within the
  147. /// @code <programs></programs> @endcode
  148. ANKI_USE_RESULT Error parseProgramsTag(const XmlElement& el);
  149. /// Parse what is within the
  150. /// @code <program></program> @endcode
  151. ANKI_USE_RESULT Error parseProgramTag(const XmlElement& el);
  152. /// Parse what is within the @code <inputs></inputs> @endcode
  153. ANKI_USE_RESULT Error parseInputsTag(const XmlElement& programEl);
  154. void processInputs();
  155. /// Parse what is within the @code <operation></operation> @endcode
  156. ANKI_USE_RESULT Error parseOperationTag(const XmlElement& el,
  157. ShaderType glshader,
  158. ShaderTypeBit glshaderbit,
  159. String& out);
  160. };
  161. } // end namespace anki