Hi!
Im rendering my scene into a RTT and then displaying that texture on the screen using the draw2dImage() function. My question is: How can I send this texture to a shader?
An even better question would be: How would I go about sending to a shader, an individual texture that isn't attached or contained within a scene node?
Thanks in advance!
Short question regarding RTT textures and shaders...
In irrlicht you can only apply shaders to nodes, the draw 2d function draws some predefined polygons which can a have shader applied to them like the polygons of a node, however i dont think irlicht has the option to apply shaders to anything but materialable nodes (not the 2d function polygons). You can use a normal mesh node with a quad/ two trianglualr polygons and use the vertex shader to transform these polygons into 2d space like what the 2d function is doing. Sending the texture would just be applying a texture to the node.
"Irrlicht is obese"
If you want modern rendering techniques learn how to make them or go to the engine next door =p
If you want modern rendering techniques learn how to make them or go to the engine next door =p
-
- Posts: 275
- Joined: Fri May 12, 2006 6:37 pm
- Location: Germany
I have what you need^^
Its a Class which give you the power to create a mesh, which is used as onscreen-quad. All you have to do is to set the pixelshader& its constants.
pretty simple isn´t it??
(i gonna releas the code in a few hours but here i´ll post some pre version..)
the render code is based on an other node i found here in the forum, but this code was old, and doesn´t work for some (unknow) reasons, so i modefied it heavily...
All you have to do, for to use it, is
and in your main loop:
hope this helps...
tgm[/code]
Its a Class which give you the power to create a mesh, which is used as onscreen-quad. All you have to do is to set the pixelshader& its constants.
pretty simple isn´t it??
(i gonna releas the code in a few hours but here i´ll post some pre version..)
Code: Select all
#ifndef __POST_PROCESS_EFFECT_BLUR__
#define __POST_PROCESS_EFFECT_BLUR__
#include "irrlicht.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
// the shader callback.. you have to set your shader constants here(just like sampleDist)
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);
}
};
// and this is the real class.. just replace the pixel shader code in the initiate function whit your one()
//if you use hlsl istead of GLSL, you even hav to replace the Vertexshader code
class IPostProcessBlur : public scene::ISceneNode
{
public:
core::aabbox3d<f32> Box;
video::S3DVertex Vertices[6];//the vertices for the onscreenquad
video::SMaterial Material;
PPE_Blur_callback* shaderCallback; //the used shadercallback for PPE shader
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(unsigned int size,float sampleDist,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 sampleStrength;"
"uniform float saturation;"
"uniform float coloringStrength;"
"uniform vec4 coloring;"
"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++)"
" {"
" col=texture2D(texture[0],samples[i]);"
" 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
(
vertShader.c_str(), "main", video::EVST_VS_1_1,
fragShader.c_str(), "main", video::EPST_PS_1_1,
callback, (video::EMT_SOLID)
);
rt0 = driver->createRenderTargetTexture(core::dimension2d<s32>(size,size));
Material.Wireframe = false;
Material.Lighting = false;
Material.Textures[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;}
};
#endif
All you have to do, for to use it, is
Code: Select all
IPostProcessBlur *BlurFilter = new IPostProcessBlur(smgr->getRootSceneNode(), smgr, 666);
BlurFilter->initiate(512,0.0005,smgr);
Code: Select all
driver->beginScene(true, true, 0);
driver->setRenderTarget(BlurFilter->rt0, true, true, video::SColor(0,0,0,0));
smgr->drawAll();
driver->setRenderTarget(0);
BlurFilter->render();
}
driver->endScene();
tgm[/code]
Thanks for replaying!
It seams like one cant send individual textures to shaders in IRRLicht, but thats fine... I solved my problem by using my own "quad", which I exported from Blender...
BTW: Thanks TheGameMaker for taking the time to write some code for me, but I think that thats a bit to advanced for me...
It seams like one cant send individual textures to shaders in IRRLicht, but thats fine... I solved my problem by using my own "quad", which I exported from Blender...
BTW: Thanks TheGameMaker for taking the time to write some code for me, but I think that thats a bit to advanced for me...