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 <android/log.h>
#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
{
cocos2d::CCTextureCache::reloadAllTextures();
ccDrawInit();
ccGLInvalidateStateCache();
cocos2d::CCDirector::sharedDirector()->setGLDefaultValues();
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
cocos2d::CCTextureCache::reloadAllTextures();
}
}

View File

@ -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);

View File

@ -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 );

View File

@ -140,6 +140,10 @@ public:
/** 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; }
private:

View File

@ -52,6 +52,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;

View File

@ -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");
@ -79,6 +79,7 @@ CCGLProgram::~CCGLProgram()
bool CCGLProgram::initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{
m_uProgram = glCreateProgram();
CHECK_GL_ERROR_DEBUG();
m_uVertShader = m_uFragShader = 0;
@ -101,12 +102,15 @@ 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;
}
@ -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);
@ -373,4 +380,27 @@ void CCGLProgram::setUniformForModelViewProjectionMatrix()
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

View File

@ -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,118 +93,176 @@ void CCShaderCache::loadDefaultShaders()
{
// Position Texture Color shader
CCGLProgram *p = new CCGLProgram();
loadDefaultShader(p, kCCShaderType_PositionTextureColor);
m_pPrograms->setObject(p, kCCShader_PositionTextureColor);
p->release();
// Position Texture Color alpha test
p = new CCGLProgram();
loadDefaultShader(p, kCCShaderType_PositionTextureColorAlphaTest);
m_pPrograms->setObject(p, kCCShader_PositionTextureColorAlphaTest);
p->release();
//
// Position, Color shader
//
p = new CCGLProgram();
loadDefaultShader(p, kCCShaderType_PositionColor);
m_pPrograms->setObject(p, kCCShader_PositionColor);
p->release();
//
// Position Texture shader
//
p = new CCGLProgram();
loadDefaultShader(p, kCCShaderType_PositionTexture);
m_pPrograms->setObject(p, kCCShader_PositionTexture);
p->release();
//
// Position, Texture attribs, 1 Color as uniform shader
//
p = new CCGLProgram();
loadDefaultShader(p, kCCShaderType_PositionTexture_uColor);
m_pPrograms->setObject(p ,kCCShader_PositionTexture_uColor);
p->release();
//
// Position Texture A8 Color shader
//
p = new CCGLProgram();
loadDefaultShader(p, kCCShaderType_PositionTextureA8Color);
m_pPrograms->setObject(p, kCCShader_PositionTextureA8Color);
p->release();
//
// 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()
{
// 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);
p->link();
p->updateUniforms();
m_pPrograms->setObject(p, kCCShader_PositionTextureColor);
p->release();
CHECK_GL_ERROR_DEBUG();
// Position Texture Color alpha test
p = new CCGLProgram();
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);
p->link();
p->updateUniforms();
m_pPrograms->setObject(p, kCCShader_PositionTextureColorAlphaTest);
p->release();
CHECK_GL_ERROR_DEBUG();
//
// Position, Color shader
//
p = new CCGLProgram();
break;
case kCCShaderType_PositionColor:
p->initWithVertexShaderByteArray(ccPositionColor_vert ,ccPositionColor_frag);
p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
p->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
p->link();
p->updateUniforms();
m_pPrograms->setObject(p, kCCShader_PositionColor);
p->release();
CHECK_GL_ERROR_DEBUG();
//
// Position Texture shader
//
p = new CCGLProgram();
break;
case kCCShaderType_PositionTexture:
p->initWithVertexShaderByteArray(ccPositionTexture_vert ,ccPositionTexture_frag);
p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
p->link();
p->updateUniforms();
m_pPrograms->setObject(p, kCCShader_PositionTexture);
p->release();
CHECK_GL_ERROR_DEBUG();
//
// Position, Texture attribs, 1 Color as uniform shader
//
p = new CCGLProgram();
break;
case kCCShaderType_PositionTexture_uColor:
p->initWithVertexShaderByteArray(ccPositionTexture_uColor_vert, ccPositionTexture_uColor_frag);
p->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
p->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
p->link();
p->updateUniforms();
m_pPrograms->setObject(p ,kCCShader_PositionTexture_uColor);
p->release();
CHECK_GL_ERROR_DEBUG();
//
// Position Texture A8 Color shader
//
p = new CCGLProgram();
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);
p->link();
p->updateUniforms();
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();
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();
m_pPrograms->setObject(p, kCCShader_Position_uColor);
p->release();
CHECK_GL_ERROR_DEBUG();
}

View File

@ -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);

View File

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