├── Example ├── Classes │ ├── AppDelegate.cpp │ ├── AppDelegate.h │ ├── SimpleShader.cpp │ ├── SimpleShader.h │ ├── SimpleShaderExampleScene.cpp │ └── SimpleShaderExampleScene.h └── Resources │ ├── shaders │ └── simple.fsh │ └── textures │ ├── 1.png │ └── 2.png ├── LICENSE ├── README.md ├── SimpleShader.cpp ├── SimpleShader.h └── example.png /Example/Classes/AppDelegate.cpp: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "SimpleShaderExampleScene.h" 3 | 4 | // #define USE_AUDIO_ENGINE 1 5 | 6 | #if USE_AUDIO_ENGINE 7 | #include "audio/include/AudioEngine.h" 8 | using namespace cocos2d::experimental; 9 | #endif 10 | 11 | USING_NS_CC; 12 | 13 | static cocos2d::Size designResolutionSize = cocos2d::Size(480, 320); 14 | static cocos2d::Size smallResolutionSize = cocos2d::Size(480, 320); 15 | static cocos2d::Size mediumResolutionSize = cocos2d::Size(1024, 768); 16 | static cocos2d::Size largeResolutionSize = cocos2d::Size(2048, 1536); 17 | 18 | AppDelegate::AppDelegate() 19 | { 20 | } 21 | 22 | AppDelegate::~AppDelegate() 23 | { 24 | #if USE_AUDIO_ENGINE 25 | AudioEngine::end(); 26 | #endif 27 | } 28 | 29 | // if you want a different context, modify the value of glContextAttrs 30 | // it will affect all platforms 31 | void AppDelegate::initGLContextAttrs() 32 | { 33 | // set OpenGL context attributes: red,green,blue,alpha,depth,stencil,multisamplesCount 34 | GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8, 0}; 35 | 36 | GLView::setGLContextAttrs(glContextAttrs); 37 | } 38 | 39 | // if you want to use the package manager to install more packages, 40 | // don't modify or remove this function 41 | static int register_all_packages() 42 | { 43 | return 0; //flag for packages manager 44 | } 45 | 46 | bool AppDelegate::applicationDidFinishLaunching() { 47 | // initialize director 48 | auto director = Director::getInstance(); 49 | auto glview = director->getOpenGLView(); 50 | if(!glview) { 51 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) 52 | glview = GLViewImpl::createWithRect("SimpleShaderExample", cocos2d::Rect(0, 0, designResolutionSize.width, designResolutionSize.height)); 53 | #else 54 | glview = GLViewImpl::create("SimpleShaderExample"); 55 | #endif 56 | director->setOpenGLView(glview); 57 | } 58 | 59 | // turn on display FPS 60 | director->setDisplayStats(false); 61 | 62 | // set FPS. the default value is 1.0/60 if you don't call this 63 | director->setAnimationInterval(1.0f / 60); 64 | 65 | // Set the design resolution 66 | glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::NO_BORDER); 67 | auto frameSize = glview->getFrameSize(); 68 | // if the frame's height is larger than the height of medium size. 69 | if (frameSize.height > mediumResolutionSize.height) 70 | { 71 | director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height, largeResolutionSize.width/designResolutionSize.width)); 72 | } 73 | // if the frame's height is larger than the height of small size. 74 | else if (frameSize.height > smallResolutionSize.height) 75 | { 76 | director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height, mediumResolutionSize.width/designResolutionSize.width)); 77 | } 78 | // if the frame's height is smaller than the height of medium size. 79 | else 80 | { 81 | director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height, smallResolutionSize.width/designResolutionSize.width)); 82 | } 83 | 84 | register_all_packages(); 85 | 86 | // create a scene. it's an autorelease object 87 | auto scene = SimpleShaderExample::create(); 88 | 89 | // run 90 | director->runWithScene(scene); 91 | 92 | return true; 93 | } 94 | 95 | // This function will be called when the app is inactive. Note, when receiving a phone call it is invoked. 96 | void AppDelegate::applicationDidEnterBackground() { 97 | Director::getInstance()->stopAnimation(); 98 | 99 | #if USE_AUDIO_ENGINE 100 | AudioEngine::pauseAll(); 101 | #endif 102 | } 103 | 104 | // this function will be called when the app is active again 105 | void AppDelegate::applicationWillEnterForeground() { 106 | Director::getInstance()->startAnimation(); 107 | 108 | #if USE_AUDIO_ENGINE 109 | AudioEngine::resumeAll(); 110 | #endif 111 | } 112 | -------------------------------------------------------------------------------- /Example/Classes/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cocos2d.h" 3 | 4 | /** 5 | @brief The cocos2d Application. 6 | 7 | Private inheritance here hides part of interface from Director. 8 | */ 9 | class AppDelegate : private cocos2d::Application 10 | { 11 | public: 12 | AppDelegate(); 13 | virtual ~AppDelegate(); 14 | 15 | virtual void initGLContextAttrs(); 16 | 17 | /** 18 | @brief Implement Director and Scene init code here. 19 | @return true Initialize success, app continue. 20 | @return false Initialize failed, app terminate. 21 | */ 22 | virtual bool applicationDidFinishLaunching(); 23 | 24 | /** 25 | @brief Called when the application moves to the background 26 | @param the pointer of the application 27 | */ 28 | virtual void applicationDidEnterBackground(); 29 | 30 | /** 31 | @brief Called when the application reenters the foreground 32 | @param the pointer of the application 33 | */ 34 | virtual void applicationWillEnterForeground(); 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /Example/Classes/SimpleShader.cpp: -------------------------------------------------------------------------------- 1 | #include "SimpleShader.h" 2 | 3 | std::string SimpleShader::defaultVert = R"( 4 | attribute vec4 a_position; 5 | attribute vec2 a_texCoord; 6 | attribute vec4 a_color; 7 | 8 | uniform mat4 u_MVPMatrix; 9 | 10 | #ifdef GL_ES 11 | varying lowp vec4 cc_FragColor; 12 | varying mediump vec2 cc_FragTexCoord1; 13 | #else 14 | varying vec4 cc_FragColor; 15 | varying vec2 cc_FragTexCoord1; 16 | #endif 17 | 18 | void main() 19 | { 20 | gl_Position = u_MVPMatrix * a_position; 21 | cc_FragColor = a_color; 22 | cc_FragTexCoord1 = a_texCoord; 23 | } 24 | )"; 25 | 26 | std::string SimpleShader::fragHead = R"( 27 | #ifdef GL_ES 28 | precision lowp float; 29 | #endif 30 | 31 | varying vec4 cc_FragColor; 32 | varying vec2 cc_FragTexCoord1; 33 | 34 | uniform sampler2D u_texture; 35 | uniform float cc_Time; 36 | )"; 37 | 38 | SimpleShader::SimpleShader(const std::string& vertSource, const std::string& fragSource) 39 | { 40 | //create the shader 41 | program = cocos2d::backend::Device::getInstance()->newProgram(vertSource, fragSource); 42 | programState = new cocos2d::backend::ProgramState(program); 43 | 44 | currentTextureSlot = 1; 45 | 46 | //add instance to shader manager 47 | SimpleShaderManager::getInstance()->shaders.push_back(this); 48 | } 49 | 50 | SimpleShader::~SimpleShader() 51 | { 52 | //cleanup 53 | delete programState; 54 | delete program; 55 | 56 | auto& vec = SimpleShaderManager::getInstance()->shaders; 57 | vec.erase(std::remove(vec.begin(), vec.end(), this), vec.end()); 58 | } 59 | 60 | SimpleShader* SimpleShader::createWithFragmentShader(const std::string& fragShaderPath) 61 | { 62 | //custom fragment shader 63 | auto fragSourceRaw = cocos2d::FileUtils::getInstance()->getStringFromFile(fragShaderPath); 64 | 65 | //build full fragment shader 66 | auto fragSource = fragHead + fragSourceRaw; 67 | 68 | return new SimpleShader(defaultVert, fragSource); 69 | } 70 | 71 | SimpleShader* SimpleShader::createWithVertexAndFragmentShader(const std::string& vertShaderPath, const std::string& fragShaderPath) 72 | { 73 | //custom vertex shader 74 | auto vertSource = cocos2d::FileUtils::getInstance()->getStringFromFile(vertShaderPath); 75 | 76 | //custom fragment shader 77 | auto fragSourceRaw = cocos2d::FileUtils::getInstance()->getStringFromFile(fragShaderPath); 78 | 79 | //build full fragment shader 80 | auto fragSource = fragHead + fragSourceRaw; 81 | 82 | return new SimpleShader(vertSource, fragSource); 83 | } 84 | 85 | void SimpleShader::setUniform(std::string uniform, cocos2d::Texture2D* value) 86 | { 87 | //determine texture slot 88 | int slot = currentTextureSlot; 89 | if (textureToSlot.count(uniform) > 0) 90 | { 91 | //texture already has a slot 92 | slot = textureToSlot[uniform]; 93 | } 94 | else 95 | { 96 | //new texture 97 | textureToSlot[uniform] = slot; 98 | currentTextureSlot++; 99 | } 100 | 101 | auto uniformLocation = programState->getUniformLocation(uniform); 102 | programState->setTexture(uniformLocation, slot, value->getBackendTexture()); 103 | } 104 | 105 | 106 | //Simple Shader Manager 107 | SimpleShaderManager::SimpleShaderManager() 108 | { 109 | baseTime = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); 110 | } 111 | 112 | SimpleShaderManager* SimpleShaderManager::getInstance() 113 | { 114 | static auto instance = new SimpleShaderManager(); 115 | 116 | return instance; 117 | } 118 | 119 | void SimpleShaderManager::updateShaderTime() 120 | { 121 | auto milliseconds = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); 122 | float seconds = (milliseconds - baseTime) / 1000.0f; 123 | 124 | for (auto shader : shaders) 125 | { 126 | shader->setUniform("cc_Time", seconds); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /Example/Classes/SimpleShader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cocos2d.h" 3 | #include "renderer/backend/Device.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class SimpleShader 10 | { 11 | private: 12 | static std::string defaultVert; 13 | static std::string fragHead; 14 | 15 | int currentTextureSlot; 16 | std::map textureToSlot; 17 | 18 | public: 19 | cocos2d::backend::Program* program; 20 | cocos2d::backend::ProgramState *programState; 21 | 22 | SimpleShader(const std::string& vertSource, const std::string& fragSource); 23 | ~SimpleShader(); 24 | 25 | static SimpleShader* createWithFragmentShader(const std::string& fragShaderPath); 26 | static SimpleShader* createWithVertexAndFragmentShader(const std::string& vertShaderPath, const std::string& fragShaderPath); 27 | 28 | template 29 | void setUniform(std::string uniform, T value); 30 | void setUniform(std::string uniform, cocos2d::Texture2D* value); 31 | }; 32 | 33 | template 34 | void SimpleShader::setUniform(std::string uniform, T value) 35 | { 36 | auto uniformLocation = programState->getUniformLocation(uniform); 37 | programState->setUniform(uniformLocation, &value, sizeof(value)); 38 | } 39 | 40 | 41 | class SimpleShaderManager 42 | { 43 | private: 44 | unsigned long long baseTime; 45 | std::vector shaders; 46 | 47 | SimpleShaderManager(); 48 | public: 49 | static SimpleShaderManager* getInstance(); 50 | 51 | void updateShaderTime(); 52 | 53 | friend SimpleShader; 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /Example/Classes/SimpleShaderExampleScene.cpp: -------------------------------------------------------------------------------- 1 | #include "SimpleShaderExampleScene.h" 2 | #include "SimpleShader.h" 3 | 4 | USING_NS_CC; 5 | 6 | bool SimpleShaderExample::init() 7 | { 8 | if ( !Scene::init() ) 9 | { 10 | return false; 11 | } 12 | 13 | auto visibleSize = Director::getInstance()->getVisibleSize(); 14 | Vec2 origin = Director::getInstance()->getVisibleOrigin(); 15 | 16 | //create sprite 17 | auto sprite = Sprite::create("textures/1.png"); 18 | 19 | // position the sprite on the center of the screen 20 | sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); 21 | 22 | //create new shader with default vertex shader 23 | auto shader = SimpleShader::createWithFragmentShader("shaders/simple.fsh"); 24 | 25 | //set float uniform 26 | shader->setUniform("speed", 1.0f); 27 | 28 | //set texture uniform (SimpleShader will manage the texture slots for you) 29 | auto tex = Director::getInstance()->getTextureCache()->addImage("textures/2.png"); 30 | shader->setUniform("someTexture", tex); 31 | 32 | //apply shader to a sprite 33 | sprite->setProgramState(shader->programState); 34 | 35 | //add sprite to scene 36 | this->addChild(sprite); 37 | 38 | scheduleUpdate(); 39 | return true; 40 | } 41 | 42 | void SimpleShaderExample::update(float delta) 43 | { 44 | //update cc_Time for all simple shaders 45 | SimpleShaderManager::getInstance()->updateShaderTime(); 46 | } 47 | -------------------------------------------------------------------------------- /Example/Classes/SimpleShaderExampleScene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cocos2d.h" 3 | 4 | class SimpleShaderExample : public cocos2d::Scene 5 | { 6 | public: 7 | virtual bool init(); 8 | virtual void update(float delta); 9 | 10 | // implement the "static create()" method manually 11 | CREATE_FUNC(SimpleShaderExample); 12 | }; 13 | -------------------------------------------------------------------------------- /Example/Resources/shaders/simple.fsh: -------------------------------------------------------------------------------- 1 | uniform sampler2D someTexture; 2 | uniform float speed; 3 | 4 | void main() 5 | { 6 | //u_texture is the sprites original texture 7 | vec4 spritesTexture = texture2D(u_texture, cc_FragTexCoord1); 8 | 9 | //the texture we passed as a uniform 10 | vec4 tex = texture2D(someTexture, cc_FragTexCoord1); 11 | 12 | //a value ocillating between 0 and 1 13 | float mixValue = sin(cc_Time * speed) * 0.5 + 0.5; 14 | 15 | //set final color 16 | gl_FragColor = cc_FragColor * mix(spritesTexture, tex, mixValue); 17 | } -------------------------------------------------------------------------------- /Example/Resources/textures/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JRCocos/SimpleShader/8e3eb13b74b832d11072f1dfd6e70621fef52036/Example/Resources/textures/1.png -------------------------------------------------------------------------------- /Example/Resources/textures/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JRCocos/SimpleShader/8e3eb13b74b832d11072f1dfd6e70621fef52036/Example/Resources/textures/2.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 SmallFont 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SimpleShader 2 | This is a simple utility for creating shaders inside of Cocos2dx 3 | it simplifies the creation and usage of fragment shaders. 4 | 5 | # Usage 6 | ```c++ 7 | //create new shader with default vertex shader 8 | auto shader = SimpleShader::createWithFragmentShader("shaders/simple.fsh"); 9 | 10 | //set float uniform 11 | shader->setUniform("opacity", 0.5f); 12 | 13 | //set texture uniform (SimpleShader will manage the texture slots for you) 14 | auto tex = Director::getInstance()->getTextureCache()->addImage("textures/tex.png"); 15 | shader->setUniform("someTexture", tex); 16 | 17 | //apply shader to a sprite 18 | sprite->setProgramState(shader->programState); 19 | ``` 20 | 21 | # Simpler Fragment Shaders 22 | SimpleShader makes creating custom fragment shaders easier by eliminating boilerplate code, 23 | all you need to do is define your custom uniforms and main function 24 | 25 | ```glsl 26 | uniform sampler2D someTexture; 27 | uniform float opacity; 28 | 29 | void main() 30 | { 31 | //u_texture is the sprites original texture 32 | vec4 spritesTexture = texture2D(u_texture, cc_FragTexCoord1); 33 | 34 | //the texture we passed as a uniform 35 | vec4 tex = texture2D(someTexture, cc_FragTexCoord1); 36 | 37 | gl_FragColor = mix(spritesTexture, tex, opacity); 38 | } 39 | ``` 40 | 41 | ![Example Shader](https://raw.githubusercontent.com/JRCocos/SimpleShader/master/example.png) 42 | 43 | SimpleShader automatically injects these uniforms into your shaders 44 | ```glsl 45 | //the texture of the sprite the shader is applied to 46 | u_texture 47 | 48 | //the texture coordinates 49 | cc_FragTexCoord1 50 | 51 | //the color of the sprite the shader is applied to 52 | cc_FragColor 53 | 54 | //the current time in seconds 55 | cc_Time 56 | ``` 57 | 58 | # Time Based Effects 59 | by default SimpleShader adds a ```cc_Time``` uniform to all fragment shaders for easily creating time based effects, 60 | to update the time uniform for all shaders simply call the ```updateShaderTime``` method on the SimpleShaderManager object in your scenes update method 61 | 62 | ```c++ 63 | //call scheduleUpdate() in your scenes init method to enable update callbacks 64 | virtual void update(float delta) 65 | { 66 | SimpleShaderManager::getInstance()->updateShaderTime(); 67 | } 68 | ``` -------------------------------------------------------------------------------- /SimpleShader.cpp: -------------------------------------------------------------------------------- 1 | #include "SimpleShader.h" 2 | 3 | std::string SimpleShader::defaultVert = R"( 4 | attribute vec4 a_position; 5 | attribute vec2 a_texCoord; 6 | attribute vec4 a_color; 7 | 8 | uniform mat4 u_MVPMatrix; 9 | 10 | #ifdef GL_ES 11 | varying lowp vec4 cc_FragColor; 12 | varying mediump vec2 cc_FragTexCoord1; 13 | #else 14 | varying vec4 cc_FragColor; 15 | varying vec2 cc_FragTexCoord1; 16 | #endif 17 | 18 | void main() 19 | { 20 | gl_Position = u_MVPMatrix * a_position; 21 | cc_FragColor = a_color; 22 | cc_FragTexCoord1 = a_texCoord; 23 | } 24 | )"; 25 | 26 | std::string SimpleShader::fragHead = R"( 27 | #ifdef GL_ES 28 | precision lowp float; 29 | #endif 30 | 31 | varying vec4 cc_FragColor; 32 | varying vec2 cc_FragTexCoord1; 33 | 34 | uniform sampler2D u_texture; 35 | uniform float cc_Time; 36 | )"; 37 | 38 | SimpleShader::SimpleShader(const std::string& vertSource, const std::string& fragSource) 39 | { 40 | //create the shader 41 | program = cocos2d::backend::Device::getInstance()->newProgram(vertSource, fragSource); 42 | programState = new cocos2d::backend::ProgramState(program); 43 | 44 | currentTextureSlot = 1; 45 | 46 | //add instance to shader manager 47 | SimpleShaderManager::getInstance()->shaders.push_back(this); 48 | } 49 | 50 | SimpleShader::~SimpleShader() 51 | { 52 | //cleanup 53 | delete programState; 54 | delete program; 55 | 56 | auto& vec = SimpleShaderManager::getInstance()->shaders; 57 | vec.erase(std::remove(vec.begin(), vec.end(), this), vec.end()); 58 | } 59 | 60 | SimpleShader* SimpleShader::createWithFragmentShader(const std::string& fragShaderPath) 61 | { 62 | //custom fragment shader 63 | auto fragSourceRaw = cocos2d::FileUtils::getInstance()->getStringFromFile(fragShaderPath); 64 | 65 | //build full fragment shader 66 | auto fragSource = fragHead + fragSourceRaw; 67 | 68 | return new SimpleShader(defaultVert, fragSource); 69 | } 70 | 71 | SimpleShader* SimpleShader::createWithVertexAndFragmentShader(const std::string& vertShaderPath, const std::string& fragShaderPath) 72 | { 73 | //custom vertex shader 74 | auto vertSource = cocos2d::FileUtils::getInstance()->getStringFromFile(vertShaderPath); 75 | 76 | //custom fragment shader 77 | auto fragSourceRaw = cocos2d::FileUtils::getInstance()->getStringFromFile(fragShaderPath); 78 | 79 | //build full fragment shader 80 | auto fragSource = fragHead + fragSourceRaw; 81 | 82 | return new SimpleShader(vertSource, fragSource); 83 | } 84 | 85 | void SimpleShader::setUniform(std::string uniform, cocos2d::Texture2D* value) 86 | { 87 | //determine texture slot 88 | int slot = currentTextureSlot; 89 | if (textureToSlot.count(uniform) > 0) 90 | { 91 | //texture already has a slot 92 | slot = textureToSlot[uniform]; 93 | } 94 | else 95 | { 96 | //new texture 97 | textureToSlot[uniform] = slot; 98 | currentTextureSlot++; 99 | } 100 | 101 | auto uniformLocation = programState->getUniformLocation(uniform); 102 | programState->setTexture(uniformLocation, slot, value->getBackendTexture()); 103 | } 104 | 105 | 106 | //Simple Shader Manager 107 | SimpleShaderManager::SimpleShaderManager() 108 | { 109 | baseTime = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); 110 | } 111 | 112 | SimpleShaderManager* SimpleShaderManager::getInstance() 113 | { 114 | static auto instance = new SimpleShaderManager(); 115 | 116 | return instance; 117 | } 118 | 119 | void SimpleShaderManager::updateShaderTime() 120 | { 121 | auto milliseconds = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); 122 | float seconds = (milliseconds - baseTime) / 1000.0f; 123 | 124 | for (auto shader : shaders) 125 | { 126 | shader->setUniform("cc_Time", seconds); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /SimpleShader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cocos2d.h" 3 | #include "renderer/backend/Device.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class SimpleShader 10 | { 11 | private: 12 | static std::string defaultVert; 13 | static std::string fragHead; 14 | 15 | int currentTextureSlot; 16 | std::map textureToSlot; 17 | 18 | public: 19 | cocos2d::backend::Program* program; 20 | cocos2d::backend::ProgramState *programState; 21 | 22 | SimpleShader(const std::string& vertSource, const std::string& fragSource); 23 | ~SimpleShader(); 24 | 25 | static SimpleShader* createWithFragmentShader(const std::string& fragShaderPath); 26 | static SimpleShader* createWithVertexAndFragmentShader(const std::string& vertShaderPath, const std::string& fragShaderPath); 27 | 28 | template 29 | void setUniform(std::string uniform, T value); 30 | void setUniform(std::string uniform, cocos2d::Texture2D* value); 31 | }; 32 | 33 | template 34 | void SimpleShader::setUniform(std::string uniform, T value) 35 | { 36 | auto uniformLocation = programState->getUniformLocation(uniform); 37 | programState->setUniform(uniformLocation, &value, sizeof(value)); 38 | } 39 | 40 | 41 | class SimpleShaderManager 42 | { 43 | private: 44 | unsigned long long baseTime; 45 | std::vector shaders; 46 | 47 | SimpleShaderManager(); 48 | public: 49 | static SimpleShaderManager* getInstance(); 50 | 51 | void updateShaderTime(); 52 | 53 | friend SimpleShader; 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JRCocos/SimpleShader/8e3eb13b74b832d11072f1dfd6e70621fef52036/example.png --------------------------------------------------------------------------------