From b401f6adc1d94bb9743e73f4b0d1d181223316f1 Mon Sep 17 00:00:00 2001 From: Ricardo Quesada Date: Wed, 7 May 2014 20:20:19 -0700 Subject: [PATCH] Lots of new code Adds GLProgramState --- build/cocos2d_libs.xcodeproj/project.pbxproj | 12 + cocos/2d/CCGLProgram.cpp | 112 ++------ cocos/2d/CCGLProgram.h | 21 +- cocos/2d/CCGLProgramState.cpp | 272 ++++++++++++++++++ cocos/2d/CCGLProgramState.h | 166 +++++++++++ cocos/2d/ccGLStateCache.cpp | 60 ++-- .../Classes/ShaderTest/ShaderTest.cpp | 12 +- .../Classes/ShaderTest/ShaderTest2.cpp | 12 +- 8 files changed, 505 insertions(+), 162 deletions(-) create mode 100644 cocos/2d/CCGLProgramState.cpp create mode 100644 cocos/2d/CCGLProgramState.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index a737cca32e..d9fa6f4268 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -1604,6 +1604,10 @@ 500DC9BD19106E89007B91BF /* CCProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 500DC9BA19106E89007B91BF /* CCProfiling.cpp */; }; 500DC9BE19106E89007B91BF /* CCProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 500DC9BB19106E89007B91BF /* CCProfiling.h */; }; 500DC9BF19106E89007B91BF /* CCProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 500DC9BB19106E89007B91BF /* CCProfiling.h */; }; + 500DC9D9191B0175007B91BF /* CCGLProgramState.h in Headers */ = {isa = PBXBuildFile; fileRef = 500DC9D7191B0175007B91BF /* CCGLProgramState.h */; }; + 500DC9DA191B0175007B91BF /* CCGLProgramState.h in Headers */ = {isa = PBXBuildFile; fileRef = 500DC9D7191B0175007B91BF /* CCGLProgramState.h */; }; + 500DC9DB191B0175007B91BF /* CCGLProgramState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 500DC9D8191B0175007B91BF /* CCGLProgramState.cpp */; }; + 500DC9DC191B0175007B91BF /* CCGLProgramState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 500DC9D8191B0175007B91BF /* CCGLProgramState.cpp */; }; 5027253A190BF1B900AAF4ED /* cocos2d.h in Headers */ = {isa = PBXBuildFile; fileRef = 50272538190BF1B900AAF4ED /* cocos2d.h */; }; 5027253B190BF1B900AAF4ED /* cocos2d.h in Headers */ = {isa = PBXBuildFile; fileRef = 50272538190BF1B900AAF4ED /* cocos2d.h */; }; 5027253C190BF1B900AAF4ED /* cocos2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50272539190BF1B900AAF4ED /* cocos2d.cpp */; }; @@ -2682,6 +2686,8 @@ 500DC9B519106E6D007B91BF /* TransformUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformUtils.h; sourceTree = ""; }; 500DC9BA19106E89007B91BF /* CCProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCProfiling.cpp; path = ../base/CCProfiling.cpp; sourceTree = ""; }; 500DC9BB19106E89007B91BF /* CCProfiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CCProfiling.h; path = ../base/CCProfiling.h; sourceTree = ""; }; + 500DC9D7191B0175007B91BF /* CCGLProgramState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCGLProgramState.h; sourceTree = ""; }; + 500DC9D8191B0175007B91BF /* CCGLProgramState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCGLProgramState.cpp; sourceTree = ""; }; 50272538190BF1B900AAF4ED /* cocos2d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cocos2d.h; path = ../cocos/cocos2d.h; sourceTree = ""; }; 50272539190BF1B900AAF4ED /* cocos2d.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cocos2d.cpp; path = ../cocos/cocos2d.cpp; sourceTree = ""; }; 50DC5180187B817900A9C23F /* RELEASE_NOTES.md */ = {isa = PBXFileReference; lastKnownFileType = text; name = RELEASE_NOTES.md; path = ../docs/RELEASE_NOTES.md; sourceTree = ""; }; @@ -3232,6 +3238,8 @@ 1A570238180BCC580088DEC7 /* shaders */ = { isa = PBXGroup; children = ( + 500DC9D7191B0175007B91BF /* CCGLProgramState.h */, + 500DC9D8191B0175007B91BF /* CCGLProgramState.cpp */, 3E9D30DD19195B22008EB309 /* CCVertexAttribBind.cpp */, 3E9D30DE19195B22008EB309 /* CCVertexAttribBind.h */, 1A57052F180BD9500088DEC7 /* CCGLProgram.cpp */, @@ -4921,6 +4929,7 @@ 500DC98C19106300007B91BF /* CCPlatformMacros.h in Headers */, 46A170131807CBFC005B8026 /* CCFileUtilsApple.h in Headers */, 46A1701F1807CBFC005B8026 /* CCImage.h in Headers */, + 500DC9D9191B0175007B91BF /* CCGLProgramState.h in Headers */, 46A170181807CBFC005B8026 /* CCApplicationProtocol.h in Headers */, 1A570063180BC5A10088DEC7 /* CCAction.h in Headers */, 1A570067180BC5A10088DEC7 /* CCActionCamera.h in Headers */, @@ -5417,6 +5426,7 @@ 500DC9AD19106300007B91BF /* ZipUtils.h in Headers */, 50FCEBC218C72017004AD434 /* TextFieldReader.h in Headers */, 1A570068180BC5A10088DEC7 /* CCActionCamera.h in Headers */, + 500DC9DA191B0175007B91BF /* CCGLProgramState.h in Headers */, 1A57006C180BC5A10088DEC7 /* CCActionCatmullRom.h in Headers */, 1A570070180BC5A10088DEC7 /* CCActionEase.h in Headers */, 1A570074180BC5A10088DEC7 /* CCActionGrid.h in Headers */, @@ -6213,6 +6223,7 @@ 1A5702FA180BCE750088DEC7 /* CCTMXXMLParser.cpp in Sources */, 1A570300180BCE890088DEC7 /* CCParallaxNode.cpp in Sources */, 1A570305180BCED90088DEC7 /* ccUtils.cpp in Sources */, + 500DC9DB191B0175007B91BF /* CCGLProgramState.cpp in Sources */, 1A57030C180BCF190088DEC7 /* CCComponent.cpp in Sources */, 500DC96019106300007B91BF /* CCEventListener.cpp in Sources */, 1A570310180BCF190088DEC7 /* CCComponentContainer.cpp in Sources */, @@ -6525,6 +6536,7 @@ 1A01C68F18F57BE800EFE3A6 /* CCDictionary.cpp in Sources */, 06CAAACC186AD7F50012A414 /* TriggerMng.cpp in Sources */, 46A1703D1807CC07005B8026 /* CCCommon.mm in Sources */, + 500DC9DC191B0175007B91BF /* CCGLProgramState.cpp in Sources */, 50FCEBC818C72017004AD434 /* WidgetReader.cpp in Sources */, 46A1702F1807CBFE005B8026 /* CCGLViewProtocol.cpp in Sources */, 46A170FC1807CECB005B8026 /* CCPhysicsBody.cpp in Sources */, diff --git a/cocos/2d/CCGLProgram.cpp b/cocos/2d/CCGLProgram.cpp index 3c0f696024..1df5b0c9b3 100644 --- a/cocos/2d/CCGLProgram.cpp +++ b/cocos/2d/CCGLProgram.cpp @@ -298,22 +298,28 @@ void GLProgram::parseUniforms() // Query uniform info. glGetActiveUniform(_program, i, length, NULL, &uniform._size, &uniform._type, uniformName); uniformName[length] = '\0'; - // remove possible array '[]' from uniform name - if(uniform._size > 1 && length > 3) - { - char* c = strrchr(uniformName, '['); - if(c) - { - *c = '\0'; - } - } - uniform._name = std::string(uniformName); - uniform._location = glGetUniformLocation(_program, uniformName); - - //something wrong, uniform is an object not a pointer, may be released soon - uniform.init(this); - _uniformsDictionary[uniform._name] = uniform; + // Only add uniforms that are not build-in. + // The ones that start with 'CC_' are built-ins + if(strncmp("CC_", uniformName, 3) != 0) { + + // remove possible array '[]' from uniform name + if(uniform._size > 1 && length > 3) + { + char* c = strrchr(uniformName, '['); + if(c) + { + *c = '\0'; + } + } + uniform._name = std::string(uniformName); + uniform._location = glGetUniformLocation(_program, uniformName); + + //something wrong, uniform is an object not a pointer, may be released soon + uniform.init(this); + + _uniformsDictionary[uniform._name] = uniform; + } } } } @@ -907,80 +913,4 @@ bool Uniform::init(GLProgram* program) return program && program && _location != -1; } -bool Uniform::setValue(float value) -{ - CCASSERT (_type == GL_FLOAT, ""); - _program->setUniformLocationWith1f(_location, value); - - return true; -} - -bool Uniform::setValue(int value) -{ - CCASSERT ((_type == GL_INT || _type == GL_SAMPLER_2D), ""); - _program->setUniformLocationWith1i(_location, value); - - return true; -} - -bool Uniform::setValue(const Vector2& value) -{ - CCASSERT (_type == GL_FLOAT_VEC2, ""); - _program->setUniformLocationWith2f(_location, value.x, value.y); - - return true; -} - -bool Uniform::setValue(const Vector3& value) -{ - CCASSERT (_type == GL_FLOAT_VEC3, ""); - _program->setUniformLocationWith3f(_location, value.x, value.y, value.z); - - return true; -} - -bool Uniform::setValue(const Vector4& value) -{ - CCASSERT (_type == GL_FLOAT_VEC4, ""); - _program->setUniformLocationWith4f(_location, value.x, value.y, value.z, value.w); - - return true; -} - -bool Uniform::setValue(const Matrix& value) -{ - CCASSERT(_type == GL_FLOAT_MAT4, ""); - _program->setUniformLocationWithMatrix4fv(_location, value.m, 1); - - return true; -} - -bool Uniform::setValue(const Vector2* value, int count) -{ - CCASSERT (_type == GL_FLOAT_VEC2 && _size == count, ""); - _program->setUniformLocationWith2fv(_location, (GLfloat*)value, count); - return true; -} - -bool Uniform::setValue(const Vector3* value, int count) -{ - CCASSERT (_type == GL_FLOAT_VEC3 && _size == count, ""); - _program->setUniformLocationWith3fv(_location, (GLfloat*)value, count); - return true; -} - -bool Uniform::setValue(const Vector4* value, int count) -{ - CCASSERT (_type == GL_FLOAT_VEC4 && _size == count, ""); - _program->setUniformLocationWith4fv(_location, (GLfloat*)value, count); - return true; -} - -bool Uniform::setValue(const Matrix* value, int count) -{ - CCASSERT (_type == GL_FLOAT_MAT4 && _size == count, ""); - _program->setUniformLocationWithMatrix4fv(_location, (GLfloat*)value, count); - return true; -} - NS_CC_END diff --git a/cocos/2d/CCGLProgram.h b/cocos/2d/CCGLProgram.h index 36f9c67cd6..603af3ec38 100644 --- a/cocos/2d/CCGLProgram.h +++ b/cocos/2d/CCGLProgram.h @@ -32,9 +32,9 @@ THE SOFTWARE. #include "base/ccMacros.h" #include "base/CCRef.h" +#include "base/ccTypes.h" #include "CCGL.h" #include "math/CCMath.h" -#include #include NS_CC_BEGIN @@ -56,6 +56,7 @@ typedef void (*GLLogFunction) (GLuint program, GLsizei bufsize, GLsizei* length, class VertexAttrib { friend class GLProgram; + friend class VertexAttribValue; friend class VertexAttribBind; public: @@ -81,21 +82,13 @@ protected: class Uniform { friend class GLProgram; + friend class UniformValue; public: Uniform(); ~Uniform(); bool init(GLProgram* program); - bool setValue(float value); - bool setValue(int value); - bool setValue(const Vector2& value); - bool setValue(const Vector3& value); - bool setValue(const Vector4& value); - bool setValue(const Matrix& value); - bool setValue(const Vector2* value, int count); - bool setValue(const Vector3* value, int count); - bool setValue(const Vector4* value, int count); - bool setValue(const Matrix* value, int count); + void apply(); protected: GLint _location; @@ -105,7 +98,6 @@ protected: GLProgram* _program; // weak ref }; - /** GLProgram Class that implements a glProgram @@ -114,6 +106,8 @@ protected: */ class CC_DLL GLProgram : public Ref { + friend class GLProgramState; + public: enum { @@ -366,9 +360,6 @@ protected: std::unordered_map _attributesDictionary; }; -// end of shaders group -/// @} - NS_CC_END #endif /* __CCGLPROGRAM_H__ */ diff --git a/cocos/2d/CCGLProgramState.cpp b/cocos/2d/CCGLProgramState.cpp new file mode 100644 index 0000000000..8297a66627 --- /dev/null +++ b/cocos/2d/CCGLProgramState.cpp @@ -0,0 +1,272 @@ +/**************************************************************************** +Copyright 2011 Jeff Lamarche +Copyright 2012 Goffredo Marocchi +Copyright 2012 Ricardo Quesada +Copyright 2012 cocos2d-x.org +Copyright 2013-2014 Chukong Technologies Inc. + +http://www.cocos2d-x.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN false EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +****************************************************************************/ + +#include "2d/CCGLProgramState.h" +#include "2d/CCGLProgram.h" +#include "2d/ccGLStateCache.h" + +NS_CC_BEGIN + +// +// +// UniformValue +// +// + +UniformValue::UniformValue() +: _useCallback(false) +, _uniform(nullptr) +{ +} + +UniformValue::UniformValue(Uniform *uniform) +: _useCallback(false) +, _uniform(uniform) +{ +} + +void UniformValue::apply() +{ + if(_useCallback) { + _value.callback(_uniform); + } + else + { + switch (_uniform->_type) { + case GL_FLOAT: + _uniform->_program->setUniformLocationWith1f(_uniform->_location, _value.floatValue); + break; + + case GL_INT: + case GL_SAMPLER_2D: + _uniform->_program->setUniformLocationWith1i(_uniform->_location, _value.intValue); + break; + + case GL_FLOAT_VEC2: + _uniform->_program->setUniformLocationWith2f(_uniform->_location, _value.v2Value.x, _value.v2Value.y); + break; + + case GL_FLOAT_VEC3: + _uniform->_program->setUniformLocationWith3f(_uniform->_location, _value.v3Value.x, _value.v3Value.y, _value.v3Value.z); + break; + + case GL_FLOAT_VEC4: + _uniform->_program->setUniformLocationWith4f(_uniform->_location, _value.v4Value.x, _value.v4Value.y, _value.v4Value.z, _value.v4Value.w); + break; + + case GL_FLOAT_MAT4: + _uniform->_program->setUniformLocationWithMatrix4fv(_uniform->_location, (GLfloat*)&_value.matrixValue, 1); + break; + + default: + CCASSERT(false, "Invalid UniformValue"); + break; + } + } +} + +void UniformValue::setValue(const std::function callback) +{ + _value.callback = callback; + _useCallback = true; +} + +void UniformValue::setValue(float value) +{ + CCASSERT (_uniform->_type == GL_FLOAT, ""); + _value.floatValue = value; +} + +void UniformValue::setValue(int value) +{ + CCASSERT ((_uniform->_type == GL_INT || _uniform->_type == GL_SAMPLER_2D), ""); + _value.intValue = value; +} + +void UniformValue::setValue(const Vector2& value) +{ + CCASSERT (_uniform->_type == GL_FLOAT_VEC2, ""); + _value.v2Value = value; +} + +void UniformValue::setValue(const Vector3& value) +{ + CCASSERT (_uniform->_type == GL_FLOAT_VEC3, ""); + _value.v3Value = value; +} + +void UniformValue::setValue(const Vector4& value) +{ + CCASSERT (_uniform->_type == GL_FLOAT_VEC4, ""); + _value.v4Value = value; +} + +void UniformValue::setValue(const Matrix& value) +{ + CCASSERT(_uniform->_type == GL_FLOAT_MAT4, ""); + _value.matrixValue = value; +} + +// +// +// VertexAttribValue +// +// + +VertexAttribValue::VertexAttribValue() +: _useCallback(false) +, _vertexAttrib(nullptr) +{ +} + +VertexAttribValue::VertexAttribValue(VertexAttrib *vertexAttrib) +: _useCallback(false) +, _vertexAttrib(vertexAttrib) +{ +} + +void VertexAttribValue::apply() +{ + GL::enableVertexAttribs(0); + + if(_useCallback) { + _value.callback(_vertexAttrib); + } + else + { + glVertexAttribPointer(_vertexAttrib->_index, + _value.pointer.size, + _value.pointer.type, + _value.pointer.normalized, + _value.pointer.stride, + _value.pointer.pointer); + } +} + +void VertexAttribValue::setValue(const std::function callback) +{ + _value.callback = callback; + _useCallback = true; +} + +void VertexAttribValue::setValue(GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLvoid *pointer) +{ + _value.pointer.size = size; + _value.pointer.type = type; + _value.pointer.normalized = normalized; + _value.pointer.stride = stride; + _value.pointer.pointer = pointer; +} + +// +// +// GLProgramState +// +// + +GLProgramState* GLProgramState::create(GLProgram *glprogram) +{ + CCASSERT(glprogram, "invalid shader"); + + auto ret = new (std::nothrow) GLProgramState; + if(ret && ret->init(glprogram)) { + ret->autorelease(); + return ret; + } + CC_SAFE_RELEASE(ret); + return nullptr; +} + +GLProgramState::~GLProgramState() +{ + _glprogram->release(); +} + +bool GLProgramState::init(GLProgram* glprogram) +{ + _glprogram = glprogram; + _glprogram->retain(); + + for(auto &attrib : _glprogram->_attributesDictionary) { + VertexAttribValue value(&attrib.second); + _attributes[attrib.first] = value; + } + + for(auto &uniform : _glprogram->_uniformsDictionary) { + UniformValue value(&uniform.second); + _uniforms[uniform.first] = value; + } + + return true; +} +void GLProgramState::apply() +{ + CCASSERT(_glprogram, "invalid glprogram"); + + // set shader + _glprogram->use(); + + + // set texture + int i = 0; + for(const auto& texture : _textures) { + GL::bindTexture2DN(i++, texture->getName()); + } + + // set blending function + GL::blendFunc(_blendFunc.src, _blendFunc.dst); + + + // set uniforms + for(auto& uniform : _uniforms) { + uniform.second.apply(); + } + + // set attributes + for(auto &attribute : _attributes) { + attribute.second.apply(); + } +} + +UniformValue* GLProgramState::getUniformValue(const std::string &name) +{ + const auto itr = _uniforms.find(name); + if( itr != _uniforms.end()) + return &itr->second; + return nullptr; +} + +VertexAttribValue* GLProgramState::getVertexAttribValue(const std::string &name) +{ + const auto itr = _attributes.find(name); + if( itr != _attributes.end()) + return &itr->second; + return nullptr; +} + +NS_CC_END diff --git a/cocos/2d/CCGLProgramState.h b/cocos/2d/CCGLProgramState.h new file mode 100644 index 0000000000..0c7ab8026b --- /dev/null +++ b/cocos/2d/CCGLProgramState.h @@ -0,0 +1,166 @@ +/**************************************************************************** +Copyright 2014 Chukong Technologies Inc. + +http://www.cocos2d-x.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +****************************************************************************/ + +#ifndef __CCGLPROGRAMSTATE_H__ +#define __CCGLPROGRAMSTATE_H__ + +#include "base/ccTypes.h" +#include "base/CCVector.h" +#include "2d/CCTexture2D.h" +#include "math/Vector2.h" +#include "math/Vector3.h" +#include "math/Vector4.h" + +#include + +NS_CC_BEGIN + +class GLProgram; +class Uniform; +class VertexAttrib; + +// +// +// UniformValue +// +// +class UniformValue +{ + friend class GLProgram; + +public: + UniformValue(); + UniformValue(Uniform *uniform); + ~UniformValue(); + + void setValue(float value); + void setValue(int value); + void setValue(const Vector2& value); + void setValue(const Vector3& value); + void setValue(const Vector4& value); + void setValue(const Matrix& value); + void setValue(const std::function callback); + + void apply(); + +protected: + Uniform* _uniform; // weak ref + bool _useCallback; + + union U{ + float floatValue; + int intValue; + Vector2 v2Value; + Vector3 v3Value; + Vector4 v4Value; + Matrix matrixValue; + std::function callback; + + U() { memset( this, 0, sizeof(*this) ); } + ~U(){} + U& operator=( const U& other ) { + memcpy(this, &other, sizeof(*this)); + return *this; + } + } _value; +}; + +// +// +// VertexAttribValue +// +// +class VertexAttribValue +{ + friend class GLProgram; + +public: + VertexAttribValue(VertexAttrib *vertexAttrib); + VertexAttribValue(); + ~VertexAttribValue(); + + void setValue(GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLvoid *pointer); + void setValue(const std::function callback); + void apply(); + +protected: + VertexAttrib* _vertexAttrib; // weak ref + bool _useCallback; + + union U{ + struct { + GLint size; + GLenum type; + GLboolean normalized; + GLsizei stride; + GLvoid *pointer; + } pointer; + std::function callback; + + U() { memset( this, 0, sizeof(*this) ); } + ~U(){} + U& operator=( const U& other ) { + memcpy(this, &other, sizeof(*this)); + return *this; + } + } _value; +}; + + +// +// +// GLProgramState +// +// +class GLProgramState : public Ref +{ +public: + GLProgramState* create(GLProgram* glprogram); + + void apply(); + void setTexture(Texture2D *texture) { _textures.insert(0, texture); } + Texture2D* getTexture() const { return _textures.at(0); } + + void setBlendFunc(const BlendFunc& blendFunc) { _blendFunc = blendFunc; } + const BlendFunc& getBlendFunc() const { return _blendFunc; } + + UniformValue* getUniformValue(const std::string &uniformName); + VertexAttribValue* getVertexAttribValue(const std::string &attributeName); + +protected: + GLProgramState(); + ~GLProgramState(); + bool init(GLProgram* program); + + std::unordered_map _uniforms; + std::unordered_map _attributes; + + GLProgram *_glprogram; + Vector _textures; + BlendFunc _blendFunc; +}; + +NS_CC_END + +#endif /* __CCGLPROGRAMSTATE_H__ */ diff --git a/cocos/2d/ccGLStateCache.cpp b/cocos/2d/ccGLStateCache.cpp index 82fd077350..466e202189 100644 --- a/cocos/2d/ccGLStateCache.cpp +++ b/cocos/2d/ccGLStateCache.cpp @@ -35,11 +35,9 @@ NS_CC_BEGIN namespace { - static GLuint s_currentProjectionMatrix = -1; - static bool s_vertexAttribPosition = false; - static bool s_vertexAttribColor = false; - static bool s_vertexAttribTexCoords = false; - + static GLuint s_currentProjectionMatrix = -1; + static unsigned int s_attributeFlags = 0; + #if CC_ENABLE_GL_STATE_CACHE #define kMaxActiveTexture 16 @@ -63,10 +61,8 @@ void invalidateStateCache( void ) { Director::getInstance()->resetMatrixStack(); s_currentProjectionMatrix = -1; - s_vertexAttribPosition = false; - s_vertexAttribColor = false; - s_vertexAttribTexCoords = false; - + s_attributeFlags = 0; + #if CC_ENABLE_GL_STATE_CACHE s_currentShaderProgram = -1; for( int i=0; i < kMaxActiveTexture; i++ ) @@ -217,42 +213,20 @@ void bindVAO(GLuint vaoId) void enableVertexAttribs( unsigned int flags ) { bindVAO(0); - - /* Position */ - bool enablePosition = flags & VERTEX_ATTRIB_FLAG_POSITION; - if( enablePosition != s_vertexAttribPosition ) { - if( enablePosition ) - glEnableVertexAttribArray( GLProgram::VERTEX_ATTRIB_POSITION ); - else - glDisableVertexAttribArray( GLProgram::VERTEX_ATTRIB_POSITION ); - - s_vertexAttribPosition = enablePosition; - } - - /* Color */ - bool enableColor = (flags & VERTEX_ATTRIB_FLAG_COLOR) != 0 ? true : false; - - if( enableColor != s_vertexAttribColor ) { - if( enableColor ) - glEnableVertexAttribArray( GLProgram::VERTEX_ATTRIB_COLOR ); - else - glDisableVertexAttribArray( GLProgram::VERTEX_ATTRIB_COLOR ); - - s_vertexAttribColor = enableColor; - } - - /* Tex Coords */ - bool enableTexCoords = (flags & VERTEX_ATTRIB_FLAG_TEX_COORDS) != 0 ? true : false; - - if( enableTexCoords != s_vertexAttribTexCoords ) { - if( enableTexCoords ) - glEnableVertexAttribArray( GLProgram::VERTEX_ATTRIB_TEX_COORDS ); - else - glDisableVertexAttribArray( GLProgram::VERTEX_ATTRIB_TEX_COORDS ); - - s_vertexAttribTexCoords = enableTexCoords; + // hardcoded! + for(int i=0; i < 16; i++) { + unsigned int bit = 1 << i; + bool enabled = flags & bit; + bool enabledBefore = s_attributeFlags & bit; + if(enabled != enabledBefore) { + if( enabled ) + glEnableVertexAttribArray(i); + else + glDisableVertexAttribArray(i); + } } + s_attributeFlags = flags; } // GL Uniforms functions diff --git a/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp b/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp index 077897401f..5a816b4152 100644 --- a/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp +++ b/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp @@ -191,8 +191,9 @@ void ShaderNode::onDraw(const Matrix &transform, bool transformUpdated) shader->use(); shader->setUniformsForBuiltins(transform); - shader->getUniform("center")->setValue(_center); - shader->getUniform("resolution")->setValue(_resolution); + // TODO: riq FIXME +// shader->getUniform("center")->setValue(_center); +// shader->getUniform("resolution")->setValue(_resolution); GL::enableVertexAttribs( cocos2d::GL::VERTEX_ATTRIB_FLAG_POSITION ); @@ -522,9 +523,10 @@ void SpriteBlur::onDraw(const Matrix &transform, bool transformUpdated) program->use(); program->setUniformsForBuiltins(transform); - program->getUniform("onePixelSize")->setValue(_pixelSize); - program->getUniform("gaussianCoefficient")->setValue(Vector4(_samplingRadius, _scale, _cons, _weightSum)); - + // TODO: riq FIXME +// program->getUniform("onePixelSize")->setValue(_pixelSize); +// program->getUniform("gaussianCoefficient")->setValue(Vector4(_samplingRadius, _scale, _cons, _weightSum)); + GL::bindTexture2D( getTexture()->getName()); // diff --git a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp index ce1425acd1..1cfad92cb3 100644 --- a/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp +++ b/tests/cpp-tests/Classes/ShaderTest/ShaderTest2.cpp @@ -760,11 +760,9 @@ void UniformSprite::draw(Renderer *renderer, const Matrix &transform, bool trans void UniformSprite::setCustomUniforms() { - - std::string name = "center"; - _shaderProgram->getUniform(name)->setValue(Vector2(480,320)); - name = "resolution"; - _shaderProgram->getUniform(name)->setValue(Vector2(256,256)); + // FIXME riq TODO +// _shaderProgram->getUniform("center")->setValue(Vector2(480,320)); +// _shaderProgram->getUniform("resolution")->setValue(Vector2(256,256)); } void UniformSprite::onDraw(const Matrix &transform, bool transformUpdated) @@ -843,7 +841,7 @@ void AttribSprite::initShader() auto shader = GLProgram::createWithFilenames(_vertSourceFile, _fragSourceFile); shader->link(); shader->updateUniforms(); - this->setShaderProgram(shader); + this->setShaderProgram(shader); } void AttribSprite::draw(Renderer *renderer, const Matrix &transform, bool transformUpdated) @@ -855,8 +853,6 @@ void AttribSprite::draw(Renderer *renderer, const Matrix &transform, bool transf void AttribSprite::setCustomUniforms() { - - } void AttribSprite::onDraw(const Matrix &transform, bool transformUpdated)