2012-09-19 15:15:01 +00:00
//-----------------------------------------------------------------------------
// 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 ;
}
}
2014-11-25 21:43:22 +00:00
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 ) ;
}
2012-09-19 15:15:01 +00:00
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 )
{
2021-01-05 02:57:17 +00:00
// TODO: Fix this to allow > GFX_MAX_DYNAMIC_VERTS!
2012-09-19 15:15:01 +00:00
2021-01-05 02:57:17 +00:00
U32 copyVerts = getMin ( ( U32 ) GFX_MAX_DYNAMIC_VERTS , numVerts ) ;
2012-09-19 15:15:01 +00:00
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 )
{
2021-01-05 02:57:17 +00:00
U32 copyVerts = getMin ( ( U32 ) GFX_MAX_DYNAMIC_VERTS , numVerts ) ;
2012-09-19 15:15:01 +00:00
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 ;
}
2017-06-23 16:36:20 +00:00
void color ( const LinearColorF & inColor )
2012-09-19 15:15:01 +00:00
{
2017-06-23 16:36:20 +00:00
mCurColor = LinearColorF ( inColor ) . toColorI ( ) ;
2012-09-19 15:15:01 +00:00
}
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