It is in development , but the version 1.0 is finnished . I am going to put the code for suggestion of the people. For 2.0 i want to do two rendertarget for complex filters
The SceneNodeFilter is a object. and the filters shader must be in a file hlsl
In the first code, you can see the object have a rendertarget, a object IShaderConstantSetCallBack for constant of shader and important anything
The idea is follow : you create the filter object and associate it the file hlsl with the filter , you create your scene (all nodes ) , you render your scene in the render target of filter object, and after select render target 0 and render de filter object
I put 3 codes :
1) the main.cpp with the code of filter object and a example of use
2) normal.hlsl ( filter normal -> no filter )
3) Black&White.hlhl
4) BLUR.hlsl ( for this filter you need a graphics target with ps 2.0)
In future versions i will put :
a second render target for complex filters
filter gaussian
alpha test
reflactoin
deep of field
z-testing
etc. I think put it in the wiki section , but i dont know how do it
MAIN.cpp
Code: Select all
#include "include/irrlicht.h"
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
float viewport_inv_width;
float viewport_inv_height;
virtual void OnSetConstants(video::IMaterialRendererServices* services)
{
video::IVideoDriver* driver = services->getVideoDriver();
services->setVertexShaderConstant("viewport_inv_width", reinterpret_cast<f32*>(&viewport_inv_width), 1);
services->setVertexShaderConstant("viewport_inv_height", reinterpret_cast<f32*>(&viewport_inv_height), 1);
}
};
class CBaseFilter : public scene::ISceneNode
{
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];
public:
video::SMaterial Material;
c8* vsFileName; // filename for the vertex shader
c8* psFileName; // filename for the pixel shader
int newMaterialType1;
MyShaderCallBack* mc;
video::ITexture* rt0;
int alto;
int ancho;
public:
CBaseFilter(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
: scene::ISceneNode(parent, mgr, id)
{
Material.Wireframe = false;
Material.Lighting = false;
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);
Box.reset(Vertices[0].Pos);
for (s32 i=1; i<4; ++i)
Box.addInternalPoint(Vertices[i].Pos);
mc = new MyShaderCallBack();
video::IVideoDriver* driver = SceneManager->getVideoDriver();
rt0 = driver->createRenderTargetTexture(core::dimension2d<s32>(640,480));
setMaterialTexture(0, rt0);
}
virtual void OnPreRender()
{
if (IsVisible)
//SceneManager->registerNodeForRendering(this);
ISceneNode::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 const core::aabbox3d<f32>& getBoundingBox() const
{
return Box;
}
virtual s32 getMaterialCount()
{
return 1;
}
virtual video::SMaterial& getMaterial(s32 i)
{
return Material;
}
};
int main()
{
// create engine and camera
IrrlichtDevice *device =
createDevice(video::EDT_DIRECTX9, core::dimension2d<s32>(640, 480), 16, false);
device->setWindowCaption(L"Custom Scene Node - Irrlicht Engine Demo");
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
smgr->addCameraSceneNodeFPS();
//------------------------------------------------------------------------
// create my filter object
//1)create of object
CBaseFilter *myFilter = new CBaseFilter(smgr->getRootSceneNode(), smgr, 666);
//2)select shader
myFilter->psFileName = "Black&White.hlsl";
myFilter->vsFileName = "Black&White.hlsl";
//3)create "new material shader" and associate with filter
myFilter->newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
myFilter->vsFileName,"vertexMain", video::EVST_VS_1_1,
myFilter->psFileName, "pixelMain", video::EPST_PS_1_1,
myFilter->mc, video::EMT_SOLID);
myFilter->setMaterialType((video::E_MATERIAL_TYPE)myFilter->newMaterialType1);
//4) pass the constant-variables to IShaderConstantSetCallBack
myFilter->mc->viewport_inv_height=1/480;
myFilter->mc->viewport_inv_width=1/640;
myFilter->drop();
//------------------------------------------------------------------------------------
// create a simple object for rendering any scene (this is only like example)
scene::ISceneNode* node = smgr->addTestSceneNode(50);
node->setPosition(core::vector3df(0,0,80));
node->setMaterialTexture(0, driver->getTexture("wall.bmp"));
//------------------------------------------------------------------------------------
while(device->run())
{
driver->beginScene(true, true, video::SColor(0,100,100,100));
driver->setRenderTarget(myFilter->rt0,true, true, video::SColor(0,0,0,255));
smgr->drawAll();
driver->setRenderTarget(0);
myFilter->render();
driver->endScene();
}
device->drop();
return 0;
}
Code: Select all
float4x4 view_proj_matrix;
float viewport_inv_width;
float viewport_inv_height;
struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 texCoord: TEXCOORD0;
};
VS_OUTPUT vertexMain( in float4 Pos : POSITION)
{
VS_OUTPUT Out;
Out.Pos = float4(Pos.xy, 0, 1);
Out.texCoord.x = 0.5 * (1 + Pos.x - viewport_inv_width);
Out.texCoord.y = 0.5 * (1 - Pos.y - viewport_inv_height);
return Out;
}
struct PS_OUTPUT
{
float4 RGBColor : COLOR0; // Pixel color
};
sampler2D tex0;
PS_OUTPUT pixelMain( float2 TexCoord : TEXCOORD0,
float4 Position : POSITION,
float4 Diffuse : COLOR0 )
{
PS_OUTPUT Output;
float4 col = tex2D( tex0, TexCoord );
Output.RGBColor= col;
return Output;
}
Code: Select all
float4x4 view_proj_matrix;
float viewport_inv_width;
float viewport_inv_height;
struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 texCoord: TEXCOORD0;
};
VS_OUTPUT vertexMain( in float4 Pos : POSITION)
{
VS_OUTPUT Out;
Out.Pos = float4(Pos.xy, 0, 1);
Out.texCoord.x = 0.5 * (1 + Pos.x - viewport_inv_width);
Out.texCoord.y = 0.5 * (1 - Pos.y - viewport_inv_height);
return Out;
}
struct PS_OUTPUT
{
float4 RGBColor : COLOR0; // Pixel color
};
sampler2D tex0;
PS_OUTPUT pixelMain( float2 TexCoord : TEXCOORD0,
float4 Position : POSITION,
float4 Diffuse : COLOR0 )
{
PS_OUTPUT Output;
float4 col = tex2D( tex0, TexCoord );
float Intensity = 0.299*col.r + 0.587*col.g + 0.184*col.r;
Output.RGBColor=float4(Intensity.xxx,col.a);;
return Output;
}
float4x4 view_proj_matrix;
float viewport_inv_width;
float viewport_inv_height;
struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 texCoord: TEXCOORD0;
};
VS_OUTPUT vertexMain( in float4 Pos : POSITION)
{
VS_OUTPUT Out;
Out.Pos = float4(Pos.xy, 0, 1);
Out.texCoord.x = 0.5 * (1 + Pos.x - viewport_inv_width);
Out.texCoord.y = 0.5 * (1 - Pos.y - viewport_inv_height);
return Out;
}
sampler2D Texture0;
const float4 samples[4] = {
-1.0, 0.0, 0, 0.25,
1.0, 0.0, 0, 0.25,
0.0, 1.0, 0, 0.25,
0.0, -1.0, 0, 0.25
};
float4 pixelMain( float2 texCoord: TEXCOORD0) : COLOR
{
float4 col = float4(0,0,0,0);
// Sample and output the box averaged colors
for(int i=0;i<4;i++)
col += samples.w*tex2D(Texture0,texCoord+float2(samples.x*viewport_inv_width,samples.x*viewport_inv_height));
return col;
}