diff --git a/cocos/2d/CCGLProgram.cpp b/cocos/2d/CCGLProgram.cpp index 6f3bce0f3b..70a5e2d3c5 100644 --- a/cocos/2d/CCGLProgram.cpp +++ b/cocos/2d/CCGLProgram.cpp @@ -84,6 +84,38 @@ const char* GLProgram::ATTRIBUTE_NAME_COLOR = "a_color"; const char* GLProgram::ATTRIBUTE_NAME_POSITION = "a_position"; const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD = "a_texCoord"; +#define CC_GLPROGRAM_MAX_MATERIAL_ID_NUMBER 1024 + +GLProgram::MaterialProgramIDAllocator::MaterialProgramIDAllocator() +{ + for(GLuint id = 1; id < CC_GLPROGRAM_MAX_MATERIAL_ID_NUMBER; ++id) + { + _freeIDs.insert(id); + } +} + +GLProgram::MaterialProgramIDAllocator::~MaterialProgramIDAllocator() +{ + //do nothing +} + +GLuint GLProgram::MaterialProgramIDAllocator::allocID() +{ + CCASSERT(_freeIDs.size()!=0, "There are no allocated ID"); + GLuint id = *(_freeIDs.begin()); + _freeIDs.erase(id); + return id; +} + +void GLProgram::MaterialProgramIDAllocator::freeID(GLuint id) +{ + CCASSERT(_freeIDs.find(id) == _freeIDs.end() && id != 0, "free id is 0 or a duplicated id"); + _freeIDs.insert(id); +} + +GLProgram::MaterialProgramIDAllocator GLProgram::_idAllocator; +const GLuint GLProgram::_maxMaterialIDNumber = CC_GLPROGRAM_MAX_MATERIAL_ID_NUMBER; + GLProgram::GLProgram() : _program(0) , _vertShader(0) @@ -92,10 +124,13 @@ GLProgram::GLProgram() , _flags() { memset(_uniforms, 0, sizeof(_uniforms)); + _materialProgramID = _idAllocator.allocID(); } GLProgram::~GLProgram() { + _idAllocator.freeID(_materialProgramID); + _materialProgramID = 0; CCLOGINFO("%s %d deallocing GLProgram: %p", __FUNCTION__, __LINE__, this); // there is no need to delete the shaders. They should have been already deleted. diff --git a/cocos/2d/CCGLProgram.h b/cocos/2d/CCGLProgram.h index 19c9865f7d..55405a4d45 100644 --- a/cocos/2d/CCGLProgram.h +++ b/cocos/2d/CCGLProgram.h @@ -34,6 +34,7 @@ THE SOFTWARE. #include "CCRef.h" #include "CCGL.h" #include "kazmath/kazmath.h" +#include NS_CC_BEGIN @@ -256,7 +257,7 @@ public: void reset(); inline const GLuint getProgram() const { return _program; } - + inline const GLuint getMaterialProgramID() const { return _materialProgramID; } // DEPRECATED CC_DEPRECATED_ATTRIBUTE bool initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray) { return initWithByteArrays(vShaderByteArray, fShaderByteArray); } @@ -272,6 +273,8 @@ private: std::string logForOpenGLObject(GLuint object, GLInfoFunction infoFunc, GLLogFunction logFunc) const; private: + //ID used for renderer material, _materialProgramID maybe different from _program + GLuint _materialProgramID; GLuint _program; GLuint _vertShader; GLuint _fragShader; @@ -292,6 +295,21 @@ private: // handy way to initialize the bitfield flag_struct() { memset(this, 0, sizeof(*this)); } } _flags; +private: + class MaterialProgramIDAllocator + { + public: + MaterialProgramIDAllocator(); + ~MaterialProgramIDAllocator(); + GLuint allocID(); + void freeID(GLuint id); + private: + std::set _freeIDs; + }; + + static MaterialProgramIDAllocator _idAllocator; +public: + static const GLuint _maxMaterialIDNumber; }; // end of shaders group diff --git a/cocos/2d/renderer/CCQuadCommand.cpp b/cocos/2d/renderer/CCQuadCommand.cpp index 5c75d43665..f4e8317f6e 100644 --- a/cocos/2d/renderer/CCQuadCommand.cpp +++ b/cocos/2d/renderer/CCQuadCommand.cpp @@ -61,9 +61,7 @@ void QuadCommand::generateMaterialID() { //Generate Material ID //TODO fix shader ID generation - CCASSERT(_shader->getProgram() < pow(2,10), "ShaderID is greater than 2^10"); - //TODO fix texture ID generation - CCASSERT(_textureID < pow(2,18), "TextureID is greater than 2^18"); + CCASSERT(_shader->getMaterialProgramID() < GLProgram::_maxMaterialIDNumber, "ShaderID is greater than Id limitation"); //TODO fix blend id generation int blendID = 0; @@ -96,7 +94,7 @@ void QuadCommand::generateMaterialID() // | Shader ID (10 bits) | Blend ID (4 bits) | empty (18bits) | Texture ID (32 bits) | // +---------------------+-------------------+----------------------------------------+ - _materialID = (uint64_t)_shader->getProgram() << 54 + _materialID = (uint64_t)_shader->getMaterialProgramID() << 54 | (uint64_t)blendID << 50 | (uint64_t)_textureID << 0; }