How to make sprite sepia

Hi all!
The question is in a subject. For now I have a CCMenuItem with two sprites: enabled and disabled. Disabled sprite is similar to enabled, but in a sepia-colors. Can I make that effect in cocos2dx, and not load second sprite from .png?

I don’t say that it is impossible, but you’d have to change each pixel. The best way to do it is to find some image-manipulation library in C++ and use it :slight_smile:

I have solved that task, maybe it can be interesting to someone.

My solution is to create custom shader to apply sepia effect to my sprite.

the sepia.vsh file for vertex shader contains:

attribute vec4 a_position;
attribute vec2 a_texCoord;

#ifdef GL_ES
varying mediump vec2 v_texCoord;
#else
varying vec2 v_texCoord;
#endif

void main()
{
gl_Position = CC_MVPMatrix * a_position;
v_texCoord = a_texCoord;
}

the sepia.fsh file contains:

#ifdef GL_ES
precision mediump float;
#endif

varying vec2 v_texCoord;
uniform sampler2D u_texture;

void main()
{
vec4 normalColor = texture2D(u_texture, v_texCoord);
float r = normalColor.r;
float g = normalColor.g;
float b = normalColor.b;
float sepiaDepth = 17.0;
float sepiaIntensity = 23.0;
if(normalColor.a >= 64.0/255.0)
{
float gray = (0.2 * normalColor.r) + (0.7 * normalColor.g) + (0.1 * normalColor.b);
r = gray+2.0*sepiaDepth/255.0;
if(r>1.0)
r = 1.0;
g = gray+sepiaDepth/255.0;
if(g>1.0)
g = 1.0;

b = gray-sepiaIntensity/255.0;
if(b>1.0)
b = 1.0;
if(b<0.0)
b = 0.0;
}
gl_FragColor = vec4(r, g, b, normalColor.a);
}

It will be ignore opacity pixels, and apply sepia to the others. You can play with parametrs sepiaDepth and sepiaIntensity to increase or decrease effect.

After creating the shaders you woud do something like that in your cocos2d-x code:
CCSprite* pSprite = CCSprite::create("Image.png"); CCGLProgram *shaderProgram_ = new CCGLProgram(); pSprite->setShaderProgram(shaderProgram_); shaderProgram_->initWithVertexShaderFilename("sepia.vsh", "sepia.fsh"); shaderProgram_->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); shaderProgram_->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); shaderProgram_->link(); shaderProgram_->updateUniforms(); pSprite->getShaderProgram()->use();

It can be much easy to use objective-C framework GPUImage on https://github.com/BradLarson/GPUImage , but I don’t want to use entire framework to one small function.

Well it’s nice to know you can use shaders with cocos! Thanks for the snippet, it may prove usefull!