axmol/cocos2dx/gles2/ccGLStateCache.cpp

229 lines
6.1 KiB
C++
Raw Normal View History

/*
* cocos2d for iPhone: http://www.cocos2d-iphone.org
*
* Copyright (c) 2011 Ricardo Quesada
* Copyright (c) 2011 Zynga Inc.
*
* 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 "ccGLStateCache.h"
#include "CCGLProgram.h"
#include "CCDirector.h"
#include "ccConfig.h"
// extern
#include "kazmath/GL/matrix.h"
#include "kazmath/kazmath.h"
NS_CC_BEGIN
static GLuint _ccCurrentProjectionMatrix = -1;
static bool _vertexAttribPosition = false;
static bool _vertexAttribColor = false;
static bool _vertexAttribTexCoords = false;
#if CC_ENABLE_GL_STATE_CACHE
#define kCCMaxActiveTexture 16
static GLuint _ccCurrentShaderProgram = -1;
static GLuint _ccCurrentBoundTexture[kCCMaxActiveTexture] = {-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, };
static GLenum _ccCurrentActiveTexture = (GL_TEXTURE0 - GL_TEXTURE0);
static GLenum _ccBlendingSource = -1;
static GLenum _ccBlendingDest = -1;
static int _ccGLServerState = 0;
#endif // CC_ENABLE_GL_STATE_CACHE
//#pragma mark - GL State Cache functions
void ccGLInvalidateStateCache( void )
{
kmGLFreeAll();
_ccCurrentProjectionMatrix = -1;
_vertexAttribPosition = false;
_vertexAttribColor = false;
_vertexAttribTexCoords = false;
#if CC_ENABLE_GL_STATE_CACHE
_ccCurrentShaderProgram = -1;
for( int i=0; i < kCCMaxActiveTexture; i++ )
_ccCurrentBoundTexture[i] = -1;
_ccCurrentActiveTexture = (GL_TEXTURE0 - GL_TEXTURE0);
_ccBlendingSource = -1;
_ccBlendingDest = -1;
_ccGLServerState = 0;
#endif
}
void ccGLDeleteProgram( GLuint program )
{
#if CC_ENABLE_GL_STATE_CACHE
if( program == _ccCurrentShaderProgram )
_ccCurrentShaderProgram = -1;
#endif // CC_ENABLE_GL_STATE_CACHE
glDeleteProgram( program );
}
void ccGLUseProgram( GLuint program )
{
#if CC_ENABLE_GL_STATE_CACHE
if( program != _ccCurrentShaderProgram ) {
_ccCurrentShaderProgram = program;
glUseProgram(program);
}
#else
glUseProgram(program);
#endif // CC_ENABLE_GL_STATE_CACHE
}
void ccGLBlendFunc(GLenum sfactor, GLenum dfactor)
{
#if CC_ENABLE_GL_STATE_CACHE
if( sfactor != _ccBlendingSource || dfactor != _ccBlendingDest ) {
_ccBlendingSource = sfactor;
_ccBlendingDest = dfactor;
glBlendFunc( sfactor, dfactor );
}
#else
glBlendFunc( sfactor, dfactor );
#endif // CC_ENABLE_GL_STATE_CACHE
}
GLenum ccGLGetActiveTexture( void )
{
#if CC_ENABLE_GL_STATE_CACHE
return _ccCurrentActiveTexture + GL_TEXTURE0;
#else
GLenum activeTexture;
glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&activeTexture);
return activeTexture;
#endif
}
void ccGLActiveTexture( GLenum textureEnum )
{
#if CC_ENABLE_GL_STATE_CACHE
CCAssert( (textureEnum - GL_TEXTURE0) < kCCMaxActiveTexture, "cocos2d ERROR: Increase kCCMaxActiveTexture to %d!", (textureEnum-GL_TEXTURE0) );
if( (textureEnum - GL_TEXTURE0) != _ccCurrentActiveTexture ) {
_ccCurrentActiveTexture = (textureEnum - GL_TEXTURE0);
glActiveTexture( textureEnum );
}
#else
glActiveTexture( textureEnum );
#endif
}
void ccGLBindTexture2D( GLuint textureId )
{
#if CC_ENABLE_GL_STATE_CACHE
if( _ccCurrentBoundTexture[ _ccCurrentActiveTexture ] != textureId )
{
_ccCurrentBoundTexture[ _ccCurrentActiveTexture ] = textureId;
glBindTexture(GL_TEXTURE_2D, textureId );
}
#else
glBindTexture(GL_TEXTURE_2D, textureId );
#endif
}
void ccGLDeleteTexture( GLuint textureId )
{
#if CC_ENABLE_GL_STATE_CACHE
if( textureId == _ccCurrentBoundTexture[ _ccCurrentActiveTexture ] )
_ccCurrentBoundTexture[ _ccCurrentActiveTexture ] = -1;
#endif
glDeleteTextures(1, &textureId );
}
void ccGLEnable( ccGLServerState flags )
{
#if CC_ENABLE_GL_STATE_CACHE
bool enabled = false;
/* GL_BLEND */
if( (enabled=(flags & CC_GL_BLEND)) != (_ccGLServerState & CC_GL_BLEND) ) {
if( enabled ) {
glEnable( GL_BLEND );
_ccGLServerState |= CC_GL_BLEND;
} else {
glDisable( GL_BLEND );
_ccGLServerState &= ~CC_GL_BLEND;
}
}
#else
if( flags & CC_GL_BLEND )
glEnable( GL_BLEND );
else
glDisable( GL_BLEND );
#endif
}
//#pragma mark - GL Vertex Attrib functions
void ccGLEnableVertexAttribs( unsigned int flags )
{
/* Position */
bool enablePosition = flags & kCCVertexAttribFlag_Position;
if( enablePosition != _vertexAttribPosition ) {
if( enablePosition )
glEnableVertexAttribArray( kCCVertexAttrib_Position );
else
glDisableVertexAttribArray( kCCVertexAttrib_Position );
_vertexAttribPosition = enablePosition;
}
/* Color */
bool enableColor = (flags & kCCVertexAttribFlag_Color) != 0 ? true : false;
if( enableColor != _vertexAttribColor ) {
if( enableColor )
glEnableVertexAttribArray( kCCVertexAttrib_Color );
else
glDisableVertexAttribArray( kCCVertexAttrib_Color );
_vertexAttribColor = enableColor;
}
/* Tex Coords */
bool enableTexCoords = (flags & kCCVertexAttribFlag_TexCoords) != 0 ? true : false;
if( enableTexCoords != _vertexAttribTexCoords ) {
if( enableTexCoords )
glEnableVertexAttribArray( kCCVertexAttrib_TexCoords );
else
glDisableVertexAttribArray( kCCVertexAttrib_TexCoords );
_vertexAttribTexCoords = enableTexCoords;
}
}
//#pragma mark - GL Uniforms functions
void ccSetProjectionMatrixDirty( void )
{
_ccCurrentProjectionMatrix = -1;
}
NS_CC_END