gfxVertexBuffer.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  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 _GFXVERTEXBUFFER_H_
  23. #define _GFXVERTEXBUFFER_H_
  24. #ifndef _GFXSTRUCTS_H_
  25. #include "gfx/gfxStructs.h"
  26. #endif
  27. //*****************************************************************************
  28. // GFXVertexBuffer - base vertex buffer class
  29. //*****************************************************************************
  30. class GFXVertexBuffer : public StrongRefBase, public GFXResource
  31. {
  32. friend class GFXVertexBufferHandleBase;
  33. friend class GFXDevice;
  34. public:
  35. /// Number of vertices in this buffer.
  36. U32 mNumVerts;
  37. /// A copy of the vertex format for this buffer.
  38. GFXVertexFormat mVertexFormat;
  39. /// Vertex size in bytes.
  40. U32 mVertexSize;
  41. /// GFX buffer type (static, dynamic or volatile).
  42. GFXBufferType mBufferType;
  43. /// Device this vertex buffer was allocated on.
  44. GFXDevice *mDevice;
  45. bool isLocked;
  46. U32 lockedVertexStart;
  47. U32 lockedVertexEnd;
  48. void* lockedVertexPtr;
  49. U32 mVolatileStart;
  50. GFXVertexBuffer( GFXDevice *device,
  51. U32 numVerts,
  52. const GFXVertexFormat *vertexFormat,
  53. U32 vertexSize,
  54. GFXBufferType bufferType )
  55. : mNumVerts( numVerts ),
  56. mVertexSize( vertexSize ),
  57. mBufferType( bufferType ),
  58. mDevice( device ),
  59. isLocked(false),
  60. lockedVertexStart(0),
  61. lockedVertexEnd(0),
  62. lockedVertexPtr(NULL),
  63. mVolatileStart( 0 )
  64. {
  65. if ( vertexFormat )
  66. {
  67. vertexFormat->getDecl();
  68. mVertexFormat.copy( *vertexFormat );
  69. }
  70. }
  71. virtual void lock(U32 vertexStart, U32 vertexEnd, void **vertexPtr) = 0;
  72. virtual void unlock() = 0;
  73. virtual void prepare() = 0;
  74. // GFXResource
  75. virtual const String describeSelf() const;
  76. };
  77. //*****************************************************************************
  78. // GFXVertexBufferHandleBase
  79. //*****************************************************************************
  80. class GFXVertexBufferHandleBase : public StrongRefPtr<GFXVertexBuffer>
  81. {
  82. friend class GFXDevice;
  83. protected:
  84. void set( GFXDevice *theDevice,
  85. U32 numVerts,
  86. const GFXVertexFormat *vertexFormat,
  87. U32 vertexSize,
  88. GFXBufferType type );
  89. void* lock(U32 vertexStart, U32 vertexEnd)
  90. {
  91. if(vertexEnd == 0)
  92. vertexEnd = getPointer()->mNumVerts;
  93. AssertFatal(vertexEnd > vertexStart, "Can't get a lock with the end before the start.");
  94. AssertFatal(vertexEnd <= getPointer()->mNumVerts || getPointer()->mBufferType == GFXBufferTypeVolatile, "Tried to get vertices beyond the end of the buffer!");
  95. getPointer()->lock(vertexStart, vertexEnd, &getPointer()->lockedVertexPtr);
  96. return getPointer()->lockedVertexPtr;
  97. }
  98. void unlock() ///< unlocks the vertex data, making changes illegal.
  99. {
  100. getPointer()->unlock();
  101. }
  102. };
  103. /// A handle object for allocating, filling, and reading a vertex buffer.
  104. template<class T>
  105. class GFXVertexBufferHandle : public GFXVertexBufferHandleBase
  106. {
  107. typedef GFXVertexBufferHandleBase Parent;
  108. /// Sets this vertex buffer as the current
  109. /// vertex buffer for the device it was allocated on
  110. void prepare() { getPointer()->prepare(); }
  111. public:
  112. GFXVertexBufferHandle() {}
  113. GFXVertexBufferHandle( GFXDevice *theDevice,
  114. U32 numVerts,
  115. GFXBufferType type = GFXBufferTypeVolatile )
  116. {
  117. set( theDevice, numVerts, type );
  118. }
  119. ~GFXVertexBufferHandle() {}
  120. void set( GFXDevice *theDevice,
  121. U32 numVerts,
  122. GFXBufferType type = GFXBufferTypeVolatile )
  123. {
  124. Parent::set( theDevice, numVerts, getGFXVertexFormat<T>(), sizeof(T), type );
  125. }
  126. T *lock(U32 vertexStart = 0, U32 vertexEnd = 0) ///< locks the vertex buffer range, and returns a pointer to the beginning of the vertex array
  127. ///< also allows the array operators to work on this vertex buffer.
  128. {
  129. return (T*)Parent::lock(vertexStart, vertexEnd);
  130. }
  131. void unlock() { Parent::unlock(); }
  132. T& operator[](U32 index) ///< Array operator allows indexing into a locked vertex buffer. The debug version of the code
  133. ///< will range check the array access as well as validate the locked vertex buffer pointer.
  134. {
  135. return ((T*)getPointer()->lockedVertexPtr)[index];
  136. }
  137. const T& operator[](U32 index) const ///< Array operator allows indexing into a locked vertex buffer. The debug version of the code
  138. ///< will range check the array access as well as validate the locked vertex buffer pointer.
  139. {
  140. index += getPointer()->mVolatileStart;
  141. AssertFatal(getPointer()->lockedVertexPtr != NULL, "Cannot access verts from an unlocked vertex buffer!!!");
  142. AssertFatal(index >= getPointer()->lockedVertexStart && index < getPointer()->lockedVertexEnd, "Out of range vertex access!");
  143. index -= getPointer()->mVolatileStart;
  144. return ((T*)getPointer()->lockedVertexPtr)[index];
  145. }
  146. T& operator[](S32 index) ///< Array operator allows indexing into a locked vertex buffer. The debug version of the code
  147. ///< will range check the array access as well as validate the locked vertex buffer pointer.
  148. {
  149. index += getPointer()->mVolatileStart;
  150. AssertFatal(getPointer()->lockedVertexPtr != NULL, "Cannot access verts from an unlocked vertex buffer!!!");
  151. AssertFatal(index >= getPointer()->lockedVertexStart && index < getPointer()->lockedVertexEnd, "Out of range vertex access!");
  152. index -= getPointer()->mVolatileStart;
  153. return ((T*)getPointer()->lockedVertexPtr)[index];
  154. }
  155. const T& operator[](S32 index) const ///< Array operator allows indexing into a locked vertex buffer. The debug version of the code
  156. ///< will range check the array access as well as validate the locked vertex buffer pointer.
  157. {
  158. index += getPointer()->mVolatileStart;
  159. AssertFatal(getPointer()->lockedVertexPtr != NULL, "Cannot access verts from an unlocked vertex buffer!!!");
  160. AssertFatal(index >= getPointer()->lockedVertexStart && index < getPointer()->lockedVertexEnd, "Out of range vertex access!");
  161. index -= getPointer()->mVolatileStart;
  162. return ((T*)getPointer()->lockedVertexPtr)[index];
  163. }
  164. GFXVertexBufferHandle<T>& operator=(GFXVertexBuffer *ptr)
  165. {
  166. StrongObjectRef::set(ptr);
  167. return *this;
  168. }
  169. };
  170. /// This is a non-typed vertex buffer handle which can be
  171. /// used when your vertex type is undefined until runtime.
  172. class GFXVertexBufferDataHandle : public GFXVertexBufferHandleBase
  173. {
  174. typedef GFXVertexBufferHandleBase Parent;
  175. protected:
  176. void prepare() { getPointer()->prepare(); }
  177. public:
  178. GFXVertexBufferDataHandle()
  179. {
  180. }
  181. void set( GFXDevice *theDevice,
  182. U32 vertSize,
  183. const GFXVertexFormat *vertexFormat,
  184. U32 numVerts,
  185. GFXBufferType type )
  186. {
  187. Parent::set( theDevice, numVerts, vertexFormat, vertSize, type );
  188. }
  189. U8* lock( U32 vertexStart = 0, U32 vertexEnd = 0 )
  190. {
  191. return (U8*)Parent::lock( vertexStart, vertexEnd );
  192. }
  193. void unlock() { Parent::unlock(); }
  194. GFXVertexBufferDataHandle& operator=( GFXVertexBuffer *ptr )
  195. {
  196. StrongObjectRef::set(ptr);
  197. return *this;
  198. }
  199. };
  200. #endif // _GFXVERTEXBUFFER_H_