Enabled motion blur shader in split screen multiplayer.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@12552 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
a14a9df3f1
commit
5445cec7ba
@ -1,17 +1,26 @@
|
||||
// motion_blur.frag
|
||||
|
||||
uniform float boost_amount; // should be in the range [0.0, 1.0]
|
||||
// The actual boost amount (which linearly scales the blur to be shown).
|
||||
// should be in the range [0.0, 1.0], though a larger value might make
|
||||
// the blurring too string. Atm we are using [0, 0.5].
|
||||
uniform float boost_amount;
|
||||
|
||||
// The color buffer to use.
|
||||
uniform sampler2D color_buffer;
|
||||
|
||||
// The blur direction points to the following center (we work in [0, 1]x[0, 1] coordinates):
|
||||
#define BLUR_DIR_CENTER vec2(0.5, 0.7)
|
||||
// Center (in texture coordinates) at which the kart is. A small circle
|
||||
// around this center is not blurred (see mask_radius below)
|
||||
uniform vec2 center;
|
||||
|
||||
// There is a mask around the character so that it doesn't get blurred
|
||||
#define BLUR_MASK_CENTER vec2(0.5, 0.2)
|
||||
#define BLUR_MASK_RADIUS 0.15
|
||||
// The direction to which the blurring aims at
|
||||
uniform vec2 direction;
|
||||
|
||||
// Final scaling factor
|
||||
#define BLUR_SCALE 0.2
|
||||
// Radius of mask around the character in which no blurring happens
|
||||
// so that the kart doesn't get blurred.
|
||||
uniform float mask_radius;
|
||||
|
||||
// Maximum height of texture used
|
||||
uniform float max_tex_height;
|
||||
|
||||
// Number of samples used for blurring
|
||||
#define NB_SAMPLES 12
|
||||
@ -23,24 +32,29 @@ void main()
|
||||
// Sample the color buffer
|
||||
vec3 color = texture2D(color_buffer, texcoords).rgb;
|
||||
|
||||
// If no motion blur is needed, don't do any of the blur computation,
|
||||
// just return the color from the texture.
|
||||
if(boost_amount==0)
|
||||
{
|
||||
gl_FragColor = vec4(color, 1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute the blur direction.
|
||||
// IMPORTANT: we don't normalize it so that it avoids a glitch around BLUR_DIR_CENTER,
|
||||
// IMPORTANT: we don't normalize it so that it avoids a glitch around 'center',
|
||||
// plus it naturally scales the motion blur in a cool way :)
|
||||
vec2 blur_dir = BLUR_DIR_CENTER - texcoords;
|
||||
vec2 blur_dir = direction - texcoords;
|
||||
|
||||
// Compute the blurring factor:
|
||||
// - apply the mask
|
||||
float blur_factor = max(0.0, length(texcoords - BLUR_MASK_CENTER) - BLUR_MASK_RADIUS);
|
||||
// - apply the mask, i.e. no blurring in a small circle around the kart
|
||||
float blur_factor = max(0.0, length(texcoords - center) - mask_radius);
|
||||
|
||||
// - avoid blurring the top of the screen
|
||||
blur_factor *= (1.0-texcoords.t);
|
||||
blur_factor *= (max_tex_height - texcoords.t);
|
||||
|
||||
// - apply the boost amount
|
||||
blur_factor *= boost_amount;
|
||||
|
||||
// - apply a final scaling factor
|
||||
blur_factor *= BLUR_SCALE;
|
||||
|
||||
// Scale the blur direction
|
||||
blur_dir *= blur_factor;
|
||||
|
||||
@ -56,5 +70,5 @@ void main()
|
||||
gl_FragColor = vec4(color, 1.0);
|
||||
|
||||
// Keep this commented line for debugging:
|
||||
// gl_FragColor = vec4(blur_factor, blur_factor, blur_factor, 0.0);
|
||||
//gl_FragColor = vec4(blur_factor, blur_factor, blur_factor, 0.0);
|
||||
}
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_TexCoord[0].st = vec2(gl_MultiTexCoord0.s, 1.0-gl_MultiTexCoord0.t);
|
||||
gl_TexCoord[0].st = vec2(gl_MultiTexCoord0.s, gl_MultiTexCoord0.t);
|
||||
gl_Position = gl_Vertex;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/particle_kind_manager.hpp"
|
||||
#include "graphics/per_camera_node.hpp"
|
||||
#include "graphics/post_processing.hpp"
|
||||
#include "graphics/referee.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "guiengine/modaldialog.hpp"
|
||||
@ -94,7 +95,15 @@ IrrDriver::IrrDriver()
|
||||
*/
|
||||
IrrDriver::~IrrDriver()
|
||||
{
|
||||
m_post_processing.shut();
|
||||
// Note that we can not simply delete m_post_processing here:
|
||||
// m_post_processing uses a material that has a reference to
|
||||
// m_post_processing (for a callback). So when the material is
|
||||
// removed it will try to drop the ref count of its callback object,
|
||||
// which is m_post_processing, and which was already deleted. So
|
||||
// instead we just decrease the ref count here. When the material
|
||||
// is deleted, it will trigger the actual deletion of
|
||||
// PostProcessing when decreasing the refcount of its callback object.
|
||||
m_post_processing->drop();
|
||||
assert(m_device != NULL);
|
||||
|
||||
m_device->drop();
|
||||
@ -102,6 +111,14 @@ IrrDriver::~IrrDriver()
|
||||
m_modes.clear();
|
||||
} // ~IrrDriver
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called before a race is started, after all cameras are set up.
|
||||
*/
|
||||
void IrrDriver::reset()
|
||||
{
|
||||
m_post_processing->reset();
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
@ -443,7 +460,7 @@ void IrrDriver::initDevice()
|
||||
//m_video_driver->enableMaterial2D();
|
||||
|
||||
// Initialize post-processing if supported
|
||||
m_post_processing.init(m_video_driver);
|
||||
m_post_processing = new PostProcessing(m_video_driver);
|
||||
|
||||
// set cursor visible by default (what's the default is not too clearly documented,
|
||||
// so let's decide ourselves...)
|
||||
@ -492,7 +509,7 @@ video::E_DRIVER_TYPE IrrDriver::getEngineDriverType( int index )
|
||||
}
|
||||
|
||||
// Ouput which render will be tried.
|
||||
Log::verbose("irr_driver", "Trying %s rendering.\n", rendererName.c_str());
|
||||
Log::verbose("irr_driver", "Trying %s rendering.", rendererName.c_str());
|
||||
|
||||
return type;
|
||||
}
|
||||
@ -1640,7 +1657,7 @@ void IrrDriver::update(float dt)
|
||||
// Start the RTT for post-processing.
|
||||
// We do this before beginScene() because we want to capture the glClear()
|
||||
// because of tracks that do not have skyboxes (generally add-on tracks)
|
||||
m_post_processing.beginCapture();
|
||||
m_post_processing->beginCapture();
|
||||
}
|
||||
|
||||
m_video_driver->beginScene(back_buffer_clear, /*zBuffer*/ true,
|
||||
@ -1680,10 +1697,10 @@ void IrrDriver::update(float dt)
|
||||
} // for i<world->getNumKarts()
|
||||
|
||||
// Stop capturing for the post-processing
|
||||
m_post_processing.endCapture();
|
||||
m_post_processing->endCapture();
|
||||
|
||||
// Render the post-processed scene
|
||||
m_post_processing.render();
|
||||
m_post_processing->render();
|
||||
|
||||
// Set the viewport back to the full screen for race gui
|
||||
m_video_driver->setViewPort(core::recti(0, 0,
|
||||
@ -1740,7 +1757,10 @@ void IrrDriver::requestScreenshot()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Irrlicht Event handler.
|
||||
/** This is not really used to process events, it's only used to shut down
|
||||
* irrLicht's chatty logging until the event handler is ready to take
|
||||
* the task.
|
||||
*/
|
||||
bool IrrDriver::OnEvent(const irr::SEvent &event)
|
||||
{
|
||||
//TODO: ideally we wouldn't use this object to STFU irrlicht's chatty
|
||||
|
@ -44,7 +44,6 @@ namespace irr
|
||||
}
|
||||
using namespace irr;
|
||||
|
||||
#include "post_processing.hpp"
|
||||
#include "utils/aligned_array.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
@ -53,6 +52,7 @@ using namespace irr;
|
||||
class AbstractKart;
|
||||
class Camera;
|
||||
class PerCameraNode;
|
||||
class PostProcessing;
|
||||
|
||||
/**
|
||||
* \brief class that creates the irrLicht device and offers higher-level
|
||||
@ -72,8 +72,8 @@ private:
|
||||
video::IVideoDriver *m_video_driver;
|
||||
/** Irrlicht race font. */
|
||||
gui::IGUIFont *m_race_font;
|
||||
/** Post-processing */
|
||||
PostProcessing m_post_processing;
|
||||
/** 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
|
||||
@ -122,40 +122,18 @@ private:
|
||||
|
||||
void doScreenShot();
|
||||
public:
|
||||
IrrDriver();
|
||||
~IrrDriver();
|
||||
void initDevice();
|
||||
|
||||
void updateConfigIfRelevant();
|
||||
|
||||
IrrDriver();
|
||||
~IrrDriver();
|
||||
void initDevice();
|
||||
void reset();
|
||||
void updateConfigIfRelevant();
|
||||
void setAllMaterialFlags(scene::IMesh *mesh) const;
|
||||
|
||||
/** Returns a list of all video modes supports by the graphics card. */
|
||||
const std::vector<VideoMode>& getVideoModes() const { return m_modes; }
|
||||
/** Returns the frame size. */
|
||||
const core::dimension2d<u32>& getFrameSize() const
|
||||
{ return m_video_driver->getCurrentRenderTargetSize(); }
|
||||
/** Returns the irrlicht device. */
|
||||
IrrlichtDevice *getDevice() const { return m_device; }
|
||||
/** Returns the irrlicht video driver. */
|
||||
video::IVideoDriver *getVideoDriver() const { return m_video_driver; }
|
||||
/** Returns the irrlicht scene manager. */
|
||||
scene::ISceneManager *getSceneManager() const { return m_scene_manager; }
|
||||
scene::IAnimatedMesh *getAnimatedMesh(const std::string &name);
|
||||
scene::IMesh *getMesh(const std::string &name);
|
||||
/** Returns the gui environment, used to add widgets to a screen. */
|
||||
gui::IGUIEnvironment *getGUI() const { return m_gui_env; }
|
||||
//irr::gui::IGUIFont *getRaceFont() const { return m_race_font; }
|
||||
|
||||
video::ITexture *applyMask(video::ITexture* texture,
|
||||
const std::string& mask_path);
|
||||
|
||||
void displayFPS();
|
||||
/** this is not really used to process events, it's only used to shut down irrLicht's
|
||||
* chatty logging until the event handler is ready to take the task
|
||||
*/
|
||||
bool OnEvent(const irr::SEvent &event);
|
||||
|
||||
const std::string& mask_path);
|
||||
void displayFPS();
|
||||
bool OnEvent(const irr::SEvent &event);
|
||||
void setAmbientLight(const video::SColor &light);
|
||||
video::ITexture *getTexture(const std::string &filename,
|
||||
bool is_premul=false,
|
||||
@ -198,7 +176,6 @@ public:
|
||||
void removeCameraSceneNode(scene::ICameraSceneNode *camera);
|
||||
void removeCamera(Camera *camera);
|
||||
void update(float dt);
|
||||
|
||||
/** Call to change resolution */
|
||||
void changeResolution(const int w, const int h, const bool fullscreen);
|
||||
/** Call this to roll back to the previous resolution if a resolution switch attempt goes bad */
|
||||
@ -212,11 +189,8 @@ public:
|
||||
core::position2di getMouseLocation();
|
||||
|
||||
void printRenderStats();
|
||||
/** Returns the current real time, which might not be 0 at start of the
|
||||
* application. Value in msec.
|
||||
*/
|
||||
unsigned int getRealTime() {return m_device->getTimer()->getRealTime(); }
|
||||
|
||||
bool supportsSplatting();
|
||||
void requestScreenshot();
|
||||
|
||||
void draw2dTriangle(const core::vector2df &a, const core::vector2df &b,
|
||||
const core::vector2df &c,
|
||||
@ -224,12 +198,36 @@ public:
|
||||
const video::SColor *ca=NULL,
|
||||
const video::SColor *cb=NULL,
|
||||
const video::SColor *cc=NULL);
|
||||
|
||||
|
||||
inline PostProcessing* getPostProcessing() {return &m_post_processing;}
|
||||
|
||||
bool supportsSplatting();
|
||||
|
||||
void requestScreenshot();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a list of all video modes supports by the graphics card. */
|
||||
const std::vector<VideoMode>& getVideoModes() const { return m_modes; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the frame size. */
|
||||
const core::dimension2d<u32>& getFrameSize() const
|
||||
{ return m_video_driver->getCurrentRenderTargetSize(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the irrlicht device. */
|
||||
IrrlichtDevice *getDevice() const { return m_device; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the irrlicht video driver. */
|
||||
video::IVideoDriver *getVideoDriver() const { return m_video_driver; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the irrlicht scene manager. */
|
||||
scene::ISceneManager *getSceneManager() const { return m_scene_manager; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the gui environment, used to add widgets to a screen. */
|
||||
gui::IGUIEnvironment *getGUI() const { return m_gui_env; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the current real time, which might not be 0 at start of the
|
||||
* application. Value in msec. */
|
||||
unsigned int getRealTime() {return m_device->getTimer()->getRealTime(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a pointer to the post processing object. */
|
||||
inline PostProcessing* getPostProcessing() {return m_post_processing;}
|
||||
// ------------------------------------------------------------------------
|
||||
#ifdef DEBUG
|
||||
/** Removes debug meshes. */
|
||||
void clearDebugMesh() { m_debug_meshes.clear(); }
|
||||
|
@ -32,19 +32,8 @@
|
||||
using namespace video;
|
||||
using namespace scene;
|
||||
|
||||
PostProcessing::PostProcessing()
|
||||
{
|
||||
m_boost_amount = 0.0f;
|
||||
} // PostProcessing
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
PostProcessing::~PostProcessing()
|
||||
{
|
||||
} // ~PostProcessing
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Initialization */
|
||||
void PostProcessing::init(video::IVideoDriver* video_driver)
|
||||
PostProcessing::PostProcessing(video::IVideoDriver* video_driver)
|
||||
: m_vertices(NULL)
|
||||
{
|
||||
// Check if post-processing is supported on this hardware
|
||||
m_supported = false;
|
||||
@ -89,35 +78,93 @@ void PostProcessing::init(video::IVideoDriver* video_driver)
|
||||
(file_manager->getShaderDir() + "motion_blur.frag").c_str(),
|
||||
"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;
|
||||
m_blur_material.MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
m_blur_material.setTexture(0, m_render_target);
|
||||
m_blur_material.Wireframe = false;
|
||||
m_blur_material.Lighting = false;
|
||||
m_blur_material.ZWriteEnable = false;
|
||||
|
||||
}
|
||||
} // init
|
||||
} // PostProcessing
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Termination */
|
||||
void PostProcessing::shut()
|
||||
PostProcessing::~PostProcessing()
|
||||
{
|
||||
if(!m_supported)
|
||||
return;
|
||||
|
||||
// TODO: do we have to delete/drop anything?
|
||||
} // shut
|
||||
} // ~PostProcessing
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Setup the render target */
|
||||
/** Initialises post processing at the (re-)start of a race. This sets up
|
||||
* the vertices, normals and texture coordinates for each
|
||||
*/
|
||||
void PostProcessing::reset()
|
||||
{
|
||||
unsigned int n = Camera::getNumCameras();
|
||||
m_boost_amount.resize(n);
|
||||
m_vertices.resize(n);
|
||||
m_center.resize(n);
|
||||
m_direction.resize(n);
|
||||
|
||||
for(unsigned int i=0; i<n; i++)
|
||||
{
|
||||
m_boost_amount[i] = 0.0f;
|
||||
|
||||
const core::recti &vp = Camera::getCamera(i)->getViewport();
|
||||
// Map viewport to [-1,1] x [-1,1]
|
||||
float right = vp.LowerRightCorner.X < UserConfigParams::m_width
|
||||
? 0.0f : 1.0f;
|
||||
float left = vp.UpperLeftCorner.X > 0.0f ? 0.0f : -1.0f;
|
||||
float top = vp.UpperLeftCorner.Y > 0.0f ? 0.0f : 1.0f;
|
||||
float bottom = vp.LowerRightCorner.Y < UserConfigParams::m_height
|
||||
? 0.0f : -1.0f;
|
||||
|
||||
m_vertices[i].v0.Pos = core::vector3df(left, bottom, 0);
|
||||
m_vertices[i].v1.Pos = core::vector3df(left, top, 0);
|
||||
m_vertices[i].v2.Pos = core::vector3df(right, top, 0);
|
||||
m_vertices[i].v3.Pos = core::vector3df(right, bottom, 0);
|
||||
m_vertices[i].v0.TCoords = core::vector2df(left ==-1.0f ? 0.0f : 0.5f,
|
||||
bottom==-1.0f ? 0.0f : 0.5f);
|
||||
m_vertices[i].v1.TCoords = core::vector2df(left ==-1.0f ? 0.0f : 0.5f,
|
||||
top == 1.0f ? 1.0f : 0.5f);
|
||||
m_vertices[i].v2.TCoords = core::vector2df(right == 0.0f ? 0.5f : 1.0f,
|
||||
top == 1.0f ? 1.0f : 0.5f);
|
||||
m_vertices[i].v3.TCoords = core::vector2df(right == 0.0f ? 0.5f : 1.0f,
|
||||
bottom==-1.0f ? 0.0f : 0.5f);
|
||||
core::vector3df normal(0,0,1);
|
||||
m_vertices[i].v0.Normal = m_vertices[i].v1.Normal =
|
||||
m_vertices[i].v2.Normal = m_vertices[i].v3.Normal = normal;
|
||||
video::SColor white(0xFF, 0xFF, 0xFF, 0xFF);
|
||||
m_vertices[i].v0.Color = m_vertices[i].v1.Color =
|
||||
m_vertices[i].v2.Color = m_vertices[i].v3.Color = white;
|
||||
|
||||
m_center[i].X=(m_vertices[i].v0.TCoords.X
|
||||
+m_vertices[i].v2.TCoords.X) * 0.5f;
|
||||
|
||||
// Center is around 20 percent from bottom of screen:
|
||||
float tex_height = m_vertices[i].v1.TCoords.Y
|
||||
- m_vertices[i].v0.TCoords.Y;
|
||||
m_center[i].Y=m_vertices[i].v0.TCoords.Y + 0.2f*tex_height;
|
||||
m_direction[i].X = m_center[i].X;
|
||||
m_direction[i].Y = m_vertices[i].v0.TCoords.Y + 0.2f*tex_height;
|
||||
} // for i <number of cameras
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Setup the render target. First determines if there is any need for post-
|
||||
* processing, and if so, set up render to texture.
|
||||
*/
|
||||
void PostProcessing::beginCapture()
|
||||
{
|
||||
if(!m_supported || !UserConfigParams::m_postprocess_enabled ||
|
||||
race_manager->getNumPlayers() > 1)
|
||||
if(!m_supported || !UserConfigParams::m_postprocess_enabled)
|
||||
return;
|
||||
|
||||
bool any_boost = false;
|
||||
for(unsigned int i=0; i<m_boost_amount.size(); i++)
|
||||
any_boost |= m_boost_amount[i]>0.0f;
|
||||
|
||||
// don't capture the input when we have no post-processing to add
|
||||
// Don't capture the input when we have no post-processing to add
|
||||
// it will be faster and this ay we won't lose anti-aliasing
|
||||
if (m_boost_amount <= 0.0f)
|
||||
if(!any_boost)
|
||||
{
|
||||
m_used_pp_this_frame = false;
|
||||
return;
|
||||
@ -128,27 +175,35 @@ void PostProcessing::beginCapture()
|
||||
} // beginCapture
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Restore the framebuffer render target */
|
||||
/** Restore the framebuffer render target.
|
||||
*/
|
||||
void PostProcessing::endCapture()
|
||||
{
|
||||
if(!m_supported || !UserConfigParams::m_postprocess_enabled ||
|
||||
race_manager->getNumPlayers() > 1)
|
||||
!m_used_pp_this_frame)
|
||||
return;
|
||||
|
||||
if (m_used_pp_this_frame)
|
||||
{
|
||||
irr_driver->getVideoDriver()->setRenderTarget(video::ERT_FRAME_BUFFER,
|
||||
true, true, 0);
|
||||
}
|
||||
irr_driver->getVideoDriver()->setRenderTarget(video::ERT_FRAME_BUFFER,
|
||||
true, true, 0);
|
||||
} // endCapture
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Set the boost amount according to the speed of the camera */
|
||||
void PostProcessing::giveBoost(unsigned int camera_index)
|
||||
{
|
||||
m_boost_amount[camera_index] = 2.5f;
|
||||
} // giveBoost
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void PostProcessing::update(float dt)
|
||||
{
|
||||
if (m_boost_amount > 0.0f)
|
||||
for(unsigned int i=0; i<m_boost_amount.size(); i++)
|
||||
{
|
||||
m_boost_amount -= dt*3.5f;
|
||||
if (m_boost_amount < 0.0f) m_boost_amount = 0.0f;
|
||||
if (m_boost_amount[i] > 0.0f)
|
||||
{
|
||||
m_boost_amount[i] -= dt*3.5f;
|
||||
if (m_boost_amount[i] < 0.0f) m_boost_amount[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
} // update
|
||||
|
||||
@ -156,38 +211,29 @@ void PostProcessing::update(float dt)
|
||||
/** Render the post-processed scene */
|
||||
void PostProcessing::render()
|
||||
{
|
||||
if(!m_supported || !UserConfigParams::m_postprocess_enabled ||
|
||||
race_manager->getNumPlayers() > 1)
|
||||
if(!m_supported || !UserConfigParams::m_postprocess_enabled)
|
||||
return;
|
||||
|
||||
if (!m_used_pp_this_frame)
|
||||
{
|
||||
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);
|
||||
|
||||
u16 indices[6] = {0, 1, 2, 3, 0, 2};
|
||||
|
||||
video_driver->setMaterial(m_material);
|
||||
video_driver->drawIndexedTriangleList(&vertices[0], 4, &indices[0], 2);
|
||||
} // render
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Set the boost amount according to the speed of the camera */
|
||||
void PostProcessing::giveBoost()
|
||||
{
|
||||
m_boost_amount = 2.5f;
|
||||
} // giveBoost
|
||||
for(m_current_camera=0; m_current_camera<Camera::getNumCameras();
|
||||
m_current_camera++)
|
||||
{
|
||||
Camera *camera = Camera::getCamera(m_current_camera);
|
||||
// Draw the fullscreen quad while applying the corresponding
|
||||
// post-processing shaders
|
||||
video::IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||
video_driver->setMaterial(m_blur_material);
|
||||
video_driver->drawIndexedTriangleList(&(m_vertices[m_current_camera].v0),
|
||||
4, &indices[0], 2);
|
||||
}
|
||||
|
||||
} // render
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Implement IShaderConstantsSetCallback. Shader constants setter for
|
||||
@ -195,7 +241,24 @@ void PostProcessing::giveBoost()
|
||||
void PostProcessing::OnSetConstants(video::IMaterialRendererServices *services,
|
||||
s32 user_data)
|
||||
{
|
||||
services->setPixelShaderConstant("boost_amount", &m_boost_amount, 1);
|
||||
// We need the maximum texture coordinates:
|
||||
float max_tex_height = m_vertices[m_current_camera].v1.TCoords.Y;
|
||||
services->setPixelShaderConstant("max_tex_height", &max_tex_height, 1);
|
||||
|
||||
float boost_amount = m_boost_amount[m_current_camera] * 0.2f;
|
||||
|
||||
if(m_boost_amount.size()>1)
|
||||
boost_amount *= 2.0f;
|
||||
services->setPixelShaderConstant("boost_amount", &boost_amount, 1);
|
||||
services->setPixelShaderConstant("center",
|
||||
&(m_center[m_current_camera].X), 2);
|
||||
services->setPixelShaderConstant("direction",
|
||||
&(m_direction[m_current_camera].X), 2);
|
||||
|
||||
// Use a radius of 0.15 when showing a single kart, otherwise (2-4 karts
|
||||
// on splitscreen) use only 0.75.
|
||||
float radius = Camera::getNumCameras()==1 ? 0.15f : 0.075f;
|
||||
services->setPixelShaderConstant("mask_radius", &radius, 1);
|
||||
const int texunit = 0;
|
||||
services->setPixelShaderConstant("color_buffer", &texunit, 1);
|
||||
} // OnSetConstants
|
||||
|
@ -18,8 +18,11 @@
|
||||
#ifndef HEADER_POST_PROCESSING_HPP
|
||||
#define HEADER_POST_PROCESSING_HPP
|
||||
|
||||
#include <IShaderConstantSetCallBack.h>
|
||||
#include <SMaterial.h>
|
||||
#include "IShaderConstantSetCallBack.h"
|
||||
#include "S3DVertex.h"
|
||||
#include "SMaterial.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
@ -33,40 +36,56 @@ using namespace irr;
|
||||
class PostProcessing : public video::IShaderConstantSetCallBack
|
||||
{
|
||||
private:
|
||||
video::ITexture *m_render_target;
|
||||
video::SMaterial m_material;
|
||||
bool m_supported;
|
||||
video::ITexture *m_render_target;
|
||||
/** Material to be used when blurring is used. */
|
||||
video::SMaterial m_blur_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;
|
||||
|
||||
bool m_used_pp_this_frame;
|
||||
std::vector<float> m_boost_amount;
|
||||
|
||||
/** The center of blurring, in texture coordinates [0,1]).*/
|
||||
std::vector<core::vector2df> m_center;
|
||||
|
||||
/** The center to which the blurring is aimed at, in [0,1]. */
|
||||
std::vector<core::vector2df> m_direction;
|
||||
|
||||
/** True if any of the cameras is using post processing. */
|
||||
bool m_used_pp_this_frame;
|
||||
|
||||
/** Currently active camera during post-processing, needed in the
|
||||
* OnSetConstants callback. */
|
||||
unsigned int m_current_camera;
|
||||
|
||||
|
||||
struct Quad { video::S3DVertex v0, v1, v2, v3; };
|
||||
|
||||
/** The vertices for the rectangle used for each camera. This includes
|
||||
* the vertex position, normal, and texture coordinate. */
|
||||
std::vector<Quad> m_vertices;
|
||||
|
||||
public:
|
||||
PostProcessing();
|
||||
virtual ~PostProcessing();
|
||||
|
||||
/** Initialization/termination management */
|
||||
void init(video::IVideoDriver* video_driver);
|
||||
void shut();
|
||||
|
||||
PostProcessing(video::IVideoDriver* video_driver);
|
||||
virtual ~PostProcessing();
|
||||
|
||||
void reset();
|
||||
/** Those should be called around the part where we render the scene to be post-processed */
|
||||
void beginCapture();
|
||||
void endCapture();
|
||||
|
||||
void update(float dt);
|
||||
void beginCapture();
|
||||
void endCapture();
|
||||
void update(float dt);
|
||||
|
||||
/** Render the post-processed scene */
|
||||
void render();
|
||||
void render();
|
||||
|
||||
/** Is the hardware able to use post-processing? */
|
||||
inline bool isSupported() const {return m_supported;}
|
||||
inline bool isSupported() const {return m_supported;}
|
||||
|
||||
/** Use motion blur for a short time */
|
||||
void giveBoost();
|
||||
void giveBoost(unsigned int cam_index);
|
||||
|
||||
/** Implement IShaderConstantsSetCallback. Shader constants setter for post-processing */
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *services, s32 user_data);
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *services, s32 user_data);
|
||||
};
|
||||
|
||||
#endif // HEADER_POST_PROCESSING_HPP
|
||||
|
@ -211,6 +211,11 @@ void InputManager::handleStaticAction(int key, int value)
|
||||
{
|
||||
AbstractKart* kart = world->getLocalPlayerKart(0);
|
||||
kart->setPowerup(PowerupManager::POWERUP_ZIPPER, 10000);
|
||||
if(world->getCurrentNumPlayers()>1)
|
||||
{
|
||||
kart = world->getLocalPlayerKart(1);
|
||||
kart->setPowerup(PowerupManager::POWERUP_ZIPPER, 10000);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "config/stk_config.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/post_processing.hpp"
|
||||
#include "input/input_manager.hpp"
|
||||
#include "items/attachment.hpp"
|
||||
#include "items/item.hpp"
|
||||
@ -445,7 +446,7 @@ void PlayerController::handleZipper(bool play_sound)
|
||||
}
|
||||
|
||||
// Apply the motion blur according to the speed of the kart
|
||||
irr_driver->getPostProcessing()->giveBoost();
|
||||
irr_driver->getPostProcessing()->giveBoost(m_camera->getIndex());
|
||||
|
||||
m_kart->showZipperFire();
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/hardware_skinning.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "input/device_manager.hpp"
|
||||
@ -181,6 +182,9 @@ void World::init()
|
||||
rg->init();
|
||||
rg->clearAllMessages();
|
||||
}
|
||||
|
||||
// Reset all data structures that depend on number of karts.
|
||||
irr_driver->reset();
|
||||
} // init
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user