Files
RCBASIC4/rcbasic_runtime/rc_post_fx.h
n00b87 61e55f72f6 Added Bone Info Functions
* Added functions to get info on bones
* Fixed ColorKey() flipping images if color is not -1
2026-01-27 23:56:30 -06:00

1555 lines
50 KiB
C++

#ifndef RC_POST_FX_H_INCLUDED
#define RC_POST_FX_H_INCLUDED
#include <irrlicht.h>
#include <cstdlib>
#include "rc_gfx_core.h"
using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
// DISTORTION
class PPE_Glass_callback: public video::IShaderConstantSetCallBack
{
public:
float strength;
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
services->setVertexShaderConstant("strength", reinterpret_cast<f32*>(&strength),1);
int var0=0;
services->setPixelShaderConstant("Texture1", (float*)(&var0), 1);
int var1=1;
services->setPixelShaderConstant("Texture2", (float*)(&var1), 1);
}
};
class IPostProcessGlass : public scene::ISceneNode
{
public:
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];//the vertices for the onscreenquad
video::SMaterial Material;//the material used with shader
video::ITexture* rt0; //the rendertarget/normalmap
video::ITexture* rt1; //the smgr->drawAll output
int mat;
PPE_Glass_callback* callback;
IPostProcessGlass(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
{
Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
callback = NULL;
rt0 = NULL;
rt1 = NULL;
}
void initiate(unsigned int sizeW,unsigned int sizeH,float strength,scene::ISceneManager* smgr)
{
static stringc vertShader =
"varying vec2 vTexCoord;"
"void main(void)"
"{"
" vec2 Position;"
" Position.xy = sign(gl_Vertex.xy);"
" gl_Position = vec4(Position.xy, 0.0, 1.0);"
"vTexCoord =Position.xy *.5 + .5;"
"}";
static stringc fragShader =
"uniform float strength;"
"varying vec2 vTexCoord;"
"uniform sampler2D Texture2; "
"uniform sampler2D Texture1;"
""
"void main(void)"
"{"
" vec2 offset= texture2D( Texture2, vTexCoord).xy;"
" float d=length(offset);"
" if(d!=0.0){offset-=0.5*d;}"
" offset=offset*strength+vTexCoord;"
" gl_FragColor = texture2D( Texture1, offset );"
//"gl_FragColor=texture2D( Texture1, vTexCoord )+texture2D( Texture2, vTexCoord );"
"}";
video::IVideoDriver* driver = smgr->getVideoDriver();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
callback= new PPE_Glass_callback();
callback->strength=strength;
Material.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader.c_str(), "main", video::EPST_PS_1_1,
callback, (video::EMT_SOLID)
);
rt0 = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
rt1 = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
Material.Wireframe = false;
Material.Lighting = false;
Material.setTexture(0, rt0);
Material.setTexture(1,rt1);
}
virtual void OnPreRender()
{
}
virtual void render()
{
u16 indices[] = {0,1,2,3,4,5};
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
virtual u32 getMaterialCount(){return 1;}
virtual video::SMaterial& getMaterial(s32 i){return (Material);}
virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};
// COLORIZE
struct PPE_Color_Setup
{
float saturation;
float coloringStrength;
video::SColorf col;
};
class PPE_Color_callback: public video::IShaderConstantSetCallBack
{
public:
float saturation;
float coloringStrength;
video::SColorf col;
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
services->setVertexShaderConstant("saturation", reinterpret_cast<f32*>(&saturation),1);
services->setVertexShaderConstant("coloringStrength", reinterpret_cast<f32*>(&coloringStrength),1);
services->setPixelShaderConstant("coloring", reinterpret_cast<f32*>(&col), 4);
}
};
class IPostProcessColor : public scene::ISceneNode
{
public:
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];//the vertices for the onscreenquad
video::SMaterial Material;
video::ITexture* rt0; //the rendertarget
int mat;
PPE_Color_callback* callback;
IPostProcessColor(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
{
Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
}
void initiate(unsigned int sizeW,unsigned int sizeH,PPE_Color_Setup data,scene::ISceneManager* smgr)
{
static stringc vertToonShader =
"varying vec2 vTexCoord;"
"void main(void)"
"{"
" vec2 Position;"
" Position.xy = sign(gl_Vertex.xy);"
" gl_Position = vec4(Position.xy, 0.0, 1.0);"
"vTexCoord =Position.xy *.5 + .5;"
"}";
static stringc fragToonShader =
"uniform sampler2D texture[2];"
"varying vec2 vTexCoord;"
"uniform float saturation;"
"uniform float coloringStrength;"
"uniform vec4 coloring;"
"void main()"
"{"
" vec4 sample = texture2D(texture[0], vTexCoord);"
" float sat=saturation/10.0;"
" float hue=coloringStrength/10.0;"
" float greyscale=sample.r*0.3+sample.g*0.49+sample.b*0.11;"
" vec4 cGreyScale;"
" cGreyScale.r=greyscale;"
" cGreyScale.g=greyscale;"
" cGreyScale.b=greyscale;"
" sample=(sample*(1.0-hue))+coloring/255.0*greyscale*(hue);"
" gl_FragColor = (cGreyScale*sat)+sample*(1.0-sat);"
"}";
video::IVideoDriver* driver = smgr->getVideoDriver();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
callback= new PPE_Color_callback;
callback->saturation=data.saturation;
callback->coloringStrength=data.coloringStrength;
callback->col=data.col;
Material.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertToonShader.c_str(), "main", video::EVST_VS_1_1,
fragToonShader.c_str(), "main", video::EPST_PS_1_1,
callback, (video::EMT_SOLID)
);
rt0 = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
Material.Wireframe = false;
Material.Lighting = false;
Material.setTexture(0,rt0);
}
virtual void OnPreRender(){}
virtual void render()
{
u16 indices[] = {0,1,2,3,4,5};
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
//Renders the Post-Process Effect
virtual u32 getMaterialCount(){return 1;}
virtual video::SMaterial& getMaterial(s32 i){return (Material);}
virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};
// RADIAL BLUR
class PPE_RadialBlur_callback: public video::IShaderConstantSetCallBack
{
public:
float sampleDist;
float sampleStrength;
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
services->setVertexShaderConstant("sampleDist", reinterpret_cast<f32*>(&sampleDist),1);
services->setVertexShaderConstant("sampleStrength", reinterpret_cast<f32*>(&sampleStrength),1);
}
};
class IPostProcessRadialBlur : public scene::ISceneNode
{
public:
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];//the vertices for the onscreenquad
video::SMaterial Material;
video::ITexture* rt0; //the rendertarget
int mat;
PPE_RadialBlur_callback* callback;
IPostProcessRadialBlur(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
{
Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
}
void initiate(int sizeW,int sizeH,float sampleDist,float sampleStrength,scene::ISceneManager* smgr)
{
static stringc vertToonShader =
"varying vec2 vTexCoord;"
"void main(void)"
"{"
" vec2 Position;"
" Position.xy = sign(gl_Vertex.xy);"
" gl_Position = vec4(Position.xy, 0.0, 1.0);"
"vTexCoord =Position.xy *.5 + .5;"
"}";
static stringc fragToonShader =
"uniform sampler2D texture[2];"
"varying vec2 vTexCoord;"
"uniform float sampleDist;"
"uniform float sampleStrength;"
"void main()"
"{"
"vec2 dir=vec2(0.5,0.5)-vTexCoord;"
"float dist=sqrt(dir.x*dir.x+dir.y*dir.y);"
"dir=normalize(dir);"
" float samples [10];"
" samples [0]=-0.08;"
" samples [1]=-0.05;"
" samples [2]=-0.03;"
" samples [3]=-0.02;"
" samples [4]=-0.01;"
" samples [5]=0.01;"
" samples [6]=0.02;"
" samples [7]=0.03;"
" samples [8]=0.05;"
" samples [9]=0.08;"
" vec4 sample = texture2D(texture[0], vTexCoord);"
" vec4 avg=sample;"
" vec4 col;"
" for (int i = 0; i < 10; i++)"
" {"
" vec2 tC=min(vec2(0.999,0.999),max(vec2(0.001,0.001),vTexCoord+dir*samples[i]*sampleDist));"
" col=texture2D(texture[0],tC);"
" float intensity=col.r+col.g+col.b;"
" avg += col; "
" }"
" avg /= 11.0;"
" float t=dist*sampleStrength;"
"t=clamp(t,0.0,1.0);"
" gl_FragColor = mix(sample,avg,t);"
"}";
video::IVideoDriver* driver = smgr->getVideoDriver();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
callback= new PPE_RadialBlur_callback;
callback->sampleDist=sampleDist;
callback->sampleStrength=sampleStrength;
Material.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertToonShader.c_str(), "main", video::EVST_VS_1_1,
fragToonShader.c_str(), "main", video::EPST_PS_1_1,
callback, (video::EMT_SOLID)
);
rt0 = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
Material.Wireframe = false;
Material.Lighting = false;
Material.setTexture(0, rt0);
}
virtual void OnPreRender(){}
virtual void render()
{
u16 indices[] = {0,1,2,3,4,5};
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
//Renders the Post-Process Effect
virtual u32 getMaterialCount(){return 1;}
virtual video::SMaterial& getMaterial(s32 i){return (Material);}
virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};
// BLOOM
struct PPE_Bloom_Setup
{
float sampleDist;
float strength;
float multiplier;
};
class PPE_Bloom_callback: public video::IShaderConstantSetCallBack
{
public:
float sampleDist;
float strength;
float multiplier;
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
services->setVertexShaderConstant("sampleDist", reinterpret_cast<f32*>(&sampleDist),1);
services->setVertexShaderConstant("strength", reinterpret_cast<f32*>(&strength),1);
services->setVertexShaderConstant("multiplier", reinterpret_cast<f32*>(&multiplier),1);
}
};
class IPostProcessBloom : public scene::ISceneNode
{
public:
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];//the vertices for the onscreenquad
video::SMaterial Material;
video::ITexture* rt0; //the rendertarget
int mat;
PPE_Bloom_callback* callback;
IPostProcessBloom(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
{
Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
}
void initiate(unsigned int sizeW,unsigned int sizeH,PPE_Bloom_Setup data,scene::ISceneManager* smgr)
{
static stringc vertShader =
"varying vec2 vTexCoord;"
"void main(void)"
"{"
" vec2 Position;"
" Position.xy = sign(gl_Vertex.xy);"
" gl_Position = vec4(Position.xy, 0.0, 1.0);"
"vTexCoord =Position.xy *.5 + .5;"
"}";
static stringc fragShader =
"uniform sampler2D texture[2];"
"varying vec2 vTexCoord;"
"uniform float sampleDist;"
"uniform float strength;"
"uniform float multiplier;"
"void main()"
"{"
" vec2 samples[12]; "
" samples[0] = vTexCoord + sampleDist * vec2(-0.326212, -0.405805);"
" samples[1] = vTexCoord + sampleDist * vec2(-0.840144, -0.073580);"
" samples[2] = vTexCoord + sampleDist * vec2(-0.695914, 0.457137);"
" samples[3] = vTexCoord + sampleDist * vec2(-0.203345, 0.620716);"
" samples[4] = vTexCoord + sampleDist * vec2(0.962340, -0.194983);"
" samples[5] = vTexCoord + sampleDist * vec2(0.473434, -0.480026);"
" samples[6] = vTexCoord + sampleDist * vec2(0.519456, 0.767022);"
" samples[7] = vTexCoord + sampleDist * vec2(0.185461, -0.893124);"
" samples[8] = vTexCoord + sampleDist * vec2(0.507431, 0.064425);"
" samples[9] = vTexCoord + sampleDist * vec2(0.896420, 0.412458);"
" samples[10] = vTexCoord + sampleDist * vec2(-0.321940, -0.932615);"
" samples[11] = vTexCoord + sampleDist * vec2(-0.791559, -0.597705);"
" vec4 sample = texture2D(texture[0], vTexCoord);"
" vec4 avg = sample;"
" vec4 col;"
" for (int i = 0; i < 12; i++)"
" {"
" vec2 tC=min(vec2(0.999,0.999),max(vec2(0.001,0.001),samples[i]));"
" avg +=texture2D(texture[0],tC);"
" }"
" avg /= 13.0;"
" avg.r=pow(avg.r,strength);"
" avg.g=pow(avg.g,strength);"
" avg.b=pow(avg.b,strength);"
" gl_FragColor = sample+avg*multiplier;"
"}";
video::IVideoDriver* driver = smgr->getVideoDriver();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
callback= new PPE_Bloom_callback();
callback->sampleDist=data.sampleDist;
callback->strength=data.strength;
callback->multiplier=data.multiplier;
Material.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader.c_str(), "main", video::EPST_PS_1_1,
callback, (video::EMT_SOLID)
);
rt0 = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
Material.Wireframe = false;
Material.Lighting = false;
Material.setTexture(0, rt0);
}
virtual void OnPreRender(){}
virtual void render()
{
u16 indices[] = {0,1,2,3,4,5};
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
//Renders the Post-Process Effect
virtual u32 getMaterialCount(){return 1;}
virtual video::SMaterial& getMaterial(s32 i){return (Material);}
virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};
// BLUR
class PPE_Blur_callback: public video::IShaderConstantSetCallBack
{
public:
float sampleDist;
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
services->setVertexShaderConstant("sampleDist", reinterpret_cast<f32*>(&sampleDist),1);
}
};
class IPostProcessBlur : public scene::ISceneNode
{
public:
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];//the vertices for the onscreenquad
video::SMaterial Material;
video::ITexture* rt0; //the rendertarget
int mat;
PPE_Blur_callback* callback;
IPostProcessBlur(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
{
Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
}
void initiate(int sizeW,int sizeH,float sampleDist,scene::ISceneManager* smgr)
{
static stringc vertToonShader =
"varying vec2 vTexCoord;"
"void main(void)"
"{"
" vec2 Position;"
" Position.xy = sign(gl_Vertex.xy);"
" gl_Position = vec4(Position.xy, 0.0, 1.0);"
"vTexCoord =Position.xy *.5 + .5;"
"}";
static stringc fragToonShader =
"uniform sampler2D texture[2];"
"varying vec2 vTexCoord;"
"uniform float sampleDist;"
"void main()"
"{"
" vec2 samples[12]; "
" samples[0] = vTexCoord + sampleDist * vec2(-0.326212, -0.405805);"
" samples[1] = vTexCoord + sampleDist * vec2(-0.840144, -0.073580);"
" samples[2] = vTexCoord + sampleDist * vec2(-0.695914, 0.457137);"
" samples[3] = vTexCoord + sampleDist * vec2(-0.203345, 0.620716);"
" samples[4] = vTexCoord + sampleDist * vec2(0.962340, -0.194983);"
" samples[5] = vTexCoord + sampleDist * vec2(0.473434, -0.480026);"
" samples[6] = vTexCoord + sampleDist * vec2(0.519456, 0.767022);"
" samples[7] = vTexCoord + sampleDist * vec2(0.185461, -0.893124);"
" samples[8] = vTexCoord + sampleDist * vec2(0.507431, 0.064425);"
" samples[9] = vTexCoord + sampleDist * vec2(0.896420, 0.412458);"
" samples[10] = vTexCoord + sampleDist * vec2(-0.321940, -0.932615);"
" samples[11] = vTexCoord + sampleDist * vec2(-0.791559, -0.597705);"
" vec4 sample = texture2D(texture[0], vTexCoord);"
" vec4 avg = sample;"
" vec4 col;"
" for (int i = 0; i < 12; i++)"
" {"
" vec2 tC=min(vec2(0.999,0.999),max(vec2(0.001,0.001),samples[i]));"
" col=texture2D(texture[0],tC );"
" float intensity=col.r+col.g+col.b;"
" avg += col; "
" }"
" avg /= 13.0;"
" gl_FragColor = avg;"
"}";
video::IVideoDriver* driver = smgr->getVideoDriver();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
callback= new PPE_Blur_callback;
callback->sampleDist=sampleDist;
Material.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertToonShader.c_str(), "main", video::EVST_VS_1_1,
fragToonShader.c_str(), "main", video::EPST_PS_1_1,
callback, (video::EMT_SOLID)
);
rt0 = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
Material.Wireframe = false;
Material.Lighting = false;
Material.setTexture(0, rt0);
}
virtual void OnPreRender(){}
virtual void render()
{
u16 indices[] = {0,1,2,3,4,5};
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
//Renders the Post-Process Effect
virtual u32 getMaterialCount(){return 1;}
virtual video::SMaterial& getMaterial(s32 i){return (Material);}
virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};
// INVERT
class IPostProcessInvert : public scene::ISceneNode
{
public:
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];//the vertices for the onscreenquad
video::SMaterial Material;
video::ITexture* rt0; //the rendertarget
int mat;
IPostProcessInvert(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
{
Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
}
void initiate(int sizeW,int sizeH,scene::ISceneManager* smgr)
{
static stringc vertToonShader =
"varying vec2 vTexCoord;"
"void main(void)"
"{"
" vec2 Position;"
" Position.xy = sign(gl_Vertex.xy);"
" gl_Position = vec4(Position.xy, 0.0, 1.0);"
"vTexCoord =Position.xy *.5 + .5;"
"}";
static stringc fragToonShader =
"uniform sampler2D texture[2];"
"varying vec2 vTexCoord;"
""
"void main()"
"{"
" vec4 col=texture2D(texture[0],vTexCoord);"
" gl_FragColor =vec4(1.0,1.0,1.0,1.0)-col;"
"}";
video::IVideoDriver* driver = smgr->getVideoDriver();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
Material.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertToonShader.c_str(), "main", video::EVST_VS_1_1,
fragToonShader.c_str(), "main", video::EPST_PS_1_1,
NULL, (video::EMT_SOLID)
);
rt0 = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
Material.Wireframe = false;
Material.Lighting = false;
Material.setTexture(0, rt0);
}
virtual void OnPreRender(){}
virtual void render()
{
u16 indices[] = {0,1,2,3,4,5};
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
//Renders the Post-Process Effect
virtual u32 getMaterialCount(){return 1;}
virtual video::SMaterial& getMaterial(s32 i){return (Material);}
virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};
// MOTION BLUR
class PPE_MotionBlur_callback: public video::IShaderConstantSetCallBack
{
public:
float strength;
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
services->setVertexShaderConstant("strength", reinterpret_cast<f32*>(&strength),1);
int var0=0;
services->setPixelShaderConstant("texture1", (float*)(&var0), 1);
int var1=1;
services->setPixelShaderConstant("texture2", (float*)(&var1), 1);
}
};
class IPostProcessMotionBlur : public scene::ISceneNode
{
public:
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];//the vertices for the onscreenquad
video::SMaterial Material;//the material used with shader
video::SMaterial Accum;//a simple diffuse material..
video::ITexture* next; //the rendertarget
video::ITexture* prev; //the rendertarget
video::ITexture* accum; //the rendertarget
int mat;
PPE_MotionBlur_callback* callback;
IPostProcessMotionBlur(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
{
Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 0.0f);
Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 1.0f);
Vertices[4] = video::S3DVertex(-1.0f, -1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 0.0f, 1.0f);
Vertices[5] = video::S3DVertex( 1.0f, 1.0f, 0.0f,1,1,0, video::SColor(255,0,255,255), 1.0f, 0.0f);
}
void initiate(unsigned int sizeW,unsigned int sizeH,float strength,scene::ISceneManager* smgr)
{
static stringc vertShader =
"varying vec2 vTexCoord;"
"void main(void)"
"{"
" vec2 Position;"
" Position.xy = sign(gl_Vertex.xy);"
" gl_Position = vec4(Position.xy, 0.0, 1.0);"
"vTexCoord =Position.xy *.5 + .5;"
"}";
static stringc fragShader =
"uniform sampler2D texture1;"
"uniform sampler2D texture2;"
"varying vec2 vTexCoord;"
"uniform float strength;"
"void main()"
"{"
" gl_FragColor = mix( texture2D( texture1, vTexCoord ), texture2D( texture2, vTexCoord ), vec4( strength,strength,strength,strength) );"
"}";
static stringc fragShader2 =
"uniform sampler2D texture1;"
"varying vec2 vTexCoord;"
"void main()"
"{"
" gl_FragColor =texture2D( texture1, vTexCoord );"
"}";
video::IVideoDriver* driver = smgr->getVideoDriver();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
callback= new PPE_MotionBlur_callback();
callback->strength=strength;
Material.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader.c_str(), "main", video::EPST_PS_1_1,
callback, (video::EMT_SOLID)
);
Accum.MaterialType=(E_MATERIAL_TYPE)gpu->addHighLevelShaderMaterial
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader2.c_str(), "main", video::EPST_PS_1_1,
NULL, (video::EMT_SOLID)
);
next = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
prev = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
accum = driver->addRenderTargetTexture(core::dimension2d<u32>(sizeW,sizeH));
Material.Wireframe = false;
Material.Lighting = false;
Material.setTexture(0, next);
Material.setTexture(1,prev);
Accum.Wireframe = false;
Accum.Lighting = false;
Accum.setTexture(0, accum);
}
virtual void OnPreRender(){}
virtual void render()
{
u16 indices[] = {0,1,2,3,4,5};
video::IVideoDriver* driver = SceneManager->getVideoDriver(); //Fills Next
driver->setRenderTarget(next, true, true, video::SColor(0,0,0,0));
SceneManager->drawAll();
driver->setRenderTarget(accum, true, true, video::SColor(0,0,0,0)); //Combine Next&prev in accum
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
driver->setRenderTarget(prev, true, true, video::SColor(0,0,0,0)); //Write back accum into prev
driver->setMaterial(Accum);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
virtual void renderFinal()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
u16 indices[] = {0,1,2,3,4,5};
driver->setMaterial(Accum);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 6, &indices[0], 2);
}
virtual u32 getMaterialCount(){return 1;}
virtual video::SMaterial& getMaterial(s32 i){return (Material);}
virtual const core::aabbox3d<f32>& getBoundingBox() const{return Box;}
};
void rc_clearPostEffect(int canvas_id)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return;
rc_canvas[canvas_id].post_effect.is_active = false;
if(rc_canvas[canvas_id].post_effect.object)
{
switch(rc_canvas[canvas_id].post_effect.type)
{
case RC_POST_PROCESS_BLOOM:
{
IPostProcessBloom* post_process = (IPostProcessBloom*)rc_canvas[canvas_id].post_effect.object;
post_process->remove();
}
break;
case RC_POST_PROCESS_BLUR:
{
IPostProcessBlur* post_process = (IPostProcessBlur*)rc_canvas[canvas_id].post_effect.object;
post_process->remove();
}
break;
case RC_POST_PROCESS_COLORIZE:
{
IPostProcessColor* post_process = (IPostProcessColor*)rc_canvas[canvas_id].post_effect.object;
post_process->remove();
}
break;
case RC_POST_PROCESS_MINERAL:
{
IPostProcessGlass* post_process = (IPostProcessGlass*)rc_canvas[canvas_id].post_effect.object;
post_process->remove();
}
break;
case RC_POST_PROCESS_INVERT:
{
IPostProcessInvert* post_process = (IPostProcessInvert*)rc_canvas[canvas_id].post_effect.object;
post_process->remove();
}
break;
case RC_POST_PROCESS_MOTION_BLUR:
{
IPostProcessMotionBlur* post_process = (IPostProcessMotionBlur*)rc_canvas[canvas_id].post_effect.object;
post_process->remove();
}
break;
case RC_POST_PROCESS_RADIAL_BLUR:
{
IPostProcessRadialBlur* post_process = (IPostProcessRadialBlur*)rc_canvas[canvas_id].post_effect.object;
post_process->remove();
}
break;
}
}
rc_canvas[canvas_id].post_effect.object = NULL;
rc_canvas[canvas_id].post_effect.type = -1;
}
bool rc_setPostEffect(int canvas_id, int effect_type)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return false;
rc_clearPostEffect(canvas_id);
rc_canvas[canvas_id].post_effect.type = effect_type;
rc_canvas[canvas_id].post_effect.object = NULL;
rc_canvas[canvas_id].post_effect.is_active = true;
switch(effect_type)
{
case RC_POST_PROCESS_BLOOM:
{
IPostProcessBloom *Bloom = new IPostProcessBloom(SceneManager->getRootSceneNode(), SceneManager, -1);
PPE_Bloom_Setup setup;
setup.sampleDist=0.01;
setup.strength=1;
setup.multiplier=1;
Bloom->initiate(rc_canvas[canvas_id].viewport.dimension.Width, rc_canvas[canvas_id].viewport.dimension.Height, setup, SceneManager);
rc_canvas[canvas_id].post_effect.object = Bloom;
}
break;
case RC_POST_PROCESS_BLUR:
{
IPostProcessBlur *Blur = new IPostProcessBlur(SceneManager->getRootSceneNode(), SceneManager, -1);
float sampleDist = 0.001;
Blur->initiate(rc_canvas[canvas_id].viewport.dimension.Width, rc_canvas[canvas_id].viewport.dimension.Height, sampleDist, SceneManager);
rc_canvas[canvas_id].post_effect.object = Blur;
}
break;
case RC_POST_PROCESS_COLORIZE:
{
IPostProcessColor * PPE_Color = new IPostProcessColor(SceneManager->getRootSceneNode(), SceneManager, -1);
PPE_Color_Setup setup;
setup.saturation=1; //
setup.coloringStrength=1;
setup.col=video::SColorf(0,0,0,0);
PPE_Color->initiate(rc_canvas[canvas_id].viewport.dimension.Width, rc_canvas[canvas_id].viewport.dimension.Height, setup, SceneManager);
rc_canvas[canvas_id].post_effect.object = PPE_Color;
}
break;
case RC_POST_PROCESS_INVERT:
{
IPostProcessInvert *Invert = new IPostProcessInvert(SceneManager->getRootSceneNode(), SceneManager, -1);
Invert->initiate(rc_canvas[canvas_id].viewport.dimension.Width, rc_canvas[canvas_id].viewport.dimension.Height, SceneManager);
rc_canvas[canvas_id].post_effect.object = Invert;
}
break;
case RC_POST_PROCESS_MOTION_BLUR:
{
IPostProcessMotionBlur *Blur = new IPostProcessMotionBlur(SceneManager->getRootSceneNode(), SceneManager, -1);
float strength = 0.1;
Blur->initiate(rc_canvas[canvas_id].viewport.dimension.Width, rc_canvas[canvas_id].viewport.dimension.Height, strength, SceneManager);
rc_canvas[canvas_id].post_effect.object = Blur;
}
break;
case RC_POST_PROCESS_RADIAL_BLUR:
{
IPostProcessRadialBlur *Blur = new IPostProcessRadialBlur(SceneManager->getRootSceneNode(), SceneManager, -1);
float dist = 0.1;
float strength = 1;
Blur->initiate(rc_canvas[canvas_id].viewport.dimension.Width, rc_canvas[canvas_id].viewport.dimension.Height, dist, strength, SceneManager);
rc_canvas[canvas_id].post_effect.object = Blur;
}
break;
case RC_POST_PROCESS_MINERAL:
{
IPostProcessGlass *Glass = new IPostProcessGlass(SceneManager->getRootSceneNode(), SceneManager, -1);
float strength = 0.1;
Glass->initiate(rc_canvas[canvas_id].viewport.dimension.Width, rc_canvas[canvas_id].viewport.dimension.Height, strength, SceneManager);
rc_canvas[canvas_id].post_effect.object = Glass;
}
break;
}
if(!rc_canvas[canvas_id].post_effect.object)
{
rc_canvas[canvas_id].post_effect.is_active = false;
rc_canvas[canvas_id].post_effect.type = -1;
return false;
}
return true;
}
void rc_setPostEffectStrength(int canvas_id, double strength)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return;
int effect_type = rc_canvas[canvas_id].post_effect.type; //type will be -1 if effect has been removed
switch(effect_type)
{
case RC_POST_PROCESS_BLOOM:
{
IPostProcessBloom *Bloom = (IPostProcessBloom*) rc_canvas[canvas_id].post_effect.object;
Bloom->callback->strength = (float)strength;
}
break;
case RC_POST_PROCESS_COLORIZE:
{
IPostProcessColor * PPE_Color = (IPostProcessColor*) rc_canvas[canvas_id].post_effect.object;
PPE_Color->callback->coloringStrength = (float)strength;
}
break;
case RC_POST_PROCESS_MOTION_BLUR:
{
IPostProcessMotionBlur *Blur = (IPostProcessMotionBlur*) rc_canvas[canvas_id].post_effect.object;
Blur->callback->strength = (float)strength;
}
break;
case RC_POST_PROCESS_RADIAL_BLUR:
{
IPostProcessRadialBlur *Blur = (IPostProcessRadialBlur*) rc_canvas[canvas_id].post_effect.object;
Blur->callback->sampleStrength = (float)strength;
}
break;
case RC_POST_PROCESS_MINERAL:
{
IPostProcessGlass *Glass = (IPostProcessGlass*) rc_canvas[canvas_id].post_effect.object;
Glass->callback->strength = (float)strength;
}
break;
}
}
void rc_setPostEffectDistance(int canvas_id, double dist)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return;
int effect_type = rc_canvas[canvas_id].post_effect.type; //type will be -1 if effect has been removed
switch(effect_type)
{
case RC_POST_PROCESS_BLOOM:
{
IPostProcessBloom *Bloom = (IPostProcessBloom*) rc_canvas[canvas_id].post_effect.object;
Bloom->callback->sampleDist = (float)dist;
}
break;
case RC_POST_PROCESS_BLUR:
{
IPostProcessBlur *Blur = (IPostProcessBlur*) rc_canvas[canvas_id].post_effect.object;
Blur->callback->sampleDist = (float)dist;
}
break;
case RC_POST_PROCESS_RADIAL_BLUR:
{
IPostProcessRadialBlur *Blur = (IPostProcessRadialBlur*) rc_canvas[canvas_id].post_effect.object;
Blur->callback->sampleDist = (float)dist;
}
break;
}
}
void rc_setPostEffectMultiplier(int canvas_id, double multiplier)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return;
int effect_type = rc_canvas[canvas_id].post_effect.type; //type will be -1 if effect has been removed
switch(effect_type)
{
case RC_POST_PROCESS_BLOOM:
{
IPostProcessBloom *Bloom = (IPostProcessBloom*) rc_canvas[canvas_id].post_effect.object;
Bloom->callback->multiplier = (float)multiplier;
}
break;
}
}
void rc_setPostEffectSaturation(int canvas_id, double saturation)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return;
int effect_type = rc_canvas[canvas_id].post_effect.type; //type will be -1 if effect has been removed
switch(effect_type)
{
case RC_POST_PROCESS_COLORIZE:
{
IPostProcessColor * PPE_Color = (IPostProcessColor*) rc_canvas[canvas_id].post_effect.object;
PPE_Color->callback->saturation = (float)saturation;
}
break;
}
}
void rc_setPostEffectColor(int canvas_id, double c_color)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return;
int effect_type = rc_canvas[canvas_id].post_effect.type; //type will be -1 if effect has been removed
switch(effect_type)
{
case RC_POST_PROCESS_COLORIZE:
{
IPostProcessColor * PPE_Color = (IPostProcessColor*) rc_canvas[canvas_id].post_effect.object;
PPE_Color->callback->col = irr::video::SColorf( irr::video::SColor((irr::u32) c_color) );
}
break;
}
}
void rc_setPostEffectProperty(int canvas_id, int effect_property, double effect_value)
{
switch(effect_property)
{
case RC_PP_PROPERTY_STRENGTH:
{
rc_setPostEffectStrength(canvas_id, effect_value);
}
break;
case RC_PP_PROPERTY_DISTANCE:
{
rc_setPostEffectDistance(canvas_id, effect_value);
}
break;
case RC_PP_PROPERTY_MULTIPLIER:
{
rc_setPostEffectMultiplier(canvas_id, effect_value);
}
break;
case RC_PP_PROPERTY_SATURATION:
{
rc_setPostEffectSaturation(canvas_id, effect_value);
}
break;
case RC_PP_PROPERTY_COLOR:
{
rc_setPostEffectColor(canvas_id, effect_value);
}
break;
}
}
double rc_getPostEffectStrength(int canvas_id)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return 0;
int effect_type = rc_canvas[canvas_id].post_effect.type; //type will be -1 if effect has been removed
switch(effect_type)
{
case RC_POST_PROCESS_BLOOM:
{
IPostProcessBloom *Bloom = (IPostProcessBloom*) rc_canvas[canvas_id].post_effect.object;
return (double)Bloom->callback->strength;
}
break;
case RC_POST_PROCESS_COLORIZE:
{
IPostProcessColor * PPE_Color = (IPostProcessColor*) rc_canvas[canvas_id].post_effect.object;
return (double)PPE_Color->callback->coloringStrength;
}
break;
case RC_POST_PROCESS_MOTION_BLUR:
{
IPostProcessMotionBlur *Blur = (IPostProcessMotionBlur*) rc_canvas[canvas_id].post_effect.object;
return (double)Blur->callback->strength;
}
break;
case RC_POST_PROCESS_RADIAL_BLUR:
{
IPostProcessRadialBlur *Blur = (IPostProcessRadialBlur*) rc_canvas[canvas_id].post_effect.object;
return (double)Blur->callback->sampleStrength;
}
break;
case RC_POST_PROCESS_MINERAL:
{
IPostProcessGlass *Glass = (IPostProcessGlass*) rc_canvas[canvas_id].post_effect.object;
return (double)Glass->callback->strength;
}
break;
}
return 0;
}
double rc_getPostEffectDistance(int canvas_id)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return 0;
int effect_type = rc_canvas[canvas_id].post_effect.type; //type will be -1 if effect has been removed
switch(effect_type)
{
case RC_POST_PROCESS_BLOOM:
{
IPostProcessBloom *Bloom = (IPostProcessBloom*) rc_canvas[canvas_id].post_effect.object;
return (double)Bloom->callback->sampleDist;
}
break;
case RC_POST_PROCESS_BLUR:
{
IPostProcessBlur *Blur = (IPostProcessBlur*) rc_canvas[canvas_id].post_effect.object;
return (double)Blur->callback->sampleDist;
}
break;
case RC_POST_PROCESS_RADIAL_BLUR:
{
IPostProcessRadialBlur *Blur = (IPostProcessRadialBlur*) rc_canvas[canvas_id].post_effect.object;
return (double)Blur->callback->sampleDist;
}
break;
}
return 0;
}
double rc_getPostEffectMultiplier(int canvas_id)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return 0;
int effect_type = rc_canvas[canvas_id].post_effect.type; //type will be -1 if effect has been removed
switch(effect_type)
{
case RC_POST_PROCESS_BLOOM:
{
IPostProcessBloom *Bloom = (IPostProcessBloom*) rc_canvas[canvas_id].post_effect.object;
return (double)Bloom->callback->multiplier;
}
break;
}
return 0;
}
double rc_getPostEffectSaturation(int canvas_id)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return 0;
int effect_type = rc_canvas[canvas_id].post_effect.type; //type will be -1 if effect has been removed
switch(effect_type)
{
case RC_POST_PROCESS_COLORIZE:
{
IPostProcessColor * PPE_Color = (IPostProcessColor*) rc_canvas[canvas_id].post_effect.object;
return (double)PPE_Color->callback->saturation;
}
break;
}
return 0;
}
double rc_getPostEffectColor(int canvas_id)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return 0;
int effect_type = rc_canvas[canvas_id].post_effect.type; //type will be -1 if effect has been removed
switch(effect_type)
{
case RC_POST_PROCESS_COLORIZE:
{
IPostProcessColor * PPE_Color = (IPostProcessColor*) rc_canvas[canvas_id].post_effect.object;
return (double)PPE_Color->callback->col.toSColor().color;
}
break;
}
return 0;
}
double rc_getPostEffectProperty(int canvas_id, int effect_property)
{
switch(effect_property)
{
case RC_PP_PROPERTY_STRENGTH:
{
return rc_getPostEffectStrength(canvas_id);
}
break;
case RC_PP_PROPERTY_DISTANCE:
{
return rc_getPostEffectDistance(canvas_id);
}
break;
case RC_PP_PROPERTY_MULTIPLIER:
{
return rc_getPostEffectMultiplier(canvas_id);
}
break;
case RC_PP_PROPERTY_SATURATION:
{
return rc_getPostEffectSaturation(canvas_id);
}
break;
case RC_PP_PROPERTY_COLOR:
{
return rc_getPostEffectColor(canvas_id);
}
break;
}
return 0;
}
void rc_setPostEffectActive(int canvas_id, bool flag)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return;
rc_canvas[canvas_id].post_effect.is_active = flag;
}
bool rc_postEffectIsActive(int canvas_id)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return false;
return rc_canvas[canvas_id].post_effect.is_active;
}
void rc_renderPostEffect(int canvas_id)
{
if(!rc_canvas[canvas_id].post_effect.is_active)
return;
int effect_type = rc_canvas[canvas_id].post_effect.type; //type will be -1 if effect has been removed
switch(effect_type)
{
case RC_POST_PROCESS_BLOOM:
{
IPostProcessBloom *Bloom = (IPostProcessBloom*) rc_canvas[canvas_id].post_effect.object;
Bloom->render();
}
break;
case RC_POST_PROCESS_BLUR:
{
IPostProcessBlur *Blur = (IPostProcessBlur*) rc_canvas[canvas_id].post_effect.object;
Blur->render();
}
break;
case RC_POST_PROCESS_COLORIZE:
{
IPostProcessColor * PPE_Color = (IPostProcessColor*) rc_canvas[canvas_id].post_effect.object;
PPE_Color->render();
}
break;
case RC_POST_PROCESS_INVERT:
{
IPostProcessInvert *Invert = (IPostProcessInvert*) rc_canvas[canvas_id].post_effect.object;
Invert->render();
}
break;
case RC_POST_PROCESS_MOTION_BLUR:
{
IPostProcessMotionBlur *Blur = (IPostProcessMotionBlur*) rc_canvas[canvas_id].post_effect.object;
Blur->renderFinal();
}
break;
case RC_POST_PROCESS_RADIAL_BLUR:
{
IPostProcessRadialBlur *Blur = (IPostProcessRadialBlur*) rc_canvas[canvas_id].post_effect.object;
Blur->render();
}
break;
case RC_POST_PROCESS_MINERAL:
{
IPostProcessGlass *Glass = (IPostProcessGlass*) rc_canvas[canvas_id].post_effect.object;
Glass->render();
}
break;
}
}
int rc_getPostEffectType(int canvas_id)
{
if(canvas_id <= 0 || canvas_id >= rc_canvas.size())
return -1;
if(!rc_canvas[canvas_id].post_effect.is_active)
return -1;
return rc_canvas[canvas_id].post_effect.type; //type will be -1 if effect has been removed
}
#endif // RC_POST_FX_H_INCLUDED