diff --git a/cocos/renderer/CCGLProgramState.cpp b/cocos/renderer/CCGLProgramState.cpp index 4341cbe4ba..990ee30182 100644 --- a/cocos/renderer/CCGLProgramState.cpp +++ b/cocos/renderer/CCGLProgramState.cpp @@ -497,9 +497,21 @@ void GLProgramState::setUniformTexture(const std::string &uniformName, GLuint te { auto v = getUniformValue(uniformName); if (v) - v->setTexture(textureId, _textureUnitIndex++); + { + if (_boundTextureUnits.find(uniformName) != _boundTextureUnits.end()) + { + v->setTexture(textureId, _boundTextureUnits[uniformName]); + } + else + { + v->setTexture(textureId, _textureUnitIndex); + _boundTextureUnits[uniformName] = _textureUnitIndex++; + } + } else + { CCLOG("cocos2d: warning: Uniform not found: %s", uniformName.c_str()); + } } diff --git a/cocos/renderer/CCGLProgramState.h b/cocos/renderer/CCGLProgramState.h index 019cd95222..833214116d 100644 --- a/cocos/renderer/CCGLProgramState.h +++ b/cocos/renderer/CCGLProgramState.h @@ -191,6 +191,7 @@ protected: bool _uniformAttributeValueDirty; std::unordered_map _uniforms; std::unordered_map _attributes; + std::unordered_map _boundTextureUnits; int _textureUnitIndex; uint32_t _vertexAttribsFlags; diff --git a/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp b/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp index 12a4c9d158..9aa84d87e0 100644 --- a/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp +++ b/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp @@ -732,7 +732,7 @@ bool ShaderGlow::init() // // ShaderMultiTexture // -ShaderMultiTexture::ShaderMultiTexture() +ShaderMultiTexture::ShaderMultiTexture():_changedTextureId(0) { init(); } @@ -785,27 +785,31 @@ bool ShaderMultiTexture::init() // Right: normal sprite auto right = Sprite::create("Images/grossinis_sister2.png"); - addChild(right); + addChild(right, 0, rightSpriteTag); right->setPosition(s.width*3/4, s.height/2); // Center: MultiTexture - _sprite = Sprite::create("Images/grossinis_sister1.png"); - Texture2D *texture1 = Director::getInstance()->getTextureCache()->addImage("Images/grossinis_sister2.png"); - + _sprite = Sprite::createWithTexture(left->getTexture()); addChild(_sprite); - _sprite->setPosition(Vec2(s.width/2, s.height/2)); auto glprogram = GLProgram::createWithFilenames("Shaders/example_MultiTexture.vsh", "Shaders/example_MultiTexture.fsh"); auto glprogramstate = GLProgramState::getOrCreateWithGLProgram(glprogram); _sprite->setGLProgramState(glprogramstate); - glprogramstate->setUniformTexture("u_texture1", texture1); + glprogramstate->setUniformTexture("u_texture1", right->getTexture()); glprogramstate->setUniformFloat("u_interpolate",0.5); // slider createSliderCtl(); + + // menu + auto label = Label::createWithTTF(TTFConfig("fonts/arial.ttf"), "change"); + auto mi = MenuItemLabel::create(label, CC_CALLBACK_1(ShaderMultiTexture::changeTexture, this)); + auto menu = Menu::create(mi, nullptr); + addChild(menu); + menu->setPosition(s.width * 7 / 8, s.height / 2); return true; } @@ -813,6 +817,21 @@ bool ShaderMultiTexture::init() return false; } +void ShaderMultiTexture::changeTexture(Ref*) +{ + static const int textureFilesCount = 3; + static const std::string textureFiles[textureFilesCount] = { + "Images/grossini.png", + "Images/grossinis_sister1.png", + "Images/grossinis_sister2.png" + }; + auto textrue = Director::getInstance()->getTextureCache()->addImage(textureFiles[_changedTextureId++ % textureFilesCount]); + Sprite* right = dynamic_cast(getChildByTag(rightSpriteTag)); + right->setTexture(textrue); + auto programState = _sprite->getGLProgramState(); + programState->setUniformTexture("u_texture1", right->getTexture()); +} + ///--------------------------------------- // diff --git a/tests/cpp-tests/Classes/ShaderTest/ShaderTest.h b/tests/cpp-tests/Classes/ShaderTest/ShaderTest.h index 9ab01be773..798466dae1 100644 --- a/tests/cpp-tests/Classes/ShaderTest/ShaderTest.h +++ b/tests/cpp-tests/Classes/ShaderTest/ShaderTest.h @@ -166,9 +166,12 @@ public: class ShaderMultiTexture : public ShaderTestDemo { + static const int rightSpriteTag = 2014; public: ShaderMultiTexture(); ui::Slider* createSliderCtl(); + void changeTexture(Ref*); + int _changedTextureId; Sprite *_sprite; virtual std::string title() const override;