| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- #pragma once
- #include <anki/util/StringList.h>
- #include <anki/Gr.h>
- #include <anki/resource/Common.h>
- #include <anki/resource/Material.h>
- namespace anki
- {
- // Forward
- class XmlElement;
- /// Material loader variable. It's the information on whatever is inside
- /// \<input\>
- class MaterialLoaderInputVariable : public NonCopyable
- {
- public:
- GenericMemoryPoolAllocator<U8> m_alloc;
- String m_name;
- StringList m_value;
- String m_line;
- ShaderVariableDataType m_type = ShaderVariableDataType::NONE;
- BuiltinMaterialVariableId m_builtin = BuiltinMaterialVariableId::NONE;
- // Flags
- class Flags
- {
- public:
- Bool8 m_inBlock = false;
- Bool8 m_texture = false;
- Bool8 m_builtin = false;
- Bool8 m_const = false;
- Bool8 m_instanced = false;
- Bool8 m_inShadow = false;
- Bool8 m_specialBuiltin = false;
- Bool operator==(const Flags& b) const
- {
- return memcmp(this, &b, sizeof(*this)) == 0;
- }
- } m_flags;
- I16 m_binding = -1; ///< Texture unit
- I16 m_index = -1;
- ShaderVariableBlockInfo m_blockInfo;
- ShaderTypeBit m_shaderDefinedMask = ShaderTypeBit::NONE; ///< Defined in
- ShaderTypeBit m_shaderReferencedMask = ShaderTypeBit::NONE; ///< Referenced
- MaterialLoaderInputVariable()
- {
- }
- MaterialLoaderInputVariable(MaterialLoaderInputVariable&& b)
- {
- move(b);
- }
- ~MaterialLoaderInputVariable()
- {
- m_name.destroy(m_alloc);
- m_value.destroy(m_alloc);
- m_line.destroy(m_alloc);
- }
- MaterialLoaderInputVariable& operator=(MaterialLoaderInputVariable&& b)
- {
- move(b);
- return *this;
- }
- void move(MaterialLoaderInputVariable& b);
- Bool duplicate(const MaterialLoaderInputVariable& b) const
- {
- return b.m_name == m_name && b.m_value == m_value && b.m_type == m_type
- && b.m_builtin == m_builtin && b.m_flags == m_flags;
- }
- CString typeStr() const;
- };
- /// Creator of shader programs. This class parses between
- /// @code <material></material> @endcode and creates the source of a custom
- /// program.
- ///
- /// @note Be carefull when you change the methods. Some change may create more
- /// unique shaders and this is never good.
- class MaterialLoader
- {
- public:
- using Input = MaterialLoaderInputVariable;
- explicit MaterialLoader(GenericMemoryPoolAllocator<U8> alloc);
- ~MaterialLoader();
- ANKI_USE_RESULT Error parseXmlDocument(const XmlDocument& doc);
- /// Get the shader source code
- const String& getShaderSource(ShaderType shaderType_) const
- {
- U shaderType = enumToType(shaderType_);
- ANKI_ASSERT(!m_sourceBaked[shaderType].isEmpty());
- return m_sourceBaked[shaderType];
- }
- /// After parsing the program mutate the sources for a specific use case.
- void mutate(const RenderingKey& key);
- /// Iterate all the variables.
- template<typename TFunc>
- ANKI_USE_RESULT Error iterateAllInputVariables(TFunc func) const
- {
- for(const Input& in : m_inputs)
- {
- if(!in.m_flags.m_const && !in.m_flags.m_specialBuiltin)
- {
- ANKI_CHECK(func(in));
- }
- }
- return ErrorCode::NONE;
- }
- Bool getTessellationEnabled() const
- {
- return m_tessellation;
- }
- U32 getUniformBlockSize() const
- {
- return m_blockSize;
- }
- Bool isInstanced() const
- {
- return m_instanced;
- }
- U getLodCount() const
- {
- return m_lodCount;
- }
- Bool getShadowEnabled() const
- {
- return m_shadow;
- }
- Bool isForwardShading() const
- {
- return m_forwardShading;
- }
- private:
- GenericMemoryPoolAllocator<char> m_alloc;
- Array<StringList, 5> m_source; ///< Shader program final source
- Array<String, 5> m_sourceBaked; ///< Final source baked
- List<Input> m_inputs;
- ShaderTypeBit m_uniformBlockReferencedMask = ShaderTypeBit::NONE;
- U32 m_blockSize = 0;
- Bool8 m_instanced = false;
- U32 m_texBinding = 0;
- ShaderTypeBit m_instanceIdMask = ShaderTypeBit::NONE;
- Bool8 m_tessellation = false;
- U8 m_lodCount = 0;
- Bool8 m_shadow = true;
- Bool8 m_forwardShading = false;
- U32 m_nextIndex = 0;
- /// Parse what is within the
- /// @code <programs></programs> @endcode
- ANKI_USE_RESULT Error parseProgramsTag(const XmlElement& el);
- /// Parse what is within the
- /// @code <program></program> @endcode
- ANKI_USE_RESULT Error parseProgramTag(const XmlElement& el);
- /// Parse what is within the @code <inputs></inputs> @endcode
- ANKI_USE_RESULT Error parseInputsTag(const XmlElement& programEl);
- void processInputs();
- /// Parse what is within the @code <operation></operation> @endcode
- ANKI_USE_RESULT Error parseOperationTag(const XmlElement& el,
- ShaderType glshader,
- ShaderTypeBit glshaderbit,
- String& out);
- };
- } // end namespace anki
|