From 04c0d794af72dc8c19c4b1f51d94f5263cd2cf07 Mon Sep 17 00:00:00 2001 From: minggo Date: Tue, 17 Apr 2012 17:55:26 +0800 Subject: [PATCH] fixed #1139: fix the bug that screen becomes black when backing to foreground on Android --- HelloWorld/android/jni/helloworld/main.cpp | 7 +- cocos2dx/CCDrawingPrimitives.cpp | 12 + cocos2dx/include/CCDrawingPrimitives.h | 3 + cocos2dx/include/CCGLProgram.h | 72 ++-- cocos2dx/include/CCShaderCache.h | 4 + cocos2dx/kazmath/include/kazmath/mat4.h | 10 +- cocos2dx/shaders/CCGLProgram.cpp | 346 ++++++++-------- cocos2dx/shaders/CCShaderCache.cpp | 222 ++++++---- cocos2dx/textures/CCTextureAtlas.cpp | 446 ++++++++++----------- tests/test.android/jni/tests/main.cpp | 5 +- 10 files changed, 633 insertions(+), 494 deletions(-) diff --git a/HelloWorld/android/jni/helloworld/main.cpp b/HelloWorld/android/jni/helloworld/main.cpp index cb40bfe106..df7b15fd86 100644 --- a/HelloWorld/android/jni/helloworld/main.cpp +++ b/HelloWorld/android/jni/helloworld/main.cpp @@ -4,6 +4,8 @@ #include #include +#include "HelloWorldScene.h" + #define LOG_TAG "main" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) @@ -34,8 +36,11 @@ void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thi } else { + ccDrawInit(); + ccGLInvalidateStateCache(); + cocos2d::CCDirector::sharedDirector()->setGLDefaultValues(); + CCShaderCache::sharedShaderCache()->reloadDefaultShaders(); cocos2d::CCTextureCache::reloadAllTextures(); - cocos2d::CCDirector::sharedDirector()->setGLDefaultValues(); } } diff --git a/cocos2dx/CCDrawingPrimitives.cpp b/cocos2dx/CCDrawingPrimitives.cpp index 48b0fc7676..e541311368 100644 --- a/cocos2dx/CCDrawingPrimitives.cpp +++ b/cocos2dx/CCDrawingPrimitives.cpp @@ -57,11 +57,18 @@ static void lazy_init( void ) shader_ = CCShaderCache::sharedShaderCache()->programForKey(kCCShader_Position_uColor); colorLocation_ = glGetUniformLocation( shader_->getProgram(), "u_color"); + CHECK_GL_ERROR_DEBUG(); pointSizeLocation_ = glGetUniformLocation( shader_->getProgram(), "u_pointSize"); + CHECK_GL_ERROR_DEBUG(); initialized = true; } +} +// When back to foreground on android, we want to it to inilialize again +void ccDrawInit() +{ + initialized = false; } void ccDrawPoint( const CCPoint& point ) @@ -132,11 +139,16 @@ void ccDrawLine( const CCPoint& origin, const CCPoint& destination ) }; shader_->use(); + CHECK_GL_ERROR_DEBUG(); shader_->setUniformForModelViewProjectionMatrix(); + CHECK_GL_ERROR_DEBUG(); shader_->setUniformLocationWith4fv(colorLocation_, (GLfloat*) &color_.r, 1); + CHECK_GL_ERROR_DEBUG(); ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position ); + CHECK_GL_ERROR_DEBUG(); glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices); + CHECK_GL_ERROR_DEBUG(); glDrawArrays(GL_LINES, 0, 2); CC_INCREMENT_GL_DRAWS(1); diff --git a/cocos2dx/include/CCDrawingPrimitives.h b/cocos2dx/include/CCDrawingPrimitives.h index 7f039fdf97..7a8911b806 100755 --- a/cocos2dx/include/CCDrawingPrimitives.h +++ b/cocos2dx/include/CCDrawingPrimitives.h @@ -49,6 +49,9 @@ THE SOFTWARE. NS_CC_BEGIN +/** initlialize context */ +void CC_DLL ccDrawInit(); + /** draws a point given x and y coordinate measured in points */ void CC_DLL ccDrawPoint( const CCPoint& point ); diff --git a/cocos2dx/include/CCGLProgram.h b/cocos2dx/include/CCGLProgram.h index 1e41a510ca..4cd389aac4 100644 --- a/cocos2dx/include/CCGLProgram.h +++ b/cocos2dx/include/CCGLProgram.h @@ -71,11 +71,11 @@ struct _hashUniformEntry; typedef void (*GLInfoFunction)(GLuint program, GLenum pname, GLint* params); typedef void (*GLLogFunction) (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog); -/** CCGLProgram - Class that implements a glProgram - - - @since v2.0.0 +/** CCGLProgram + Class that implements a glProgram + + + @since v2.0.0 */ class CC_DLL CCGLProgram : public CCObject { @@ -84,7 +84,7 @@ public: CCGLProgram(); virtual ~CCGLProgram(); - /** Initializes the CCGLProgram with a vertex and fragment with bytes array */ + /** Initializes the CCGLProgram with a vertex and fragment with bytes array */ bool initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray); /** Initializes the CCGLProgram with a vertex and fragment with contents of filenames */ bool initWithVertexShaderFilename(const char* vShaderFilename, const char* fShaderFilename); @@ -103,34 +103,34 @@ public: */ void updateUniforms(); - /** calls glUniform1i only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWith1i(unsigned int location, GLint i1); - - /** calls glUniform1f only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWith1f(unsigned int location, GLfloat f1); - - /** calls glUniform2f only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWith2f(unsigned int location, GLfloat f1, GLfloat f2); - - /** calls glUniform3f only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWith3f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3); - - /** calls glUniform4f only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWith4f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4); - - /** calls glUniform2fv only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWith2fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays); - - /** calls glUniform3fv only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWith3fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays); - - /** calls glUniform4fv only if the values are different than the previous call for this same shader program. */ - void setUniformLocationWith4fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays); - - /** calls glUniformMatrix4fv only if the values are different than the previous call for this same shader program. */ - void setUniformLocationwithMatrix4fv(unsigned int location, GLfloat* matrixArray, unsigned int numberOfMatrices); - - /** will update the MVP matrix on the MVP uniform if it is different than the previous call for this same shader program. */ + /** calls glUniform1i only if the values are different than the previous call for this same shader program. */ + void setUniformLocationWith1i(unsigned int location, GLint i1); + + /** calls glUniform1f only if the values are different than the previous call for this same shader program. */ + void setUniformLocationWith1f(unsigned int location, GLfloat f1); + + /** calls glUniform2f only if the values are different than the previous call for this same shader program. */ + void setUniformLocationWith2f(unsigned int location, GLfloat f1, GLfloat f2); + + /** calls glUniform3f only if the values are different than the previous call for this same shader program. */ + void setUniformLocationWith3f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3); + + /** calls glUniform4f only if the values are different than the previous call for this same shader program. */ + void setUniformLocationWith4f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4); + + /** calls glUniform2fv only if the values are different than the previous call for this same shader program. */ + void setUniformLocationWith2fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays); + + /** calls glUniform3fv only if the values are different than the previous call for this same shader program. */ + void setUniformLocationWith3fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays); + + /** calls glUniform4fv only if the values are different than the previous call for this same shader program. */ + void setUniformLocationWith4fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays); + + /** calls glUniformMatrix4fv only if the values are different than the previous call for this same shader program. */ + void setUniformLocationwithMatrix4fv(unsigned int location, GLfloat* matrixArray, unsigned int numberOfMatrices); + + /** will update the MVP matrix on the MVP uniform if it is different than the previous call for this same shader program. */ void setUniformForModelViewProjectionMatrix(); /** returns the vertexShader error log */ @@ -139,6 +139,10 @@ public: const char* fragmentShaderLog(); /** returns the program error log */ const char* programLog(); + + // reload all shaders, this function is designed for android + // when opengl context lost, so don't call it. + void reset(); inline const GLuint getProgram() { return m_uProgram; } diff --git a/cocos2dx/include/CCShaderCache.h b/cocos2dx/include/CCShaderCache.h index fa24a4743f..109988b4a9 100644 --- a/cocos2dx/include/CCShaderCache.h +++ b/cocos2dx/include/CCShaderCache.h @@ -51,6 +51,9 @@ public: /** loads the default shaders */ void loadDefaultShaders(); + + /** reload the default shaders */ + void reloadDefaultShaders(); /** returns a GL program for a given key */ CCGLProgram * programForKey(const char* key); @@ -60,6 +63,7 @@ public: private: bool init(); + void loadDefaultShader(CCGLProgram *program, int type); CCDictionary* m_pPrograms; diff --git a/cocos2dx/kazmath/include/kazmath/mat4.h b/cocos2dx/kazmath/include/kazmath/mat4.h index ca5004499b..3a37dfe84b 100644 --- a/cocos2dx/kazmath/include/kazmath/mat4.h +++ b/cocos2dx/kazmath/include/kazmath/mat4.h @@ -29,7 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "CCPlatformMacros.h" #include "utility.h" -struct kmVec3; +struct kmVec3; struct kmMat3; struct kmQuaternion; struct kmPlane; @@ -38,7 +38,7 @@ struct kmPlane; A 4x4 matrix | 0 4 8 12 | -mat = | 1 5 9 13 | +mat = | 1 5 9 13 | | 2 6 10 14 | | 3 7 11 15 | */ @@ -83,10 +83,10 @@ CC_DLL struct kmVec3* const kmMat4GetForwardVec3(struct kmVec3* pOut, const kmMa CC_DLL kmMat4* const kmMat4PerspectiveProjection(kmMat4* pOut, kmScalar fovY, kmScalar aspect, kmScalar zNear, kmScalar zFar); CC_DLL kmMat4* const kmMat4OrthographicProjection(kmMat4* pOut, kmScalar left, kmScalar right, kmScalar bottom, kmScalar top, kmScalar nearVal, kmScalar farVal); CC_DLL kmMat4* const kmMat4LookAt(kmMat4* pOut, const struct kmVec3* pEye, const struct kmVec3* pCenter, const struct kmVec3* pUp); - -CC_DLL kmMat4* const kmMat4RotationAxisAngle(kmMat4* pOut, const struct kmVec3* axis, kmScalar radians); + +CC_DLL kmMat4* const kmMat4RotationAxisAngle(kmMat4* pOut, const struct kmVec3* axis, kmScalar radians); CC_DLL struct kmMat3* const kmMat4ExtractRotation(struct kmMat3* pOut, const kmMat4* pIn); -CC_DLL struct kmPlane* const kmMat4ExtractPlane(struct kmPlane* pOut, const kmMat4* pIn, const kmEnum plane); +CC_DLL struct kmPlane* const kmMat4ExtractPlane(struct kmPlane* pOut, const kmMat4* pIn, const kmEnum plane); CC_DLL struct kmVec3* const kmMat4RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn); #ifdef __cplusplus } diff --git a/cocos2dx/shaders/CCGLProgram.cpp b/cocos2dx/shaders/CCGLProgram.cpp index c3ccc008e9..39fcdeced4 100644 --- a/cocos2dx/shaders/CCGLProgram.cpp +++ b/cocos2dx/shaders/CCGLProgram.cpp @@ -31,17 +31,17 @@ THE SOFTWARE. #include "CCFileUtils.h" #include "support/data_support/uthash.h" #include "CCString.h" -// extern -#include "kazmath/GL/matrix.h" +// extern +#include "kazmath/GL/matrix.h" #include "kazmath/kazmath.h" NS_CC_BEGIN -typedef struct _hashUniformEntry -{ - GLvoid* value; // value - unsigned int location; // Key - UT_hash_handle hh; // hash entry +typedef struct _hashUniformEntry +{ + GLvoid* value; // value + unsigned int location; // Key + UT_hash_handle hh; // hash entry } tHashUniformEntry; CCGLProgram::CCGLProgram() @@ -55,7 +55,7 @@ CCGLProgram::CCGLProgram() CCGLProgram::~CCGLProgram() { - CCLOGINFO("cocos2d: deallocing 0x%X", this); + CCLOGINFO("cocos2d: %s %d deallocing 0x%X", __FUNCTION__, __LINE__, this); // there is no need to delete the shaders. They should have been already deleted. CCAssert( m_uVertShader == 0, "Vertex Shaders should have been already deleted"); @@ -66,19 +66,20 @@ CCGLProgram::~CCGLProgram() ccGLDeleteProgram(m_uProgram); } - tHashUniformEntry *current_element, *tmp; - - // Purge uniform hash - HASH_ITER(hh, m_pHashForUniforms, current_element, tmp) { - HASH_DEL(m_pHashForUniforms, current_element); - free(current_element->value); - free(current_element); + tHashUniformEntry *current_element, *tmp; + + // Purge uniform hash + HASH_ITER(hh, m_pHashForUniforms, current_element, tmp) { + HASH_DEL(m_pHashForUniforms, current_element); + free(current_element->value); + free(current_element); } } bool CCGLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray) { m_uProgram = glCreateProgram(); + CHECK_GL_ERROR_DEBUG(); m_uVertShader = m_uFragShader = 0; @@ -101,20 +102,23 @@ bool CCGLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray, if( m_uVertShader ) { glAttachShader(m_uProgram, m_uVertShader); } + CHECK_GL_ERROR_DEBUG(); if( m_uFragShader ) { glAttachShader(m_uProgram, m_uFragShader); } m_pHashForUniforms = NULL; + + CHECK_GL_ERROR_DEBUG(); return true; } bool CCGLProgram::initWithVertexShaderFilename(const char* vShaderFilename, const char* fShaderFilename) { - const GLchar * vertexSource = (GLchar*) CCString::stringWithContentsOfFile(CCFileUtils::fullPathFromRelativePath(vShaderFilename))->getCString(); - const GLchar * fragmentSource = (GLchar*) CCString::stringWithContentsOfFile(CCFileUtils::fullPathFromRelativePath(fShaderFilename))->getCString(); - + const GLchar * vertexSource = (GLchar*) CCString::stringWithContentsOfFile(CCFileUtils::fullPathFromRelativePath(vShaderFilename))->getCString(); + const GLchar * fragmentSource = (GLchar*) CCString::stringWithContentsOfFile(CCFileUtils::fullPathFromRelativePath(fShaderFilename))->getCString(); + return initWithVertexShaderByteArray(vertexSource, fragmentSource); } @@ -132,9 +136,12 @@ bool CCGLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* sour *shader = glCreateShader(type); glShaderSource(*shader, 1, &source, NULL); + CHECK_GL_ERROR_DEBUG(); glCompileShader(*shader); + CHECK_GL_ERROR_DEBUG(); glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); + CHECK_GL_ERROR_DEBUG(); if( ! status ) { if( type == GL_VERTEX_SHADER ) @@ -169,7 +176,7 @@ bool CCGLProgram::link() { glLinkProgram(m_uProgram); -#if DEBUG +//#if DEBUG GLint status; glValidateProgram(m_uProgram); @@ -184,7 +191,7 @@ bool CCGLProgram::link() m_uVertShader = m_uFragShader = m_uProgram = 0; return false; } -#endif +//#endif if (m_uVertShader) glDeleteShader(m_uVertShader); @@ -233,144 +240,167 @@ const char* CCGLProgram::programLog() return this->logForOpenGLObject(m_uProgram, (GLInfoFunction)&glGetProgramiv, (GLLogFunction)&glGetProgramInfoLog); } -// Uniform cache - -bool CCGLProgram::updateUniformLocation(unsigned int location, GLvoid* data, unsigned int bytes) -{ - bool updated = true; - tHashUniformEntry *element = NULL; - HASH_FIND_INT(m_pHashForUniforms, &location, element); - - if( ! element ) { - - element = (tHashUniformEntry*)malloc( sizeof(*element) ); - - // key - element->location = location; - - // value - element->value = malloc( bytes ); - memcpy(element->value, data, bytes ); - - HASH_ADD_INT(m_pHashForUniforms, location, element); - } - else - { - if( memcmp( element->value, data, bytes) == 0 ) - updated = false; - else - memcpy( element->value, data, bytes ); - } - - return updated; -} - -void CCGLProgram::setUniformLocationWith1i(unsigned int location, GLint i1) -{ - bool updated = updateUniformLocation(location, &i1, sizeof(i1)*1); - - if( updated ) - { - glUniform1i( (GLint)location, i1); - } -} - -void CCGLProgram::setUniformLocationWith1f(unsigned int location, GLfloat f1) -{ - bool updated = updateUniformLocation(location, &f1, sizeof(f1)*1); - - if( updated ) - { - glUniform1f( (GLint)location, f1); - } -} - -void CCGLProgram::setUniformLocationWith2f(unsigned int location, GLfloat f1, GLfloat f2) -{ - GLfloat floats[2] = {f1,f2}; - bool updated = updateUniformLocation(location, floats, sizeof(floats)); - - if( updated ) - { - glUniform2f( (GLint)location, f1, f2); - } -} - -void CCGLProgram::setUniformLocationWith3f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3) -{ - GLfloat floats[3] = {f1,f2,f3}; - bool updated = updateUniformLocation(location, floats, sizeof(floats)); - - if( updated ) - { - glUniform3f( (GLint)location, f1, f2, f3); - } -} - -void CCGLProgram::setUniformLocationWith4f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4) -{ - GLfloat floats[4] = {f1,f2,f3,f4}; - bool updated = updateUniformLocation(location, floats, sizeof(floats)); - - if( updated ) - { - glUniform4f( (GLint)location, f1, f2, f3,f4); - } -} - -void CCGLProgram::setUniformLocationWith2fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays) -{ - bool updated = updateUniformLocation(location, floats, sizeof(float)*2*numberOfArrays); - - if( updated ) - { - glUniform2fv( (GLint)location, (GLsizei)numberOfArrays, floats ); - } -} - -void CCGLProgram::setUniformLocationWith3fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays) -{ - bool updated = updateUniformLocation(location, floats, sizeof(float)*3*numberOfArrays); - - if( updated ) - { - glUniform3fv( (GLint)location, (GLsizei)numberOfArrays, floats ); - } -} - -void CCGLProgram::setUniformLocationWith4fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays) -{ - bool updated = updateUniformLocation(location, floats, sizeof(float)*4*numberOfArrays); - - if( updated ) - { - glUniform4fv( (GLint)location, (GLsizei)numberOfArrays, floats ); - } -} - - -void CCGLProgram::setUniformLocationwithMatrix4fv(unsigned int location, GLfloat* matrixArray, unsigned int numberOfMatrices) -{ - bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*16*numberOfMatrices); - - if( updated ) - { - glUniformMatrix4fv( (GLint)location, (GLsizei)numberOfMatrices, GL_FALSE, matrixArray); - } -} - -void CCGLProgram::setUniformForModelViewProjectionMatrix() -{ - kmMat4 matrixP; - kmMat4 matrixMV; - kmMat4 matrixMVP; - - kmGLGetMatrix(KM_GL_PROJECTION, &matrixP ); - kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV ); - - kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV); - - setUniformLocationwithMatrix4fv(m_uUniforms[kCCUniformMVPMatrix], matrixMVP.mat, 1); +// Uniform cache + +bool CCGLProgram::updateUniformLocation(unsigned int location, GLvoid* data, unsigned int bytes) +{ + bool updated = true; + tHashUniformEntry *element = NULL; + HASH_FIND_INT(m_pHashForUniforms, &location, element); + + if( ! element ) { + + element = (tHashUniformEntry*)malloc( sizeof(*element) ); + + // key + element->location = location; + + // value + element->value = malloc( bytes ); + memcpy(element->value, data, bytes ); + + HASH_ADD_INT(m_pHashForUniforms, location, element); + } + else + { + if( memcmp( element->value, data, bytes) == 0 ) + updated = false; + else + memcpy( element->value, data, bytes ); + } + + return updated; +} + +void CCGLProgram::setUniformLocationWith1i(unsigned int location, GLint i1) +{ + bool updated = updateUniformLocation(location, &i1, sizeof(i1)*1); + + if( updated ) + { + glUniform1i( (GLint)location, i1); + } +} + +void CCGLProgram::setUniformLocationWith1f(unsigned int location, GLfloat f1) +{ + bool updated = updateUniformLocation(location, &f1, sizeof(f1)*1); + + if( updated ) + { + glUniform1f( (GLint)location, f1); + } +} + +void CCGLProgram::setUniformLocationWith2f(unsigned int location, GLfloat f1, GLfloat f2) +{ + GLfloat floats[2] = {f1,f2}; + bool updated = updateUniformLocation(location, floats, sizeof(floats)); + + if( updated ) + { + glUniform2f( (GLint)location, f1, f2); + } +} + +void CCGLProgram::setUniformLocationWith3f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3) +{ + GLfloat floats[3] = {f1,f2,f3}; + bool updated = updateUniformLocation(location, floats, sizeof(floats)); + + if( updated ) + { + glUniform3f( (GLint)location, f1, f2, f3); + } +} + +void CCGLProgram::setUniformLocationWith4f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4) +{ + GLfloat floats[4] = {f1,f2,f3,f4}; + bool updated = updateUniformLocation(location, floats, sizeof(floats)); + + if( updated ) + { + glUniform4f( (GLint)location, f1, f2, f3,f4); + } +} + +void CCGLProgram::setUniformLocationWith2fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays) +{ + bool updated = updateUniformLocation(location, floats, sizeof(float)*2*numberOfArrays); + + if( updated ) + { + glUniform2fv( (GLint)location, (GLsizei)numberOfArrays, floats ); + } +} + +void CCGLProgram::setUniformLocationWith3fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays) +{ + bool updated = updateUniformLocation(location, floats, sizeof(float)*3*numberOfArrays); + + if( updated ) + { + glUniform3fv( (GLint)location, (GLsizei)numberOfArrays, floats ); + } +} + +void CCGLProgram::setUniformLocationWith4fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays) +{ + bool updated = updateUniformLocation(location, floats, sizeof(float)*4*numberOfArrays); + + if( updated ) + { + glUniform4fv( (GLint)location, (GLsizei)numberOfArrays, floats ); + } +} + + +void CCGLProgram::setUniformLocationwithMatrix4fv(unsigned int location, GLfloat* matrixArray, unsigned int numberOfMatrices) +{ + bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*16*numberOfMatrices); + + if( updated ) + { + glUniformMatrix4fv( (GLint)location, (GLsizei)numberOfMatrices, GL_FALSE, matrixArray); + } +} + +void CCGLProgram::setUniformForModelViewProjectionMatrix() +{ + kmMat4 matrixP; + kmMat4 matrixMV; + kmMat4 matrixMVP; + + kmGLGetMatrix(KM_GL_PROJECTION, &matrixP ); + kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV ); + + kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV); + + setUniformLocationwithMatrix4fv(m_uUniforms[kCCUniformMVPMatrix], matrixMVP.mat, 1); +} + +void CCGLProgram::reset() +{ + m_uVertShader = m_uFragShader = 0; + memset(m_uUniforms, 0, sizeof(m_uUniforms)); + + + // it is already deallocated by android + //ccGLDeleteProgram(m_uProgram); + m_uProgram = 0; + + + tHashUniformEntry *current_element, *tmp; + + // Purge uniform hash + HASH_ITER(hh, m_pHashForUniforms, current_element, tmp) + { + HASH_DEL(m_pHashForUniforms, current_element); + free(current_element->value); + free(current_element); + } + m_pHashForUniforms = NULL; } NS_CC_END diff --git a/cocos2dx/shaders/CCShaderCache.cpp b/cocos2dx/shaders/CCShaderCache.cpp index 8e1d1a36db..9a14d2d961 100644 --- a/cocos2dx/shaders/CCShaderCache.cpp +++ b/cocos2dx/shaders/CCShaderCache.cpp @@ -31,6 +31,26 @@ THE SOFTWARE. NS_CC_BEGIN +#define kCCShader_PositionTextureColor "ShaderPositionTextureColor" +#define kCCShader_PositionTextureColorAlphaTest "ShaderPositionTextureColorAlphaTest" +#define kCCShader_PositionColor "ShaderPositionColor" +#define kCCShader_PositionTexture "ShaderPositionTexture" +#define kCCShader_PositionTexture_uColor "ShaderPositionTexture_uColor" +#define kCCShader_PositionTextureA8Color "ShaderPositionTextureA8Color" +#define kCCShader_Position_uColor "ShaderPosition_uColor" + +enum { + kCCShaderType_PositionTextureColor, + kCCShaderType_PositionTextureColorAlphaTest, + kCCShaderType_PositionColor, + kCCShaderType_PositionTexture, + kCCShaderType_PositionTexture_uColor, + kCCShaderType_PositionTextureA8Color, + kCCShaderType_Position_uColor, + + kCCShaderType_MAX, +}; + static CCShaderCache *_sharedShaderCache = 0; CCShaderCache* CCShaderCache::sharedShaderCache() @@ -73,119 +93,177 @@ void CCShaderCache::loadDefaultShaders() { // Position Texture Color shader CCGLProgram *p = new CCGLProgram(); - p->initWithVertexShaderByteArray(ccPositionTextureColor_vert, ccPositionTextureColor_frag); - - p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); - p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); - p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); - - p->link(); - p->updateUniforms(); + loadDefaultShader(p, kCCShaderType_PositionTextureColor); m_pPrograms->setObject(p, kCCShader_PositionTextureColor); p->release(); - CHECK_GL_ERROR_DEBUG(); - // Position Texture Color alpha test p = new CCGLProgram(); - p->initWithVertexShaderByteArray(ccPositionTextureColor_vert, ccPositionTextureColorAlphaTest_frag); - - p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); - p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); - p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); - - p->link(); - p->updateUniforms(); + loadDefaultShader(p, kCCShaderType_PositionTextureColorAlphaTest); m_pPrograms->setObject(p, kCCShader_PositionTextureColorAlphaTest); p->release(); - CHECK_GL_ERROR_DEBUG(); - // // Position, Color shader // p = new CCGLProgram(); - p->initWithVertexShaderByteArray(ccPositionColor_vert ,ccPositionColor_frag); - - p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); - p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); - - p->link(); - p->updateUniforms(); + loadDefaultShader(p, kCCShaderType_PositionColor); m_pPrograms->setObject(p, kCCShader_PositionColor); p->release(); - CHECK_GL_ERROR_DEBUG(); // // Position Texture shader // p = new CCGLProgram(); - p->initWithVertexShaderByteArray(ccPositionTexture_vert ,ccPositionTexture_frag); - - p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); - p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); - - p->link(); - p->updateUniforms(); + loadDefaultShader(p, kCCShaderType_PositionTexture); m_pPrograms->setObject(p, kCCShader_PositionTexture); p->release(); - CHECK_GL_ERROR_DEBUG(); - // // Position, Texture attribs, 1 Color as uniform shader // p = new CCGLProgram(); - p->initWithVertexShaderByteArray(ccPositionTexture_uColor_vert, ccPositionTexture_uColor_frag); - - p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); - p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); - - p->link(); - p->updateUniforms(); + loadDefaultShader(p, kCCShaderType_PositionTexture_uColor); m_pPrograms->setObject(p ,kCCShader_PositionTexture_uColor); p->release(); - CHECK_GL_ERROR_DEBUG(); - // // Position Texture A8 Color shader // p = new CCGLProgram(); - p->initWithVertexShaderByteArray(ccPositionTextureA8Color_vert, ccPositionTextureA8Color_frag); - - p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); - p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); - p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); - - p->link(); - p->updateUniforms(); - - m_pPrograms->setObject(p, kCCShader_PositionTextureA8Color); + loadDefaultShader(p, kCCShaderType_PositionTextureA8Color); + + m_pPrograms->setObject(p, kCCShader_PositionTextureA8Color); p->release(); - CHECK_GL_ERROR_DEBUG(); + // + // Position and 1 color passed as a uniform (to similate glColor4ub ) + // + p = new CCGLProgram(); + loadDefaultShader(p, kCCShaderType_Position_uColor); + + m_pPrograms->setObject(p, kCCShader_Position_uColor); + p->release(); +} - // - // Position and 1 color passed as a uniform (to similate glColor4ub ) - // - p = new CCGLProgram(); - p->initWithVertexShaderByteArray(ccPosition_uColor_vert, ccPosition_uColor_frag); - - p->addAttribute("aVertex", kCCVertexAttrib_Position); - - p->link(); - p->updateUniforms(); - - m_pPrograms->setObject(p, kCCShader_Position_uColor); - p->release(); - - CHECK_GL_ERROR_DEBUG(); +void CCShaderCache::reloadDefaultShaders() +{ + // reset all programs and reload them + + // Position Texture Color shader + CCGLProgram *p = programForKey(kCCShader_PositionTextureColor); + p->reset(); + loadDefaultShader(p, kCCShaderType_PositionTextureColor); + + // Position Texture Color alpha test + p = programForKey(kCCShader_PositionTextureColorAlphaTest); + p->reset(); + loadDefaultShader(p, kCCShaderType_PositionTextureColorAlphaTest); + + // + // Position, Color shader + // + p = programForKey(kCCShader_PositionColor); + p->reset(); + loadDefaultShader(p, kCCShaderType_PositionColor); + + // + // Position Texture shader + // + p = programForKey(kCCShader_PositionTexture); + p->reset(); + loadDefaultShader(p, kCCShaderType_PositionTexture); + + // + // Position, Texture attribs, 1 Color as uniform shader + // + p = programForKey(kCCShader_PositionTexture_uColor); + p->reset(); + loadDefaultShader(p, kCCShaderType_PositionTexture_uColor); + + // + // Position Texture A8 Color shader + // + p = programForKey(kCCShader_PositionTextureA8Color); + p->reset(); + loadDefaultShader(p, kCCShaderType_PositionTextureA8Color); + + // + // Position and 1 color passed as a uniform (to similate glColor4ub ) + // + p = programForKey(kCCShader_Position_uColor); + p->reset(); + loadDefaultShader(p, kCCShaderType_Position_uColor); +} + +void CCShaderCache::loadDefaultShader(CCGLProgram *p, int type) +{ + switch (type) { + case kCCShaderType_PositionTextureColor: + p->initWithVertexShaderByteArray(ccPositionTextureColor_vert, ccPositionTextureColor_frag); + + p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); + p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); + p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); + + break; + case kCCShaderType_PositionTextureColorAlphaTest: + p->initWithVertexShaderByteArray(ccPositionTextureColor_vert, ccPositionTextureColorAlphaTest_frag); + + p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); + p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); + p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); + + break; + case kCCShaderType_PositionColor: + p->initWithVertexShaderByteArray(ccPositionColor_vert ,ccPositionColor_frag); + + p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); + p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); + + break; + case kCCShaderType_PositionTexture: + p->initWithVertexShaderByteArray(ccPositionTexture_vert ,ccPositionTexture_frag); + + p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); + p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); + + break; + case kCCShaderType_PositionTexture_uColor: + p->initWithVertexShaderByteArray(ccPositionTexture_uColor_vert, ccPositionTexture_uColor_frag); + + p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); + p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); + + break; + case kCCShaderType_PositionTextureA8Color: + p->initWithVertexShaderByteArray(ccPositionTextureA8Color_vert, ccPositionTextureA8Color_frag); + + p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); + p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); + p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); + + break; + case kCCShaderType_Position_uColor: + p->initWithVertexShaderByteArray(ccPosition_uColor_vert, ccPosition_uColor_frag); + + p->addAttribute("aVertex", kCCVertexAttrib_Position); + + break; + default: + CCLOG("cocos2d: %s:%d, error shader type", __FUNCTION__, __LINE__); + return; + } + + p->link(); + p->updateUniforms(); + + CHECK_GL_ERROR_DEBUG(); } CCGLProgram* CCShaderCache::programForKey(const char* key) diff --git a/cocos2dx/textures/CCTextureAtlas.cpp b/cocos2dx/textures/CCTextureAtlas.cpp index 1ed4b357ae..d6fdadf9cb 100644 --- a/cocos2dx/textures/CCTextureAtlas.cpp +++ b/cocos2dx/textures/CCTextureAtlas.cpp @@ -28,7 +28,7 @@ THE SOFTWARE. #include "CCTextureAtlas.h" #include "CCTextureCache.h" #include "ccMacros.h" -#include "CCGLProgram.h" +#include "CCGLProgram.h" #include "ccGLStateCache.h" // support #include "CCTexture2D.h" @@ -50,7 +50,7 @@ CCTextureAtlas::CCTextureAtlas() CCTextureAtlas::~CCTextureAtlas() { - CCLOGINFO("cocos2d: CCTextureAtlas deallocing %p."this); + CCLOGINFO("cocos2d: CCTextureAtlas deallocing %p.", this); CC_SAFE_FREE(m_pQuads); CC_SAFE_FREE(m_pIndices); @@ -87,7 +87,7 @@ void CCTextureAtlas::setTexture(CCTexture2D * var) ccV3F_C4B_T2F_Quad* CCTextureAtlas::getQuads() { - //if someone accesses the quads directly, presume that changes will be made + //if someone accesses the quads directly, presume that changes will be made m_bDirty = true; return m_pQuads; } @@ -172,12 +172,12 @@ bool CCTextureAtlas::initWithTexture(CCTexture2D *texture, unsigned int capacity memset( m_pQuads, 0, m_uCapacity * sizeof(ccV3F_C4B_T2F_Quad) ); memset( m_pIndices, 0, m_uCapacity * 6 * sizeof(GLushort) ); - this->setupIndices(); - -#if CC_TEXTURE_ATLAS_USE_VAO - setupVBOandVAO(); -#else - setupVBO(); + this->setupIndices(); + +#if CC_TEXTURE_ATLAS_USE_VAO + setupVBOandVAO(); +#else + setupVBO(); #endif m_bDirty = true; @@ -217,62 +217,62 @@ void CCTextureAtlas::setupIndices() #endif } } - -//TextureAtlas - VAO / VBO specific - -#if CC_TEXTURE_ATLAS_USE_VAO -void CCTextureAtlas::setupVBOandVAO() -{ - glGenVertexArrays(1, &m_uVAOname); - glBindVertexArray(m_uVAOname); - -#define kQuadSize sizeof(m_pQuads[0].bl) - - glGenBuffers(2, &m_pBuffersVBO[0]); - - glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW); - - // vertices - glEnableVertexAttribArray(kCCVertexAttrib_Position); - glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices)); - - // colors - glEnableVertexAttribArray(kCCVertexAttrib_Color); - glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors)); - - // tex coords - glEnableVertexAttribArray(kCCVertexAttrib_TexCoords); - glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords)); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_pIndices[0]) * m_uCapacity * 6, m_pIndices, GL_STATIC_DRAW); - - glBindVertexArray(0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - CHECK_GL_ERROR_DEBUG(); -} -#else // CC_TEXTURE_ATLAS_USE_VAO -void CCTextureAtlas::setupVBO() -{ - glGenBuffers(2, &m_pBuffersVBO[0]); - - mapBuffers(); -} -#endif // ! // CC_TEXTURE_ATLAS_USE_VAO - + +//TextureAtlas - VAO / VBO specific + +#if CC_TEXTURE_ATLAS_USE_VAO +void CCTextureAtlas::setupVBOandVAO() +{ + glGenVertexArrays(1, &m_uVAOname); + glBindVertexArray(m_uVAOname); + +#define kQuadSize sizeof(m_pQuads[0].bl) + + glGenBuffers(2, &m_pBuffersVBO[0]); + + glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW); + + // vertices + glEnableVertexAttribArray(kCCVertexAttrib_Position); + glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices)); + + // colors + glEnableVertexAttribArray(kCCVertexAttrib_Color); + glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors)); + + // tex coords + glEnableVertexAttribArray(kCCVertexAttrib_TexCoords); + glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords)); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_pIndices[0]) * m_uCapacity * 6, m_pIndices, GL_STATIC_DRAW); + + glBindVertexArray(0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + CHECK_GL_ERROR_DEBUG(); +} +#else // CC_TEXTURE_ATLAS_USE_VAO +void CCTextureAtlas::setupVBO() +{ + glGenBuffers(2, &m_pBuffersVBO[0]); + + mapBuffers(); +} +#endif // ! // CC_TEXTURE_ATLAS_USE_VAO + void CCTextureAtlas::mapBuffers() -{ - glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_pIndices[0]) * m_uCapacity * 6, m_pIndices, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - +{ + glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_pIndices[0]) * m_uCapacity * 6, m_pIndices, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + CHECK_GL_ERROR_DEBUG(); } @@ -317,32 +317,32 @@ void CCTextureAtlas::insertQuad(ccV3F_C4B_T2F_Quad *quad, unsigned int index) void CCTextureAtlas::insertQuads(ccV3F_C4B_T2F_Quad* quads, unsigned int index, unsigned int amount) { - CCAssert(index + amount <= m_uCapacity, "insertQuadWithTexture: Invalid index + amount"); - - m_uTotalQuads += amount; - - CCAssert( m_uTotalQuads <= m_uCapacity, "invalid totalQuads"); - - // issue #575. index can be > totalQuads - int remaining = (m_uTotalQuads-1) - index - amount; - - // last object doesn't need to be moved - if( remaining > 0) - { - // tex coordinates - memmove( &m_pQuads[index+amount],&m_pQuads[index], sizeof(m_pQuads[0]) * remaining ); - } - - - unsigned int max = index + amount; - unsigned int j = 0; - for (unsigned int i = index; i < max ; i++) - { - m_pQuads[index] = quads[j]; - index++; - j++; - } - + CCAssert(index + amount <= m_uCapacity, "insertQuadWithTexture: Invalid index + amount"); + + m_uTotalQuads += amount; + + CCAssert( m_uTotalQuads <= m_uCapacity, "invalid totalQuads"); + + // issue #575. index can be > totalQuads + int remaining = (m_uTotalQuads-1) - index - amount; + + // last object doesn't need to be moved + if( remaining > 0) + { + // tex coordinates + memmove( &m_pQuads[index+amount],&m_pQuads[index], sizeof(m_pQuads[0]) * remaining ); + } + + + unsigned int max = index + amount; + unsigned int j = 0; + for (unsigned int i = index; i < max ; i++) + { + m_pQuads[index] = quads[j]; + index++; + j++; + } + m_bDirty = true; } @@ -399,17 +399,17 @@ void CCTextureAtlas::removeQuadAtIndex(unsigned int index) void CCTextureAtlas::removeQuadsAtIndex(unsigned int index, unsigned int amount) { - CCAssert(index + amount <= m_uTotalQuads, "removeQuadAtIndex: index + amount out of bounds"); - - unsigned int remaining = (m_uTotalQuads) - (index + amount); - - m_uTotalQuads -= amount; - - if ( remaining ) - { - memmove( &m_pQuads[index], &m_pQuads[index+amount], sizeof(m_pQuads[0]) * remaining ); - } - + CCAssert(index + amount <= m_uTotalQuads, "removeQuadAtIndex: index + amount out of bounds"); + + unsigned int remaining = (m_uTotalQuads) - (index + amount); + + m_uTotalQuads -= amount; + + if ( remaining ) + { + memmove( &m_pQuads[index], &m_pQuads[index+amount], sizeof(m_pQuads[0]) * remaining ); + } + m_bDirty = true; } @@ -492,58 +492,58 @@ bool CCTextureAtlas::resizeCapacity(unsigned int newCapacity) return true; } -void CCTextureAtlas::increaseTotalQuadsWith(unsigned int amount) -{ - m_uTotalQuads += amount; -} - -void CCTextureAtlas::moveQuadsFromIndex(unsigned int oldIndex, unsigned int amount, unsigned int newIndex) -{ - CCAssert(newIndex + amount <= m_uTotalQuads, "insertQuadFromIndex:atIndex: Invalid index"); - CCAssert(oldIndex < m_uTotalQuads, "insertQuadFromIndex:atIndex: Invalid index"); - - if( oldIndex == newIndex ) - { - return; - } - //create buffer - size_t quadSize = sizeof(ccV3F_C4B_T2F_Quad); - ccV3F_C4B_T2F_Quad* tempQuads = (ccV3F_C4B_T2F_Quad*)malloc( quadSize * amount); - memcpy( tempQuads, &m_pQuads[oldIndex], quadSize * amount ); - - if (newIndex < oldIndex) - { - // move quads from newIndex to newIndex + amount to make room for buffer - memmove( &m_pQuads[newIndex], &m_pQuads[newIndex+amount], (oldIndex-newIndex)*quadSize); - } - else - { - // move quads above back - memmove( &m_pQuads[oldIndex], &m_pQuads[oldIndex+amount], (newIndex-oldIndex)*quadSize); - } - memcpy( &m_pQuads[newIndex], tempQuads, amount*quadSize); - - free(tempQuads); - - m_bDirty = true; -} - -void CCTextureAtlas::moveQuadsFromIndex(unsigned int index, unsigned int newIndex) +void CCTextureAtlas::increaseTotalQuadsWith(unsigned int amount) { - CCAssert(newIndex + (m_uTotalQuads - index) <= m_uCapacity, "moveQuadsFromIndex move is out of bounds"); - + m_uTotalQuads += amount; +} + +void CCTextureAtlas::moveQuadsFromIndex(unsigned int oldIndex, unsigned int amount, unsigned int newIndex) +{ + CCAssert(newIndex + amount <= m_uTotalQuads, "insertQuadFromIndex:atIndex: Invalid index"); + CCAssert(oldIndex < m_uTotalQuads, "insertQuadFromIndex:atIndex: Invalid index"); + + if( oldIndex == newIndex ) + { + return; + } + //create buffer + size_t quadSize = sizeof(ccV3F_C4B_T2F_Quad); + ccV3F_C4B_T2F_Quad* tempQuads = (ccV3F_C4B_T2F_Quad*)malloc( quadSize * amount); + memcpy( tempQuads, &m_pQuads[oldIndex], quadSize * amount ); + + if (newIndex < oldIndex) + { + // move quads from newIndex to newIndex + amount to make room for buffer + memmove( &m_pQuads[newIndex], &m_pQuads[newIndex+amount], (oldIndex-newIndex)*quadSize); + } + else + { + // move quads above back + memmove( &m_pQuads[oldIndex], &m_pQuads[oldIndex+amount], (newIndex-oldIndex)*quadSize); + } + memcpy( &m_pQuads[newIndex], tempQuads, amount*quadSize); + + free(tempQuads); + + m_bDirty = true; +} + +void CCTextureAtlas::moveQuadsFromIndex(unsigned int index, unsigned int newIndex) +{ + CCAssert(newIndex + (m_uTotalQuads - index) <= m_uCapacity, "moveQuadsFromIndex move is out of bounds"); + memmove(m_pQuads + newIndex,m_pQuads + index, (m_uTotalQuads - index) * sizeof(m_pQuads[0])); } void CCTextureAtlas::fillWithEmptyQuadsFromIndex(unsigned int index, unsigned int amount) { - ccV3F_C4B_T2F_Quad quad; - memset(&quad, 0, sizeof(quad)); - - unsigned int to = index + amount; - for (int i = index ; i < to ; i++) - { - m_pQuads[i] = quad; + ccV3F_C4B_T2F_Quad quad; + memset(&quad, 0, sizeof(quad)); + + unsigned int to = index + amount; + for (int i = index ; i < to ; i++) + { + m_pQuads[i] = quad; } } @@ -562,82 +562,82 @@ void CCTextureAtlas::drawNumberOfQuads(unsigned int n) void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start) { if (0 == n) return; - ccGLBindTexture2D( m_pTexture->getName() ); - -#if CC_TEXTURE_ATLAS_USE_VAO - - // - // Using VBO and VAO - // - - // XXX: update is done in draw... perhaps it should be done in a timer - if (m_bDirty) - { - glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); - glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0])*start, sizeof(m_pQuads[0]) * n , &m_pQuads[start] ); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - m_bDirty = false; - } - - glBindVertexArray( m_uVAOname ); - -#if CC_REBIND_INDICES_BUFFER - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); -#endif - -#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP - glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); -#else - glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); -#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP - -#if CC_REBIND_INDICES_BUFFER - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -#endif - - glBindVertexArray(0); - -#else // ! CC_TEXTURE_ATLAS_USE_VAO - - // - // Using VBO without VAO - // - -#define kQuadSize sizeof(m_pQuads[0].bl) - glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); - - // XXX: update is done in draw... perhaps it should be done in a timer - if (m_bDirty) { - glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0])*start, sizeof(m_pQuads[0]) * n , &m_pQuads[start] ); - m_bDirty = false; - } - - ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex ); - - // vertices - glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices)); - - // colors - glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors)); - - // tex coords - glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords)); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); - -#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP - glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); -#else - glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); -#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - -#endif // CC_TEXTURE_ATLAS_USE_VAO - - CC_INCREMENT_GL_DRAWS(1); + ccGLBindTexture2D( m_pTexture->getName() ); + +#if CC_TEXTURE_ATLAS_USE_VAO + + // + // Using VBO and VAO + // + + // XXX: update is done in draw... perhaps it should be done in a timer + if (m_bDirty) + { + glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); + glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0])*start, sizeof(m_pQuads[0]) * n , &m_pQuads[start] ); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + m_bDirty = false; + } + + glBindVertexArray( m_uVAOname ); + +#if CC_REBIND_INDICES_BUFFER + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); +#endif + +#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP + glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); +#else + glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); +#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP + +#if CC_REBIND_INDICES_BUFFER + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +#endif + + glBindVertexArray(0); + +#else // ! CC_TEXTURE_ATLAS_USE_VAO + + // + // Using VBO without VAO + // + +#define kQuadSize sizeof(m_pQuads[0].bl) + glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); + + // XXX: update is done in draw... perhaps it should be done in a timer + if (m_bDirty) { + glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0])*start, sizeof(m_pQuads[0]) * n , &m_pQuads[start] ); + m_bDirty = false; + } + + ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex ); + + // vertices + glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices)); + + // colors + glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors)); + + // tex coords + glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords)); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); + +#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP + glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); +#else + glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); +#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + +#endif // CC_TEXTURE_ATLAS_USE_VAO + + CC_INCREMENT_GL_DRAWS(1); CHECK_GL_ERROR_DEBUG(); } diff --git a/tests/test.android/jni/tests/main.cpp b/tests/test.android/jni/tests/main.cpp index 69d946187c..1177245ee6 100644 --- a/tests/test.android/jni/tests/main.cpp +++ b/tests/test.android/jni/tests/main.cpp @@ -34,8 +34,11 @@ void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thi } else { + ccDrawInit(); + ccGLInvalidateStateCache(); + cocos2d::CCDirector::sharedDirector()->setGLDefaultValues(); + CCShaderCache::sharedShaderCache()->reloadDefaultShaders(); cocos2d::CCTextureCache::reloadAllTextures(); - cocos2d::CCDirector::sharedDirector()->setGLDefaultValues(); } }