primBuilder.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  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. {
  102. numPrims = mCurVertIndex - 2;
  103. break;
  104. }
  105. case GFXPT_COUNT:
  106. // handle warning
  107. break;
  108. }
  109. return mVertBuff;
  110. }
  111. void end( bool useGenericShaders )
  112. {
  113. if ( mCurVertIndex == 0 )
  114. return;
  115. VERTEX_SIZE_CHECK();
  116. U32 vertStride = 1;
  117. U32 stripStart = 0;
  118. AssertFatal( mType >= GFXPT_FIRST && mType < GFXPT_COUNT, "PrimBuilder::end() - Bad primitive type!" );
  119. switch( mType )
  120. {
  121. default:
  122. case GFXPointList:
  123. {
  124. vertStride = 1;
  125. break;
  126. }
  127. case GFXLineList:
  128. {
  129. vertStride = 2;
  130. break;
  131. }
  132. case GFXTriangleList:
  133. {
  134. vertStride = 3;
  135. break;
  136. }
  137. case GFXLineStrip:
  138. {
  139. stripStart = 1;
  140. vertStride = 1;
  141. break;
  142. }
  143. case GFXTriangleStrip:
  144. {
  145. stripStart = 2;
  146. vertStride = 1;
  147. break;
  148. }
  149. }
  150. if ( useGenericShaders )
  151. {
  152. GFXStateBlock *currentBlock = GFX->getStateBlock();
  153. if (currentBlock && currentBlock->getDesc().samplersDefined)
  154. {
  155. if (currentBlock->getDesc().vertexColorEnable)
  156. GFX->setupGenericShaders( GFXDevice::GSModColorTexture );
  157. else
  158. GFX->setupGenericShaders( GFXDevice::GSTexture );
  159. }
  160. else
  161. GFX->setupGenericShaders( GFXDevice::GSColor );
  162. }
  163. const GFXVertexPCT *srcVerts = mTempVertBuff.address();
  164. U32 numVerts = mCurVertIndex;
  165. // Make sure we don't have a dirty prim buffer left.
  166. GFX->setPrimitiveBuffer( NULL );
  167. if ( stripStart > 0 )
  168. {
  169. // TODO: Fix this to allow > GFX_MAX_DYNAMIC_VERTS!
  170. U32 copyVerts = getMin( (U32)GFX_MAX_DYNAMIC_VERTS, numVerts );
  171. mVertBuff.set( GFX, copyVerts, GFXBufferTypeVolatile );
  172. GFXVertexPCT *verts = mVertBuff.lock();
  173. dMemcpy( verts, srcVerts, copyVerts * sizeof( GFXVertexPCT ) );
  174. mVertBuff.unlock();
  175. U32 numPrims = ( copyVerts / vertStride ) - stripStart;
  176. GFX->setVertexBuffer( mVertBuff );
  177. GFX->drawPrimitive( mType, 0, numPrims );
  178. }
  179. else
  180. {
  181. while ( numVerts > 0 )
  182. {
  183. U32 copyVerts = getMin( (U32)GFX_MAX_DYNAMIC_VERTS, numVerts );
  184. copyVerts -= copyVerts % vertStride;
  185. mVertBuff.set( GFX, copyVerts, GFXBufferTypeVolatile );
  186. GFXVertexPCT *verts = mVertBuff.lock();
  187. dMemcpy( verts, srcVerts, copyVerts * sizeof( GFXVertexPCT ) );
  188. mVertBuff.unlock();
  189. U32 numPrims = copyVerts / vertStride;
  190. GFX->setVertexBuffer( mVertBuff );
  191. GFX->drawPrimitive( mType, 0, numPrims );
  192. srcVerts += copyVerts;
  193. numVerts -= copyVerts;
  194. }
  195. }
  196. }
  197. //-----------------------------------------------------------------------------
  198. // vertex2f
  199. //-----------------------------------------------------------------------------
  200. void vertex2f( F32 x, F32 y )
  201. {
  202. VERTEX_BOUNDS_CHECK();
  203. GFXVertexPCT *vert = &mTempVertBuff[mCurVertIndex++];
  204. vert->point.x = x;
  205. vert->point.y = y;
  206. vert->point.z = 0.0;
  207. vert->color = mCurColor;
  208. vert->texCoord = mCurTexCoord;
  209. }
  210. //-----------------------------------------------------------------------------
  211. // vertex3f
  212. //-----------------------------------------------------------------------------
  213. void vertex3f( F32 x, F32 y, F32 z )
  214. {
  215. VERTEX_BOUNDS_CHECK();
  216. GFXVertexPCT *vert = &mTempVertBuff[mCurVertIndex++];
  217. vert->point.x = x;
  218. vert->point.y = y;
  219. vert->point.z = z;
  220. vert->color = mCurColor;
  221. vert->texCoord = mCurTexCoord;
  222. }
  223. //-----------------------------------------------------------------------------
  224. // vertex3fv
  225. //-----------------------------------------------------------------------------
  226. void vertex3fv( const F32 *data )
  227. {
  228. VERTEX_BOUNDS_CHECK();
  229. GFXVertexPCT *vert = &mTempVertBuff[mCurVertIndex++];
  230. vert->point.set( data[0], data[1], data[2] );
  231. vert->color = mCurColor;
  232. vert->texCoord = mCurTexCoord;
  233. }
  234. //-----------------------------------------------------------------------------
  235. // vertex2fv
  236. //-----------------------------------------------------------------------------
  237. void vertex2fv( const F32 *data )
  238. {
  239. VERTEX_BOUNDS_CHECK();
  240. GFXVertexPCT *vert = &mTempVertBuff[mCurVertIndex++];
  241. vert->point.set( data[0], data[1], 0.f );
  242. vert->color = mCurColor;
  243. vert->texCoord = mCurTexCoord;
  244. }
  245. //-----------------------------------------------------------------------------
  246. // color
  247. //-----------------------------------------------------------------------------
  248. void color( const ColorI &inColor )
  249. {
  250. mCurColor = inColor;
  251. }
  252. void color( const LinearColorF &inColor )
  253. {
  254. mCurColor = LinearColorF(inColor).toColorI();
  255. }
  256. void color3i( U8 red, U8 green, U8 blue )
  257. {
  258. mCurColor.set( red, green, blue );
  259. }
  260. void color4i( U8 red, U8 green, U8 blue, U8 alpha )
  261. {
  262. mCurColor.set( red, green, blue, alpha );
  263. }
  264. void color3f( F32 red, F32 green, F32 blue )
  265. {
  266. mCurColor.set( U8( red * 255 ), U8( green * 255 ), U8( blue * 255 ) );
  267. }
  268. void color4f( F32 red, F32 green, F32 blue, F32 alpha )
  269. {
  270. mCurColor.set( U8( red * 255 ), U8( green * 255 ), U8( blue * 255 ), U8( alpha * 255 ) );
  271. }
  272. //-----------------------------------------------------------------------------
  273. // texCoord
  274. //-----------------------------------------------------------------------------
  275. void texCoord2f( F32 x, F32 y )
  276. {
  277. mCurTexCoord.set( x, y );
  278. }
  279. void shutdown()
  280. {
  281. mVertBuff = NULL;
  282. }
  283. } // namespace PrimBuild