gfxVertexBuffer.h 8.5 KB

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