SpriteBatchItem.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 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 _SPRITE_BATCH_ITEM_H_
  23. #define _SPRITE_BATCH_ITEM_H_
  24. #ifndef _IMAGE_FRAME_PROVIDER_H
  25. #include "2d/core/ImageFrameProvider.h"
  26. #endif
  27. //------------------------------------------------------------------------------
  28. class SpriteBatch;
  29. class SceneRenderRequest;
  30. //------------------------------------------------------------------------------
  31. extern StringTableEntry spritesItemTypeName;
  32. //------------------------------------------------------------------------------
  33. class SpriteBatchItem : public ImageFrameProvider
  34. {
  35. friend class SpriteBatch;
  36. typedef ImageFrameProvider Parent;
  37. public:
  38. // Represents a logical position.
  39. struct LogicalPosition : public IFactoryObjectReset
  40. {
  41. const static S32 MAX_ARGUMENTS = 6;
  42. LogicalPosition()
  43. {
  44. resetState();
  45. }
  46. LogicalPosition( const char* pLogicalPositionArgs )
  47. {
  48. // Sanity!
  49. AssertFatal( pLogicalPositionArgs != NULL, "LogicalPosition() - Cannot use NULL position arguments." );
  50. resetState();
  51. // Finish if no position arguments were specified.
  52. if ( dStrlen(pLogicalPositionArgs) == 0 )
  53. return;
  54. // Fetch argument count.
  55. const char* pLogicalPositionSeparator = ",\t ";
  56. mArgCount = (S32)StringUnit::getUnitCount( pLogicalPositionArgs, pLogicalPositionSeparator );
  57. // Do we have a valid argument count?
  58. if ( mArgCount > MAX_ARGUMENTS )
  59. {
  60. // No, so warn.
  61. Con::warnf( "LogicalPosition: Encountered an invalid logical position of '%s'.", pLogicalPositionArgs );
  62. // Set no arguments.
  63. mArgCount = 0;
  64. return;
  65. }
  66. // Set arguments.
  67. for ( S32 index = 0; index < mArgCount; ++index )
  68. {
  69. mArgs[index] = StringUnit::getStringTableUnit( pLogicalPositionArgs, index, pLogicalPositionSeparator );
  70. }
  71. // Set argument string.
  72. mArgString = StringTable->insert( pLogicalPositionArgs );
  73. }
  74. inline bool isValid( void ) const { return mArgCount != 0; }
  75. inline S32 getArgCount( void ) const { return mArgCount; }
  76. inline StringTableEntry getArg( const S32 argIndex ) const
  77. {
  78. // Is the argument index valid?
  79. if ( argIndex < 0 || argIndex > 5 )
  80. {
  81. // No, so warn.
  82. Con::warnf( "LogicalPosition::getArg() - Cannot get a logical position argument; index '%d' out of range.", argIndex );
  83. return StringTable->EmptyString;
  84. }
  85. return mArgs[argIndex];
  86. }
  87. inline Vector2 getAsVector2( void ) const
  88. {
  89. // Do we have enough arguments?
  90. if ( mArgCount != 2 )
  91. {
  92. // No, so warn.
  93. Con::warnf( "LogicalPosition::getAsVector2() - Cannot get a logical position as Vector2; not enough arguments." );
  94. return Vector2::getZero();
  95. }
  96. return Vector2( getFloatArg(0), getFloatArg(1) );
  97. }
  98. inline F32 getFloatArg( const S32 argIndex ) const { return dAtof( getArg(argIndex) ); }
  99. inline S32 getIntArg( const S32 argIndex ) const { return dAtoi( getArg(argIndex) ); }
  100. inline bool getBoolArg( const S32 argIndex ) const { return dAtob( getArg(argIndex) ); }
  101. inline StringTableEntry getString( void ) const { return mArgString; }
  102. virtual void resetState( void )
  103. {
  104. mArgCount = 0;
  105. dMemset( mArgs, 0, sizeof(mArgs) );
  106. mArgString = StringTable->EmptyString;
  107. }
  108. // This should be as unique as possible as it is used for hashing.
  109. operator const U32() const
  110. {
  111. #ifdef TORQUE_64
  112. return (U32)((U64)(mArgString) * (U32)2654435761);
  113. #else
  114. return (U32)(mArgString) * (U32)2654435761;
  115. #endif
  116. }
  117. /// Value equality check for hashing.
  118. bool operator==( const LogicalPosition& logicalPosition ) const
  119. {
  120. // Not equal if argument counts are different.
  121. if ( mArgCount != logicalPosition.getArgCount() )
  122. return false;
  123. // Not equal if arguments are different.
  124. for ( S32 index = 0; index < mArgCount; ++index )
  125. {
  126. if ( mArgs[index] != logicalPosition.getArg(index) )
  127. return false;
  128. }
  129. // Equal.
  130. return true;
  131. }
  132. /// Value inequality check.
  133. bool operator!=( const LogicalPosition& logicalPosition ) const
  134. {
  135. // Not equal if argument counts are different.
  136. if ( mArgCount != logicalPosition.getArgCount() )
  137. return true;
  138. // Not equal if arguments are different.
  139. for ( S32 index = 0; index < mArgCount; ++index )
  140. {
  141. if ( mArgs[index] != logicalPosition.getArg(index) )
  142. return true;
  143. }
  144. // Equal.
  145. return false;
  146. }
  147. private:
  148. S32 mArgCount;
  149. StringTableEntry mArgs[MAX_ARGUMENTS];
  150. StringTableEntry mArgString;
  151. };
  152. protected:
  153. SpriteBatch* mSpriteBatch;
  154. U32 mBatchId;
  155. S32 mProxyId;
  156. StringTableEntry mName;
  157. LogicalPosition mLogicalPosition;
  158. bool mVisible;
  159. bool mExplicitMode;
  160. Vector2 mLocalPosition;
  161. Vector2 mExplicitVerts[4];
  162. F32 mLocalAngle;
  163. Vector2 mSize;
  164. F32 mDepth;
  165. bool mFlipX;
  166. bool mFlipY;
  167. Vector2 mSortPoint;
  168. StringTableEntry mRenderGroup;
  169. bool mBlendMode;
  170. GLenum mSrcBlendFactor;
  171. GLenum mDstBlendFactor;
  172. ColorF mBlendColor;
  173. F32 mAlphaTest;
  174. SimObjectPtr<SimObject> mDataObject;
  175. Vector2 mLocalOOBB[4];
  176. b2AABB mLocalAABB;
  177. bool mLocalTransformDirty;
  178. Vector2 mRenderOOBB[4];
  179. b2AABB mRenderAABB;
  180. Vector2 mRenderPosition;
  181. U32 mLastBatchTransformId;
  182. U32 mSpriteBatchQueryKey;
  183. void* mUserData;
  184. public:
  185. SpriteBatchItem();
  186. virtual ~SpriteBatchItem();
  187. virtual void resetState( void );
  188. inline SpriteBatch* getBatchParent( void ) const { return mSpriteBatch; }
  189. inline U32 getBatchId( void ) const { return mBatchId; }
  190. inline S32 getProxyId( void ) const { return mProxyId; }
  191. inline StringTableEntry getName( void ) const { return mName; }
  192. inline void setLogicalPosition( const LogicalPosition& logicalPosition ) { mLogicalPosition = logicalPosition; }
  193. inline const LogicalPosition& getLogicalPosition( void ) const { return mLogicalPosition; }
  194. inline void setVisible( const bool visible ) { mVisible = visible; }
  195. inline bool getVisible( void ) const { return mVisible; }
  196. inline void setExplicitMode( const bool explicitMode ) { mExplicitMode = explicitMode; }
  197. inline bool getExplicitMode( void ) const { return mExplicitMode; }
  198. inline void setLocalPosition( const Vector2& localPosition ) { mLocalPosition = localPosition; mLocalTransformDirty = true; }
  199. inline Vector2 getLocalPosition( void ) const { return mLocalPosition; }
  200. void setExplicitVertices( const Vector2* explicitVertices );
  201. inline void setLocalAngle( const F32 localAngle ) { mLocalAngle = localAngle; mLocalTransformDirty = true; }
  202. inline F32 getLocalAngle( void ) const { return mLocalAngle; }
  203. inline void setSize( const Vector2& size ) { mSize = size; mLocalTransformDirty = true; }
  204. inline Vector2 getSize( void ) const { return mSize; }
  205. inline const b2AABB& getLocalAABB( void ) { if ( mLocalTransformDirty ) updateLocalTransform(); return mLocalAABB; }
  206. void setDepth( const F32 depth ) { mDepth = depth; }
  207. F32 getDepth( void ) const { return mDepth; }
  208. inline void setFlipX( const bool flipX ) { mFlipX = flipX; }
  209. inline bool getFlipX( void ) const { return mFlipX; }
  210. inline void setFlipY( const bool flipY ) { mFlipY = flipY; }
  211. inline bool getFlipY( void ) const { return mFlipY; }
  212. inline void setSortPoint( const Vector2& sortPoint ) { mSortPoint = sortPoint; }
  213. inline Vector2 getSortPoint( void ) const { return mSortPoint; }
  214. inline void setRenderGroup( const char* pRenderGroup ) { mRenderGroup = StringTable->insert( pRenderGroup ); }
  215. inline StringTableEntry getRenderGroup( void ) const { return mRenderGroup; }
  216. inline void setBlendMode( const bool blendMode ) { mBlendMode = blendMode; }
  217. inline bool getBlendMode( void ) const { return mBlendMode; }
  218. inline void setSrcBlendFactor( GLenum srcBlendFactor ) { mSrcBlendFactor = srcBlendFactor; }
  219. inline GLenum getSrcBlendFactor( void ) const { return mSrcBlendFactor; }
  220. inline void setDstBlendFactor( GLenum dstBlendFactor ) { mDstBlendFactor = dstBlendFactor; }
  221. inline GLenum getDstBlendFactor( void ) const { return mDstBlendFactor; }
  222. inline void setBlendColor( const ColorF& blendColor ) { mBlendColor = blendColor; }
  223. inline const ColorF& getBlendColor( void ) const { return mBlendColor; }
  224. inline void setBlendAlpha( const F32 alpha ) { mBlendColor.alpha = alpha; }
  225. inline F32 getBlendAlpha( void ) const { return mBlendColor.alpha; }
  226. inline void setAlphaTest( const F32 alphaTest ) { mAlphaTest = alphaTest; }
  227. inline F32 getAlphaTest( void ) const { return mAlphaTest; }
  228. inline void setDataObject( SimObject* pDataObject ) { mDataObject = pDataObject; }
  229. inline SimObject* getDataObject( void ) const { return mDataObject; }
  230. inline void setUserData( void* pUserData ) { mUserData = pUserData; }
  231. inline void* getUserData( void ) const { return mUserData; }
  232. template<class T> T* getUserData( void ) const { return (T*)mUserData; }
  233. inline void setSpriteBatchQueryKey( const U32 key ) { mSpriteBatchQueryKey = key; }
  234. inline U32 getSpriteBatchQueryKey( void ) const { return mSpriteBatchQueryKey; }
  235. virtual void copyTo( SpriteBatchItem* pSpriteBatchItem ) const;
  236. inline const Vector2* getLocalOOBB( void ) const { return mLocalOOBB; }
  237. inline const Vector2* getRenderOOBB( void ) const { return mRenderOOBB; }
  238. void prepareRender( SceneRenderRequest* pSceneRenderRequest, const U32 batchTransformId );
  239. void render( BatchRender* pBatchRenderer, const SceneRenderRequest* pSceneRenderRequest, const U32 batchTransformId );
  240. static void WriteCustomTamlSchema( const AbstractClassRep* pClassRep, TiXmlElement* pParentElement );
  241. protected:
  242. void setBatchParent( SpriteBatch* pSpriteBatch, const U32 batchId );
  243. inline void setProxyId( const S32 proxyId ) { mProxyId = proxyId; }
  244. inline void setName( const char* pName ) { mName = StringTable->insert( pName ); }
  245. void updateLocalTransform( void );
  246. void updateWorldTransform( const U32 batchTransformId );
  247. void onTamlCustomWrite( TamlCustomNode* pParentNode );
  248. void onTamlCustomRead( const TamlCustomNode* pSpriteNode );
  249. };
  250. //------------------------------------------------------------------------------
  251. static FactoryCache<SpriteBatchItem> SpriteBatchItemFactory;
  252. #endif // _SPRITE_BATCH_ITEM_H_