2013-09-01 14:27:21 +00:00
|
|
|
/*
|
|
|
|
** shader.h
|
|
|
|
**
|
|
|
|
** This file is part of mkxp.
|
|
|
|
**
|
|
|
|
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
|
|
|
|
**
|
|
|
|
** mkxp is free software: you can redistribute it and/or modify
|
|
|
|
** it under the terms of the GNU General Public License as published by
|
|
|
|
** the Free Software Foundation, either version 2 of the License, or
|
|
|
|
** (at your option) any later version.
|
|
|
|
**
|
|
|
|
** mkxp is distributed in the hope that it will be useful,
|
|
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
** GNU General Public License for more details.
|
|
|
|
**
|
|
|
|
** You should have received a copy of the GNU General Public License
|
|
|
|
** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SHADER_H
|
|
|
|
#define SHADER_H
|
|
|
|
|
|
|
|
#include "etc-internal.h"
|
|
|
|
#include "gl-util.h"
|
2013-09-23 05:15:01 +00:00
|
|
|
#include "glstate.h"
|
2013-09-01 14:27:21 +00:00
|
|
|
|
2013-09-23 05:15:01 +00:00
|
|
|
class Shader
|
2013-09-01 14:27:21 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
void bind();
|
|
|
|
static void unbind();
|
|
|
|
|
2013-09-23 05:15:01 +00:00
|
|
|
enum Attribute
|
|
|
|
{
|
|
|
|
Position = 0,
|
|
|
|
TexCoord = 1,
|
|
|
|
Color = 2
|
|
|
|
};
|
|
|
|
|
2013-09-01 14:27:21 +00:00
|
|
|
protected:
|
2013-09-23 05:15:01 +00:00
|
|
|
Shader();
|
|
|
|
~Shader();
|
2013-09-01 14:27:21 +00:00
|
|
|
|
2013-09-23 05:15:01 +00:00
|
|
|
void init(const unsigned char *vert, int vertSize,
|
2013-12-30 00:38:10 +00:00
|
|
|
const unsigned char *frag, int fragSize,
|
|
|
|
const char *vertName, const char *fragName,
|
|
|
|
const char *programName);
|
|
|
|
void initFromFile(const char *vertFile, const char *fragFile,
|
|
|
|
const char *programName);
|
2013-09-01 14:27:21 +00:00
|
|
|
|
2013-09-23 05:15:01 +00:00
|
|
|
static void setVec4Uniform(GLint location, const Vec4 &vec);
|
|
|
|
static void setTexUniform(GLint location, unsigned unitIndex, TEX::ID texture);
|
2013-09-01 14:27:21 +00:00
|
|
|
|
2013-09-23 05:15:01 +00:00
|
|
|
GLuint vertShader, fragShader;
|
2013-09-01 14:27:21 +00:00
|
|
|
GLuint program;
|
|
|
|
};
|
|
|
|
|
2013-09-23 05:15:01 +00:00
|
|
|
class ShaderBase : public Shader
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
struct GLProjMat : public GLProperty<Vec2i>
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
void apply(const Vec2i &value);
|
|
|
|
GLint u_mat;
|
|
|
|
|
|
|
|
friend class ShaderBase;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Stack is not used (only 'set()') */
|
|
|
|
GLProjMat projMat;
|
|
|
|
|
|
|
|
/* Retrieves the current glState.viewport size,
|
|
|
|
* calculates the corresponding ortho projection matrix
|
|
|
|
* and loads it into the shaders uniform */
|
|
|
|
void applyViewportProj();
|
|
|
|
|
|
|
|
void setTexSize(const Vec2i &value);
|
|
|
|
void setTranslation(const Vec2i &value);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void init();
|
|
|
|
|
|
|
|
GLint u_texSizeInv, u_translation;
|
|
|
|
};
|
|
|
|
|
|
|
|
class SimpleShader : public ShaderBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SimpleShader();
|
|
|
|
|
|
|
|
void setTexOffsetX(int value);
|
|
|
|
|
|
|
|
private:
|
|
|
|
GLint u_texOffsetX;
|
|
|
|
};
|
|
|
|
|
|
|
|
class SimpleColorShader : public ShaderBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SimpleColorShader();
|
|
|
|
};
|
|
|
|
|
|
|
|
class SimpleAlphaShader : public ShaderBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SimpleAlphaShader();
|
|
|
|
};
|
|
|
|
|
|
|
|
class SimpleSpriteShader : public ShaderBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SimpleSpriteShader();
|
|
|
|
|
|
|
|
void setSpriteMat(const float value[16]);
|
|
|
|
|
|
|
|
private:
|
|
|
|
GLint u_spriteMat;
|
|
|
|
};
|
|
|
|
|
|
|
|
class TransShader : public ShaderBase
|
2013-09-01 14:27:21 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
TransShader();
|
|
|
|
|
2013-09-06 10:26:41 +00:00
|
|
|
void setCurrentScene(TEX::ID tex);
|
|
|
|
void setFrozenScene(TEX::ID tex);
|
|
|
|
void setTransMap(TEX::ID tex);
|
2013-09-01 14:27:21 +00:00
|
|
|
void setProg(float value);
|
|
|
|
void setVague(float value);
|
|
|
|
|
|
|
|
private:
|
|
|
|
GLint u_currentScene, u_frozenScene, u_transMap, u_prog, u_vague;
|
|
|
|
};
|
|
|
|
|
2013-09-23 05:15:01 +00:00
|
|
|
class SimpleTransShader : public ShaderBase
|
2013-09-01 14:27:21 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
SimpleTransShader();
|
|
|
|
|
2013-09-06 10:26:41 +00:00
|
|
|
void setCurrentScene(TEX::ID tex);
|
|
|
|
void setFrozenScene(TEX::ID tex);
|
2013-09-01 14:27:21 +00:00
|
|
|
void setProg(float value);
|
|
|
|
|
|
|
|
private:
|
|
|
|
GLint u_currentScene, u_frozenScene, u_prog;
|
|
|
|
};
|
|
|
|
|
2013-09-23 05:15:01 +00:00
|
|
|
class SpriteShader : public ShaderBase
|
2013-09-01 14:27:21 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
SpriteShader();
|
|
|
|
|
2013-09-23 05:15:01 +00:00
|
|
|
void setSpriteMat(const float value[16]);
|
2013-09-01 14:27:21 +00:00
|
|
|
void setTone(const Vec4 &value);
|
|
|
|
void setColor(const Vec4 &value);
|
|
|
|
void setOpacity(float value);
|
|
|
|
void setBushDepth(float value);
|
|
|
|
void setBushOpacity(float value);
|
|
|
|
|
|
|
|
private:
|
2013-09-23 05:15:01 +00:00
|
|
|
GLint u_spriteMat, u_tone, u_opacity, u_color, u_bushDepth, u_bushOpacity;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PlaneShader : public ShaderBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PlaneShader();
|
|
|
|
|
|
|
|
void setTone(const Vec4 &value);
|
|
|
|
void setColor(const Vec4 &value);
|
|
|
|
void setFlash(const Vec4 &value);
|
|
|
|
void setOpacity(float value);
|
|
|
|
|
|
|
|
private:
|
|
|
|
GLint u_tone, u_color, u_flash, u_opacity;
|
2013-09-01 14:27:21 +00:00
|
|
|
};
|
|
|
|
|
Tilemap: Use vertex shader based autotile animation strategy
Previously, we would just stuff the entire tilemap vertex data
four times into the buffers, with only the autotile vertices
offset according to the animation frame. This meant we could
prepare the buffers once, and then just bind a different offset
for each animation frame without any shader changes, but it also
lead to a huge amount of data being duplicated (and blowing up
the buffer sizes).
The new method only requires one buffer, and instead animates by
recognizing vertices belonging to autotiles in a custom vertex
shader, which offsets them on the fly according to the animation
index.
With giant tilemaps, this method would turn out to be a little
less efficient, but considering the Tilemap is planned to be
rewritten to only hold the range of tiles visible on the screen
in its buffers, the on the fly offsetting will become neglient,
while at the same time the amount of data we have to send to the
GPU everytime the tilemap is updated is greatly reduced; so a
net win in the end.
2014-07-06 17:44:19 +00:00
|
|
|
class TilemapShader : public ShaderBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
TilemapShader();
|
|
|
|
|
|
|
|
void setAniIndex(int value);
|
|
|
|
|
|
|
|
private:
|
|
|
|
GLint u_aniIndex;
|
|
|
|
};
|
|
|
|
|
2013-09-23 06:27:28 +00:00
|
|
|
class FlashMapShader : public ShaderBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
FlashMapShader();
|
|
|
|
|
|
|
|
void setAlpha(float value);
|
|
|
|
|
|
|
|
private:
|
|
|
|
GLint u_alpha;
|
|
|
|
};
|
|
|
|
|
2013-09-23 05:15:01 +00:00
|
|
|
class HueShader : public ShaderBase
|
2013-09-01 14:27:21 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
HueShader();
|
|
|
|
|
|
|
|
void setHueAdjust(float value);
|
2013-09-06 10:26:41 +00:00
|
|
|
void setInputTexture(TEX::ID tex);
|
2013-09-01 14:27:21 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
GLint u_hueAdjust, u_inputTexture;
|
|
|
|
};
|
|
|
|
|
2013-10-02 20:40:09 +00:00
|
|
|
class SimpleMatrixShader : public ShaderBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SimpleMatrixShader();
|
|
|
|
|
|
|
|
void setMatrix(const float value[16]);
|
|
|
|
|
|
|
|
private:
|
|
|
|
GLint u_matrix;
|
|
|
|
};
|
|
|
|
|
2013-10-01 16:10:43 +00:00
|
|
|
/* Gaussian blur */
|
|
|
|
struct BlurShader
|
|
|
|
{
|
|
|
|
class HPass : public ShaderBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
HPass();
|
|
|
|
};
|
|
|
|
|
|
|
|
class VPass : public ShaderBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
VPass();
|
|
|
|
};
|
|
|
|
|
|
|
|
HPass pass1;
|
|
|
|
VPass pass2;
|
|
|
|
};
|
2014-08-15 11:59:28 +00:00
|
|
|
|
|
|
|
class TilemapVXShader : public ShaderBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
TilemapVXShader();
|
|
|
|
|
|
|
|
void setAniOffset(const Vec2 &value);
|
|
|
|
|
|
|
|
private:
|
|
|
|
GLint u_aniOffset;
|
|
|
|
};
|
|
|
|
|
2013-09-01 14:27:21 +00:00
|
|
|
/* Bitmap blit */
|
2013-09-23 05:15:01 +00:00
|
|
|
class BltShader : public ShaderBase
|
2013-09-01 14:27:21 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
BltShader();
|
|
|
|
|
|
|
|
void setSource();
|
2013-09-06 10:26:41 +00:00
|
|
|
void setDestination(const TEX::ID value);
|
2013-09-01 14:27:21 +00:00
|
|
|
void setDestCoorF(const Vec2 &value);
|
|
|
|
void setSubRect(const FloatRect &value);
|
|
|
|
void setOpacity(float value);
|
|
|
|
|
|
|
|
private:
|
|
|
|
GLint u_source, u_destination, u_subRect, u_opacity;
|
|
|
|
};
|
|
|
|
|
2013-12-11 04:22:13 +00:00
|
|
|
/* Global object containing all available shaders */
|
|
|
|
struct ShaderSet
|
|
|
|
{
|
|
|
|
SimpleShader simple;
|
|
|
|
SimpleColorShader simpleColor;
|
|
|
|
SimpleAlphaShader simpleAlpha;
|
|
|
|
SimpleSpriteShader simpleSprite;
|
|
|
|
SpriteShader sprite;
|
|
|
|
PlaneShader plane;
|
Tilemap: Use vertex shader based autotile animation strategy
Previously, we would just stuff the entire tilemap vertex data
four times into the buffers, with only the autotile vertices
offset according to the animation frame. This meant we could
prepare the buffers once, and then just bind a different offset
for each animation frame without any shader changes, but it also
lead to a huge amount of data being duplicated (and blowing up
the buffer sizes).
The new method only requires one buffer, and instead animates by
recognizing vertices belonging to autotiles in a custom vertex
shader, which offsets them on the fly according to the animation
index.
With giant tilemaps, this method would turn out to be a little
less efficient, but considering the Tilemap is planned to be
rewritten to only hold the range of tiles visible on the screen
in its buffers, the on the fly offsetting will become neglient,
while at the same time the amount of data we have to send to the
GPU everytime the tilemap is updated is greatly reduced; so a
net win in the end.
2014-07-06 17:44:19 +00:00
|
|
|
TilemapShader tilemap;
|
2013-12-11 04:22:13 +00:00
|
|
|
FlashMapShader flashMap;
|
|
|
|
TransShader trans;
|
|
|
|
SimpleTransShader simpleTrans;
|
|
|
|
HueShader hue;
|
|
|
|
BltShader blt;
|
|
|
|
SimpleMatrixShader simpleMatrix;
|
|
|
|
BlurShader blur;
|
2014-08-15 11:59:28 +00:00
|
|
|
TilemapVXShader tilemapVX;
|
2013-12-11 04:22:13 +00:00
|
|
|
};
|
|
|
|
|
2013-09-01 14:27:21 +00:00
|
|
|
#endif // SHADER_H
|