forked from Mirrorlandia_minetest/irrlicht
Simplify example 27 slightly.
Also use tab instead of spaces (as usual in Irrlicht) git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6408 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
parent
d70d96031b
commit
338af5c0ea
@ -1,16 +1,16 @@
|
||||
/** Example 027 Post Processing
|
||||
|
||||
This tutorial shows how to implement post processing for D3D9 and OpenGL with
|
||||
This tutorial shows how to implement post processing for D3D9 and OpenGL with
|
||||
the engine. In order to do post processing, scene objects are firstly rendered
|
||||
to render target. With the help of screen quad, the render target texture
|
||||
is then drawn on the quad with shader-defined effects applied.
|
||||
|
||||
This tutorial shows how to create a screen quad. It also shows how to create a
|
||||
This tutorial shows how to create a screen quad. It also shows how to create a
|
||||
render target texture and associate it with the quad. Effects are defined as
|
||||
shaders which are applied during rendering the quad with the render target
|
||||
shaders which are applied during rendering the quad with the render target
|
||||
texture attached to it.
|
||||
|
||||
A simple color inverse example is presented in this tutorial. The effect is
|
||||
A simple color inverse example is presented in this tutorial. The effect is
|
||||
written in HLSL and GLSL.
|
||||
|
||||
@author Boshen Guan
|
||||
@ -29,46 +29,42 @@ using namespace irr;
|
||||
|
||||
/*
|
||||
We write a class derived from IShaderConstantSetCallBack class and implement
|
||||
OnSetConstants callback interface. In this callback, we will set constants
|
||||
OnSetConstants callback interface. In this callback, we will set constants
|
||||
used by the shader.
|
||||
In this example, our HLSL shader needs texture size as input in its vertex
|
||||
In this example, our HLSL shader needs texture size as input in its vertex
|
||||
shader. Therefore, we set texture size in OnSetConstants callback using
|
||||
setVertexShaderConstant function.
|
||||
*/
|
||||
|
||||
IrrlichtDevice* device = 0;
|
||||
video::ITexture* rt = 0;
|
||||
|
||||
class QuadShaderCallBack : public video::IShaderConstantSetCallBack
|
||||
{
|
||||
public:
|
||||
QuadShaderCallBack() : FirstUpdate(true), TextureSizeID(-1), TextureSamplerID(-1)
|
||||
{ }
|
||||
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices* services,
|
||||
s32 userData)
|
||||
{
|
||||
core::dimension2d<u32> size = rt->getSize();
|
||||
|
||||
// get texture size array
|
||||
f32 textureSize[] =
|
||||
{
|
||||
(f32)size.Width, (f32)size.Height
|
||||
};
|
||||
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices* services,
|
||||
s32 userData)
|
||||
{
|
||||
if ( FirstUpdate )
|
||||
{
|
||||
FirstUpdate = false;
|
||||
TextureSizeID = services->getVertexShaderConstantID("TextureSize");
|
||||
TextureSamplerID = services->getPixelShaderConstantID("TextureSampler");
|
||||
}
|
||||
|
||||
// set texture size to vertex shader
|
||||
services->setVertexShaderConstant(TextureSizeID, reinterpret_cast<f32*>(textureSize), 2);
|
||||
|
||||
// set texture for an OpenGL driver
|
||||
s32 textureLayer = 0;
|
||||
services->setPixelShaderConstant(TextureSamplerID, &textureLayer, 1);
|
||||
}
|
||||
// get texture size array (for our simple example HLSL just needs that to calculate pixel centers)
|
||||
core::dimension2d<u32> size = services->getVideoDriver()->getCurrentRenderTargetSize();
|
||||
f32 textureSize[2];
|
||||
textureSize[0] = (f32)size.Width;
|
||||
textureSize[1] = (f32)size.Height;
|
||||
|
||||
// set texture size to vertex shader
|
||||
services->setVertexShaderConstant(TextureSizeID, textureSize, 2);
|
||||
|
||||
// set texture for an OpenGL driver
|
||||
s32 textureLayer = 0;
|
||||
services->setPixelShaderConstant(TextureSamplerID, &textureLayer, 1);
|
||||
}
|
||||
|
||||
private:
|
||||
bool FirstUpdate;
|
||||
@ -80,102 +76,88 @@ class ScreenQuad : public IReferenceCounted
|
||||
{
|
||||
public:
|
||||
|
||||
ScreenQuad(video::IVideoDriver* driver)
|
||||
: Driver(driver)
|
||||
{
|
||||
// --------------------------------> u
|
||||
// |[1](-1, 1)----------[2](1, 1)
|
||||
// | | ( 0, 0) / | (1, 0)
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | | / |
|
||||
// |[0](-1, -1)---------[3](1, -1)
|
||||
// | ( 0, 1) (1, 1)
|
||||
// V
|
||||
// v
|
||||
ScreenQuad(video::IVideoDriver* driver)
|
||||
: Driver(driver)
|
||||
{
|
||||
// --------------------------------> u
|
||||
// |[1](-1, 1)----------[2](1, 1)
|
||||
// | | ( 0, 0) / | (1, 0)
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | | / |
|
||||
// | | / |
|
||||
// |[0](-1, -1)---------[3](1, -1)
|
||||
// | ( 0, 1) (1, 1)
|
||||
// V
|
||||
// v
|
||||
|
||||
/*
|
||||
A screen quad is composed of two adjacent triangles with 4 vertices.
|
||||
Vertex [0], [1] and [2] create the first triangle and Vertex [0],
|
||||
[2] and [3] create the second one. To map texture on the quad, UV
|
||||
coordinates are assigned to the vertices. The origin of UV coordinate
|
||||
locates on the top-left corner. And the value of UVs range from 0 to 1.
|
||||
*/
|
||||
/*
|
||||
A screen quad is composed of two adjacent triangles with 4 vertices.
|
||||
Vertex [0], [1] and [2] create the first triangle and Vertex [0],
|
||||
[2] and [3] create the second one. To map texture on the quad, UV
|
||||
coordinates are assigned to the vertices. The origin of UV coordinate
|
||||
locates on the top-left corner. And the value of UVs range from 0 to 1.
|
||||
*/
|
||||
|
||||
// define vertices array
|
||||
// define vertices array
|
||||
|
||||
Vertices[0] = irr::video::S3DVertex(-1.0f, -1.0f, 0.0f, 1, 1, 0, irr::video::SColor(0,255,255,255), 0.0f, 1.0f);
|
||||
Vertices[1] = irr::video::S3DVertex(-1.0f, 1.0f, 0.0f, 1, 1, 0, irr::video::SColor(0,255,255,255), 0.0f, 0.0f);
|
||||
Vertices[2] = irr::video::S3DVertex( 1.0f, 1.0f, 0.0f, 1, 1, 0, irr::video::SColor(0,255,255,255), 1.0f, 0.0f);
|
||||
Vertices[3] = irr::video::S3DVertex( 1.0f, -1.0f, 0.0f, 1, 1, 0, irr::video::SColor(0,255,255,255), 1.0f, 1.0f);
|
||||
Vertices[0] = irr::video::S3DVertex(-1.0f, -1.0f, 0.0f, 1, 1, 0, irr::video::SColor(0,255,255,255), 0.0f, 1.0f);
|
||||
Vertices[1] = irr::video::S3DVertex(-1.0f, 1.0f, 0.0f, 1, 1, 0, irr::video::SColor(0,255,255,255), 0.0f, 0.0f);
|
||||
Vertices[2] = irr::video::S3DVertex( 1.0f, 1.0f, 0.0f, 1, 1, 0, irr::video::SColor(0,255,255,255), 1.0f, 0.0f);
|
||||
Vertices[3] = irr::video::S3DVertex( 1.0f, -1.0f, 0.0f, 1, 1, 0, irr::video::SColor(0,255,255,255), 1.0f, 1.0f);
|
||||
|
||||
// define indices for triangles
|
||||
// define indices for triangles
|
||||
|
||||
Indices[0] = 0;
|
||||
Indices[1] = 1;
|
||||
Indices[2] = 2;
|
||||
Indices[3] = 0;
|
||||
Indices[4] = 2;
|
||||
Indices[5] = 3;
|
||||
Indices[0] = 0;
|
||||
Indices[1] = 1;
|
||||
Indices[2] = 2;
|
||||
Indices[3] = 0;
|
||||
Indices[4] = 2;
|
||||
Indices[5] = 3;
|
||||
|
||||
// turn off lighting as default
|
||||
Material.setFlag(video::EMF_LIGHTING, false);
|
||||
// turn off lighting as default
|
||||
Material.setFlag(video::EMF_LIGHTING, false);
|
||||
|
||||
// set texture warp settings to clamp to edge pixel
|
||||
for (u32 i = 0; i < video::MATERIAL_MAX_TEXTURES; i++)
|
||||
{
|
||||
Material.TextureLayer[i].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
|
||||
Material.TextureLayer[i].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
|
||||
}
|
||||
}
|
||||
// set texture warp settings to clamp to edge pixel
|
||||
for (u32 i = 0; i < video::MATERIAL_MAX_TEXTURES; i++)
|
||||
{
|
||||
Material.TextureLayer[i].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
|
||||
Material.TextureLayer[i].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~ScreenQuad() {}
|
||||
virtual ~ScreenQuad() {}
|
||||
|
||||
|
||||
//! render the screen quad
|
||||
virtual void render()
|
||||
{
|
||||
// set the material of screen quad
|
||||
Driver->setMaterial(Material);
|
||||
//! render the screen quad
|
||||
virtual void render()
|
||||
{
|
||||
// set the material of screen quad
|
||||
Driver->setMaterial(Material);
|
||||
|
||||
// set matrices to fit the quad to full viewport
|
||||
Driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
|
||||
Driver->setTransform(video::ETS_VIEW, core::IdentityMatrix);
|
||||
Driver->setTransform(video::ETS_PROJECTION, core::IdentityMatrix);
|
||||
// set world matrix to fit the quad to full viewport (we only use ETS_WORLD in the shader, so view, projection currently don't matter)
|
||||
Driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
|
||||
|
||||
// draw screen quad
|
||||
Driver->drawVertexPrimitiveList(Vertices, 4, Indices, 2);
|
||||
}
|
||||
// draw screen quad
|
||||
Driver->drawVertexPrimitiveList(Vertices, 4, Indices, 2);
|
||||
}
|
||||
|
||||
//! sets a flag of material to a new value
|
||||
virtual void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
|
||||
{
|
||||
Material.setFlag(flag, newvalue);
|
||||
}
|
||||
|
||||
//! sets the texture of the specified layer in material to the new texture.
|
||||
void setMaterialTexture(u32 textureLayer, video::ITexture* texture)
|
||||
{
|
||||
Material.setTexture(textureLayer, texture);
|
||||
}
|
||||
|
||||
//! sets the material type to a new material type.
|
||||
virtual void setMaterialType(video::E_MATERIAL_TYPE newType)
|
||||
{
|
||||
Material.MaterialType = newType;
|
||||
}
|
||||
//! Access the material
|
||||
virtual video::SMaterial& getMaterial()
|
||||
{
|
||||
return Material;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
video::IVideoDriver *Driver;
|
||||
video::S3DVertex Vertices[4];
|
||||
u16 Indices[6];
|
||||
video::SMaterial Material;
|
||||
video::IVideoDriver *Driver;
|
||||
video::S3DVertex Vertices[4];
|
||||
u16 Indices[6];
|
||||
video::SMaterial Material;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -184,233 +166,234 @@ according to the driver type.
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
// ask user for driver
|
||||
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
|
||||
if (driverType==video::EDT_COUNT)
|
||||
return 1;
|
||||
// ask user for driver
|
||||
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
|
||||
if (driverType==video::EDT_COUNT)
|
||||
return 1;
|
||||
|
||||
// create device
|
||||
device = createDevice(driverType, core::dimension2d<u32>(640, 480));
|
||||
// create device
|
||||
IrrlichtDevice* device = createDevice(driverType, core::dimension2d<u32>(640, 480));
|
||||
|
||||
if (device == 0)
|
||||
return 1; // could not create selected driver.
|
||||
if (device == 0)
|
||||
return 1; // could not create selected driver.
|
||||
|
||||
video::IVideoDriver* driver = device->getVideoDriver();
|
||||
scene::ISceneManager* smgr = device->getSceneManager();
|
||||
video::IVideoDriver* driver = device->getVideoDriver();
|
||||
scene::ISceneManager* smgr = device->getSceneManager();
|
||||
|
||||
/*
|
||||
In this example, high level post processing shaders are loaded for both
|
||||
Direct3D and OpenGL drivers.
|
||||
File pp_d3d9.hlsl is for Direct3D 9, and pp_opengl.frag/pp_opengl.vert
|
||||
are for OpenGL.
|
||||
*/
|
||||
/*
|
||||
In this example, high level post processing shaders are loaded for both
|
||||
Direct3D and OpenGL drivers.
|
||||
File pp_d3d9.hlsl is for Direct3D 9, and pp_opengl.frag/pp_opengl.vert
|
||||
are for OpenGL.
|
||||
*/
|
||||
|
||||
const io::path mediaPath = getExampleMediaPath();
|
||||
io::path vsFileName; // filename for the vertex shader
|
||||
io::path psFileName; // filename for the pixel shader
|
||||
io::path vsFileName; // filename for the vertex shader
|
||||
io::path psFileName; // filename for the pixel shader
|
||||
|
||||
switch(driverType)
|
||||
{
|
||||
case video::EDT_DIRECT3D9:
|
||||
psFileName = mediaPath + "pp_d3d9.hlsl";
|
||||
vsFileName = psFileName; // both shaders are in the same file
|
||||
break;
|
||||
switch(driverType)
|
||||
{
|
||||
case video::EDT_DIRECT3D9:
|
||||
psFileName = mediaPath + "pp_d3d9.hlsl";
|
||||
vsFileName = psFileName; // both shaders are in the same file
|
||||
break;
|
||||
|
||||
case video::EDT_OPENGL:
|
||||
case video::EDT_BURNINGSVIDEO:
|
||||
psFileName = mediaPath + "pp_opengl.frag";
|
||||
vsFileName = mediaPath + "pp_opengl.vert";
|
||||
break;
|
||||
}
|
||||
case video::EDT_OPENGL:
|
||||
case video::EDT_BURNINGSVIDEO:
|
||||
psFileName = mediaPath + "pp_opengl.frag";
|
||||
vsFileName = mediaPath + "pp_opengl.vert";
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
Check for hardware capability of executing the corresponding shaders
|
||||
on selected renderer. This is not necessary though.
|
||||
*/
|
||||
/*
|
||||
Check for hardware capability of executing the corresponding shaders
|
||||
on selected renderer. This is not necessary though.
|
||||
*/
|
||||
|
||||
if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) &&
|
||||
!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1))
|
||||
{
|
||||
device->getLogger()->log("WARNING: Pixel shaders disabled "\
|
||||
"because of missing driver/hardware support.");
|
||||
psFileName = "";
|
||||
}
|
||||
if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) &&
|
||||
!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1))
|
||||
{
|
||||
device->getLogger()->log("WARNING: Pixel shaders disabled "\
|
||||
"because of missing driver/hardware support.");
|
||||
psFileName = "";
|
||||
}
|
||||
|
||||
if (!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) &&
|
||||
!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
|
||||
{
|
||||
device->getLogger()->log("WARNING: Vertex shaders disabled "\
|
||||
"because of missing driver/hardware support.");
|
||||
vsFileName = "";
|
||||
}
|
||||
if (!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) &&
|
||||
!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
|
||||
{
|
||||
device->getLogger()->log("WARNING: Vertex shaders disabled "\
|
||||
"because of missing driver/hardware support.");
|
||||
vsFileName = "";
|
||||
}
|
||||
|
||||
/*
|
||||
An animated mesh is loaded to be displayed. As in most examples,
|
||||
we'll take the fairy md2 model.
|
||||
*/
|
||||
/*
|
||||
An animated mesh is loaded to be displayed. As in most examples,
|
||||
we'll take the fairy md2 model.
|
||||
*/
|
||||
|
||||
// load and display animated fairy mesh
|
||||
// load and display animated fairy mesh
|
||||
|
||||
scene::IAnimatedMeshSceneNode* fairy = smgr->addAnimatedMeshSceneNode(
|
||||
smgr->getMesh(mediaPath + "faerie.md2"));
|
||||
scene::IAnimatedMeshSceneNode* fairy = smgr->addAnimatedMeshSceneNode(
|
||||
smgr->getMesh(mediaPath + "faerie.md2"));
|
||||
|
||||
if (fairy)
|
||||
{
|
||||
fairy->setMaterialTexture(0,
|
||||
driver->getTexture(mediaPath + "faerie2.bmp")); // set diffuse texture
|
||||
fairy->setMaterialFlag(video::EMF_LIGHTING, false); // disable dynamic lighting
|
||||
fairy->setPosition(core::vector3df(-10,0,-100));
|
||||
fairy->setMD2Animation ( scene::EMAT_STAND );
|
||||
}
|
||||
if (fairy)
|
||||
{
|
||||
fairy->setMaterialTexture(0,
|
||||
driver->getTexture(mediaPath + "faerie2.bmp")); // set diffuse texture
|
||||
fairy->setMaterialFlag(video::EMF_LIGHTING, false); // disable dynamic lighting
|
||||
fairy->setPosition(core::vector3df(-10,0,-100));
|
||||
fairy->setMD2Animation ( scene::EMAT_STAND );
|
||||
}
|
||||
|
||||
// add scene camera
|
||||
smgr->addCameraSceneNode(0, core::vector3df(10,10,-80),
|
||||
core::vector3df(-10,10,-100));
|
||||
// add scene camera
|
||||
smgr->addCameraSceneNode(0, core::vector3df(10,10,-80),
|
||||
core::vector3df(-10,10,-100));
|
||||
|
||||
/*
|
||||
We create a render target texture (RTT) with the same size as frame buffer.
|
||||
Instead of rendering the scene directly to the frame buffer, we firstly
|
||||
render it to this RTT. Post processing is then applied based on this RTT.
|
||||
RTT size needs not to be the same with frame buffer though. However in this
|
||||
example, we expect the result of rendering to RTT to be consistent with the
|
||||
result of rendering directly to the frame buffer. Therefore, the size of
|
||||
RTT keeps the same with frame buffer.
|
||||
*/
|
||||
/*
|
||||
We create a render target texture (RTT) with the same size as frame buffer.
|
||||
Instead of rendering the scene directly to the frame buffer, we firstly
|
||||
render it to this RTT. Post processing is then applied based on this RTT.
|
||||
RTT size needs not to be the same with frame buffer though. However in this
|
||||
example, we expect the result of rendering to RTT to be consistent with the
|
||||
result of rendering directly to the frame buffer. Therefore, the size of
|
||||
RTT keeps the same with frame buffer.
|
||||
*/
|
||||
|
||||
// create render target
|
||||
// create render target
|
||||
video::ITexture* rt = 0;
|
||||
if (driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
|
||||
{
|
||||
rt = driver->addRenderTargetTexture(core::dimension2d<u32>(640, 480), "RTT1");
|
||||
}
|
||||
else
|
||||
{
|
||||
device->getLogger()->log("Your hardware or this renderer is not able to use the "\
|
||||
"render to texture feature. RTT Disabled.");
|
||||
}
|
||||
|
||||
if (driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
|
||||
{
|
||||
rt = driver->addRenderTargetTexture(core::dimension2d<u32>(640, 480), "RTT1");
|
||||
}
|
||||
else
|
||||
{
|
||||
device->getLogger()->log("Your hardware or this renderer is not able to use the "\
|
||||
"render to texture feature. RTT Disabled.");
|
||||
}
|
||||
/*
|
||||
Post processing is achieved by rendering a screen quad with this RTT (with
|
||||
previously rendered result) as a texture on the quad. A screen quad is
|
||||
geometry of flat plane composed of two adjacent triangles covering the
|
||||
entire area of viewport. In this pass of rendering, RTT works just like
|
||||
a normal texture and is drawn on the quad during rendering. We can then
|
||||
take control of this rendering process by applying various shader-defined
|
||||
materials to the quad. In other words, we can achieve different effect by
|
||||
writing different shaders.
|
||||
This process is called post processing because it normally does not rely
|
||||
on scene geometry. The inputs of this process are just textures, or in
|
||||
other words, just images. With the help of screen quad, we can draw these
|
||||
images on the screen with different effects. For example, we can adjust
|
||||
contrast, make grayscale, add noise, do more fancy effect such as blur,
|
||||
bloom, ghost, or just like in this example, we invert the color to produce
|
||||
negative image.
|
||||
Note that post processing is not limited to use only one texture. It can
|
||||
take multiple textures as shader inputs to provide desired result. In
|
||||
addition, post processing can also be chained to produce compound result.
|
||||
*/
|
||||
|
||||
/*
|
||||
Post processing is achieved by rendering a screen quad with this RTT (with
|
||||
previously rendered result) as a texture on the quad. A screen quad is
|
||||
geometry of flat plane composed of two adjacent triangles covering the
|
||||
entire area of viewport. In this pass of rendering, RTT works just like
|
||||
a normal texture and is drawn on the quad during rendering. We can then
|
||||
take control of this rendering process by applying various shader-defined
|
||||
materials to the quad. In other words, we can achieve different effect by
|
||||
writing different shaders.
|
||||
This process is called post processing because it normally does not rely
|
||||
on scene geometry. The inputs of this process are just textures, or in
|
||||
other words, just images. With the help of screen quad, we can draw these
|
||||
images on the screen with different effects. For example, we can adjust
|
||||
contrast, make grayscale, add noise, do more fancy effect such as blur,
|
||||
bloom, ghost, or just like in this example, we invert the color to produce
|
||||
negative image.
|
||||
Note that post processing is not limited to use only one texture. It can
|
||||
take multiple textures as shader inputs to provide desired result. In
|
||||
addition, post processing can also be chained to produce compound result.
|
||||
*/
|
||||
// we create a screen quad
|
||||
ScreenQuad *screenQuad = new ScreenQuad(driver);
|
||||
video::SMaterial& screenQuadMaterial = screenQuad->getMaterial();
|
||||
|
||||
// we create a screen quad
|
||||
ScreenQuad *screenQuad = new ScreenQuad(driver);
|
||||
// turn off mip maps and bilinear filter since we do not want interpolated results
|
||||
screenQuadMaterial.setFlag(video::EMF_USE_MIP_MAPS, false);
|
||||
screenQuadMaterial.setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
|
||||
// turn off mip maps and bilinear filter since we do not want interpolated result
|
||||
screenQuad->setMaterialFlag(video::EMF_USE_MIP_MAPS, false);
|
||||
screenQuad->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
|
||||
// set quad texture to RTT we just create
|
||||
screenQuadMaterial.setTexture(0, rt);
|
||||
|
||||
// set quad texture to RTT we just create
|
||||
screenQuad->setMaterialTexture(0, rt);
|
||||
/*
|
||||
Let's create material for the quad. Like in other example, we create material
|
||||
using IGPUProgrammingServices and call addShaderMaterialFromFiles, which
|
||||
returns a material type identifier.
|
||||
*/
|
||||
|
||||
/*
|
||||
Let's create material for the quad. Like in other example, we create material
|
||||
using IGPUProgrammingServices and call addShaderMaterialFromFiles, which
|
||||
returns a material type identifier.
|
||||
*/
|
||||
// create materials
|
||||
|
||||
// create materials
|
||||
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
|
||||
s32 ppMaterialType = 0;
|
||||
|
||||
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
|
||||
s32 ppMaterialType = 0;
|
||||
if (gpu)
|
||||
{
|
||||
// We write a QuadShaderCallBack class that implements OnSetConstants
|
||||
// callback of IShaderConstantSetCallBack class at the beginning of
|
||||
// this tutorial. We set shader constants in this callback.
|
||||
|
||||
if (gpu)
|
||||
{
|
||||
// We write a QuadShaderCallBack class that implements OnSetConstants
|
||||
// callback of IShaderConstantSetCallBack class at the beginning of
|
||||
// this tutorial. We set shader constants in this callback.
|
||||
|
||||
// create an instance of callback class
|
||||
// create an instance of callback class
|
||||
|
||||
QuadShaderCallBack* mc = new QuadShaderCallBack();
|
||||
QuadShaderCallBack* mc = new QuadShaderCallBack();
|
||||
|
||||
// create material from post processing shaders
|
||||
// create material from post processing shaders
|
||||
|
||||
ppMaterialType = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
vsFileName, "vertexMain", video::EVST_VS_1_1,
|
||||
psFileName, "pixelMain", video::EPST_PS_1_1, mc);
|
||||
ppMaterialType = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
vsFileName, "vertexMain", video::EVST_VS_1_1,
|
||||
psFileName, "pixelMain", video::EPST_PS_1_1, mc);
|
||||
|
||||
mc->drop();
|
||||
}
|
||||
mc->drop();
|
||||
}
|
||||
|
||||
// set post processing material type to the quad
|
||||
screenQuad->setMaterialType((video::E_MATERIAL_TYPE)ppMaterialType);
|
||||
// set post processing material type to the quad
|
||||
screenQuadMaterial.MaterialType = (video::E_MATERIAL_TYPE)ppMaterialType;
|
||||
|
||||
/*
|
||||
Now draw everything. That's all.
|
||||
*/
|
||||
/*
|
||||
Now draw everything. That's all.
|
||||
*/
|
||||
|
||||
int lastFPS = -1;
|
||||
int lastFPS = -1;
|
||||
|
||||
while(device->run())
|
||||
{
|
||||
if (device->isWindowActive())
|
||||
{
|
||||
driver->beginScene(true, true, video::SColor(255,0,0,0));
|
||||
while(device->run())
|
||||
{
|
||||
if (device->isWindowActive())
|
||||
{
|
||||
driver->beginScene(true, true, video::SColor(255,0,0,0));
|
||||
|
||||
if (rt)
|
||||
{
|
||||
// draw scene into render target
|
||||
if (rt)
|
||||
{
|
||||
// draw scene into render target
|
||||
|
||||
// set render target to RTT
|
||||
driver->setRenderTarget(rt, true, true, video::SColor(255,0,0,0));
|
||||
// set render target to RTT
|
||||
driver->setRenderTarget(rt, true, true, video::SColor(255,0,0,0));
|
||||
|
||||
// draw scene to RTT just like normal rendering
|
||||
smgr->drawAll();
|
||||
// draw scene to RTT just like normal rendering
|
||||
smgr->drawAll();
|
||||
|
||||
// after rendering to RTT, we change render target back
|
||||
driver->setRenderTarget(0, true, true, video::SColor(255,0,0,0));
|
||||
// after rendering to RTT, we change render target back
|
||||
driver->setRenderTarget(0, true, true, video::SColor(255,0,0,0));
|
||||
|
||||
// render screen quad to apply post processing
|
||||
screenQuad->render();
|
||||
}
|
||||
else
|
||||
{
|
||||
// draw scene normally
|
||||
smgr->drawAll();
|
||||
}
|
||||
// render screen quad to apply post processing
|
||||
screenQuad->render();
|
||||
}
|
||||
else
|
||||
{
|
||||
// draw scene normally
|
||||
smgr->drawAll();
|
||||
}
|
||||
|
||||
driver->endScene();
|
||||
driver->endScene();
|
||||
|
||||
int fps = driver->getFPS();
|
||||
int fps = driver->getFPS();
|
||||
|
||||
if (lastFPS != fps)
|
||||
{
|
||||
core::stringw str = L"Irrlicht Engine - Post processing example [";
|
||||
str += driver->getName();
|
||||
str += "] FPS:";
|
||||
str += fps;
|
||||
if (lastFPS != fps)
|
||||
{
|
||||
core::stringw str = L"Irrlicht Engine - Post processing example [";
|
||||
str += driver->getName();
|
||||
str += "] FPS:";
|
||||
str += fps;
|
||||
|
||||
device->setWindowCaption(str.c_str());
|
||||
lastFPS = fps;
|
||||
}
|
||||
}
|
||||
}
|
||||
device->setWindowCaption(str.c_str());
|
||||
lastFPS = fps;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do not forget to manually drop the screen quad
|
||||
// do not forget to manually drop the screen quad
|
||||
|
||||
screenQuad->drop();
|
||||
screenQuad->drop();
|
||||
|
||||
device->drop();
|
||||
device->drop();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user