|
@@ -32,9 +32,9 @@
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
BatchRender::BatchRender() :
|
|
BatchRender::BatchRender() :
|
|
- mQuadCount( 0 ),
|
|
|
|
|
|
+ mTriangleCount( 0 ),
|
|
mVertexCount( 0 ),
|
|
mVertexCount( 0 ),
|
|
- mTextureResidentCount( 0 ),
|
|
|
|
|
|
+ mTextureCoordCount( 0 ),
|
|
mIndexCount( 0 ),
|
|
mIndexCount( 0 ),
|
|
mColorCount( 0 ),
|
|
mColorCount( 0 ),
|
|
NoColor( -1.0f, -1.0f, -1.0f ),
|
|
NoColor( -1.0f, -1.0f, -1.0f ),
|
|
@@ -99,6 +99,125 @@ void BatchRender::setAlphaTestMode( const SceneRenderRequest* pSceneRenderReques
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
+void BatchRender::SubmitTriangles(
|
|
|
|
+ const U32 vertexCount,
|
|
|
|
+ const Vector2* pVertexArray,
|
|
|
|
+ const Vector2* pTextureArray,
|
|
|
|
+ TextureHandle& texture,
|
|
|
|
+ const ColorF& color )
|
|
|
|
+{
|
|
|
|
+ // Debug Profiling.
|
|
|
|
+ PROFILE_SCOPE(BatchRender_SubmitTriangles);
|
|
|
|
+
|
|
|
|
+ // Sanity!
|
|
|
|
+ AssertFatal( mpDebugStats != NULL, "Debug stats have not been configured." );
|
|
|
|
+ AssertFatal( vertexCount % 3 == 0, "BatchRender::SubmitTriangles() - Invalid vertex count, cannot represent whole triangles." );
|
|
|
|
+ AssertFatal( vertexCount <= BATCHRENDER_BUFFERSIZE, "BatchRender::SubmitTriangles() - Invalid vertex count." );
|
|
|
|
+
|
|
|
|
+ // Calculate triangle count.
|
|
|
|
+ const U32 triangleCount = vertexCount / 3;
|
|
|
|
+
|
|
|
|
+ // Would we exceed the triangle buffer size?
|
|
|
|
+ if ( (mTriangleCount + triangleCount) > BATCHRENDER_MAXTRIANGLES )
|
|
|
|
+ {
|
|
|
|
+ // Yes, so flush.
|
|
|
|
+ flush( mpDebugStats->batchBufferFullFlush );
|
|
|
|
+ }
|
|
|
|
+ // Do we have anything batched?
|
|
|
|
+ else if ( mTriangleCount > 0 )
|
|
|
|
+ {
|
|
|
|
+ // Yes, so do we have any existing colors?
|
|
|
|
+ if ( mColorCount == 0 )
|
|
|
|
+ {
|
|
|
|
+ // No, so flush if color is specified.
|
|
|
|
+ if ( color != NoColor )
|
|
|
|
+ flush( mpDebugStats->batchColorStateFlush );
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // Yes, so flush if color is not specified.
|
|
|
|
+ if ( color == NoColor )
|
|
|
|
+ flush( mpDebugStats->batchColorStateFlush );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Strict order mode?
|
|
|
|
+ if ( mStrictOrderMode )
|
|
|
|
+ {
|
|
|
|
+ // Yes, so is there a texture change?
|
|
|
|
+ if ( texture != mStrictOrderTextureHandle && mTriangleCount > 0 )
|
|
|
|
+ {
|
|
|
|
+ // Yes, so flush.
|
|
|
|
+ flush( mpDebugStats->batchTextureChangeFlush );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Fetch vertex index.
|
|
|
|
+ U16 vertexIndex = (U16)mVertexCount;
|
|
|
|
+
|
|
|
|
+ // Add new indices.
|
|
|
|
+ for( U32 n = 0; n < triangleCount; ++n )
|
|
|
|
+ {
|
|
|
|
+ mIndexBuffer[mIndexCount++] = vertexIndex++;
|
|
|
|
+ mIndexBuffer[mIndexCount++] = vertexIndex++;
|
|
|
|
+ mIndexBuffer[mIndexCount++] = vertexIndex++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Set strict order mode texture handle.
|
|
|
|
+ mStrictOrderTextureHandle = texture;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // No, so add triangle run.
|
|
|
|
+ findTextureBatch( texture )->push_back( TriangleRun( TriangleRun::TRIANGLE, triangleCount, mVertexCount ) );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Is a color specified?
|
|
|
|
+ if ( color != NoColor )
|
|
|
|
+ {
|
|
|
|
+ // Yes, so add colors.
|
|
|
|
+ for( U32 n = 0; n < triangleCount; ++n )
|
|
|
|
+ {
|
|
|
|
+ mColorBuffer[mColorCount++] = color;
|
|
|
|
+ mColorBuffer[mColorCount++] = color;
|
|
|
|
+ mColorBuffer[mColorCount++] = color;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Add textured vertices.
|
|
|
|
+ for( U32 n = 0; n < triangleCount; ++n )
|
|
|
|
+ {
|
|
|
|
+ mVertexBuffer[mVertexCount++] = *(pVertexArray++);
|
|
|
|
+ mVertexBuffer[mVertexCount++] = *(pVertexArray++);
|
|
|
|
+ mVertexBuffer[mVertexCount++] = *(pVertexArray++);
|
|
|
|
+ mTextureBuffer[mTextureCoordCount++] = *(pTextureArray++);
|
|
|
|
+ mTextureBuffer[mTextureCoordCount++] = *(pTextureArray++);
|
|
|
|
+ mTextureBuffer[mTextureCoordCount++] = *(pTextureArray++);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Stats.
|
|
|
|
+ mpDebugStats->batchTrianglesSubmitted += triangleCount;
|
|
|
|
+
|
|
|
|
+ // Increase triangle count.
|
|
|
|
+ mTriangleCount += triangleCount;
|
|
|
|
+
|
|
|
|
+ // Have we reached the buffer limit?
|
|
|
|
+ if ( mTriangleCount == BATCHRENDER_MAXTRIANGLES )
|
|
|
|
+ {
|
|
|
|
+ // Yes, so flush.
|
|
|
|
+ flush( mpDebugStats->batchBufferFullFlush );
|
|
|
|
+ }
|
|
|
|
+ // Is batching enabled?
|
|
|
|
+ else if ( !mBatchEnabled )
|
|
|
|
+ {
|
|
|
|
+ // No, so flush immediately.
|
|
|
|
+ // NOTE: Technically this is still batching but will still revert to using
|
|
|
|
+ // more draw calls therefore can be used in comparison.
|
|
|
|
+ flushInternal();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
+
|
|
void BatchRender::SubmitQuad(
|
|
void BatchRender::SubmitQuad(
|
|
const Vector2& vertexPos0,
|
|
const Vector2& vertexPos0,
|
|
const Vector2& vertexPos1,
|
|
const Vector2& vertexPos1,
|
|
@@ -114,10 +233,17 @@ void BatchRender::SubmitQuad(
|
|
// Sanity!
|
|
// Sanity!
|
|
AssertFatal( mpDebugStats != NULL, "Debug stats have not been configured." );
|
|
AssertFatal( mpDebugStats != NULL, "Debug stats have not been configured." );
|
|
|
|
|
|
- PROFILE_START(BatchRender_SubmitQuad);
|
|
|
|
|
|
+ // Debug Profiling.
|
|
|
|
+ PROFILE_SCOPE(BatchRender_SubmitQuad);
|
|
|
|
|
|
|
|
+ // Would we exceed the triangle buffer size?
|
|
|
|
+ if ( (mTriangleCount + 2) > BATCHRENDER_MAXTRIANGLES )
|
|
|
|
+ {
|
|
|
|
+ // Yes, so flush.
|
|
|
|
+ flush( mpDebugStats->batchBufferFullFlush );
|
|
|
|
+ }
|
|
// Do we have anything batched?
|
|
// Do we have anything batched?
|
|
- if ( mQuadCount > 0 )
|
|
|
|
|
|
+ else if ( mTriangleCount > 0 )
|
|
{
|
|
{
|
|
// Yes, so do we have any existing colors?
|
|
// Yes, so do we have any existing colors?
|
|
if ( mColorCount == 0 )
|
|
if ( mColorCount == 0 )
|
|
@@ -134,21 +260,11 @@ void BatchRender::SubmitQuad(
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- // Is a color specified?
|
|
|
|
- if ( color != NoColor )
|
|
|
|
- {
|
|
|
|
- // Yes, so add colors.
|
|
|
|
- mColorBuffer[mColorCount++] = color;
|
|
|
|
- mColorBuffer[mColorCount++] = color;
|
|
|
|
- mColorBuffer[mColorCount++] = color;
|
|
|
|
- mColorBuffer[mColorCount++] = color;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
// Strict order mode?
|
|
// Strict order mode?
|
|
if ( mStrictOrderMode )
|
|
if ( mStrictOrderMode )
|
|
{
|
|
{
|
|
- // Is there is a texture change.
|
|
|
|
- if ( texture != mStrictOrderTextureHandle )
|
|
|
|
|
|
+ // Yes, so is there a texture change?
|
|
|
|
+ if ( texture != mStrictOrderTextureHandle && mTriangleCount > 0 )
|
|
{
|
|
{
|
|
// Yes, so flush.
|
|
// Yes, so flush.
|
|
flush( mpDebugStats->batchTextureChangeFlush );
|
|
flush( mpDebugStats->batchTextureChangeFlush );
|
|
@@ -167,44 +283,18 @@ void BatchRender::SubmitQuad(
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- // No, so fetch texture binding.
|
|
|
|
- const U32 textureBinding = texture.getGLName();
|
|
|
|
-
|
|
|
|
- indexVectorType* pIndexVector = NULL;
|
|
|
|
-
|
|
|
|
- // Find texture binding.
|
|
|
|
- textureBatchType::iterator itr = mTextureBatchMap.find( textureBinding );
|
|
|
|
-
|
|
|
|
- // Did we find a texture binding?
|
|
|
|
- if ( itr == mTextureBatchMap.end() )
|
|
|
|
- {
|
|
|
|
- // No, so fetch index vector pool count.
|
|
|
|
- const U32 indexVectorPoolCount = mIndexVectorPool.size();
|
|
|
|
-
|
|
|
|
- // Do we have any in the index vector pool?
|
|
|
|
- if ( indexVectorPoolCount > 0 )
|
|
|
|
- {
|
|
|
|
- // Yes, so use it.
|
|
|
|
- pIndexVector = mIndexVectorPool[indexVectorPoolCount-1];
|
|
|
|
- mIndexVectorPool.pop_back();
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- // No, so generate one.
|
|
|
|
- pIndexVector = new indexVectorType( 6 * 6 );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Insert into texture batch map.
|
|
|
|
- mTextureBatchMap.insert( textureBinding, pIndexVector );
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- // Yes, so fetch it.
|
|
|
|
- pIndexVector = itr->value;
|
|
|
|
- }
|
|
|
|
|
|
+ // No, so add triangle run.
|
|
|
|
+ findTextureBatch( texture )->push_back( TriangleRun( TriangleRun::QUAD, 1, mVertexCount ) );
|
|
|
|
+ }
|
|
|
|
|
|
- // Add vertex start.
|
|
|
|
- pIndexVector->push_back( mVertexCount );
|
|
|
|
|
|
+ // Is a color specified?
|
|
|
|
+ if ( color != NoColor )
|
|
|
|
+ {
|
|
|
|
+ // Yes, so add colors.
|
|
|
|
+ mColorBuffer[mColorCount++] = color;
|
|
|
|
+ mColorBuffer[mColorCount++] = color;
|
|
|
|
+ mColorBuffer[mColorCount++] = color;
|
|
|
|
+ mColorBuffer[mColorCount++] = color;
|
|
}
|
|
}
|
|
|
|
|
|
// Add textured vertices.
|
|
// Add textured vertices.
|
|
@@ -213,42 +303,39 @@ void BatchRender::SubmitQuad(
|
|
mVertexBuffer[mVertexCount++] = vertexPos1;
|
|
mVertexBuffer[mVertexCount++] = vertexPos1;
|
|
mVertexBuffer[mVertexCount++] = vertexPos3;
|
|
mVertexBuffer[mVertexCount++] = vertexPos3;
|
|
mVertexBuffer[mVertexCount++] = vertexPos2;
|
|
mVertexBuffer[mVertexCount++] = vertexPos2;
|
|
- mTextureBuffer[mTextureResidentCount++] = texturePos0;
|
|
|
|
- mTextureBuffer[mTextureResidentCount++] = texturePos1;
|
|
|
|
- mTextureBuffer[mTextureResidentCount++] = texturePos3;
|
|
|
|
- mTextureBuffer[mTextureResidentCount++] = texturePos2;
|
|
|
|
|
|
+ mTextureBuffer[mTextureCoordCount++] = texturePos0;
|
|
|
|
+ mTextureBuffer[mTextureCoordCount++] = texturePos1;
|
|
|
|
+ mTextureBuffer[mTextureCoordCount++] = texturePos3;
|
|
|
|
+ mTextureBuffer[mTextureCoordCount++] = texturePos2;
|
|
|
|
|
|
// Stats.
|
|
// Stats.
|
|
mpDebugStats->batchTrianglesSubmitted+=2;
|
|
mpDebugStats->batchTrianglesSubmitted+=2;
|
|
|
|
|
|
- // Increase quad count.
|
|
|
|
- mQuadCount++;
|
|
|
|
|
|
+ // Increase triangle count.
|
|
|
|
+ mTriangleCount += 2;
|
|
|
|
|
|
// Have we reached the buffer limit?
|
|
// Have we reached the buffer limit?
|
|
- if ( mQuadCount == BATCHRENDER_MAXQUADS )
|
|
|
|
|
|
+ if ( mTriangleCount == BATCHRENDER_MAXTRIANGLES )
|
|
{
|
|
{
|
|
// Yes, so flush.
|
|
// Yes, so flush.
|
|
flush( mpDebugStats->batchBufferFullFlush );
|
|
flush( mpDebugStats->batchBufferFullFlush );
|
|
}
|
|
}
|
|
-
|
|
|
|
// Is batching enabled?
|
|
// Is batching enabled?
|
|
- if ( !mBatchEnabled )
|
|
|
|
|
|
+ else if ( !mBatchEnabled )
|
|
{
|
|
{
|
|
// No, so flush immediately.
|
|
// No, so flush immediately.
|
|
// NOTE: Technically this is still batching but will still revert to using
|
|
// NOTE: Technically this is still batching but will still revert to using
|
|
// more draw calls therefore can be used in comparison.
|
|
// more draw calls therefore can be used in comparison.
|
|
flushInternal();
|
|
flushInternal();
|
|
}
|
|
}
|
|
-
|
|
|
|
- PROFILE_END(); // BatchRender_SubmitQuad
|
|
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
void BatchRender::flush( U32& reasonMetric )
|
|
void BatchRender::flush( U32& reasonMetric )
|
|
{
|
|
{
|
|
- // Finish if no quads to flush.
|
|
|
|
- if ( mQuadCount == 0 )
|
|
|
|
|
|
+ // Finish if no triangles to flush.
|
|
|
|
+ if ( mTriangleCount == 0 )
|
|
return;
|
|
return;
|
|
|
|
|
|
// Increase reason metric.
|
|
// Increase reason metric.
|
|
@@ -262,8 +349,8 @@ void BatchRender::flush( U32& reasonMetric )
|
|
|
|
|
|
void BatchRender::flush( void )
|
|
void BatchRender::flush( void )
|
|
{
|
|
{
|
|
- // Finish if no quads to flush.
|
|
|
|
- if ( mQuadCount == 0 )
|
|
|
|
|
|
+ // Finish if no triangles to flush.
|
|
|
|
+ if ( mTriangleCount == 0 )
|
|
return;
|
|
return;
|
|
|
|
|
|
// Increase reason metric.
|
|
// Increase reason metric.
|
|
@@ -277,11 +364,12 @@ void BatchRender::flush( void )
|
|
|
|
|
|
void BatchRender::flushInternal( void )
|
|
void BatchRender::flushInternal( void )
|
|
{
|
|
{
|
|
- // Finish if no quads to flush.
|
|
|
|
- if ( mQuadCount == 0 )
|
|
|
|
- return;
|
|
|
|
|
|
+ // Debug Profiling.
|
|
|
|
+ PROFILE_SCOPE(T2D_BatchRender_flush);
|
|
|
|
|
|
- PROFILE_START(T2D_BatchRender_flush);
|
|
|
|
|
|
+ // Finish if no triangles to flush.
|
|
|
|
+ if ( mTriangleCount == 0 )
|
|
|
|
+ return;
|
|
|
|
|
|
// Stats.
|
|
// Stats.
|
|
mpDebugStats->batchFlushes++;
|
|
mpDebugStats->batchFlushes++;
|
|
@@ -352,32 +440,16 @@ void BatchRender::flushInternal( void )
|
|
if ( !mWireframeMode )
|
|
if ( !mWireframeMode )
|
|
glBindTexture( GL_TEXTURE_2D, mStrictOrderTextureHandle.getGLName() );
|
|
glBindTexture( GL_TEXTURE_2D, mStrictOrderTextureHandle.getGLName() );
|
|
|
|
|
|
- // Yes, so do we have a single quad?
|
|
|
|
- if ( mQuadCount == 1 )
|
|
|
|
- {
|
|
|
|
- // Yes, so draw the quad using a triangle-strip with indexes.
|
|
|
|
- glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
|
|
|
|
-
|
|
|
|
- // Stats.
|
|
|
|
- mpDebugStats->batchDrawCallsStrictSingle++;
|
|
|
|
|
|
+ // Draw the triangles
|
|
|
|
+ glDrawElements( GL_TRIANGLES, mIndexCount, GL_UNSIGNED_SHORT, mIndexBuffer );
|
|
|
|
|
|
- // Stats.
|
|
|
|
- if ( mpDebugStats->batchMaxTriangleDrawn < 2 )
|
|
|
|
- mpDebugStats->batchMaxTriangleDrawn = 2;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- // Draw the quads using triangles with indexes.
|
|
|
|
- glDrawElements( GL_TRIANGLES, mIndexCount, GL_UNSIGNED_SHORT, mIndexBuffer );
|
|
|
|
-
|
|
|
|
- // Stats.
|
|
|
|
- mpDebugStats->batchDrawCallsStrictMultiple++;
|
|
|
|
|
|
+ // Stats.
|
|
|
|
+ mpDebugStats->batchDrawCallsStrict++;
|
|
|
|
|
|
- // Stats.
|
|
|
|
- const U32 trianglesDrawn = mIndexCount / 3;
|
|
|
|
- if ( trianglesDrawn > mpDebugStats->batchMaxTriangleDrawn )
|
|
|
|
- mpDebugStats->batchMaxTriangleDrawn = trianglesDrawn;
|
|
|
|
- }
|
|
|
|
|
|
+ // Stats.
|
|
|
|
+ const U32 trianglesDrawn = mIndexCount / 3;
|
|
|
|
+ if ( trianglesDrawn > mpDebugStats->batchMaxTriangleDrawn )
|
|
|
|
+ mpDebugStats->batchMaxTriangleDrawn = trianglesDrawn;
|
|
|
|
|
|
// Stats.
|
|
// Stats.
|
|
if ( mVertexCount > mpDebugStats->batchMaxVertexBuffer )
|
|
if ( mVertexCount > mpDebugStats->batchMaxVertexBuffer )
|
|
@@ -388,28 +460,58 @@ void BatchRender::flushInternal( void )
|
|
// No, so iterate texture batch map.
|
|
// No, so iterate texture batch map.
|
|
for( textureBatchType::iterator batchItr = mTextureBatchMap.begin(); batchItr != mTextureBatchMap.end(); ++batchItr )
|
|
for( textureBatchType::iterator batchItr = mTextureBatchMap.begin(); batchItr != mTextureBatchMap.end(); ++batchItr )
|
|
{
|
|
{
|
|
- // Fetch texture binding.
|
|
|
|
- const U32 textureBinding = batchItr->key;
|
|
|
|
|
|
+ // Reset index count.
|
|
|
|
+ mIndexCount = 0;
|
|
|
|
|
|
// Fetch index vector.
|
|
// Fetch index vector.
|
|
indexVectorType* pIndexVector = batchItr->value;
|
|
indexVectorType* pIndexVector = batchItr->value;
|
|
|
|
|
|
- // Reset index count.
|
|
|
|
- mIndexCount = 0;
|
|
|
|
-
|
|
|
|
// Iterate indexes.
|
|
// Iterate indexes.
|
|
for( indexVectorType::iterator indexItr = pIndexVector->begin(); indexItr != pIndexVector->end(); ++indexItr )
|
|
for( indexVectorType::iterator indexItr = pIndexVector->begin(); indexItr != pIndexVector->end(); ++indexItr )
|
|
{
|
|
{
|
|
- // Fetch quad index.
|
|
|
|
- U32 quadIndex = (*indexItr);
|
|
|
|
-
|
|
|
|
- // Add new indices.
|
|
|
|
- mIndexBuffer[mIndexCount++] = (U16)quadIndex++;
|
|
|
|
- mIndexBuffer[mIndexCount++] = (U16)quadIndex++;
|
|
|
|
- mIndexBuffer[mIndexCount++] = (U16)quadIndex++;
|
|
|
|
- mIndexBuffer[mIndexCount++] = (U16)quadIndex--;
|
|
|
|
- mIndexBuffer[mIndexCount++] = (U16)quadIndex--;
|
|
|
|
- mIndexBuffer[mIndexCount++] = (U16)quadIndex;
|
|
|
|
|
|
+ // Fetch triangle run.
|
|
|
|
+ const TriangleRun& triangleRun = *indexItr;
|
|
|
|
+
|
|
|
|
+ // Fetch primitivecount.
|
|
|
|
+ const U32 primitiveCount = triangleRun.mPrimitiveCount;
|
|
|
|
+
|
|
|
|
+ // Fetch triangle index start.
|
|
|
|
+ U16 triangleIndex = (U16)triangleRun.mStartIndex;
|
|
|
|
+
|
|
|
|
+ // Fetch primitive mode.
|
|
|
|
+ const TriangleRun::PrimitiveMode& primitiveMode = triangleRun.mPrimitiveMode;
|
|
|
|
+
|
|
|
|
+ // Handle primitive mode.
|
|
|
|
+ if ( primitiveMode == TriangleRun::QUAD )
|
|
|
|
+ {
|
|
|
|
+ // Add triangle run for quad.
|
|
|
|
+ for( U32 n = 0; n < primitiveCount; ++n )
|
|
|
|
+ {
|
|
|
|
+ // Add new indices.
|
|
|
|
+ mIndexBuffer[mIndexCount++] = triangleIndex++;
|
|
|
|
+ mIndexBuffer[mIndexCount++] = triangleIndex++;
|
|
|
|
+ mIndexBuffer[mIndexCount++] = triangleIndex++;
|
|
|
|
+ mIndexBuffer[mIndexCount++] = triangleIndex--;
|
|
|
|
+ mIndexBuffer[mIndexCount++] = triangleIndex--;
|
|
|
|
+ mIndexBuffer[mIndexCount++] = triangleIndex--;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if ( primitiveMode == TriangleRun::TRIANGLE )
|
|
|
|
+ {
|
|
|
|
+ // Add triangle run for triangles.
|
|
|
|
+ for( U32 n = 0; n < primitiveCount; ++n )
|
|
|
|
+ {
|
|
|
|
+ // Add new indices.
|
|
|
|
+ mIndexBuffer[mIndexCount++] = triangleIndex++;
|
|
|
|
+ mIndexBuffer[mIndexCount++] = triangleIndex++;
|
|
|
|
+ mIndexBuffer[mIndexCount++] = triangleIndex++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // Sanity!
|
|
|
|
+ AssertFatal( false, "BatchRender::flushInternal() - Unrecognized primitive mode encountered for triangle run." );
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
// Sanity!
|
|
// Sanity!
|
|
@@ -417,9 +519,9 @@ void BatchRender::flushInternal( void )
|
|
|
|
|
|
// Bind the texture if not in wireframe mode.
|
|
// Bind the texture if not in wireframe mode.
|
|
if ( !mWireframeMode )
|
|
if ( !mWireframeMode )
|
|
- glBindTexture( GL_TEXTURE_2D, textureBinding );
|
|
|
|
|
|
+ glBindTexture( GL_TEXTURE_2D, batchItr->key );
|
|
|
|
|
|
- // Draw the quads using triangles with indexes.
|
|
|
|
|
|
+ // Draw the triangles.
|
|
glDrawElements( GL_TRIANGLES, mIndexCount, GL_UNSIGNED_SHORT, mIndexBuffer );
|
|
glDrawElements( GL_TRIANGLES, mIndexCount, GL_UNSIGNED_SHORT, mIndexBuffer );
|
|
|
|
|
|
// Stats.
|
|
// Stats.
|
|
@@ -453,37 +555,54 @@ void BatchRender::flushInternal( void )
|
|
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
|
|
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
|
|
|
|
|
|
// Reset batch state.
|
|
// Reset batch state.
|
|
- mQuadCount = 0;
|
|
|
|
|
|
+ mTriangleCount = 0;
|
|
mVertexCount = 0;
|
|
mVertexCount = 0;
|
|
- mTextureResidentCount = 0;
|
|
|
|
|
|
+ mTextureCoordCount = 0;
|
|
mIndexCount = 0;
|
|
mIndexCount = 0;
|
|
mColorCount = 0;
|
|
mColorCount = 0;
|
|
-
|
|
|
|
- PROFILE_END(); // T2D_BatchRender_flush
|
|
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
-void BatchRender::RenderQuad(
|
|
|
|
- const Vector2& vertexPos0,
|
|
|
|
- const Vector2& vertexPos1,
|
|
|
|
- const Vector2& vertexPos2,
|
|
|
|
- const Vector2& vertexPos3,
|
|
|
|
- const Vector2& texturePos0,
|
|
|
|
- const Vector2& texturePos1,
|
|
|
|
- const Vector2& texturePos2,
|
|
|
|
- const Vector2& texturePos3 )
|
|
|
|
|
|
+BatchRender::indexVectorType* BatchRender::findTextureBatch( TextureHandle& handle )
|
|
{
|
|
{
|
|
- glBegin( GL_TRIANGLE_STRIP );
|
|
|
|
- glTexCoord2f( texturePos0.x, texturePos0.y );
|
|
|
|
- glVertex2f( vertexPos0.x, vertexPos0.y );
|
|
|
|
- glTexCoord2f( texturePos1.x, texturePos1.y );
|
|
|
|
- glVertex2f( vertexPos1.x, vertexPos1.y );
|
|
|
|
- glTexCoord2f( texturePos3.x, texturePos3.y );
|
|
|
|
- glVertex2f( vertexPos3.x, vertexPos3.y );
|
|
|
|
- glTexCoord2f( texturePos2.x, texturePos2.y );
|
|
|
|
- glVertex2f( vertexPos2.x, vertexPos2.y );
|
|
|
|
- glEnd();
|
|
|
|
|
|
+ // Fetch texture binding.
|
|
|
|
+ const U32 textureBinding = handle.getGLName();
|
|
|
|
+
|
|
|
|
+ indexVectorType* pIndexVector = NULL;
|
|
|
|
+
|
|
|
|
+ // Find texture binding.
|
|
|
|
+ textureBatchType::iterator itr = mTextureBatchMap.find( textureBinding );
|
|
|
|
+
|
|
|
|
+ // Did we find a texture binding?
|
|
|
|
+ if ( itr == mTextureBatchMap.end() )
|
|
|
|
+ {
|
|
|
|
+ // No, so fetch index vector pool count.
|
|
|
|
+ const U32 indexVectorPoolCount = mIndexVectorPool.size();
|
|
|
|
+
|
|
|
|
+ // Do we have any in the index vector pool?
|
|
|
|
+ if ( indexVectorPoolCount > 0 )
|
|
|
|
+ {
|
|
|
|
+ // Yes, so use it.
|
|
|
|
+ pIndexVector = mIndexVectorPool[indexVectorPoolCount-1];
|
|
|
|
+ mIndexVectorPool.pop_back();
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // No, so generate one.
|
|
|
|
+ pIndexVector = new indexVectorType( 6 * 6 );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Insert into texture batch map.
|
|
|
|
+ mTextureBatchMap.insert( textureBinding, pIndexVector );
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // Yes, so fetch it.
|
|
|
|
+ pIndexVector = itr->value;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return pIndexVector;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|