fixed #1139: fix the bug that screen becomes black when backing to foreground on Android

This commit is contained in:
minggo 2012-04-17 17:55:26 +08:00
parent 1fe71210ed
commit 04c0d794af
10 changed files with 633 additions and 494 deletions

View File

@ -4,6 +4,8 @@
#include <jni.h> #include <jni.h>
#include <android/log.h> #include <android/log.h>
#include "HelloWorldScene.h"
#define LOG_TAG "main" #define LOG_TAG "main"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) #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 else
{ {
ccDrawInit();
ccGLInvalidateStateCache();
cocos2d::CCDirector::sharedDirector()->setGLDefaultValues();
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
cocos2d::CCTextureCache::reloadAllTextures(); cocos2d::CCTextureCache::reloadAllTextures();
cocos2d::CCDirector::sharedDirector()->setGLDefaultValues();
} }
} }

View File

@ -57,11 +57,18 @@ static void lazy_init( void )
shader_ = CCShaderCache::sharedShaderCache()->programForKey(kCCShader_Position_uColor); shader_ = CCShaderCache::sharedShaderCache()->programForKey(kCCShader_Position_uColor);
colorLocation_ = glGetUniformLocation( shader_->getProgram(), "u_color"); colorLocation_ = glGetUniformLocation( shader_->getProgram(), "u_color");
CHECK_GL_ERROR_DEBUG();
pointSizeLocation_ = glGetUniformLocation( shader_->getProgram(), "u_pointSize"); pointSizeLocation_ = glGetUniformLocation( shader_->getProgram(), "u_pointSize");
CHECK_GL_ERROR_DEBUG();
initialized = true; initialized = true;
} }
}
// When back to foreground on android, we want to it to inilialize again
void ccDrawInit()
{
initialized = false;
} }
void ccDrawPoint( const CCPoint& point ) void ccDrawPoint( const CCPoint& point )
@ -132,11 +139,16 @@ void ccDrawLine( const CCPoint& origin, const CCPoint& destination )
}; };
shader_->use(); shader_->use();
CHECK_GL_ERROR_DEBUG();
shader_->setUniformForModelViewProjectionMatrix(); shader_->setUniformForModelViewProjectionMatrix();
CHECK_GL_ERROR_DEBUG();
shader_->setUniformLocationWith4fv(colorLocation_, (GLfloat*) &color_.r, 1); shader_->setUniformLocationWith4fv(colorLocation_, (GLfloat*) &color_.r, 1);
CHECK_GL_ERROR_DEBUG();
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position ); ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
CHECK_GL_ERROR_DEBUG();
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices); glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices);
CHECK_GL_ERROR_DEBUG();
glDrawArrays(GL_LINES, 0, 2); glDrawArrays(GL_LINES, 0, 2);
CC_INCREMENT_GL_DRAWS(1); CC_INCREMENT_GL_DRAWS(1);

View File

@ -49,6 +49,9 @@ THE SOFTWARE.
NS_CC_BEGIN NS_CC_BEGIN
/** initlialize context */
void CC_DLL ccDrawInit();
/** draws a point given x and y coordinate measured in points */ /** draws a point given x and y coordinate measured in points */
void CC_DLL ccDrawPoint( const CCPoint& point ); void CC_DLL ccDrawPoint( const CCPoint& point );

View File

@ -71,11 +71,11 @@ struct _hashUniformEntry;
typedef void (*GLInfoFunction)(GLuint program, GLenum pname, GLint* params); typedef void (*GLInfoFunction)(GLuint program, GLenum pname, GLint* params);
typedef void (*GLLogFunction) (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog); typedef void (*GLLogFunction) (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
/** CCGLProgram /** CCGLProgram
Class that implements a glProgram Class that implements a glProgram
@since v2.0.0 @since v2.0.0
*/ */
class CC_DLL CCGLProgram : public CCObject class CC_DLL CCGLProgram : public CCObject
{ {
@ -84,7 +84,7 @@ public:
CCGLProgram(); CCGLProgram();
virtual ~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); bool initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray);
/** Initializes the CCGLProgram with a vertex and fragment with contents of filenames */ /** Initializes the CCGLProgram with a vertex and fragment with contents of filenames */
bool initWithVertexShaderFilename(const char* vShaderFilename, const char* fShaderFilename); bool initWithVertexShaderFilename(const char* vShaderFilename, const char* fShaderFilename);
@ -103,34 +103,34 @@ public:
*/ */
void updateUniforms(); void updateUniforms();
/** calls glUniform1i only if the values are 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); void setUniformLocationWith1i(unsigned int location, GLint i1);
/** calls glUniform1f only if the values are different than the previous call for this same shader program. */ /** calls glUniform1f only if the values are different than the previous call for this same shader program. */
void setUniformLocationWith1f(unsigned int location, GLfloat f1); void setUniformLocationWith1f(unsigned int location, GLfloat f1);
/** calls glUniform2f only if the values are different than the previous call for this same shader program. */ /** 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); 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. */ /** 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); 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. */ /** 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); 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. */ /** 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); 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. */ /** 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); 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. */ /** 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); 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. */ /** 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); 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. */ /** will update the MVP matrix on the MVP uniform if it is different than the previous call for this same shader program. */
void setUniformForModelViewProjectionMatrix(); void setUniformForModelViewProjectionMatrix();
/** returns the vertexShader error log */ /** returns the vertexShader error log */
@ -139,6 +139,10 @@ public:
const char* fragmentShaderLog(); const char* fragmentShaderLog();
/** returns the program error log */ /** returns the program error log */
const char* programLog(); 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; } inline const GLuint getProgram() { return m_uProgram; }

