From 9f26ff9fb02c11e98d241ee3fb69a4bc9f8ecc93 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Wed, 4 Sep 2013 21:03:59 +0200 Subject: [PATCH] Port over Bitmap 'radial_blur' from old SFML codebase This implementation is also heaps better than the old one as it doesn't use a (differently sized) aux texture, meaning the Bitmap discards its old texture and aquires one of same size, making reuse through the TexPool a lot more likely. It also saves on the aux texture blits and binding switches. As the setup / resource acquisition far outweighs the actual rendering cost, operation time is relatively constant no matter how many divisions are used. --- mkxp.pro | 1 + shader/simpleMatrix.vert | 20 ++++++++ src/bitmap.cpp | 98 ++++++++++++++++++++++++++++++++++++++++ src/bitmap.h | 2 +- src/globalstate.cpp | 2 + src/globalstate.h | 2 + src/shader.cpp | 16 +++++++ src/shader.h | 11 +++++ 8 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 shader/simpleMatrix.vert diff --git a/mkxp.pro b/mkxp.pro index 6856568..9673a6b 100644 --- a/mkxp.pro +++ b/mkxp.pro @@ -104,6 +104,7 @@ EMBED = shader/transSimple.frag \ shader/simple.vert \ shader/simpleColor.vert \ shader/sprite.vert \ + shader/simpleMatrix.vert \ assets/liberation.ttf defineReplace(xxdOutput) { diff --git a/shader/simpleMatrix.vert b/shader/simpleMatrix.vert new file mode 100644 index 0000000..23287cb --- /dev/null +++ b/shader/simpleMatrix.vert @@ -0,0 +1,20 @@ + +uniform mat4 projMat; +uniform mat4 matrix; + +uniform vec2 texSizeInv; + +attribute vec2 position; +attribute vec2 texCoord; +attribute vec4 color; + +varying vec2 v_texCoord; +varying vec4 v_color; + +void main() +{ + gl_Position = projMat * matrix * vec4(position, 0, 1); + + v_texCoord = texCoord * texSizeInv; + v_color = color; +} diff --git a/src/bitmap.cpp b/src/bitmap.cpp index b9f61a7..16bfa5c 100644 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -31,6 +31,7 @@ #include "gl-util.h" #include "quad.h" #include "quadarray.h" +#include "transform.h" #include "exception.h" #include "globalstate.h" @@ -507,6 +508,103 @@ void Bitmap::clearRect(const IntRect &rect) modified(); } +void Bitmap::radialBlur(int angle, int divisions) +{ + GUARD_DISPOSED; + + GUARD_MEGA; + + flush(); + + angle = clamp(angle, 0, 359); + divisions = clamp(divisions, 2, 100); + + const int _width = width(); + const int _height = height(); + + float angleStep = (float) angle / (divisions-1); + float opacity = 1.0f / divisions; + float baseAngle = -((float) angle / 2); + + ColorQuadArray qArray; + qArray.resize(5); + + QVector &vert = qArray.vertices; + + int i = 0; + + /* Center */ + FloatRect texRect(0, 0, _width, _height); + FloatRect posRect(0, 0, _width, _height); + + i += Quad::setTexPosRect(&vert[i*4], texRect, posRect); + + /* Upper */ + posRect = FloatRect(0, 0, _width, -_height); + + i += Quad::setTexPosRect(&vert[i*4], texRect, posRect); + + /* Lower */ + posRect = FloatRect(0, _height*2, _width, -_height); + + i += Quad::setTexPosRect(&vert[i*4], texRect, posRect); + + /* Left */ + posRect = FloatRect(0, 0, -_width, _height); + + i += Quad::setTexPosRect(&vert[i*4], texRect, posRect); + + /* Right */ + posRect = FloatRect(_width*2, 0, -_width, _height); + + i += Quad::setTexPosRect(&vert[i*4], texRect, posRect); + + for (int i = 0; i < 4*5; ++i) + vert[i].color = Vec4(1, 1, 1, opacity); + + qArray.commit(); + + TEXFBO newTex = gState->texPool().request(_width, _height); + + FBO::bind(newTex.fbo, FBO::Draw); + + glState.clearColor.pushSet(Vec4()); + glClear(GL_COLOR_BUFFER_BIT); + + Transform trans; + trans.setOrigin(Vec2(_width / 2.0f, _height / 2.0f)); + trans.setPosition(Vec2(_width / 2.0f, _height / 2.0f)); + + glState.blendMode.pushSet(BlendAddition); + + SimpleMatrixShader &shader = gState->simpleMatrixShader(); + shader.bind(); + + p->bindTexture(shader); + TEX::setSmooth(true); + + p->pushSetViewport(shader); + + for (int i = 0; i < divisions; i++) + { + trans.setRotation(baseAngle + i*angleStep); + shader.setMatrix(trans.getMatrix()); + qArray.draw(); + } + + p->popViewport(); + + TEX::setSmooth(false); + + glState.blendMode.pop(); + glState.clearColor.pop(); + + gState->texPool().release(p->tex); + p->tex = newTex; + + modified(); +} + void Bitmap::clear() { GUARD_DISPOSED; diff --git a/src/bitmap.h b/src/bitmap.h index 91de0ec..1f6822e 100644 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -74,7 +74,7 @@ public: int width, int height); void clearRect(const IntRect &rect); -// void radialBlur(int angle, int divisions); + void radialBlur(int angle, int divisions); // /* ----- */ void clear(); diff --git a/src/globalstate.cpp b/src/globalstate.cpp index 7b52b60..1c247af 100644 --- a/src/globalstate.cpp +++ b/src/globalstate.cpp @@ -69,6 +69,7 @@ struct GlobalStatePrivate SimpleColorShader simpleColorShader; SimpleAlphaShader simpleAlphaShader; SimpleSpriteShader simpleSpriteShader; + SimpleMatrixShader simpleMatrixShader; SpriteShader spriteShader; PlaneShader planeShader; FlashMapShader flashMapShader; @@ -188,6 +189,7 @@ GSATT(SimpleShader&, simpleShader) GSATT(SimpleColorShader&, simpleColorShader) GSATT(SimpleAlphaShader&, simpleAlphaShader) GSATT(SimpleSpriteShader&, simpleSpriteShader) +GSATT(SimpleMatrixShader&, simpleMatrixShader) GSATT(SpriteShader&, spriteShader) GSATT(PlaneShader&, planeShader) GSATT(FlashMapShader&, flashMapShader) diff --git a/src/globalstate.h b/src/globalstate.h index f6f0966..b0e2a4d 100644 --- a/src/globalstate.h +++ b/src/globalstate.h @@ -46,6 +46,7 @@ class SimpleShader; class SimpleColorShader; class SimpleAlphaShader; class SimpleSpriteShader; +class SimpleMatrixShader; class SpriteShader; class PlaneShader; class FlashMapShader; @@ -86,6 +87,7 @@ struct GlobalState SimpleColorShader &simpleColorShader(); SimpleAlphaShader &simpleAlphaShader(); SimpleSpriteShader &simpleSpriteShader(); + SimpleMatrixShader &simpleMatrixShader(); SpriteShader &spriteShader(); PlaneShader &planeShader(); FlashMapShader &flashMapShader(); diff --git a/src/shader.cpp b/src/shader.cpp index 55ae1bb..845bbb4 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -40,6 +40,7 @@ #include "../simple.vert.xxd" #include "../simpleColor.vert.xxd" #include "../sprite.vert.xxd" +#include "../simpleMatrix.vert.xxd" #define INIT_SHADER(vert, frag) \ @@ -226,6 +227,21 @@ void SimpleSpriteShader::setSpriteMat(const float value[16]) } +SimpleMatrixShader::SimpleMatrixShader() +{ + INIT_SHADER(simpleMatrix, simpleAlpha); + + ShaderBase::init(); + + GET_U(matrix); +} + +void SimpleMatrixShader::setMatrix(const float value[16]) +{ + glUniformMatrix4fv(u_matrix, 1, GL_FALSE, value); +} + + TransShader::TransShader() { INIT_SHADER(simple, trans); diff --git a/src/shader.h b/src/shader.h index e259d8c..e5ece70 100644 --- a/src/shader.h +++ b/src/shader.h @@ -118,6 +118,17 @@ private: GLint u_spriteMat; }; +class SimpleMatrixShader : public ShaderBase +{ +public: + SimpleMatrixShader(); + + void setMatrix(const float value[16]); + +private: + GLint u_matrix; +}; + class TransShader : public ShaderBase { public: