primBuilder.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  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 "primBuilder.h"
  23. #include "gfxDevice.h"
  24. #include "console/console.h"
  25. //*****************************************************************************
  26. // Primitive Builder
  27. //*****************************************************************************
  28. namespace PrimBuild
  29. {
  30. Vector<GFXVertexPCT> mTempVertBuff;
  31. GFXVertexBufferHandle<GFXVertexPCT> mVertBuff;
  32. GFXPrimitiveType mType;
  33. U32 mCurVertIndex;
  34. ColorI mCurColor( 255, 255, 255 );
  35. Point2F mCurTexCoord;
  36. const ColorI _colWhite( 255, 255, 255, 255 );
  37. #ifdef TORQUE_DEBUG
  38. U32 mMaxVerts;
  39. #define INIT_VERTEX_SIZE(x) mMaxVerts = x;
  40. #define VERTEX_BOUNDS_CHECK() AssertFatal( mCurVertIndex < mMaxVerts, "PrimBuilder encountered an out of bounds vertex! Break and debug!" );
  41. // This next check shouldn't really be used a lot unless you are tracking down
  42. // a specific bug. -pw
  43. #define VERTEX_SIZE_CHECK() AssertFatal( mCurVertIndex <= mMaxVerts, "PrimBuilder allocated more verts than you used! Break and debug or rendering artifacts could occur." );
  44. #else
  45. #define INIT_VERTEX_SIZE(x)
  46. #define VERTEX_BOUNDS_CHECK()
  47. #define VERTEX_SIZE_CHECK()
  48. #endif
  49. //-----------------------------------------------------------------------------
  50. // begin
  51. //-----------------------------------------------------------------------------
  52. void begin( GFXPrimitiveType type, U32 maxVerts )
  53. {
  54. AssertFatal( type >= GFXPT_FIRST && type < GFXPT_COUNT, "PrimBuilder::end() - Bad primitive type!" );
  55. mType = type;
  56. mCurVertIndex = 0;
  57. INIT_VERTEX_SIZE( maxVerts );
  58. mTempVertBuff.setSize( maxVerts );
  59. }
  60. void beginToBuffer( GFXPrimitiveType type, U32 maxVerts )
  61. {
  62. AssertFatal( type >= GFXPT_FIRST && type < GFXPT_COUNT, "PrimBuilder::end() - Bad primitive type!" );
  63. mType = type;
  64. mCurVertIndex = 0;
  65. INIT_VERTEX_SIZE( maxVerts );
  66. mTempVertBuff.setSize( maxVerts );
  67. }
  68. //-----------------------------------------------------------------------------
  69. // end
  70. //-----------------------------------------------------------------------------
  71. GFXVertexBuffer * endToBuffer( U32 &numPrims )
  72. {
  73. mVertBuff.set(GFX, mTempVertBuff.size(), GFXBufferTypeVolatile);
  74. GFXVertexPCT *verts = mVertBuff.lock();
  75. dMemcpy( verts, mTempVertBuff.address(), mTempVertBuff.size() * sizeof(GFXVertexPCT) );
  76. mVertBuff.unlock();
  77. VERTEX_SIZE_CHECK();
  78. switch( mType )
  79. {
  80. case GFXPointList:
  81. {
  82. numPrims = mCurVertIndex;
  83. break;
  84. }
  85. case GFXLineList:
  86. {
  87. numPrims = mCurVertIndex / 2;
  88. break;
  89. }
  90. case GFXLineStrip:
  91. {
  92. numPrims = mCurVertIndex - 1;
  93. break;
  94. }
  95. case GFXTriangleList:
  96. {
  97. numPrims = mCurVertIndex / 3;
  98. break;
  99. }
  100. case GFXTriangleStrip:
  101. case GFXTriangleFan:
  102. {
  103. numPrims = mCurVertIndex - 2;
  104. break;
  105. }
  106. case GFXPT_COUNT:
  107. // handle warning
  108. break;
  109. }
  110. return mVertBuff;
  111. }
  112. void end( bool useGenericShaders )
  113. {
  114. if ( mCurVertIndex == 0 )
  115. return;
  116. VERTEX_SIZE_CHECK();
  117. U32 vertStride = 1;
  118. U32 stripStart = 0;
  119. AssertFatal( mType >= GFXPT_FIRST && mType < GFXPT_COUNT, "PrimBuilder::end() - Bad primitive type!" );
  120. switch( mType )
  121. {
  122. default:
  123. case GFXPointList:
  124. {
  125. vertStride = 1;
  126. break;
  127. }
  128. case GFXLineList:
  129. {
  130. vertStride = 2;
  131. break;
  132. }
  133. case GFXTriangleList:
  134. {
  135. vertStride = 3;
  136. break;
  137. }
  138. case GFXLineStrip:
  139. {
  140. stripStart = 1;
  141. vertStride = 1;
  142. break;
  143. }
  144. case GFXTriangleStrip:
  145. case GFXTriangleFan:
  146. {
  147. stripStart = 2;
  148. vertStride = 1;
  149. break;
  150. }
  151. }
  152. if ( useGenericShaders )
  153. {
  154. GFXStateBlock *currentBlock = GFX->getStateBlock();
  155. if (currentBlock && currentBlock->getDesc().samplersDefined)
  156. {
  157. if (currentBlock->getDesc().vertexColorEnable)
  158. GFX->setupGenericShaders( GFXDevice::GSModColorTexture );
  159. else
  160. GFX->setupGenericShaders( GFXDevice::GSTexture );
  161. }
  162. else
  163. GFX->setupGenericShaders( GFXDevice::GSColor );
  164. }
  165. const GFXVertexPCT *srcVerts = mTempVertBuff.address();
  166. U32 numVerts = mCurVertIndex;
  167. // Make sure we don't have a dirty prim buffer left.
  168. GFX->setPrimitiveBuffer( NULL );
  169. if ( stripStart > 0 )
  170. {
  171. // TODO: Fix this to allow > MAX_DYNAMIC_VERTS!
  172. U32 copyVerts = getMin( (U32)MAX_DYNAMIC_VERTS, numVerts );
  173. mVertBuff.set( GFX, copyVerts, GFXBufferTypeVolatile );
  174. GFXVertexPCT *verts = mVertBuff.lock();
  175. dMemcpy( verts, srcVerts, copyVerts * sizeof( GFXVertexPCT ) );
  176. mVertBuff.unlock();
  177. U32 numPrims = ( copyVerts / vertStride ) - stripStart;
  178. GFX->setVertexBuffer( mVertBuff );
  179. GFX->drawPrimitive( mType, 0, numPrims );
  180. }
  181. else
  182. {
  183. while ( numVerts > 0 )
  184. {
  185. U32 copyVerts = getMin( (U32)MAX_DYNAMIC_VERTS, numVerts );
  186. copyVerts -= copyVerts % vertStride;
  187. mVertBuff.set( GFX, copyVerts, GFXBufferTypeVolatile );
  188. GFXVertexPCT *verts = mVertBuff.lock();
  189. dMemcpy( verts, srcVerts, copyVerts * sizeof( GFXVertexPCT ) );
  190. mVertBuff.unlock();
  191. U32 numPrims = copyVerts / vertStride;
  192. GFX->setVertexBuffer( mVertBuff );
  193. GFX->drawPrimitive( mType, 0, numPrims );
  194. srcVerts += copyVerts;
  195. numVerts -= copyVerts;
  196. }
  197. }
  198. }
  199. //-----------------------------------------------------------------------------
  200. // vertex2f
  201. //-----------------------------------------------------------------------------
  202. void vertex2f( F32 x, F32 y )
  203. {
  204. VERTEX_BOUNDS_CHECK();
  205. GFXVertexPCT *vert = &mTempVertBuff[mCurVertIndex++];
  206. vert->point.x = x;
  207. vert->point.y = y;
  208. vert->point.z = 0.0;
  209. vert->color = mCurColor;
  210. vert->texCoord = mCurTexCoord;
  211. }
  212. //-----------------------------------------------------------------------------
  213. // vertex3f
  214. //-----------------------------------------------------------------------------
  215. void vertex3f( F32 x, F32 y, F32 z )
  216. {
  217. VERTEX_BOUNDS_CHECK();
  218. GFXVertexPCT *vert = &mTempVertBuff[mCurVertIndex++];
  219. vert->point.x = x;
  220. vert->point.y = y;
  221. vert->point.z = z;
  222. vert->color = mCurColor;
  223. vert->texCoord = mCurTexCoord;
  224. }
  225. //-----------------------------------------------------------------------------
  226. // vertex3fv
  227. //-----------------------------------------------------------------------------
  228. void vertex3fv( const F32 *data )
  229. {
  230. VERTEX_BOUNDS_CHECK();
  231. GFXVertexPCT *vert = &mTempVertBuff[mCurVertIndex++];
  232. vert->point.set( data[0], data[1], data[2] );
  233. vert->color = mCurColor;
  234. vert->texCoord = mCurTexCoord;
  235. }
  236. //-----------------------------------------------------------------------------
  237. // vertex2fv
  238. //-----------------------------------------------------------------------------
  239. void vertex2fv( const F32 *data )
  240. {
  241. VERTEX_BOUNDS_CHECK();
  242. GFXVertexPCT *vert = &mTempVertBuff[mCurVertIndex++];
  243. vert->point.set( data[0], data[1], 0.f );
  244. vert->color = mCurColor;
  245. vert->texCoord = mCurTexCoord;
  246. }
  247. //-----------------------------------------------------------------------------
  248. // color
  249. //-----------------------------------------------------------------------------
  250. void color( const ColorI &inColor )
  251. {
  252. mCurColor = inColor;
  253. }
  254. void color( const ColorF &inColor )
  255. {
  256. mCurColor = inColor;
  257. }
  258. void color3i( U8 red, U8 green, U8 blue )
  259. {
  260. mCurColor.set( red, green, blue );
  261. }
  262. void color4i( U8 red, U8 green, U8 blue, U8 alpha )
  263. {
  264. mCurColor.set( red, green, blue, alpha );
  265. }
  266. void color3f( F32 red, F32 green, F32 blue )
  267. {
  268. mCurColor.set( U8( red * 255 ), U8( green * 255 ), U8( blue * 255 ) );
  269. }
  270. void color4f( F32 red, F32 green, F32 blue, F32 alpha )
  271. {
  272. mCurColor.set( U8( red * 255 ), U8( green * 255 ), U8( blue * 255 ), U8( alpha * 255 ) );
  273. }
  274. //-----------------------------------------------------------------------------
  275. // texCoord
  276. //-----------------------------------------------------------------------------
  277. void texCoord2f( F32 x, F32 y )
  278. {
  279. mCurTexCoord.set( x, y );
  280. }
  281. void shutdown()
  282. {
  283. mVertBuff = NULL;
  284. }
  285. } // namespace PrimBuild