Implement Bitmap 'blur'

I was a bit confused at first because I thought Enterbrain
had actually implemented a full Gaussian blur, but nope,
just dumb averaging.
This commit is contained in:
Jonas Kulla 2013-10-01 18:10:43 +02:00
parent 20ec560145
commit a54acce6b7
10 changed files with 149 additions and 1 deletions

View File

@ -101,10 +101,13 @@ EMBED = shader/transSimple.frag \
shader/simpleColor.frag \
shader/simpleAlpha.frag \
shader/flashMap.frag \
shader/blur.frag \
shader/simple.vert \
shader/simpleColor.vert \
shader/sprite.vert \
shader/simpleMatrix.vert \
shader/blurH.vert \
shader/blurV.vert \
assets/liberation.ttf
defineReplace(xxdOutput) {

16
shader/blur.frag Normal file
View File

@ -0,0 +1,16 @@
uniform sampler2D texture;
varying vec2 v_texCoord;
varying vec2 v_blurCoord[2];
void main()
{
vec4 frag = vec4(0, 0, 0, 0);
frag += texture2D(texture, v_texCoord);
frag += texture2D(texture, v_blurCoord[0]);
frag += texture2D(texture, v_blurCoord[1]);
gl_FragColor = frag / 3.0;
}

19
shader/blurH.vert Normal file
View File

@ -0,0 +1,19 @@
uniform mat4 projMat;
uniform vec2 texSizeInv;
attribute vec2 position;
attribute vec2 texCoord;
varying vec2 v_texCoord;
varying vec2 v_blurCoord[2];
void main()
{
gl_Position = projMat * vec4(position, 0, 1);
v_texCoord = texCoord * texSizeInv;
v_blurCoord[0] = vec2(texCoord.x-1, texCoord.y) * texSizeInv;
v_blurCoord[1] = vec2(texCoord.x+1, texCoord.y) * texSizeInv;
}

19
shader/blurV.vert Normal file
View File

@ -0,0 +1,19 @@
uniform mat4 projMat;
uniform vec2 texSizeInv;
attribute vec2 position;
attribute vec2 texCoord;
varying vec2 v_texCoord;
varying vec2 v_blurCoord[2];
void main()
{
gl_Position = projMat * vec4(position, 0, 1);
v_texCoord = texCoord * texSizeInv;
v_blurCoord[0] = vec2(texCoord.x, texCoord.y-1) * texSizeInv;
v_blurCoord[1] = vec2(texCoord.x, texCoord.y+1) * texSizeInv;
}

View File

@ -508,6 +508,53 @@ void Bitmap::clearRect(const IntRect &rect)
modified();
}
void Bitmap::blur()
{
GUARD_DISPOSED;
GUARD_MEGA;
flush();
Quad &quad = gState->gpQuad();
FloatRect rect(0, 0, width(), height());
quad.setTexPosRect(rect, rect);
TEXFBO auxTex = gState->texPool().request(width(), height());
BlurShader &shader = gState->blurShader();
BlurShader::HPass &pass1 = shader.pass1;
BlurShader::VPass &pass2 = shader.pass2;
glState.blendMode.pushSet(BlendNone);
glState.viewport.pushSet(IntRect(0, 0, width(), height()));
TEX::bind(p->tex.tex);
FBO::bind(auxTex.fbo, FBO::Draw);
pass1.bind();
pass1.setTexSize(Vec2i(width(), height()));
pass1.applyViewportProj();
quad.draw();
TEX::bind(auxTex.tex);
FBO::bind(p->tex.fbo, FBO::Draw);
pass2.bind();
pass2.setTexSize(Vec2i(width(), height()));
pass2.applyViewportProj();
quad.draw();
glState.viewport.pop();
glState.blendMode.pop();
gState->texPool().release(auxTex);
modified();
}
void Bitmap::radialBlur(int angle, int divisions)
{
GUARD_DISPOSED;

View File

@ -74,8 +74,10 @@ public:
int width, int height);
void clearRect(const IntRect &rect);
void blur();
void radialBlur(int angle, int divisions);
// /* ----- */
/* ----- */
void clear();

View File

@ -76,6 +76,7 @@ struct GlobalStatePrivate
TransShader transShader;
SimpleTransShader sTransShader;
HueShader hueShader;
BlurShader blurShader;
BltShader bltShader;
TexPool texPool;
@ -196,6 +197,7 @@ GSATT(FlashMapShader&, flashMapShader)
GSATT(TransShader&, transShader)
GSATT(SimpleTransShader&, sTransShader)
GSATT(HueShader&, hueShader)
GSATT(BlurShader&, blurShader)
GSATT(BltShader&, bltShader)
GSATT(TexPool&, texPool)
GSATT(FontPool&, fontPool)

View File

@ -57,6 +57,7 @@ class BltShader;
class TexPool;
class FontPool;
class Font;
struct BlurShader;
struct GlobalIBO;
struct Config;
struct Vec2i;
@ -94,6 +95,7 @@ struct GlobalState
TransShader &transShader();
SimpleTransShader &sTransShader();
HueShader &hueShader();
BlurShader &blurShader();
BltShader &bltShader();
TexPool &texPool();

View File

@ -37,10 +37,13 @@
#include "../simpleColor.frag.xxd"
#include "../simpleAlpha.frag.xxd"
#include "../flashMap.frag.xxd"
#include "../blur.frag.xxd"
#include "../simple.vert.xxd"
#include "../simpleColor.vert.xxd"
#include "../sprite.vert.xxd"
#include "../simpleMatrix.vert.xxd"
#include "../blurH.vert.xxd"
#include "../blurV.vert.xxd"
#define INIT_SHADER(vert, frag) \
@ -422,6 +425,22 @@ void HueShader::setInputTexture(TEX::ID tex)
}
BlurShader::HPass::HPass()
{
INIT_SHADER(blurH, blur);
ShaderBase::init();
}
BlurShader::VPass::VPass()
{
INIT_SHADER(blurV, blur);
ShaderBase::init();
}
BltShader::BltShader()
{
INIT_SHADER(simple, bitmapBlit);

View File

@ -210,6 +210,25 @@ private:
GLint u_hueAdjust, u_inputTexture;
};
/* Gaussian blur */
struct BlurShader
{
class HPass : public ShaderBase
{
public:
HPass();
};
class VPass : public ShaderBase
{
public:
VPass();
};
HPass pass1;
VPass pass2;
};
/* Bitmap blit */
class BltShader : public ShaderBase
{