View File

@ -51,6 +51,9 @@ public:
/** loads the default shaders */ /** loads the default shaders */
void loadDefaultShaders(); void loadDefaultShaders();
/** reload the default shaders */
void reloadDefaultShaders();
/** returns a GL program for a given key */ /** returns a GL program for a given key */
CCGLProgram * programForKey(const char* key); CCGLProgram * programForKey(const char* key);
@ -60,6 +63,7 @@ public:
private: private:
bool init(); bool init();
void loadDefaultShader(CCGLProgram *program, int type);
CCDictionary* m_pPrograms; CCDictionary* m_pPrograms;

View File

@ -29,7 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "CCPlatformMacros.h" #include "CCPlatformMacros.h"
#include "utility.h" #include "utility.h"
struct kmVec3; struct kmVec3;
struct kmMat3; struct kmMat3;
struct kmQuaternion; struct kmQuaternion;
struct kmPlane; struct kmPlane;
@ -38,7 +38,7 @@ struct kmPlane;
A 4x4 matrix A 4x4 matrix
| 0 4 8 12 | | 0 4 8 12 |
mat = | 1 5 9 13 | mat = | 1 5 9 13 |
| 2 6 10 14 | | 2 6 10 14 |
| 3 7 11 15 | | 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 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 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 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 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); CC_DLL struct kmVec3* const kmMat4RotationToAxisAngle(struct kmVec3* pAxis, kmScalar* radians, const kmMat4* pIn);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -31,17 +31,17 @@ THE SOFTWARE.
#include "CCFileUtils.h" #include "CCFileUtils.h"
#include "support/data_support/uthash.h" #include "support/data_support/uthash.h"
#include "CCString.h" #include "CCString.h"
// extern // extern
#include "kazmath/GL/matrix.h" #include "kazmath/GL/matrix.h"
#include "kazmath/kazmath.h" #include "kazmath/kazmath.h"
NS_CC_BEGIN NS_CC_BEGIN
typedef struct _hashUniformEntry typedef struct _hashUniformEntry
{ {
GLvoid* value; // value GLvoid* value; // value
unsigned int location; // Key unsigned int location; // Key
UT_hash_handle hh; // hash entry UT_hash_handle hh; // hash entry
} tHashUniformEntry; } tHashUniformEntry;
CCGLProgram::CCGLProgram() CCGLProgram::CCGLProgram()
@ -55,7 +55,7 @@ CCGLProgram::CCGLProgram()
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. // 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"); CCAssert( m_uVertShader == 0, "Vertex Shaders should have been already deleted");
@ -66,19 +66,20 @@ CCGLProgram::~CCGLProgram()
ccGLDeleteProgram(m_uProgram); ccGLDeleteProgram(m_uProgram);
} }
tHashUniformEntry *current_element, *tmp; tHashUniformEntry *current_element, *tmp;
// Purge uniform hash // Purge uniform hash
HASH_ITER(hh, m_pHashForUniforms, current_element, tmp) { HASH_ITER(hh, m_pHashForUniforms, current_element, tmp) {
HASH_DEL(m_pHashForUniforms, current_element); HASH_DEL(m_pHashForUniforms, current_element);
free(current_element->value); free(current_element->value);
free(current_element); free(current_element);
} }
} }
bool CCGLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray) bool CCGLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{ {
m_uProgram = glCreateProgram(); m_uProgram = glCreateProgram();
CHECK_GL_ERROR_DEBUG();
m_uVertShader = m_uFragShader = 0; m_uVertShader = m_uFragShader = 0;
@ -101,20 +102,23 @@ bool CCGLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray,
if( m_uVertShader ) { if( m_uVertShader ) {
glAttachShader(m_uProgram, m_uVertShader); glAttachShader(m_uProgram, m_uVertShader);
} }
CHECK_GL_ERROR_DEBUG();
if( m_uFragShader ) { if( m_uFragShader ) {
glAttachShader(m_uProgram, m_uFragShader); glAttachShader(m_uProgram, m_uFragShader);
} }
m_pHashForUniforms = NULL; m_pHashForUniforms = NULL;
CHECK_GL_ERROR_DEBUG();
return true; return true;
} }
bool CCGLProgram::initWithVertexShaderFilename(const char* vShaderFilename, const char* fShaderFilename) bool CCGLProgram::initWithVertexShaderFilename(const char* vShaderFilename, const char* fShaderFilename)
{ {
const GLchar * vertexSource = (GLchar*) CCString::stringWithContentsOfFile(CCFileUtils::fullPathFromRelativePath(vShaderFilename))->getCString(); const GLchar * vertexSource = (GLchar*) CCString::stringWithContentsOfFile(CCFileUtils::fullPathFromRelativePath(vShaderFilename))->getCString();
const GLchar * fragmentSource = (GLchar*) CCString::stringWithContentsOfFile(CCFileUtils::fullPathFromRelativePath(fShaderFilename))->getCString(); const GLchar * fragmentSource = (GLchar*) CCString::stringWithContentsOfFile(CCFileUtils::fullPathFromRelativePath(fShaderFilename))->getCString();
return initWithVertexShaderByteArray(vertexSource, fragmentSource); return initWithVertexShaderByteArray(vertexSource, fragmentSource);
} }
@ -132,9 +136,12 @@ bool CCGLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* sour
*shader = glCreateShader(type); *shader = glCreateShader(type);
glShaderSource(*shader, 1, &source, NULL); glShaderSource(*shader, 1, &source, NULL);
CHECK_GL_ERROR_DEBUG();
glCompileShader(*shader); glCompileShader(*shader);
CHECK_GL_ERROR_DEBUG();
glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
CHECK_GL_ERROR_DEBUG();
if( ! status ) { if( ! status ) {
if( type == GL_VERTEX_SHADER ) if( type == GL_VERTEX_SHADER )
@ -169,7 +176,7 @@ bool CCGLProgram::link()
{ {
glLinkProgram(m_uProgram); glLinkProgram(m_uProgram);
#if DEBUG //#if DEBUG
GLint status; GLint status;
glValidateProgram(m_uProgram); glValidateProgram(m_uProgram);
@ -184,7 +191,7 @@ bool CCGLProgram::link()
m_uVertShader = m_uFragShader = m_uProgram = 0; m_uVertShader = m_uFragShader = m_uProgram = 0;
return false; return false;
} }
#endif //#endif
if (m_uVertShader) if (m_uVertShader)
glDeleteShader(m_uVertShader); glDeleteShader(m_uVertShader);
@ -233,144 +240,167 @@ const char* CCGLProgram::programLog()
return this->logForOpenGLObject(m_uProgram, (GLInfoFunction)&glGetProgramiv, (GLLogFunction)&glGetProgramInfoLog); return this->logForOpenGLObject(m_uProgram, (GLInfoFunction)&glGetProgramiv, (GLLogFunction)&glGetProgramInfoLog);
} }
// Uniform cache // Uniform cache
bool CCGLProgram::updateUniformLocation(unsigned int location, GLvoid* data, unsigned int bytes) bool CCGLProgram::updateUniformLocation(unsigned int location, GLvoid* data, unsigned int bytes)
{ {
bool updated = true; bool updated = true;
tHashUniformEntry *element = NULL; tHashUniformEntry *element = NULL;
HASH_FIND_INT(m_pHashForUniforms, &location, element); HASH_FIND_INT(m_pHashForUniforms, &location, element);
if( ! element ) { if( ! element ) {
element = (tHashUniformEntry*)malloc( sizeof(*element) ); element = (tHashUniformEntry*)malloc( sizeof(*element) );
// key // key
element->location = location; element->location = location;
// value // value
element->value = malloc( bytes ); element->value = malloc( bytes );
memcpy(element->value, data, bytes ); memcpy(element->value, data, bytes );
HASH_ADD_INT(m_pHashForUniforms, location, element); HASH_ADD_INT(m_pHashForUniforms, location, element);
} }
else else
{ {
if( memcmp( element->value, data, bytes) == 0 ) if( memcmp( element->value, data, bytes) == 0 )
updated = false; updated = false;
else else
memcpy( element->value, data, bytes ); memcpy( element->value, data, bytes );
} }
return updated; return updated;
} }
void CCGLProgram::setUniformLocationWith1i(unsigned int location, GLint i1) void CCGLProgram::setUniformLocationWith1i(unsigned int location, GLint i1)
{ {
bool updated = updateUniformLocation(location, &i1, sizeof(i1)*1); bool updated = updateUniformLocation(location, &i1, sizeof(i1)*1);
if( updated ) if( updated )
{ {
glUniform1i( (GLint)location, i1); glUniform1i( (GLint)location, i1);
} }
} }
void CCGLProgram::setUniformLocationWith1f(unsigned int location, GLfloat f1) void CCGLProgram::setUniformLocationWith1f(unsigned int location, GLfloat f1)
{ {
bool updated = updateUniformLocation(location, &f1, sizeof(f1)*1); bool updated = updateUniformLocation(location, &f1, sizeof(f1)*1);
if( updated ) if( updated )
{ {
glUniform1f( (GLint)location, f1); glUniform1f( (GLint)location, f1);
} }
} }
void CCGLProgram::setUniformLocationWith2f(unsigned int location, GLfloat f1, GLfloat f2) void CCGLProgram::setUniformLocationWith2f(unsigned int location, GLfloat f1, GLfloat f2)
{ {
GLfloat floats[2] = {f1,f2}; GLfloat floats[2] = {f1,f2};
bool updated = updateUniformLocation(location, floats, sizeof(floats)); bool updated = updateUniformLocation(location, floats, sizeof(floats));
if( updated ) if( updated )
{ {
glUniform2f( (GLint)location, f1, f2); glUniform2f( (GLint)location, f1, f2);
} }
} }
void CCGLProgram::setUniformLocationWith3f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3) void CCGLProgram::setUniformLocationWith3f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3)
{ {
GLfloat floats[3] = {f1,f2,f3}; GLfloat floats[3] = {f1,f2,f3};
bool updated = updateUniformLocation(location, floats, sizeof(floats)); bool updated = updateUniformLocation(location, floats, sizeof(floats));
if( updated ) if( updated )
{ {
glUniform3f( (GLint)location, f1, f2, f3); glUniform3f( (GLint)location, f1, f2, f3);
} }
} }
void CCGLProgram::setUniformLocationWith4f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4) void CCGLProgram::setUniformLocationWith4f(unsigned int location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4)
{ {
GLfloat floats[4] = {f1,f2,f3,f4}; GLfloat floats[4] = {f1,f2,f3,f4};
bool updated = updateUniformLocation(location, floats, sizeof(floats)); bool updated = updateUniformLocation(location, floats, sizeof(floats));
if( updated ) if( updated )
{ {
glUniform4f( (GLint)location, f1, f2, f3,f4); glUniform4f( (GLint)location, f1, f2, f3,f4);
} }
} }
void CCGLProgram::setUniformLocationWith2fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays) void CCGLProgram::setUniformLocationWith2fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays)
{ {
bool updated = updateUniformLocation(location, floats, sizeof(float)*2*numberOfArrays); bool updated = updateUniformLocation(location, floats, sizeof(float)*2*numberOfArrays);
if( updated ) if( updated )
{ {
glUniform2fv( (GLint)location, (GLsizei)numberOfArrays, floats ); glUniform2fv( (GLint)location, (GLsizei)numberOfArrays, floats );
} }
} }
void CCGLProgram::setUniformLocationWith3fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays) void CCGLProgram::setUniformLocationWith3fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays)
{ {
bool updated = updateUniformLocation(location, floats, sizeof(float)*3*numberOfArrays); bool updated = updateUniformLocation(location, floats, sizeof(float)*3*numberOfArrays);
if( updated ) if( updated )
{ {
glUniform3fv( (GLint)location, (GLsizei)numberOfArrays, floats ); glUniform3fv( (GLint)location, (GLsizei)numberOfArrays, floats );
} }
} }
void CCGLProgram::setUniformLocationWith4fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays) void CCGLProgram::setUniformLocationWith4fv(unsigned int location, GLfloat* floats, unsigned int numberOfArrays)
{ {
bool updated = updateUniformLocation(location, floats, sizeof(float)*4*numberOfArrays); bool updated = updateUniformLocation(location, floats, sizeof(float)*4*numberOfArrays);
if( updated ) if( updated )
{ {
glUniform4fv( (GLint)location, (GLsizei)numberOfArrays, floats ); glUniform4fv( (GLint)location, (GLsizei)numberOfArrays, floats );
} }
} }
void CCGLProgram::setUniformLocationwithMatrix4fv(unsigned int location, GLfloat* matrixArray, unsigned int numberOfMatrices) void CCGLProgram::setUniformLocationwithMatrix4fv(unsigned int location, GLfloat* matrixArray, unsigned int numberOfMatrices)
{ {
bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*16*numberOfMatrices); bool updated = updateUniformLocation(location, matrixArray, sizeof(float)*16*numberOfMatrices);
if( updated ) if( updated )
{ {
glUniformMatrix4fv( (GLint)location, (GLsizei)numberOfMatrices, GL_FALSE, matrixArray); glUniformMatrix4fv( (GLint)location, (GLsizei)numberOfMatrices, GL_FALSE, matrixArray);
} }
} }
void CCGLProgram::setUniformForModelViewProjectionMatrix() void CCGLProgram::setUniformForModelViewProjectionMatrix()
{ {
kmMat4 matrixP; kmMat4 matrixP;
kmMat4 matrixMV; kmMat4 matrixMV;
kmMat4 matrixMVP; kmMat4 matrixMVP;
kmGLGetMatrix(KM_GL_PROJECTION, &matrixP ); kmGLGetMatrix(KM_GL_PROJECTION, &matrixP );
kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV ); kmGLGetMatrix(KM_GL_MODELVIEW, &matrixMV );
kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV); kmMat4Multiply(&matrixMVP, &matrixP, &matrixMV);
setUniformLocationwithMatrix4fv(m_uUniforms[kCCUniformMVPMatrix], matrixMVP.mat, 1); 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 NS_CC_END

View File

@ -31,6 +31,26 @@ THE SOFTWARE.
NS_CC_BEGIN 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; static CCShaderCache *_sharedShaderCache = 0;
CCShaderCache* CCShaderCache::sharedShaderCache() CCShaderCache* CCShaderCache::sharedShaderCache()
@ -73,119 +93,177 @@ void CCShaderCache::loadDefaultShaders()
{ {
// Position Texture Color shader // Position Texture Color shader
CCGLProgram *p = new CCGLProgram(); CCGLProgram *p = new CCGLProgram();
p->initWithVertexShaderByteArray(ccPositionTextureColor_vert, ccPositionTextureColor_frag); loadDefaultShader(p, kCCShaderType_PositionTextureColor);
p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
p->link();
p->updateUniforms();
m_pPrograms->setObject(p, kCCShader_PositionTextureColor); m_pPrograms->setObject(p, kCCShader_PositionTextureColor);
p->release(); p->release();
CHECK_GL_ERROR_DEBUG();
// Position Texture Color alpha test // Position Texture Color alpha test
p = new CCGLProgram(); p = new CCGLProgram();
p->initWithVertexShaderByteArray(ccPositionTextureColor_vert, ccPositionTextureColorAlphaTest_frag); loadDefaultShader(p, kCCShaderType_PositionTextureColorAlphaTest);
p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
p->link();
p->updateUniforms();
m_pPrograms->setObject(p, kCCShader_PositionTextureColorAlphaTest); m_pPrograms->setObject(p, kCCShader_PositionTextureColorAlphaTest);
p->release(); p->release();
CHECK_GL_ERROR_DEBUG();
// //
// Position, Color shader // Position, Color shader
// //
p = new CCGLProgram(); p = new CCGLProgram();
p->initWithVertexShaderByteArray(ccPositionColor_vert ,ccPositionColor_frag); loadDefaultShader(p, kCCShaderType_PositionColor);
p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
p->link();
p->updateUniforms();
m_pPrograms->setObject(p, kCCShader_PositionColor); m_pPrograms->setObject(p, kCCShader_PositionColor);
p->release(); p->release();
CHECK_GL_ERROR_DEBUG();
// //
// Position Texture shader // Position Texture shader
// //
p = new CCGLProgram(); p = new CCGLProgram();
p->initWithVertexShaderByteArray(ccPositionTexture_vert ,ccPositionTexture_frag); loadDefaultShader(p, kCCShaderType_PositionTexture);
p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
p->link();
p->updateUniforms();
m_pPrograms->setObject(p, kCCShader_PositionTexture); m_pPrograms->setObject(p, kCCShader_PositionTexture);
p->release(); p->release();
CHECK_GL_ERROR_DEBUG();
// //
// Position, Texture attribs, 1 Color as uniform shader // Position, Texture attribs, 1 Color as uniform shader
// //
p = new CCGLProgram(); p = new CCGLProgram();
p->initWithVertexShaderByteArray(ccPositionTexture_uColor_vert, ccPositionTexture_uColor_frag); loadDefaultShader(p, kCCShaderType_PositionTexture_uColor);
p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
p->link();
p->updateUniforms();
m_pPrograms->setObject(p ,kCCShader_PositionTexture_uColor); m_pPrograms->setObject(p ,kCCShader_PositionTexture_uColor);
p->release(); p->release();
CHECK_GL_ERROR_DEBUG();
// //
// Position Texture A8 Color shader // Position Texture A8 Color shader
// //
p = new CCGLProgram(); p = new CCGLProgram();
p->initWithVertexShaderByteArray(ccPositionTextureA8Color_vert, ccPositionTextureA8Color_frag); loadDefaultShader(p, kCCShaderType_PositionTextureA8Color);
p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); m_pPrograms->setObject(p, kCCShader_PositionTextureA8Color);
p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
p->link();
p->updateUniforms();
m_pPrograms->setObject(p, kCCShader_PositionTextureA8Color);
p->release(); 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();
}
// void CCShaderCache::reloadDefaultShaders()
// Position and 1 color passed as a uniform (to similate glColor4ub ) {
// // reset all programs and reload them
p = new CCGLProgram();
p->initWithVertexShaderByteArray(ccPosition_uColor_vert, ccPosition_uColor_frag); // Position Texture Color shader
CCGLProgram *p = programForKey(kCCShader_PositionTextureColor);
p->addAttribute("aVertex", kCCVertexAttrib_Position); p->reset();
loadDefaultShader(p, kCCShaderType_PositionTextureColor);
p->link();
p->updateUniforms(); // Position Texture Color alpha test
p = programForKey(kCCShader_PositionTextureColorAlphaTest);
m_pPrograms->setObject(p, kCCShader_Position_uColor); p->reset();
p->release(); loadDefaultShader(p, kCCShaderType_PositionTextureColorAlphaTest);
CHECK_GL_ERROR_DEBUG(); //
// 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) CCGLProgram* CCShaderCache::programForKey(const char* key)

