123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "primBuilder.h"
- #include "gfxDevice.h"
- #include "console/console.h"
- //*****************************************************************************
- // Primitive Builder
- //*****************************************************************************
- namespace PrimBuild
- {
- Vector<GFXVertexPCT> mTempVertBuff;
- GFXVertexBufferHandle<GFXVertexPCT> mVertBuff;
- GFXPrimitiveType mType;
- U32 mCurVertIndex;
- ColorI mCurColor( 255, 255, 255 );
- Point2F mCurTexCoord;
- const ColorI _colWhite( 255, 255, 255, 255 );
- #ifdef TORQUE_DEBUG
- U32 mMaxVerts;
- #define INIT_VERTEX_SIZE(x) mMaxVerts = x;
- #define VERTEX_BOUNDS_CHECK() AssertFatal( mCurVertIndex < mMaxVerts, "PrimBuilder encountered an out of bounds vertex! Break and debug!" );
- // This next check shouldn't really be used a lot unless you are tracking down
- // a specific bug. -pw
- #define VERTEX_SIZE_CHECK() AssertFatal( mCurVertIndex <= mMaxVerts, "PrimBuilder allocated more verts than you used! Break and debug or rendering artifacts could occur." );
- #else
- #define INIT_VERTEX_SIZE(x)
- #define VERTEX_BOUNDS_CHECK()
- #define VERTEX_SIZE_CHECK()
- #endif
- //-----------------------------------------------------------------------------
- // begin
- //-----------------------------------------------------------------------------
- void begin( GFXPrimitiveType type, U32 maxVerts )
- {
- AssertFatal( type >= GFXPT_FIRST && type < GFXPT_COUNT, "PrimBuilder::end() - Bad primitive type!" );
- mType = type;
- mCurVertIndex = 0;
- INIT_VERTEX_SIZE( maxVerts );
- mTempVertBuff.setSize( maxVerts );
- }
- void beginToBuffer( GFXPrimitiveType type, U32 maxVerts )
- {
- AssertFatal( type >= GFXPT_FIRST && type < GFXPT_COUNT, "PrimBuilder::end() - Bad primitive type!" );
- mType = type;
- mCurVertIndex = 0;
- INIT_VERTEX_SIZE( maxVerts );
- mTempVertBuff.setSize( maxVerts );
- }
- //-----------------------------------------------------------------------------
- // end
- //-----------------------------------------------------------------------------
- GFXVertexBuffer * endToBuffer( U32 &numPrims )
- {
- mVertBuff.set(GFX, mTempVertBuff.size(), GFXBufferTypeVolatile);
- GFXVertexPCT *verts = mVertBuff.lock();
- dMemcpy( verts, mTempVertBuff.address(), mTempVertBuff.size() * sizeof(GFXVertexPCT) );
- mVertBuff.unlock();
- VERTEX_SIZE_CHECK();
- switch( mType )
- {
- case GFXPointList:
- {
- numPrims = mCurVertIndex;
- break;
- }
- case GFXLineList:
- {
- numPrims = mCurVertIndex / 2;
- break;
- }
- case GFXLineStrip:
- {
- numPrims = mCurVertIndex - 1;
- break;
- }
- case GFXTriangleList:
- {
- numPrims = mCurVertIndex / 3;
- break;
- }
- case GFXTriangleStrip:
- {
- numPrims = mCurVertIndex - 2;
- break;
- }
- case GFXPT_COUNT:
- // handle warning
- break;
- }
- return mVertBuff;
- }
- void end( bool useGenericShaders )
- {
- if ( mCurVertIndex == 0 )
- return;
- VERTEX_SIZE_CHECK();
- U32 vertStride = 1;
- U32 stripStart = 0;
- AssertFatal( mType >= GFXPT_FIRST && mType < GFXPT_COUNT, "PrimBuilder::end() - Bad primitive type!" );
-
- switch( mType )
- {
- default:
- case GFXPointList:
- {
- vertStride = 1;
- break;
- }
- case GFXLineList:
- {
- vertStride = 2;
- break;
- }
- case GFXTriangleList:
- {
- vertStride = 3;
- break;
- }
- case GFXLineStrip:
- {
- stripStart = 1;
- vertStride = 1;
- break;
- }
- case GFXTriangleStrip:
- {
- stripStart = 2;
- vertStride = 1;
- break;
- }
- }
- if ( useGenericShaders )
- {
- GFXStateBlock *currentBlock = GFX->getStateBlock();
- if (currentBlock && currentBlock->getDesc().samplersDefined)
- {
- if (currentBlock->getDesc().vertexColorEnable)
- GFX->setupGenericShaders( GFXDevice::GSModColorTexture );
- else
- GFX->setupGenericShaders( GFXDevice::GSTexture );
- }
- else
- GFX->setupGenericShaders( GFXDevice::GSColor );
- }
- const GFXVertexPCT *srcVerts = mTempVertBuff.address();
- U32 numVerts = mCurVertIndex;
-
- // Make sure we don't have a dirty prim buffer left.
- GFX->setPrimitiveBuffer( NULL );
- if ( stripStart > 0 )
- {
- // TODO: Fix this to allow > GFX_MAX_DYNAMIC_VERTS!
- U32 copyVerts = getMin( (U32)GFX_MAX_DYNAMIC_VERTS, numVerts );
- mVertBuff.set( GFX, copyVerts, GFXBufferTypeVolatile );
- GFXVertexPCT *verts = mVertBuff.lock();
- dMemcpy( verts, srcVerts, copyVerts * sizeof( GFXVertexPCT ) );
- mVertBuff.unlock();
- U32 numPrims = ( copyVerts / vertStride ) - stripStart;
- GFX->setVertexBuffer( mVertBuff );
- GFX->drawPrimitive( mType, 0, numPrims );
- }
- else
- {
- while ( numVerts > 0 )
- {
- U32 copyVerts = getMin( (U32)GFX_MAX_DYNAMIC_VERTS, numVerts );
- copyVerts -= copyVerts % vertStride;
- mVertBuff.set( GFX, copyVerts, GFXBufferTypeVolatile );
- GFXVertexPCT *verts = mVertBuff.lock();
- dMemcpy( verts, srcVerts, copyVerts * sizeof( GFXVertexPCT ) );
- mVertBuff.unlock();
- U32 numPrims = copyVerts / vertStride;
- GFX->setVertexBuffer( mVertBuff );
- GFX->drawPrimitive( mType, 0, numPrims );
- srcVerts += copyVerts;
- numVerts -= copyVerts;
- }
- }
- }
- //-----------------------------------------------------------------------------
- // vertex2f
- //-----------------------------------------------------------------------------
- void vertex2f( F32 x, F32 y )
- {
- VERTEX_BOUNDS_CHECK();
- GFXVertexPCT *vert = &mTempVertBuff[mCurVertIndex++];
- vert->point.x = x;
- vert->point.y = y;
- vert->point.z = 0.0;
- vert->color = mCurColor;
- vert->texCoord = mCurTexCoord;
- }
- //-----------------------------------------------------------------------------
- // vertex3f
- //-----------------------------------------------------------------------------
- void vertex3f( F32 x, F32 y, F32 z )
- {
- VERTEX_BOUNDS_CHECK();
- GFXVertexPCT *vert = &mTempVertBuff[mCurVertIndex++];
- vert->point.x = x;
- vert->point.y = y;
- vert->point.z = z;
- vert->color = mCurColor;
- vert->texCoord = mCurTexCoord;
- }
- //-----------------------------------------------------------------------------
- // vertex3fv
- //-----------------------------------------------------------------------------
- void vertex3fv( const F32 *data )
- {
- VERTEX_BOUNDS_CHECK();
- GFXVertexPCT *vert = &mTempVertBuff[mCurVertIndex++];
- vert->point.set( data[0], data[1], data[2] );
- vert->color = mCurColor;
- vert->texCoord = mCurTexCoord;
- }
- //-----------------------------------------------------------------------------
- // vertex2fv
- //-----------------------------------------------------------------------------
- void vertex2fv( const F32 *data )
- {
- VERTEX_BOUNDS_CHECK();
- GFXVertexPCT *vert = &mTempVertBuff[mCurVertIndex++];
- vert->point.set( data[0], data[1], 0.f );
- vert->color = mCurColor;
- vert->texCoord = mCurTexCoord;
- }
- //-----------------------------------------------------------------------------
- // color
- //-----------------------------------------------------------------------------
- void color( const ColorI &inColor )
- {
- mCurColor = inColor;
- }
- void color( const LinearColorF &inColor )
- {
- mCurColor = LinearColorF(inColor).toColorI();
- }
- void color3i( U8 red, U8 green, U8 blue )
- {
- mCurColor.set( red, green, blue );
- }
- void color4i( U8 red, U8 green, U8 blue, U8 alpha )
- {
- mCurColor.set( red, green, blue, alpha );
- }
- void color3f( F32 red, F32 green, F32 blue )
- {
- mCurColor.set( U8( red * 255 ), U8( green * 255 ), U8( blue * 255 ) );
- }
- void color4f( F32 red, F32 green, F32 blue, F32 alpha )
- {
- mCurColor.set( U8( red * 255 ), U8( green * 255 ), U8( blue * 255 ), U8( alpha * 255 ) );
- }
- //-----------------------------------------------------------------------------
- // texCoord
- //-----------------------------------------------------------------------------
- void texCoord2f( F32 x, F32 y )
- {
- mCurTexCoord.set( x, y );
- }
- void shutdown()
- {
- mVertBuff = NULL;
- }
- } // namespace PrimBuild
|