Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //-----------------------------------------------------------------------------
- // Copyright (c) 2013 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 "BatchRender.h"
- #ifndef _SCENE_OBJECT_H_
- #include "2d/sceneobject/SceneObject.h"
- #endif
- // Debug Profiling.
- #include "debug/profiler.h"
- //-----------------------------------------------------------------------------
- BatchRender::BatchRender() :
- mQuadCount( 0 ),
- mVertexCount( 0 ),
- mTextureResidentCount( 0 ),
- mIndexCount( 0 ),
- mColorCount( 0 ),
- NoColor( -1.0f, -1.0f, -1.0f ),
- mStrictOrderMode( false ),
- mpDebugStats( NULL ),
- mBlendMode( true ),
- mSrcBlendFactor( GL_SRC_ALPHA ),
- mDstBlendFactor( GL_ONE_MINUS_SRC_ALPHA ),
- mBlendColor( ColorF(1.0f,1.0f,1.0f,1.0f) ),
- mAlphaTestMode( -1.0f ),
- mWireframeMode( false ),
- mBatchEnabled( true ),
- mLightIndex(0)
- {
- }
- //-----------------------------------------------------------------------------
- BatchRender::~BatchRender()
- {
- // Destroy index vectors in texture batch map.
- for ( textureBatchType::iterator itr = mTextureBatchMap.begin(); itr != mTextureBatchMap.end(); ++itr )
- {
- delete itr->value;
- }
- mTextureBatchMap.clear();
- // Destroy index vectors in index vector pool.
- for ( VectorPtr< indexVectorType* >::iterator itr = mIndexVectorPool.begin(); itr != mIndexVectorPool.end(); ++itr )
- {
- delete (*itr);
- }
- mIndexVectorPool.clear();
- }
- //-----------------------------------------------------------------------------
- void BatchRender::setBlendMode( const SceneRenderRequest* pSceneRenderRequest )
- {
- // Are we blending?
- if ( pSceneRenderRequest->mBlendMode )
- {
- // Yes, so set blending to standard alpha-blending.
- setBlendMode(
- pSceneRenderRequest->mSrcBlendFactor,
- pSceneRenderRequest->mDstBlendFactor,
- pSceneRenderRequest->mBlendColor );
- }
- else
- {
- // No, so turn-off blending.
- setBlendOff();
- }
- }
- //-----------------------------------------------------------------------------
- void BatchRender::setAlphaTestMode( const SceneRenderRequest* pSceneRenderRequest )
- {
- // Set alpha-test mode.
- setAlphaTestMode( pSceneRenderRequest->mAlphaTest );
- }
- //-----------------------------------------------------------------------------
- void BatchRender::SubmitQuad(
- const Vector2& vertexPos0,
- const Vector2& vertexPos1,
- const Vector2& vertexPos2,
- const Vector2& vertexPos3,
- const Vector2& texturePos0,
- const Vector2& texturePos1,
- const Vector2& texturePos2,
- const Vector2& texturePos3,
- TextureHandle& texture,
- const ColorF& color )
- {
- // Sanity!
- AssertFatal( mpDebugStats != NULL, "Debug stats have not been configured." );
- PROFILE_START(BatchRender_SubmitQuad);
- // Do we have anything batched?
- if ( mQuadCount > 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 );
- }
- }
- // 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?
- if ( mStrictOrderMode )
- {
- // Is there is a texture change.
- if ( texture != mStrictOrderTextureHandle )
- {
- // Yes, so flush.
- flush( mpDebugStats->batchTextureChangeFlush );
- }
- // Add new indices.
- mIndexBuffer[mIndexCount++] = (U16)mVertexCount++;
- mIndexBuffer[mIndexCount++] = (U16)mVertexCount++;
- mIndexBuffer[mIndexCount++] = (U16)mVertexCount++;
- mIndexBuffer[mIndexCount++] = (U16)mVertexCount--;
- mIndexBuffer[mIndexCount++] = (U16)mVertexCount--;
- mIndexBuffer[mIndexCount++] = (U16)mVertexCount--;
- // find the GL name for our lightmap texture
- if (strstr(texture.getTextureKey(), "lightmap.PNG") != NULL){
- mLightIndex = texture.getGLName();
- }
- // Set strict order mode texture handle.
- mStrictOrderTextureHandle = texture;
- }
- 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;
- }
- // Add vertex start.
- pIndexVector->push_back( mVertexCount );
- }
- // Add textured vertices.
- // NOTE: We swap #2/#3 here.
- mVertexBuffer[mVertexCount++] = vertexPos0;
- mVertexBuffer[mVertexCount++] = vertexPos1;
- mVertexBuffer[mVertexCount++] = vertexPos3;
- mVertexBuffer[mVertexCount++] = vertexPos2;
- mTextureBuffer[mTextureResidentCount++] = texturePos0;
- mTextureBuffer[mTextureResidentCount++] = texturePos1;
- mTextureBuffer[mTextureResidentCount++] = texturePos3;
- mTextureBuffer[mTextureResidentCount++] = texturePos2;
- // Stats.
- mpDebugStats->batchTrianglesSubmitted+=2;
- // Increase quad count.
- mQuadCount++;
- // Have we reached the buffer limit?
- if ( mQuadCount == BATCHRENDER_MAXQUADS )
- {
- // Yes, so flush.
- flush( mpDebugStats->batchBufferFullFlush );
- }
- // Is batching enabled?
- 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();
- }
- PROFILE_END(); // BatchRender_SubmitQuad
- }
- //-----------------------------------------------------------------------------
- void BatchRender::flush( U32& reasonMetric )
- {
- // Finish if no quads to flush.
- if ( mQuadCount == 0 )
- return;
- // Increase reason metric.
- reasonMetric++;
- // Flush.
- flushInternal();
- }
- //-----------------------------------------------------------------------------
- void BatchRender::flush( void )
- {
- // Finish if no quads to flush.
- if ( mQuadCount == 0 )
- return;
- // Increase reason metric.
- mpDebugStats->batchAnonymousFlush++;
- // Flush.
- flushInternal();
- }
- //-----------------------------------------------------------------------------
- void BatchRender::flushInternal( void )
- {
- // Finish if no quads to flush.
- if ( mQuadCount == 0 )
- return;
- PROFILE_START(T2D_BatchRender_flush);
- // Stats.
- mpDebugStats->batchFlushes++;
- if ( mWireframeMode )
- {
- // Disable texturing.
- glDisable( GL_TEXTURE_2D );
- // Set the polygon mode to line.
- glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
- }
- else
- {
- // Enable texturing.
- glEnable( GL_TEXTURE_2D );
- glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
- // Set the polygon mode to fill.
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- }
- // Set blend mode.
- if ( mBlendMode )
- {
- glEnable( GL_BLEND );
- glBlendFunc( mSrcBlendFactor, mDstBlendFactor );
- glColor4f(mBlendColor.red, mBlendColor.green, mBlendColor.blue, mBlendColor.alpha );
- }
- else
- {
- glDisable( GL_BLEND );
- glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
- }
- // Set alpha-blend mode.
- if ( mAlphaTestMode >= 0.0f )
- {
- glEnable( GL_ALPHA_TEST );
- glAlphaFunc( GL_GREATER, mAlphaTestMode );
- }
- else
- {
- glDisable( GL_ALPHA_TEST );
- }
- // Enable vertex and texture arrays.
- glEnableClientState( GL_VERTEX_ARRAY );
- glVertexPointer( 2, GL_FLOAT, 0, mVertexBuffer );
- glTexCoordPointer( 2, GL_FLOAT, 0, mTextureBuffer );
- // Use the texture coordinates if not in wireframe mode.
- if ( !mWireframeMode )
- glEnableClientState( GL_TEXTURE_COORD_ARRAY );
- // Do we have any colors?
- if ( mColorCount > 0 )
- {
- // Yes, so enable color array.
- glEnableClientState( GL_COLOR_ARRAY );
- glColorPointer( 4, GL_FLOAT, 0, mColorBuffer );
- }
- // Strict order mode?
- if ( mStrictOrderMode )
- {
- // Bind the texture if not in wireframe mode.
- if ( !mWireframeMode )
- glBindTexture( GL_TEXTURE_2D, mStrictOrderTextureHandle.getGLName() );
- //enable stencil test for lighting effect
- glEnable(GL_STENCIL_TEST);
- glEnable(GL_ALPHA_TEST); //make sure the alpha is enabled
- // Identify lights
- if (mStrictOrderTextureHandle.getGLName() == mLightIndex && mLightIndex != 0){
- glClear(GL_DEPTH_BUFFER_BIT);
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- glDepthMask(GL_FALSE);
- glStencilFunc(GL_NEVER, 1, 0xFF);
- glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
- glAlphaFunc(GL_GREATER, 0);
- glStencilMask(0xFF);
- glClear(GL_STENCIL_BUFFER_BIT);
- }
- // 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++;
- // 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.
- const U32 trianglesDrawn = mIndexCount / 3;
- if ( trianglesDrawn > mpDebugStats->batchMaxTriangleDrawn )
- mpDebugStats->batchMaxTriangleDrawn = trianglesDrawn;
- }
- // Stats.
- if ( mVertexCount > mpDebugStats->batchMaxVertexBuffer )
- mpDebugStats->batchMaxVertexBuffer = mVertexCount;
- }
- else
- {
- // No, so iterate texture batch map.
- for( textureBatchType::iterator batchItr = mTextureBatchMap.begin(); batchItr != mTextureBatchMap.end(); ++batchItr )
- {
- // Fetch texture binding.
- const U32 textureBinding = batchItr->key;
- // Fetch index vector.
- indexVectorType* pIndexVector = batchItr->value;
- // Reset index count.
- mIndexCount = 0;
- // Iterate indexes.
- 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;
- }
- // Sanity!
- AssertFatal( mIndexCount > 0, "No batching indexes are present." );
- // Bind the texture if not in wireframe mode.
- if ( !mWireframeMode )
- glBindTexture( GL_TEXTURE_2D, textureBinding );
- // Draw the quads using triangles with indexes.
- glDrawElements( GL_TRIANGLES, mIndexCount, GL_UNSIGNED_SHORT, mIndexBuffer );
- // Stats.
- mpDebugStats->batchDrawCallsSorted++;
- // Stats.
- if ( mVertexCount > mpDebugStats->batchMaxVertexBuffer )
- mpDebugStats->batchMaxVertexBuffer = mVertexCount;
- // Stats.
- const U32 trianglesDrawn = mIndexCount / 3;
- if ( trianglesDrawn > mpDebugStats->batchMaxTriangleDrawn )
- mpDebugStats->batchMaxTriangleDrawn = trianglesDrawn;
- // Return index vector to pool.
- pIndexVector->clear();
- mIndexVectorPool.push_back( pIndexVector );
- }
- // Clear texture batch map.
- mTextureBatchMap.clear();
- }
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glDepthMask(GL_TRUE);
- glStencilMask(0x00);
- glAlphaFunc(GL_LEQUAL, 1);
- glStencilFunc(GL_EQUAL, 0, 0xFF);
- glStencilFunc(GL_EQUAL, 1, 0xFF);
- // only disable stencil after other objects have been rendered
- if (mStrictOrderTextureHandle.getGLName() != mLightIndex){
- glDisable(GL_STENCIL_TEST);
- }
- // Reset common render state.
- glDisableClientState( GL_VERTEX_ARRAY );
- glDisableClientState( GL_TEXTURE_COORD_ARRAY );
- glDisableClientState( GL_COLOR_ARRAY );
- glDisable( GL_ALPHA_TEST );
- glDisable( GL_BLEND );
- glDisable( GL_TEXTURE_2D );
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- // Reset batch state.
- mQuadCount = 0;
- mVertexCount = 0;
- mTextureResidentCount = 0;
- mIndexCount = 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 )
- {
- 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();
- }
Advertisement
RAW Paste Data
Copied
Advertisement