View File

@ -28,7 +28,7 @@ THE SOFTWARE.
#include "CCTextureAtlas.h" #include "CCTextureAtlas.h"
#include "CCTextureCache.h" #include "CCTextureCache.h"
#include "ccMacros.h" #include "ccMacros.h"
#include "CCGLProgram.h" #include "CCGLProgram.h"
#include "ccGLStateCache.h" #include "ccGLStateCache.h"
// support // support
#include "CCTexture2D.h" #include "CCTexture2D.h"
@ -50,7 +50,7 @@ CCTextureAtlas::CCTextureAtlas()
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_pQuads);
CC_SAFE_FREE(m_pIndices); CC_SAFE_FREE(m_pIndices);
@ -87,7 +87,7 @@ void CCTextureAtlas::setTexture(CCTexture2D * var)
ccV3F_C4B_T2F_Quad* CCTextureAtlas::getQuads() 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; m_bDirty = true;
return m_pQuads; 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_pQuads, 0, m_uCapacity * sizeof(ccV3F_C4B_T2F_Quad) );
memset( m_pIndices, 0, m_uCapacity * 6 * sizeof(GLushort) ); memset( m_pIndices, 0, m_uCapacity * 6 * sizeof(GLushort) );
this->setupIndices(); this->setupIndices();
#if CC_TEXTURE_ATLAS_USE_VAO #if CC_TEXTURE_ATLAS_USE_VAO
setupVBOandVAO(); setupVBOandVAO();
#else #else
setupVBO(); setupVBO();
#endif #endif
m_bDirty = true; m_bDirty = true;
@ -217,62 +217,62 @@ void CCTextureAtlas::setupIndices()
#endif #endif
} }
} }
//TextureAtlas - VAO / VBO specific //TextureAtlas - VAO / VBO specific
#if CC_TEXTURE_ATLAS_USE_VAO #if CC_TEXTURE_ATLAS_USE_VAO
void CCTextureAtlas::setupVBOandVAO() void CCTextureAtlas::setupVBOandVAO()
{ {
glGenVertexArrays(1, &m_uVAOname); glGenVertexArrays(1, &m_uVAOname);
glBindVertexArray(m_uVAOname); glBindVertexArray(m_uVAOname);
#define kQuadSize sizeof(m_pQuads[0].bl) #define kQuadSize sizeof(m_pQuads[0].bl)
glGenBuffers(2, &m_pBuffersVBO[0]); glGenBuffers(2, &m_pBuffersVBO[0]);
glBindBuffer(GL_ARRAY_BUFFER, 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); glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW);
// vertices // vertices
glEnableVertexAttribArray(kCCVertexAttrib_Position); glEnableVertexAttribArray(kCCVertexAttrib_Position);
glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices)); glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices));
// colors // colors
glEnableVertexAttribArray(kCCVertexAttrib_Color); glEnableVertexAttribArray(kCCVertexAttrib_Color);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors)); glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors));
// tex coords // tex coords
glEnableVertexAttribArray(kCCVertexAttrib_TexCoords); glEnableVertexAttribArray(kCCVertexAttrib_TexCoords);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords)); glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); 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); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_pIndices[0]) * m_uCapacity * 6, m_pIndices, GL_STATIC_DRAW);
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
CHECK_GL_ERROR_DEBUG(); CHECK_GL_ERROR_DEBUG();
} }
#else // CC_TEXTURE_ATLAS_USE_VAO #else // CC_TEXTURE_ATLAS_USE_VAO
void CCTextureAtlas::setupVBO() void CCTextureAtlas::setupVBO()
{ {
glGenBuffers(2, &m_pBuffersVBO[0]); glGenBuffers(2, &m_pBuffersVBO[0]);
mapBuffers(); mapBuffers();
} }
#endif // ! // CC_TEXTURE_ATLAS_USE_VAO #endif // ! // CC_TEXTURE_ATLAS_USE_VAO
void CCTextureAtlas::mapBuffers() void CCTextureAtlas::mapBuffers()
{ {
glBindBuffer(GL_ARRAY_BUFFER, 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); glBufferData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0]) * m_uCapacity, m_pQuads, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); 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); 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_ELEMENT_ARRAY_BUFFER, 0);
CHECK_GL_ERROR_DEBUG(); 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) void CCTextureAtlas::insertQuads(ccV3F_C4B_T2F_Quad* quads, unsigned int index, unsigned int amount)
{ {
CCAssert(index + amount <= m_uCapacity, "insertQuadWithTexture: Invalid index + amount"); CCAssert(index + amount <= m_uCapacity, "insertQuadWithTexture: Invalid index + amount");
m_uTotalQuads += amount; m_uTotalQuads += amount;
CCAssert( m_uTotalQuads <= m_uCapacity, "invalid totalQuads"); CCAssert( m_uTotalQuads <= m_uCapacity, "invalid totalQuads");
// issue #575. index can be > totalQuads // issue #575. index can be > totalQuads
int remaining = (m_uTotalQuads-1) - index - amount; int remaining = (m_uTotalQuads-1) - index - amount;
// last object doesn't need to be moved // last object doesn't need to be moved
if( remaining > 0) if( remaining > 0)
{ {
// tex coordinates // tex coordinates
memmove( &m_pQuads[index+amount],&m_pQuads[index], sizeof(m_pQuads[0]) * remaining ); memmove( &m_pQuads[index+amount],&m_pQuads[index], sizeof(m_pQuads[0]) * remaining );
} }
unsigned int max = index + amount; unsigned int max = index + amount;
unsigned int j = 0; unsigned int j = 0;
for (unsigned int i = index; i < max ; i++) for (unsigned int i = index; i < max ; i++)
{ {
m_pQuads[index] = quads[j]; m_pQuads[index] = quads[j];
index++; index++;
j++; j++;
} }
m_bDirty = true; m_bDirty = true;
} }
@ -399,17 +399,17 @@ void CCTextureAtlas::removeQuadAtIndex(unsigned int index)
void CCTextureAtlas::removeQuadsAtIndex(unsigned int index, unsigned int amount) void CCTextureAtlas::removeQuadsAtIndex(unsigned int index, unsigned int amount)
{ {
CCAssert(index + amount <= m_uTotalQuads, "removeQuadAtIndex: index + amount out of bounds"); CCAssert(index + amount <= m_uTotalQuads, "removeQuadAtIndex: index + amount out of bounds");
unsigned int remaining = (m_uTotalQuads) - (index + amount); unsigned int remaining = (m_uTotalQuads) - (index + amount);
m_uTotalQuads -= amount; m_uTotalQuads -= amount;
if ( remaining ) if ( remaining )
{ {
memmove( &m_pQuads[index], &m_pQuads[index+amount], sizeof(m_pQuads[0]) * remaining ); memmove( &m_pQuads[index], &m_pQuads[index+amount], sizeof(m_pQuads[0]) * remaining );
} }
m_bDirty = true; m_bDirty = true;
} }
@ -492,58 +492,58 @@ bool CCTextureAtlas::resizeCapacity(unsigned int newCapacity)
return true; return true;
} }
void CCTextureAtlas::increaseTotalQuadsWith(unsigned int amount) 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)
{ {
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])); memmove(m_pQuads + newIndex,m_pQuads + index, (m_uTotalQuads - index) * sizeof(m_pQuads[0]));
} }
void CCTextureAtlas::fillWithEmptyQuadsFromIndex(unsigned int index, unsigned int amount) void CCTextureAtlas::fillWithEmptyQuadsFromIndex(unsigned int index, unsigned int amount)
{ {
ccV3F_C4B_T2F_Quad quad; ccV3F_C4B_T2F_Quad quad;
memset(&quad, 0, sizeof(quad)); memset(&quad, 0, sizeof(quad));
unsigned int to = index + amount; unsigned int to = index + amount;
for (int i = index ; i < to ; i++) for (int i = index ; i < to ; i++)
{ {
m_pQuads[i] = quad; m_pQuads[i] = quad;
} }
} }
@ -562,82 +562,82 @@ void CCTextureAtlas::drawNumberOfQuads(unsigned int n)
void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start) void CCTextureAtlas::drawNumberOfQuads(unsigned int n, unsigned int start)
{ {
if (0 == n) return; if (0 == n) return;
ccGLBindTexture2D( m_pTexture->getName() ); ccGLBindTexture2D( m_pTexture->getName() );
#if CC_TEXTURE_ATLAS_USE_VAO #if CC_TEXTURE_ATLAS_USE_VAO
// //
// Using VBO and VAO // Using VBO and VAO
// //
// XXX: update is done in draw... perhaps it should be done in a timer // XXX: update is done in draw... perhaps it should be done in a timer
if (m_bDirty) if (m_bDirty)
{ {
glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0])*start, sizeof(m_pQuads[0]) * n , &m_pQuads[start] ); glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0])*start, sizeof(m_pQuads[0]) * n , &m_pQuads[start] );
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
m_bDirty = false; m_bDirty = false;
} }
glBindVertexArray( m_uVAOname ); glBindVertexArray( m_uVAOname );
#if CC_REBIND_INDICES_BUFFER #if CC_REBIND_INDICES_BUFFER
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
#endif #endif
#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP #if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) );
#else #else
glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) );
#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP #endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
#if CC_REBIND_INDICES_BUFFER #if CC_REBIND_INDICES_BUFFER
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif #endif
glBindVertexArray(0); glBindVertexArray(0);
#else // ! CC_TEXTURE_ATLAS_USE_VAO #else // ! CC_TEXTURE_ATLAS_USE_VAO
// //
// Using VBO without VAO // Using VBO without VAO
// //
#define kQuadSize sizeof(m_pQuads[0].bl) #define kQuadSize sizeof(m_pQuads[0].bl)
glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]); glBindBuffer(GL_ARRAY_BUFFER, m_pBuffersVBO[0]);
// XXX: update is done in draw... perhaps it should be done in a timer // XXX: update is done in draw... perhaps it should be done in a timer
if (m_bDirty) { if (m_bDirty) {
glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0])*start, sizeof(m_pQuads[0]) * n , &m_pQuads[start] ); glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_pQuads[0])*start, sizeof(m_pQuads[0]) * n , &m_pQuads[start] );
m_bDirty = false; m_bDirty = false;
} }
ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex ); ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex );
// vertices // vertices
glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices)); glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, vertices));
// colors // colors
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors)); glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, colors));
// tex coords // tex coords
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords)); glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof( ccV3F_C4B_T2F, texCoords));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1]);
#if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP #if CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); glDrawElements(GL_TRIANGLE_STRIP, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) );
#else #else
glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) ); glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(m_pIndices[0])) );
#endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP #endif // CC_TEXTURE_ATLAS_USE_TRIANGLE_STRIP
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
#endif // CC_TEXTURE_ATLAS_USE_VAO #endif // CC_TEXTURE_ATLAS_USE_VAO
CC_INCREMENT_GL_DRAWS(1); CC_INCREMENT_GL_DRAWS(1);
CHECK_GL_ERROR_DEBUG(); CHECK_GL_ERROR_DEBUG();
} }

View File

@ -34,8 +34,11 @@ void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thi
} }
else else
{ {
ccDrawInit();
ccGLInvalidateStateCache();
cocos2d::CCDirector::sharedDirector()->setGLDefaultValues();
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
cocos2d::CCTextureCache::reloadAllTextures(); cocos2d::CCTextureCache::reloadAllTextures();
cocos2d::CCDirector::sharedDirector()->setGLDefaultValues();
} }
} }