I want to put a “shadow” sprite on a background sprite using the equation:
max(0, Cd*1 - Cs*S)
where Cd is the destination color (that is, a background pixel), Cs is the source color (the shadow pixel) , S is the scale factor (between 0 and 1).
The max() function is used to avoid negative results. This is a lighting effect: when the shadow sprite pixel is 0, there is no effect on the background
pixel, otherwise, the background pixel becomes darker.
Now, the only way that comes to my mind is to change the blending equation to GL_FUNC_SUBTRACT, but it doesn’t compile with cocos2d-x…
I would subclass the CCSprite class in order to implement the draw() method in order to change, when needed,
the blending equation, call the original draw() method and restore the blending equation to its previous state at the end of the method.
So my questions are two:
how to use glBlendEquation() with cocos2d-x? Keep in mind that i am writing a game for iphone/android/windows.
Ok, i have solved this. Subclass the CCSprite class, overload the virtual method draw():
void CMySprite::draw()
{
// is_shadow is true if this sprite is to be considered like a shadow sprite, false otherwise.@
if (is_shadow)
{
ccBlendFunc blend;
// Change the default blending factors to this one.
blend.src = GL_SRC_ALPHA;
blend.dst = GL_ONE;
setBlendFunc( blend );
// Change the blending equation to thi in order to subtract from the values already written in the frame buffer
// the ones of the sprite.
glBlendEquationOES(GL_FUNC_REVERSE_SUBTRACT_OES);
}
CCSprite::draw();
if (is_shadow)
{
// The default blending function of cocos2d-x is GL_FUNC_ADD.
glBlendEquationOES(GL_FUNC_ADD_OES);
}
}
Generally speaking, the glBlendEquationOES() can be used to change the blend equation in order to get different effects. Just remember to
take care of the blending factors…
Maybe this isn’t what you want, but wouldn’t it be easier to have a sprite image which is black. Then draw this sprite with the opacity set like “mySprite->setOpacity(70)”.
That would cast a rectangular shadow image, while the effect i wanted to have is a non-uniform brightness change across the shadow image
(a shadow sprite of constant RGB would be equal to what you say, while a shadow sprite like a 3D gaussian would cast a round-shaped soft
shadow).
In them I made a copy of the car, flipped it upside down, add a layer mask, gradient fill the mask so it becomes more transparent in one direction, then I also skewed it to add some perspective. There are tutorials on the net,
That’s cool! Exactly the effect i wanted to obtain. I render them simply subtracting the shadow from the background (i don’t know if
there are are methods).
@Gav Hey Gav, what’s if I have space for thing inside sprite to translate. That space is by mean to allow its center position to be aligned with other animations as well. In that case, I can’t just track the current position of the sprite and set it to shadow sprite then finally draw in different layer. Because we have no information of current x-position of thing inside its own sprite while’s it’s moving internally.
I created the question here, if you would like to take a look http://cocos2d-x.org/boards/6/topics/23551.