the definition of node is the part :
Code: Select all
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;
}
};
This node need file shader (hlsl,glsl,vs,ps etc , anyone) for the effect post-processing
In the code of top, i put three examples (three files shaders):
normal.hlsl ->it doesnt change anything
black&white.hlsl-> (no commnet)
blur.hlsl->(no comment)
(you can do your own shaders files and put it in this forum for all people)
it is VERY simple
You can put a lot of nodes-filter , but i recommend only two like maximun, for do loops
In the example of the top of thread i put only one filter black&white, like old TV
For declaration the filter in code main.cpp:
Code: Select all
//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();
BUT the DIFFERENT is in the RENDER SCENE
the node filter has a texture rrender target. you select that render target and render your scene nomal (example of main.cpp)
Code: Select all
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();
Now you select the render target 0 (backbuffer) and render ONLY the node-filter :
Code: Select all
driver->setRenderTarget(0);
myFilter->render();
driver->endScene();
}
device->drop();
return 0;
}
Explication:
http://pruebalaboratorio.iespana.es/Dibujo.bmp
Examples:
http://pruebalaboratorio.iespana.es/1.bmp
http://pruebalaboratorio.iespana.es/2.bmp
NOTE (for the example of the top you need copy the texture "wall.bmp" , file "black&white.hlsl" and DIR "include" of irrlicht in the same DIR of the your main.cpp)
Other question is combinate various nodes doing loops. For example for doing complex blur. It is explicated more top
The idea for this node-filter-shader is the people can do your own filters-shader (files hlsl,glsls,vs or ps, and put it for all pepole of irrlicht)