gfxVertexFormat.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "gfx/gfxVertexFormat.h"
  24. #include "platform/profiler.h"
  25. #include "core/util/hashFunction.h"
  26. #include "gfx/gfxDevice.h"
  27. namespace GFXSemantic
  28. {
  29. const String POSITION = String( "POSITION" ).intern();
  30. const String NORMAL = String( "NORMAL" ).intern();
  31. const String BINORMAL = String( "BINORMAL" ).intern();
  32. const String TANGENT = String( "TANGENT" ).intern();
  33. const String TANGENTW = String( "TANGENTW" ).intern();
  34. const String COLOR = String( "COLOR" ).intern();
  35. const String TEXCOORD = String( "TEXCOORD" ).intern();
  36. const String BLENDINDICES = String( "BLENDINDICES" ).intern();
  37. const String BLENDWEIGHT = String( "BLENDWEIGHT" ).intern();
  38. const String PADDING = String( "PADDING" ).intern();
  39. }
  40. U32 GFXVertexElement::getSizeInBytes() const
  41. {
  42. switch ( mType )
  43. {
  44. case GFXDeclType_Float:
  45. return 4;
  46. case GFXDeclType_Float2:
  47. return 8;
  48. case GFXDeclType_Float3:
  49. return 12;
  50. case GFXDeclType_Float4:
  51. return 16;
  52. case GFXDeclType_Color:
  53. return 4;
  54. case GFXDeclType_UByte4:
  55. return 4;
  56. default:
  57. return 0;
  58. };
  59. }
  60. GFXVertexFormat::GFXVertexFormat()
  61. : mDirty( true ),
  62. mHasNormal( false ),
  63. mHasColor( false ),
  64. mHasTangent( false ),
  65. mHasInstancing( false ),
  66. mTexCoordCount( 0 ),
  67. mSizeInBytes( 0 ),
  68. mDecl( NULL )
  69. {
  70. VECTOR_SET_ASSOCIATION( mElements );
  71. }
  72. void GFXVertexFormat::copy( const GFXVertexFormat &format )
  73. {
  74. mDirty = format.mDirty;
  75. mHasNormal = format.mHasNormal;
  76. mHasTangent = format.mHasTangent;
  77. mHasColor = format.mHasColor;
  78. mHasInstancing = format.mHasInstancing;
  79. mHasBlendIndices = format.mHasBlendIndices;
  80. mTexCoordCount = format.mTexCoordCount;
  81. mSizeInBytes = format.mSizeInBytes;
  82. mDescription = format.mDescription;
  83. mElements = format.mElements;
  84. mDecl = format.mDecl;
  85. }
  86. void GFXVertexFormat::append( const GFXVertexFormat &format, U32 streamIndex )
  87. {
  88. for ( U32 i=0; i < format.getElementCount(); i++ )
  89. {
  90. mElements.increment();
  91. mElements.last() = format.getElement( i );
  92. if ( streamIndex != -1 )
  93. mElements.last().mStreamIndex = streamIndex;
  94. }
  95. mDirty = true;
  96. }
  97. void GFXVertexFormat::clear()
  98. {
  99. mDirty = true;
  100. mElements.clear();
  101. mDecl = NULL;
  102. }
  103. void GFXVertexFormat::addElement( const String& semantic, GFXDeclType type, U32 index, U32 stream )
  104. {
  105. mDirty = true;
  106. mElements.increment();
  107. GFXVertexElement& lastElement = mElements.last();
  108. lastElement.mStreamIndex = stream;
  109. lastElement.mSemantic = semantic.intern();
  110. lastElement.mSemanticIndex = index;
  111. lastElement.mType = type;
  112. }
  113. const String& GFXVertexFormat::getDescription() const
  114. {
  115. if ( mDirty )
  116. const_cast<GFXVertexFormat*>(this)->_updateDirty();
  117. return mDescription;
  118. }
  119. GFXVertexDecl* GFXVertexFormat::getDecl() const
  120. {
  121. if ( !mDecl || mDirty )
  122. const_cast<GFXVertexFormat*>(this)->_updateDecl();
  123. return mDecl;
  124. }
  125. bool GFXVertexFormat::hasNormal() const
  126. {
  127. if ( mDirty )
  128. const_cast<GFXVertexFormat*>(this)->_updateDirty();
  129. return mHasNormal;
  130. }
  131. bool GFXVertexFormat::hasTangent() const
  132. {
  133. if ( mDirty )
  134. const_cast<GFXVertexFormat*>(this)->_updateDirty();
  135. return mHasTangent;
  136. }
  137. bool GFXVertexFormat::hasColor() const
  138. {
  139. if ( mDirty )
  140. const_cast<GFXVertexFormat*>(this)->_updateDirty();
  141. return mHasColor;
  142. }
  143. bool GFXVertexFormat::hasInstancing() const
  144. {
  145. if (mDirty)
  146. const_cast<GFXVertexFormat*>(this)->_updateDirty();
  147. return mHasInstancing;
  148. }
  149. bool GFXVertexFormat::hasBlendIndices() const
  150. {
  151. if ( mDirty )
  152. const_cast<GFXVertexFormat*>(this)->_updateDirty();
  153. return mHasBlendIndices;
  154. }
  155. U32 GFXVertexFormat::getNumBlendIndices() const
  156. {
  157. if ( mDirty )
  158. const_cast<GFXVertexFormat*>(this)->_updateDirty();
  159. if ( !mHasBlendIndices )
  160. return 0;
  161. U32 numIndices = 0;
  162. for ( U32 i=0; i < mElements.size(); i++ )
  163. {
  164. const GFXVertexElement &element = mElements[i];
  165. if ( element.isSemantic( GFXSemantic::BLENDINDICES ) )
  166. numIndices++;
  167. }
  168. return numIndices;
  169. }
  170. U32 GFXVertexFormat::getTexCoordCount() const
  171. {
  172. if ( mDirty )
  173. const_cast<GFXVertexFormat*>(this)->_updateDirty();
  174. return mTexCoordCount;
  175. }
  176. U32 GFXVertexFormat::getSizeInBytes() const
  177. {
  178. if ( mDirty )
  179. const_cast<GFXVertexFormat*>(this)->_updateDirty();
  180. return mSizeInBytes;
  181. }
  182. void GFXVertexFormat::enableInstancing()
  183. {
  184. mHasInstancing = true;
  185. }
  186. void GFXVertexFormat::_updateDirty()
  187. {
  188. PROFILE_SCOPE( GFXVertexFormat_updateDirty );
  189. mTexCoordCount = 0;
  190. mHasColor = false;
  191. mHasBlendIndices = false;
  192. mHasNormal = false;
  193. mHasTangent = false;
  194. mSizeInBytes = 0;
  195. String desc;
  196. for ( U32 i=0; i < mElements.size(); i++ )
  197. {
  198. const GFXVertexElement &element = mElements[i];
  199. desc += String::ToString( "%d,%s,%d,%d\n", element.mStreamIndex,
  200. element.mSemantic.c_str(),
  201. element.mSemanticIndex,
  202. element.mType );
  203. if ( element.isSemantic( GFXSemantic::NORMAL ) )
  204. mHasNormal = true;
  205. else if ( element.isSemantic( GFXSemantic::TANGENT ) )
  206. mHasTangent = true;
  207. else if ( element.isSemantic( GFXSemantic::COLOR ) )
  208. mHasColor = true;
  209. else if ( element.isSemantic( GFXSemantic::TEXCOORD ) )
  210. ++mTexCoordCount;
  211. else if ( element.isSemantic( GFXSemantic::BLENDINDICES ) )
  212. mHasBlendIndices = true;
  213. mSizeInBytes += element.getSizeInBytes();
  214. }
  215. // Intern the string for fast compares later.
  216. mDescription = desc.intern();
  217. mDirty = false;
  218. }
  219. void GFXVertexFormat::_updateDecl()
  220. {
  221. PROFILE_SCOPE( GFXVertexFormat_updateDecl );
  222. if ( mDirty )
  223. _updateDirty();
  224. mDecl = GFX->allocVertexDecl( this );
  225. }