RenderComponent.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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/scene/Common.h>
  7. #include <anki/scene/SceneComponent.h>
  8. #include <anki/resource/Material.h>
  9. #include <anki/resource/Model.h>
  10. namespace anki
  11. {
  12. /// @addtogroup scene
  13. /// @{
  14. // Forward
  15. class RenderComponentVariable;
  16. template<typename T>
  17. class RenderComponentVariableTemplate;
  18. /// RenderComponent variable base. It's a visitable.
  19. using RenderComponentVariableVisitable =
  20. VisitableCommonBase<RenderComponentVariable, // The base
  21. RenderComponentVariableTemplate<F32>,
  22. RenderComponentVariableTemplate<Vec2>,
  23. RenderComponentVariableTemplate<Vec3>,
  24. RenderComponentVariableTemplate<Vec4>,
  25. RenderComponentVariableTemplate<Mat3>,
  26. RenderComponentVariableTemplate<Mat4>,
  27. RenderComponentVariableTemplate<TextureResourcePtr>>;
  28. /// A wrapper on top of MaterialVariable
  29. class RenderComponentVariable : public RenderComponentVariableVisitable
  30. {
  31. public:
  32. using Base = RenderComponentVariableVisitable;
  33. RenderComponentVariable(const MaterialVariable* mvar);
  34. virtual ~RenderComponentVariable();
  35. /// This will trigger copy on write
  36. template<typename T>
  37. void setValue(const T& value)
  38. {
  39. ANKI_ASSERT(Base::isTypeOf<RenderComponentVariableTemplate<T>>());
  40. auto derived = static_cast<RenderComponentVariableTemplate<T>*>(this);
  41. derived->setValue(value);
  42. }
  43. template<typename T>
  44. const T& getValue() const
  45. {
  46. ANKI_ASSERT(Base::isTypeOf<RenderComponentVariableTemplate<T>>());
  47. auto derived =
  48. static_cast<const RenderComponentVariableTemplate<T>*>(this);
  49. return derived->getValue();
  50. }
  51. const MaterialVariable& getMaterialVariable() const
  52. {
  53. return *m_mvar;
  54. }
  55. protected:
  56. const MaterialVariable* m_mvar = nullptr;
  57. };
  58. /// RenderComponent variable. This class should not be visible to other
  59. /// interfaces except render component
  60. template<typename T>
  61. class RenderComponentVariableTemplate : public RenderComponentVariable
  62. {
  63. public:
  64. using Base = RenderComponentVariable;
  65. using Type = T;
  66. RenderComponentVariableTemplate(const MaterialVariable* mvar)
  67. : RenderComponentVariable(mvar)
  68. {
  69. setupVisitable(this);
  70. }
  71. ~RenderComponentVariableTemplate()
  72. {
  73. }
  74. void setValue(const T& value)
  75. {
  76. ANKI_ASSERT(isTypeOf<RenderComponentVariableTemplate<T>>());
  77. ANKI_ASSERT(Base::getMaterialVariable().getBuiltin()
  78. == BuiltinMaterialVariableId::NONE);
  79. m_copy = value;
  80. }
  81. const T& getValue() const
  82. {
  83. return m_copy;
  84. }
  85. private:
  86. T m_copy; ///< Copy of the data
  87. };
  88. /// Rendering data input and output. This is a structure because we don't want
  89. /// to change what buildRendering accepts all the time
  90. class RenderingBuildInfo
  91. {
  92. public:
  93. RenderingKey m_key;
  94. const U8* m_subMeshIndicesArray; ///< @note indices != drawing indices
  95. U32 m_subMeshIndicesCount;
  96. CommandBufferPtr m_cmdb; ///< A command buffer to append to.
  97. DynamicBufferInfo* m_dynamicBufferInfo ANKI_DBG_NULLIFY_PTR;
  98. };
  99. /// RenderComponent interface. Implemented by renderable scene nodes
  100. class RenderComponent : public SceneComponent
  101. {
  102. public:
  103. using Variables = DArray<RenderComponentVariable*>;
  104. static Bool classof(const SceneComponent& c)
  105. {
  106. return c.getType() == Type::RENDER;
  107. }
  108. RenderComponent(SceneNode* node, const Material* mtl, U64 hash = 0);
  109. ~RenderComponent();
  110. ANKI_USE_RESULT Error create();
  111. Variables::Iterator getVariablesBegin()
  112. {
  113. return m_vars.begin();
  114. }
  115. Variables::Iterator getVariablesEnd()
  116. {
  117. return m_vars.end();
  118. }
  119. Variables::ConstIterator getVariablesBegin() const
  120. {
  121. return m_vars.begin();
  122. }
  123. Variables::ConstIterator getVariablesEnd() const
  124. {
  125. return m_vars.end();
  126. }
  127. /// Build up the rendering.
  128. /// Given an array of submeshes that are visible append jobs to the GL
  129. /// job chain
  130. virtual ANKI_USE_RESULT Error buildRendering(
  131. RenderingBuildInfo& data) const = 0;
  132. /// Access the material
  133. const Material& getMaterial() const
  134. {
  135. ANKI_ASSERT(m_mtl);
  136. return *m_mtl;
  137. }
  138. /// Information for movables. It's actualy an array of transformations.
  139. virtual void getRenderWorldTransform(
  140. Bool& hasWorldTransforms, Transform& trf) const
  141. {
  142. hasWorldTransforms = false;
  143. (void)trf;
  144. }
  145. Bool getCastsShadow() const
  146. {
  147. const Material& mtl = getMaterial();
  148. return mtl.getShadowEnabled();
  149. }
  150. /// Iterate variables using a lambda
  151. template<typename Func>
  152. ANKI_USE_RESULT Error iterateVariables(Func func)
  153. {
  154. Error err = ErrorCode::NONE;
  155. Variables::Iterator it = m_vars.getBegin();
  156. for(; it != m_vars.getEnd() && !err; it++)
  157. {
  158. err = func(*(*it));
  159. }
  160. return err;
  161. }
  162. Bool canMergeDrawcalls(const RenderComponent& b) const
  163. {
  164. return m_mtl->isInstanced() && m_hash != 0 && m_hash == b.m_hash;
  165. }
  166. private:
  167. Variables m_vars;
  168. const Material* m_mtl;
  169. /// If 2 components have the same hash the renderer may potentially try
  170. /// to merge them.
  171. U64 m_hash = 0;
  172. };
  173. /// @}
  174. } // end namespace anki