Separated the post-processing calculations from IrrDriver

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9319 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
funto66 2011-07-21 23:29:37 +00:00
parent 8c30a00405
commit a3ca6dadaf
6 changed files with 211 additions and 80 deletions

View File

@ -87,6 +87,8 @@ supertuxkart_SOURCES = \
graphics/particle_kind_manager.hpp \
graphics/per_camera_node.cpp \
graphics/per_camera_node.hpp \
graphics/post_processing.cpp \
graphics/post_processing.hpp \
graphics/rain.cpp \
graphics/rain.hpp \
graphics/shadow.cpp \

View File

@ -65,7 +65,6 @@ IrrDriver::IrrDriver()
{
m_resolution_changing = RES_CHANGE_NONE;
m_device = NULL;
m_boost_amount = 0.0f;
file_manager->dropFileSystem();
initDevice();
} // IrrDriver
@ -74,6 +73,7 @@ IrrDriver::IrrDriver()
IrrDriver::~IrrDriver()
{
m_post_processing.shut();
assert(m_device != NULL);
m_device->drop();
m_device = NULL;
@ -255,35 +255,8 @@ void IrrDriver::initDevice()
material2D.AntiAliasing=video::EAAM_FULL_BASIC;
//m_video_driver->enableMaterial2D();
// Initialize post-processing, if possible and asked
if(UserConfigParams::m_postprocess_enabled)
{
if(!m_video_driver->queryFeature(EVDF_RENDER_TO_TARGET))
UserConfigParams::m_postprocess_enabled = false;
else
{
// Render target
m_postprocess_render_target = m_video_driver->addRenderTargetTexture(m_video_driver->getScreenSize(), "postprocess");
if(!m_postprocess_render_target)
{
fprintf(stderr, "Couldn't create the render target for post-processing, disabling it\n");
UserConfigParams::m_postprocess_enabled = false;
}
// Material and shaders
IGPUProgrammingServices* gpu = m_video_driver->getGPUProgrammingServices();
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
"../data/shaders/motion_blur.vert", "main", video::EVST_VS_2_0,
"../data/shaders/motion_blur.frag", "main", video::EPST_PS_2_0,
this, video::EMT_SOLID);
m_postprocess_material.MaterialType = (E_MATERIAL_TYPE)material_type;
m_postprocess_material.setTexture(0, m_postprocess_render_target);
m_postprocess_material.Wireframe = false;
m_postprocess_material.Lighting = false;
m_postprocess_material.ZWriteEnable = false;
}
}
// Initialize post-processing if supported
m_post_processing.init(m_video_driver);
// set cursor visible by default (what's the default is not too clearly documented,
// so let's decide ourselves...)
@ -1238,8 +1211,7 @@ void IrrDriver::update(float dt)
}
// Start the RTT for post-processing
if(UserConfigParams::m_postprocess_enabled)
m_video_driver->setRenderTarget(m_postprocess_render_target, true, true);
m_post_processing.beginCapture();
{
PROFILER_PUSH_CPU_MARKER("Update GUI widgets", 0x7F, 0x7F, 0x00);
@ -1381,29 +1353,11 @@ void IrrDriver::update(float dt)
}
#endif
// Draw the fullscreen quad while applying the corresponding post-processing shaders
if(UserConfigParams::m_postprocess_enabled)
{
m_video_driver->setRenderTarget(0, true, true, 0);
irr::video::S3DVertex vertices[6];
irr::video::SColor white(0xFF, 0xFF, 0xFF, 0xFF);
vertices[0] = irr::video::S3DVertex(-1.0f,-1.0f,0.0f,0,0,1, white, 0.0f,1.0f);
vertices[1] = irr::video::S3DVertex(-1.0f, 1.0f,0.0f,0,0,1, white, 0.0f,0.0f);
vertices[2] = irr::video::S3DVertex( 1.0f, 1.0f,0.0f,0,0,1, white, 1.0f,0.0f);
vertices[3] = irr::video::S3DVertex( 1.0f,-1.0f,0.0f,0,0,1, white, 1.0f,1.0f);
vertices[4] = irr::video::S3DVertex(-1.0f,-1.0f,0.0f,0,0,1, white, 0.0f,1.0f);
vertices[5] = irr::video::S3DVertex( 1.0f, 1.0f,0.0f,0,0,1, white, 1.0f,0.0f);
irr::u16 indices[6] = {0, 1, 2, 3, 4, 5};
m_video_driver->setMaterial(m_postprocess_material);
m_video_driver->setTransform(irr::video::ETS_WORLD, irr::core::matrix4());
m_video_driver->setTransform(irr::video::ETS_VIEW, irr::core::matrix4());
m_video_driver->setTransform(irr::video::ETS_PROJECTION, irr::core::matrix4());
m_video_driver->drawIndexedTriangleList(&vertices[0], 6, &indices[0], 2);
}
// Stop capturing for the post-processing
m_post_processing.endCapture();
// Render the post-processed scene
m_post_processing.render();
m_video_driver->endScene();
@ -1444,15 +1398,6 @@ bool IrrDriver::OnEvent(const irr::SEvent &event)
// ----------------------------------------------------------------------------
/** Implement IShaderConstantsSetCallback. Shader constants setter for post-processing */
void IrrDriver::OnSetConstants(video::IMaterialRendererServices *services, s32 user_data)
{
services->setPixelShaderConstant("boost_amount", &m_boost_amount, 1);
//services->setPixelShaderConstant("color_buffer", &m_boost_amount, 1);
} // OnSetConstants
// ----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark RTT

