Sprite: Add special case shader for translucent effect

Translucent sprites (opacity < 255) are very common,
so using a custom shader instead of the full blown effect one
helps a lot, especially on mobile.
This commit is contained in:
Jonas Kulla 2014-12-23 17:52:32 +01:00
parent a53163660f
commit 3c0a530eba
6 changed files with 58 additions and 1 deletions

View File

@ -220,6 +220,7 @@ set(EMBEDDED_INPUT
shader/simple.frag shader/simple.frag
shader/simpleColor.frag shader/simpleColor.frag
shader/simpleAlpha.frag shader/simpleAlpha.frag
shader/simpleAlphaUni.frag
shader/flashMap.frag shader/flashMap.frag
shader/simple.vert shader/simple.vert
shader/simpleColor.vert shader/simpleColor.vert

View File

@ -193,6 +193,7 @@ EMBED = \
shader/simple.frag \ shader/simple.frag \
shader/simpleColor.frag \ shader/simpleColor.frag \
shader/simpleAlpha.frag \ shader/simpleAlpha.frag \
shader/simpleAlphaUni.frag \
shader/flashMap.frag \ shader/flashMap.frag \
shader/simple.vert \ shader/simple.vert \
shader/simpleColor.vert \ shader/simpleColor.vert \

View File

@ -0,0 +1,11 @@
uniform sampler2D texture;
uniform lowp float alpha;
varying vec2 v_texCoord;
void main()
{
gl_FragColor = texture2D(texture, v_texCoord);
gl_FragColor.a *= alpha;
}

View File

@ -38,6 +38,7 @@
#include "simple.frag.xxd" #include "simple.frag.xxd"
#include "simpleColor.frag.xxd" #include "simpleColor.frag.xxd"
#include "simpleAlpha.frag.xxd" #include "simpleAlpha.frag.xxd"
#include "simpleAlphaUni.frag.xxd"
#include "flashMap.frag.xxd" #include "flashMap.frag.xxd"
#include "simple.vert.xxd" #include "simple.vert.xxd"
#include "simpleColor.vert.xxd" #include "simpleColor.vert.xxd"
@ -314,6 +315,27 @@ void SimpleSpriteShader::setSpriteMat(const float value[16])
} }
AlphaSpriteShader::AlphaSpriteShader()
{
INIT_SHADER(sprite, simpleAlphaUni, AlphaSpriteShader);
ShaderBase::init();
GET_U(spriteMat);
GET_U(alpha);
}
void AlphaSpriteShader::setSpriteMat(const float value[16])
{
gl.UniformMatrix4fv(u_spriteMat, 1, GL_FALSE, value);
}
void AlphaSpriteShader::setAlpha(float value)
{
gl.Uniform1f(u_alpha, value);
}
TransShader::TransShader() TransShader::TransShader()
{ {
INIT_SHADER(simple, trans, TransShader); INIT_SHADER(simple, trans, TransShader);

View File

@ -121,6 +121,18 @@ private:
GLint u_spriteMat; GLint u_spriteMat;
}; };
class AlphaSpriteShader : public ShaderBase
{
public:
AlphaSpriteShader();
void setSpriteMat(const float value[16]);
void setAlpha(float value);
private:
GLint u_spriteMat, u_alpha;
};
class TransShader : public ShaderBase class TransShader : public ShaderBase
{ {
public: public:
@ -277,6 +289,7 @@ struct ShaderSet
SimpleColorShader simpleColor; SimpleColorShader simpleColor;
SimpleAlphaShader simpleAlpha; SimpleAlphaShader simpleAlpha;
SimpleSpriteShader simpleSprite; SimpleSpriteShader simpleSprite;
AlphaSpriteShader alphaSprite;
SpriteShader sprite; SpriteShader sprite;
PlaneShader plane; PlaneShader plane;
TilemapShader tilemap; TilemapShader tilemap;

View File

@ -515,7 +515,6 @@ void Sprite::draw()
bool renderEffect = p->color->hasEffect() || bool renderEffect = p->color->hasEffect() ||
p->tone->hasEffect() || p->tone->hasEffect() ||
p->opacity != 255 ||
flashing || flashing ||
p->bushDepth != 0; p->bushDepth != 0;
@ -541,6 +540,16 @@ void Sprite::draw()
base = &shader; base = &shader;
} }
else if (p->opacity != 255)
{
AlphaSpriteShader &shader = shState->shaders().alphaSprite;
shader.bind();
shader.setSpriteMat(p->trans.getMatrix());
shader.setAlpha(p->opacity.norm);
shader.applyViewportProj();
base = &shader;
}
else else
{ {
SimpleSpriteShader &shader = shState->shaders().simpleSprite; SimpleSpriteShader &shader = shState->shaders().simpleSprite;