Topic discussion (and screenshot) here:
http://irrlicht.sourceforge.net/phpBB2/ ... 2&start=64
A C++ class is used for the reflective water technique, so it is easily reusable.
NOTE: You will need the demo from the forum post above for the files used by the demo.
ISSUES: Castle mesh in demo is missing textures (3ds loader?). *** Works fully in OpenGL only ***.
UPDATE: SViewFrustrum is now exposed in SVN irrlicht.h.
Class CReflectedWater.cpp:
Code: Select all
//
// Reflected Water.
// sio2 'at' users.sourceforge.net
// Based on .NET code by DeusXL (Irrlicht forum)
//
#include "CReflectedWater.h"
#include "CReflectedWater_ShaderCode.h"
CReflectedWater::CReflectedWater(const irr::c8 *name, IrrlichtDevice *device, scene::ISceneManager* smgr,
s32 id, f32 tileSize, s32 tileCount, core::dimension2di RenderTargetSize)
{
m_device = device;
m_smgr = smgr;
m_name = name;
// Init constants
m_AddedColor = video::SColor(255, 1, 1, 30);
m_MultiColor = video::SColor(255, 190, 190, 210);
m_WaveHeight = 3.0f;
m_WaveLength = 50.0f;
m_WaveSpeed = 10.0f;
m_WaveDisplacement = 7.0f;
m_WaveRepetition = 5.0f;
m_RefractionFactor = 0.8f;
scene::IAnimatedMesh *wmesh = smgr->addHillPlaneMesh(m_name, core::dimension2df(tileSize, tileSize), core::dimension2di(tileCount, tileCount));
if (!wmesh) return;
m_waternode = smgr->addMeshSceneNode(wmesh->getMesh(0));
if (!m_waternode) return;
s32 dmat = irr::video::EMT_SOLID;
video::IVideoDriver* _driver = smgr->getVideoDriver();
video::E_DRIVER_TYPE edt = _driver->getDriverType();
video::IGPUProgrammingServices *gpu = _driver->getGPUProgrammingServices();
if (edt == video::EDT_OPENGL) {
dmat = gpu->addHighLevelShaderMaterial(
WATER_VERTEX_GLSL, "main", video::EVST_VS_1_1,
WATER_FRAGMENT_GLSL, "main", video::EPST_PS_1_1,
this, video::EMT_TRANSPARENT_ALPHA_CHANNEL, 0);
} else {
dmat = gpu->addHighLevelShaderMaterial(
WATER_HLSL, "vertexMain", video::EVST_VS_2_0,
WATER_HLSL, "pixelMain", video::EPST_PS_2_0,
this, video::EMT_TRANSPARENT_ALPHA_CHANNEL, 2);
}
m_waternode->setMaterialType((video::E_MATERIAL_TYPE)dmat);
m_waternode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false);
m_waternode->setMaterialFlag(video::EMF_LIGHTING, false);
m_waternode->setMaterialFlag(video::EMF_FOG_ENABLE, false);
m_rt = _driver->createRenderTargetTexture(RenderTargetSize);
m_waternode->setMaterialTexture(0, m_rt);
scene::ICameraSceneNode *camera = smgr->getActiveCamera();
m_watercam = smgr->addCameraSceneNode();
smgr->setActiveCamera(camera);
}
// --------------------------------------------------------------------------
CReflectedWater::~CReflectedWater()
{
m_rt->drop();
}
// --------------------------------------------------------------------------
void CReflectedWater::updateRendertarget(scene::ISceneManager* smgr)
{
if (!(m_rt && m_waternode && smgr))
return;
video::IVideoDriver* driver = smgr->getVideoDriver();
if (!driver) return;
scene::ICameraSceneNode *camera = smgr->getActiveCamera();
m_watercam->setFarValue(camera->getFarValue());
core::vector3df Position = m_waternode->getPosition();
core::vector3df campos = camera->getPosition();
if (campos.Y >= Position.Y)
{
m_watercam->setPosition(core::vector3df(campos.X, 2 * Position.Y - campos.Y, campos.Z));
core::vector3df target = camera->getTarget() - campos;
target.normalize();
target.Y *= -1;
m_watercam->setTarget(m_watercam->getPosition() + target * 20000);
m_watercam->setUpVector(camera->getUpVector());
}
else
{
m_watercam->setPosition(camera->getPosition());
core::vector3df target = camera->getTarget() - camera->getPosition();
target.normalize();
target *= 200000;
m_watercam->setTarget(m_watercam->getPosition() + target);
m_watercam->setUpVector(camera->getUpVector());
}
driver->setRenderTarget(m_rt, true, true, video::SColor(0,100,100,100));
smgr->setActiveCamera(m_watercam);
m_waternode->setVisible(false);
smgr->drawAll();
driver->setRenderTarget(0);
m_waternode->setVisible(true);
smgr->setActiveCamera(camera);
}
// --------------------------------------------------------------------------
void CReflectedWater::OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
if (!services) return;
video::IVideoDriver* driver = services->getVideoDriver();
if (!driver || !m_device) return;
if (userData == 2 || userData == 3) //All DirectX Shaders
{
core::matrix4 worldViewProj;
worldViewProj = driver->getTransform(video::ETS_PROJECTION);
worldViewProj *= driver->getTransform(video::ETS_VIEW);
worldViewProj *= driver->getTransform(video::ETS_WORLD);
services->setVertexShaderConstant("mWorldViewProj", &worldViewProj.M[0], 16);
}
/* if (userData == 1 || userData == 3) //Clamp Shaders
{
if (userData == 1) //OpenGL Clamp Shader
{
services->setPixelShaderConstant("DiffuseMap", 0f);
services->setPixelShaderConstant("DetailMap", 1f);
}
services->setPixelShaderConstant("WaterPositionY", WaterNode.Position.Y);
return;
}*/
//Water Shaders
float time = (float)m_device->getTimer()->getRealTime();
services->setVertexShaderConstant("Time", &time, 1);
services->setVertexShaderConstant("WaveHeight", &m_WaveHeight, 1);
services->setVertexShaderConstant("WaveLength", &m_WaveLength, 1);
services->setVertexShaderConstant("WaveSpeed", &m_WaveSpeed, 1);
services->setPixelShaderConstant("AddedColor", reinterpret_cast<f32*>(&m_AddedColor), 4);
services->setPixelShaderConstant("MultiColor", reinterpret_cast<f32*>(&m_MultiColor), 4);
services->setPixelShaderConstant("WaveDisplacement", &m_WaveDisplacement, 1);
services->setPixelShaderConstant("WaveRepetition", &m_WaveRepetition, 1);
services->setPixelShaderConstant("RefractionFactor", &m_RefractionFactor, 1);
float fUnderWater = (m_smgr->getActiveCamera()->getPosition().Y < m_waternode->getPosition().Y) ? 1.0f : 0.0f;
services->setPixelShaderConstant("UnderWater", &fUnderWater, 1);
}
Code: Select all
//
// Reflected Water.
// sio2 'at' users.sourceforge.net
// Based on .NET code by DeusXL (Irrlicht forum)
//
#ifndef _CREFLECTEDWATER_H
#define _CREFLECTEDWATER_H
#include <irrlicht.h>
using namespace irr;
class CReflectedWater : public video::IShaderConstantSetCallBack
{
public:
//! constructor
CReflectedWater(const irr::c8 *name, IrrlichtDevice *device, scene::ISceneManager* smgr, s32 id,
f32 tileSize, s32 tileCount, core::dimension2di RenderTargetSize);
//! destructor
~CReflectedWater();
void updateRendertarget(scene::ISceneManager* smgr);
//! Returns type of the scene node
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData);
const irr::c8 *m_name;
video::SColorf m_AddedColor;
video::SColorf m_MultiColor;
f32 m_WaveHeight;
f32 m_WaveLength;
f32 m_WaveSpeed;
f32 m_WaveDisplacement;
f32 m_WaveRepetition;
f32 m_RefractionFactor;
IrrlichtDevice *m_device;
scene::ISceneManager *m_smgr;
scene::ISceneNode *m_waternode;
scene::ICameraSceneNode *m_watercam;
video::ITexture *m_rt;
};
#endif
Code: Select all
//
// Reflected Water.
// sio2 'at' users.sourceforge.net
// Based on .NET code by DeusXL (Irrlicht forum)
//
#ifndef _CREFLECTEDWATER_SHADERCODE_H
#define _CREFLECTEDWATER_SHADERCODE_H
const irr::c8 WATER_VERTEX_GLSL[] =
"uniform float Time;\n" \
"uniform float WaveHeight, WaveLength, WaveSpeed;\n" \
"varying vec4 waterpos;\n" \
"varying float addition;\n" \
"void main()\n" \
"{\n" \
" waterpos = ftransform();\n" \
" addition = (sin((gl_Vertex.x/WaveLength) + (Time * WaveSpeed / 10000.0))) +\n" \
" (cos((gl_Vertex.z/WaveLength) + (Time * WaveSpeed / 10000.0)));\n" \
" waterpos.y += addition * WaveHeight;\n" \
" gl_Position = waterpos;\n" \
"}\n";
const irr::c8 WATER_FRAGMENT_GLSL[] =
"uniform sampler2D ReflectionTexture;\n" \
"uniform vec4 AddedColor, MultiColor;\n" \
"uniform float UnderWater, WaveDisplacement, WaveRepetition, RefractionFactor;\n" \
"varying vec4 waterpos;\n" \
"varying float addition;\n" \
"void main()\n" \
"{\n" \
" vec4 projCoord = waterpos / waterpos.w;\n" \
" projCoord += vec4(1.0);\n" \
" projCoord *= 0.5;\n" \
" projCoord.x += sin(addition * WaveRepetition) * (WaveDisplacement / 1000.0);\n" \
" projCoord.y += cos(addition * WaveRepetition) * (WaveDisplacement / 1000.0);\n" \
" projCoord = clamp(projCoord, 0.001, 0.999);\n" \
" if(UnderWater == 0.0)\n" \
" projCoord.y = 1.0 - projCoord.y;\n" \
" vec4 refTex = texture2D(ReflectionTexture, vec2(projCoord));\n" \
" refTex = (refTex + AddedColor) * MultiColor;\n" \
" gl_FragColor = refTex;\n" \
" if(UnderWater == 1.0)\n" \
" gl_FragColor *= (MultiColor / 1.1);\n" \
" gl_FragColor.a = RefractionFactor;" \
"}\n";
const irr::c8 WATER_HLSL[] =
"uniform float Time;\n" \
"float4x4 mWorldViewProj;\n" \
"float WaveHeight, WaveLength, WaveSpeed;\n" \
"float4 AddedColor, MultiColor;\n" \
"float UnderWater, WaveDisplacement, WaveRepetition, RefractionFactor;\n" \
"struct VS_OUTPUT\n" \
"{\n" \
" float4 Position : POSITION;\n" \
" float4 Diffuse : COLOR0;\n" \
" float2 TexCoord : TEXCOORD0;\n" \
"};\n" \
"VS_OUTPUT vertexMain( in float4 vPosition : POSITION,\n" \
" in float3 vNormal : NORMAL,\n" \
" float2 texCoord : TEXCOORD0 )\n" \
"{\n" \
" VS_OUTPUT Output;\n" \
" Output.Position = mul(vPosition, mWorldViewProj);\n" \
" float addition = (sin((vPosition.x/WaveLength) + (Time * WaveSpeed / 10000.0))) +\n" \
" (cos((vPosition.z/WaveLength) + (Time * WaveSpeed / 10000.0)));\n" \
" Output.Position.y += addition * WaveHeight;\n" \
" Output.Diffuse = float4(addition, addition, addition, addition);\n" \
" Output.TexCoord = Output.Position / Output.Position.w;\n" \
" return Output;\n" \
"}\n" \
"struct PS_OUTPUT\n" \
"{\n" \
" float4 RGBColor : COLOR0;\n" \
"};\n" \
"texture ReflectionTexture;\n" \
"sampler MySampler = sampler_state\n" \
"{\n" \
" Texture = ReflectionTexture;\n" \
" AddressU = CLAMP;\n" \
" AddressV = CLAMP;\n" \
"};\n" \
"PS_OUTPUT pixelMain( float2 TexCoord : TEXCOORD0,\n" \
" float4 Position : POSITION,\n" \
" float4 Diffuse : COLOR0 )\n" \
"{\n" \
" PS_OUTPUT Output;\n" \
" float2 projCoord = TexCoord;\n" \
" float addition = Diffuse.r;\n" \
" projCoord += float2(1.0, 1.0);\n" \
" projCoord *= 0.5;\n" \
" projCoord.x += sin(addition * WaveRepetition) * (WaveDisplacement / 1000.0);\n" \
" projCoord.y += cos(addition *WaveRepetition) * (WaveDisplacement / 1000.0);\n" \
" if(UnderWater == 1.0)\n" \
" projCoord.y = 1.0 - projCoord.y;\n" \
" projCoord = clamp(projCoord, 0.001, 0.999);\n" \
" float4 refTex = tex2D(MySampler, projCoord);\n" \
" refTex = (refTex + AddedColor) * MultiColor;\n" \
" Output.RGBColor = refTex;\n" \
" if(UnderWater == 1.0)\n" \
" Output.RGBColor *= (MultiColor / 1.1);\n" \
" Output.RGBColor.a = RefractionFactor;\n" \
" return Output;\n" \
"}";
const irr::c8 CLAMP_VERTEX_GLSL[] =
"varying float cutoff;\n" \
"void main()\n" \
"{\n" \
" cutoff = gl_Vertex.y;\n" \
" gl_Position = ftransform();\n" \
" gl_TexCoord[0] = gl_MultiTexCoord0;\n" \
"}\n";
const irr::c8 CLAMP_FRAGMENT_GLSL[] =
"uniform sampler2D DiffuseMap, DetailMap;\n" \
"uniform float WaterPositionY;\n" \
"varying float cutoff;\n" \
"void main()\n" \
"{\n" \
" vec4 color = texture2D(DiffuseMap, gl_TexCoord[0].st) * 2.0 *\n" \
" texture2D(DetailMap, vec2(gl_TexCoord[0].x * 5.0, gl_TexCoord[0].y * 5.0));\n" \
" if(cutoff <= (WaterPositionY - 10.0))\n" \
" color.a = 0.0;\n" \
" else\n" \
" color.a = 1.0;\n" \
" gl_FragColor = color; \n" \
"}\n";
const irr::c8 CLAMP_HLSL[] =
"uniform float Time;\n" \
"float4x4 mWorldViewProj;\n" \
"float WaterPositionY;\n" \
"struct VS_OUTPUT\n" \
"{\n" \
" float4 Position : POSITION;\n" \
" float4 Diffuse : COLOR0;\n" \
" float2 TexCoord : TEXCOORD0;\n" \
" float2 TexCoord1 : TEXCOORD1;\n" \
"};\n" \
"VS_OUTPUT vertexMain( in float4 vPosition : POSITION,\n" \
" in float3 vNormal : NORMAL,\n" \
" float2 texCoord : TEXCOORD0,\n" \
" float2 texCoord1 : TEXCOORD1)\n" \
"{\n" \
" VS_OUTPUT Output;\n" \
" Output.Position = mul(vPosition, mWorldViewProj);\n" \
" Output.Diffuse = vPosition;\n" \
" Output.TexCoord = texCoord;\n" \
" Output.TexCoord1 = texCoord1;\n" \
" return Output;\n" \
"}\n" \
"struct PS_OUTPUT\n" \
"{\n" \
" float4 RGBColor : COLOR0;\n" \
"};\n" \
"sampler2D DiffuseMap;\n" \
"sampler2D DetailMap;\n" \
"PS_OUTPUT pixelMain( float2 TexCoord : TEXCOORD0,\n" \
" float2 TexCoord1 : TEXCOORD1,\n" \
" float4 Position : POSITION,\n" \
" float4 Diffuse : COLOR0 )\n" \
"{\n" \
" PS_OUTPUT Output;\n" \
" float4 color = tex2D(DiffuseMap, TexCoord) * 2.0f *\n" \
" tex2D(DetailMap, float2(TexCoord1.x * 5.0f, TexCoord1.y * 5.0f));\n" \
" if(Diffuse.y <= WaterPositionY)\n" \
" color.a = 0.0;\n" \
" else\n" \
" color.a = 1.0;\n" \
" Output.RGBColor = color;\n" \
" return Output;\n" \
"}";
#endif
Code: Select all
//
// Reflected Water Demo.
// sio2 'at' users.sourceforge.net
// Converted to C++ from the .NET code written by DeusXL (Irrlicht forum)
//
#include <stdio.h>
#include <iostream>
#include <wchar.h>
#include <irrlicht.h>
#include "CReflectedWater.h"
using namespace irr;
using namespace irr::core;
using namespace irr::video;
using namespace irr::scene;
#pragma comment(lib, "Irrlicht.lib")
IrrlichtDevice* _device = 0;
bool _bExit = false;
class CMainOnSetConstants : public irr::video::IShaderConstantSetCallBack
{
public:
virtual void OnSetConstants(irr::video::IMaterialRendererServices* services, s32 userData)
{
float fVal;
SColorf col(0.0f,0.0f,0.0f,0.0f);
if (userData == 1) {
fVal = 5000000.0f;
services->setPixelShaderConstant("Radius", &fVal, 1);
services->setPixelShaderConstant("Ambient", reinterpret_cast<f32*>(&col), 4);
fVal = 0.0f;
services->setPixelShaderConstant("Texture", &fVal, 1);
}
fVal = 5000000.0f;
services->setPixelShaderConstant("range", &fVal, 1);
fVal = 0.0f;
services->setPixelShaderConstant("decalMap", &fVal, 1);
fVal = 1.0f;
services->setPixelShaderConstant("heightMap", &fVal, 1);
};
};
class CEventReceiver : public IEventReceiver
{
bool OnEvent(const SEvent &Event)
{
if ((Event.EventType == irr::EET_KEY_INPUT_EVENT) &&
Event.KeyInput.PressedDown && (Event.KeyInput.Key==KEY_ESCAPE))
{
_bExit = true;
return true;
}
return false;
}
};
int main()
{
char i;
// ask user for driver
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_SOFTWARE; break;
case 'e': driverType = video::EDT_SOFTWARE2;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
CEventReceiver *_EventReceiver = new CEventReceiver();
_device = createDevice(driverType, core::dimension2di(800, 600),
16, false, false, false, _EventReceiver);
video::IVideoDriver* _driver = _device->getVideoDriver();
scene::ISceneManager* _scene = _device->getSceneManager();
_device->getFileSystem()->changeWorkingDirectoryTo("medias");
_device->getCursorControl()->setVisible(false);
_scene->addCameraSceneNodeFPS(0, 100.0f, 1000.0f); //, false);
_scene->getActiveCamera()->setPosition(core::vector3df(0, 400, -5000));
float fFar = _scene->getActiveCamera()->getFarValue();
_scene->getActiveCamera()->setFarValue(fFar *= 1000); // TODO: revise this
_scene->setShadowColor(video::SColor(150,0,0,0));
scene::IMesh *castlemesh = _scene->getMesh("castl3ds/a3dcastl.3ds")->getMesh(0);
scene::ISceneNode *castlenode = _scene->addMeshSceneNode(castlemesh);
castlenode->setMaterialFlag(video::EMF_LIGHTING, false);
castlenode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false);
castlenode->setScale(core::vector3df(10, 10, 10));
SMaterial m = castlenode->getMaterial(1);
m.MaterialType = EMT_SOLID;
m.Texture1 = _driver->getTexture("castl3ds/casstne2.bmp");
m = castlenode->getMaterial(2);
m.MaterialType = EMT_SOLID;
m.Texture1 = _driver->getTexture("castl3ds/caswd2.bmp");
m.Texture2 = _driver->getTexture("castl3ds/caswd2.bmp");
CMainOnSetConstants *_MainOnSetConstants = new CMainOnSetConstants;
int ppxshading = _driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles(
"ppxshading.vert", "main", irr::video::EVST_VS_1_1, "ppxshading.frag", "main",
irr::video::EPST_PS_1_1, _MainOnSetConstants, EMT_SOLID, 1);
core::array<IAnimatedMeshSceneNode*> tinies;
for (int i = -1000; i <= 1000; i += 500)
{
IAnimatedMesh *tinymesh = _scene->getMesh("tiny/tiny.x");
IAnimatedMeshSceneNode *tiny = _scene->addAnimatedMeshSceneNode(tinymesh);
tiny->setMaterialFlag(video::EMF_LIGHTING, false);
tiny->setAnimationSpeed(5000);
tiny->setMaterialType((E_MATERIAL_TYPE)ppxshading);
tiny->setPosition(vector3df((float)i, 300, -2200));
ISceneNode *hand = tiny->getXJointNode("Bip01_L_Hand");
IMesh *clevemesh = _scene->getMesh("cleve3ds/a3dcleve.3ds")->getMesh(0);
ISceneNode *clevenode = _scene->addMeshSceneNode(clevemesh, hand, -1);
clevenode->setMaterialFlag(video::EMF_LIGHTING, false);
clevenode->setScale(vector3df(5, 5, 5));
clevenode->setRotation(vector3df(0, 20, 90));
clevenode->setPosition(vector3df(70, 0, -40));
clevenode->setMaterialType((E_MATERIAL_TYPE)ppxshading);
hand = tiny->getXJointNode("Bip01_R_Hand");
clevemesh = _scene->getMesh("cleve3ds/a3dcleve.3ds")->getMesh(0);
clevenode = _scene->addMeshSceneNode(clevemesh, hand, -1);
clevenode->setMaterialFlag(video::EMF_LIGHTING, false);
clevenode->setScale(vector3df(5, 5, 5));
clevenode->setRotation(vector3df(0, 160, 90));
clevenode->setPosition(vector3df(70, 0, 40));
clevenode->setMaterialType((E_MATERIAL_TYPE)ppxshading);
tinies.push_back(tiny);
}
for (int i = -1000; i <= 1000; i += 500)
{
IAnimatedMesh *tinymesh = _scene->getMesh("dwarf/Dwarf.x");
IAnimatedMeshSceneNode *tiny = _scene->addAnimatedMeshSceneNode(tinymesh);
tiny->setMaterialFlag(video::EMF_LIGHTING, false);
tiny->setAnimationSpeed(15);
tiny->setMaterialType((E_MATERIAL_TYPE)ppxshading);
tiny->setPosition(vector3df((float)i, 50, -4000));
tiny->setRotation(vector3df(0, 180, 0));
tiny->setScale(vector3df(7, 7, 7));
tinies.push_back(tiny);
}
int parallax = _driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles(
"opengl2.vert", "main", EVST_VS_1_1, "opengl2.frag", "main",
EPST_PS_1_1, _MainOnSetConstants, EMT_SOLID, 0);
IMesh *plane = _scene->addHillPlaneMesh("plane", dimension2df(6000, 6000), dimension2di(10, 10),
0, 0.0f, dimension2df(0, 0), dimension2df(100, 100))->getMesh(0);
plane = _scene->getMeshManipulator()->createMeshWithTangents(plane);
ISceneNode *parallaxplane = _scene->addMeshSceneNode(plane); //, null, -1);
parallaxplane->setMaterialFlag(EMF_LIGHTING, false);
parallaxplane->setMaterialTexture(0, _driver->getTexture("rockwall.bmp"));
parallaxplane->setMaterialTexture(1, _driver->getTexture("rockwall_height.bmp"));
parallaxplane->setMaterialType((E_MATERIAL_TYPE)parallax);
CReflectedWater *water = new CReflectedWater("ReflectedWater", _device, _scene, -1, 180, 100, dimension2di(512,512));
ISceneNode *waternode = water->m_waternode;
waternode->setPosition(vector3df(0, 50, -3000));
water->m_WaveDisplacement /= 1.5f;
water->m_WaveHeight *= 2.0f;
water->m_WaveSpeed *= 5.0f;
water->m_RefractionFactor = 0.51f;
ISceneNode *sky = _scene->addSkyDomeSceneNode(_driver->getTexture("sky.png"), 10, 10, 1, 1.3, NULL);
int lastfps = -1;
while (_device->run() && !_bExit)
{
if (_device->isWindowActive())
{
//SViewFrustrum *frustrum = (SViewFrustrum *)_scene->getActiveCamera()->getViewFrustrum();
//frustrum->recalculateBoundingBox();
//Box3D fbox = frustrum.BoundingBox;
_driver->beginScene(true, true, SColor(255,100,100,100));
/*foreach (AnimatedMeshSceneNode t in tinies)
if (t.TransformedBoundingBox.IntersectsWithBox(fbox))
t.Visible = true;
else
t.Visible = false;*/
water->updateRendertarget(_scene);
_scene->drawAll();
_driver->endScene();
int fps = _driver->getFPS();
if (fps != lastfps)
{
core::stringw str;
str = L"Irrlicht .NET CP RPG (C++ Conversion) - FPS : ";
str += fps;
str += L" Polycount : ";
str += (int)_driver->getPrimitiveCountDrawn();
_device->setWindowCaption(str.c_str());
lastfps = fps;
}
}
}
_device->drop();
}