/*
The Drill Of The Pill 0.1
'''''''''''''''''''''''''
cSoundManager.h
'''''''''''''''''''''''''
Last Edit: 18.02.2005
*/
#ifndef __IRR_CHDRMODULE_H_INCLUDED__
#define __IRR_CHDRMODULE_H_INCLUDED__
#include <irrlicht.h>
#include <list>
using std::list;
using namespace irr;
class cHDRManager
{
public:
IrrlichtDevice* device;
scene::ISceneManager* smgr;
video::IVideoDriver* driver;
video::IGPUProgrammingServices* gpu;
scene::ICameraSceneNode* camera;
scene::ISceneNode* postprocessorNode;
gui::IGUIEnvironment* guiEnv;
scene::ISceneNode* glowNode;
scene::ISceneNode* grassNode;
scene::ISceneNode* obstrcutNode;
video::E_MATERIAL_TYPE backupMaterial;
/* naming convention
Rt= render target of original scene
color= pass of color except alpha channel
alpha= indactes a rendering of all the alpha channels that are assigned to be rendered in that pass
shrink= these shrink the image for the blooom effect to appear
v= vertical process pass
h= horizontal process pass
*/
//textures needed for the rendering
video::ITexture* rtcolor;
video::ITexture* rtalpha;
video::ITexture* finalshaddow;
video::ITexture* hcolor;
video::ITexture* halpha;
video::ITexture* small;
video::ITexture* smalla;
video::ITexture* shaddowtex;
//textures needed for the rendering
video::ITexture* nrstage;
video::ITexture* texstage;
c8* postvertFile; // filename for the pixel shader
c8* postfragFile; // filename for the pixel shader
c8* nrvertFile; // filename for the vertex shader
c8* nrfragFile; // filename for the vertex shader
bool shaddowon;
//shader files(i wouldnt mess with the code since this class modifies some shader stuff on load to allow diffrent otions)
c8* scenealphavertFileName; // filename for the pixel shader
c8* postvertFileName; // filename for the pixel shader
c8* alphafragFileName; // filename for the pixel shader
c8* alphafragscFileName; // filename for the pixel shader
c8* blurhFileName; // filename for the pixel shader
c8* blurhaFileName; // filename for the pixel shader
c8* blurvFileName; // filename for the pixel shader
c8* blurvaFileName; // filename for the pixel shader
c8* finalFileName; // filename for the pixel shader
c8* shrinkFileName; // filename for the vertex shader
c8* shrinkaFileName; // filename for the vertex shader
// signed 32's(integers) as the shader numbers
s32 alphasceneshader;
s32 alphashader;
s32 alphashrink;
s32 shrink;
s32 vblur;
s32 vblura;
s32 hblur;
s32 hblura;
s32 finalshader;
float exposure;
// signed 32's(integers) as the shader numbers
s32 postShader;
s32 backupShader;
s32 nrShader;
/* ok this is the instiliser
screenx= resoultion (x) of rendering window
screeny= resoultion (y) of rendering window
exposure= howmuch exposure is used when rendering (think of it interms of exposure in camera films)
glowres= determines quality of bloom effect
its is in the form of a ratio so
1.0 would mean that the bloom would be very high res but wll be quite small
.25 would mean that the bloom might sufer from some aliasing but will be nice and big and also fast
nearest power is for stuff ie: if 128 then its 100 if 1024 then its 1000
*/
cHDRManager(IrrlichtDevice* m_device,scene::ISceneManager* m_smgr,int m_screenx, int m_screeny, float m_exposure, float m_glowres, int m_nearestpower);
//sets scope size 0.25= quarter of screen etc...
void setScope(f32 scope);
//sets focus of camera at this position of the screen
void setFocalPoint(int x,int y,float focusSize);
//THIS IS NEEDED FOR DEPTH OF FIELD
//sets focus of camera at this node
void setFocalNode(irr::scene::ISceneNode *focusnode,float focusSize);
//adds a glowing node to the render list (needs alpha channel texture)
void addScenodeGlow(irr::scene::ISceneNode *newnode);
//tonemaps the node (may not be good for all purpouses but adds style to the picture
void addScenodeTonemap(irr::scene::ISceneNode *newnode);
//place in main loop to render the hdr pipline
int Render();
float getblursize();
float getexposure();
float getfocalx();
float getfocaly();
void disablePostProcessor();
bool menuActive;
//adds a grass node to the render list
void addScenodeGrass(irr::scene::ISceneNode *newnode);
//Node that obstraucts grass (non furred node)
void addScenodeObstruct(irr::scene::ISceneNode *newnode);
private:
//list of tone mapped glow scennodes
list <irr::scene::ISceneNode*> glowList;
//list of tone mapped scennodes
list <irr::scene::ISceneNode*> toneList;
int screenx;
int screeny;
float glowres;
bool focal;
float focussize;
float scope;
int focusptx;
int nearestpower;
int focuspty;
core::vector3df prevrot;
list <irr::scene::ISceneNode*> grassList;
list <irr::scene::ISceneNode*> obstructList;
//we will use this function to remove uneeded process's from the shader depending on the user settings.(for extra speed)
};
#endif
#include "cHDRManager.h"
#include <math.h>
cHDRManager::cHDRManager(IrrlichtDevice* m_device,scene::ISceneManager* m_smgr,int m_screenx, int m_screeny, float m_exposure, float m_glowres, int m_nearestpower)
{
device = m_device;
smgr = m_smgr;
driver = device->getVideoDriver();
guiEnv = device->getGUIEnvironment();
camera=smgr->getActiveCamera();
postprocessorNode=smgr->addCubeSceneNode(60);
screenx =m_screenx;
screeny=m_screeny;
exposure=m_exposure;
glowres=m_glowres;
nearestpower=m_nearestpower;
//default
focussize=3;
if (glowres>1)
{
printf("Please reduce glow resoultion for bloom to appear.\n");
glowres=1;
}
//setup textures with correct sizes
rtcolor = driver->createRenderTargetTexture(core::dimension2d<s32>(512,512));
rtalpha = driver->createRenderTargetTexture(core::dimension2d<s32>(512,512));
finalshaddow = driver->createRenderTargetTexture(core::dimension2d<s32>(128,128));
hcolor = driver->createRenderTargetTexture(core::dimension2d<s32>(128,128));
halpha = driver->createRenderTargetTexture(core::dimension2d<s32>(128,128));
small = driver->createRenderTargetTexture(core::dimension2d<s32>(128,128));
smalla = driver->createRenderTargetTexture(core::dimension2d<s32>(128,128));
shaddowtex= driver->createRenderTargetTexture(core::dimension2d<s32>(128,128));
nrstage = driver->createRenderTargetTexture(core::dimension2d<s32>(128,128));
texstage = driver->createRenderTargetTexture(core::dimension2d<s32>(512,512));
//assign files locations
scenealphavertFileName = "./alphavert.vert"; // filename for the pixel shader
postvertFileName = "./post.vert"; // filename for the pixel shader
alphafragFileName = "./alpha.frag"; // filename for the pixel shader
alphafragscFileName = "./alphasc.frag"; // filename for the pixel shader
blurhFileName = "./blurh.frag"; // filename for the pixel shader
blurhaFileName = "./blurha.frag"; // filename for the pixel shader
finalFileName = "./final.frag"; // filename for the pixel shader
shrinkFileName = "./shrink.frag"; // filename for the vertex shader
shrinkaFileName = "./shrinka.frag"; // filename for the vertex shader
c8* postvertFile="gpost.vert"; // filename for the pixel shader
c8* postfragFile="gpost.frag"; // filename for the pixel shader
c8* nrvertFile="nr.vert"; // filename for the vertex shader
c8* nrfragFile="nr.frag";// filename for the vertex shader
gpu = driver->getGPUProgrammingServices();
//makes a shader call back
#include "HDRcallback.h"
HDRShaderCallBack* mc = new HDRShaderCallBack(this);
//compile shaders and turn them into irrlicht materials
alphasceneshader = gpu->addHighLevelShaderMaterialFromFiles(
scenealphavertFileName, "main", video::EVST_VS_2_0,
alphafragscFileName, "main", video::EPST_PS_2_0,
mc, video::EMT_SOLID );
alphashader = gpu->addHighLevelShaderMaterialFromFiles(
postvertFileName, "main", video::EVST_VS_2_0,
alphafragFileName, "main", video::EPST_PS_2_0,
mc, video::EMT_SOLID);
hblur = gpu->addHighLevelShaderMaterialFromFiles(
postvertFileName, "main", video::EVST_VS_2_0,
blurhFileName, "main", video::EPST_PS_2_0,
mc, video::EMT_SOLID);
hblura = gpu->addHighLevelShaderMaterialFromFiles(
postvertFileName, "main", video::EVST_VS_2_0,
blurhaFileName, "main", video::EPST_PS_2_0,
mc, video::EMT_SOLID);
finalshader = gpu->addHighLevelShaderMaterialFromFiles(
postvertFileName, "main", video::EVST_VS_2_0,
finalFileName, "main", video::EPST_PS_2_0,
mc, video::EMT_SOLID);
shrink = gpu->addHighLevelShaderMaterialFromFiles(
postvertFileName, "main", video::EVST_VS_2_0,
shrinkFileName, "main", video::EPST_PS_2_0,
mc, video::EMT_SOLID);
alphashrink = gpu->addHighLevelShaderMaterialFromFiles(
postvertFileName, "main", video::EVST_VS_2_0,
shrinkaFileName, "main", video::EPST_PS_2_0,
mc, video::EMT_SOLID);
nrShader = gpu->addHighLevelShaderMaterialFromFiles(
nrvertFile, "main", video::EVST_VS_2_0,
nrfragFile, "main", video::EPST_PS_2_0,
mc, video::EMT_SOLID );
postShader = gpu->addHighLevelShaderMaterialFromFiles(
postvertFile, "main", video::EVST_VS_2_0,
postfragFile, "main", video::EPST_PS_2_0,
mc, video::EMT_SOLID);
this->setFocalPoint(screenx/2,screeny/2,2.5);
}
int cHDRManager::Render()
{
camera=smgr->getActiveCamera();
camera->setFarValue(1000000);
driver->beginScene(true, true, 0);
if (shaddowon & !menuActive)
{
smgr->drawAll(true);
this->setFocalPoint(screenx/2,screeny/2,2.0);
}
//color pass//
driver->setRenderTarget(texstage, true, true, video::SColor(0,0,0,0));
postprocessorNode->setVisible(false);
smgr->drawAll(false);
driver->setRenderTarget(nrstage, true, true, video::SColor(0,0,0,0));
list<irr::scene::ISceneNode*>::const_iterator grassNodeIter;
for (grassNodeIter=grassList.begin();grassNodeIter!=grassList.end(); ++grassNodeIter)
{
grassNode= (*grassNodeIter);
backupShader= grassNode->getMaterial(0).MaterialType;
grassNode->setMaterialType((video::E_MATERIAL_TYPE)nrShader);
video::ITexture* temptex=grassNode->getMaterial(0).Textures[0];
grassNode->render();
grassNode->setMaterialType((video::E_MATERIAL_TYPE)backupShader);
grassNode->setMaterialTexture(0, temptex);
}
list<irr::scene::ISceneNode*>::const_iterator obstructNodeIter;
for (obstructNodeIter=obstructList.begin();obstructNodeIter!=obstructList.end(); ++obstructNodeIter)
{
obstrcutNode= (*obstructNodeIter);
video::ITexture* temptex=obstrcutNode->getMaterial(0).Textures[0];
obstrcutNode->setMaterialTexture(0, driver->getTexture("black.bmp"));
obstrcutNode->render();
obstrcutNode->setMaterialTexture(0, temptex);
}
driver->setRenderTarget(rtcolor, true, true, video::SColor(0,0,0,0));
postprocessorNode->setMaterialTexture(0, nrstage);
postprocessorNode->setMaterialTexture(1, texstage);
postprocessorNode->setVisible(true);
postprocessorNode->setMaterialType((video::E_MATERIAL_TYPE)postShader);
postprocessorNode->render();
//smgr->drawAll(false);
if (menuActive)
{
guiEnv->drawAll();
//this->setFocalPoint(cursorpos.X,cursorpos.Y,1.5);
//g_GameApp->console.renderConsole(guiEnv, driver, 0);
}
//color alpha//
driver->setRenderTarget(rtalpha, true, true, video::SColor(0,0,0,0));
//send the new kid some data on the old kids
list<irr::scene::ISceneNode*>::const_iterator glowNodeIter;
for (glowNodeIter=glowList.begin();glowNodeIter!=glowList.end(); ++glowNodeIter)
{
glowNode= (*glowNodeIter);
backupMaterial=glowNode->getMaterial(0).MaterialType;
glowNode->setMaterialType((video::E_MATERIAL_TYPE)alphasceneshader);
glowNode->render();
glowNode->setMaterialType((video::E_MATERIAL_TYPE)backupMaterial);
}
//send the new kid some data on the old kids
list<irr::scene::ISceneNode*>::const_iterator toneNodeIter;
for (toneNodeIter=toneList.begin();toneNodeIter!=toneList.end(); ++toneNodeIter)
{
glowNode= (*toneNodeIter);
glowNode->render();
}
if (menuActive)
{
guiEnv->drawAll();
//g_GameApp->console.renderConsole(guiEnv, driver, 0);
}
postprocessorNode->setMaterialTexture(0, smgr->getSoftShadowTex());
driver->setRenderTarget(finalshaddow, true, true, video::SColor(0,0,0,0));
postprocessorNode->setMaterialType((video::E_MATERIAL_TYPE)hblur);
postprocessorNode->render();
driver->setRenderTarget(smalla, true, true, video::SColor(0,0,0,0));
postprocessorNode->setMaterialType((video::E_MATERIAL_TYPE)alphashrink);
postprocessorNode->setMaterialTexture(1, rtalpha);
postprocessorNode->render();
driver->setRenderTarget(small, true, true, video::SColor(0,0,0,0));
postprocessorNode->setMaterialType((video::E_MATERIAL_TYPE)shrink);
postprocessorNode->setMaterialTexture(0, rtcolor);
postprocessorNode->render();
driver->setRenderTarget(halpha, true, true, video::SColor(0,0,0,0));
postprocessorNode->setMaterialType((video::E_MATERIAL_TYPE)hblura);
postprocessorNode->setMaterialTexture(1, smalla);
postprocessorNode->render();
postprocessorNode->setMaterialTexture(0, small);
driver->setRenderTarget(hcolor, true, true, video::SColor(0,0,0,0));
postprocessorNode->setMaterialType((video::E_MATERIAL_TYPE)hblur);
postprocessorNode->render();
driver->setRenderTarget(0);
postprocessorNode->setVisible(true);
postprocessorNode->setMaterialTexture(0, rtcolor);
postprocessorNode->setMaterialTexture(1, rtalpha);
postprocessorNode->setMaterialTexture(2, hcolor);
postprocessorNode->setMaterialTexture(3, halpha);
//if(shaddowon & !menuActive)
postprocessorNode->setMaterialTexture(4, finalshaddow);
postprocessorNode->setMaterialType((video::E_MATERIAL_TYPE)finalshader);
postprocessorNode->render();
driver->endScene();
return 1;
}
void cHDRManager::addScenodeGlow(irr::scene::ISceneNode *newnode)
{
glowList.push_back(newnode);
}
void cHDRManager::addScenodeTonemap(irr::scene::ISceneNode *newnode)
{
toneList.push_back(newnode);
}
float cHDRManager::getblursize()
{
return focussize;
}
float cHDRManager::getexposure()
{
return exposure;
}
float cHDRManager::getfocalx()
{
//focusptx=100;
return (focusptx/(screenx/nearestpower));
}
float cHDRManager::getfocaly()
{
return (focuspty/(screeny/nearestpower));
}
void cHDRManager::setFocalPoint(int x,int y,float focusSize)
{
focussize=focusSize;
focusptx=x;
focuspty=y;
}
void cHDRManager::setFocalNode(scene::ISceneNode*focusnode,float focusSize)
{
focussize=focusSize;
core::position2d<s32> pos=smgr->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition (focusnode->getBoundingBox().getCenter(),camera);
focusptx=pos.X;
focuspty=pos.Y;
}
void cHDRManager::disablePostProcessor()
{
postprocessorNode->setVisible(false);
}
void cHDRManager::addScenodeGrass(irr::scene::ISceneNode *newnode)
{
grassList.push_back(newnode);
}
void cHDRManager::addScenodeObstruct(irr::scene::ISceneNode *newnode)
{
obstructList.push_back(newnode);
}