C'est normal, c'est le cas.
Le RTT ne fait qu'écrire le contenu du back buffer dans une texture (au lieu du front buffer).
Pour l'appliquer correctement sur le plan d'eau, il faut se prendre la tête avec la projection de texture. C'est ce sur quoi je me documente en ce moment.
#include <irrlicht.h>
#include <iostream>
using namespace irr;
#include "MyShaderCallBack.h"
int main ( int argc , char** argv )
{
// Initialise Irrlicht
IrrlichtDevice* device = createDevice ( video::EDT_OPENGL , core::dimension2d<s32>(640, 480) );
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
gui::IGUIEnvironment* gui = device->getGUIEnvironment();
// Verifie le support des shaders
bool pixel_shader_support = ( driver->queryFeature ( video::EVDF_PIXEL_SHADER_1_1 ) || driver->queryFeature ( video::EVDF_ARB_FRAGMENT_PROGRAM_1 ) );
bool vertex_shader_support = ( driver->queryFeature ( video::EVDF_VERTEX_SHADER_1_1 ) || driver->queryFeature ( video::EVDF_ARB_VERTEX_PROGRAM_1 ) );
if ( !pixel_shader_support || !vertex_shader_support )
{
std::cerr << "Les shaders 1.1 ne sont pas supportés !" << std::endl;
}
// Creer le shader
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
// L'ID du matériau personnalisé
s32 newMaterialType = 0;
if (gpu)
{
// On instancie notre callback
MyShaderCallBack* shader_callback = new MyShaderCallBack ( device );
// On créer un nouveau matériau à partir du shader
newMaterialType = gpu->addHighLevelShaderMaterialFromFiles(
"vertex_shader.vert", "main", video::EVST_VS_1_1,
"pixel_shader.frag", "main" , video::EPST_PS_1_1,
shader_callback, video::EMT_SOLID);
shader_callback->drop();
}
// Ajoute un plan d'eau
scene::IAnimatedMesh* water_mesh = smgr->addHillPlaneMesh("myHill",
core::dimension2d<f32>(1000,1000),
core::dimension2d<u32>(2,2), 0, 0,
core::dimension2d<f32>(0,0),
core::dimension2d<f32>(1,1));
scene::ISceneNode* water_node = smgr->addMeshSceneNode ( water_mesh->getMesh(0) );
water_node->setMaterialTexture ( 0 , driver->getTexture ( "Water2.jpg" ) );
water_node->setMaterialTexture ( 1 , driver->getTexture ( "waves.jpg" ) );
water_node->setMaterialFlag ( video::EMF_LIGHTING , false );
water_node->setMaterialType ( (video::E_MATERIAL_TYPE)newMaterialType );
// Ajoute un cube texturé et lui assigne le shader
scene::ISceneNode* node = smgr->addCubeSceneNode(50);
node->setPosition ( core::vector3df ( 0 , 10.0f , 0 ) );
node->setMaterialTexture ( 0 , driver->getTexture ( "chess.jpg" ) );
node->setMaterialFlag ( video::EMF_LIGHTING , false );
// Fait tourner le cube sur lui même
scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator ( core::vector3df ( 1.0f , 0.3f , 1.0f ) );
node->addAnimator ( anim );
anim->drop();
// Ajoute une caméra à la scène
scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f);
cam->setPosition(core::vector3df(-100,50,100));
cam->setTarget(core::vector3df(0,0,0));
// Créer les textures pour le RTT (la moitié de la résolution réelle suffira)
video::ITexture* refraction_texture = driver->createRenderTargetTexture ( core::dimension2d<s32>( 320 , 240 ) );
video::ITexture* reflexion_texture = driver->createRenderTargetTexture ( core::dimension2d<s32>( 320 , 240 ) );
// Créer les plans de clipping
core::plane3df refraction ( core::vector3df( 0 , 0 , 0 ) , core::vector3df ( 0 , -1 , 0 ) );
core::plane3df reflexion ( core::vector3df( 0 , 0 , 0 ) , core::vector3df ( 0 , 1 , 0 ) );
driver->setClipPlane( 1 , refraction , false );
driver->setClipPlane( 2 , reflexion , false );
// Boucle du jeu
while ( device->run() )
{
if ( device->isWindowActive() )
{
driver->beginScene(true, true, video::SColor(255,128,128,128));
// Refracion
driver->enableClipPlane ( 1 , true );
driver->setRenderTarget ( refraction_texture );
water_node->setVisible ( false );
smgr->drawAll();
driver->enableClipPlane ( 1 , false );
// Reflexion
driver->enableClipPlane ( 2 , true );
driver->setRenderTarget ( reflexion_texture );
smgr->drawAll();
driver->enableClipPlane ( 2 , false );
// Reel
driver->setRenderTarget( 0 , true , true , 0 );
water_node->setVisible ( true );
water_node->setMaterialTexture ( 2 , refraction_texture );
water_node->setMaterialTexture ( 3 , reflexion_texture );
smgr->drawAll();
// Pour tester : affiche les deux textures en haut de l'écran
//driver->draw2DImage ( refraction_texture , core::position2di ( 0 , 0 ) );
//driver->draw2DImage ( reflexion_texture , core::position2di ( 320 , 0 ) );
driver->endScene();
}
}
device->drop();
return 0;
}