A Bit of a mess and far from optimized, but here is the code for the Post Processor Class..
I used it as a class with its own render function and not as a Custom Scene Node like the clouds and the water
while developing.. (it works fine under GL GLSL, but HLSL ...)
Code: Select all
#ifndef POSTPROCESSOR_INCD
#define POSTPROCESSOR_INCD
#include <irrlicht.h>
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
// using namespace gui;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// class PostProcShadCallbckGLSL; // As a forward declaration because we might refer to it before we define it.. (I love c++)
// class PostProcShadCallbckHLSL; // As a forward declaration because we might refer to it before we define it.. (I love c++)
// GLSL..
class PostProcShadCallbckGLSL : public video::IShaderConstantSetCallBack
{public:
virtual void OnSetConstants(video::IMaterialRendererServices* MatRenderServices,s32 userData)
{video::IVideoDriver* AquiredVideoDriver = MatRenderServices->getVideoDriver();
s32 TextureLayerID = 0;
MatRenderServices->setPixelShaderConstant ("Image01", (s32*)(&TextureLayerID), 1); // To where the scne was rendered..
// Later, for when we deal with complex multipass effects..
// TextureLayerID = 1;
// Optional extra Texture used in Additional Effects..
// MatRenderServices->setPixelShaderConstant ("Image02",(s32*)(&TextureLayerID), 1);
}
};
// HLSL..
class PostProcShadCallbckHLSL : public video::IShaderConstantSetCallBack
{public:
virtual void OnSetConstants(video::IMaterialRendererServices* MatRenderServices,s32 userData)
{video::IVideoDriver* AquiredVideoDriver = MatRenderServices->getVideoDriver();
// here as a test.. not used..
M01World = AquiredVideoDriver->getTransform(video::ETS_WORLD);
M05WorldViewProjection = AquiredVideoDriver->getTransform(video::ETS_PROJECTION);
M05WorldViewProjection *= AquiredVideoDriver->getTransform(video::ETS_VIEW);
M05WorldViewProjection *= AquiredVideoDriver->getTransform(video::ETS_WORLD);
M17WorldInverseTranspose = M01World.getTransposed(); // For Irrlicht this replaces the commonly used "world matrix!"
M17WorldInverseTranspose.makeInverse();
/*
MatRenderServices->setVertexShaderConstant("M01World", M01World.pointer(), 16);
MatRenderServices->setVertexShaderConstant("M05WorldViewProjection", M05WorldViewProjection.pointer(), 16);
MatRenderServices->setVertexShaderConstant("M17WorldInverseTranspose", M17WorldInverseTranspose.pointer(), 16);
*/
s32 TextureLayerID = 0;
MatRenderServices->setPixelShaderConstant("Image01", (s32*)(&TextureLayerID), 1); // To where the scne was rendered..
// Later, for when we deal with complex multipass effects..
// TextureLayerID = 1;
// Optional extra Texture used in Additional Effects..
// MatRenderServices->setPixelShaderConstant("Image02", (s32*)(&TextureLayerID), 1);
}
private:
IrrlichtDevice* PassedIrrDevice;
video::IVideoDriver* AquiredVideoDriver;
core::matrix4 M01World;
core::matrix4 M05WorldViewProjection;
core::matrix4 M17WorldInverseTranspose;
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Class to hold our Screen Quad and Render-Target texture..
class ScreenQuadAndTexture
{public:
// ScreenQuadAndTexture(IrrlichtDevice* PassDevice);
ScreenQuadAndTexture();
~ScreenQuadAndTexture();
void CleanUp();
ITexture* GetAlterTextFirst ();
ITexture* GetAlterTextSecond ();
ITexture* GetFlippedTexture ();
void FlipTextures ();
void WriteAltFirstToFile ();
void Reset();
void RenderSinglePass(s32 ChosenSHADERID);
void RenderToScreen();
void Draw2DImage();
video::SMaterial& getMaterial();
void SetTextureSize(u32 XRes, u32 YRes);
void AddFragShaderByFilename(const char* TheFileName);
void DeleteFragShaderByFilename(const char* TheFileName);
u32 GetFragShaderArraySize();
const char* GetFragShaderShaderFileNameByIndex(u32 GetI);
void InsertFragShaderShaderFileNameAtIndex(const char* TheFileName,u32 GetInsetrI);
void DeleteFragShaderByIndex(u32 DelI);
void SetPassShader (u32 PassI, u32 UncheckedI);
void ShiftPassShaderToNext (u32 PassI);
void ShiftPassShaderToPrevious (u32 PassI);
void AddPPRenderPass ();
u32 GetPPRenderPassCount ();
u32 GetPassShaderIndex (u32 PassI);
u32 GetGeneratedShaderID (u32 Index);
void SetDevice (IrrlichtDevice* SetDevice);
void RenderPassesThenToScreen();
private:
IrrlichtDevice* PassedIrrDevice;
video::IVideoDriver* AquiredVideoDriver;
video::ITexture* FlippedTexture;
video::ITexture* TempTexture;
video::ITexture* AlterTexSECOND;
video::ITexture* AlterTexFIRST;
video::ITexture* AlterTexTHIRD;
video::SMaterial ScreenQuadMaterial;
video::S3DVertex vert[4];
// THE OTHER VERTICES..
video::S3DVertex Vertices[4]; // Screen Quad mesh..
u16 index[6];
u16 Indices[6];
bool Flipper;
bool FirstRender;
irr::video::IImage* TestImage;
u32 TxXRes;
u32 TxYRes;
core::array<const char*> ShaderFileNames; // Should include directory name relative to the EXE file..
s32 PassShaderIDs [32]; // Which Effect is chosen for a given Pass..
s32 ShaderIDarray [32]; // s32, as it is filled with Shader IDs as returned by "addHighLevelShaderMaterialFromFiles"..
s32 ShaderGeneratedIDs [32];
core::array<u32> GeneratedShaderIDs;
core::array<u32> PassShaderAssignments;
core::array<u32> CurrentShaderIDIndices;
u32 RenderPassCount;
u32 PPShaderCount;
PostProcShadCallbckGLSL* TheCallbackForGLSL;
PostProcShadCallbckHLSL* TheCallbackForHLSL;
video::IGPUProgrammingServices* TheGPUServices;
video::E_DRIVER_TYPE TheSelectedDriverType;// aquired from "AquiredVideoDriver"..
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ScreenQuadAndTexture::ScreenQuadAndTexture() : Flipper (0), FirstRender(true)
{
// AquiredVideoDriver = PassDevice->getVideoDriver();
RenderPassCount = 0;
PPShaderCount = 0;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ScreenQuadAndTexture::~ScreenQuadAndTexture()
{// LEft here as a reminder..
// if ((AlterTexSECOND)) AquiredVideoDriver->removeTexture(AlterTexSECOND);
// if ((AlterTexFIRST)) AquiredVideoDriver->removeTexture(AlterTexFIRST);
// if ((AlterTexTHIRD)) AquiredVideoDriver->removeTexture(AlterTexTHIRD);
// PassedIrrDevice->drop(); // THE HIST SHOULD BE RESPONSIBLE FOR THIS....
}
void ScreenQuadAndTexture::CleanUp() // HOST WANTS YOU TO DO THIS AT THE RIGHT TIME..???
{// Take a good look at how we alternate between these two textures during Multipass Rendering..
if ((AlterTexSECOND)) AquiredVideoDriver->removeTexture(AlterTexSECOND);
if ((AlterTexFIRST)) AquiredVideoDriver->removeTexture(AlterTexFIRST);
if ((AlterTexTHIRD)) AquiredVideoDriver->removeTexture(AlterTexTHIRD);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ITexture* ScreenQuadAndTexture::GetAlterTextFirst ()
{return AlterTexFIRST;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ITexture* ScreenQuadAndTexture::GetAlterTextSecond ()
{return AlterTexSECOND;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ITexture* ScreenQuadAndTexture::GetFlippedTexture ()
{return FlippedTexture;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::FlipTextures ()
{
FlippedTexture = Flipper == 0 ? AlterTexFIRST : AlterTexSECOND;
Flipper = !Flipper;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::WriteAltFirstToFile ()
{
TestImage = AquiredVideoDriver->createImage(irr::video::ECF_A8R8G8B8,core::dimension2d<u32>( 512 , 512 ));
// Someone noted..
// You can use textures as rendertarget (IVideoDriver::setRenderTarget).
// And then convert the texture to an IImage (IVideoDriver::createImage).
// I don't think there is a solution aside from that in Irrlicht.
TestImage->setPixel(10, 10, SColor( 255 , 207 , 223 , 169 )); // Test works..
TestImage->fill(SColor( 255 , 207 , 0 , 0 )); // Test works..
// AquiredVideoDriver->setRenderTarget(TestImage, false, false); // No!
// FIGURE THIS OUT..
AquiredVideoDriver->writeImageToFile(TestImage,L"data/XXXXsample.jpg");
TestImage->drop();
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::Reset()
{FirstRender = true;
Flipper = 0;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::RenderSinglePass(s32 ChosenSHADERID)
{
if (FirstRender = true )
{FlipTextures (); FirstRender = false;} // As the very first render was to "AlterTexFIRST"..
// ---- --- -- - Pass (for multipass effects this is the basis) --- --- -- -
ScreenQuadMaterial.setTexture(0, FlippedTexture); // Allready done in "main", but ommitting this causes a strange initial "flash"..
ScreenQuadMaterial.MaterialType = (video::E_MATERIAL_TYPE) ChosenSHADERID;
AquiredVideoDriver->setMaterial(ScreenQuadMaterial); // Because we had assigned the material a new shader..
FlipTextures ();
AquiredVideoDriver->setRenderTarget(FlippedTexture, false, false);
// AquiredVideoDriver->drawIndexedTriangleList(vert, 4, index, 2);
// THESE DID NTO HELP FOR HLSL..
//AquiredVideoDriver->setTransform(video::ETS_PROJECTION, core::IdentityMatrix); // clear the projection matrix
//AquiredVideoDriver->setTransform(video::ETS_VIEW, core::IdentityMatrix); // clear the view matrix
//AquiredVideoDriver->setTransform(video::ETS_WORLD, core::IdentityMatrix ); // set the transform
//AquiredVideoDriver->setMaterial(ScreenQuadMaterial);
//AquiredVideoDriver->drawIndexedTriangleList(Vertices, 4, Indices, 2);
// ---- --- -- -
FlipTextures ();
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::RenderToScreen()
{
// Render the "FINAL PROCESSES PIXELS" to the "FRAME BUFFER"..
AquiredVideoDriver->setRenderTarget(video::ERT_FRAME_BUFFER, true, true);
AquiredVideoDriver->drawIndexedTriangleList(vert, 4, index, 2);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::RenderPassesThenToScreen()
{
for (u32 PassIndx = 0; PassIndx < RenderPassCount; PassIndx++)
{
if (FirstRender = true )
{FlipTextures (); FirstRender = false;} // As the very first render was to "AlterTexFIRST"..
// ---- --- -- - Pass (for multipass effects this is the basis) --- --- -- -
ScreenQuadMaterial.setTexture(0, FlippedTexture); // Allready done in "main", but ommitting this causes a strange initial "flash"..
ScreenQuadMaterial.MaterialType
// = (video::E_MATERIAL_TYPE) GetGeneratedShaderID (GetPassShaderIndex (PassIndx)); // Shows how we reached this index into the array below..
= (video::E_MATERIAL_TYPE) GeneratedShaderIDs[CurrentShaderIDIndices [PassIndx]] ;
AquiredVideoDriver->setMaterial(ScreenQuadMaterial); // Because we had assigned the material a new shader..
FlipTextures (); // May need arch redo for effects..
AquiredVideoDriver->setRenderTarget(FlippedTexture, false, false);
AquiredVideoDriver->drawIndexedTriangleList(vert, 4, index, 2);
// ---- --- -- -
FlipTextures ();
}
AquiredVideoDriver->setRenderTarget(video::ERT_FRAME_BUFFER, true, true);
AquiredVideoDriver->drawIndexedTriangleList(vert, 4, index, 2); // Final render before buffers swap..
// Reset... (also available as a function possible needed in further development)..
FirstRender = true;
Flipper = 0;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::Draw2DImage()
{TempTexture = Flipper == 0 ? AlterTexFIRST : AlterTexSECOND;
AquiredVideoDriver->draw2DImage(TempTexture,
core::rect<s32>(0 + 128,
0 + 128,
(TempTexture->getSize().Width / 2) + 128,
(TempTexture->getSize().Height / 2) + 128),
core::rect<s32>(0 + 128,
0 + 128,
(TempTexture->getSize().Width / 8) + 128,
(TempTexture->getSize().Height / 8) + 128 )
);
}
video::SMaterial& ScreenQuadAndTexture::getMaterial()
{return ScreenQuadMaterial;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::SetTextureSize(u32 XRes, u32 YRes)
{TxXRes = XRes;
TxYRes = YRes;
AlterTexSECOND = AquiredVideoDriver->addRenderTargetTexture(core::dimension2d<u32>(XRes, YRes)); // SAME AS IN FXAA!!!
AlterTexFIRST = AquiredVideoDriver->addRenderTargetTexture(core::dimension2d<u32>(XRes, YRes));
AlterTexTHIRD = AquiredVideoDriver->addRenderTargetTexture(core::dimension2d<u32>(XRes, YRes)); // Future advanced stuff where images are mixed after PP..
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::AddFragShaderByFilename(const char* TheFileName)
{// if(ShaderFileNames.binary_search(TheFileName) == -1) // UNDERSTAND WHY THIS WAS USED IN OTHER CODE..
// if(ShaderFileNames.linear_search(TheFileName) == -1) // IF WE WANTED TO REFER TO A SHADER ID BY ITS FILENAME AND NOT JUST AN INDEX??
ShaderFileNames.push_back(TheFileName); // Add a new filename..
CurrentShaderIDIndices.push_back(0);
u32 ResutlingID = 0;
//
if (TheSelectedDriverType == EDT_OPENGL)
{
TheCallbackForGLSL = new PostProcShadCallbckGLSL(); // DO THEY DIFFER BETWEEN GLSL AND HLSL? NO!..
ResutlingID = TheGPUServices
->addHighLevelShaderMaterialFromFiles("Shaders/GL_0000_VERT_PP_GENERIC.glsl",
"main", EVST_VS_2_0, TheFileName,
"main", EPST_PS_3_0, TheCallbackForGLSL,
EMT_SOLID, 0, EGSL_DEFAULT
);
}
if (TheSelectedDriverType == EDT_DIRECT3D9)
{
// printf("THIS HAPPENED"); while (1 == 1) {}
TheCallbackForHLSL = new PostProcShadCallbckHLSL(); // DO THEY DIFFER BETWEEN GLSL AND HLSL? NO!..
ResutlingID = TheGPUServices
->addHighLevelShaderMaterialFromFiles( "Shaders/HL_0000_VERT_PP_GENERIC.hlsl", //..
// TheFileName, //..
"VertexMain", EVST_VS_3_0, TheFileName,
"PixelMain", EPST_PS_3_0, TheCallbackForHLSL,
EMT_SOLID, 0, EGSL_DEFAULT
);
}
GeneratedShaderIDs.push_back(ResutlingID);
if (TheSelectedDriverType == EDT_OPENGL)
{
TheCallbackForGLSL->drop();
}
if (TheSelectedDriverType == EDT_DIRECT3D9)
{
TheCallbackForHLSL->drop();
}
//
PPShaderCount ++;
// printf("THIS HAPPENED"); while (1 == 1) {}
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::DeleteFragShaderByFilename(const char* TheFileName)
{s32 index = ShaderFileNames.binary_search(TheFileName); // Remove node from depth pass array..
if(index != -1) ShaderFileNames.erase(index);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::DeleteFragShaderByIndex(u32 DelI)
{ ShaderFileNames.erase(DelI);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
u32 ScreenQuadAndTexture::GetFragShaderArraySize()
{return ShaderFileNames.size();
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const char* ScreenQuadAndTexture::GetFragShaderShaderFileNameByIndex(u32 GetI)
{return ShaderFileNames[GetI];
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::InsertFragShaderShaderFileNameAtIndex(const char* TheFileName,u32 GetInsetrI)
{return ShaderFileNames.insert(TheFileName,GetInsetrI);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::SetPassShader (u32 PassI, u32 UncheckedI)
{CurrentShaderIDIndices [PassI] = UncheckedI;
PassShaderAssignments [PassI] = GeneratedShaderIDs[CurrentShaderIDIndices[UncheckedI]]; // CHECK FOR MAX..
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::ShiftPassShaderToNext (u32 PassI) // At least one pass must have been created..
{
// /*
if (CurrentShaderIDIndices [PassI] >= (PPShaderCount - 1))
{CurrentShaderIDIndices [PassI] = 0;
PassShaderAssignments [PassI] = GeneratedShaderIDs[CurrentShaderIDIndices [PassI]];
return;
}
CurrentShaderIDIndices [PassI] ++;
PassShaderAssignments [PassI] = GeneratedShaderIDs[CurrentShaderIDIndices [PassI]];
// *//
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::ShiftPassShaderToPrevious (u32 PassI)
{
// /*
if (CurrentShaderIDIndices [PassI] == 0)
{CurrentShaderIDIndices [PassI] = (PPShaderCount - 1);
PassShaderAssignments [PassI] = GeneratedShaderIDs[CurrentShaderIDIndices [PassI]];
return;
}
CurrentShaderIDIndices [PassI] --;
PassShaderAssignments [PassI] = GeneratedShaderIDs[CurrentShaderIDIndices [PassI]];
// */
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
u32 ScreenQuadAndTexture::GetPassShaderIndex (u32 PassI)
{return CurrentShaderIDIndices [PassI]; // Wre not interested in the actual ID, but we are in the Index..
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// case KEY_KEY_1: PassShaderIDs [0]++; if(PassShaderIDs [0] > 16) {PassShaderIDs [0] = 0;} break;
void ScreenQuadAndTexture::AddPPRenderPass ()
{RenderPassCount++;
//CurrentShaderIDIndices.push_back(0); // All Created Pass Shader ID Incices at 0 (bypass)..
PassShaderAssignments.push_back(0);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
u32 ScreenQuadAndTexture::GetPPRenderPassCount ()
{
return RenderPassCount;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
u32 ScreenQuadAndTexture::GetGeneratedShaderID (u32 Index)
{
return GeneratedShaderIDs[Index];
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ScreenQuadAndTexture::SetDevice (IrrlichtDevice* SetDevice)
{ PassedIrrDevice = SetDevice;
AquiredVideoDriver = PassedIrrDevice->getVideoDriver();
TheSelectedDriverType = AquiredVideoDriver->getDriverType();
// PassedIrrDevice->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
// PassedIrrDevice->getVideoDriver()->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
//
// video::IGPUProgrammingServices* TheGPUServices = AquiredVideoDriver->getGPUProgrammingServices();
// Done once at construction..
TheGPUServices = AquiredVideoDriver->getGPUProgrammingServices();
if (TheGPUServices == 0)
{std::cout << "Could not access the GPU" << std::endl;
// return 3;
}
// PostProcShadCallbckGLSL* TheCallbackForGLSL = new PostProcShadCallbckGLSL();
// TheCallbackForGLSL = new PostProcShadCallbckGLSL();
//
// These "Render Target Resolutions" could have been copied from "Device Resolution"..
// With "FXAA", this Buffer Resolution should be Identical to its reference inside the "FXAA" Shader Code..
// While we don't control these values inside the shader code from the application we should make sure they are the same..
// We have TWO Render Target Textures because we "Alternate" or "Flip-Flop" between them to make the "Multi Layering" of PP-Effects possible..
// NOTE: When your Render Target Texture is not EXACTLY the same size (Biggest value between X and Y) as your 3d View, i.e.
// your Window Viewport then there will be some "automatic smoothing" of the pixels in the Rendertarget
// which means that FXAA would not be fed the bare pixels and that the full effect of FXAA may not be achieved,
// but, FXAA still does a mrvelous job! In any case, many times our RTT is smaller than the Window Viewort.
// AlterTexSECOND = AquiredVideoDriver->addRenderTargetTexture(core::dimension2d<u32>( 512, 512 )); // SAME AS IN FXAA!!!
// AlterTexFIRST = AquiredVideoDriver->addRenderTargetTexture(core::dimension2d<u32>( 512, 512 ));
// AlterTexTHIRD = AquiredVideoDriver->addRenderTargetTexture(core::dimension2d<u32>( 512, 512 )); // Future advanced stuff where images are mixed after PP..
FlippedTexture = AlterTexFIRST;
// When dealing with BLUR based PP Effects it is usually better to save time by using
// smaller images as resolution becomes less important with blur..
// Also note that these are only two images accesed in an alternating fasion for this
// example and that we could have many images in different sizes for different effects.
// It is however still important to keep the buffers related to FXAA at the same resolution
// as the resolution referred to inside the FXAA Shader..
ScreenQuadMaterial.Wireframe = false; // Material for screen quad
ScreenQuadMaterial.Lighting = false;
ScreenQuadMaterial.ZWriteEnable = false;
ScreenQuadMaterial.TextureLayer->TextureWrapU = ETC_CLAMP_TO_EDGE;
ScreenQuadMaterial.TextureLayer->TextureWrapV = ETC_CLAMP_TO_EDGE;
vert[0] = video::S3DVertex(-1, -1, 0, 0, 0, 1, video::SColor(0), 0, 1); // Screen Quad..
vert[1] = video::S3DVertex(-1, 1, 0, 0, 0, 1, video::SColor(0), 0, 0);
vert[2] = video::S3DVertex( 1, 1, 0, 0, 0, 1, video::SColor(0), 1, 0);
vert[3] = video::S3DVertex( 1, -1, 0, 0, 0, 1, video::SColor(0), 1, 1);
// Drawing order..
index[0] = 0; index[1] = 1; index[2] = 2; index[3] = 0; index[4] = 2; index[5] = 3;
Vertices[0] = video::S3DVertex(-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, video::SColor(255,255,255,255), 0.f, 1.f);
Vertices[1] = video::S3DVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, video::SColor(255,255,255,255), 0.f, 0.f);
Vertices[2] = video::S3DVertex( 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, video::SColor(255,255,255,255), 1.f, 0.f);
Vertices[3] = video::S3DVertex( 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, video::SColor(255,255,255,255), 1.f, 1.f);
Indices[0] = 0; Indices[1] = 1; Indices[2] = 2; // setup the corresponding indices..
Indices[3] = 2; Indices[4] = 3; Indices[5] = 0;
}