@Obg1 Thanks for replying RenderTexture will first render our whole scene in a buffer then pass it to our GL programme to give us visual output but that definitely looks like a costly procedure , can you please tag a guy who can give more light on this procedure
What does your scene consist of? If Sprites are created for every rendered aspect of the scene then you are probably best off using this graySprite method, or deriving a new class from Sprite and adding the shader in init() and then using this sprite class instead of Sprite::create you would use GraySprite::create.
I think that if you want to gray-scale UI and other aspects of the scene that are rendered using different shaders by default then the Render Texture is really the only good option. The simplest approach would be to setup a frame buffer object (FBO) and have the main camera render to this FBO. Then create a second identical camera that renders only a sprite using the FBO as the texture. You could render everything into a RenderTexture directly, but this would likely require changes to your more new/modified code than the camera method.
Note that it will be more costly to render a post-processed image because you have to render all the sprites once before hand and the cost for rendering a default colored sprite is basically the same as rendering each sprite using a gray-scale shader. There is a cost, but higher-end mobile devices (or desktops) it should be negligible. YMMV.
This is my first implementation of what you suggested, inspired by the test. Seems like it works. Just adding a second camera with a new fbo worked too but it caused everything to draw twice, seems like doing things this way doesn’t do that. I don’t understand much of what I wrote but it works, thanks @stevetranby
cocos2d::GLProgram* program = cocos2d::GLProgram::createWithFilenames(
"shaders/bloom.vert",
"shaders/bloom.frag"
);
if (program)
{
program->link();
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
cocos2d::experimental::FrameBuffer* fbo = cocos2d::experimental::FrameBuffer::getOrCreateDefaultFBO(glview);
auto render_target = fbo->getRenderTarget();
const cocos2d::Size size = cocos2d::Director::getInstance()->getWinSizeInPixels();
cocos2d::experimental::FrameBuffer* frameBuffer = cocos2d::experimental::FrameBuffer::create(1, (unsigned)size.width, (unsigned)size.height);
cocos2d::experimental::RenderTarget* renderTarget = cocos2d::experimental::RenderTarget::create((unsigned)size.width, (unsigned)size.height);
cocos2d::Camera* default_camera = cocos2d::Camera::getDefaultCamera();
frameBuffer->attachRenderTarget(renderTarget);
default_camera->setFrameBufferObject(frameBuffer);
cocos2d::Camera* second_camera = cocos2d::Camera::create();
//pretty sure this means that the only thing this camera will see if stuff masked with USER1
second_camera->setCameraFlag(cocos2d::CameraFlag::USER1);
//second_camera->setDepth(-1);
GET_RUNNING_SCENE()->addChild(second_camera);
cocos2d::Texture2D* texture = frameBuffer->getRenderTarget()->getTexture();
cocos2d::Sprite* sprite = cocos2d::Sprite::createWithTexture(texture);
sprite->setGLProgram(program);
sprite->setFlippedY(true);
sprite->setPosition(get_center_pos());
sprite->setGlobalZOrder(15);
sprite->setCameraMask((unsigned short)cocos2d::CameraFlag::USER1);
GET_RUNNING_SCENE()->addChild(sprite);
CCLOG("shader success");
}
else
{
CCLOG("\n\nglimmer shader failed!!!!!");
}
Haha, sorry for the multiple deleted posts, I just realized that you said that it is in fact working for you with your code. I was going to offer how to try and fix duplicate drawing issues. Let me know if you are experiencing issues still.