Started implementing post-processing

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9311 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
funto66 2011-07-20 23:50:25 +00:00
parent b88a8da625
commit 1079391fd1
5 changed files with 125 additions and 2 deletions

View File

@ -0,0 +1,30 @@
// motion_blur.frag
uniform float boost_amount;
uniform sampler2D color_buffer;
#define BLUR_CENTER vec2(0.5, 0.3)
#define BLUR_SCALE 0.1
#define NB_SAMPLES 12
void main()
{
vec2 texcoords = gl_TexCoord[0].st;
vec3 color = texture2D(color_buffer, texcoords);
vec2 blur_dir = -BLUR_SCALE * (texcoords - BLUR_CENTER);
// Avoid blurring the top of the screen
float blur_factor = (1.0-texcoords.t);
blur_dir *= blur_factor;
vec2 inc_vec = blur_dir / NB_SAMPLES;
vec2 blur_texcoords = texcoords + inc_vec;
for(int i=1 ; i < NB_SAMPLES ; i++)
{
color += texture2D(color_buffer, blur_texcoords);
blur_texcoords += inc_vec;
}
color /= NB_SAMPLES;
gl_FragColor = vec4(color, 0.0);
}

View File

@ -0,0 +1,7 @@
// motion_blur.vert
void main()
{
gl_TexCoord[0].st = vec2(gl_MultiTexCoord0.s, 1.0-gl_MultiTexCoord0.t);
gl_Position = gl_Vertex;
}

View File

@ -387,6 +387,9 @@ namespace UserConfigParams
/** True if hardware skinning should be enabled */
PARAM_PREFIX bool m_hw_skinning_enabled PARAM_DEFAULT( false );
/** True if post-processing effects should be enabled */
PARAM_PREFIX bool m_postprocess_enabled PARAM_DEFAULT( false );
// not saved to file
// ---- Networking

View File

@ -65,6 +65,7 @@ IrrDriver::IrrDriver()
{
m_resolution_changing = RES_CHANGE_NONE;
m_device = NULL;
m_boost_amount = 0.0f;
file_manager->dropFileSystem();
initDevice();
} // IrrDriver
@ -237,6 +238,7 @@ void IrrDriver::initDevice()
m_gui_env = m_device->getGUIEnvironment();
m_video_driver = m_device->getVideoDriver();
// Initialize material2D
video::SMaterial& material2D = m_video_driver->getMaterial2D();
material2D.setFlag(video::EMF_ANTI_ALIASING, true);
for (unsigned int n=0; n<MATERIAL_MAX_TEXTURES; n++)
@ -253,6 +255,35 @@ 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;
}
}
// set cursor visible by default (what's the default is not too clearly documented,
// so let's decide ourselves...)
@ -1206,6 +1237,10 @@ void IrrDriver::update(float dt)
true, video::SColor(255,100,101,140));
}
// Start the RTT for post-processing
if(UserConfigParams::m_postprocess_enabled)
m_video_driver->setRenderTarget(m_postprocess_render_target, true, true);
{
PROFILER_PUSH_CPU_MARKER("Update GUI widgets", 0x7F, 0x7F, 0x00);
@ -1346,7 +1381,32 @@ 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);
}
m_video_driver->endScene();
// Enable this next print statement to get render information printed
// E.g. number of triangles rendered, culled etc. The stats is only
// printed while the race is running and not while the in-game menu
@ -1384,6 +1444,15 @@ 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,11 +32,13 @@
#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;
@ -60,7 +62,7 @@ struct VideoMode
* ways to manage the 3D scene
* \ingroup graphics
*/
class IrrDriver : public IEventReceiver, public NoCopy
class IrrDriver : public IEventReceiver, public video::IShaderConstantSetCallBack, public NoCopy
{
private:
/** The irrlicht device. */
@ -72,7 +74,14 @@ private:
/** Irrlicht video driver. */
video::IVideoDriver *m_video_driver;
/** Irrlicht race font. */
irr::gui::IGUIFont *m_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;
/** Flag to indicate if a resolution change is pending (which will be
* acted upon in the next update). None means no change, yes means
@ -188,6 +197,11 @@ 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);
// --------------------- RTT --------------------
/**
* Class that provides RTT (currently, only when no other 3D rendering