gfxVertexFormat.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  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. #ifndef _GFXVERTEXFORMAT_H_
  23. #define _GFXVERTEXFORMAT_H_
  24. #ifndef _TVECTOR_H_
  25. #include "core/util/tVector.h"
  26. #endif
  27. #ifndef _GFXENUMS_H_
  28. #include "gfx/gfxEnums.h"
  29. #endif
  30. /// The known Torque vertex element semantics. You can use
  31. /// other semantic strings, but they will be interpreted as
  32. /// a TEXCOORD.
  33. /// @see GFXVertexElement
  34. /// @see GFXVertexFormat
  35. namespace GFXSemantic
  36. {
  37. extern const String POSITION;
  38. extern const String NORMAL;
  39. extern const String BINORMAL;
  40. extern const String TANGENT;
  41. extern const String TANGENTW;
  42. extern const String COLOR;
  43. extern const String TEXCOORD;
  44. extern const String BLENDWEIGHT;
  45. extern const String BLENDINDICES;
  46. extern const String PADDING;
  47. }
  48. /// This is a simple wrapper for the platform specific
  49. /// vertex declaration data which is held by the vertex
  50. /// format.
  51. ///
  52. /// If your using it... you probably shouldn't be.
  53. ///
  54. /// @see GFXVertexFormat
  55. class GFXVertexDecl
  56. {
  57. public:
  58. virtual ~GFXVertexDecl() {}
  59. };
  60. /// The element structure helps define the data layout
  61. /// for GFXVertexFormat.
  62. ///
  63. /// @see GFXVertexFormat
  64. ///
  65. class GFXVertexElement
  66. {
  67. friend class GFXVertexFormat;
  68. protected:
  69. /// The stream index when rendering from multiple
  70. /// vertex streams. In most cases this is 0.
  71. U32 mStreamIndex;
  72. /// A valid Torque shader symantic.
  73. /// @see GFXSemantic
  74. String mSemantic;
  75. /// The semantic index is used where there are
  76. /// multiple semantics of the same type. For
  77. /// instance with texcoords.
  78. U32 mSemanticIndex;
  79. /// The element type.
  80. GFXDeclType mType;
  81. public:
  82. /// Default constructor.
  83. GFXVertexElement()
  84. : mStreamIndex( 0 ),
  85. mSemanticIndex( 0 ),
  86. mType( GFXDeclType_Float4 )
  87. {
  88. }
  89. /// Copy constructor.
  90. GFXVertexElement( const GFXVertexElement &elem )
  91. : mStreamIndex( elem.mStreamIndex ),
  92. mSemantic( elem.mSemantic ),
  93. mSemanticIndex( elem.mSemanticIndex ),
  94. mType( elem.mType )
  95. {
  96. }
  97. /// Returns the stream index.
  98. U32 getStreamIndex() const { return mStreamIndex; }
  99. /// Returns the semantic name which is usually a
  100. /// valid Torque semantic.
  101. /// @see GFXSemantic
  102. const String& getSemantic() const { return mSemantic; }
  103. /// Returns the semantic index which is used where there
  104. /// are multiple semantics of the same type. For instance
  105. /// with texcoords.
  106. U32 getSemanticIndex() const { return mSemanticIndex; }
  107. /// Returns the type for the semantic.
  108. GFXDeclType getType() const { return mType; }
  109. /// Returns true of the semantic matches.
  110. bool isSemantic( const String& str ) const { return ( mSemantic == str ); }
  111. /// Returns the size in bytes of the semantic type.
  112. U32 getSizeInBytes() const;
  113. };
  114. /// The vertex format structure usually created via the declare and
  115. /// implement macros.
  116. ///
  117. /// You can use this class directly to create a vertex format, but
  118. /// note that it is expected to live as long as the VB that uses it
  119. /// exists.
  120. ///
  121. /// @see GFXDeclareVertexFormat
  122. /// @see GFXImplementVertexFormat
  123. /// @see GFXVertexElement
  124. ///
  125. class GFXVertexFormat
  126. {
  127. public:
  128. /// Default constructor for an empty format.
  129. GFXVertexFormat();
  130. /// The copy constructor.
  131. GFXVertexFormat( const GFXVertexFormat &format ) { copy( format ); }
  132. /// Tell this format it has instancing
  133. void enableInstancing();
  134. /// Copy the other vertex format.
  135. void copy( const GFXVertexFormat &format );
  136. /// Used to append a vertex format to the end of this one.
  137. void append( const GFXVertexFormat &format, U32 streamIndex = -1 );
  138. /// Returns a unique description string for this vertex format.
  139. const String& getDescription() const;
  140. /// Clears all the vertex elements.
  141. void clear();
  142. /// Adds a vertex element to the format.
  143. ///
  144. /// @param semantic A valid Torque semantic string.
  145. /// @param type The element type.
  146. /// @param index The semantic index which is typically only used for texcoords.
  147. ///
  148. void addElement( const String& semantic, GFXDeclType type, U32 index = 0, U32 stream = 0 );
  149. /// Returns true if there is a NORMAL semantic in this vertex format.
  150. bool hasNormal() const;
  151. /// Returns true if there is a TANGENT semantic in this vertex format.
  152. bool hasTangent() const;
  153. /// Returns true if there is a COLOR semantic in this vertex format.
  154. bool hasColor() const;
  155. /// Returns true if there is a BLENDWEIGHT or BLENDINDICES semantic in this vertex format.
  156. bool hasBlendIndices() const;
  157. /// Return true if instancing is used with this vertex format.
  158. bool hasInstancing() const;
  159. /// Returns number of blend indices
  160. U32 getNumBlendIndices() const;
  161. /// Returns the texture coordinate count by
  162. /// counting the number of TEXCOORD semantics.
  163. U32 getTexCoordCount() const;
  164. /// Returns true if these two formats are equal.
  165. inline bool isEqual( const GFXVertexFormat &format ) const;
  166. /// Returns the total elements in this format.
  167. U32 getElementCount() const { return mElements.size(); }
  168. /// Returns the vertex element by index.
  169. const GFXVertexElement& getElement( U32 index ) const { return mElements[index]; }
  170. /// Returns the size in bytes of the format as described.
  171. U32 getSizeInBytes() const;
  172. /// Returns the hardware specific vertex declaration for this format.
  173. GFXVertexDecl* getDecl() const;
  174. protected:
  175. /// We disable the copy operator.
  176. GFXVertexFormat& operator =( const GFXVertexFormat& ) { return *this; }
  177. /// Recreates the description and state when
  178. /// the format has been modified.
  179. void _updateDirty();
  180. /// Requests the vertex declaration from the GFX device.
  181. void _updateDecl();
  182. /// Set when the element list is changed.
  183. bool mDirty;
  184. /// Is set if there is a NORMAL semantic in this vertex format.
  185. bool mHasNormal;
  186. /// Is true if there is a TANGENT semantic in this vertex format.
  187. bool mHasTangent;
  188. /// Is true if there is a COLOR semantic in this vertex format.
  189. bool mHasColor;
  190. /// Is true if there is a BLENDWEIGHT or BLENDINDICES semantic in this vertex format.
  191. bool mHasBlendIndices;
  192. /// Is instaning used with this vertex format.
  193. bool mHasInstancing;
  194. /// The texture coordinate count by counting the
  195. /// number of "TEXCOORD" semantics.
  196. U32 mTexCoordCount;
  197. /// The size in bytes of the vertex format as described.
  198. U32 mSizeInBytes;
  199. /// An interned string which uniquely identifies the format.
  200. String mDescription;
  201. /// The elements of the vertex format.
  202. Vector<GFXVertexElement> mElements;
  203. /// The hardware specific vertex declaration.
  204. GFXVertexDecl *mDecl;
  205. };
  206. inline bool GFXVertexFormat::isEqual( const GFXVertexFormat &format ) const
  207. {
  208. // Comparing the strings works because we know both
  209. // these are interned strings. This saves one comparison
  210. // over the string equality operator.
  211. return getDescription().c_str() == format.getDescription().c_str();
  212. }
  213. /// This template class is usused to initialize the format in
  214. /// the GFXImplement/DeclareVertexFormat macros. You shouldn't
  215. /// need to use it directly in your code.
  216. ///
  217. /// @see GFXVertexFormat
  218. /// @see GFXImplementVertexFormat
  219. ///
  220. template<class T>
  221. class _GFXVertexFormatConstructor : public GFXVertexFormat
  222. {
  223. protected:
  224. void _construct();
  225. public:
  226. _GFXVertexFormatConstructor() { _construct(); }
  227. };
  228. /// Helper template function which returns the correct
  229. /// GFXVertexFormat object for a vertex structure.
  230. /// @see GFXVertexFormat
  231. template<class T> inline const GFXVertexFormat* getGFXVertexFormat();
  232. #define GFX_VERTEX_STRUCT struct
  233. /// The vertex format declaration which is usally placed in your header
  234. /// file. It should be used in conjunction with the implementation macro.
  235. ///
  236. /// @param name The name for the vertex structure.
  237. ///
  238. /// @code
  239. ///
  240. /// // A simple vertex format declaration.
  241. /// GFXDeclareVertexFormat( GFXVertexPCT )
  242. /// {
  243. /// Point3F pos;
  244. /// GFXVertexColor color;
  245. /// Point2F texCoord;
  246. /// }
  247. ///
  248. /// @endcode
  249. ///
  250. /// @see GFXImplementVertexFormat
  251. ///
  252. #define GFXDeclareVertexFormat( name ) \
  253. GFX_VERTEX_STRUCT name; \
  254. extern const GFXVertexFormat _gfxVertexFormat##name; \
  255. template<> inline const GFXVertexFormat* getGFXVertexFormat<name>() { static _GFXVertexFormatConstructor<name> vertexFormat; return &vertexFormat; } \
  256. GFX_VERTEX_STRUCT name \
  257. /// The vertex format implementation which is usally placed in your source
  258. /// file. It should be used in conjunction with the declaration macro.
  259. ///
  260. /// @param name The name of the vertex structure.
  261. ///
  262. /// @code
  263. ///
  264. /// // A simple vertex format implementation.
  265. /// GFXImplementVertexFormat( GFXVertexPCT )
  266. /// {
  267. /// addElement( "POSITION", GFXDeclType_Float3 );
  268. /// addElement( "COLOR", GFXDeclType_Color );
  269. /// addElement( "TEXCOORD", GFXDeclType_Float2, 0 );
  270. /// }
  271. ///
  272. /// @endcode
  273. ///
  274. /// @see GFXDeclareVertexFormat
  275. ///
  276. #define GFXImplementVertexFormat( name ) \
  277. template<> void _GFXVertexFormatConstructor<name>::_construct() \
  278. #endif // _GFXVERTEXFORMAT_H_