View File

@ -32,22 +32,20 @@
#include <dimension2d.h>
#include <SColor.h>
#include <IrrlichtDevice.h>
#include <IShaderConstantSetCallBack.h>
namespace irr
{
namespace scene { class ISceneManager; class IMesh; class IAnimatedMeshSceneNode; class IAnimatedMesh;
class IMeshSceneNode; class IParticleSystemSceneNode; class ICameraSceneNode; class ILightSceneNode; }
namespace gui { class IGUIEnvironment; class IGUIFont; }
namespace video { class ITexture; }
}
using namespace irr;
#include "post_processing.hpp"
#include "utils/aligned_array.hpp"
#include "utils/no_copy.hpp"
#include "utils/ptr_vector.hpp"
#include "utils/vec3.hpp"
class Camera;
class Kart;
class PerCameraNode;
@ -62,7 +60,7 @@ struct VideoMode
* ways to manage the 3D scene
* \ingroup graphics
*/
class IrrDriver : public IEventReceiver, public video::IShaderConstantSetCallBack, public NoCopy
class IrrDriver : public IEventReceiver, public NoCopy
{
private:
/** The irrlicht device. */
@ -75,13 +73,8 @@ private:
video::IVideoDriver *m_video_driver;
/** Irrlicht race font. */
gui::IGUIFont *m_race_font;
// ------ Post-processing -------
video::ITexture *m_postprocess_render_target;
video::SMaterial m_postprocess_material;
/** Boost amount, used to tune the motion blur. Must be in the range 0.0 to 1.0 */
float m_boost_amount;
/** Post-processing */
PostProcessing m_post_processing;
/** Flag to indicate if a resolution change is pending (which will be
* acted upon in the next update). None means no change, yes means
@ -197,10 +190,7 @@ public:
const video::SColor *cb=NULL,
const video::SColor *cc=NULL);
inline void setBoostAmount(float boost_amount) {m_boost_amount = boost_amount;}
/** Implement IShaderConstantsSetCallback. Shader constants setter for post-processing */
void OnSetConstants(video::IMaterialRendererServices *services, s32 user_data);
inline PostProcessing* getPostProcessing() {return &m_post_processing;}
// --------------------- RTT --------------------
/**

View File

@ -0,0 +1,130 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2011 the SuperTuxKart team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#include <IGPUProgrammingServices.h>
#include <IMaterialRendererServices.h>
#include "post_processing.hpp"
#include "irr_driver.hpp"
#include "config/user_config.hpp"
using namespace video;
using namespace scene;
PostProcessing::PostProcessing()
{
m_boost_amount = 0.0f;
//UserConfigParams::m_postprocess_enabled = true; // BOUM
}
PostProcessing::~PostProcessing()
{
}
/** Initialization */
void PostProcessing::init(video::IVideoDriver* video_driver)
{
// Check if post-processing is supported on this hardware
m_supported = false;
if( video_driver->queryFeature(video::EVDF_ARB_GLSL) &&
video_driver->queryFeature(video::EVDF_PIXEL_SHADER_2_0) &&
video_driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
{
m_supported = true;
}
// Initialization
if(m_supported)
{
// Render target
m_render_target = video_driver->addRenderTargetTexture(video_driver->getScreenSize(), "postprocess");
if(!m_render_target)
{
fprintf(stderr, "Couldn't create the render target for post-processing, disabling it\n");
UserConfigParams::m_postprocess_enabled = false;
}
// Material and shaders
IGPUProgrammingServices* gpu = video_driver->getGPUProgrammingServices();
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
"../data/shaders/motion_blur.vert", "main", video::EVST_VS_2_0,
"../data/shaders/motion_blur.frag", "main", video::EPST_PS_2_0,
this, video::EMT_SOLID);
m_material.MaterialType = (E_MATERIAL_TYPE)material_type;
m_material.setTexture(0, m_render_target);
m_material.Wireframe = false;
m_material.Lighting = false;
m_material.ZWriteEnable = false;
}
}
/** Termination */
void PostProcessing::shut()
{
if(!m_supported)
return;
// TODO: do we have to delete/drop anything?
}
/** Setup the render target */
void PostProcessing::beginCapture()
{
if(!m_supported || !UserConfigParams::m_postprocess_enabled)
return;
irr_driver->getVideoDriver()->setRenderTarget(m_render_target, true, true);
}
/** Restore the framebuffer render target */
void PostProcessing::endCapture()
{
if(!m_supported || !UserConfigParams::m_postprocess_enabled)
return;
irr_driver->getVideoDriver()->setRenderTarget(0, true, true, 0);
}
/** Render the post-processed scene */
void PostProcessing::render()
{
if(!m_supported || !UserConfigParams::m_postprocess_enabled)
return;
// Draw the fullscreen quad while applying the corresponding post-processing shaders
video::IVideoDriver* video_driver = irr_driver->getVideoDriver();
video::S3DVertex vertices[6];
video::SColor white(0xFF, 0xFF, 0xFF, 0xFF);
vertices[0] = irr::video::S3DVertex(-1.0f,-1.0f,0.0f,0,0,1, white, 0.0f,1.0f);
vertices[1] = irr::video::S3DVertex(-1.0f, 1.0f,0.0f,0,0,1, white, 0.0f,0.0f);
vertices[2] = irr::video::S3DVertex( 1.0f, 1.0f,0.0f,0,0,1, white, 1.0f,0.0f);
vertices[3] = irr::video::S3DVertex( 1.0f,-1.0f,0.0f,0,0,1, white, 1.0f,1.0f);
vertices[4] = irr::video::S3DVertex(-1.0f,-1.0f,0.0f,0,0,1, white, 0.0f,1.0f);
vertices[5] = irr::video::S3DVertex( 1.0f, 1.0f,0.0f,0,0,1, white, 1.0f,0.0f);
u16 indices[6] = {0, 1, 2, 3, 4, 5};
video_driver->setMaterial(m_material);
video_driver->drawIndexedTriangleList(&vertices[0], 6, &indices[0], 2);
}
/** Implement IShaderConstantsSetCallback. Shader constants setter for post-processing */
void PostProcessing::OnSetConstants(video::IMaterialRendererServices *services, s32 user_data)
{
services->setPixelShaderConstant("boost_amount", &m_boost_amount, 1);
// TODO: texture map
}

View File

@ -0,0 +1,64 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2011 the SuperTuxKart team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_POST_PROCESSING_HPP
#define HEADER_POST_PROCESSING_HPP
#include <IShaderConstantSetCallBack.h>
#include <SMaterial.h>
namespace irr
{
namespace video { class IVideoDriver; class ITexture; }
}
using namespace irr;
class PostProcessing : public video::IShaderConstantSetCallBack
{
private:
video::ITexture *m_render_target;
video::SMaterial m_material;
bool m_supported;
/** Boost amount, used to tune the motion blur. Must be in the range 0.0 to 1.0 */
float m_boost_amount;
public:
PostProcessing();
virtual ~PostProcessing();
/** Initialization/termination management */
void init(video::IVideoDriver* video_driver);
void shut();
/** Those should be called around the part where we render the scene to be post-processed */
void beginCapture();
void endCapture();
/** Render the post-processed scene */
void render();
/** Is the hardware able to use post-processing? */
inline bool isSupported() const {return m_supported;}
/** Boost amount, used to tune the motion blur. Must be in the range 0.0 to 1.0 */
inline void setBoostAmount(float boost_amount) {m_boost_amount = boost_amount;}
/** Implement IShaderConstantsSetCallback. Shader constants setter for post-processing */
virtual void OnSetConstants(video::IMaterialRendererServices *services, s32 user_data);
};
#endif // HEADER_POST_PROCESSING_HPP

View File

@ -1023,7 +1023,7 @@ void DynamicRibbonWidget::update(float dt)
bool DynamicRibbonWidget::findItemInRows(const char* name, int* p_row, int* p_id)
{
int row = -1;
int id;
int id = -1;
for (int r=0; r<m_rows.size(); r++)
{