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.
This commit is contained in:
parent
088f0a2a30
commit
9f26ff9fb0
1
mkxp.pro
1
mkxp.pro
|
@ -104,6 +104,7 @@ EMBED = shader/transSimple.frag \
|
||||||
shader/simple.vert \
|
shader/simple.vert \
|
||||||
shader/simpleColor.vert \
|
shader/simpleColor.vert \
|
||||||
shader/sprite.vert \
|
shader/sprite.vert \
|
||||||
|
shader/simpleMatrix.vert \
|
||||||
assets/liberation.ttf
|
assets/liberation.ttf
|
||||||
|
|
||||||
defineReplace(xxdOutput) {
|
defineReplace(xxdOutput) {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -31,6 +31,7 @@
|
||||||
#include "gl-util.h"
|
#include "gl-util.h"
|
||||||
#include "quad.h"
|
#include "quad.h"
|
||||||
#include "quadarray.h"
|
#include "quadarray.h"
|
||||||
|
#include "transform.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
|
||||||
#include "globalstate.h"
|
#include "globalstate.h"
|
||||||
|
@ -507,6 +508,103 @@ void Bitmap::clearRect(const IntRect &rect)
|
||||||
modified();
|
modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bitmap::radialBlur(int angle, int divisions)
|
||||||
|
{
|
||||||
|
GUARD_DISPOSED;
|
||||||
|
|
||||||
|
GUARD_MEGA;
|
||||||
|
|
||||||
|
flush();
|
||||||
|
|
||||||
|
angle = clamp<int>(angle, 0, 359);
|
||||||
|
divisions = clamp<int>(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<Vertex> &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()
|
void Bitmap::clear()
|
||||||
{
|
{
|
||||||
GUARD_DISPOSED;
|
GUARD_DISPOSED;
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
int width, int height);
|
int width, int height);
|
||||||
void clearRect(const IntRect &rect);
|
void clearRect(const IntRect &rect);
|
||||||
|
|
||||||
// void radialBlur(int angle, int divisions);
|
void radialBlur(int angle, int divisions);
|
||||||
// /* ----- */
|
// /* ----- */
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
|
@ -69,6 +69,7 @@ struct GlobalStatePrivate
|
||||||
SimpleColorShader simpleColorShader;
|
SimpleColorShader simpleColorShader;
|
||||||
SimpleAlphaShader simpleAlphaShader;
|
SimpleAlphaShader simpleAlphaShader;
|
||||||
SimpleSpriteShader simpleSpriteShader;
|
SimpleSpriteShader simpleSpriteShader;
|
||||||
|
SimpleMatrixShader simpleMatrixShader;
|
||||||
SpriteShader spriteShader;
|
SpriteShader spriteShader;
|
||||||
PlaneShader planeShader;
|
PlaneShader planeShader;
|
||||||
FlashMapShader flashMapShader;
|
FlashMapShader flashMapShader;
|
||||||
|
@ -188,6 +189,7 @@ GSATT(SimpleShader&, simpleShader)
|
||||||
GSATT(SimpleColorShader&, simpleColorShader)
|
GSATT(SimpleColorShader&, simpleColorShader)
|
||||||
GSATT(SimpleAlphaShader&, simpleAlphaShader)
|
GSATT(SimpleAlphaShader&, simpleAlphaShader)
|
||||||
GSATT(SimpleSpriteShader&, simpleSpriteShader)
|
GSATT(SimpleSpriteShader&, simpleSpriteShader)
|
||||||
|
GSATT(SimpleMatrixShader&, simpleMatrixShader)
|
||||||
GSATT(SpriteShader&, spriteShader)
|
GSATT(SpriteShader&, spriteShader)
|
||||||
GSATT(PlaneShader&, planeShader)
|
GSATT(PlaneShader&, planeShader)
|
||||||
GSATT(FlashMapShader&, flashMapShader)
|
GSATT(FlashMapShader&, flashMapShader)
|
||||||
|
|
|
@ -46,6 +46,7 @@ class SimpleShader;
|
||||||
class SimpleColorShader;
|
class SimpleColorShader;
|
||||||
class SimpleAlphaShader;
|
class SimpleAlphaShader;
|
||||||
class SimpleSpriteShader;
|
class SimpleSpriteShader;
|
||||||
|
class SimpleMatrixShader;
|
||||||
class SpriteShader;
|
class SpriteShader;
|
||||||
class PlaneShader;
|
class PlaneShader;
|
||||||
class FlashMapShader;
|
class FlashMapShader;
|
||||||
|
@ -86,6 +87,7 @@ struct GlobalState
|
||||||
SimpleColorShader &simpleColorShader();
|
SimpleColorShader &simpleColorShader();
|
||||||
SimpleAlphaShader &simpleAlphaShader();
|
SimpleAlphaShader &simpleAlphaShader();
|
||||||
SimpleSpriteShader &simpleSpriteShader();
|
SimpleSpriteShader &simpleSpriteShader();
|
||||||
|
SimpleMatrixShader &simpleMatrixShader();
|
||||||
SpriteShader &spriteShader();
|
SpriteShader &spriteShader();
|
||||||
PlaneShader &planeShader();
|
PlaneShader &planeShader();
|
||||||
FlashMapShader &flashMapShader();
|
FlashMapShader &flashMapShader();
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "../simple.vert.xxd"
|
#include "../simple.vert.xxd"
|
||||||
#include "../simpleColor.vert.xxd"
|
#include "../simpleColor.vert.xxd"
|
||||||
#include "../sprite.vert.xxd"
|
#include "../sprite.vert.xxd"
|
||||||
|
#include "../simpleMatrix.vert.xxd"
|
||||||
|
|
||||||
|
|
||||||
#define INIT_SHADER(vert, frag) \
|
#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()
|
TransShader::TransShader()
|
||||||
{
|
{
|
||||||
INIT_SHADER(simple, trans);
|
INIT_SHADER(simple, trans);
|
||||||
|
|
11
src/shader.h
11
src/shader.h
|
@ -118,6 +118,17 @@ private:
|
||||||
GLint u_spriteMat;
|
GLint u_spriteMat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SimpleMatrixShader : public ShaderBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SimpleMatrixShader();
|
||||||
|
|
||||||
|
void setMatrix(const float value[16]);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLint u_matrix;
|
||||||
|
};
|
||||||
|
|
||||||
class TransShader : public ShaderBase
|
class TransShader : public ShaderBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue