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
{
ccDrawInit();
ccGLInvalidateStateCache();
cocos2d::CCDirector::sharedDirector()->setGLDefaultValues();
CCShaderCache::sharedShaderCache()->reloadDefaultShaders();
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);
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

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

View File

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

View File

@ -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
}

View File

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

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,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)

View File

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

View File

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