Currently I am toying around with shaders in Cocos2d. My goal is to apply a shader to the entire screen (except one node and it's childnodes) to have an overlay menu while the game is blurred.
Now I found this tutorial to work with shaders in cocos2D which resulted in the following code
CCSprite *aSprite = [CCSprite spriteWithImageNamed:@"Default.png"];
aSprite.contentSizeType = CCSizeTypeNormalized;
aSprite.contentSize = CGSizeMake(0.5,0.5);
NSString *fullPath = [[NSBundle mainBundle] pathForResource:@"CSEEmboss" ofType:@"fsh"];
const GLchar * fragmentSource = (GLchar*) [[NSString stringWithContentsOfFile:fullPath encoding:NSUTF8StringEncoding error:nil] UTF8String];
aSprite.shaderProgram = [[CCGLProgram alloc] initWithVertexShaderByteArray:ccPositionTextureA8Color_vert
fragmentShaderByteArray:fragmentSource];
[aSprite.shaderProgram addAttribute:kCCAttributeNamePosition index:kCCVertexAttrib_Position];
[aSprite.shaderProgram addAttribute:kCCAttributeNameTexCoord index:kCCVertexAttrib_TexCoords];
[aSprite.shaderProgram link];
[aSprite.shaderProgram updateUniforms];
[aSprite.shaderProgram use];
[self.scene addChild:aSprite];
Which indeed applies the emboss to the sprite, however when I add children to that sprite, the shader is not applied there, how should I go about that? My scene contains numerous children and adding and removing the shaders with a loop to every children doesn't seem right to mee.
After some research myself, I think the best way to accomplish this is to use a CCRenderTexture and make a screenshot of the rest of your interface. Then use a blur shader on the CCSprite generated by the Render Texture. You could then position your menu interface above the render texture.
Below is a Cocos-2D Obj-C friendly implementation similar to the one at http://saeedoo.com/?p=644 (Cocos2d-x)
All children nodes of a ShaderNode will be rendered using the given shader.
The shading is done by first rendering all of the children nodes into a CCTextureNode , then rendering that texture with the given shader.
ShaderNode.h
#import "CCNode.h"
@interface ShaderNode : CCNode
-(id)initWithShader:(CCShader*)shader;
@end
ShaderNode.m
#import "ShaderNode.h"
#import "cocos2d.h"
@implementation TRShaderNode
{
CCShader *_shader;
CCRenderTexture *_renderTexture;
CCSprite *_sprite;
}
- (id)initWithShader:(CCShader*)shader {
self = [super init];
if (self) {
NSAssert(shader, @"Shader cannot be nil.");
_shader = shader;
CGSize size = [[CCDirector sharedDirector] viewSize];
_renderTexture = [[CCRenderTexture alloc] initWithWidth:size.width height:size.height pixelFormat:CCTexturePixelFormat_RGBA8888];
_sprite = [[CCSprite alloc] initWithTexture:_renderTexture.texture rect:CGRectMake(0, 0, _renderTexture.texture.contentSize.width, _renderTexture.texture.contentSize.height)];
_sprite.position = CGPointZero;
_sprite.anchorPoint = CGPointZero;
_sprite.shader = _shader;
}
return self;
}
-(void)visit:(CCRenderer *)renderer parentTransform:(const GLKMatrix4 *)parentTransform {
CCRenderer *textureRenderer = [_renderTexture beginWithClear:0 g:0 b:0 a:0];
for (CCNode *node in self.children){
[node visit:textureRenderer parentTransform:parentTransform];
}
[_renderTexture end];
[_sprite visit:renderer parentTransform:parentTransform];
}
@end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.