SMaterialLayer.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #ifndef S_MATERIAL_LAYER_H_INCLUDED
  5. #define S_MATERIAL_LAYER_H_INCLUDED
  6. #include "matrix4.h"
  7. #include "irrAllocator.h"
  8. namespace irr
  9. {
  10. namespace video
  11. {
  12. class ITexture;
  13. //! Texture coord clamp mode outside [0.0, 1.0]
  14. enum E_TEXTURE_CLAMP
  15. {
  16. //! Texture repeats
  17. ETC_REPEAT = 0,
  18. //! Texture is clamped to the last pixel
  19. ETC_CLAMP,
  20. //! Texture is clamped to the edge pixel
  21. ETC_CLAMP_TO_EDGE,
  22. //! Texture is clamped to the border pixel (if exists)
  23. ETC_CLAMP_TO_BORDER,
  24. //! Texture is alternatingly mirrored (0..1..0..1..0..)
  25. ETC_MIRROR,
  26. //! Texture is mirrored once and then clamped (0..1..0)
  27. ETC_MIRROR_CLAMP,
  28. //! Texture is mirrored once and then clamped to edge
  29. ETC_MIRROR_CLAMP_TO_EDGE,
  30. //! Texture is mirrored once and then clamped to border
  31. ETC_MIRROR_CLAMP_TO_BORDER
  32. };
  33. static const char* const aTextureClampNames[] = {
  34. "texture_clamp_repeat",
  35. "texture_clamp_clamp",
  36. "texture_clamp_clamp_to_edge",
  37. "texture_clamp_clamp_to_border",
  38. "texture_clamp_mirror",
  39. "texture_clamp_mirror_clamp",
  40. "texture_clamp_mirror_clamp_to_edge",
  41. "texture_clamp_mirror_clamp_to_border", 0};
  42. //! Struct for holding material parameters which exist per texture layer
  43. // Note for implementers: Serialization is in CNullDriver
  44. class SMaterialLayer
  45. {
  46. public:
  47. //! Default constructor
  48. SMaterialLayer() : Texture(0), TextureWrapU(ETC_REPEAT), TextureWrapV(ETC_REPEAT), TextureWrapW(ETC_REPEAT),
  49. BilinearFilter(true), TrilinearFilter(false), AnisotropicFilter(0), LODBias(0),
  50. TextureMatrix(0), TextureMatrixUsed(false)
  51. {
  52. }
  53. //! Copy constructor
  54. /** \param other Material layer to copy from. */
  55. SMaterialLayer(const SMaterialLayer& other)
  56. {
  57. // This pointer is checked during assignment
  58. TextureMatrix = 0;
  59. *this = other;
  60. }
  61. //! Destructor
  62. ~SMaterialLayer()
  63. {
  64. if ( TextureMatrix )
  65. {
  66. MatrixAllocator.destruct(TextureMatrix);
  67. MatrixAllocator.deallocate(TextureMatrix);
  68. }
  69. }
  70. //! Assignment operator
  71. /** \param other Material layer to copy from.
  72. \return This material layer, updated. */
  73. SMaterialLayer& operator=(const SMaterialLayer& other)
  74. {
  75. // Check for self-assignment!
  76. if (this == &other)
  77. return *this;
  78. Texture = other.Texture;
  79. if (other.TextureMatrixUsed)
  80. {
  81. if (TextureMatrix)
  82. {
  83. *TextureMatrix = *other.TextureMatrix;
  84. }
  85. else
  86. {
  87. TextureMatrix = MatrixAllocator.allocate(1);
  88. MatrixAllocator.construct(TextureMatrix,*other.TextureMatrix);
  89. }
  90. TextureMatrixUsed = true;
  91. }
  92. else
  93. {
  94. TextureMatrixUsed = false;
  95. }
  96. TextureWrapU = other.TextureWrapU;
  97. TextureWrapV = other.TextureWrapV;
  98. TextureWrapW = other.TextureWrapW;
  99. BilinearFilter = other.BilinearFilter;
  100. TrilinearFilter = other.TrilinearFilter;
  101. AnisotropicFilter = other.AnisotropicFilter;
  102. LODBias = other.LODBias;
  103. return *this;
  104. }
  105. //! Gets the texture transformation matrix
  106. /** \return Texture matrix of this layer. */
  107. core::matrix4& getTextureMatrix()
  108. {
  109. if (!TextureMatrix)
  110. {
  111. TextureMatrix = MatrixAllocator.allocate(1);
  112. MatrixAllocator.construct(TextureMatrix,core::IdentityMatrix);
  113. TextureMatrixUsed = true;
  114. }
  115. else if ( !TextureMatrixUsed )
  116. {
  117. *TextureMatrix = core::IdentityMatrix;
  118. TextureMatrixUsed = true;
  119. }
  120. return *TextureMatrix;
  121. }
  122. //! Gets the immutable texture transformation matrix
  123. /** \return Texture matrix of this layer. */
  124. const core::matrix4& getTextureMatrix() const
  125. {
  126. if (TextureMatrixUsed)
  127. return *TextureMatrix;
  128. else
  129. return core::IdentityMatrix;
  130. }
  131. //! Sets the texture transformation matrix to mat
  132. /** NOTE: Pipelines can ignore this matrix when the
  133. texture is 0.
  134. \param mat New texture matrix for this layer. */
  135. void setTextureMatrix(const core::matrix4& mat)
  136. {
  137. if (!TextureMatrix)
  138. {
  139. TextureMatrix = MatrixAllocator.allocate(1);
  140. MatrixAllocator.construct(TextureMatrix,mat);
  141. }
  142. else
  143. *TextureMatrix = mat;
  144. TextureMatrixUsed = true;
  145. }
  146. //! Check if we have set a custom texture matrix
  147. //! Note that otherwise we get an IdentityMatrix as default
  148. inline bool hasSetTextureMatrix() const
  149. {
  150. return TextureMatrixUsed;
  151. }
  152. //! Reset texture matrix to identity matrix
  153. /** \param releaseMemory Releases also texture memory. Otherwise done in destructor */
  154. void resetTextureMatrix(bool releaseMemory=true)
  155. {
  156. if ( TextureMatrix && releaseMemory)
  157. {
  158. MatrixAllocator.destruct(TextureMatrix);
  159. MatrixAllocator.deallocate(TextureMatrix);
  160. TextureMatrix = 0;
  161. }
  162. TextureMatrixUsed = false;
  163. }
  164. //! Inequality operator
  165. /** \param b Layer to compare to.
  166. \return True if layers are different, else false. */
  167. inline bool operator!=(const SMaterialLayer& b) const
  168. {
  169. bool different =
  170. Texture != b.Texture ||
  171. TextureWrapU != b.TextureWrapU ||
  172. TextureWrapV != b.TextureWrapV ||
  173. TextureWrapW != b.TextureWrapW ||
  174. BilinearFilter != b.BilinearFilter ||
  175. TrilinearFilter != b.TrilinearFilter ||
  176. AnisotropicFilter != b.AnisotropicFilter ||
  177. LODBias != b.LODBias;
  178. if (different)
  179. return true;
  180. else
  181. {
  182. different = (TextureMatrixUsed && b.TextureMatrixUsed && (*TextureMatrix != *b.TextureMatrix))
  183. || (TextureMatrixUsed && !b.TextureMatrixUsed && (*TextureMatrix != core::IdentityMatrix))
  184. || (!TextureMatrixUsed && b.TextureMatrixUsed && (core::IdentityMatrix != *b.TextureMatrix));
  185. }
  186. return different;
  187. }
  188. //! Equality operator
  189. /** \param b Layer to compare to.
  190. \return True if layers are equal, else false. */
  191. inline bool operator==(const SMaterialLayer& b) const
  192. { return !(b!=*this); }
  193. //! Texture
  194. ITexture* Texture;
  195. //! Texture Clamp Mode
  196. /** Values are taken from E_TEXTURE_CLAMP. */
  197. u8 TextureWrapU:4;
  198. u8 TextureWrapV:4;
  199. u8 TextureWrapW:4;
  200. //! Is bilinear filtering enabled? Default: true
  201. bool BilinearFilter:1;
  202. //! Is trilinear filtering enabled? Default: false
  203. /** If the trilinear filter flag is enabled,
  204. the bilinear filtering flag is ignored. */
  205. bool TrilinearFilter:1;
  206. //! Is anisotropic filtering enabled? Default: 0, disabled
  207. /** In Irrlicht you can use anisotropic texture filtering
  208. in conjunction with bilinear or trilinear texture
  209. filtering to improve rendering results. Primitives
  210. will look less blurry with this flag switched on. The number gives
  211. the maximal anisotropy degree, and is often in the range 2-16.
  212. Value 1 is equivalent to 0, but should be avoided. */
  213. u8 AnisotropicFilter;
  214. //! Bias for the mipmap choosing decision.
  215. /** This value can make the textures more or less blurry than with the
  216. default value of 0. The value (divided by 8.f) is added to the mipmap level
  217. chosen initially, and thus takes a smaller mipmap for a region
  218. if the value is positive. */
  219. s8 LODBias;
  220. private:
  221. friend class SMaterial;
  222. irr::core::irrAllocator<irr::core::matrix4> MatrixAllocator;
  223. //! Texture Matrix
  224. /** Do not access this element directly as the internal
  225. resource management has to cope with Null pointers etc. */
  226. core::matrix4* TextureMatrix;
  227. bool TextureMatrixUsed; // TextureMatrix memory stays until destructor even when unused to avoid unnecessary allocation/de-allocations
  228. };
  229. } // end namespace video
  230. } // end namespace irr
  231. #endif // S_MATERIAL_LAYER_H_INCLUDED