Merged with trunk, part 1 (due to previous failures I am splitting this
patch). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/uni@14605 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
c0783283e0
commit
bced8cdb9f
@ -1139,7 +1139,7 @@ MATHJAX_RELPATH = http://www.mathjax.org/mathjax
|
||||
# typically be disabled. For large projects the javascript based search engine
|
||||
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
|
||||
|
||||
SEARCHENGINE = NO
|
||||
SEARCHENGINE = YES
|
||||
|
||||
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
||||
# implemented using a PHP enabled web server instead of at the web client
|
||||
|
@ -1202,7 +1202,7 @@ MATHJAX_EXTENSIONS =
|
||||
# typically be disabled. For large projects the javascript based search engine
|
||||
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
|
||||
|
||||
SEARCHENGINE = NO
|
||||
SEARCHENGINE = YES
|
||||
|
||||
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
||||
# implemented using a PHP enabled web server instead of at the web client
|
||||
|
@ -69,10 +69,14 @@ supertuxkart_SOURCES = \
|
||||
config/device_config.hpp \
|
||||
graphics/CBatchingMesh.cpp \
|
||||
graphics/CBatchingMesh.hpp \
|
||||
graphics/callbacks.cpp \
|
||||
graphics/callbacks.hpp \
|
||||
graphics/camera.cpp \
|
||||
graphics/camera.hpp \
|
||||
graphics/explosion.cpp \
|
||||
graphics/explosion.hpp \
|
||||
graphics/glow.cpp \
|
||||
graphics/glow.hpp \
|
||||
graphics/hardware_skinning.cpp \
|
||||
graphics/hardware_skinning.hpp \
|
||||
graphics/hit_effect.hpp \
|
||||
@ -80,6 +84,11 @@ supertuxkart_SOURCES = \
|
||||
graphics/hit_sfx.hpp \
|
||||
graphics/irr_driver.cpp \
|
||||
graphics/irr_driver.hpp \
|
||||
graphics/large_mesh_buffer.hpp \
|
||||
graphics/lens_flare.cpp \
|
||||
graphics/lens_flare.hpp \
|
||||
graphics/light.hpp \
|
||||
graphics/light.cpp \
|
||||
graphics/lod_node.cpp \
|
||||
graphics/lod_node.hpp \
|
||||
graphics/material.cpp \
|
||||
@ -102,10 +111,19 @@ supertuxkart_SOURCES = \
|
||||
graphics/post_processing.hpp \
|
||||
graphics/rain.cpp \
|
||||
graphics/rain.hpp \
|
||||
graphics/render.cpp \
|
||||
graphics/referee.cpp \
|
||||
graphics/referee.hpp \
|
||||
graphics/rtts.hpp \
|
||||
graphics/rtts.cpp \
|
||||
graphics/screenquad.cpp \
|
||||
graphics/screenquad.hpp \
|
||||
graphics/shaders.cpp \
|
||||
graphics/shaders.hpp \
|
||||
graphics/shadow.cpp \
|
||||
graphics/shadow.hpp \
|
||||
graphics/shadow_importance.cpp \
|
||||
graphics/shadow_importance.hpp \
|
||||
graphics/show_curve.cpp \
|
||||
graphics/show_curve.hpp \
|
||||
graphics/skid_marks.cpp \
|
||||
@ -114,6 +132,12 @@ supertuxkart_SOURCES = \
|
||||
graphics/slip_stream.hpp \
|
||||
graphics/stars.cpp \
|
||||
graphics/stars.hpp \
|
||||
graphics/sun.hpp \
|
||||
graphics/sun.cpp \
|
||||
graphics/water.hpp \
|
||||
graphics/water.cpp \
|
||||
graphics/wind.hpp \
|
||||
graphics/wind.cpp \
|
||||
guiengine/CGUISpriteBank.cpp \
|
||||
guiengine/CGUISpriteBank.h \
|
||||
guiengine/abstract_state_manager.cpp \
|
||||
@ -496,6 +520,8 @@ supertuxkart_SOURCES = \
|
||||
utils/aligned_array.hpp \
|
||||
utils/constants.hpp \
|
||||
utils/constants.cpp \
|
||||
utils/helpers.hpp \
|
||||
utils/helpers.cpp \
|
||||
utils/leak_check.cpp \
|
||||
utils/leak_check.hpp \
|
||||
utils/log.cpp \
|
||||
@ -510,6 +536,7 @@ supertuxkart_SOURCES = \
|
||||
utils/string_utils.hpp \
|
||||
utils/synchronised.hpp \
|
||||
utils/time.hpp \
|
||||
utils/time.cpp \
|
||||
utils/translation.cpp \
|
||||
utils/translation.hpp \
|
||||
utils/utf8.h \
|
||||
@ -517,7 +544,8 @@ supertuxkart_SOURCES = \
|
||||
utils/utf8/core.h \
|
||||
utils/utf8/unchecked.h \
|
||||
utils/vec3.cpp \
|
||||
utils/vec3.hpp
|
||||
utils/vec3.hpp \
|
||||
utils/vs.hpp
|
||||
|
||||
# Link in the specific gcc 4.1 bug work around
|
||||
supertuxkart_LDADD = \
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Lucas Baudin, Joerg Henrichs
|
||||
// Copyright (C) 2010-2013 Lucas Baudin, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -162,7 +162,7 @@ void Addon::writeXML(std::ofstream *out_stream)
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string Addon::getDateAsString() const
|
||||
{
|
||||
return Time::toString(m_date);
|
||||
return StkTime::toString(m_date);
|
||||
} // getDateAsString
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Lucas Baudin, Joerg Henrichs
|
||||
// Copyright (C) 2010-2013 Lucas Baudin, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -99,7 +99,7 @@ private:
|
||||
* in the addons.xml file. */
|
||||
bool m_still_exists;
|
||||
/** Date when the addon was added. */
|
||||
Time::TimeType m_date;
|
||||
StkTime::TimeType m_date;
|
||||
/** A description of this addon. */
|
||||
core::stringw m_description;
|
||||
/** The URL of the icon (relative to the server) */
|
||||
@ -171,7 +171,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the date (in seconds since epoch) when the addon was
|
||||
* uploaded. */
|
||||
Time::TimeType getDate() const { return m_date; }
|
||||
StkTime::TimeType getDate() const { return m_date; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a user readable date as a string. */
|
||||
std::string getDateAsString() const;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Lucas Baudin
|
||||
// Copyright (C) 2010-2013 Lucas Baudin
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Lucas Baudin, Joerg Henrichs
|
||||
// Copyright (C) 2010-2013 Lucas Baudin, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Lucas Baudin
|
||||
// Copyright (C) 2010-2013 Lucas Baudin
|
||||
// 2011 Lucas Baudin, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2012 Joerg Henrichs
|
||||
// Copyright (C) 2012-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Lucas Baudin
|
||||
// 2011 Lucas Baudin, Joerg Henrichs
|
||||
// Copyright (C) 2010-2013 Lucas Baudin
|
||||
// Copyright (C) 2011-2013 Lucas Baudin, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Lucas Baudin
|
||||
// 2011 Lucas Baudin, Joerg Henrichs
|
||||
// Copyright (C) 2010-2013 Lucas Baudin
|
||||
// Copyright (C) 2011-2013 Lucas Baudin, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -24,14 +24,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
# include <windows.h>
|
||||
# define isnan _isnan
|
||||
#else
|
||||
# include <sys/time.h>
|
||||
# include <math.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "addons/news_manager.hpp"
|
||||
#include "addons/request.hpp"
|
||||
@ -42,6 +35,7 @@
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/time.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Create a thread that handles all network functions independent of the
|
||||
@ -270,7 +264,7 @@ CURLcode NetworkHttp::init(bool forceRefresh)
|
||||
bool download = UserConfigParams::m_news_last_updated==0 ||
|
||||
UserConfigParams::m_news_last_updated
|
||||
+UserConfigParams::m_news_frequency
|
||||
< Time::getTimeSinceEpoch() || forceRefresh;
|
||||
< StkTime::getTimeSinceEpoch() || forceRefresh;
|
||||
|
||||
if(!download)
|
||||
{
|
||||
@ -303,7 +297,7 @@ CURLcode NetworkHttp::init(bool forceRefresh)
|
||||
{
|
||||
std::string xml_file = file_manager->getAddonsFile("news.xml");
|
||||
if(download)
|
||||
UserConfigParams::m_news_last_updated = Time::getTimeSinceEpoch();
|
||||
UserConfigParams::m_news_last_updated = StkTime::getTimeSinceEpoch();
|
||||
const XMLNode *xml = new XMLNode(xml_file);
|
||||
|
||||
// A proper news file has at least a version number, mtime, and
|
||||
@ -319,7 +313,7 @@ CURLcode NetworkHttp::init(bool forceRefresh)
|
||||
status = downloadFileInternal(&r);
|
||||
if(status==CURLE_OK)
|
||||
UserConfigParams::m_news_last_updated =
|
||||
Time::getTimeSinceEpoch();
|
||||
StkTime::getTimeSinceEpoch();
|
||||
delete xml;
|
||||
xml = new XMLNode(xml_file);
|
||||
}
|
||||
@ -416,7 +410,7 @@ CURLcode NetworkHttp::loadAddonsList(const XMLNode *xml,
|
||||
bool forceRefresh)
|
||||
{
|
||||
std::string addon_list_url("");
|
||||
Time::TimeType mtime(0);
|
||||
StkTime::TimeType mtime(0);
|
||||
const XMLNode *include = xml->getNode("include");
|
||||
if(include)
|
||||
{
|
||||
@ -456,7 +450,7 @@ CURLcode NetworkHttp::loadAddonsList(const XMLNode *xml,
|
||||
{
|
||||
std::string xml_file = file_manager->getAddonsFile("addons.xml");
|
||||
if(download)
|
||||
UserConfigParams::m_addons_last_updated=Time::getTimeSinceEpoch();
|
||||
UserConfigParams::m_addons_last_updated=StkTime::getTimeSinceEpoch();
|
||||
const XMLNode *xml = new XMLNode(xml_file);
|
||||
addons_manager->initOnline(xml);
|
||||
if(UserConfigParams::logAddons())
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Lucas Baudin
|
||||
// 2011 Lucas Baudin, Joerg Henrichs
|
||||
// Copyright (C) 2010-2013 Lucas Baudin
|
||||
// Copyright (C) 2011-2013 Lucas Baudin, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs
|
||||
// Copyright (C) 2011-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -50,7 +50,7 @@ NewsManager::~NewsManager()
|
||||
*/
|
||||
void NewsManager::init()
|
||||
{
|
||||
UserConfigParams::m_news_last_updated = Time::getTimeSinceEpoch();
|
||||
UserConfigParams::m_news_last_updated = StkTime::getTimeSinceEpoch();
|
||||
|
||||
std::string xml_file = file_manager->getAddonsFile("news.xml");
|
||||
const XMLNode *xml = new XMLNode(xml_file);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs
|
||||
// Copyright (C) 2011-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs
|
||||
// Copyright (C) 2011-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs
|
||||
// Copyright (C) 2011-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Lucas Baudin
|
||||
// Copyright (C) 2010-2013 Lucas Baudin
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Lucas Baudin
|
||||
// Copyright (C) 2010-2013 Lucas Baudin
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Joerg Henrichs
|
||||
// Copyright (C) 2009-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -21,14 +21,10 @@
|
||||
#include "animations/ipo.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
||||
# define isnan _isnan
|
||||
#else
|
||||
# include <math.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
|
||||
AnimationBase::AnimationBase(const XMLNode &node)
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Joerg Henrichs
|
||||
// Copyright (C) 2009-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Joerg Henrichs
|
||||
// Copyright (C) 2009-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -19,14 +19,11 @@
|
||||
#include "animations/ipo.hpp"
|
||||
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
||||
# define isnan _isnan
|
||||
#else
|
||||
# include <math.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
const std::string Ipo::m_all_channel_names[IPO_MAX] =
|
||||
{"LocX", "LocY", "LocZ", "LocXYZ",
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Joerg Henrichs
|
||||
// Copyright (C) 2009-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Joerg Henrichs
|
||||
// Copyright (C) 2009-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Joerg Henrichs
|
||||
// Copyright (C) 2009-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 Patrick Ammann <pammann@aro.ch>
|
||||
// Copyright (C) 2008 Joerg Henrichs, Patrick Ammann
|
||||
// Copyright (C) 2006-2013 Patrick Ammann <pammann@aro.ch>
|
||||
// Copyright (C) 2008-2013 Joerg Henrichs, Patrick Ammann
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 Patrick Ammann <pammann@aro.ch>
|
||||
// Copyright (C) 2006-2013 Patrick Ammann <pammann@aro.ch>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 Patrick Ammann <pammann@aro.ch>
|
||||
// Copyright (C) 2006-2013 Patrick Ammann <pammann@aro.ch>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
// Copyright (C) 2008-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
// Copyright (C) 2008-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 Patrick Ammann <pammann@aro.ch>
|
||||
// Copyright (C) 2008 Patrick Ammann <pammann@aro.ch>, Joerg Henrichs
|
||||
// Copyright (C) 2006-2013 Patrick Ammann <pammann@aro.ch>
|
||||
// Copyright (C) 2008-2013 Patrick Ammann <pammann@aro.ch>, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 Patrick Ammann <pammann@aro.ch>
|
||||
// Copyright (C) 2008 Patrick Ammann <pammann@aro.ch>, Joerg Henrichs
|
||||
// Copyright (C) 2006-2013 Patrick Ammann <pammann@aro.ch>
|
||||
// Copyright (C) 2008-2013 Patrick Ammann <pammann@aro.ch>, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2007 Damien Morel <divdams@free.fr>
|
||||
// Copyright (C) 2007-2013 Damien Morel <divdams@free.fr>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2007 Damien Morel <divdams@free.fr>
|
||||
// Copyright (C) 2007-2013 Damien Morel <divdams@free.fr>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 Patrick Ammann <pammann@aro.ch>
|
||||
// Copyright (C) 2008 Joerg Henrichs, Patrick Ammann
|
||||
// Copyright (C) 2006-2013 Patrick Ammann <pammann@aro.ch>
|
||||
// Copyright (C) 2008-2013 Joerg Henrichs, Patrick Ammann
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -55,6 +55,7 @@ public:
|
||||
virtual void resume() = 0;
|
||||
virtual void speed(float factor) = 0;
|
||||
virtual void volume(float gain) = 0;
|
||||
virtual void masterVolume(float gain) = 0;
|
||||
virtual SFXManager::SFXStatus
|
||||
getStatus() = 0;
|
||||
virtual void onSoundEnabledBack() = 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Marianne Gagnon
|
||||
// Copyright (C) 2010-2013 Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -18,6 +18,7 @@
|
||||
|
||||
#include "audio/sfx_buffer.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
|
||||
@ -76,6 +77,8 @@ SFXBuffer::SFXBuffer(const std::string& file,
|
||||
|
||||
bool SFXBuffer::load()
|
||||
{
|
||||
if (UserConfigParams::m_sfx == false) return false;
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
if (m_loaded) return false;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 Marianne Gagnon
|
||||
// Copyright (C) 2010-2013 Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
// Copyright (C) 2008-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -154,14 +154,16 @@ void SFXManager::loadSfx()
|
||||
std::cerr << "Could not read sounf effects XML file " << sfx_config_name.c_str() << std::endl;
|
||||
}
|
||||
|
||||
int i;
|
||||
|
||||
const int amount = root->getNumNodes();
|
||||
for (int i=0; i<amount; i++)
|
||||
for (i=0; i<amount; i++)
|
||||
{
|
||||
const XMLNode* node = root->getNode(i);
|
||||
|
||||
if (node->getName() == "sfx")
|
||||
{
|
||||
loadSingleSfx(node);
|
||||
loadSingleSfx(node, "", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -171,7 +173,27 @@ void SFXManager::loadSfx()
|
||||
}// nend for
|
||||
|
||||
delete root;
|
||||
} // loadSfx
|
||||
|
||||
// Now load them in parallel
|
||||
const int max = m_all_sfx_types.size();
|
||||
SFXBuffer **array = new SFXBuffer *[max];
|
||||
i = 0;
|
||||
|
||||
for (std::map<std::string, SFXBuffer*>::iterator it = m_all_sfx_types.begin();
|
||||
it != m_all_sfx_types.end(); it++)
|
||||
{
|
||||
SFXBuffer* const buffer = (*it).second;
|
||||
array[i++] = buffer;
|
||||
}
|
||||
|
||||
#pragma omp parallel for private(i)
|
||||
for (i = 0; i < max; i++)
|
||||
{
|
||||
array[i]->load();
|
||||
}
|
||||
|
||||
delete [] array;
|
||||
} // loadSfx
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Introduces a mechanism by which one can load sound effects beyond the basic
|
||||
@ -188,7 +210,8 @@ SFXBuffer* SFXManager::addSingleSfx(const std::string &sfx_name,
|
||||
bool positional,
|
||||
float rolloff,
|
||||
float max_width,
|
||||
float gain)
|
||||
float gain,
|
||||
const bool load)
|
||||
{
|
||||
|
||||
SFXBuffer* buffer = new SFXBuffer(sfx_file, positional, rolloff, max_width, gain);
|
||||
@ -205,7 +228,7 @@ SFXBuffer* SFXManager::addSingleSfx(const std::string &sfx_name,
|
||||
if (UserConfigParams::logMisc())
|
||||
Log::debug("SFXManager", "Loading SFX %s\n", sfx_file.c_str());
|
||||
|
||||
if (buffer->load()) return buffer;
|
||||
if (load && buffer->load()) return buffer;
|
||||
|
||||
return NULL;
|
||||
} // addSingleSFX
|
||||
@ -215,7 +238,8 @@ SFXBuffer* SFXManager::addSingleSfx(const std::string &sfx_name,
|
||||
* \param node The XML node with the data for this sfx.
|
||||
*/
|
||||
SFXBuffer* SFXManager::loadSingleSfx(const XMLNode* node,
|
||||
const std::string &path)
|
||||
const std::string &path,
|
||||
const bool load)
|
||||
{
|
||||
std::string filename;
|
||||
|
||||
@ -254,7 +278,8 @@ SFXBuffer* SFXManager::loadSingleSfx(const XMLNode* node,
|
||||
tmpbuffer.isPositional(),
|
||||
tmpbuffer.getRolloff(),
|
||||
tmpbuffer.getMaxDist(),
|
||||
tmpbuffer.getGain());
|
||||
tmpbuffer.getGain(),
|
||||
load);
|
||||
|
||||
} // loadSingleSfx
|
||||
|
||||
@ -288,7 +313,7 @@ SFXBase* SFXManager::createSoundSource(SFXBuffer* buffer,
|
||||
SFXBase* sfx = new DummySFX(buffer, positional, buffer->getGain(), owns_buffer);
|
||||
#endif
|
||||
|
||||
sfx->volume(m_master_gain);
|
||||
sfx->masterVolume(m_master_gain);
|
||||
|
||||
if (add_to_SFX_list) m_all_sfx.push_back(sfx);
|
||||
|
||||
@ -442,7 +467,7 @@ void SFXManager::setMasterSFXVolume(float gain)
|
||||
for (std::vector<SFXBase*>::iterator i=m_all_sfx.begin();
|
||||
i!=m_all_sfx.end(); i++)
|
||||
{
|
||||
(*i)->volume(m_master_gain);
|
||||
(*i)->masterVolume(m_master_gain);
|
||||
} // for i in m_all_sfx
|
||||
}
|
||||
|
||||
@ -451,7 +476,7 @@ void SFXManager::setMasterSFXVolume(float gain)
|
||||
std::map<std::string, SFXBase*>::iterator i = m_quick_sounds.begin();
|
||||
for (; i != m_quick_sounds.end(); i++)
|
||||
{
|
||||
(*i).second->volume(m_master_gain);
|
||||
(*i).second->masterVolume(m_master_gain);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
// Copyright (C) 2008-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -106,13 +106,15 @@ public:
|
||||
virtual ~SFXManager();
|
||||
bool sfxAllowed();
|
||||
SFXBuffer* loadSingleSfx(const XMLNode* node,
|
||||
const std::string &path=std::string(""));
|
||||
const std::string &path=std::string(""),
|
||||
const bool load = true);
|
||||
SFXBuffer* addSingleSfx(const std::string &sfx_name,
|
||||
const std::string &filename,
|
||||
bool positional,
|
||||
float rolloff,
|
||||
float max_width,
|
||||
float gain);
|
||||
float gain,
|
||||
const bool load = true);
|
||||
|
||||
SFXBase* createSoundSource(SFXBuffer* info,
|
||||
const bool addToSFXList=true,
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 Patrick Ammann <pammann@aro.ch>
|
||||
// 2009-2011 Marianne Gagnon
|
||||
// Copyright (C) 2006-2013 Patrick Ammann <pammann@aro.ch>
|
||||
// Copyright (C) 2009-2013 Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -20,11 +20,11 @@
|
||||
#if HAVE_OGGVORBIS
|
||||
|
||||
#include "audio/sfx_openal.hpp"
|
||||
|
||||
#include "audio/sfx_buffer.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <OpenAL/al.h>
|
||||
@ -32,8 +32,16 @@
|
||||
# include <AL/al.h>
|
||||
#endif
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
||||
# define isnan _isnan
|
||||
#else
|
||||
# include <math.h>
|
||||
#endif
|
||||
|
||||
|
||||
SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool ownsBuffer) : SFXBase()
|
||||
{
|
||||
@ -44,6 +52,7 @@ SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool ownsBu
|
||||
m_defaultGain = gain;
|
||||
m_loop = false;
|
||||
m_gain = -1.0f;
|
||||
m_master_gain = 1.0f;
|
||||
m_owns_buffer = ownsBuffer;
|
||||
|
||||
// Don't initialise anything else if the sfx manager was not correctly
|
||||
@ -98,11 +107,11 @@ bool SFXOpenAL::init()
|
||||
|
||||
if (m_gain < 0.0f)
|
||||
{
|
||||
alSourcef (m_soundSource, AL_GAIN, m_defaultGain);
|
||||
alSourcef (m_soundSource, AL_GAIN, m_defaultGain * m_master_gain);
|
||||
}
|
||||
else
|
||||
{
|
||||
alSourcef (m_soundSource, AL_GAIN, m_gain);
|
||||
alSourcef (m_soundSource, AL_GAIN, m_gain * m_master_gain);
|
||||
}
|
||||
|
||||
if (m_positional) alSourcei (m_soundSource, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
@ -121,7 +130,7 @@ bool SFXOpenAL::init()
|
||||
*/
|
||||
void SFXOpenAL::speed(float factor)
|
||||
{
|
||||
if(!m_ok) return;
|
||||
if(!m_ok || isnan(factor)) return;
|
||||
|
||||
//OpenAL only accepts pitches in the range of 0.5 to 2.0
|
||||
if(factor > 2.0f)
|
||||
@ -146,10 +155,22 @@ void SFXOpenAL::volume(float gain)
|
||||
|
||||
if(!m_ok) return;
|
||||
|
||||
alSourcef(m_soundSource, AL_GAIN, m_defaultGain * gain);
|
||||
alSourcef(m_soundSource, AL_GAIN, m_gain * m_master_gain);
|
||||
SFXManager::checkError("setting volume");
|
||||
} // volume
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXOpenAL::masterVolume(float gain)
|
||||
{
|
||||
m_master_gain = gain;
|
||||
|
||||
if(!m_ok) return;
|
||||
|
||||
alSourcef(m_soundSource, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain);
|
||||
SFXManager::checkError("setting volume");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Loops this sound effect.
|
||||
*/
|
||||
@ -258,7 +279,7 @@ void SFXOpenAL::position(const Vec3 &position)
|
||||
}
|
||||
else
|
||||
{
|
||||
alSourcef(m_soundSource, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain));
|
||||
alSourcef(m_soundSource, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain);
|
||||
}
|
||||
|
||||
SFXManager::checkError("positioning");
|
||||
@ -295,7 +316,7 @@ void SFXOpenAL::onSoundEnabledBack()
|
||||
alSourcef(m_soundSource, AL_GAIN, 0);
|
||||
play();
|
||||
pause();
|
||||
alSourcef(m_soundSource, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain));
|
||||
alSourcef(m_soundSource, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 Patrick Ammann <pammann@aro.ch>
|
||||
// Copyright (C) 2006-2013 Patrick Ammann <pammann@aro.ch>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -56,6 +56,9 @@ private:
|
||||
sounds later. */
|
||||
float m_gain;
|
||||
|
||||
/** The master gain set in user preferences */
|
||||
float m_master_gain;
|
||||
|
||||
bool m_owns_buffer;
|
||||
|
||||
public:
|
||||
@ -74,6 +77,7 @@ public:
|
||||
virtual void speed(float factor);
|
||||
virtual void position(const Vec3 &position);
|
||||
virtual void volume(float gain);
|
||||
virtual void masterVolume(float gain);
|
||||
virtual SFXManager::SFXStatus getStatus();
|
||||
virtual void onSoundEnabledBack();
|
||||
virtual void setRolloff(float rolloff);
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
// Copyright (C) 2008-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
// Copyright (C) 2008-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
// Copyright (C) 2008-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
// Copyright (C) 2008-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 SuperTuxKart-Team
|
||||
// Copyright (C) 2010-2013 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 SuperTuxKart-Team
|
||||
// Copyright (C) 2010-2013 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
// Copyright (C) 2008-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
// Copyright (C) 2008-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 SuperTuxKart-Team
|
||||
// Copyright (C) 2010-2013 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 SuperTuxKart-Team
|
||||
// Copyright (C) 2010-2013 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2012
|
||||
// Copyright (C) 2012-2013 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -79,7 +79,7 @@ void PlayerProfile::incrementUseFrequency()
|
||||
//------------------------------------------------------------------------------
|
||||
int64_t PlayerProfile::generateUniqueId(const char* playerName)
|
||||
{
|
||||
return ((int64_t)(Time::getTimeSinceEpoch()) << 32) |
|
||||
return ((int64_t)(StkTime::getTimeSinceEpoch()) << 32) |
|
||||
((rand() << 16) & 0xFFFF0000) |
|
||||
(StringUtils::simpleHash(playerName) & 0xFFFF);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 SuperTuxKart-Team
|
||||
// Copyright (C) 2010-2013 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013
|
||||
// Copyright (C) 2013-2013 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -19,6 +19,7 @@
|
||||
|
||||
#include "config/saved_grand_prix.hpp"
|
||||
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
@ -145,10 +146,12 @@ void SavedGrandPrix::loadKarts(std::vector<RaceManager::KartStatus> & kart_list)
|
||||
int aikarts = 0;
|
||||
for(int i = 0; i < m_karts.size(); i++)
|
||||
{
|
||||
const KartProperties *kp = kart_properties_manager->getKart(m_karts[i].m_ident);
|
||||
|
||||
if(m_karts[i].m_local_player_id == -1)
|
||||
{
|
||||
//AI kart found
|
||||
kart_list[aikarts].m_ident = m_karts[i].m_ident;
|
||||
if(kp) kart_list[aikarts].m_ident = m_karts[i].m_ident;
|
||||
kart_list[aikarts].m_score = m_karts[i].m_score;
|
||||
kart_list[aikarts].m_overall_time = m_karts[i].m_overall_time;
|
||||
aikarts++;
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2010 SuperTuxKart-Team
|
||||
// Copyright (C) 2010-2013 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 Joerg Henrichs
|
||||
// Copyright (C) 2006-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -181,6 +181,13 @@ void STKConfig::init_defaults()
|
||||
m_disable_steer_while_unskid = false;
|
||||
m_camera_follow_skid = false;
|
||||
|
||||
m_nitro_glow_color[0] = 1.0f;
|
||||
m_nitro_glow_color[1] = 1.0f;
|
||||
m_nitro_glow_color[2] = 1.0f;
|
||||
m_box_glow_color[0] = 1.0f;
|
||||
m_box_glow_color[1] = 1.0f;
|
||||
m_box_glow_color[2] = 1.0f;
|
||||
|
||||
m_score_increase.clear();
|
||||
m_leader_intervals.clear();
|
||||
m_switch_items.clear();
|
||||
@ -362,6 +369,25 @@ void STKConfig::getAllData(const XMLNode * root)
|
||||
replay_node->get("delta-pos", &m_replay_delta_pos2 );
|
||||
replay_node->get("delta-t", &m_replay_dt );
|
||||
}
|
||||
|
||||
if(const XMLNode *colors = root->getNode("glow-colors"))
|
||||
{
|
||||
video::SColor tmpcol;
|
||||
if (colors->get("nitro", &tmpcol))
|
||||
{
|
||||
m_nitro_glow_color[0] = tmpcol.getRed() / 255.0f;
|
||||
m_nitro_glow_color[1] = tmpcol.getGreen() / 255.0f;
|
||||
m_nitro_glow_color[2] = tmpcol.getBlue() / 255.0f;
|
||||
}
|
||||
|
||||
if (colors->get("box", &tmpcol))
|
||||
{
|
||||
m_box_glow_color[0] = tmpcol.getRed() / 255.0f;
|
||||
m_box_glow_color[1] = tmpcol.getGreen() / 255.0f;
|
||||
m_box_glow_color[2] = tmpcol.getBlue() / 255.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the default KartProperties
|
||||
// ------------------------------
|
||||
const XMLNode *node = root -> getNode("general-kart-defaults");
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 Joerg Henrichs
|
||||
// Copyright (C) 2006-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -148,6 +148,11 @@ public:
|
||||
* be generated. */
|
||||
float m_replay_delta_angle;
|
||||
|
||||
/** Colors for glows */
|
||||
float m_nitro_glow_color[3];
|
||||
|
||||
float m_box_glow_color[3];
|
||||
|
||||
private:
|
||||
/** True if stk_config has been loaded. This is necessary if the
|
||||
* --stk-config command line parameter has been specified to avoid
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 SuperTuxKart-Team
|
||||
// Copyright (C) 2006-2013 SuperTuxKart-Team
|
||||
// Modelled after Supertux's configfile.cpp
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
@ -46,6 +46,9 @@ static PtrVector<UserConfigParam, REF> all_params;
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
const int UserConfig::m_current_config_version = 8;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
UserConfigParam::~UserConfigParam()
|
||||
{
|
||||
@ -242,7 +245,7 @@ void IntUserConfigParam::findYourDataInAnAttributeOf(const XMLNode* node)
|
||||
} // findYourDataInAnAttributeOf
|
||||
|
||||
// ============================================================================
|
||||
TimeUserConfigParam::TimeUserConfigParam(Time::TimeType default_value,
|
||||
TimeUserConfigParam::TimeUserConfigParam(StkTime::TimeType default_value,
|
||||
const char* param_name,
|
||||
const char* comment)
|
||||
{
|
||||
@ -254,7 +257,7 @@ TimeUserConfigParam::TimeUserConfigParam(Time::TimeType default_value,
|
||||
} // TimeUserConfigParam
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
TimeUserConfigParam::TimeUserConfigParam(Time::TimeType default_value,
|
||||
TimeUserConfigParam::TimeUserConfigParam(StkTime::TimeType default_value,
|
||||
const char* param_name,
|
||||
GroupUserConfigParam* group,
|
||||
const char* comment)
|
||||
@ -649,13 +652,14 @@ bool UserConfig::loadConfig()
|
||||
}
|
||||
|
||||
// ---- Read config file version
|
||||
int configFileVersion = CURRENT_CONFIG_VERSION;
|
||||
if(root->get("version", &configFileVersion) < 1)
|
||||
int config_file_version = m_current_config_version;
|
||||
if(root->get("version", &config_file_version) < 1)
|
||||
{
|
||||
GUIEngine::showMessage( _("Your config file was malformed, so it was deleted and a new one will be created."), 10.0f);
|
||||
std::cerr << "Warning, malformed user config file! Contains no version\n";
|
||||
Log::error("UserConfig",
|
||||
"Warning, malformed user config file! Contains no version");
|
||||
}
|
||||
if (configFileVersion < CURRENT_CONFIG_VERSION)
|
||||
if (config_file_version < m_current_config_version)
|
||||
{
|
||||
// current version (8) is 100% incompatible with other versions (which were lisp)
|
||||
// so we just delete the old config. in the future, for smaller updates, we can
|
||||
@ -713,6 +717,16 @@ bool UserConfig::loadConfig()
|
||||
return true;
|
||||
} // loadConfig
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void UserConfig::postLoadInit()
|
||||
{
|
||||
for (int i = 0; i < UserConfigParams::m_all_players.size(); i++)
|
||||
{
|
||||
PlayerProfile* player = UserConfigParams::m_all_players.get(i);
|
||||
if (player->isGuestAccount()) player->setName(_LTR("Guest"));
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Write settings to config file. */
|
||||
@ -732,7 +746,8 @@ void UserConfig::saveConfig()
|
||||
XMLWriter configfile(filename.c_str());
|
||||
|
||||
configfile << L"<?xml version=\"1.0\"?>\n";
|
||||
configfile << L"<stkconfig version=\"" << CURRENT_CONFIG_VERSION << L"\" >\n\n";
|
||||
configfile << L"<stkconfig version=\"" << m_current_config_version
|
||||
<< L"\" >\n\n";
|
||||
|
||||
const int paramAmount = all_params.size();
|
||||
for(int i=0; i<paramAmount; i++)
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 SuperTuxKart-Team
|
||||
// Copyright (C) 2006-2013 SuperTuxKart-Team
|
||||
// Modelled after Supertux's configfile.h
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
@ -37,8 +37,6 @@
|
||||
cause an undefined game action now
|
||||
6: Added stick configurations.
|
||||
*/
|
||||
const int CURRENT_CONFIG_VERSION = 8;
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
@ -132,14 +130,14 @@ public:
|
||||
// ============================================================================
|
||||
class TimeUserConfigParam : public UserConfigParam
|
||||
{
|
||||
Time::TimeType m_value;
|
||||
Time::TimeType m_default_value;
|
||||
StkTime::TimeType m_value;
|
||||
StkTime::TimeType m_default_value;
|
||||
|
||||
public:
|
||||
|
||||
TimeUserConfigParam(Time::TimeType default_value, const char* param_name,
|
||||
TimeUserConfigParam(StkTime::TimeType default_value, const char* param_name,
|
||||
const char* comment = NULL);
|
||||
TimeUserConfigParam(Time::TimeType default_value, const char* param_name,
|
||||
TimeUserConfigParam(StkTime::TimeType default_value, const char* param_name,
|
||||
GroupUserConfigParam* group, const char* comment=NULL);
|
||||
|
||||
void write(XMLWriter& stream) const;
|
||||
@ -148,10 +146,10 @@ public:
|
||||
|
||||
irr::core::stringw toString() const;
|
||||
void revertToDefaults() { m_value = m_default_value; }
|
||||
operator Time::TimeType() const { return m_value; }
|
||||
Time::TimeType& operator=(const Time::TimeType& v)
|
||||
operator StkTime::TimeType() const { return m_value; }
|
||||
StkTime::TimeType& operator=(const StkTime::TimeType& v)
|
||||
{ m_value = v; return m_value; }
|
||||
Time::TimeType& operator=(const TimeUserConfigParam& v)
|
||||
StkTime::TimeType& operator=(const TimeUserConfigParam& v)
|
||||
{ m_value = (int)v; return m_value; }
|
||||
}; // TimeUserConfigParam
|
||||
|
||||
@ -328,6 +326,9 @@ namespace UserConfigParams
|
||||
PARAM_PREFIX IntUserConfigParam m_num_laps
|
||||
PARAM_DEFAULT( IntUserConfigParam(4, "numlaps",
|
||||
&m_race_setup_group, "Default number of laps.") );
|
||||
PARAM_PREFIX IntUserConfigParam m_num_goals
|
||||
PARAM_DEFAULT( IntUserConfigParam(3, "numgoals",
|
||||
&m_race_setup_group, "Default number of goals in soccer mode.") );
|
||||
PARAM_PREFIX IntUserConfigParam m_difficulty
|
||||
PARAM_DEFAULT( IntUserConfigParam(0, "difficulty",
|
||||
&m_race_setup_group,
|
||||
@ -348,18 +349,18 @@ namespace UserConfigParams
|
||||
PARAM_PREFIX GroupUserConfigParam m_wiimote_group
|
||||
PARAM_DEFAULT( GroupUserConfigParam("WiiMote",
|
||||
"Settings for the wiimote") );
|
||||
PARAM_PREFIX FloatUserConfigParam m_wiimote_max
|
||||
PARAM_DEFAULT( FloatUserConfigParam(90.0f, "wiimote-max",
|
||||
PARAM_PREFIX FloatUserConfigParam m_wiimote_raw_max
|
||||
PARAM_DEFAULT( FloatUserConfigParam(20.0f, "wiimote-raw-max",
|
||||
&m_wiimote_group,
|
||||
"At what angle (0-128) maximum steering is reached.") );
|
||||
"At what raw input value maximum steering is reached (between 1 and 25).") );
|
||||
|
||||
PARAM_PREFIX FloatUserConfigParam m_wiimote_weight_linear
|
||||
PARAM_DEFAULT( FloatUserConfigParam(0.2f, "wiimote-weight-linear",
|
||||
PARAM_DEFAULT( FloatUserConfigParam(1.0f, "wiimote-weight-linear",
|
||||
&m_wiimote_group,
|
||||
"A weight applied to the linear component of mapping wiimote angle to steering angle"));
|
||||
|
||||
PARAM_PREFIX FloatUserConfigParam m_wiimote_weight_square
|
||||
PARAM_DEFAULT( FloatUserConfigParam(0.8f, "wiimote-weight-square",
|
||||
PARAM_DEFAULT( FloatUserConfigParam(0.0f, "wiimote-weight-square",
|
||||
&m_wiimote_group,
|
||||
"A weight applied to the square component of mapping wiimote angle to steering angle"));
|
||||
|
||||
@ -448,8 +449,9 @@ namespace UserConfigParams
|
||||
/** True if check structures should be debugged. */
|
||||
PARAM_PREFIX bool m_check_debug PARAM_DEFAULT( false );
|
||||
|
||||
/** Special debug camera being high over the kart. */
|
||||
PARAM_PREFIX bool m_camera_debug PARAM_DEFAULT( false );
|
||||
/** Special debug camera: 0: normal cameral; 1: being high over the kart.;
|
||||
2: on ground level. */
|
||||
PARAM_PREFIX int m_camera_debug PARAM_DEFAULT( false );
|
||||
|
||||
/** True if physics debugging should be enabled. */
|
||||
PARAM_PREFIX bool m_physics_debug PARAM_DEFAULT( false );
|
||||
@ -481,9 +483,6 @@ namespace UserConfigParams
|
||||
/** True if hardware skinning should be enabled */
|
||||
PARAM_PREFIX bool m_hw_skinning_enabled PARAM_DEFAULT( false );
|
||||
|
||||
/** True if Christmas Mode should be enabled */
|
||||
PARAM_PREFIX bool m_xmas_enabled PARAM_DEFAULT( false );
|
||||
|
||||
// not saved to file
|
||||
|
||||
// ---- Networking
|
||||
@ -513,14 +512,15 @@ namespace UserConfigParams
|
||||
#define FBO_DEFAULT true
|
||||
#endif
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_fbo
|
||||
PARAM_DEFAULT( BoolUserConfigParam(FBO_DEFAULT, "fbo",
|
||||
&m_graphics_quality, "Use frame buffer objects (FBOs)") );
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_graphical_effects
|
||||
PARAM_DEFAULT( BoolUserConfigParam(true, "anim_gfx",
|
||||
&m_graphics_quality, "Scenery animations") );
|
||||
|
||||
// This saves the actual user preference.
|
||||
PARAM_PREFIX IntUserConfigParam m_xmas_mode
|
||||
PARAM_DEFAULT( IntUserConfigParam(0, "christmas-mode",
|
||||
&m_graphics_quality, "Christmas hats: 0 use calendar, 1 always on, 2 always off") );
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_weather_effects
|
||||
PARAM_DEFAULT( BoolUserConfigParam(true, "weather_gfx",
|
||||
&m_graphics_quality, "Weather effects") );
|
||||
@ -538,10 +538,12 @@ namespace UserConfigParams
|
||||
&m_graphics_quality,
|
||||
"Whether trilinear filtering is allowed to be "
|
||||
"used (true or false)") );
|
||||
/*
|
||||
PARAM_PREFIX IntUserConfigParam m_antialiasing
|
||||
PARAM_DEFAULT( IntUserConfigParam(0,
|
||||
"antialiasing", &m_graphics_quality,
|
||||
"Whether antialiasing is enabled (0 = disabled, 1 = 2x, 2 = 4x, 3 = 8x") );
|
||||
*/
|
||||
PARAM_PREFIX BoolUserConfigParam m_vsync
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "vsync",
|
||||
&m_graphics_quality,
|
||||
@ -550,18 +552,27 @@ namespace UserConfigParams
|
||||
PARAM_DEFAULT( BoolUserConfigParam(true, "pixel_shaders",
|
||||
&m_graphics_quality,
|
||||
"Whether to enable pixel shaders (splatting, normal maps, ...)") );
|
||||
PARAM_PREFIX BoolUserConfigParam m_postprocess_enabled
|
||||
PARAM_PREFIX BoolUserConfigParam m_motionblur
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false,
|
||||
"postprocess_enabled", &m_graphics_quality,
|
||||
"Whether post-processing (motion blur...) should "
|
||||
"be enabled") );
|
||||
"motionblur_enabled", &m_graphics_quality,
|
||||
"Whether motion blur should be enabled") );
|
||||
PARAM_PREFIX BoolUserConfigParam m_mlaa
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false,
|
||||
"mlaa", &m_graphics_quality,
|
||||
"Whether MLAA anti-aliasing should be enabled") );
|
||||
PARAM_PREFIX IntUserConfigParam m_ssao
|
||||
PARAM_DEFAULT( IntUserConfigParam(0,
|
||||
"ssao", &m_graphics_quality,
|
||||
"Whether SSAO is enabled (0 = disabled, 1 = low, 2 = high") );
|
||||
PARAM_PREFIX IntUserConfigParam m_shadows
|
||||
PARAM_DEFAULT( IntUserConfigParam(0,
|
||||
"shadows", &m_graphics_quality,
|
||||
"Whether shadows are enabled (0 = disabled, 1 = low, 2 = high") );
|
||||
|
||||
// ---- Misc
|
||||
PARAM_PREFIX BoolUserConfigParam m_cache_overworld
|
||||
PARAM_DEFAULT( BoolUserConfigParam(true, "cache-overworld") );
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_minimal_race_gui
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "minimal-race-gui") );
|
||||
// TODO : is this used with new code? does it still work?
|
||||
PARAM_PREFIX BoolUserConfigParam m_crashed
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "crashed") );
|
||||
@ -735,6 +746,8 @@ private:
|
||||
std::string m_filename;
|
||||
irr::core::stringw m_warning;
|
||||
|
||||
static const int m_current_config_version;
|
||||
|
||||
public:
|
||||
/** Create the user config object; does not actually load it,
|
||||
* UserConfig::loadConfig needs to be called. */
|
||||
@ -747,7 +760,7 @@ public:
|
||||
const irr::core::stringw& getWarning() { return m_warning; }
|
||||
void resetWarning() { m_warning=""; }
|
||||
void setWarning(irr::core::stringw& warning) { m_warning=warning; }
|
||||
|
||||
void postLoadInit();
|
||||
void addDefaultPlayer();
|
||||
|
||||
}; // UserConfig
|
||||
|
775
src/graphics/callbacks.cpp
Normal file
775
src/graphics/callbacks.cpp
Normal file
@ -0,0 +1,775 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
//
|
||||
// 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 "graphics/callbacks.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/helpers.hpp"
|
||||
|
||||
using namespace video;
|
||||
using namespace core;
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void NormalMapProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
s32 decaltex = 0;
|
||||
srv->setPixelShaderConstant("DecalTex", &decaltex, 1);
|
||||
|
||||
s32 bumptex = 1;
|
||||
srv->setPixelShaderConstant("BumpTex", &bumptex, 1);
|
||||
|
||||
s32 lightmapTex = (m_with_lightmap ? 2 : 0);
|
||||
srv->setPixelShaderConstant("LightMapTex", &lightmapTex, 1);
|
||||
|
||||
s32 hasLightMap = (m_with_lightmap ? 1 : 0);
|
||||
srv->setPixelShaderConstant("HasLightMap", &hasLightMap, 1);
|
||||
|
||||
// We could calculate light direction as coming from the sun (then we'd need to
|
||||
// transform it into camera space). But I find that pretending light
|
||||
// comes from the camera gives good results
|
||||
const float lightdir[] = {0.1852f, -0.1852f, -0.9259f};
|
||||
srv->setVertexShaderConstant("lightdir", lightdir, 3);
|
||||
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void WaterShaderProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
|
||||
float strength = time;
|
||||
strength = 1.4f - fabsf(noise2d(strength / 30.0f + 133)) * 0.8f;
|
||||
|
||||
m_dx_1 += GUIEngine::getLatestDt() * m_water_shader_speed_1 * strength;
|
||||
m_dy_1 += GUIEngine::getLatestDt() * m_water_shader_speed_1 * strength;
|
||||
|
||||
m_dx_2 += GUIEngine::getLatestDt() * m_water_shader_speed_2 * strength;
|
||||
m_dy_2 -= GUIEngine::getLatestDt() * m_water_shader_speed_2 * strength;
|
||||
|
||||
if (m_dx_1 > 1.0f) m_dx_1 -= 1.0f;
|
||||
if (m_dy_1 > 1.0f) m_dy_1 -= 1.0f;
|
||||
if (m_dx_2 > 1.0f) m_dx_2 -= 1.0f;
|
||||
if (m_dy_2 < 0.0f) m_dy_2 += 1.0f;
|
||||
|
||||
const float d1[2] = { m_dx_1, m_dy_1 };
|
||||
const float d2[2] = { m_dx_2, m_dy_2 };
|
||||
|
||||
srv->setVertexShaderConstant("delta1", d1, 2);
|
||||
srv->setVertexShaderConstant("delta2", d2, 2);
|
||||
|
||||
const float speed = irr_driver->getDevice()->getTimer()->getTime() / m_speed;
|
||||
const float height = m_height * strength;
|
||||
|
||||
srv->setVertexShaderConstant("height", &height, 1);
|
||||
srv->setVertexShaderConstant("speed", &speed, 1);
|
||||
srv->setVertexShaderConstant("waveLength", &m_length, 1);
|
||||
|
||||
// Can't use the firstdone optimization, as the callback is shared
|
||||
//if (!firstdone)
|
||||
{
|
||||
s32 decaltex = 0;
|
||||
srv->setPixelShaderConstant("DecalTex", &decaltex, 1);
|
||||
|
||||
s32 bumptex = 1;
|
||||
srv->setPixelShaderConstant("BumpTex1", &bumptex, 1);
|
||||
|
||||
bumptex = 2;
|
||||
srv->setPixelShaderConstant("BumpTex2", &bumptex, 1);
|
||||
|
||||
// Calculate light direction as coming from the sun.
|
||||
matrix4 normalm = srv->getVideoDriver()->getTransform(ETS_VIEW);
|
||||
normalm.makeInverse();
|
||||
normalm = normalm.getTransposed();
|
||||
vector3df tmp = m_sunpos;
|
||||
normalm.transformVect(tmp);
|
||||
tmp.normalize();
|
||||
|
||||
const float lightdir[] = {tmp.X, tmp.Y, tmp.Z};
|
||||
srv->setVertexShaderConstant("lightdir", lightdir, 3);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void GrassShaderProvider::OnSetConstants(IMaterialRendererServices *srv, int userData)
|
||||
{
|
||||
IVideoDriver * const drv = srv->getVideoDriver();
|
||||
const core::vector3df pos = drv->getTransform(ETS_WORLD).getTranslation();
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
|
||||
float strength = (pos.X + pos.Y + pos.Z) * 1.2f + time * m_speed;
|
||||
strength = noise2d(strength / 10.0f) * m_amplitude * 5;
|
||||
// * 5 is to work with the existing amplitude values.
|
||||
|
||||
// Pre-multiply on the cpu
|
||||
vector3df wind = irr_driver->getWind() * strength;
|
||||
|
||||
srv->setVertexShaderConstant("windDir", &wind.X, 3);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
s32 tex = 0;
|
||||
srv->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void SplattingProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float camfar = irr_driver->getSceneManager()->getActiveCamera()->getFarValue();
|
||||
srv->setVertexShaderConstant("far", &camfar, 1);
|
||||
|
||||
// The normal is transformed by the inverse transposed world matrix
|
||||
// because we want world-space normals
|
||||
matrix4 invtworldm = irr_driver->getVideoDriver()->getTransform(ETS_WORLD);
|
||||
invtworldm.makeInverse();
|
||||
invtworldm = invtworldm.getTransposed();
|
||||
|
||||
srv->setVertexShaderConstant("invtworldm", invtworldm.pointer(), 16);
|
||||
|
||||
float objectid = 0;
|
||||
const stringc name = mat.TextureLayer[0].Texture->getName().getPath();
|
||||
objectid = shash8((const u8 *) name.c_str(), name.size()) / 255.0f;
|
||||
srv->setVertexShaderConstant("objectid", &objectid, 1);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
s32 tex_layout = 1;
|
||||
srv->setPixelShaderConstant("tex_layout", &tex_layout, 1);
|
||||
|
||||
s32 tex_detail0 = 2;
|
||||
srv->setPixelShaderConstant("tex_detail0", &tex_detail0, 1);
|
||||
|
||||
s32 tex_detail1 = 3;
|
||||
srv->setPixelShaderConstant("tex_detail1", &tex_detail1, 1);
|
||||
|
||||
s32 tex_detail2 = 4;
|
||||
srv->setPixelShaderConstant("tex_detail2", &tex_detail2, 1);
|
||||
|
||||
s32 tex_detail3 = 5;
|
||||
srv->setPixelShaderConstant("tex_detail3", &tex_detail3, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void BubbleEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float start = fabsf(mat.MaterialTypeParam2);
|
||||
const bool visible = mat.MaterialTypeParam2 > 0;
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
float transparency;
|
||||
|
||||
const float diff = (time - start) / 3.0f;
|
||||
|
||||
if (visible)
|
||||
{
|
||||
transparency = diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
transparency = 1.0 - diff;
|
||||
}
|
||||
|
||||
transparency = clampf(transparency, 0, 1);
|
||||
|
||||
srv->setVertexShaderConstant("time", &time, 1);
|
||||
srv->setVertexShaderConstant("transparency", &transparency, 1);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void RainEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float screenw = UserConfigParams::m_width;
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f;
|
||||
const matrix4 viewm = srv->getVideoDriver()->getTransform(ETS_VIEW);
|
||||
const vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition();
|
||||
|
||||
srv->setVertexShaderConstant("screenw", &screenw, 1);
|
||||
srv->setVertexShaderConstant("time", &time, 1);
|
||||
srv->setVertexShaderConstant("viewm", viewm.pointer(), 16);
|
||||
srv->setVertexShaderConstant("campos", &campos.X, 3);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void SnowEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
|
||||
srv->setVertexShaderConstant("time", &time, 1);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MotionBlurProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
// We need the maximum texture coordinates:
|
||||
float max_tex_height = m_maxheight[m_current_camera];
|
||||
srv->setPixelShaderConstant("max_tex_height", &max_tex_height, 1);
|
||||
|
||||
// Scale the boost time to get a usable boost amount:
|
||||
float boost_amount = m_boost_time[m_current_camera] * 0.7f;
|
||||
|
||||
// Especially for single screen the top of the screen is less blurred
|
||||
// in the fragment shader by multiplying the blurr factor by
|
||||
// (max_tex_height - texcoords.t), where max_tex_height is the maximum
|
||||
// texture coordinate (1.0 or 0.5). In split screen this factor is too
|
||||
// small (half the value compared with non-split screen), so we
|
||||
// multiply this by 2.
|
||||
if(Camera::getNumCameras() > 1)
|
||||
boost_amount *= 2.0f;
|
||||
|
||||
srv->setPixelShaderConstant("boost_amount", &boost_amount, 1);
|
||||
srv->setPixelShaderConstant("center",
|
||||
&(m_center[m_current_camera].X), 2);
|
||||
srv->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;
|
||||
srv->setPixelShaderConstant("mask_radius", &radius, 1);
|
||||
|
||||
const int texunit = 0;
|
||||
srv->setPixelShaderConstant("color_buffer", &texunit, 1);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void GaussianBlurProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("pixel", m_pixel, 2);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MipVizProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const ITexture * const tex = mat.TextureLayer[0].Texture;
|
||||
|
||||
const int notex = (mat.TextureLayer[0].Texture == NULL);
|
||||
srv->setVertexShaderConstant("notex", ¬ex, 1);
|
||||
if (!tex) return;
|
||||
|
||||
const dimension2du size = tex->getSize();
|
||||
|
||||
const float texsize[2] = {
|
||||
size.Width,
|
||||
size.Height
|
||||
};
|
||||
|
||||
srv->setVertexShaderConstant("texsize", texsize, 2);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void ColorizeProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("col", m_color, 3);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void GlowProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("res", m_res, 2);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void ObjectPassProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float camfar = irr_driver->getSceneManager()->getActiveCamera()->getFarValue();
|
||||
srv->setVertexShaderConstant("far", &camfar, 1);
|
||||
|
||||
// The normal is transformed by the inverse transposed world matrix
|
||||
// because we want world-space normals
|
||||
matrix4 invtworldm = irr_driver->getVideoDriver()->getTransform(ETS_WORLD);
|
||||
invtworldm.makeInverse();
|
||||
invtworldm = invtworldm.getTransposed();
|
||||
|
||||
srv->setVertexShaderConstant("invtworldm", invtworldm.pointer(), 16);
|
||||
|
||||
const int hastex = mat.TextureLayer[0].Texture != NULL;
|
||||
srv->setVertexShaderConstant("hastex", &hastex, 1);
|
||||
|
||||
const int haslightmap = mat.TextureLayer[1].Texture != NULL;
|
||||
srv->setVertexShaderConstant("haslightmap", &haslightmap, 1);
|
||||
|
||||
float objectid = 0;
|
||||
if (hastex)
|
||||
{
|
||||
const stringc name = mat.TextureLayer[0].Texture->getName().getPath();
|
||||
objectid = shash8((const u8 *) name.c_str(), name.size()) / 255.0f;
|
||||
}
|
||||
srv->setVertexShaderConstant("objectid", &objectid, 1);
|
||||
|
||||
//if (!firstdone)
|
||||
// Can't use the firstdone optimization, as this callback is used for multiple shaders
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("lighttex", &tex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void LightBlendProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const SColorf s = irr_driver->getSceneManager()->getAmbientLight();
|
||||
|
||||
float ambient[3] = { s.r, s.g, s.b };
|
||||
srv->setVertexShaderConstant("ambient", ambient, 3);
|
||||
|
||||
int spectex = 1;
|
||||
srv->setVertexShaderConstant("spectex", &spectex, 1);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void PointLightProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("screen", m_screen, 2);
|
||||
srv->setVertexShaderConstant("spec", &m_specular, 1);
|
||||
srv->setVertexShaderConstant("col", m_color, 3);
|
||||
srv->setVertexShaderConstant("campos", m_campos, 3);
|
||||
srv->setVertexShaderConstant("center", m_pos, 3);
|
||||
srv->setVertexShaderConstant("r", &m_radius, 1);
|
||||
srv->setVertexShaderConstant("invprojview", m_invprojview.pointer(), 16);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("ntex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("dtex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void SunLightProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const int hasclouds = World::getWorld()->getTrack()->hasClouds() &&
|
||||
UserConfigParams::m_weather_effects;
|
||||
|
||||
srv->setVertexShaderConstant("screen", m_screen, 2);
|
||||
srv->setVertexShaderConstant("col", m_color, 3);
|
||||
srv->setVertexShaderConstant("center", m_pos, 3);
|
||||
srv->setVertexShaderConstant("invprojview", m_invprojview.pointer(), 16);
|
||||
srv->setVertexShaderConstant("hasclouds", &hasclouds, 1);
|
||||
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
|
||||
float strength = time;
|
||||
strength = fabsf(noise2d(strength / 10.0f)) * 0.003f;
|
||||
|
||||
const vector3df winddir = irr_driver->getWind() * strength;
|
||||
m_wind[0] += winddir.X;
|
||||
m_wind[1] += winddir.Z;
|
||||
srv->setVertexShaderConstant("wind", m_wind, 2);
|
||||
|
||||
if (UserConfigParams::m_shadows)
|
||||
{
|
||||
srv->setVertexShaderConstant("shadowmat", m_shadowmat.pointer(), 16);
|
||||
}
|
||||
|
||||
// Can't use the firstdone optimization, as this callback is used for multiple shaders
|
||||
//if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("ntex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("dtex", &tex, 1);
|
||||
|
||||
tex = 2;
|
||||
srv->setVertexShaderConstant("cloudtex", &tex, 1);
|
||||
|
||||
tex = 3;
|
||||
srv->setVertexShaderConstant("shadowtex", &tex, 1);
|
||||
|
||||
tex = 4;
|
||||
srv->setVertexShaderConstant("warpx", &tex, 1);
|
||||
|
||||
tex = 5;
|
||||
srv->setVertexShaderConstant("warpy", &tex, 1);
|
||||
|
||||
const float shadowoffset = 1.0f / irr_driver->getRTT(RTT_SHADOW)->getSize().Width;
|
||||
srv->setVertexShaderConstant("shadowoffset", &shadowoffset, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void BloomProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("low", &m_threshold, 1);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MLAAColor1Provider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
const float pixels[2] = {
|
||||
1.0f / UserConfigParams::m_width,
|
||||
1.0f / UserConfigParams::m_height
|
||||
};
|
||||
|
||||
srv->setPixelShaderConstant("PIXEL_SIZE", pixels, 2);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MLAABlend2Provider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
const float pixels[2] = {
|
||||
1.0f / UserConfigParams::m_width,
|
||||
1.0f / UserConfigParams::m_height
|
||||
};
|
||||
|
||||
srv->setPixelShaderConstant("PIXEL_SIZE", pixels, 2);
|
||||
|
||||
|
||||
int tex = 0;
|
||||
srv->setPixelShaderConstant("edgesMap", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setPixelShaderConstant("areaMap", &tex, 1);
|
||||
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MLAANeigh3Provider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
const float pixels[2] = {
|
||||
1.0f / UserConfigParams::m_width,
|
||||
1.0f / UserConfigParams::m_height
|
||||
};
|
||||
|
||||
srv->setPixelShaderConstant("PIXEL_SIZE", pixels, 2);
|
||||
|
||||
|
||||
int tex = 0;
|
||||
srv->setPixelShaderConstant("blendMap", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setPixelShaderConstant("colorMap", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void SSAOProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setPixelShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setPixelShaderConstant("oldtex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void GodRayProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setPixelShaderConstant("sunpos", m_sunpos, 2);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void ShadowPassProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const int hastex = mat.TextureLayer[0].Texture != NULL;
|
||||
srv->setVertexShaderConstant("hastex", &hastex, 1);
|
||||
|
||||
int viz = irr_driver->getShadowViz();
|
||||
srv->setVertexShaderConstant("viz", &viz, 1);
|
||||
|
||||
int wireframe = mat.Wireframe;
|
||||
srv->setVertexShaderConstant("wireframe", &wireframe, 1);
|
||||
|
||||
float objectid = 0;
|
||||
if (hastex)
|
||||
{
|
||||
const stringc name = mat.TextureLayer[0].Texture->getName().getPath();
|
||||
objectid = shash8((const u8 *) name.c_str(), name.size()) / 255.0f;
|
||||
}
|
||||
srv->setVertexShaderConstant("objectid", &objectid, 1);
|
||||
|
||||
//if (!firstdone)
|
||||
// Can't use the firstdone optimization, as this callback is used for multiple shaders
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("warpx", &tex, 1);
|
||||
tex = 2;
|
||||
srv->setVertexShaderConstant("warpy", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void ShadowImportanceProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("shadowmat", m_shadowmat.pointer(), 16);
|
||||
srv->setVertexShaderConstant("ipvmat", m_invprojview.pointer(), 16);
|
||||
|
||||
srv->setVertexShaderConstant("campos", m_campos, 3);
|
||||
|
||||
int low = UserConfigParams::m_shadows == 1;
|
||||
srv->setVertexShaderConstant("low", &low, 1);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("ntex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("dtex", &tex, 1);
|
||||
|
||||
tex = 2;
|
||||
srv->setVertexShaderConstant("ctex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CollapseProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("pixel", m_pixel, 2);
|
||||
srv->setVertexShaderConstant("multi", m_multi, 2);
|
||||
srv->setVertexShaderConstant("size", &m_size, 1);
|
||||
|
||||
//if (!firstdone)
|
||||
// Can't use the firstdone optimization, as this callback is used for multiple shaders
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("oldtex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void BloomPowerProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
srv->setVertexShaderConstant("power", &m_power, 1);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void MultiplyProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex1", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("tex2", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void ShadowGenProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("halft", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("quarter", &tex, 1);
|
||||
|
||||
tex = 2;
|
||||
srv->setVertexShaderConstant("eighth", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void CausticsProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
const float speed = World::getWorld()->getTrack()->getCausticsSpeed();
|
||||
|
||||
float strength = time;
|
||||
strength = fabsf(noise2d(strength / 10.0f)) * 0.006f + 0.001f;
|
||||
|
||||
vector3df wind = irr_driver->getWind() * strength * speed;
|
||||
m_dir[0] += wind.X;
|
||||
m_dir[1] += wind.Z;
|
||||
|
||||
strength = time * 0.56f + sinf(time);
|
||||
strength = fabsf(noise2d(0.0, strength / 6.0f)) * 0.0095f + 0.001f;
|
||||
|
||||
wind = irr_driver->getWind() * strength * speed;
|
||||
wind.rotateXZBy(cosf(time));
|
||||
m_dir2[0] += wind.X;
|
||||
m_dir2[1] += wind.Z;
|
||||
|
||||
srv->setVertexShaderConstant("dir", m_dir, 2);
|
||||
srv->setVertexShaderConstant("dir2", m_dir2, 2);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setVertexShaderConstant("caustictex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void DisplaceProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
const float speed = World::getWorld()->getTrack()->getDisplacementSpeed();
|
||||
|
||||
float strength = time;
|
||||
strength = fabsf(noise2d(strength / 10.0f)) * 0.006f + 0.002f;
|
||||
|
||||
vector3df wind = irr_driver->getWind() * strength * speed;
|
||||
m_dir[0] += wind.X;
|
||||
m_dir[1] += wind.Z;
|
||||
|
||||
strength = time * 0.56f + sinf(time);
|
||||
strength = fabsf(noise2d(0.0, strength / 6.0f)) * 0.0095f + 0.0025f;
|
||||
|
||||
wind = irr_driver->getWind() * strength * speed;
|
||||
wind.rotateXZBy(cosf(time));
|
||||
m_dir2[0] += wind.X;
|
||||
m_dir2[1] += wind.Z;
|
||||
|
||||
srv->setVertexShaderConstant("dir", m_dir, 2);
|
||||
srv->setVertexShaderConstant("dir2", m_dir2, 2);
|
||||
|
||||
srv->setVertexShaderConstant("screen", m_screen, 2);
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void PPDisplaceProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
int viz = irr_driver->getDistortViz();
|
||||
srv->setPixelShaderConstant("viz", &viz, 1);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setPixelShaderConstant("tex", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setPixelShaderConstant("dtex", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
void FogProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
const Track * const track = World::getWorld()->getTrack();
|
||||
|
||||
// This function is only called once per frame - thus no need for setters.
|
||||
const float fogmax = track->getFogMax();
|
||||
const float startH = track->getFogStartHeight();
|
||||
const float endH = track->getFogEndHeight();
|
||||
const float start = track->getFogStart();
|
||||
const float end = track->getFogEnd();
|
||||
const SColor tmpcol = track->getFogColor();
|
||||
|
||||
const float col[3] = { tmpcol.getRed() / 255.0f,
|
||||
tmpcol.getGreen() / 255.0f,
|
||||
tmpcol.getBlue() / 255.0f };
|
||||
|
||||
srv->setPixelShaderConstant("fogmax", &fogmax, 1);
|
||||
srv->setPixelShaderConstant("startH", &startH, 1);
|
||||
srv->setPixelShaderConstant("endH", &endH, 1);
|
||||
srv->setPixelShaderConstant("start", &start, 1);
|
||||
srv->setPixelShaderConstant("end", &end, 1);
|
||||
srv->setPixelShaderConstant("col", col, 3);
|
||||
srv->setVertexShaderConstant("ipvmat", m_invprojview.pointer(), 16);
|
||||
srv->setVertexShaderConstant("campos", m_campos, 3);
|
||||
}
|
712
src/graphics/callbacks.hpp
Normal file
712
src/graphics/callbacks.hpp
Normal file
@ -0,0 +1,712 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
//
|
||||
// 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_CALLBACKS_HPP
|
||||
#define HEADER_CALLBACKS_HPP
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
|
||||
#include <IShaderConstantSetCallBack.h>
|
||||
#include <SMaterial.h>
|
||||
#include <ISceneManager.h>
|
||||
#include <ICameraSceneNode.h>
|
||||
#include <IMaterialRendererServices.h>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace irr;
|
||||
|
||||
class CallBase: public video::IShaderConstantSetCallBack
|
||||
{
|
||||
public:
|
||||
CallBase()
|
||||
{
|
||||
firstdone = 0;
|
||||
}
|
||||
|
||||
virtual void OnSetMaterial(const video::SMaterial &material)
|
||||
{
|
||||
mat = material;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool firstdone;
|
||||
video::SMaterial mat;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class NormalMapProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
NormalMapProvider(bool withLightmap)
|
||||
{
|
||||
m_with_lightmap = withLightmap;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_with_lightmap;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class WaterShaderProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setSpeed(const float s1, const float s2)
|
||||
{
|
||||
m_water_shader_speed_1 = s1;
|
||||
m_water_shader_speed_2 = s2;
|
||||
}
|
||||
|
||||
WaterShaderProvider()
|
||||
{
|
||||
m_dx_1 = 0.0f;
|
||||
m_dx_2 = 0.0f;
|
||||
m_dy_1 = 0.0f;
|
||||
m_dy_2 = 0.0f;
|
||||
|
||||
m_water_shader_speed_1 =
|
||||
m_water_shader_speed_2 = 0.0f;
|
||||
}
|
||||
|
||||
void setSunPosition(const core::vector3df &in)
|
||||
{
|
||||
m_sunpos = in;
|
||||
m_sunpos.normalize();
|
||||
}
|
||||
|
||||
void setSpeed(float speed) { m_speed = speed; }
|
||||
void setHeight(float height) { m_height = height; }
|
||||
void setLength(float length) { m_length = length; }
|
||||
|
||||
private:
|
||||
core::vector3df m_sunpos;
|
||||
|
||||
float m_dx_1, m_dy_1, m_dx_2, m_dy_2;
|
||||
float m_water_shader_speed_1;
|
||||
float m_water_shader_speed_2;
|
||||
|
||||
float m_speed;
|
||||
float m_height;
|
||||
float m_length;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class GrassShaderProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
GrassShaderProvider()
|
||||
{
|
||||
m_amplitude =
|
||||
m_speed = 0.0f;
|
||||
}
|
||||
|
||||
void setSpeed(float speed)
|
||||
{
|
||||
m_speed = speed;
|
||||
}
|
||||
|
||||
void setAmplitude(float amp)
|
||||
{
|
||||
m_amplitude = amp;
|
||||
}
|
||||
|
||||
private:
|
||||
float m_amplitude, m_speed;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class SplattingProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class BubbleEffectProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
BubbleEffectProvider()
|
||||
{
|
||||
}
|
||||
|
||||
// We hijack the material type param 2 of bubbles.
|
||||
// It's time to start the fade, negative if fade out, positive if in.
|
||||
// It'd be unused otherwise.
|
||||
|
||||
void onMadeVisible(scene::IMeshBuffer * const mb)
|
||||
{
|
||||
if (!contains(mb))
|
||||
return;
|
||||
|
||||
video::SMaterial &mat = mb->getMaterial();
|
||||
mat.MaterialTypeParam2 = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
|
||||
}
|
||||
|
||||
void onHidden(scene::IMeshBuffer * const mb)
|
||||
{
|
||||
if (!contains(mb))
|
||||
return;
|
||||
|
||||
video::SMaterial &mat = mb->getMaterial();
|
||||
mat.MaterialTypeParam2 = irr_driver->getDevice()->getTimer()->getTime() / -1000.0f;
|
||||
}
|
||||
|
||||
void isInitiallyHidden(scene::IMeshBuffer * const mb)
|
||||
{
|
||||
if (!contains(mb))
|
||||
return;
|
||||
|
||||
video::SMaterial &mat = mb->getMaterial();
|
||||
mat.MaterialTypeParam2 = irr_driver->getDevice()->getTimer()->getTime() / -1000.0f;
|
||||
}
|
||||
|
||||
void removeBubble(const scene::IMeshBuffer * const mb)
|
||||
{
|
||||
m_bubbles.erase(mb);
|
||||
}
|
||||
|
||||
void addBubble(scene::IMeshBuffer * const mb)
|
||||
{
|
||||
m_bubbles.insert(mb);
|
||||
|
||||
video::SMaterial &mat = mb->getMaterial();
|
||||
mat.MaterialTypeParam2 = 1;
|
||||
}
|
||||
|
||||
bool contains(const scene::IMeshBuffer * const mb) const
|
||||
{
|
||||
return m_bubbles.count(mb);
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<const scene::IMeshBuffer *> m_bubbles;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class RainEffectProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class SnowEffectProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MotionBlurProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setMaxHeight(u32 who, float height)
|
||||
{
|
||||
assert(who < MAX_PLAYER_COUNT);
|
||||
m_maxheight[who] = height;
|
||||
}
|
||||
|
||||
void setBoostTime(u32 who, float time)
|
||||
{
|
||||
assert(who < MAX_PLAYER_COUNT);
|
||||
m_boost_time[who] = time;
|
||||
}
|
||||
|
||||
void setCenter(u32 who, float X, float Y)
|
||||
{
|
||||
assert(who < MAX_PLAYER_COUNT);
|
||||
m_center[who].X = X;
|
||||
m_center[who].Y = Y;
|
||||
}
|
||||
|
||||
void setDirection(u32 who, float X, float Y)
|
||||
{
|
||||
assert(who < MAX_PLAYER_COUNT);
|
||||
m_direction[who].X = X;
|
||||
m_direction[who].Y = Y;
|
||||
}
|
||||
|
||||
void setCurrentCamera(u32 who)
|
||||
{
|
||||
m_current_camera = who;
|
||||
}
|
||||
|
||||
private:
|
||||
float m_maxheight[MAX_PLAYER_COUNT];
|
||||
u32 m_current_camera;
|
||||
float m_boost_time[MAX_PLAYER_COUNT];
|
||||
core::vector2df m_center[MAX_PLAYER_COUNT];
|
||||
core::vector2df m_direction[MAX_PLAYER_COUNT];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class GaussianBlurProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
GaussianBlurProvider()
|
||||
{
|
||||
m_pixel[0] = 1.0f / UserConfigParams::m_width;
|
||||
m_pixel[1] = 1.0f / UserConfigParams::m_height;
|
||||
}
|
||||
|
||||
void setResolution(float x, float y)
|
||||
{
|
||||
m_pixel[0] = 1.0f / x;
|
||||
m_pixel[1] = 1.0f / y;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
private:
|
||||
float m_pixel[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MipVizProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ColorizeProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setColor(float r, float g, float b)
|
||||
{
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
}
|
||||
|
||||
private:
|
||||
float m_color[3];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class GlowProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setResolution(float x, float y)
|
||||
{
|
||||
m_res[0] = x;
|
||||
m_res[1] = y;
|
||||
}
|
||||
|
||||
private:
|
||||
float m_res[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ObjectPassProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class LightBlendProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class PointLightProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
PointLightProvider()
|
||||
{
|
||||
m_screen[0] = UserConfigParams::m_width;
|
||||
m_screen[1] = UserConfigParams::m_height;
|
||||
|
||||
m_specular = 200;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setColor(float r, float g, float b)
|
||||
{
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
}
|
||||
|
||||
void setPosition(float x, float y, float z)
|
||||
{
|
||||
m_pos[0] = x;
|
||||
m_pos[1] = y;
|
||||
m_pos[2] = z;
|
||||
}
|
||||
|
||||
void setRadius(float r)
|
||||
{
|
||||
m_radius = r;
|
||||
}
|
||||
|
||||
void setSpecular(float s)
|
||||
{
|
||||
m_specular = s;
|
||||
}
|
||||
|
||||
void updateIPVMatrix()
|
||||
{
|
||||
// Update the campos and IPV matrix, only once per frame since it's costly
|
||||
const core::vector3df &campos =
|
||||
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
|
||||
m_campos[0] = campos.X;
|
||||
m_campos[1] = campos.Y;
|
||||
m_campos[2] = campos.Z;
|
||||
|
||||
const video::IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
m_invprojview = drv->getTransform(video::ETS_PROJECTION);
|
||||
m_invprojview *= drv->getTransform(video::ETS_VIEW);
|
||||
m_invprojview.makeInverse();
|
||||
}
|
||||
|
||||
private:
|
||||
core::matrix4 m_invprojview;
|
||||
|
||||
float m_campos[3];
|
||||
float m_color[3];
|
||||
float m_pos[3];
|
||||
float m_screen[2];
|
||||
float m_radius;
|
||||
float m_specular;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class SunLightProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
SunLightProvider()
|
||||
{
|
||||
m_screen[0] = UserConfigParams::m_width;
|
||||
m_screen[1] = UserConfigParams::m_height;
|
||||
|
||||
m_wind[0] = m_wind[1] = 0;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setColor(float r, float g, float b)
|
||||
{
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
}
|
||||
|
||||
void setPosition(float x, float y, float z)
|
||||
{
|
||||
m_pos[0] = x;
|
||||
m_pos[1] = y;
|
||||
m_pos[2] = z;
|
||||
}
|
||||
|
||||
void updateIPVMatrix()
|
||||
{
|
||||
// Update the IPV matrix, only once per frame since it's costly
|
||||
const video::IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
m_invprojview = drv->getTransform(video::ETS_PROJECTION);
|
||||
m_invprojview *= drv->getTransform(video::ETS_VIEW);
|
||||
m_invprojview.makeInverse();
|
||||
}
|
||||
|
||||
void setShadowMatrix(const core::matrix4 &mat)
|
||||
{
|
||||
m_shadowmat = mat;
|
||||
}
|
||||
|
||||
private:
|
||||
core::matrix4 m_invprojview, m_shadowmat;
|
||||
float m_color[3];
|
||||
float m_pos[3];
|
||||
float m_screen[2];
|
||||
float m_wind[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class BloomProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
BloomProvider() { m_threshold = 0.75f; }
|
||||
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setThreshold(const float f) { m_threshold = f; }
|
||||
|
||||
private:
|
||||
float m_threshold;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MLAAColor1Provider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MLAABlend2Provider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MLAANeigh3Provider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class SSAOProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class GodRayProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
// In texcoords
|
||||
void setSunPosition(float x, float y) { m_sunpos[0] = x; m_sunpos[1] = y; }
|
||||
|
||||
private:
|
||||
float m_sunpos[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ShadowPassProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ShadowImportanceProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void updateIPVMatrix()
|
||||
{
|
||||
// Update the IPV matrix, only once per frame since it's costly
|
||||
const video::IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
const core::vector3df &campos =
|
||||
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
|
||||
m_campos[0] = campos.X;
|
||||
m_campos[1] = campos.Y;
|
||||
m_campos[2] = campos.Z;
|
||||
|
||||
m_invprojview = drv->getTransform(video::ETS_PROJECTION);
|
||||
m_invprojview *= drv->getTransform(video::ETS_VIEW);
|
||||
m_invprojview.makeInverse();
|
||||
}
|
||||
|
||||
void setShadowMatrix(const core::matrix4 &mat)
|
||||
{
|
||||
m_shadowmat = mat;
|
||||
}
|
||||
|
||||
private:
|
||||
core::matrix4 m_invprojview, m_shadowmat;
|
||||
float m_campos[3];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class CollapseProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setResolution(const float x, const float y)
|
||||
{
|
||||
m_pixel[0] = 1.0f / x;
|
||||
m_pixel[1] = 1.0f / y;
|
||||
|
||||
m_multi[0] = m_multi[1] = 1;
|
||||
|
||||
if (x < 2 || y < 2)
|
||||
{
|
||||
u32 i;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
// No increase for the other direction
|
||||
if (m_pixel[i] > 0.9f) m_pixel[i] = m_multi[i] = 0;
|
||||
}
|
||||
|
||||
std::swap(m_multi[0], m_multi[1]);
|
||||
}
|
||||
|
||||
m_size = std::max(x, y);
|
||||
}
|
||||
|
||||
private:
|
||||
float m_pixel[2];
|
||||
int m_size;
|
||||
float m_multi[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class BloomPowerProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void setPower(float power)
|
||||
{
|
||||
m_power = power / 10.0f;
|
||||
}
|
||||
|
||||
private:
|
||||
float m_power;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class MultiplyProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class ShadowGenProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class CausticsProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
CausticsProvider() { m_dir[0] = m_dir[1] = m_dir2[0] = m_dir2[1] = 0; }
|
||||
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
private:
|
||||
float m_dir[2], m_dir2[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class DisplaceProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
DisplaceProvider()
|
||||
{
|
||||
m_screen[0] = UserConfigParams::m_width;
|
||||
m_screen[1] = UserConfigParams::m_height;
|
||||
|
||||
m_dir[0] = m_dir[1] = m_dir2[0] = m_dir2[1] = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
float m_screen[2];
|
||||
float m_dir[2], m_dir2[2];
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class PPDisplaceProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
class FogProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
void updateIPVMatrix()
|
||||
{
|
||||
// Update the campos and IPV matrix, only once per frame since it's costly
|
||||
const core::vector3df &campos =
|
||||
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
|
||||
m_campos[0] = campos.X;
|
||||
m_campos[1] = campos.Y;
|
||||
m_campos[2] = campos.Z;
|
||||
|
||||
const video::IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
m_invprojview = drv->getTransform(video::ETS_PROJECTION);
|
||||
m_invprojview *= drv->getTransform(video::ETS_VIEW);
|
||||
m_invprojview.makeInverse();
|
||||
}
|
||||
|
||||
private:
|
||||
core::matrix4 m_invprojview;
|
||||
float m_campos[3];
|
||||
};
|
||||
|
||||
#endif
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2004-2005 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2006 SuperTuxKart-Team, Steve Baker
|
||||
// Copyright (C) 2004-2013 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2006-2013 SuperTuxKart-Team, Steve Baker
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -19,11 +19,7 @@
|
||||
|
||||
#include "graphics/camera.hpp"
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
||||
# define isnan _isnan
|
||||
#else
|
||||
# include <math.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "audio/music_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
@ -35,10 +31,12 @@
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/skidding.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "physics/btKart.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/aligned_array.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#include "ICameraSceneNode.h"
|
||||
#include "ISceneManager.h"
|
||||
@ -386,14 +384,22 @@ void Camera::getCameraSettings(float *above_kart, float *cam_angle,
|
||||
}
|
||||
// Fall through to falling mode.
|
||||
case CM_FALLING:
|
||||
{
|
||||
if(UserConfigParams::m_camera_debug==2)
|
||||
{
|
||||
*above_kart = 0;
|
||||
*cam_angle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*above_kart = 0.75f;
|
||||
*cam_angle = kp->getCameraForwardUpAngle();
|
||||
}
|
||||
float steering = m_kart->getSteerPercent()
|
||||
* (1.0f + (m_kart->getSkidding()->getSkidFactor()
|
||||
- 1.0f)/2.3f );
|
||||
// quadratically to dampen small variations (but keep sign)
|
||||
float dampened_steer = fabsf(steering) * steering;
|
||||
*cam_angle = kp->getCameraForwardUpAngle();
|
||||
*sideway = -m_rotation_range*dampened_steer*0.5f;
|
||||
*distance = -m_distance;
|
||||
*smoothing = true;
|
||||
@ -442,19 +448,12 @@ void Camera::getCameraSettings(float *above_kart, float *cam_angle,
|
||||
*/
|
||||
void Camera::update(float dt)
|
||||
{
|
||||
if (UserConfigParams::m_graphical_effects)
|
||||
{
|
||||
if (m_rain)
|
||||
{
|
||||
m_rain->setPosition( getCameraSceneNode()->getPosition() );
|
||||
m_rain->update(dt);
|
||||
}
|
||||
} // UserConfigParams::m_graphical_effects
|
||||
|
||||
float above_kart, cam_angle, side_way, distance;
|
||||
bool smoothing;
|
||||
|
||||
// The following settings give a debug camera which shows the track from
|
||||
// high above the kart straight down.
|
||||
if(UserConfigParams::m_camera_debug)
|
||||
if (UserConfigParams::m_camera_debug==1)
|
||||
{
|
||||
core::vector3df xyz = m_kart->getXYZ().toIrrVector();
|
||||
m_camera->setTarget(xyz);
|
||||
@ -464,24 +463,18 @@ void Camera::update(float dt)
|
||||
// To view inside tunnels (FIXME 27>15 why??? makes no sense
|
||||
// - the kart should not be visible, but it works)
|
||||
m_camera->setNearValue(27.0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_mode==CM_FINAL)
|
||||
else if (m_mode==CM_FINAL)
|
||||
{
|
||||
handleEndCamera(dt);
|
||||
return;
|
||||
}
|
||||
|
||||
float above_kart, cam_angle, side_way, distance;
|
||||
bool smoothing;
|
||||
getCameraSettings(&above_kart, &cam_angle, &side_way, &distance,
|
||||
&smoothing);
|
||||
|
||||
// If an explosion is happening, stop moving the camera,
|
||||
// but keep it target on the kart.
|
||||
if(dynamic_cast<ExplosionAnimation*>(m_kart->getKartAnimation()))
|
||||
else if (dynamic_cast<ExplosionAnimation*>(m_kart->getKartAnimation()))
|
||||
{
|
||||
getCameraSettings(&above_kart, &cam_angle, &side_way, &distance, &smoothing);
|
||||
// The camera target needs to be 'smooth moved', otherwise
|
||||
// there will be a noticable jump in the first frame
|
||||
|
||||
@ -495,10 +488,19 @@ void Camera::update(float dt)
|
||||
current_target += ((wanted_target-current_target)*m_target_speed)*dt;
|
||||
|
||||
m_camera->setTarget(current_target);
|
||||
return;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
getCameraSettings(&above_kart, &cam_angle, &side_way, &distance, &smoothing);
|
||||
positionCamera(dt, above_kart, cam_angle, side_way, distance, smoothing);
|
||||
}
|
||||
|
||||
if (UserConfigParams::m_graphical_effects && m_rain)
|
||||
{
|
||||
m_rain->setPosition( getCameraSceneNode()->getPosition() );
|
||||
m_rain->update(dt);
|
||||
} // UserConfigParams::m_graphical_effects
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -513,9 +515,10 @@ void Camera::positionCamera(float dt, float above_kart, float cam_angle,
|
||||
{
|
||||
Vec3 wanted_position;
|
||||
Vec3 wanted_target = m_kart->getXYZ();
|
||||
|
||||
if(UserConfigParams::m_camera_debug==2)
|
||||
wanted_target.setY(m_kart->getVehicle()->getWheelInfo(2).m_raycastInfo.m_contactPointWS.getY());
|
||||
else
|
||||
wanted_target.setY(wanted_target.getY()+above_kart);
|
||||
|
||||
float tan_up = tan(cam_angle);
|
||||
Vec3 relative_position(side_way,
|
||||
fabsf(distance)*tan_up+above_kart,
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2004-2005 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2006 SuperTuxKart-Team, Steve Baker
|
||||
// Copyright (C) 2004-2013 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2006-2013 SuperTuxKart-Team, Steve Baker
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2004-2013 Steve Baker <sjbaker1@airmail.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2004-2013 Steve Baker <sjbaker1@airmail.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
85
src/graphics/glow.cpp
Normal file
85
src/graphics/glow.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Lauri Kasanen
|
||||
//
|
||||
// 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 "graphics/glow.hpp"
|
||||
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
|
||||
using namespace video;
|
||||
using namespace scene;
|
||||
using namespace core;
|
||||
|
||||
IMesh * GlowNode::sphere = NULL;
|
||||
SMaterial GlowNode::mat;
|
||||
aabbox3df GlowNode::box;
|
||||
|
||||
|
||||
GlowNode::GlowNode(scene::ISceneManager* mgr, float radius): ISceneNode(mgr->getRootSceneNode(), mgr, -1)
|
||||
{
|
||||
if (!sphere)
|
||||
{
|
||||
mat.Lighting = false;
|
||||
mat.MaterialType = irr_driver->getShader(ES_GLOW);
|
||||
|
||||
mat.setTexture(0, irr_driver->getRTT(RTT_QUARTER1));
|
||||
mat.TextureLayer[0].TextureWrapU =
|
||||
mat.TextureLayer[0].TextureWrapV = ETC_CLAMP_TO_EDGE;
|
||||
mat.setFlag(EMF_TRILINEAR_FILTER, true);
|
||||
mat.BlendOperation = EBO_ADD;
|
||||
|
||||
sphere = mgr->getGeometryCreator()->createSphereMesh(1, 4, 4);
|
||||
box = sphere->getBoundingBox();
|
||||
}
|
||||
|
||||
setScale(vector3df(radius));
|
||||
}
|
||||
|
||||
GlowNode::~GlowNode()
|
||||
{
|
||||
}
|
||||
|
||||
void GlowNode::render()
|
||||
{
|
||||
IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
drv->setTransform(ETS_WORLD, AbsoluteTransformation);
|
||||
drv->setMaterial(mat);
|
||||
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_EQUAL, 0, ~0);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
drv->drawMeshBuffer(sphere->getMeshBuffer(0));
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
void GlowNode::OnRegisterSceneNode()
|
||||
{
|
||||
if (IsVisible)
|
||||
{
|
||||
SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT);
|
||||
}
|
||||
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
}
|
53
src/graphics/glow.hpp
Normal file
53
src/graphics/glow.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Lauri Kasanen
|
||||
//
|
||||
// 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_GLOW_HPP
|
||||
#define HEADER_GLOW_HPP
|
||||
|
||||
#include <ISceneNode.h>
|
||||
#include <IMesh.h>
|
||||
|
||||
using namespace irr;
|
||||
|
||||
// The actual node
|
||||
class GlowNode: public scene::ISceneNode
|
||||
{
|
||||
public:
|
||||
GlowNode(scene::ISceneManager* mgr, float radius);
|
||||
~GlowNode();
|
||||
|
||||
virtual void render();
|
||||
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const
|
||||
{
|
||||
return box;
|
||||
}
|
||||
|
||||
virtual void OnRegisterSceneNode();
|
||||
|
||||
virtual u32 getMaterialCount() const { return 1; }
|
||||
virtual video::SMaterial& getMaterial(u32 i) { return mat; }
|
||||
|
||||
private:
|
||||
static video::SMaterial mat;
|
||||
static core::aabbox3df box;
|
||||
|
||||
static scene::IMesh *sphere;
|
||||
};
|
||||
|
||||
#endif
|
21
src/graphics/glwrap.hpp
Normal file
21
src/graphics/glwrap.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef GLWRAP_HEADER_H
|
||||
#define GLWRAP_HEADER_H
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# include <OpenGL/gl.h>
|
||||
#elif defined(ANDROID)
|
||||
# include <GLES/gl.h>
|
||||
#elif defined(WIN32)
|
||||
# define _WINSOCKAPI_
|
||||
// has to be included before gl.h because of WINGDIAPI and APIENTRY definitions
|
||||
# include <windows.h>
|
||||
# include <GL/gl.h>
|
||||
#else
|
||||
# include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
// already includes glext.h, which defines useful GL constants.
|
||||
// COpenGLDriver has already loaded the extension GL functions we use (e.g glBeginQuery)
|
||||
#include "../../lib/irrlicht/source/Irrlicht/COpenGLDriver.h"
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2004-2013 Steve Baker <sjbaker1@airmail.net>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 the SuperTuxKart team
|
||||
// Copyright (C) 2011-2013 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
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs
|
||||
// Copyright (C) 2011-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs
|
||||
// Copyright (C) 2011-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs
|
||||
// Copyright (C) 2011-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Joerg Henrichs
|
||||
// Copyright (C) 2009-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -19,13 +19,23 @@
|
||||
#include "graphics/irr_driver.hpp"
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/hardware_skinning.hpp"
|
||||
#include "graphics/lens_flare.hpp"
|
||||
#include "graphics/light.hpp"
|
||||
#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 "graphics/shaders.hpp"
|
||||
#include "graphics/shadow_importance.hpp"
|
||||
#include "graphics/sun.hpp"
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/water.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "guiengine/modaldialog.hpp"
|
||||
#include "guiengine/scalable_font.hpp"
|
||||
@ -47,6 +57,7 @@
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/profiler.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#include <irrlicht.h>
|
||||
|
||||
@ -62,19 +73,12 @@
|
||||
|
||||
using namespace irr;
|
||||
|
||||
#ifndef round
|
||||
# define round(x) (floor(x+0.5f))
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
namespace X11
|
||||
{
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
}
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
/** singleton */
|
||||
@ -96,6 +100,11 @@ IrrDriver::IrrDriver()
|
||||
m_resolution_changing = RES_CHANGE_NONE;
|
||||
m_device = createDevice(video::EDT_NULL);
|
||||
m_request_screenshot = false;
|
||||
m_shaders = NULL;
|
||||
m_rtts = NULL;
|
||||
m_wind = new Wind();
|
||||
m_mipviz = m_wireframe = m_normals = m_ssaoviz = \
|
||||
m_lightviz = m_shadowviz = m_distortviz = 0;
|
||||
} // IrrDriver
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -117,6 +126,9 @@ IrrDriver::~IrrDriver()
|
||||
m_device->drop();
|
||||
m_device = NULL;
|
||||
m_modes.clear();
|
||||
|
||||
delete m_shaders;
|
||||
delete m_wind;
|
||||
} // ~IrrDriver
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -124,7 +136,7 @@ IrrDriver::~IrrDriver()
|
||||
*/
|
||||
void IrrDriver::reset()
|
||||
{
|
||||
m_post_processing->reset();
|
||||
if (m_glsl) m_post_processing->reset();
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -135,22 +147,22 @@ Returns the parent window of "window" (i.e. the ancestor of window
|
||||
that is a direct child of the root, or window itself if it is a direct child).
|
||||
If window is the root window, returns window.
|
||||
*/
|
||||
X11::Window get_toplevel_parent(X11::Display* display, X11::Window window)
|
||||
Window get_toplevel_parent(Display* display, Window window)
|
||||
{
|
||||
X11::Window parent;
|
||||
X11::Window root;
|
||||
X11::Window * children;
|
||||
Window parent;
|
||||
Window root;
|
||||
Window * children;
|
||||
unsigned int num_children;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (0 == X11::XQueryTree(display, window, &root,
|
||||
if (0 == XQueryTree(display, window, &root,
|
||||
&parent, &children, &num_children))
|
||||
{
|
||||
Log::fatal("irr_driver", "XQueryTree error\n");
|
||||
}
|
||||
if (children) { //must test for null
|
||||
X11::XFree(children);
|
||||
XFree(children);
|
||||
}
|
||||
if (window == root || parent == root) {
|
||||
return window;
|
||||
@ -201,7 +213,6 @@ void IrrDriver::updateConfigIfRelevant()
|
||||
Log::warn("irr_driver", "Could not retrieve window location\n");
|
||||
}
|
||||
#elif defined(__linux__) && !defined(ANDROID)
|
||||
using namespace X11;
|
||||
const video::SExposedVideoData& videoData =
|
||||
m_device->getVideoDriver()->getExposedVideoData();
|
||||
Display* display = (Display*)videoData.OpenGLLinux.X11Display;
|
||||
@ -326,6 +337,8 @@ void IrrDriver::initDevice()
|
||||
params.WindowSize =
|
||||
core::dimension2du(UserConfigParams::m_width,
|
||||
UserConfigParams::m_height);
|
||||
|
||||
/*
|
||||
switch ((int)UserConfigParams::m_antialiasing)
|
||||
{
|
||||
case 0:
|
||||
@ -345,9 +358,12 @@ void IrrDriver::initDevice()
|
||||
"anti-alias setting : %i\n",
|
||||
(int)UserConfigParams::m_antialiasing);
|
||||
}
|
||||
*/
|
||||
m_device = createDeviceEx(params);
|
||||
if(m_device)
|
||||
break;
|
||||
} // for bits=32, 24, 16
|
||||
|
||||
m_device = createDeviceEx(params);
|
||||
|
||||
// if still no device, try with a standard 800x600 window size, maybe
|
||||
// size is the problem
|
||||
@ -382,7 +398,8 @@ void IrrDriver::initDevice()
|
||||
m_gui_env = m_device->getGUIEnvironment();
|
||||
m_video_driver = m_device->getVideoDriver();
|
||||
m_glsl = m_video_driver->queryFeature(video::EVDF_ARB_GLSL) &&
|
||||
m_video_driver->queryFeature(video::EVDF_TEXTURE_NPOT);
|
||||
m_video_driver->queryFeature(video::EVDF_TEXTURE_NPOT) &&
|
||||
UserConfigParams::m_pixel_shaders;
|
||||
|
||||
// This remaps the window, so it has to be done before the clear to avoid flicker
|
||||
m_device->setResizable(false);
|
||||
@ -394,10 +411,48 @@ void IrrDriver::initDevice()
|
||||
if (m_glsl)
|
||||
{
|
||||
Log::info("irr_driver", "GLSL supported.");
|
||||
|
||||
// Order matters, create RTTs as soon as possible, as they are the largest blocks.
|
||||
m_rtts = new RTT();
|
||||
m_shaders = new Shaders();
|
||||
m_shadow_importance = new ShadowImportance();
|
||||
|
||||
m_mrt.clear();
|
||||
m_mrt.reallocate(3);
|
||||
m_mrt.push_back(m_rtts->getRTT(RTT_COLOR));
|
||||
m_mrt.push_back(m_rtts->getRTT(RTT_NORMAL));
|
||||
m_mrt.push_back(m_rtts->getRTT(RTT_DEPTH));
|
||||
|
||||
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
|
||||
gl_driver->extGlGenQueries(1, &m_lensflare_query);
|
||||
|
||||
scene::IMesh * const sphere = m_scene_manager->getGeometryCreator()->createSphereMesh(1, 16, 16);
|
||||
m_sun_interposer = m_scene_manager->addMeshSceneNode(sphere);
|
||||
m_sun_interposer->grab();
|
||||
m_sun_interposer->setParent(NULL);
|
||||
m_sun_interposer->setScale(core::vector3df(20));
|
||||
|
||||
m_sun_interposer->getMaterial(0).Lighting = false;
|
||||
m_sun_interposer->getMaterial(0).ColorMask = video::ECP_NONE;
|
||||
m_sun_interposer->getMaterial(0).ZWriteEnable = false;
|
||||
m_sun_interposer->getMaterial(0).MaterialType = m_shaders->getShader(ES_PASSFAR);
|
||||
|
||||
sphere->drop();
|
||||
|
||||
m_lensflare = new scene::CLensFlareSceneNode(NULL, m_scene_manager, -1);
|
||||
video::ITexture * const tex =
|
||||
m_video_driver->getTexture((file_manager->getTextureDir() + "lensflare.png").c_str());
|
||||
if (!tex) Log::fatal("irr_driver", "Cannot find lens flare texture");
|
||||
m_lensflare->setMaterialTexture(0, tex);
|
||||
m_lensflare->setAutomaticCulling(scene::EAC_OFF);
|
||||
|
||||
m_suncam = m_scene_manager->addCameraSceneNode(0, vector3df(0), vector3df(0), -1, false);
|
||||
m_suncam->grab();
|
||||
m_suncam->setParent(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::warn("irr_driver", "Too old GPU; using the fixed pipeline.");
|
||||
Log::warn("irr_driver", "Using the fixed pipeline (old GPU, or shaders disabled in options)");
|
||||
}
|
||||
|
||||
// Only change video driver settings if we are showing graphics
|
||||
@ -405,7 +460,6 @@ void IrrDriver::initDevice()
|
||||
{
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
// Set class hints on Linux, used by Window Managers.
|
||||
using namespace X11;
|
||||
const video::SExposedVideoData& videoData = m_video_driver
|
||||
->getExposedVideoData();
|
||||
XClassHint* classhint = XAllocClassHint();
|
||||
@ -421,11 +475,6 @@ void IrrDriver::initDevice()
|
||||
->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
|
||||
m_device->getVideoDriver()
|
||||
->setTextureCreationFlag(video::ETCF_OPTIMIZED_FOR_QUALITY, true);
|
||||
if (!UserConfigParams::m_fbo)
|
||||
{
|
||||
m_device->getVideoDriver()
|
||||
->disableFeature(video::EVDF_FRAMEBUFFER_OBJECT);
|
||||
}
|
||||
|
||||
// Force creation of mipmaps even if the mipmaps flag in a b3d file
|
||||
// does not set the 'enable mipmap' flag.
|
||||
@ -524,7 +573,6 @@ bool IrrDriver::moveWindow(const int x, const int y)
|
||||
return false;
|
||||
}
|
||||
#elif defined(__linux__) && !defined(ANDROID)
|
||||
using namespace X11;
|
||||
const video::SExposedVideoData& videoData = m_video_driver->getExposedVideoData();
|
||||
// TODO: Actually handle possible failure
|
||||
XMoveWindow((Display*)videoData.OpenGLLinux.X11Display,
|
||||
@ -769,6 +817,7 @@ void IrrDriver::setAllMaterialFlags(scene::IMesh *mesh) const
|
||||
* \param wave_length Lenght of a water wave.
|
||||
*/
|
||||
scene::ISceneNode* IrrDriver::addWaterNode(scene::IMesh *mesh,
|
||||
scene::IMesh **welded,
|
||||
float wave_height,
|
||||
float wave_speed,
|
||||
float wave_length)
|
||||
@ -776,11 +825,24 @@ scene::ISceneNode* IrrDriver::addWaterNode(scene::IMesh *mesh,
|
||||
mesh->setMaterialFlag(video::EMF_GOURAUD_SHADING, true);
|
||||
scene::IMesh* welded_mesh = m_scene_manager->getMeshManipulator()
|
||||
->createMeshWelded(mesh);
|
||||
scene::ISceneNode* out = m_scene_manager->addWaterSurfaceSceneNode(welded_mesh,
|
||||
scene::ISceneNode* out = NULL;
|
||||
|
||||
if (!m_glsl)
|
||||
{
|
||||
out = m_scene_manager->addWaterSurfaceSceneNode(welded_mesh,
|
||||
wave_height, wave_speed,
|
||||
wave_length);
|
||||
} else
|
||||
{
|
||||
out = new WaterNode(m_scene_manager, welded_mesh, wave_height, wave_speed,
|
||||
wave_length);
|
||||
}
|
||||
|
||||
out->getMaterial(0).setFlag(video::EMF_GOURAUD_SHADING, true);
|
||||
welded_mesh->drop(); // The scene node keeps a reference
|
||||
|
||||
*welded = welded_mesh;
|
||||
|
||||
return out;
|
||||
} // addWaterNode
|
||||
|
||||
@ -839,11 +901,22 @@ PerCameraNode *IrrDriver::addPerCameraMesh(scene::IMesh* mesh,
|
||||
scene::ICameraSceneNode* camera,
|
||||
scene::ISceneNode *parent)
|
||||
{
|
||||
scene::ISceneNode *node = m_scene_manager->addMeshSceneNode(mesh);
|
||||
|
||||
return new PerCameraNode((parent ? parent
|
||||
: m_scene_manager->getRootSceneNode()),
|
||||
m_scene_manager, -1, camera, mesh);
|
||||
m_scene_manager, -1, camera, node);
|
||||
} // addMesh
|
||||
|
||||
PerCameraNode *IrrDriver::addPerCameraNode(scene::ISceneNode* node,
|
||||
scene::ICameraSceneNode* camera,
|
||||
scene::ISceneNode *parent)
|
||||
{
|
||||
return new PerCameraNode((parent ? parent
|
||||
: m_scene_manager->getRootSceneNode()),
|
||||
m_scene_manager, -1, camera, node);
|
||||
} // addNode
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Adds a billboard node to scene.
|
||||
@ -994,9 +1067,9 @@ void IrrDriver::removeTexture(video::ITexture *t)
|
||||
/** Adds an animated mesh to the scene.
|
||||
* \param mesh The animated mesh to add.
|
||||
*/
|
||||
scene::IAnimatedMeshSceneNode *IrrDriver::addAnimatedMesh(scene::IAnimatedMesh *mesh)
|
||||
scene::IAnimatedMeshSceneNode *IrrDriver::addAnimatedMesh(scene::IAnimatedMesh *mesh, scene::ISceneNode* parent)
|
||||
{
|
||||
return m_scene_manager->addAnimatedMeshSceneNode(mesh, NULL, -1,
|
||||
return m_scene_manager->addAnimatedMeshSceneNode(mesh, parent, -1,
|
||||
core::vector3df(0,0,0),
|
||||
core::vector3df(0,0,0),
|
||||
core::vector3df(1,1,1),
|
||||
@ -1067,6 +1140,32 @@ void IrrDriver::removeCameraSceneNode(scene::ICameraSceneNode *camera)
|
||||
camera->remove();
|
||||
} // removeCameraSceneNode
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets an error message to be displayed when a texture is not found. This
|
||||
* error message is shown before the "Texture '%s' not found" message. It can
|
||||
* be used to supply additional details like what kart is currently being
|
||||
* loaded.
|
||||
* \param error Error message, potentially with a '%' which will be replaced
|
||||
* with detail.
|
||||
* \param detail String to replace a '%' in the error message.
|
||||
*/
|
||||
void IrrDriver::setTextureErrorMessage(const std::string &error,
|
||||
const std::string &detail)
|
||||
{
|
||||
if(detail=="")
|
||||
m_texture_error_message = error;
|
||||
else
|
||||
m_texture_error_message = StringUtils::insertValues(error, detail);
|
||||
} // setTextureErrorMessage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Disables the texture error message again.
|
||||
*/
|
||||
void IrrDriver::unsetTextureErrorMessage()
|
||||
{
|
||||
m_texture_error_message = "";
|
||||
} // unsetTextureErrorMessage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Loads a texture from a file and returns the texture object.
|
||||
* \param filename File name of the texture to load.
|
||||
@ -1096,7 +1195,7 @@ video::ITexture *IrrDriver::getTexture(const std::string &filename,
|
||||
// PNGs are non premul, but some are used for premul tasks, so convert
|
||||
// http://home.comcast.net/~tom_forsyth/blog.wiki.html#[[Premultiplied%20alpha]]
|
||||
// FIXME check param, not name
|
||||
if(is_premul &&
|
||||
if(img && is_premul &&
|
||||
StringUtils::hasSuffix(filename.c_str(), ".png") &&
|
||||
(img->getColorFormat() == video::ECF_A8R8G8B8) &&
|
||||
img->lock())
|
||||
@ -1119,7 +1218,7 @@ video::ITexture *IrrDriver::getTexture(const std::string &filename,
|
||||
} // if png and ColorFOrmat and lock
|
||||
// Other formats can be premul, but the tasks can be non premul
|
||||
// So divide to get the separate RGBA (only possible if alpha!=0)
|
||||
else if(is_prediv &&
|
||||
else if(img && is_prediv &&
|
||||
(img->getColorFormat() == video::ECF_A8R8G8B8) &&
|
||||
img->lock())
|
||||
{
|
||||
@ -1148,9 +1247,12 @@ video::ITexture *IrrDriver::getTexture(const std::string &filename,
|
||||
|
||||
if (complain_if_not_found && out == NULL)
|
||||
{
|
||||
Log::error("irr_driver", "Texture '%s' not found; Put a breakpoint "
|
||||
"at line %s:%i to debug!\n",
|
||||
filename.c_str(), __FILE__, __LINE__);
|
||||
|
||||
if(m_texture_error_message.size()>0)
|
||||
{
|
||||
Log::error("irr_driver", m_texture_error_message.c_str());
|
||||
}
|
||||
Log::error("irr_driver", "Texture '%s' not found.", filename.c_str());
|
||||
}
|
||||
|
||||
return out;
|
||||
@ -1581,6 +1683,11 @@ void IrrDriver::update(float dt)
|
||||
return;
|
||||
}
|
||||
|
||||
// If we quit via the menu the m_device->run() does not return true.
|
||||
// To avoid any other calls, we return here.
|
||||
if(main_loop->isAborted())
|
||||
return;
|
||||
|
||||
// If the resolution should be switched, do it now. This will delete the
|
||||
// old device and create a new one.
|
||||
if (m_resolution_changing!=RES_CHANGE_NONE)
|
||||
@ -1591,6 +1698,8 @@ void IrrDriver::update(float dt)
|
||||
m_resolution_changing = RES_CHANGE_NONE;
|
||||
}
|
||||
|
||||
m_wind->update();
|
||||
|
||||
World *world = World::getWorld();
|
||||
|
||||
// Handle cut scenes (which do not have any karts in it)
|
||||
@ -1615,97 +1724,24 @@ void IrrDriver::update(float dt)
|
||||
m_video_driver->endScene();
|
||||
return;
|
||||
}
|
||||
|
||||
const bool inRace = world!=NULL;
|
||||
|
||||
if (inRace)
|
||||
else if (!world)
|
||||
{
|
||||
// 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_video_driver->beginScene(/*backBuffer clear*/ true, /*zBuffer*/ true,
|
||||
world ? world->getClearColor()
|
||||
: video::SColor(255,100,101,140));
|
||||
video::SColor(255,100,101,140));
|
||||
|
||||
if (inRace)
|
||||
{
|
||||
irr_driver->getVideoDriver()->enableMaterial2D();
|
||||
|
||||
RaceGUIBase *rg = world->getRaceGUI();
|
||||
if (rg) rg->update(dt);
|
||||
|
||||
|
||||
for(unsigned int i=0; i<Camera::getNumCameras(); i++)
|
||||
{
|
||||
Camera *camera = Camera::getCamera(i);
|
||||
|
||||
#ifdef ENABLE_PROFILER
|
||||
std::ostringstream oss;
|
||||
oss << "drawAll() for kart " << i << std::flush;
|
||||
PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), (i+1)*60,
|
||||
0x00, 0x00);
|
||||
#endif
|
||||
camera->activate();
|
||||
rg->preRenderCallback(camera); // adjusts start referee
|
||||
m_scene_manager->drawAll();
|
||||
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
// Note that drawAll must be called before rendering
|
||||
// the bullet debug view, since otherwise the camera
|
||||
// is not set up properly. This is only used for
|
||||
// the bullet debug view.
|
||||
if (UserConfigParams::m_artist_debug_mode)
|
||||
World::getWorld()->getPhysics()->draw();
|
||||
} // for i<world->getNumKarts()
|
||||
|
||||
// Stop capturing for the post-processing
|
||||
m_post_processing->endCapture();
|
||||
|
||||
// Render the post-processed scene
|
||||
m_post_processing->render();
|
||||
|
||||
// Set the viewport back to the full screen for race gui
|
||||
m_video_driver->setViewPort(core::recti(0, 0,
|
||||
UserConfigParams::m_width,
|
||||
UserConfigParams::m_height));
|
||||
|
||||
for(unsigned int i=0; i<Camera::getNumCameras(); i++)
|
||||
{
|
||||
Camera *camera = Camera::getCamera(i);
|
||||
char marker_name[100];
|
||||
sprintf(marker_name, "renderPlayerView() for kart %d", i);
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER(marker_name, 0x00, 0x00, (i+1)*60);
|
||||
rg->renderPlayerView(camera, dt);
|
||||
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
} // for i<getNumKarts
|
||||
}
|
||||
|
||||
// Either render the gui, or the global elements of the race gui.
|
||||
GUIEngine::render(dt);
|
||||
|
||||
// Render the profiler
|
||||
if(UserConfigParams::m_profiler_enabled)
|
||||
{
|
||||
PROFILER_DRAW();
|
||||
m_video_driver->endScene();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
drawDebugMeshes();
|
||||
#endif
|
||||
|
||||
m_video_driver->endScene();
|
||||
if (m_glsl)
|
||||
renderGLSL(dt);
|
||||
else
|
||||
renderFixed(dt);
|
||||
|
||||
if (m_request_screenshot) doScreenShot();
|
||||
|
||||
getPostProcessing()->update(dt);
|
||||
|
||||
// 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
|
||||
@ -1739,7 +1775,7 @@ bool IrrDriver::OnEvent(const irr::SEvent &event)
|
||||
// Ignore 'normal' messages
|
||||
if (event.LogEvent.Level > 1)
|
||||
{
|
||||
printf("[IrrDriver Temp Logger] Level %d: %s\n",
|
||||
Log::warn("[IrrDriver Temp Logger]", "Level %d: %s\n",
|
||||
event.LogEvent.Level,event.LogEvent.Text);
|
||||
}
|
||||
return true;
|
||||
@ -1755,7 +1791,7 @@ bool IrrDriver::OnEvent(const irr::SEvent &event)
|
||||
|
||||
bool IrrDriver::supportsSplatting()
|
||||
{
|
||||
return UserConfigParams::m_pixel_shaders && m_glsl;
|
||||
return m_glsl;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -1941,6 +1977,11 @@ video::ITexture* IrrDriver::RTTProvider::renderToTexture(float angle,
|
||||
if (angle != -1 && m_rtt_main_node != NULL)
|
||||
m_rtt_main_node->setRotation( core::vector3df(0, angle, 0) );
|
||||
|
||||
video::SOverrideMaterial &overridemat = m_video_driver->getOverrideMaterial();
|
||||
overridemat.EnablePasses = scene::ESNRP_SOLID;
|
||||
overridemat.EnableFlags = video::EMF_MATERIAL_TYPE;
|
||||
overridemat.Material.MaterialType = video::EMT_SOLID;
|
||||
|
||||
if (m_rtt_main_node == NULL)
|
||||
{
|
||||
irr_driver->getSceneManager()->drawAll();
|
||||
@ -1954,6 +1995,129 @@ video::ITexture* IrrDriver::RTTProvider::renderToTexture(float angle,
|
||||
m_light->setVisible(false);
|
||||
}
|
||||
|
||||
overridemat.EnablePasses = 0;
|
||||
|
||||
m_video_driver->setRenderTarget(0, false, false);
|
||||
return m_render_target_texture;
|
||||
}
|
||||
|
||||
void IrrDriver::applyObjectPassShader(scene::ISceneNode * const node, bool rimlit)
|
||||
{
|
||||
if (!m_glsl)
|
||||
return;
|
||||
|
||||
// Don't override sky
|
||||
if (node->getType() == scene::ESNT_SKY_DOME ||
|
||||
node->getType() == scene::ESNT_SKY_BOX)
|
||||
return;
|
||||
|
||||
const u32 mcount = node->getMaterialCount();
|
||||
u32 i;
|
||||
const video::E_MATERIAL_TYPE ref = rimlit ? m_shaders->getShader(ES_OBJECTPASS_RIMLIT):
|
||||
m_shaders->getShader(ES_OBJECTPASS_REF);
|
||||
const video::E_MATERIAL_TYPE pass = rimlit ? m_shaders->getShader(ES_OBJECTPASS_RIMLIT):
|
||||
m_shaders->getShader(ES_OBJECTPASS);
|
||||
|
||||
const video::E_MATERIAL_TYPE origref = m_shaders->getShader(ES_OBJECTPASS_REF);
|
||||
const video::E_MATERIAL_TYPE origpass = m_shaders->getShader(ES_OBJECTPASS);
|
||||
|
||||
bool viamb = false;
|
||||
scene::IMesh *mesh = NULL;
|
||||
if (node->getType() == scene::ESNT_ANIMATED_MESH)
|
||||
{
|
||||
viamb = ((scene::IAnimatedMeshSceneNode *) node)->isReadOnlyMaterials();
|
||||
mesh = ((scene::IAnimatedMeshSceneNode *) node)->getMesh();
|
||||
}
|
||||
else if (node->getType() == scene::ESNT_MESH)
|
||||
{
|
||||
viamb = ((scene::IMeshSceneNode *) node)->isReadOnlyMaterials();
|
||||
mesh = ((scene::IMeshSceneNode *) node)->getMesh();
|
||||
}
|
||||
|
||||
for (i = 0; i < mcount; i++)
|
||||
{
|
||||
video::SMaterial &nodemat = node->getMaterial(i);
|
||||
video::SMaterial &mbmat = mesh ? mesh->getMeshBuffer(i)->getMaterial() : nodemat;
|
||||
video::SMaterial *mat = &nodemat;
|
||||
|
||||
if (viamb)
|
||||
mat = &mbmat;
|
||||
|
||||
if (mat->MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF ||
|
||||
mat->MaterialType == origref)
|
||||
mat->MaterialType = ref;
|
||||
else if (mat->MaterialType == video::EMT_SOLID ||
|
||||
mat->MaterialType == origpass ||
|
||||
(mat->MaterialType >= video::EMT_LIGHTMAP &&
|
||||
mat->MaterialType <= video::EMT_LIGHTMAP_LIGHTING_M4))
|
||||
mat->MaterialType = pass;
|
||||
}
|
||||
|
||||
|
||||
core::list<scene::ISceneNode*> kids = node->getChildren();
|
||||
scene::ISceneNodeList::Iterator it = kids.begin();
|
||||
for (; it != kids.end(); ++it)
|
||||
{
|
||||
applyObjectPassShader(*it, rimlit);
|
||||
}
|
||||
}
|
||||
|
||||
void IrrDriver::applyObjectPassShader()
|
||||
{
|
||||
if (!m_glsl)
|
||||
return;
|
||||
|
||||
applyObjectPassShader(m_scene_manager->getRootSceneNode());
|
||||
}
|
||||
|
||||
scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float radius,
|
||||
float r, float g, float b, bool sun)
|
||||
{
|
||||
if (m_glsl)
|
||||
{
|
||||
LightNode *light = NULL;
|
||||
|
||||
if (!sun)
|
||||
light = new LightNode(m_scene_manager, radius, r, g, b);
|
||||
else
|
||||
light = new SunNode(m_scene_manager, r, g, b);
|
||||
|
||||
light->grab();
|
||||
light->setParent(NULL);
|
||||
|
||||
light->setPosition(pos);
|
||||
light->updateAbsolutePosition();
|
||||
|
||||
m_lights.push_back(light);
|
||||
|
||||
if (sun) {
|
||||
m_sun_interposer->setPosition(pos);
|
||||
m_sun_interposer->updateAbsolutePosition();
|
||||
|
||||
m_lensflare->setPosition(pos);
|
||||
m_lensflare->updateAbsolutePosition();
|
||||
|
||||
m_suncam->setPosition(pos);
|
||||
m_suncam->updateAbsolutePosition();
|
||||
|
||||
((WaterShaderProvider *) m_shaders->m_callbacks[ES_WATER])->setSunPosition(pos);
|
||||
}
|
||||
|
||||
return light;
|
||||
} else
|
||||
{
|
||||
return m_scene_manager->addLightSceneNode(NULL, pos, video::SColorf(r, g, b), radius);
|
||||
}
|
||||
}
|
||||
|
||||
void IrrDriver::clearLights()
|
||||
{
|
||||
u32 i;
|
||||
const u32 max = m_lights.size();
|
||||
for (i = 0; i < max; i++)
|
||||
{
|
||||
m_lights[i]->drop();
|
||||
}
|
||||
|
||||
m_lights.clear();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Joerg Henrichs
|
||||
// Copyright (C) 2009-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -39,11 +39,15 @@
|
||||
namespace irr
|
||||
{
|
||||
namespace scene { class ISceneManager; class IMesh; class IAnimatedMeshSceneNode; class IAnimatedMesh;
|
||||
class IMeshSceneNode; class IParticleSystemSceneNode; class ICameraSceneNode; class ILightSceneNode; }
|
||||
class IMeshSceneNode; class IParticleSystemSceneNode; class ICameraSceneNode; class ILightSceneNode;
|
||||
class CLensFlareSceneNode; }
|
||||
namespace gui { class IGUIEnvironment; class IGUIFont; }
|
||||
}
|
||||
using namespace irr;
|
||||
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "utils/aligned_array.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
@ -53,6 +57,8 @@ class AbstractKart;
|
||||
class Camera;
|
||||
class PerCameraNode;
|
||||
class PostProcessing;
|
||||
class LightNode;
|
||||
class ShadowImportance;
|
||||
|
||||
/**
|
||||
* \brief class that creates the irrLicht device and offers higher-level
|
||||
@ -74,6 +80,21 @@ private:
|
||||
gui::IGUIFont *m_race_font;
|
||||
/** Post-processing. */
|
||||
PostProcessing *m_post_processing;
|
||||
/** Shaders. */
|
||||
Shaders *m_shaders;
|
||||
/** Wind. */
|
||||
Wind *m_wind;
|
||||
/** RTTs. */
|
||||
RTT *m_rtts;
|
||||
/** Shadow importance. */
|
||||
ShadowImportance *m_shadow_importance;
|
||||
|
||||
/** Additional details to be shown in case that a texture is not found.
|
||||
* This is used to specify details like: "while loading kart '...'" */
|
||||
std::string m_texture_error_message;
|
||||
|
||||
/** The main MRT setup. */
|
||||
core::array<video::IRenderTarget> m_mrt;
|
||||
|
||||
/** Flag to indicate if a resolution change is pending (which will be
|
||||
* acted upon in the next update). None means no change, yes means
|
||||
@ -95,6 +116,12 @@ public:
|
||||
int getWidth() const {return m_width; }
|
||||
int getHeight() const {return m_height; }
|
||||
}; // VideoMode
|
||||
|
||||
struct BloomData {
|
||||
scene::ISceneNode * node;
|
||||
float power;
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<VideoMode> m_modes;
|
||||
|
||||
@ -112,6 +139,34 @@ private:
|
||||
|
||||
bool m_request_screenshot;
|
||||
|
||||
bool m_wireframe;
|
||||
bool m_mipviz;
|
||||
bool m_normals;
|
||||
bool m_ssaoviz;
|
||||
bool m_shadowviz;
|
||||
bool m_lightviz;
|
||||
bool m_distortviz;
|
||||
u32 m_renderpass;
|
||||
u32 m_lensflare_query;
|
||||
scene::IMeshSceneNode *m_sun_interposer;
|
||||
scene::CLensFlareSceneNode *m_lensflare;
|
||||
scene::ICameraSceneNode *m_suncam;
|
||||
|
||||
struct GlowData {
|
||||
scene::ISceneNode * node;
|
||||
float r, g, b;
|
||||
};
|
||||
|
||||
std::vector<GlowData> m_glowing;
|
||||
|
||||
std::vector<LightNode *> m_lights;
|
||||
|
||||
std::vector<BloomData> m_forcedbloom;
|
||||
|
||||
std::vector<scene::ISceneNode *> m_displacing;
|
||||
|
||||
std::vector<scene::ISceneNode *> m_background;
|
||||
|
||||
#ifdef DEBUG
|
||||
/** Used to visualise skeletons. */
|
||||
std::vector<irr::scene::IAnimatedMeshSceneNode*> m_debug_meshes;
|
||||
@ -122,6 +177,9 @@ private:
|
||||
irr::scene::ISkinnedMesh* mesh, int id);
|
||||
#endif
|
||||
|
||||
void renderFixed(float dt);
|
||||
void renderGLSL(float dt);
|
||||
|
||||
void doScreenShot();
|
||||
public:
|
||||
IrrDriver();
|
||||
@ -147,7 +205,8 @@ public:
|
||||
bool create_one_quad=false);
|
||||
scene::IMesh *createTexturedQuadMesh(const video::SMaterial *material,
|
||||
const double w, const double h);
|
||||
scene::ISceneNode *addWaterNode(scene::IMesh *mesh, float wave_height,
|
||||
scene::ISceneNode *addWaterNode(scene::IMesh *mesh, scene::IMesh **welded,
|
||||
float wave_height,
|
||||
float wave_speed, float wave_length);
|
||||
scene::IMeshSceneNode*addOctTree(scene::IMesh *mesh);
|
||||
scene::IMeshSceneNode*addSphere(float radius,
|
||||
@ -157,6 +216,9 @@ public:
|
||||
PerCameraNode *addPerCameraMesh(scene::IMesh* mesh,
|
||||
scene::ICameraSceneNode* node,
|
||||
scene::ISceneNode *parent = NULL);
|
||||
PerCameraNode *addPerCameraNode(scene::ISceneNode* node,
|
||||
scene::ICameraSceneNode* cam,
|
||||
scene::ISceneNode *parent = NULL);
|
||||
scene::ISceneNode *addBillboard(const core::dimension2d< f32 > size,
|
||||
video::ITexture *texture,
|
||||
scene::ISceneNode* parent=NULL, bool alphaTesting = false);
|
||||
@ -171,7 +233,7 @@ public:
|
||||
void removeMeshFromCache(scene::IMesh *mesh);
|
||||
void removeTexture(video::ITexture *t);
|
||||
scene::IAnimatedMeshSceneNode
|
||||
*addAnimatedMesh(scene::IAnimatedMesh *mesh);
|
||||
*addAnimatedMesh(scene::IAnimatedMesh *mesh, scene::ISceneNode* parent=NULL);
|
||||
scene::ICameraSceneNode
|
||||
*addCameraSceneNode();
|
||||
Camera *addCamera(unsigned int index, AbstractKart *kart);
|
||||
@ -193,6 +255,9 @@ public:
|
||||
void printRenderStats();
|
||||
bool supportsSplatting();
|
||||
void requestScreenshot();
|
||||
void setTextureErrorMessage(const std::string &error,
|
||||
const std::string &detail="");
|
||||
void unsetTextureErrorMessage();
|
||||
|
||||
void draw2dTriangle(const core::vector2df &a, const core::vector2df &b,
|
||||
const core::vector2df &c,
|
||||
@ -203,6 +268,55 @@ public:
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Convenience function that loads a texture with default parameters
|
||||
* but includes an error message.
|
||||
* \param filename File name of the texture to load.
|
||||
* \param error Error message, potentially with a '%' which will be replaced
|
||||
* with detail.
|
||||
* \param detail String to replace a '%' in the error message.
|
||||
*/
|
||||
video::ITexture* getTexture(const std::string &filename,
|
||||
const std::string &error_message,
|
||||
const std::string &detail="")
|
||||
{
|
||||
setTextureErrorMessage(error_message, detail);
|
||||
video::ITexture *tex = getTexture(filename);
|
||||
unsetTextureErrorMessage();
|
||||
return tex;
|
||||
} // getTexture
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Convenience function that loads a texture with default parameters
|
||||
* but includes an error message.
|
||||
* \param filename File name of the texture to load.
|
||||
* \param error Error message, potentially with a '%' which will be replaced
|
||||
* with detail.
|
||||
* \param detail String to replace a '%' in the error message.
|
||||
*/
|
||||
video::ITexture* getTexture(const std::string &filename,
|
||||
char *error_message,
|
||||
char *detail=NULL)
|
||||
{
|
||||
if(!detail)
|
||||
return getTexture(filename, std::string(error_message),
|
||||
std::string(""));
|
||||
|
||||
return getTexture(filename, std::string(error_message),
|
||||
std::string(detail));
|
||||
} // getTexture
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the currently defined texture error message, which is used
|
||||
* by event_handler.cpp to print additional info about irrlicht
|
||||
* internal errors or warnings. If no error message is currently
|
||||
* defined, the error message is "".
|
||||
*/
|
||||
const std::string &getTextureErrorMessage()
|
||||
{
|
||||
return m_texture_error_message;
|
||||
} // getTextureErrorMessage
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a list of all video modes supports by the graphics card. */
|
||||
const std::vector<VideoMode>& getVideoModes() const { return m_modes; }
|
||||
@ -230,9 +344,89 @@ public:
|
||||
/** Returns a pointer to the post processing object. */
|
||||
inline PostProcessing* getPostProcessing() {return m_post_processing;}
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
inline core::vector3df getWind() {return m_wind->getWind();}
|
||||
// ------------------------------------------------------------------------
|
||||
inline video::E_MATERIAL_TYPE getShader(const ShaderType num) {return m_shaders->getShader(num);}
|
||||
// ------------------------------------------------------------------------
|
||||
inline video::IShaderConstantSetCallBack* getCallback(const ShaderType num)
|
||||
{
|
||||
return (m_shaders == NULL ? NULL : m_shaders->m_callbacks[num]);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
inline video::ITexture* getRTT(TypeRTT which) {return m_rtts->getRTT(which);}
|
||||
// ------------------------------------------------------------------------
|
||||
inline bool isGLSL() const { return m_glsl; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleWireframe() { m_wireframe ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleMipVisualization() { m_mipviz ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleNormals() { m_normals ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getNormals() { return m_normals; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleSSAOViz() { m_ssaoviz ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleLightViz() { m_lightviz ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getSSAOViz() { return m_ssaoviz; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleShadowViz() { m_shadowviz ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getShadowViz() { return m_shadowviz; }
|
||||
// ------------------------------------------------------------------------
|
||||
void toggleDistortViz() { m_distortviz ^= 1; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool getDistortViz() { return m_distortviz; }
|
||||
// ------------------------------------------------------------------------
|
||||
u32 getRenderPass() { return m_renderpass; }
|
||||
// ------------------------------------------------------------------------
|
||||
void addGlowingNode(scene::ISceneNode *n, float r = 1.0f, float g = 1.0f, float b = 1.0f)
|
||||
{
|
||||
GlowData dat;
|
||||
dat.node = n;
|
||||
dat.r = r;
|
||||
dat.g = g;
|
||||
dat.b = b;
|
||||
|
||||
m_glowing.push_back(dat);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void clearGlowingNodes() { m_glowing.clear(); }
|
||||
// ------------------------------------------------------------------------
|
||||
void addForcedBloomNode(scene::ISceneNode *n, float power = 1)
|
||||
{
|
||||
BloomData dat;
|
||||
dat.node = n;
|
||||
dat.power = power;
|
||||
|
||||
m_forcedbloom.push_back(dat);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void clearForcedBloom() { m_forcedbloom.clear(); }
|
||||
// ------------------------------------------------------------------------
|
||||
const std::vector<BloomData> &getForcedBloom() const { return m_forcedbloom; }
|
||||
// ------------------------------------------------------------------------
|
||||
void clearDisplacingNodes() { m_displacing.clear(); }
|
||||
// ------------------------------------------------------------------------
|
||||
const std::vector<scene::ISceneNode *> &getDisplacingNodes() const { return m_displacing; }
|
||||
// ------------------------------------------------------------------------
|
||||
void addDisplacingNode(scene::ISceneNode * const n) { m_displacing.push_back(n); }
|
||||
// ------------------------------------------------------------------------
|
||||
void clearBackgroundNodes() { m_background.clear(); }
|
||||
// ------------------------------------------------------------------------
|
||||
void addBackgroundNode(scene::ISceneNode * const n) { m_background.push_back(n); }
|
||||
// ------------------------------------------------------------------------
|
||||
void applyObjectPassShader();
|
||||
void applyObjectPassShader(scene::ISceneNode * const node, bool rimlit = false);
|
||||
// ------------------------------------------------------------------------
|
||||
scene::ISceneNode *addLight(const core::vector3df &pos, float radius = 1.0f, float r = 1.0f,
|
||||
float g = 1.0f, float b = 1.0f, bool sun = false);
|
||||
// ------------------------------------------------------------------------
|
||||
void clearLights();
|
||||
// ------------------------------------------------------------------------
|
||||
scene::IMeshSceneNode *getSunInterposer() { return m_sun_interposer; }
|
||||
|
||||
#ifdef DEBUG
|
||||
/** Removes debug meshes. */
|
||||
void clearDebugMesh() { m_debug_meshes.clear(); }
|
||||
|
58
src/graphics/large_mesh_buffer.hpp
Normal file
58
src/graphics/large_mesh_buffer.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright (C) 2002-2012 Nikolaus Gebhardt
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
#ifndef __LARGE_MESH_BUFFER_H_INCLUDED__
|
||||
#define __LARGE_MESH_BUFFER_H_INCLUDED__
|
||||
|
||||
#include "irrArray.h"
|
||||
#include "IMeshBuffer.h"
|
||||
#include "CMeshBuffer.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
//! A SMeshBuffer with 32-bit indices
|
||||
class LargeMeshBuffer : public SMeshBuffer
|
||||
{
|
||||
public:
|
||||
//! Get type of index data which is stored in this meshbuffer.
|
||||
/** \return Index type of this buffer. */
|
||||
virtual video::E_INDEX_TYPE getIndexType() const
|
||||
{
|
||||
return video::EIT_32BIT;
|
||||
}
|
||||
|
||||
//! Get pointer to indices
|
||||
/** \return Pointer to indices. */
|
||||
virtual const u16* getIndices() const
|
||||
{
|
||||
return (u16 *) Indices.const_pointer();
|
||||
}
|
||||
|
||||
|
||||
//! Get pointer to indices
|
||||
/** \return Pointer to indices. */
|
||||
virtual u16* getIndices()
|
||||
{
|
||||
return (u16 *) Indices.pointer();
|
||||
}
|
||||
|
||||
|
||||
//! Get number of indices
|
||||
/** \return Number of indices. */
|
||||
virtual u32 getIndexCount() const
|
||||
{
|
||||
return Indices.size();
|
||||
}
|
||||
|
||||
//! Indices into the vertices of this buffer.
|
||||
core::array<u32> Indices;
|
||||
};
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
||||
|
||||
|
264
src/graphics/lens_flare.cpp
Normal file
264
src/graphics/lens_flare.cpp
Normal file
@ -0,0 +1,264 @@
|
||||
/* TODO: copyright */
|
||||
|
||||
#include "graphics/lens_flare.hpp"
|
||||
#include "IVideoDriver.h"
|
||||
#include "ISceneManager.h"
|
||||
#include "ISceneCollisionManager.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
|
||||
CLensFlareSceneNode::CLensFlareSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id) :
|
||||
scene::ISceneNode(parent, mgr, id)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CLensFlareSceneNode");
|
||||
#endif
|
||||
|
||||
// set the bounding box
|
||||
BBox.MaxEdge.set(0,0,0);
|
||||
BBox.MinEdge.set(0,0,0);
|
||||
|
||||
// set the initial Strength
|
||||
Strength = 1.0f;
|
||||
|
||||
// setup the vertices
|
||||
Vertices[0] = video::S3DVertex(-1.f, -1.f, 0.f, 0.f, 0.f, 1.f, 0xffffffff, 0.f, 1.f);
|
||||
Vertices[1] = video::S3DVertex(-1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 0xffffffff, 0.f, 0.f);
|
||||
Vertices[2] = video::S3DVertex( 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 0xffffffff, 1.f, 0.f);
|
||||
Vertices[3] = video::S3DVertex( 1.f, -1.f, 0.f, 0.f, 0.f, 1.f, 0xffffffff, 1.f, 1.f);
|
||||
|
||||
// setup the indices
|
||||
Indices[0] = 0;
|
||||
Indices[1] = 1;
|
||||
Indices[2] = 2;
|
||||
Indices[3] = 2;
|
||||
Indices[4] = 3;
|
||||
Indices[5] = 0;
|
||||
|
||||
// set the default material properties
|
||||
Material.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
||||
Material.Lighting = false;
|
||||
Material.ZBuffer = video::ECFN_NEVER;
|
||||
|
||||
FlareData.reallocate(30);
|
||||
|
||||
// prepare the flare data array
|
||||
// circles, halos and ring behind the sun
|
||||
FlareData.push_back(SFlareData(EFT_CIRCLE, 0.5f, 0.12f, video::SColor(120, 60, 180, 35)));
|
||||
FlareData.push_back(SFlareData(EFT_HALO, 0.45f, 0.4f, video::SColor(200, 100, 200, 60)));
|
||||
FlareData.push_back(SFlareData(EFT_CIRCLE, 0.4f, 0.17f, video::SColor(240, 120, 220, 40)));
|
||||
FlareData.push_back(SFlareData(EFT_CIRCLE, 0.2f, 0.35f, video::SColor(175, 175, 255, 20)));
|
||||
FlareData.push_back(SFlareData(EFT_RING, 0.15f, 0.2f, video::SColor(120, 60, 255, 100)));
|
||||
|
||||
// sun and glow effect at sun position
|
||||
FlareData.push_back(SFlareData(EFT_SUN, 0.0f, 0.75f, video::SColor(255, 255, 255, 255)));
|
||||
// FlareData.push_back(SFlareData(EFT_STREAKS, 0.0f, 2.9f, video::SColor(255, 255, 255, 255)));
|
||||
FlareData.push_back(SFlareData(EFT_GLOW, 0.0f, 3.5f, video::SColor(255, 255, 255, 255)));
|
||||
// FlareData.push_back(SFlareData(EFT_RING, 0.0f, 1.5f, video::SColor(120, 120, 120, 150)));
|
||||
|
||||
// some lenses, halos and circles
|
||||
FlareData.push_back(SFlareData(EFT_LENS, -0.15f, 0.15f, video::SColor(255, 60, 60, 90)));
|
||||
FlareData.push_back(SFlareData(EFT_HALO, -0.3f, 0.3f, video::SColor(120, 60, 255, 180)));
|
||||
FlareData.push_back(SFlareData(EFT_HALO, -0.4f, 0.2f, video::SColor(220, 80, 80, 98)));
|
||||
FlareData.push_back(SFlareData(EFT_CIRCLE, -0.45f, 0.1f, video::SColor(220, 80, 80, 85)));
|
||||
FlareData.push_back(SFlareData(EFT_RING, -0.42f, 0.3f, video::SColor(180, 60, 255, 110)));
|
||||
|
||||
// some small lenses, halos and rings
|
||||
FlareData.push_back(SFlareData(EFT_LENS, -0.55f, 0.2f, video::SColor(255, 60, 60, 130)));
|
||||
FlareData.push_back(SFlareData(EFT_HALO, -0.6f, 0.3f, video::SColor(120, 60, 255, 80)));
|
||||
FlareData.push_back(SFlareData(EFT_LENS, -0.7f, 0.2f, video::SColor(200, 60, 60, 130)));
|
||||
FlareData.push_back(SFlareData(EFT_LENS, -0.71f, 0.2f, video::SColor(200, 60, 130, 60)));
|
||||
FlareData.push_back(SFlareData(EFT_LENS, -0.72f, 0.2f, video::SColor(200, 130, 130, 60)));
|
||||
FlareData.push_back(SFlareData(EFT_LENS, -0.74f, 0.2f, video::SColor(200, 130, 60, 60)));
|
||||
|
||||
// some polyons, lenses and circle
|
||||
FlareData.push_back(SFlareData(scene::EFT_POLY, -0.79f, 0.2f, video::SColor(200, 60, 130, 60)));
|
||||
FlareData.push_back(SFlareData(scene::EFT_POLY, -0.86f, 0.3f, video::SColor(200, 130, 130, 60)));
|
||||
FlareData.push_back(SFlareData(scene::EFT_LENS, -0.87f, 0.3f, video::SColor(180,255,192,178)));
|
||||
FlareData.push_back(SFlareData(scene::EFT_CIRCLE, -0.9f, 0.1f, video::SColor(200, 60, 60, 130)));
|
||||
FlareData.push_back(SFlareData(scene::EFT_POLY, -0.93f, 0.4f, video::SColor(200, 130, 60, 60)));
|
||||
|
||||
// finally som polygons
|
||||
FlareData.push_back(SFlareData(EFT_POLY, -0.95f, 0.6f, video::SColor(120, 60, 255, 120)));
|
||||
FlareData.push_back(SFlareData(EFT_POLY, -1.0f, 0.15f, video::SColor(120, 20, 255, 85)));
|
||||
}
|
||||
|
||||
CLensFlareSceneNode::~CLensFlareSceneNode()
|
||||
{
|
||||
}
|
||||
|
||||
u32 CLensFlareSceneNode::getMaterialCount() const
|
||||
{
|
||||
// return the material count (always one in our case)
|
||||
return 1;
|
||||
}
|
||||
|
||||
video::SMaterial& CLensFlareSceneNode::getMaterial(u32 i)
|
||||
{
|
||||
// return the material
|
||||
return Material;
|
||||
}
|
||||
|
||||
core::array<SFlareData>& CLensFlareSceneNode::getFlareData()
|
||||
{
|
||||
// return the flare data array
|
||||
return FlareData;
|
||||
}
|
||||
|
||||
void CLensFlareSceneNode::OnRegisterSceneNode()
|
||||
{
|
||||
// if node is visible and Strength is greater than 0 register it for the ESNRP_TRANSPARENT_EFFECT pass
|
||||
if(IsVisible && Strength > 0.0f)
|
||||
{
|
||||
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT_EFFECT);
|
||||
}
|
||||
|
||||
// call base OnRegisterSceneNode
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
|
||||
void CLensFlareSceneNode::render()
|
||||
{
|
||||
// get the videodriver and the active camera
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
ICameraSceneNode* camera = SceneManager->getActiveCamera();
|
||||
|
||||
// return if we don't have a valid driver or a valid camera
|
||||
// or if we have no texture attached to the material
|
||||
if (!camera || !driver || !Material.getTexture(0))
|
||||
return;
|
||||
|
||||
// get screencenter
|
||||
const core::vector2d<s32> screenCenter = core::vector2d<s32>(
|
||||
SceneManager->getVideoDriver()->getScreenSize().Width,
|
||||
SceneManager->getVideoDriver()->getScreenSize().Height)/2;
|
||||
|
||||
// get screencoordinates of the node
|
||||
const core::vector2d<s32> lightPos = SceneManager->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(
|
||||
getAbsolutePosition(),
|
||||
camera);
|
||||
|
||||
// store old projection matrix
|
||||
core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION);
|
||||
|
||||
// store old view matrix
|
||||
core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW);
|
||||
|
||||
// clear the projection matrix
|
||||
driver->setTransform(video::ETS_PROJECTION, core::IdentityMatrix);
|
||||
|
||||
// clear the view matrix
|
||||
driver->setTransform(video::ETS_VIEW, core::IdentityMatrix);
|
||||
|
||||
// set the transform
|
||||
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
|
||||
|
||||
// set the material
|
||||
driver->setMaterial(Material);
|
||||
|
||||
// calculate some handy constants
|
||||
const f32 texPos = 1.0f/EFT_COUNT;
|
||||
const s32 texHeight = s32(Material.getTexture(0)->getSize().Height*0.5f);
|
||||
const f32 screenWidth = f32(driver->getScreenSize().Width);
|
||||
const f32 screenHeight = f32(driver->getScreenSize().Height);
|
||||
|
||||
// render the flares
|
||||
for (u32 i=0; i<FlareData.size(); ++i)
|
||||
{
|
||||
// get the flare element
|
||||
SFlareData& flare = FlareData[i];
|
||||
|
||||
// calculate center of the flare
|
||||
core::vector2d<s32>flarePos = screenCenter.getInterpolated(lightPos, -2.0*flare.Position);
|
||||
|
||||
// calculate flareposition in vertex coordinates using the scalefactor of the flare
|
||||
s32 flareScale = s32((texHeight*flare.Scale));
|
||||
core::rect<f32> flareRect = core::rect<f32>(
|
||||
-1.f + 2.f * f32(flarePos.X-flareScale) / screenWidth,
|
||||
-1.f + 2.f * f32(screenHeight-flarePos.Y-flareScale) / screenHeight,
|
||||
-1.f + 2.f * f32(flarePos.X+flareScale) / screenWidth,
|
||||
-1.f + 2.f * f32(screenHeight-flarePos.Y+flareScale) / screenHeight);
|
||||
|
||||
// calculate flarecolor in dependence of occlusion
|
||||
f32 flareAlpha = f32(flare.Color.getAlpha()) / 255.f;
|
||||
video::SColor flareColor(255,
|
||||
(u32)(Strength * flareAlpha * flare.Color.getRed()),
|
||||
(u32)(Strength * flareAlpha * flare.Color.getGreen()),
|
||||
(u32)(Strength * flareAlpha * flare.Color.getBlue()));
|
||||
|
||||
// set vertex colors
|
||||
Vertices[0].Color = flareColor;
|
||||
Vertices[1].Color = flareColor;
|
||||
Vertices[2].Color = flareColor;
|
||||
Vertices[3].Color = flareColor;
|
||||
|
||||
// set texture coordinates
|
||||
Vertices[0].TCoords.set( flare.Type * texPos, 1.0f);
|
||||
Vertices[1].TCoords.set( flare.Type * texPos, 0.0f);
|
||||
Vertices[2].TCoords.set((flare.Type+1) * texPos, 0.0f);
|
||||
Vertices[3].TCoords.set((flare.Type+1) * texPos, 1.0f);
|
||||
|
||||
// set vertex positions
|
||||
Vertices[0].Pos.set(flareRect.UpperLeftCorner.X, flareRect.UpperLeftCorner.Y, 0);
|
||||
Vertices[1].Pos.set(flareRect.UpperLeftCorner.X, flareRect.LowerRightCorner .Y, 0);
|
||||
Vertices[2].Pos.set(flareRect.LowerRightCorner.X, flareRect.LowerRightCorner.Y, 0);
|
||||
Vertices[3].Pos.set(flareRect.LowerRightCorner.X, flareRect.UpperLeftCorner.Y, 0);
|
||||
|
||||
//draw the mesh
|
||||
driver->drawIndexedTriangleList(Vertices, 4, Indices, 2);
|
||||
}
|
||||
|
||||
// restore view matrix
|
||||
driver->setTransform(video::ETS_VIEW, oldViewMat);
|
||||
|
||||
// restore projection matrix
|
||||
driver->setTransform(video::ETS_PROJECTION, oldProjMat);
|
||||
}
|
||||
|
||||
const core::aabbox3df& CLensFlareSceneNode::getBoundingBox() const
|
||||
{
|
||||
// return the bounding box
|
||||
return BBox;
|
||||
}
|
||||
|
||||
ESCENE_NODE_TYPE CLensFlareSceneNode::getType() const
|
||||
{
|
||||
// return type of the scene node
|
||||
// (important when using with a custom scene node factory)
|
||||
return scene::ESNT_UNKNOWN; //(ESCENE_NODE_TYPE) ECSNT_LENSFLARE;
|
||||
}
|
||||
|
||||
void CLensFlareSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
|
||||
{
|
||||
// write attributes of the scene node.
|
||||
ISceneNode::serializeAttributes(out, options);
|
||||
}
|
||||
|
||||
void CLensFlareSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
|
||||
{
|
||||
// read attributes of the scene node.
|
||||
ISceneNode::deserializeAttributes(in, options);
|
||||
}
|
||||
|
||||
ISceneNode* CLensFlareSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
|
||||
{
|
||||
if (!newParent)
|
||||
newParent = Parent;
|
||||
if (!newManager)
|
||||
newManager = SceneManager;
|
||||
|
||||
CLensFlareSceneNode* nb = new CLensFlareSceneNode(newParent, newManager, ID);
|
||||
|
||||
nb->cloneMembers(this, newManager);
|
||||
nb->Material = Material;
|
||||
|
||||
nb->drop();
|
||||
return nb;
|
||||
}
|
||||
|
||||
}// end irr namespace
|
||||
}// end scene namespace
|
||||
|
117
src/graphics/lens_flare.hpp
Normal file
117
src/graphics/lens_flare.hpp
Normal file
@ -0,0 +1,117 @@
|
||||
#ifndef _CLENSFLARESCENENODE_H
|
||||
#define _CLENSFLARESCENENODE_H
|
||||
|
||||
#include <ISceneNode.h>
|
||||
#include <S3DVertex.h>
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
// enum with different flare types (used by SFlareData)
|
||||
enum E_FLARE_TYPE
|
||||
{
|
||||
EFT_SUN = 0,
|
||||
EFT_GLOW,
|
||||
EFT_LENS,
|
||||
EFT_STREAKS,
|
||||
EFT_RING,
|
||||
EFT_HALO,
|
||||
EFT_CIRCLE,
|
||||
EFT_POLY,
|
||||
EFT_COUNT
|
||||
};
|
||||
|
||||
// struct holding the flare specification
|
||||
struct SFlareData
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
SFlareData(const E_FLARE_TYPE type, const float position,
|
||||
const float scale, const video::SColor &color)
|
||||
{
|
||||
Type = type;
|
||||
Position = position;
|
||||
Scale = scale;
|
||||
Color = color;
|
||||
}
|
||||
|
||||
// flare type
|
||||
E_FLARE_TYPE Type;
|
||||
// position
|
||||
f32 Position;
|
||||
// flare scale
|
||||
f32 Scale;
|
||||
// flare color
|
||||
video::SColor Color;
|
||||
};
|
||||
|
||||
class CLensFlareSceneNode : public ISceneNode
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CLensFlareSceneNode(ISceneNode* parent, scene::ISceneManager* mgr, s32 id = -1);
|
||||
|
||||
// destructor
|
||||
virtual ~CLensFlareSceneNode();
|
||||
|
||||
protected:
|
||||
// material of the node
|
||||
video::SMaterial Material;
|
||||
|
||||
// Bounding box
|
||||
core::aabbox3d<f32> BBox;
|
||||
|
||||
// vertices and indices of a flare element
|
||||
video::S3DVertex Vertices[4];
|
||||
u16 Indices[6];
|
||||
|
||||
// flare data array
|
||||
core::array<SFlareData> FlareData;
|
||||
|
||||
// Strength of the flare effect (between 0 and 1)
|
||||
f32 Strength;
|
||||
|
||||
public:
|
||||
// typical OnRegisterSceneNode function
|
||||
virtual void OnRegisterSceneNode();
|
||||
|
||||
// renders the node
|
||||
virtual void render();
|
||||
|
||||
// returns the bounding box
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const;
|
||||
|
||||
// returns the node type
|
||||
virtual ESCENE_NODE_TYPE getType() const;
|
||||
|
||||
// returns the material count
|
||||
virtual u32 getMaterialCount() const;
|
||||
|
||||
// returns the material
|
||||
virtual video::SMaterial& getMaterial(u32 i);
|
||||
|
||||
// writes attributes of the scene node.
|
||||
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options = 0) const;
|
||||
|
||||
// reads attributes of the scene node.
|
||||
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options = 0);
|
||||
|
||||
// clones the node
|
||||
virtual ISceneNode* clone(ISceneNode* newParent = 0, ISceneManager* newManager = 0);
|
||||
|
||||
// returns the flare data array
|
||||
core::array<SFlareData>& getFlareData();
|
||||
|
||||
// returns the strength (visibility) of the flares
|
||||
f32 getStrength() { return Strength; }
|
||||
|
||||
// sets the strength (visibility) of the flares
|
||||
void setStrength(f32 strength) { Strength = core::clamp(strength, 0.0f, 0.7f); }
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
||||
|
||||
#endif
|
||||
|
93
src/graphics/light.cpp
Normal file
93
src/graphics/light.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Lauri Kasanen
|
||||
//
|
||||
// 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 "graphics/light.hpp"
|
||||
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/rtts.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
|
||||
using namespace video;
|
||||
using namespace scene;
|
||||
using namespace core;
|
||||
|
||||
IMesh * LightNode::sphere = NULL;
|
||||
SMaterial LightNode::mat;
|
||||
aabbox3df LightNode::box;
|
||||
|
||||
|
||||
LightNode::LightNode(scene::ISceneManager* mgr, float radius, float r, float g, float b):
|
||||
ISceneNode(mgr->getRootSceneNode(), mgr, -1)
|
||||
{
|
||||
if (!sphere)
|
||||
{
|
||||
mat.Lighting = false;
|
||||
mat.MaterialType = irr_driver->getShader(ES_POINTLIGHT);
|
||||
|
||||
mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL));
|
||||
mat.setTexture(1, irr_driver->getRTT(RTT_DEPTH));
|
||||
|
||||
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
|
||||
{
|
||||
mat.TextureLayer[i].TextureWrapU =
|
||||
mat.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE;
|
||||
}
|
||||
|
||||
mat.setFlag(EMF_BILINEAR_FILTER, false);
|
||||
mat.setFlag(EMF_ZWRITE_ENABLE, false);
|
||||
|
||||
mat.MaterialTypeParam = pack_textureBlendFunc(EBF_ONE, EBF_ONE);
|
||||
mat.BlendOperation = EBO_ADD;
|
||||
|
||||
sphere = mgr->getGeometryCreator()->createSphereMesh(1, 16, 16);
|
||||
box = sphere->getBoundingBox();
|
||||
}
|
||||
|
||||
setScale(vector3df(radius));
|
||||
m_radius = radius;
|
||||
|
||||
m_color[0] = r;
|
||||
m_color[1] = g;
|
||||
m_color[2] = b;
|
||||
}
|
||||
|
||||
LightNode::~LightNode()
|
||||
{
|
||||
}
|
||||
|
||||
void LightNode::render()
|
||||
{
|
||||
PointLightProvider * const cb = (PointLightProvider *) irr_driver->getCallback(ES_POINTLIGHT);
|
||||
cb->setColor(m_color[0], m_color[1], m_color[2]);
|
||||
cb->setPosition(getPosition().X, getPosition().Y, getPosition().Z);
|
||||
cb->setRadius(m_radius);
|
||||
|
||||
IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
drv->setTransform(ETS_WORLD, AbsoluteTransformation);
|
||||
drv->setMaterial(mat);
|
||||
|
||||
drv->drawMeshBuffer(sphere->getMeshBuffer(0));
|
||||
}
|
||||
|
||||
void LightNode::OnRegisterSceneNode()
|
||||
{ // This node is only drawn manually.
|
||||
}
|
64
src/graphics/light.hpp
Normal file
64
src/graphics/light.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Lauri Kasanen
|
||||
//
|
||||
// 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_LIGHT_HPP
|
||||
#define HEADER_LIGHT_HPP
|
||||
|
||||
#include <ISceneNode.h>
|
||||
#include <utils/cpp2011.h>
|
||||
|
||||
using namespace irr;
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene { class IMesh; }
|
||||
}
|
||||
|
||||
// The actual node
|
||||
class LightNode: public scene::ISceneNode
|
||||
{
|
||||
public:
|
||||
LightNode(scene::ISceneManager* mgr, float radius, float r, float g, float b);
|
||||
virtual ~LightNode();
|
||||
|
||||
virtual void render() OVERRIDE;
|
||||
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const OVERRIDE
|
||||
{
|
||||
return box;
|
||||
}
|
||||
|
||||
virtual void OnRegisterSceneNode() OVERRIDE;
|
||||
|
||||
virtual u32 getMaterialCount() const OVERRIDE { return 1; }
|
||||
virtual video::SMaterial& getMaterial(u32 i) OVERRIDE { return mat; }
|
||||
|
||||
float getRadius() const { return m_radius; }
|
||||
void getColor(float out[3]) const { memcpy(out, m_color, 3 * sizeof(float)); }
|
||||
|
||||
protected:
|
||||
static video::SMaterial mat;
|
||||
static core::aabbox3df box;
|
||||
|
||||
static scene::IMesh *sphere;
|
||||
|
||||
float m_radius;
|
||||
float m_color[3];
|
||||
};
|
||||
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Marianne Gagnon
|
||||
// based on code Copyright (C) 2002-2010 Nikolaus Gebhardt
|
||||
// Copyright (C) 2011-2013 Marianne Gagnon
|
||||
// based on code Copyright 2002-2010 Nikolaus Gebhardt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -49,6 +49,7 @@ LODNode::LODNode(std::string group_name, scene::ISceneNode* parent,
|
||||
drop();
|
||||
|
||||
m_forced_lod = -1;
|
||||
m_last_tick = 0;
|
||||
}
|
||||
|
||||
LODNode::~LODNode()
|
||||
@ -81,6 +82,11 @@ int LODNode::getLevel()
|
||||
if (dist < m_detail[n])
|
||||
return n;
|
||||
}
|
||||
|
||||
// If it's the shadow pass, and we would have otherwise hidden the item, show the min one
|
||||
if (curr_cam->isOrthogonal())
|
||||
return m_detail.size() - 1;
|
||||
|
||||
return -1;
|
||||
} // getLevel
|
||||
|
||||
@ -139,9 +145,12 @@ void LODNode::OnRegisterSceneNode()
|
||||
shown = true;
|
||||
}
|
||||
|
||||
const u32 now = irr_driver->getDevice()->getTimer()->getTime();
|
||||
|
||||
// support an optional, mostly hard-coded fade-in/out effect for objects with a single level
|
||||
if (m_nodes.size() == 1 && (m_nodes[0]->getType() == scene::ESNT_MESH ||
|
||||
m_nodes[0]->getType() == scene::ESNT_ANIMATED_MESH))
|
||||
m_nodes[0]->getType() == scene::ESNT_ANIMATED_MESH) &&
|
||||
now > m_last_tick)
|
||||
{
|
||||
if (m_previous_visibility == WAS_HIDDEN && shown)
|
||||
{
|
||||
@ -237,6 +246,7 @@ void LODNode::OnRegisterSceneNode()
|
||||
}
|
||||
|
||||
m_previous_visibility = (shown ? WAS_SHOWN : WAS_HIDDEN);
|
||||
m_last_tick = now;
|
||||
|
||||
// If this node has children other than the LOD nodes, draw them
|
||||
core::list<ISceneNode*>::Iterator it;
|
||||
@ -279,7 +289,13 @@ void LODNode::add(int level, scene::ISceneNode* node, bool reparent)
|
||||
if(UserConfigParams::m_hw_skinning_enabled && node->getType() == scene::ESNT_ANIMATED_MESH)
|
||||
HardwareSkinning::prepareNode((scene::IAnimatedMeshSceneNode*)node);
|
||||
|
||||
if (node->getType() == scene::ESNT_ANIMATED_MESH)
|
||||
((scene::IAnimatedMeshSceneNode *) node)->setReadOnlyMaterials(true);
|
||||
if (node->getType() == scene::ESNT_MESH)
|
||||
((scene::IMeshSceneNode *) node)->setReadOnlyMaterials(true);
|
||||
|
||||
node->drop();
|
||||
|
||||
node->updateAbsolutePosition();
|
||||
irr_driver->applyObjectPassShader(node);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Marianne Gagnon
|
||||
// based on code Copyright (C) 2002-2010 Nikolaus Gebhardt
|
||||
// Copyright (C) 2011-2013 Marianne Gagnon
|
||||
// based on code Copyright 2002-2010 Nikolaus Gebhardt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -71,6 +71,8 @@ private:
|
||||
|
||||
PreviousVisibility m_previous_visibility;
|
||||
|
||||
u32 m_last_tick;
|
||||
|
||||
public:
|
||||
|
||||
LODNode(std::string group_name, scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id=-1);
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
|
||||
// 2010 Steve Baker, Joerg Henrichs
|
||||
// Copyright (C) 2010-2013 Steve Baker, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -27,8 +27,10 @@
|
||||
#include "config/user_config.hpp"
|
||||
#include "config/stk_config.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/particle_kind_manager.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
@ -36,7 +38,6 @@
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#include <IGPUProgrammingServices.h>
|
||||
#include <IMaterialRendererServices.h>
|
||||
#include <ISceneNode.h>
|
||||
#include <IShaderConstantSetCallBack.h>
|
||||
@ -46,351 +47,6 @@ using namespace irr::video;
|
||||
const unsigned int UCLAMP = 1;
|
||||
const unsigned int VCLAMP = 2;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class NormalMapProvider : public video::IShaderConstantSetCallBack
|
||||
{
|
||||
bool m_with_lightmap;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
NormalMapProvider(bool withLightmap)
|
||||
{
|
||||
m_with_lightmap = withLightmap;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(
|
||||
irr::video::IMaterialRendererServices *services,
|
||||
s32 userData)
|
||||
{
|
||||
s32 decaltex = 0;
|
||||
services->setPixelShaderConstant("DecalTex", &decaltex, 1);
|
||||
|
||||
s32 bumptex = 1;
|
||||
services->setPixelShaderConstant("BumpTex", &bumptex, 1);
|
||||
|
||||
s32 lightmapTex = (m_with_lightmap ? 2 : 0);
|
||||
services->setPixelShaderConstant("LightMapTex", &lightmapTex, 1);
|
||||
|
||||
s32 hasLightMap = (m_with_lightmap ? 1 : 0);
|
||||
services->setPixelShaderConstant("HasLightMap", &hasLightMap, 1);
|
||||
|
||||
// We could calculate light direction as coming from the sun (then we'd need to
|
||||
// transform it into camera space). But I find that pretending light
|
||||
// comes from the camera gives good results
|
||||
const float lightdir[] = {0.1852f, -0.1852f, -0.9259f};
|
||||
services->setVertexShaderConstant("lightdir", lightdir, 3);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class WaterShaderProvider : public video::IShaderConstantSetCallBack
|
||||
{
|
||||
float m_dx_1, m_dy_1, m_dx_2, m_dy_2;
|
||||
float m_water_shader_speed_1;
|
||||
float m_water_shader_speed_2;
|
||||
bool m_fog;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
void enableFog(bool enable)
|
||||
{
|
||||
m_fog = enable;
|
||||
}
|
||||
|
||||
|
||||
WaterShaderProvider(float water_shader_speed_1,
|
||||
float water_shader_speed_2)
|
||||
{
|
||||
m_dx_1 = 0.0f;
|
||||
m_dy_1 = 0.0f;
|
||||
m_dx_2 = 0.0f;
|
||||
m_dy_2 = 0.0f;
|
||||
|
||||
m_water_shader_speed_1 = water_shader_speed_1/100.0f;
|
||||
m_water_shader_speed_2 = water_shader_speed_2/100.0f;
|
||||
|
||||
m_fog = false;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(
|
||||
irr::video::IMaterialRendererServices *services,
|
||||
s32 userData)
|
||||
{
|
||||
m_dx_1 += GUIEngine::getLatestDt()*m_water_shader_speed_1;
|
||||
m_dy_1 += GUIEngine::getLatestDt()*m_water_shader_speed_1;
|
||||
|
||||
m_dx_2 += GUIEngine::getLatestDt()*m_water_shader_speed_2;
|
||||
m_dy_2 -= GUIEngine::getLatestDt()*m_water_shader_speed_2;
|
||||
|
||||
if (m_dx_1 > 1.0f) m_dx_1 -= 1.0f;
|
||||
if (m_dy_1 > 1.0f) m_dy_1 -= 1.0f;
|
||||
if (m_dx_2 > 1.0f) m_dx_2 -= 1.0f;
|
||||
if (m_dy_2 < 0.0f) m_dy_2 += 1.0f;
|
||||
|
||||
s32 decaltex = 0;
|
||||
services->setPixelShaderConstant("DecalTex", &decaltex, 1);
|
||||
|
||||
s32 bumptex = 1;
|
||||
services->setPixelShaderConstant("BumpTex1", &bumptex, 1);
|
||||
|
||||
bumptex = 2;
|
||||
services->setPixelShaderConstant("BumpTex2", &bumptex, 1);
|
||||
|
||||
// We could calculate light direction as coming from the sun (then we'd need to
|
||||
// transform it into camera space). But I find that pretending light
|
||||
// comes from the camera gives good results
|
||||
const float lightdir[] = {-0.315f, 0.91f, -0.3f};
|
||||
services->setVertexShaderConstant("lightdir", lightdir, 3);
|
||||
|
||||
services->setVertexShaderConstant("delta1", &m_dx_1, 2);
|
||||
services->setVertexShaderConstant("delta2", &m_dx_2, 2);
|
||||
|
||||
if (m_fog)
|
||||
{
|
||||
Track* t = World::getWorld()->getTrack();
|
||||
|
||||
float fogStart = t->getFogStart();
|
||||
services->setPixelShaderConstant("fogFrom", &fogStart, 1);
|
||||
|
||||
float fogEnd = t->getFogEnd();
|
||||
services->setPixelShaderConstant("fogTo", &fogEnd, 1);
|
||||
|
||||
video::SColor fogColor = t->getFogColor();
|
||||
float fogColorVec[] = {fogColor.getRed()/255.0f,
|
||||
fogColor.getGreen()/255.0f,
|
||||
fogColor.getBlue()/255.0f, 1.0f};
|
||||
services->setVertexShaderConstant("fogColor", fogColorVec, 4);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// FIXME: refactor this hack to get per-instance properties, and apply the
|
||||
// clean fix to all shaders why we're at it......
|
||||
std::map<int, float> grass_shaders_times;
|
||||
int grass_shaders_times_index = 0;
|
||||
|
||||
class GrassShaderProvider : public video::IShaderConstantSetCallBack
|
||||
{
|
||||
bool m_fog;
|
||||
float m_angle;
|
||||
float m_amplitude;
|
||||
float m_speed;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
|
||||
GrassShaderProvider(float amplitude, float speed)
|
||||
{
|
||||
m_fog = false;
|
||||
m_angle = 0.0f;
|
||||
m_amplitude = amplitude;
|
||||
m_speed = speed;
|
||||
}
|
||||
|
||||
|
||||
void enableFog(bool enable)
|
||||
{
|
||||
m_fog = enable;
|
||||
}
|
||||
|
||||
void update(float dt)
|
||||
{
|
||||
m_angle += GUIEngine::getLatestDt()*m_speed;
|
||||
if (m_angle > M_PI*2) m_angle -= M_PI*2;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(irr::video::IMaterialRendererServices *services,
|
||||
s32 userData)
|
||||
{
|
||||
grass_shaders_times[userData] += GUIEngine::getLatestDt()*m_speed;
|
||||
if (grass_shaders_times[userData] > M_PI*2) grass_shaders_times[userData] -= M_PI*2;
|
||||
|
||||
services->setVertexShaderConstant("angle", &grass_shaders_times[userData], 1);
|
||||
|
||||
int fog = (m_fog ? 1 : 0);
|
||||
services->setVertexShaderConstant("fog", &fog, 1);
|
||||
|
||||
s32 tex = 0;
|
||||
services->setVertexShaderConstant("tex", &tex, 1);
|
||||
|
||||
services->setVertexShaderConstant("amplitude", &m_amplitude, 1);
|
||||
|
||||
if (m_fog)
|
||||
{
|
||||
Track* t = World::getWorld()->getTrack();
|
||||
|
||||
float fogStart = t->getFogStart();
|
||||
services->setPixelShaderConstant("fogFrom", &fogStart, 1);
|
||||
|
||||
float fogEnd = t->getFogEnd();
|
||||
services->setPixelShaderConstant("fogTo", &fogEnd, 1);
|
||||
|
||||
video::SColor fogColor = t->getFogColor();
|
||||
float fogColorVec[] = {fogColor.getRed()/255.0f,
|
||||
fogColor.getGreen()/255.0f,
|
||||
fogColor.getBlue()/255.0f, 1.0f};
|
||||
services->setVertexShaderConstant("fogColor", fogColorVec, 4);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
class SplattingProvider : public video::IShaderConstantSetCallBack
|
||||
{
|
||||
core::vector3df m_light_direction;
|
||||
bool m_light_dir_calculated;
|
||||
bool m_lightmap;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
SplattingProvider(bool lightmap)
|
||||
{
|
||||
m_light_dir_calculated = false;
|
||||
m_lightmap = lightmap;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(
|
||||
irr::video::IMaterialRendererServices *services,
|
||||
s32 userData)
|
||||
{
|
||||
if (!m_light_dir_calculated)
|
||||
{
|
||||
m_light_dir_calculated = true;
|
||||
m_light_direction = -World::getWorld()->getTrack()->getSunRotation().rotationToDirection();
|
||||
}
|
||||
|
||||
s32 tex_layout = 1;
|
||||
services->setPixelShaderConstant("tex_layout", &tex_layout, 1);
|
||||
|
||||
s32 tex_detail0 = 2;
|
||||
services->setPixelShaderConstant("tex_detail0", &tex_detail0, 1);
|
||||
|
||||
s32 tex_detail1 = 3;
|
||||
services->setPixelShaderConstant("tex_detail1", &tex_detail1, 1);
|
||||
|
||||
s32 tex_detail2 = 4;
|
||||
services->setPixelShaderConstant("tex_detail2", &tex_detail2, 1);
|
||||
|
||||
s32 tex_detail3 = 5;
|
||||
services->setPixelShaderConstant("tex_detail3", &tex_detail3, 1);
|
||||
|
||||
if (m_lightmap)
|
||||
{
|
||||
s32 tex_lightmap = 6;
|
||||
services->setPixelShaderConstant("tex_lightmap", &tex_lightmap, 1);
|
||||
}
|
||||
|
||||
services->setVertexShaderConstant("lightdir", &m_light_direction.X, 3);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
class SphereMapProvider: public video::IShaderConstantSetCallBack
|
||||
{
|
||||
core::vector3df m_light_direction;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
SphereMapProvider()
|
||||
{
|
||||
m_light_direction = core::vector3df(-0.6f, -0.5f, -0.63f);
|
||||
//m_light_direction = core::vector3df(-0.315f, 0.91f, -0.3f);
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(
|
||||
irr::video::IMaterialRendererServices *services,
|
||||
s32 userData)
|
||||
{
|
||||
s32 texture = 0;
|
||||
services->setPixelShaderConstant("texture", &texture, 1);
|
||||
|
||||
services->setVertexShaderConstant("lightdir", &m_light_direction.X, 3);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
class BubbleEffectProvider : public video::IShaderConstantSetCallBack
|
||||
{
|
||||
irr::u32 initial_time;
|
||||
float m_transparency;
|
||||
bool m_is_visible;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
BubbleEffectProvider()
|
||||
{
|
||||
initial_time = irr_driver->getDevice()->getTimer()->getRealTime();
|
||||
m_transparency = 1.0f;
|
||||
m_is_visible = true;
|
||||
}
|
||||
|
||||
virtual void OnSetConstants(
|
||||
irr::video::IMaterialRendererServices *services,
|
||||
s32 userData)
|
||||
{
|
||||
if (m_is_visible && m_transparency < 1.0f)
|
||||
{
|
||||
m_transparency += GUIEngine::getLatestDt()*0.3f;
|
||||
if (m_transparency > 1.0f) m_transparency = 1.0f;
|
||||
}
|
||||
else if (!m_is_visible && m_transparency > 0.0f)
|
||||
{
|
||||
m_transparency -= GUIEngine::getLatestDt()*0.3f;
|
||||
if (m_transparency < 0.0f) m_transparency = 0.0f;
|
||||
}
|
||||
|
||||
float time = (irr_driver->getDevice()->getTimer()->getRealTime() - initial_time) / 1000.0f;
|
||||
services->setVertexShaderConstant("time", &time, 1);
|
||||
services->setVertexShaderConstant("transparency", &m_transparency, 1);
|
||||
}
|
||||
|
||||
void onMadeVisible()
|
||||
{
|
||||
m_is_visible = true;
|
||||
}
|
||||
|
||||
void onHidden()
|
||||
{
|
||||
m_is_visible = false;
|
||||
m_transparency = 0.0f;
|
||||
}
|
||||
|
||||
void isInitiallyHidden()
|
||||
{
|
||||
m_is_visible = false;
|
||||
m_transparency = 0.0f;
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Create a new material using the parameters specified in the xml file.
|
||||
* \param node Node containing the parameters for this material.
|
||||
@ -430,7 +86,8 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
else if (s=="" || s=="none")
|
||||
m_adjust_image = ADJ_NONE;
|
||||
else
|
||||
printf("Incorrect adjust-image specification: '%s' - ignored.\n",
|
||||
Log::warn("material",
|
||||
"Incorrect adjust-image specification: '%s' - ignored.",
|
||||
s.c_str());
|
||||
node->get("alpha", &m_alpha_blending );
|
||||
node->get("light", &m_lighting );
|
||||
@ -458,9 +115,14 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
{
|
||||
m_collision_reaction = PUSH_BACK;
|
||||
}
|
||||
else if (creaction == "push-soccer")
|
||||
{
|
||||
m_collision_reaction = PUSH_SOCCER_BALL;
|
||||
}
|
||||
else if (creaction.size() > 0)
|
||||
{
|
||||
fprintf(stderr, "[Material] WARNING: Unknown collision reaction '%s'\n", creaction.c_str());
|
||||
Log::warn("Material","Unknown collision reaction '%s'",
|
||||
creaction.c_str());
|
||||
}
|
||||
|
||||
node->get("below-surface", &m_below_surface );
|
||||
@ -562,15 +224,18 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
node->get("splatting-texture-2", &m_splatting_texture_2);
|
||||
node->get("splatting-texture-3", &m_splatting_texture_3);
|
||||
node->get("splatting-texture-4", &m_splatting_texture_4);
|
||||
node->get("splatting-lightmap", &m_splatting_lightmap);
|
||||
}
|
||||
else if (s == "caustics")
|
||||
{
|
||||
m_graphical_effect = GE_CAUSTICS;
|
||||
}
|
||||
else if (s == "none")
|
||||
{
|
||||
}
|
||||
else if (s != "")
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Invalid graphical effect specification: '%s' - ignored.\n",
|
||||
Log::warn("material",
|
||||
"Invalid graphical effect specification: '%s' - ignored.",
|
||||
s.c_str());
|
||||
}
|
||||
else
|
||||
@ -591,7 +256,8 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "[Material] WARNING: could not find normal map image in materials.xml\n");
|
||||
Log::warn("material",
|
||||
"Could not find normal map image in materials.xml");
|
||||
}
|
||||
|
||||
node->get("normal-light-map", &m_normal_map_shader_lightmap);
|
||||
@ -614,8 +280,7 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
else if (s == "additive") m_add = true;
|
||||
else if (s == "coverage") m_alpha_to_coverage = true;
|
||||
else if (s != "none")
|
||||
fprintf(stderr,
|
||||
"[Material] WARNING: Unknown compositing mode '%s'\n",
|
||||
Log::warn("material", "Unknown compositing mode '%s'",
|
||||
s.c_str());
|
||||
}
|
||||
|
||||
@ -661,9 +326,8 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[Material] WARNING: unknown node type '%s' for texture "
|
||||
"'%s' - ignored.\n",
|
||||
Log::warn("material", "Unknown node type '%s' for texture "
|
||||
"'%s' - ignored.",
|
||||
child_node->getName().c_str(), m_texname.c_str());
|
||||
}
|
||||
|
||||
@ -735,8 +399,6 @@ void Material::init(unsigned int index)
|
||||
m_water_splash = false;
|
||||
m_is_jump_texture = false;
|
||||
|
||||
m_shaders.resize(SHADER_COUNT, NULL);
|
||||
|
||||
for (int n=0; n<EMIT_KINDS_COUNT; n++)
|
||||
{
|
||||
m_particles_effects[n] = NULL;
|
||||
@ -752,14 +414,16 @@ void Material::install(bool is_full_path, bool complain_if_not_found)
|
||||
|
||||
if (complain_if_not_found && full_path.size() == 0)
|
||||
{
|
||||
fprintf(stderr, "[Material] WARNING, cannot find texture '%s'\n", m_texname.c_str());
|
||||
Log::error("material", "Cannot find texture '%s'.", m_texname.c_str());
|
||||
m_texture = NULL;
|
||||
}
|
||||
|
||||
|
||||
else
|
||||
{
|
||||
m_texture = irr_driver->getTexture(full_path,
|
||||
isPreMul(),
|
||||
isPreDiv(),
|
||||
complain_if_not_found);
|
||||
}
|
||||
|
||||
if (m_texture == NULL) return;
|
||||
|
||||
@ -776,9 +440,8 @@ void Material::install(bool is_full_path, bool complain_if_not_found)
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Applying mask failed for '%s'!\n",
|
||||
Log::warn("material", "Applying mask failed for '%s'!",
|
||||
m_texname.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_texture->grab();
|
||||
@ -794,20 +457,6 @@ Material::~Material()
|
||||
irr_driver->removeTexture(m_texture);
|
||||
}
|
||||
|
||||
for (unsigned int n=0; n<m_shaders.size(); n++)
|
||||
{
|
||||
if (m_shaders[n])
|
||||
{
|
||||
m_shaders[n]->drop();
|
||||
}
|
||||
}
|
||||
|
||||
for (std::map<scene::IMeshBuffer*, BubbleEffectProvider*>::iterator it = m_bubble_provider.begin();
|
||||
it != m_bubble_provider.end(); it++)
|
||||
{
|
||||
it->second->drop();
|
||||
}
|
||||
|
||||
// If a special sfx is installed (that isn't part of stk itself), the
|
||||
// entry needs to be removed from the sfx_manager's mapping, since other
|
||||
// tracks might use the same name.
|
||||
@ -830,8 +479,8 @@ void Material::initCustomSFX(const XMLNode *sfx)
|
||||
|
||||
if (filename.empty())
|
||||
{
|
||||
fprintf(stderr, "[Material] WARNING: sfx node has no 'filename' "
|
||||
"attribute, sound effect will be ignored\n");
|
||||
Log::warn("material", "Sfx node has no 'filename' "
|
||||
"attribute, sound effect will be ignored.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -909,9 +558,9 @@ void Material::initParticlesEffect(const XMLNode *node)
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
fprintf(stderr, "[Material::initParticlesEffect] WARNING: Particles "
|
||||
Log::warn("material", "initParticlesEffect: Particles "
|
||||
"'%s' for material '%s' are declared but not used "
|
||||
"(no emission condition set)\n",
|
||||
"(no emission condition set).",
|
||||
base.c_str(), m_texname.c_str());
|
||||
}
|
||||
|
||||
@ -927,8 +576,8 @@ void Material::initParticlesEffect(const XMLNode *node)
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "[Material::initParticlesEffect] WARNING: Unknown "
|
||||
"condition '%s' for material '%s'\n",
|
||||
Log::warn("material", "initParticlesEffect: Unknown "
|
||||
"condition '%s' for material '%s'",
|
||||
conditions[c].c_str(), m_texname.c_str());
|
||||
}
|
||||
}
|
||||
@ -938,8 +587,9 @@ void Material::initParticlesEffect(const XMLNode *node)
|
||||
/** Adjusts the pitch of the given sfx depending on the given speed.
|
||||
* \param sfx The sound effect to adjust.
|
||||
* \param speed The speed of the kart.
|
||||
* \param should_be_paused Pause for other reasons, i.e. kart is rescued.
|
||||
*/
|
||||
void Material::setSFXSpeed(SFXBase *sfx, float speed) const
|
||||
void Material::setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) const
|
||||
{
|
||||
// Still make a sound when driving backwards on the material.
|
||||
if (speed < 0) speed = -speed;
|
||||
@ -947,14 +597,14 @@ void Material::setSFXSpeed(SFXBase *sfx, float speed) const
|
||||
// If we paused it due to too low speed earlier, we can continue now.
|
||||
if (sfx->getStatus() == SFXManager::SFX_PAUSED)
|
||||
{
|
||||
if (speed<m_sfx_min_speed) return;
|
||||
if (speed<m_sfx_min_speed || should_be_paused == 1) return;
|
||||
// TODO: Do we first need to stop the sound completely so it
|
||||
// starts over?
|
||||
sfx->play();
|
||||
}
|
||||
else if (sfx->getStatus() == SFXManager::SFX_PLAYING)
|
||||
{
|
||||
if (speed<m_sfx_min_speed)
|
||||
if (speed<m_sfx_min_speed || should_be_paused == 1)
|
||||
{
|
||||
// Pausing it to differentiate with sounds that ended etc
|
||||
sfx->pause();
|
||||
@ -981,9 +631,12 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
// materials.xml, if you want to set flags for all surfaces, see
|
||||
// 'MaterialManager::setAllMaterialFlags'
|
||||
|
||||
if (m_deprecated || (m->getTexture(0) != NULL && ((core::stringc)m->getTexture(0)->getName()).find("deprecated") != -1))
|
||||
if (m_deprecated ||
|
||||
(m->getTexture(0) != NULL &&
|
||||
((core::stringc)m->getTexture(0)->getName()).find("deprecated") != -1))
|
||||
{
|
||||
fprintf(stderr, "WARNING: track uses deprecated texture <%s>\n", m_texname.c_str());
|
||||
Log::warn("material", "Track uses deprecated texture '%s'\n",
|
||||
m_texname.c_str());
|
||||
}
|
||||
|
||||
|
||||
@ -1022,24 +675,9 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
}
|
||||
if (m_smooth_reflection_shader)
|
||||
{
|
||||
IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||
if (UserConfigParams::m_pixel_shaders &&
|
||||
irr_driver->isGLSL())
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
if (m_shaders[SHADER_SPHERE_MAP] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_SPHERE_MAP] = new SphereMapProvider();
|
||||
}
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu =
|
||||
irr_driver->getVideoDriver()->getGPUProgrammingServices();
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir() + "spheremap.vert").c_str(),
|
||||
"main", video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir() + "spheremap.frag").c_str(),
|
||||
"main", video::EPST_PS_2_0,
|
||||
m_shaders[SHADER_SPHERE_MAP], video::EMT_SOLID_2_LAYER );
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
m->MaterialType = irr_driver->getShader(ES_SPHERE_MAP);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1058,6 +696,12 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
}
|
||||
}
|
||||
if (m_graphical_effect == GE_SPHERE_MAP)
|
||||
{
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_SPHERE_MAP);
|
||||
}
|
||||
else
|
||||
{
|
||||
m->MaterialType = video::EMT_SPHERE_MAP;
|
||||
|
||||
@ -1072,7 +716,8 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
modes++;
|
||||
}
|
||||
}
|
||||
#if !LIGHTMAP_VISUALISATION
|
||||
}
|
||||
|
||||
if (m_lightmap)
|
||||
{
|
||||
m->MaterialType = video::EMT_LIGHTMAP;
|
||||
@ -1083,7 +728,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
m->MaterialType = video::EMT_LIGHTMAP_ADD;
|
||||
modes++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_add)
|
||||
{
|
||||
//m->MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
||||
@ -1102,8 +747,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
if (m_graphical_effect == GE_NORMAL_MAP)
|
||||
{
|
||||
IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||
if (UserConfigParams::m_pixel_shaders &&
|
||||
irr_driver->isGLSL())
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
||||
if (m_is_heightmap)
|
||||
@ -1121,37 +765,9 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
with_lightmap = true;
|
||||
}
|
||||
|
||||
if (with_lightmap)
|
||||
{
|
||||
if (m_shaders[SHADER_NORMAL_MAP_WITH_LIGHTMAP] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_NORMAL_MAP_WITH_LIGHTMAP] =
|
||||
new NormalMapProvider(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_shaders[SHADER_NORMAL_MAP] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_NORMAL_MAP] = new NormalMapProvider(false);
|
||||
}
|
||||
}
|
||||
|
||||
const char* vertex_shader = "normalmap.vert";
|
||||
const char* pixel_shader = "normalmap.frag";
|
||||
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu =
|
||||
video_driver->getGPUProgrammingServices();
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir() + vertex_shader).c_str(),
|
||||
"main", video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir() + pixel_shader).c_str(),
|
||||
"main", video::EPST_PS_2_0,
|
||||
m_shaders[with_lightmap ? SHADER_NORMAL_MAP_WITH_LIGHTMAP
|
||||
: SHADER_NORMAL_MAP],
|
||||
video::EMT_SOLID_2_LAYER );
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
m->MaterialType = irr_driver->getShader(
|
||||
with_lightmap ? ES_NORMAL_MAP_LIGHTMAP : ES_NORMAL_MAP );
|
||||
m->Lighting = false;
|
||||
m->ZWriteEnable = true;
|
||||
|
||||
@ -1201,64 +817,20 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
}
|
||||
m->setTexture(5, tex);
|
||||
|
||||
if (m_splatting_lightmap.size() > 0)
|
||||
{
|
||||
tex = irr_driver->getTexture(m_splatting_lightmap);
|
||||
}
|
||||
m->setTexture(6, tex);
|
||||
|
||||
if (m_splatting_lightmap.size() > 0)
|
||||
{
|
||||
if (m_shaders[SHADER_SPLATTING_LIGHTMAP] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_SPLATTING_LIGHTMAP] =
|
||||
new SplattingProvider(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_shaders[SHADER_SPLATTING] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_SPLATTING] = new SplattingProvider(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu =
|
||||
irr_driver->getVideoDriver()->getGPUProgrammingServices();
|
||||
|
||||
if (m_splatting_lightmap.size() > 0)
|
||||
{
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir()
|
||||
+ "splatting_lightmap.vert").c_str(),
|
||||
"main",video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir()
|
||||
+ "splatting_lightmap.frag").c_str(),
|
||||
"main",video::EPST_PS_2_0,
|
||||
m_shaders[SHADER_SPLATTING_LIGHTMAP],
|
||||
video::EMT_SOLID );
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir()
|
||||
+ "splatting.vert").c_str(),
|
||||
"main",video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir()
|
||||
+ "splatting.frag").c_str(),
|
||||
"main",video::EPST_PS_2_0,
|
||||
m_shaders[SHADER_SPLATTING], video::EMT_SOLID );
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
}
|
||||
m->MaterialType = irr_driver->getShader(ES_SPLATTING);
|
||||
}
|
||||
else
|
||||
{
|
||||
m->MaterialType = video::EMT_SOLID;
|
||||
}
|
||||
}
|
||||
if (m_graphical_effect == GE_CAUSTICS && irr_driver->isGLSL())
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_CAUSTICS);
|
||||
|
||||
m->setTexture(1, irr_driver->getTexture((file_manager->getTextureDir() + "caustics.png").c_str()));
|
||||
}
|
||||
|
||||
|
||||
// Modify lightmap materials so that vertex colors are taken into account.
|
||||
@ -1275,26 +847,14 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
|
||||
if (m_graphical_effect == GE_BUBBLE && mb != NULL)
|
||||
{
|
||||
IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||
if (UserConfigParams::m_pixel_shaders &&
|
||||
irr_driver->isGLSL())
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
if (m_bubble_provider.find(mb) == m_bubble_provider.end())
|
||||
{
|
||||
m_bubble_provider[mb] = new BubbleEffectProvider();
|
||||
}
|
||||
BubbleEffectProvider * bubble = (BubbleEffectProvider *)
|
||||
irr_driver->getCallback(ES_BUBBLES);
|
||||
bubble->addBubble(mb);
|
||||
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu = video_driver->getGPUProgrammingServices();
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir() + "bubble.vert").c_str(),
|
||||
"main", video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir() + "bubble.frag").c_str(),
|
||||
"main", video::EPST_PS_2_0,
|
||||
m_bubble_provider[mb],
|
||||
(m_alpha_blending ? video::EMT_TRANSPARENT_ALPHA_CHANNEL
|
||||
: video::EMT_SOLID) );
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
m->MaterialType = irr_driver->getShader(ES_BUBBLES);
|
||||
m->BlendOperation = video::EBO_ADD;
|
||||
|
||||
// alpha blending and bubble shading can work together so when both are enabled
|
||||
// don't increment the 'modes' counter to not get the 'too many modes' warning
|
||||
@ -1308,72 +868,40 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
|
||||
if (m_graphical_effect == GE_WATER_SHADER)
|
||||
{
|
||||
IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||
if (UserConfigParams::m_pixel_shaders &&
|
||||
irr_driver->isGLSL())
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
if (m_shaders[SHADER_WATER] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_WATER] =
|
||||
new WaterShaderProvider(m_water_shader_speed_1,
|
||||
m_water_shader_speed_2);
|
||||
}
|
||||
|
||||
m->setTexture(1, irr_driver->getTexture(file_manager->getTextureFile("waternormals.jpg")));
|
||||
m->setTexture(2, irr_driver->getTexture(file_manager->getTextureFile("waternormals2.jpg")));
|
||||
|
||||
bool fog = World::getWorld()->getTrack()->isFogEnabled();
|
||||
const char* vertex_shader = (fog ? "water_fog.vert" : "water.vert");
|
||||
const char* pixel_shader = (fog ? "water_fog.frag" : "water.frag");
|
||||
((WaterShaderProvider *) irr_driver->getCallback(ES_WATER))->
|
||||
setSpeed(m_water_shader_speed_1/100.0f, m_water_shader_speed_2/100.0f);
|
||||
|
||||
((WaterShaderProvider*)m_shaders[SHADER_WATER])->enableFog(fog);
|
||||
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu =
|
||||
irr_driver->getVideoDriver()->getGPUProgrammingServices();
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir() + vertex_shader).c_str(),
|
||||
"main", video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir() + pixel_shader ).c_str(),
|
||||
"main", video::EPST_PS_2_0,
|
||||
m_shaders[SHADER_WATER],
|
||||
video::EMT_TRANSPARENT_ALPHA_CHANNEL);
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
m->MaterialType = irr_driver->getShader(ES_WATER);
|
||||
}
|
||||
modes++;
|
||||
}
|
||||
|
||||
if (m_graphical_effect == GE_GRASS)
|
||||
{
|
||||
IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||
if (UserConfigParams::m_pixel_shaders &&
|
||||
if (UserConfigParams::m_weather_effects &&
|
||||
irr_driver->isGLSL())
|
||||
{
|
||||
if (m_shaders[SHADER_GRASS] == NULL)
|
||||
{
|
||||
m_shaders[SHADER_GRASS] =
|
||||
new GrassShaderProvider(m_grass_amplitude, m_grass_speed);
|
||||
}
|
||||
|
||||
bool fog = World::getWorld()->getTrack()->isFogEnabled();
|
||||
((GrassShaderProvider*)m_shaders[SHADER_GRASS])->enableFog(fog);
|
||||
|
||||
grass_shaders_times[grass_shaders_times_index] = (rand() % 500)/500.0f * M_PI * 2.0f;
|
||||
// Only one grass speed & amplitude per map for now
|
||||
((GrassShaderProvider *) irr_driver->getCallback(ES_GRASS))->
|
||||
setSpeed(m_grass_speed);
|
||||
((GrassShaderProvider *) irr_driver->getCallback(ES_GRASS))->
|
||||
setAmplitude(m_grass_amplitude);
|
||||
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu =
|
||||
irr_driver->getVideoDriver()->getGPUProgrammingServices();
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir() + "grass.vert").c_str(),
|
||||
"main", video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir() + "grass.frag").c_str(),
|
||||
"main", video::EPST_PS_2_0,
|
||||
m_shaders[SHADER_GRASS],
|
||||
video::EMT_TRANSPARENT_ALPHA_CHANNEL,
|
||||
grass_shaders_times_index);
|
||||
m->MaterialType = (E_MATERIAL_TYPE)material_type;
|
||||
if (m_alpha_testing)
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_GRASS_REF);
|
||||
}
|
||||
else {
|
||||
m->MaterialType = irr_driver->getShader(ES_GRASS);
|
||||
m->BlendOperation = video::EBO_ADD;
|
||||
}
|
||||
|
||||
grass_shaders_times_index++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1468,6 +996,10 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
void Material::adjustForFog(scene::ISceneNode* parent, video::SMaterial *m,
|
||||
bool use_fog) const
|
||||
{
|
||||
// The new pipeline does fog as a post-process effect.
|
||||
if (irr_driver->isGLSL())
|
||||
return;
|
||||
|
||||
m->setFlag(video::EMF_FOG_ENABLE, m_fog && use_fog);
|
||||
|
||||
if (parent != NULL)
|
||||
@ -1481,10 +1013,13 @@ void Material::adjustForFog(scene::ISceneNode* parent, video::SMaterial *m,
|
||||
/** Callback from LOD nodes to create some effects */
|
||||
void Material::onMadeVisible(scene::IMeshBuffer* who)
|
||||
{
|
||||
if (m_bubble_provider.find(who) != m_bubble_provider.end())
|
||||
{
|
||||
m_bubble_provider[who]->onMadeVisible();
|
||||
}
|
||||
if (!irr_driver->isGLSL()) return;
|
||||
|
||||
BubbleEffectProvider * bubble = (BubbleEffectProvider *)
|
||||
irr_driver->getCallback(ES_BUBBLES);
|
||||
|
||||
if (bubble != NULL)
|
||||
bubble->onMadeVisible(who);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1492,20 +1027,24 @@ void Material::onMadeVisible(scene::IMeshBuffer* who)
|
||||
/** Callback from LOD nodes to create some effects */
|
||||
void Material::onHidden(scene::IMeshBuffer* who)
|
||||
{
|
||||
if (m_bubble_provider.find(who) != m_bubble_provider.end())
|
||||
{
|
||||
m_bubble_provider[who]->onHidden();
|
||||
}
|
||||
if (!irr_driver->isGLSL()) return;
|
||||
|
||||
BubbleEffectProvider * bubble = (BubbleEffectProvider *)
|
||||
irr_driver->getCallback(ES_BUBBLES);
|
||||
if (bubble != NULL)
|
||||
bubble->onHidden(who);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Material::isInitiallyHidden(scene::IMeshBuffer* who)
|
||||
{
|
||||
if (m_bubble_provider.find(who) != m_bubble_provider.end())
|
||||
{
|
||||
m_bubble_provider[who]->isInitiallyHidden();
|
||||
}
|
||||
if (!irr_driver->isGLSL()) return;
|
||||
|
||||
BubbleEffectProvider * bubble = (BubbleEffectProvider *)
|
||||
irr_driver->getCallback(ES_BUBBLES);
|
||||
if (bubble != NULL)
|
||||
bubble->isInitiallyHidden(who);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1,6 +1,7 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2010-2013 Steve Baker, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -27,8 +28,6 @@
|
||||
|
||||
#include <IShaderConstantSetCallBack.h>
|
||||
|
||||
#define LIGHTMAP_VISUALISATION 0
|
||||
|
||||
|
||||
namespace irr
|
||||
{
|
||||
@ -41,10 +40,6 @@ class XMLNode;
|
||||
class SFXBase;
|
||||
class ParticleKind;
|
||||
|
||||
class NormalMapProvider;
|
||||
class SplattingProvider;
|
||||
class BubbleEffectProvider;
|
||||
|
||||
/**
|
||||
* \ingroup graphics
|
||||
*/
|
||||
@ -59,7 +54,8 @@ public:
|
||||
GE_WATER_SHADER,
|
||||
GE_SPHERE_MAP,
|
||||
GE_SPLATTING,
|
||||
GE_NORMAL_MAP};
|
||||
GE_NORMAL_MAP,
|
||||
GE_CAUSTICS};
|
||||
|
||||
enum ParticleConditions
|
||||
{
|
||||
@ -73,23 +69,12 @@ public:
|
||||
{
|
||||
NORMAL,
|
||||
RESCUE,
|
||||
PUSH_BACK
|
||||
PUSH_BACK,
|
||||
PUSH_SOCCER_BALL
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
enum Shaders
|
||||
{
|
||||
SHADER_NORMAL_MAP,
|
||||
SHADER_NORMAL_MAP_WITH_LIGHTMAP,
|
||||
SHADER_SPLATTING,
|
||||
SHADER_WATER,
|
||||
SHADER_SPHERE_MAP,
|
||||
SHADER_SPLATTING_LIGHTMAP,
|
||||
SHADER_GRASS,
|
||||
SHADER_COUNT
|
||||
};
|
||||
|
||||
video::ITexture *m_texture;
|
||||
unsigned int m_index;
|
||||
std::string m_texname;
|
||||
@ -232,13 +217,6 @@ private:
|
||||
/** If m_splatting is true, indicates the fourth splatting texture */
|
||||
std::string m_splatting_texture_4;
|
||||
|
||||
std::string m_splatting_lightmap;
|
||||
|
||||
std::vector<irr::video::IShaderConstantSetCallBack*> m_shaders;
|
||||
|
||||
/** Only used if bubble effect is enabled */
|
||||
std::map<scene::IMeshBuffer*, BubbleEffectProvider*> m_bubble_provider;
|
||||
|
||||
bool m_deprecated;
|
||||
|
||||
void init (unsigned int index);
|
||||
@ -253,7 +231,7 @@ public:
|
||||
bool complain_if_not_found=true);
|
||||
~Material ();
|
||||
|
||||
void setSFXSpeed(SFXBase *sfx, float speed) const;
|
||||
void setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) const;
|
||||
void setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* mb);
|
||||
void adjustForFog(scene::ISceneNode* parent, video::SMaterial *m, bool use_fog) const;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2004-2013 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2010-2013 Steve Baker, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -59,10 +60,6 @@ MaterialManager::~MaterialManager()
|
||||
m_materials.clear();
|
||||
} // ~MaterialManager
|
||||
|
||||
#if LIGHTMAP_VISUALISATION
|
||||
std::set<scene::IMeshBuffer*> g_processed;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Material* MaterialManager::getMaterialFor(video::ITexture* t,
|
||||
|
@ -1,6 +1,7 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2004-2013 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2010-2013 Steve Baker, Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Joerg Henrichs
|
||||
// Copyright (C) 2009-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2009 Joerg Henrichs
|
||||
// Copyright (C) 2009-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
200
src/graphics/mlaa_areamap.hpp
Normal file
200
src/graphics/mlaa_areamap.hpp
Normal file
@ -0,0 +1,200 @@
|
||||
#ifndef AREAMAP_H
|
||||
#define AREAMAP_H
|
||||
|
||||
static const unsigned char AreaMap33[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa5,
|
||||
0x08, 0x04, 0x00, 0x00, 0x00, 0x97, 0x22, 0xf5, 0x51, 0x00, 0x00, 0x00,
|
||||
0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
|
||||
0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x87, 0x8f, 0xcc, 0xbf,
|
||||
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13,
|
||||
0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00,
|
||||
0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, 0x07, 0x09, 0x17, 0x12,
|
||||
0x5f, 0x51, 0x45, 0x04, 0x00, 0x00, 0x08, 0x87, 0x49, 0x44, 0x41, 0x54,
|
||||
0x78, 0xda, 0xed, 0x5d, 0x4b, 0x6e, 0xdb, 0x48, 0x14, 0x2c, 0x89, 0x2f,
|
||||
0x4e, 0xe2, 0x09, 0x30, 0x9b, 0x38, 0x5b, 0xf9, 0x24, 0x73, 0xbb, 0xb9,
|
||||
0x49, 0x6e, 0x32, 0x67, 0x98, 0x7d, 0xbc, 0xf2, 0xc2, 0x18, 0x78, 0x31,
|
||||
0x81, 0xc6, 0xa6, 0xc4, 0xd7, 0xc3, 0x8f, 0x1a, 0x0d, 0x9a, 0x92, 0x5b,
|
||||
0x64, 0x91, 0x7a, 0x1d, 0xa1, 0xab, 0x41, 0x28, 0x41, 0x80, 0x42, 0xd5,
|
||||
0x63, 0x93, 0x32, 0x9c, 0x42, 0x35, 0xc0, 0x63, 0x03, 0x73, 0x6c, 0x60,
|
||||
0x8f, 0x35, 0x78, 0xdc, 0xe3, 0x16, 0x2c, 0x78, 0x09, 0x57, 0x31, 0xca,
|
||||
0x6f, 0xb8, 0xc3, 0x0d, 0x68, 0xd8, 0x4b, 0xb0, 0x1f, 0xe5, 0x2d, 0xbe,
|
||||
0xe2, 0x77, 0x08, 0x48, 0xd8, 0x4b, 0xb0, 0x1f, 0xe5, 0x47, 0x7c, 0xa9,
|
||||
0x7d, 0xfc, 0x86, 0x02, 0x06, 0x48, 0x46, 0x02, 0x64, 0x16, 0x8e, 0xcf,
|
||||
0xb5, 0x8b, 0x17, 0x54, 0xd8, 0x42, 0x41, 0xc0, 0x5a, 0x82, 0xfd, 0x28,
|
||||
0x0b, 0x7c, 0xac, 0x9d, 0xdc, 0x62, 0x07, 0xc5, 0x0b, 0xe1, 0xc4, 0x5c,
|
||||
0x82, 0xfd, 0x28, 0xd7, 0xb8, 0xa9, 0x9d, 0x7c, 0xc2, 0x2b, 0xf6, 0x70,
|
||||
0x78, 0x25, 0x9c, 0x98, 0x4b, 0xb0, 0x1f, 0xa5, 0x1c, 0x9c, 0xec, 0xa1,
|
||||
0x50, 0x94, 0x70, 0x20, 0x60, 0x27, 0xc1, 0x7e, 0x94, 0x2b, 0x14, 0xf8,
|
||||
0x50, 0xaf, 0xda, 0x4b, 0xeb, 0x04, 0x84, 0x13, 0x73, 0x09, 0xf6, 0xa3,
|
||||
0x94, 0xd6, 0x47, 0x59, 0x3b, 0x51, 0x28, 0x1c, 0x76, 0x84, 0x13, 0x53,
|
||||
0x09, 0xf6, 0xa3, 0x2c, 0xf0, 0xa1, 0xf5, 0xb2, 0xc7, 0xbe, 0xf5, 0xe1,
|
||||
0xb0, 0x27, 0x9c, 0x98, 0x49, 0xb0, 0x1f, 0xe5, 0x1a, 0xd2, 0x38, 0xf1,
|
||||
0x3e, 0x5a, 0x27, 0x20, 0x9c, 0x18, 0x4a, 0xb0, 0x1f, 0x65, 0xe7, 0x44,
|
||||
0xda, 0x6d, 0x51, 0x1d, 0x9c, 0x38, 0x54, 0x84, 0x13, 0x13, 0x09, 0xf6,
|
||||
0xa3, 0xf4, 0x4e, 0xe4, 0xe0, 0xc4, 0xfb, 0x00, 0xe1, 0xc4, 0x40, 0x82,
|
||||
0xfd, 0x28, 0x81, 0x35, 0x8a, 0x6e, 0xb5, 0x3e, 0x2a, 0x54, 0x84, 0x13,
|
||||
0x53, 0x09, 0xf6, 0xbb, 0xd2, 0x6f, 0x8a, 0xe0, 0x26, 0xf8, 0x70, 0xa8,
|
||||
0xc0, 0x23, 0x7d, 0x09, 0x90, 0x79, 0x9c, 0xf4, 0x3c, 0x54, 0xa8, 0xda,
|
||||
0x4f, 0x77, 0x58, 0x20, 0x9c, 0x18, 0x48, 0xb0, 0x1f, 0xa5, 0xf7, 0xb2,
|
||||
0x46, 0xd8, 0x14, 0xda, 0xba, 0x00, 0xe1, 0xc4, 0x48, 0x82, 0xfd, 0x03,
|
||||
0x1e, 0x9e, 0x30, 0x6d, 0x2f, 0x47, 0x6c, 0x8b, 0x5f, 0x4d, 0x02, 0x64,
|
||||
0x36, 0x27, 0xc1, 0xc5, 0x3a, 0xf8, 0x68, 0x2e, 0x62, 0x5b, 0x18, 0x48,
|
||||
0xb0, 0x1e, 0x25, 0x06, 0x9b, 0xa2, 0x7a, 0xe3, 0xc3, 0x2d, 0xe8, 0x84,
|
||||
0x90, 0x90, 0xe6, 0xbb, 0xb2, 0xbf, 0x0a, 0x68, 0xbb, 0x0a, 0xb8, 0x76,
|
||||
0x15, 0x40, 0xfb, 0xa9, 0x60, 0xc1, 0x4b, 0x48, 0xfb, 0x5d, 0x39, 0xd8,
|
||||
0x14, 0x55, 0xf7, 0x19, 0x5e, 0x54, 0x07, 0x2f, 0x20, 0x9c, 0x18, 0x48,
|
||||
0xb0, 0x7a, 0xc0, 0xfb, 0x4e, 0xb4, 0x59, 0xfe, 0x6f, 0xde, 0x05, 0xe1,
|
||||
0x24, 0x79, 0x09, 0x32, 0xf3, 0x17, 0xa8, 0x77, 0x12, 0xf4, 0xf7, 0x9f,
|
||||
0x2e, 0x47, 0x38, 0x31, 0x90, 0x60, 0xbd, 0x2b, 0x87, 0xab, 0xf0, 0x5e,
|
||||
0x88, 0x6d, 0x91, 0xbc, 0x04, 0x99, 0xd7, 0xc5, 0x09, 0x2f, 0xae, 0xbd,
|
||||
0xc2, 0x96, 0x70, 0x11, 0x27, 0x56, 0x12, 0xec, 0xbf, 0x76, 0x06, 0x4f,
|
||||
0x58, 0x70, 0x13, 0x5e, 0x53, 0x7d, 0x17, 0x88, 0x38, 0xb1, 0x95, 0x60,
|
||||
0xbf, 0x2b, 0x7b, 0x0e, 0x56, 0x6f, 0x36, 0x44, 0xe1, 0x5d, 0xb4, 0x9f,
|
||||
0x8e, 0x70, 0x62, 0x20, 0xc1, 0xe0, 0x5d, 0x79, 0xf4, 0x09, 0x53, 0xac,
|
||||
0xfb, 0xef, 0x7d, 0x62, 0x5b, 0x24, 0x2c, 0x41, 0xe6, 0x77, 0x32, 0xfc,
|
||||
0x1a, 0xed, 0xd4, 0x7b, 0x3f, 0xde, 0x07, 0xe1, 0x24, 0x49, 0x09, 0x32,
|
||||
0xf7, 0x4f, 0xc8, 0xde, 0x4b, 0xcf, 0x55, 0x70, 0xb1, 0x1e, 0xf8, 0x70,
|
||||
0x70, 0xd7, 0x21, 0x61, 0x85, 0x0d, 0xee, 0xf1, 0x0d, 0xb7, 0xf8, 0x08,
|
||||
0x41, 0x71, 0xb8, 0x9d, 0x61, 0x85, 0x37, 0x3a, 0xfc, 0xe7, 0xe0, 0x4f,
|
||||
0x7f, 0x61, 0x45, 0x32, 0xfc, 0x09, 0x12, 0x9b, 0xcd, 0x03, 0xe9, 0x62,
|
||||
0xf3, 0x9d, 0x65, 0x10, 0x3c, 0xe0, 0x09, 0x77, 0xf8, 0x8a, 0x2f, 0xf8,
|
||||
0x5c, 0xd3, 0xdc, 0xb4, 0x44, 0x85, 0x27, 0xeb, 0x11, 0x22, 0x90, 0xf6,
|
||||
0xc8, 0x57, 0xf8, 0x1b, 0x3f, 0x28, 0x06, 0x1a, 0xf7, 0x0f, 0x4f, 0x4f,
|
||||
0x5b, 0xca, 0x05, 0xcf, 0x20, 0x00, 0xb6, 0x78, 0xc4, 0xb6, 0xcd, 0xd4,
|
||||
0x75, 0x24, 0x1f, 0x5a, 0x1a, 0x69, 0x49, 0x8a, 0x37, 0x3f, 0x5d, 0xe0,
|
||||
0x08, 0xe1, 0x37, 0xfc, 0xc0, 0x3f, 0x0c, 0xc3, 0x2c, 0x51, 0xd5, 0xed,
|
||||
0xe3, 0x63, 0x49, 0x68, 0xe0, 0x19, 0x04, 0x0d, 0x4a, 0x3c, 0xd7, 0xd7,
|
||||
0x0b, 0x6e, 0xf1, 0xa9, 0x26, 0xf9, 0xd0, 0xae, 0x8e, 0xa4, 0xe8, 0xd1,
|
||||
0xd4, 0xd7, 0x60, 0x75, 0x39, 0xd1, 0x2d, 0xfe, 0x25, 0x18, 0x38, 0x78,
|
||||
0x09, 0xe5, 0xf3, 0xf3, 0x7e, 0xb2, 0x06, 0x9e, 0x41, 0xd0, 0x61, 0x8f,
|
||||
0x9f, 0xa8, 0xb0, 0xc3, 0x6b, 0x4d, 0x72, 0x53, 0x2f, 0x39, 0x90, 0x14,
|
||||
0x07, 0x1a, 0xbf, 0x56, 0x43, 0xa2, 0x43, 0x4e, 0xb4, 0xc4, 0x7f, 0x93,
|
||||
0x19, 0x58, 0x78, 0x09, 0xfb, 0x9f, 0x3f, 0xab, 0x89, 0x1a, 0x78, 0x06,
|
||||
0x81, 0x47, 0x97, 0xf2, 0xdc, 0xd7, 0xeb, 0x23, 0xca, 0xf6, 0x7e, 0x88,
|
||||
0x7f, 0x5f, 0xf4, 0x49, 0x06, 0xf7, 0xe5, 0x16, 0x3e, 0x27, 0xfa, 0x32,
|
||||
0x8d, 0x61, 0xc6, 0xa8, 0x6a, 0xb5, 0xdd, 0xea, 0x24, 0x0d, 0x73, 0x30,
|
||||
0x04, 0x68, 0xcd, 0xe4, 0xa0, 0x0d, 0x49, 0x4b, 0x25, 0x81, 0x24, 0xdc,
|
||||
0x93, 0x01, 0xc9, 0xba, 0x97, 0x13, 0x2d, 0xa7, 0x30, 0xcc, 0x1a, 0x55,
|
||||
0xd5, 0x97, 0x17, 0x9d, 0xa0, 0x81, 0x67, 0x90, 0x9e, 0x22, 0xc5, 0x2b,
|
||||
0xb4, 0x59, 0x2d, 0x85, 0xbf, 0x1f, 0xd2, 0x12, 0x78, 0x8a, 0x21, 0x4d,
|
||||
0x3f, 0x27, 0xba, 0x1b, 0xcf, 0x30, 0x73, 0x54, 0x55, 0x5f, 0x5f, 0x75,
|
||||
0xb4, 0x06, 0x9e, 0x41, 0xd0, 0x87, 0xa2, 0x04, 0xd0, 0xd1, 0x54, 0x6d,
|
||||
0xf8, 0xa6, 0x40, 0xd5, 0x11, 0x9c, 0x22, 0x19, 0xe4, 0x44, 0x77, 0x63,
|
||||
0x19, 0x66, 0x8f, 0xaa, 0x6a, 0x59, 0xba, 0x91, 0x1a, 0x78, 0x06, 0xc1,
|
||||
0x5b, 0x38, 0x94, 0x70, 0xf5, 0xf2, 0x34, 0xd2, 0x50, 0x44, 0xb6, 0xf7,
|
||||
0xdb, 0x9c, 0xe8, 0x6e, 0x1c, 0xc3, 0x02, 0x51, 0x55, 0x57, 0x8f, 0x62,
|
||||
0x94, 0x06, 0x9e, 0x41, 0x30, 0x84, 0xeb, 0x8d, 0x42, 0xfd, 0xff, 0xce,
|
||||
0xfb, 0x3b, 0xe3, 0x29, 0x02, 0xd1, 0x91, 0x9c, 0xe8, 0x7e, 0x0c, 0xc3,
|
||||
0x22, 0x51, 0x55, 0xb7, 0xdb, 0xb9, 0x11, 0x1a, 0x78, 0x06, 0xc1, 0x11,
|
||||
0xb4, 0xa3, 0x00, 0x3c, 0x8d, 0x34, 0x34, 0xed, 0x52, 0xac, 0x9b, 0xab,
|
||||
0x4f, 0x72, 0x22, 0x27, 0x5a, 0xa1, 0x3c, 0x97, 0x61, 0xa1, 0xa8, 0xaa,
|
||||
0xdb, 0xef, 0xdd, 0xd9, 0x2e, 0x78, 0x06, 0xc1, 0x71, 0x74, 0xfb, 0xca,
|
||||
0x2f, 0xf5, 0x2b, 0x50, 0x04, 0xa2, 0x13, 0x39, 0xd1, 0x12, 0xd5, 0xb9,
|
||||
0x0c, 0x8b, 0x45, 0x55, 0x9b, 0x51, 0x9c, 0xa9, 0x81, 0x67, 0x10, 0x1c,
|
||||
0x87, 0x8f, 0x7f, 0x79, 0x0a, 0xff, 0x59, 0x34, 0x57, 0x9f, 0xe2, 0x9d,
|
||||
0x9c, 0xa8, 0x62, 0x77, 0x0e, 0xc3, 0x82, 0x51, 0x55, 0x57, 0x55, 0xee,
|
||||
0x2c, 0x17, 0x3c, 0x83, 0x00, 0x91, 0x61, 0x06, 0x1a, 0x45, 0xd1, 0xfd,
|
||||
0x8e, 0xaa, 0x4f, 0xf1, 0x4e, 0x4e, 0x74, 0x07, 0xc5, 0x3e, 0xce, 0xb0,
|
||||
0x68, 0x54, 0xb5, 0x1d, 0x45, 0x5c, 0x03, 0xcf, 0x20, 0x40, 0x64, 0x98,
|
||||
0x2d, 0x1b, 0x9c, 0x5f, 0x03, 0x8a, 0xf5, 0xbb, 0x39, 0xd1, 0x3d, 0x14,
|
||||
0xbb, 0x18, 0xc3, 0x62, 0x51, 0xd5, 0x30, 0x8a, 0xa8, 0x0b, 0x9e, 0x41,
|
||||
0x80, 0xe8, 0x30, 0x71, 0x94, 0xa2, 0x80, 0xeb, 0xde, 0x17, 0x91, 0x9c,
|
||||
0xe8, 0x2e, 0xce, 0xb0, 0x78, 0x54, 0xd5, 0x55, 0x51, 0x0d, 0x3c, 0x83,
|
||||
0x20, 0x8e, 0xaa, 0xa5, 0xf0, 0x44, 0x45, 0x77, 0x75, 0x44, 0xed, 0x67,
|
||||
0x3c, 0x27, 0x1a, 0x67, 0x58, 0x3e, 0xaa, 0x1a, 0xd1, 0xc0, 0x33, 0x08,
|
||||
0xce, 0x81, 0xbf, 0x23, 0x05, 0xd0, 0x11, 0xf4, 0x62, 0x0f, 0x91, 0x9c,
|
||||
0x68, 0x9c, 0xe1, 0x42, 0x51, 0xd5, 0x88, 0x06, 0x96, 0x41, 0x80, 0x11,
|
||||
0xc3, 0x0c, 0x34, 0xcd, 0xea, 0x48, 0xf4, 0x9c, 0x9c, 0x68, 0x84, 0xe1,
|
||||
0x52, 0x51, 0xd5, 0x77, 0x34, 0xf0, 0x0c, 0x82, 0x73, 0x51, 0xf5, 0xee,
|
||||
0x87, 0x27, 0x51, 0xac, 0xe3, 0x39, 0xd1, 0x18, 0xc3, 0x05, 0xa3, 0xaa,
|
||||
0x27, 0x35, 0xf0, 0x0c, 0x82, 0xf3, 0x51, 0x21, 0x44, 0x1b, 0x3c, 0xf7,
|
||||
0x1a, 0xee, 0xbc, 0x9c, 0x68, 0x84, 0xe1, 0x72, 0x51, 0xd5, 0x13, 0x1a,
|
||||
0x78, 0x06, 0xc1, 0x18, 0x28, 0x02, 0x05, 0x0e, 0x44, 0xeb, 0xb1, 0x39,
|
||||
0xd1, 0x21, 0xc3, 0x85, 0xa3, 0xaa, 0x47, 0x35, 0xf0, 0x0c, 0x82, 0x71,
|
||||
0x50, 0x04, 0xb8, 0x6e, 0x11, 0x39, 0x51, 0xff, 0xaf, 0x97, 0x8e, 0xaa,
|
||||
0x1e, 0xd1, 0xc0, 0x33, 0x08, 0x30, 0x71, 0x98, 0xce, 0xaf, 0xa9, 0x39,
|
||||
0xd1, 0xc0, 0x60, 0x10, 0x55, 0x1d, 0x68, 0xe0, 0x19, 0x04, 0x98, 0x34,
|
||||
0x4c, 0x47, 0xe7, 0x44, 0x9d, 0x71, 0x54, 0xd5, 0x6b, 0x20, 0x19, 0xd8,
|
||||
0xa0, 0x8b, 0xf6, 0xee, 0xc7, 0xc4, 0x9c, 0x68, 0x60, 0x30, 0x8a, 0xaa,
|
||||
0xf6, 0x34, 0xf0, 0x0c, 0x82, 0x69, 0xd0, 0xab, 0x88, 0xaa, 0xea, 0x9c,
|
||||
0x0c, 0x82, 0xa9, 0xd0, 0xab, 0x88, 0xaa, 0xea, 0x7c, 0x0c, 0x42, 0xe8,
|
||||
0xd7, 0xab, 0x88, 0xaa, 0xea, 0x5c, 0x0c, 0x02, 0x06, 0x7a, 0x15, 0x51,
|
||||
0x55, 0x9d, 0x87, 0x41, 0xc0, 0x41, 0xe1, 0xe8, 0x9c, 0xa8, 0x33, 0x8f,
|
||||
0xaa, 0x2a, 0x1c, 0xcf, 0x20, 0x60, 0xe1, 0xae, 0x22, 0xaa, 0xea, 0xc0,
|
||||
0x33, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
|
||||
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
|
||||
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
|
||||
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x83, 0x15, 0x5f, 0xaa,
|
||||
0xfa, 0x7d, 0x73, 0xff, 0x60, 0x5c, 0xaa, 0x8a, 0x3f, 0xb0, 0x32, 0x77,
|
||||
0x21, 0x7c, 0xa9, 0xea, 0xc3, 0xfd, 0xd3, 0xd3, 0xdd, 0x96, 0x61, 0xe0,
|
||||
0xc1, 0x17, 0xbb, 0xf2, 0x2e, 0x84, 0x2f, 0x55, 0xc5, 0xb7, 0xed, 0xdd,
|
||||
0xe3, 0xe3, 0xb6, 0x24, 0x18, 0x68, 0xf0, 0xc5, 0xae, 0xbc, 0x0b, 0x61,
|
||||
0x4b, 0x55, 0xbb, 0x4a, 0xd3, 0x72, 0xfb, 0xfc, 0x5c, 0xee, 0x8d, 0x4a,
|
||||
0x55, 0x43, 0xb1, 0xab, 0xa9, 0x0b, 0xe1, 0x4b, 0x55, 0xbb, 0x4a, 0xd3,
|
||||
0x7d, 0xd9, 0xf4, 0x91, 0x1a, 0x95, 0xaa, 0x86, 0x62, 0x57, 0x43, 0x17,
|
||||
0xc2, 0x97, 0xaa, 0xfa, 0x4a, 0xd3, 0xae, 0x8f, 0x74, 0x0a, 0x03, 0x0f,
|
||||
0xa1, 0x8b, 0x5d, 0x79, 0x17, 0xc2, 0x97, 0xaa, 0x86, 0x4a, 0xd3, 0xa6,
|
||||
0x8f, 0xd4, 0xe9, 0x78, 0x06, 0x1e, 0x7c, 0xb1, 0x2b, 0xef, 0x42, 0xe8,
|
||||
0x52, 0xd5, 0x5e, 0xa5, 0xa9, 0xba, 0xa6, 0x8f, 0x74, 0x2c, 0x03, 0x0f,
|
||||
0xbe, 0xd8, 0x95, 0x77, 0x21, 0x7c, 0xa9, 0x6a, 0xbf, 0xd2, 0x54, 0xb5,
|
||||
0x2c, 0xe1, 0xc6, 0x31, 0xf0, 0xe0, 0x8b, 0x5d, 0x79, 0x17, 0x42, 0x97,
|
||||
0xaa, 0x0e, 0x2a, 0x4d, 0x1d, 0x9a, 0x3e, 0xd2, 0x31, 0x0c, 0x3c, 0xf8,
|
||||
0x62, 0x57, 0xde, 0x85, 0xf0, 0xa5, 0xaa, 0xc3, 0x4a, 0xd3, 0xae, 0x8f,
|
||||
0x74, 0x04, 0x03, 0x0d, 0xbe, 0xd8, 0x95, 0x77, 0x21, 0x74, 0xa9, 0xea,
|
||||
0xd1, 0x4a, 0xd3, 0xa6, 0x8f, 0x14, 0xee, 0x5c, 0x06, 0x1e, 0x7c, 0xb1,
|
||||
0x2b, 0xef, 0x42, 0xe8, 0x52, 0xd5, 0x13, 0x95, 0xa6, 0x0e, 0x4d, 0x1f,
|
||||
0xe9, 0x79, 0x0c, 0x3c, 0xf8, 0x62, 0x57, 0xde, 0x85, 0xd0, 0xa5, 0xaa,
|
||||
0x27, 0x2b, 0x4d, 0xdb, 0xa2, 0x42, 0x77, 0x0e, 0x03, 0x0f, 0xbe, 0xd8,
|
||||
0x95, 0x77, 0x21, 0x7c, 0xa9, 0xea, 0xe9, 0x4a, 0x53, 0x87, 0x46, 0x46,
|
||||
0x9c, 0x81, 0x07, 0x5f, 0xec, 0xca, 0xbb, 0x10, 0xba, 0x54, 0xf5, 0x44,
|
||||
0xa5, 0x69, 0x90, 0xe1, 0x5c, 0x8c, 0x81, 0x07, 0x5f, 0xec, 0xca, 0xbb,
|
||||
0x10, 0xba, 0x54, 0x35, 0x52, 0x69, 0xda, 0x3c, 0x20, 0x31, 0x06, 0x1e,
|
||||
0x7c, 0xb1, 0x2b, 0xef, 0x42, 0xf8, 0x52, 0xd5, 0x78, 0xa5, 0x69, 0x55,
|
||||
0x45, 0x18, 0x48, 0x44, 0x25, 0x5c, 0xc4, 0x85, 0xf0, 0xa5, 0xaa, 0xf1,
|
||||
0x4a, 0xd3, 0x46, 0x46, 0x84, 0x81, 0x44, 0x5c, 0xc2, 0xf2, 0x2e, 0x84,
|
||||
0x2e, 0x55, 0x3d, 0xb3, 0xd2, 0xb4, 0xaa, 0x4e, 0x32, 0xcc, 0xf5, 0x80,
|
||||
0x47, 0x24, 0x2c, 0xed, 0x42, 0xe8, 0x52, 0xd5, 0xb3, 0x2b, 0x4d, 0xab,
|
||||
0x6a, 0xb9, 0x52, 0xd5, 0xb8, 0x84, 0xe5, 0x5d, 0x08, 0x5d, 0xaa, 0x3a,
|
||||
0xa2, 0xd2, 0xb4, 0xaa, 0x16, 0x2c, 0x55, 0x8d, 0x4b, 0x58, 0xd8, 0x85,
|
||||
0xd0, 0xa5, 0xaa, 0xa3, 0x2a, 0x4d, 0x55, 0x8f, 0x31, 0x5c, 0xb4, 0x55,
|
||||
0x75, 0x31, 0x17, 0x42, 0x97, 0xaa, 0x8e, 0xac, 0x34, 0x55, 0x1d, 0x32,
|
||||
0x5c, 0xb0, 0x55, 0x75, 0x41, 0x17, 0x42, 0x97, 0xaa, 0x8e, 0xae, 0x34,
|
||||
0x55, 0x7d, 0xcb, 0x60, 0xd0, 0xaa, 0xba, 0x80, 0x0b, 0x99, 0x58, 0xaa,
|
||||
0x4a, 0x55, 0x9a, 0xaa, 0x7a, 0x06, 0x93, 0x56, 0xd5, 0x85, 0x5c, 0x08,
|
||||
0x5d, 0xaa, 0x3a, 0xa9, 0xd2, 0x54, 0xb5, 0xc7, 0x60, 0xd0, 0xaa, 0x3a,
|
||||
0xbf, 0x0b, 0xc1, 0x24, 0x28, 0x5d, 0x69, 0xaa, 0xd6, 0xad, 0xaa, 0xb3,
|
||||
0xbb, 0x10, 0x4c, 0x84, 0xd2, 0x95, 0xa6, 0x6a, 0xd9, 0xaa, 0xba, 0x80,
|
||||
0x0b, 0xc1, 0x64, 0x28, 0x5d, 0x69, 0xaa, 0xb6, 0xad, 0xaa, 0x33, 0xbb,
|
||||
0x10, 0x10, 0x50, 0xba, 0xd2, 0x54, 0x2d, 0x5b, 0x55, 0x67, 0x76, 0x21,
|
||||
0x74, 0xa9, 0x2a, 0x59, 0x69, 0xaa, 0xea, 0x60, 0xdd, 0xaa, 0xca, 0xbb,
|
||||
0x68, 0x5c, 0x08, 0x48, 0x38, 0xba, 0xd2, 0xd4, 0xd9, 0xb7, 0xaa, 0xce,
|
||||
0xe2, 0x62, 0x05, 0x1a, 0x1b, 0xc3, 0xa8, 0x6a, 0xd0, 0xf0, 0x70, 0x0f,
|
||||
0x63, 0x11, 0x02, 0x16, 0x49, 0x44, 0x55, 0xf9, 0xe3, 0xfb, 0x01, 0xfb,
|
||||
0x51, 0x26, 0x11, 0x55, 0xe5, 0x8f, 0xef, 0xb7, 0x1f, 0x65, 0x22, 0x51,
|
||||
0x55, 0xfe, 0xf8, 0xfe, 0x14, 0x46, 0x99, 0x44, 0x54, 0x95, 0x3f, 0xbe,
|
||||
0x3f, 0x85, 0x51, 0x26, 0x11, 0x55, 0x25, 0x8e, 0xef, 0x4f, 0x68, 0x94,
|
||||
0x49, 0x44, 0x55, 0xf9, 0xe3, 0xfb, 0x53, 0x18, 0x65, 0x12, 0x51, 0x55,
|
||||
0xfe, 0xf8, 0xfe, 0x44, 0x46, 0x69, 0x1f, 0x55, 0x65, 0x8f, 0xef, 0x4f,
|
||||
0x63, 0x94, 0x49, 0x44, 0x55, 0x89, 0xe3, 0xfb, 0xd3, 0x1a, 0xa5, 0x7d,
|
||||
0x54, 0x95, 0x3f, 0xbe, 0x3f, 0x91, 0x51, 0xda, 0x47, 0x55, 0xf9, 0xe3,
|
||||
0xfb, 0x13, 0x19, 0xa5, 0x7d, 0x54, 0x95, 0x39, 0xbe, 0x3f, 0xa9, 0x51,
|
||||
0xda, 0x47, 0x55, 0x89, 0xe3, 0xfb, 0x59, 0x11, 0xf3, 0x8e, 0xd2, 0x3e,
|
||||
0xaa, 0x4a, 0x1c, 0xdf, 0x9f, 0xd0, 0x28, 0x93, 0x88, 0xaa, 0xf2, 0xc7,
|
||||
0xf7, 0xa7, 0x30, 0xca, 0x24, 0xa2, 0xaa, 0xdc, 0xf1, 0xfd, 0xa9, 0x8c,
|
||||
0x32, 0x89, 0xa8, 0x2a, 0x7f, 0x7c, 0x7f, 0x4a, 0xa3, 0x4c, 0x3f, 0xaa,
|
||||
0x1a, 0xc9, 0xaa, 0xda, 0x8f, 0x32, 0x89, 0xa8, 0x2a, 0x7f, 0x7c, 0x7f,
|
||||
0x0a, 0xa3, 0x4c, 0x22, 0xaa, 0xca, 0x1f, 0xdf, 0x9f, 0xc8, 0x28, 0xed,
|
||||
0xa3, 0xaa, 0xfc, 0xf1, 0xfd, 0x89, 0x8c, 0xd2, 0x3e, 0xaa, 0xca, 0x1f,
|
||||
0xdf, 0x9f, 0xc2, 0x28, 0x7f, 0xc5, 0xa8, 0xaa, 0x22, 0x20, 0xa1, 0xaf,
|
||||
0x9d, 0x5f, 0x33, 0xaa, 0xaa, 0x7e, 0x90, 0xf6, 0xa3, 0xfc, 0xf5, 0xa3,
|
||||
0xaa, 0x8a, 0x99, 0x45, 0xc8, 0xc5, 0x73, 0xa2, 0xe9, 0x44, 0x55, 0x35,
|
||||
0x8d, 0x07, 0xfc, 0x3a, 0xa2, 0xaa, 0x9a, 0xc6, 0xae, 0xbc, 0x8e, 0xa8,
|
||||
0xaa, 0xa6, 0x31, 0xca, 0xeb, 0x88, 0xaa, 0x6a, 0x1a, 0xa3, 0xbc, 0x8e,
|
||||
0xa8, 0xaa, 0xa6, 0x32, 0xca, 0x6b, 0x88, 0xaa, 0x6a, 0x1a, 0x5f, 0x3b,
|
||||
0xd7, 0x11, 0x55, 0x75, 0xa0, 0xf1, 0x3f, 0x19, 0xc2, 0xb4, 0x90, 0x78,
|
||||
0xb9, 0x76, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
|
||||
0x42, 0x60, 0x82,
|
||||
};
|
||||
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 Joerg Henrichs
|
||||
// Copyright (C) 2006-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2006 Joerg Henrichs
|
||||
// Copyright (C) 2006-2013 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs, Marianne Gagnon
|
||||
// Copyright (C) 2011-2013 Joerg Henrichs, Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -22,9 +22,12 @@
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/particle_kind.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/wind.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
#include "utils/helpers.hpp"
|
||||
|
||||
#include <SParticle.h>
|
||||
#include <IParticleAffector.h>
|
||||
@ -32,6 +35,7 @@
|
||||
#include <IParticleSystemSceneNode.h>
|
||||
#include <IParticleBoxEmitter.h>
|
||||
#include <ISceneManager.h>
|
||||
#include <algorithm>
|
||||
|
||||
class FadeAwayAffector : public scene::IParticleAffector
|
||||
{
|
||||
@ -173,6 +177,46 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
|
||||
class WindAffector : public scene::IParticleAffector
|
||||
{
|
||||
/** (Squared) distance from camera at which a particle is completely faded out */
|
||||
float m_speed;
|
||||
float m_seed;
|
||||
|
||||
public:
|
||||
WindAffector(float speed): m_speed(speed)
|
||||
{
|
||||
m_seed = (rand() % 1000) - 500;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
virtual void affect(u32 now, scene::SParticle* particlearray, u32 count)
|
||||
{
|
||||
const float time = irr_driver->getDevice()->getTimer()->getTime() / 10000.0f;
|
||||
core::vector3df dir = irr_driver->getWind();
|
||||
dir *= m_speed * std::min(noise2d(time, m_seed), -0.2f);
|
||||
|
||||
for (u32 n = 0; n < count; n++)
|
||||
{
|
||||
scene::SParticle& cur = particlearray[n];
|
||||
|
||||
cur.pos += dir;
|
||||
} // for n<count
|
||||
} // affect
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
virtual scene::E_PARTICLE_AFFECTOR_TYPE getType() const
|
||||
{
|
||||
// FIXME: this method seems to make sense only for built-in affectors
|
||||
return scene::EPAT_FADE_OUT;
|
||||
}
|
||||
|
||||
}; // WindAffector
|
||||
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@ -498,6 +542,21 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
||||
m_node->addAffector(scale_affector);
|
||||
scale_affector->drop();
|
||||
}
|
||||
|
||||
const float windspeed = type->getWindSpeed();
|
||||
if (windspeed > 0.01f)
|
||||
{
|
||||
WindAffector *waf = new WindAffector(windspeed);
|
||||
m_node->addAffector(waf);
|
||||
waf->drop();
|
||||
}
|
||||
|
||||
const bool flips = type->getFlips();
|
||||
if (flips)
|
||||
{
|
||||
m_node->getMaterial(0).MaterialType = irr_driver->getShader(ES_SNOW);
|
||||
m_node->getMaterial(0).BlendOperation = video::EBO_ADD;
|
||||
}
|
||||
}
|
||||
} // setParticleType
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs, Marianne Gagnon
|
||||
// Copyright (C) 2011-2013 Joerg Henrichs, Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs, Marianne Gagnon
|
||||
// Copyright (C) 2011-2013 Joerg Henrichs, Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -54,6 +54,8 @@ ParticleKind::ParticleKind(const std::string file) : m_min_start_color(255,255,2
|
||||
m_has_scale_affector = NULL;
|
||||
m_scale_affector_factor_x = 0.0f;
|
||||
m_scale_affector_factor_y = 0.0f;
|
||||
m_wind_speed = 0;
|
||||
m_flips = false;
|
||||
|
||||
|
||||
// ----- Read XML file
|
||||
@ -219,6 +221,14 @@ ParticleKind::ParticleKind(const std::string file) : m_min_start_color(255,255,2
|
||||
m_material_file = material_manager->getLatestMaterial()->getTexFname();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const XMLNode* wind = xml->getNode("wind");
|
||||
if (wind != NULL)
|
||||
{
|
||||
wind->get("speed", &m_wind_speed);
|
||||
wind->get("flips", &m_flips);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs, Marianne Gagnon
|
||||
// Copyright (C) 2011-2013 Joerg Henrichs, Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -86,6 +86,11 @@ private:
|
||||
|
||||
int m_emission_decay_rate;
|
||||
|
||||
/** Wind. < 0.01 if disabled. */
|
||||
float m_wind_speed;
|
||||
|
||||
bool m_flips;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
std::string m_material_file;
|
||||
@ -148,11 +153,14 @@ public:
|
||||
|
||||
int getEmissionDecayRate() const { return m_emission_decay_rate; }
|
||||
|
||||
|
||||
bool hasScaleAffector() const { return m_has_scale_affector; }
|
||||
float getScaleAffectorFactorX() const { return m_scale_affector_factor_x; }
|
||||
float getScaleAffectorFactorY() const { return m_scale_affector_factor_y; };
|
||||
|
||||
float getWindSpeed() const { return m_wind_speed; }
|
||||
|
||||
bool getFlips() const { return m_flips; }
|
||||
|
||||
std::string getName() const { return m_name; }
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Joerg Henrichs, Marianne Gagnon
|
||||
// Copyright (C) 2011-2013 Joerg Henrichs, Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Marianne Gagnon
|
||||
// Copyright (C) 2011-2013 Marianne Gagnon
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Marianne Gagnon
|
||||
// based on code Copyright (C) 2002-2010 Nikolaus Gebhardt
|
||||
// Copyright (C) 2011-2013 Marianne Gagnon
|
||||
// based on code Copyright 2002-2010 Nikolaus Gebhardt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -24,7 +24,7 @@
|
||||
#include <IMeshSceneNode.h>
|
||||
|
||||
PerCameraNode::PerCameraNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id,
|
||||
scene::ICameraSceneNode* camera, scene::IMesh* mesh)
|
||||
scene::ICameraSceneNode* camera, scene::ISceneNode *node)
|
||||
: IDummyTransformationSceneNode(parent, mgr, id)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
@ -33,7 +33,10 @@ PerCameraNode::PerCameraNode(scene::ISceneNode* parent, scene::ISceneManager* mg
|
||||
#endif
|
||||
|
||||
m_camera = camera;
|
||||
m_child = mgr->addMeshSceneNode(mesh, this);
|
||||
|
||||
node->setParent(this);
|
||||
m_child = node;
|
||||
|
||||
//m_child = mgr->addCubeSceneNode(0.5f, this, -1, core::vector3df(0,0,0), core::vector3df(0,0,0), core::vector3df(3.0f,0.2f,3.0f));
|
||||
//RelativeTransformationMatrix.setTranslation( core::vector3df(-0.5,-1,3) );
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011 Marianne Gagnon
|
||||
// based on code Copyright (C) 2002-2010 Nikolaus Gebhardt
|
||||
// Copyright (C) 2011-2013 Marianne Gagnon
|
||||
// based on code Copyright 2002-2010 Nikolaus Gebhardt
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -54,7 +54,7 @@ private:
|
||||
public:
|
||||
|
||||
PerCameraNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id,
|
||||
scene::ICameraSceneNode* camera, scene::IMesh* mesh);
|
||||
scene::ICameraSceneNode* camera, scene::ISceneNode* node);
|
||||
virtual ~PerCameraNode();
|
||||
|
||||
//! returns the axis aligned bounding box of this node
|
||||
|
@ -1,6 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011-2013 the SuperTuxKart team
|
||||
// Copyright (C) 2013 Joerg Henrichs
|
||||
// Copyright (C) 2011-2013 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
|
||||
@ -20,69 +19,46 @@
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "graphics/callbacks.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/mlaa_areamap.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#include <IGPUProgrammingServices.h>
|
||||
#include <IMaterialRendererServices.h>
|
||||
|
||||
#define MOTION_BLUR_FACTOR (1.0f/15.0f)
|
||||
#define MOTION_BLUR_OFFSET 20.0f
|
||||
#include <SViewFrustum.h>
|
||||
|
||||
using namespace video;
|
||||
using namespace scene;
|
||||
|
||||
PostProcessing::PostProcessing(video::IVideoDriver* video_driver)
|
||||
PostProcessing::PostProcessing(IVideoDriver* video_driver)
|
||||
{
|
||||
// Check if post-processing is supported on this hardware
|
||||
m_supported = false;
|
||||
if( irr_driver->isGLSL() )
|
||||
{
|
||||
m_supported = true;
|
||||
}
|
||||
|
||||
//Check which texture dimensions are supported on this hardware
|
||||
bool nonsquare = video_driver->queryFeature(video::EVDF_TEXTURE_NSQUARE);
|
||||
bool nonpower = video_driver->queryFeature(video::EVDF_TEXTURE_NPOT);
|
||||
if (!nonpower) {
|
||||
Log::warn("PostProcessing",
|
||||
"Only power of two textures are supported.");
|
||||
}
|
||||
if (!nonsquare) {
|
||||
Log::warn("PostProcessing", "Only square textures are supported.");
|
||||
}
|
||||
// Initialization
|
||||
if(m_supported)
|
||||
m_material.Wireframe = false;
|
||||
m_material.Lighting = false;
|
||||
m_material.ZWriteEnable = false;
|
||||
m_material.ZBuffer = ECFN_ALWAYS;
|
||||
m_material.setFlag(EMF_TRILINEAR_FILTER, true);
|
||||
|
||||
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
|
||||
{
|
||||
// Render target
|
||||
core::dimension2du opt = video_driver->getScreenSize()
|
||||
.getOptimalSize(!nonpower, !nonsquare);
|
||||
m_render_target =
|
||||
video_driver->addRenderTargetTexture(opt, "postprocess");
|
||||
if(!m_render_target)
|
||||
{
|
||||
Log::warn("PostProcessing", "Couldn't create the render target "
|
||||
"for post-processing, disabling it.");
|
||||
UserConfigParams::m_postprocess_enabled = false;
|
||||
m_material.TextureLayer[i].TextureWrapU =
|
||||
m_material.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE;
|
||||
}
|
||||
|
||||
// Material and shaders
|
||||
IGPUProgrammingServices* gpu =
|
||||
video_driver->getGPUProgrammingServices();
|
||||
s32 material_type = gpu->addHighLevelShaderMaterialFromFiles(
|
||||
(file_manager->getShaderDir() + "motion_blur.vert").c_str(),
|
||||
"main", video::EVST_VS_2_0,
|
||||
(file_manager->getShaderDir() + "motion_blur.frag").c_str(),
|
||||
"main", video::EPST_PS_2_0,
|
||||
this, video::EMT_SOLID);
|
||||
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;
|
||||
// Load the MLAA area map
|
||||
io::IReadFile *areamap = irr_driver->getDevice()->getFileSystem()->
|
||||
createMemoryReadFile((void *) AreaMap33, sizeof(AreaMap33),
|
||||
"AreaMap33", false);
|
||||
if (!areamap) Log::fatal("postprocessing", "Failed to load the areamap");
|
||||
m_areamap = irr_driver->getVideoDriver()->getTexture(areamap);
|
||||
areamap->drop();
|
||||
|
||||
}
|
||||
} // PostProcessing
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -97,12 +73,15 @@ PostProcessing::~PostProcessing()
|
||||
*/
|
||||
void PostProcessing::reset()
|
||||
{
|
||||
unsigned int n = Camera::getNumCameras();
|
||||
const u32 n = Camera::getNumCameras();
|
||||
m_boost_time.resize(n);
|
||||
m_vertices.resize(n);
|
||||
m_center.resize(n);
|
||||
m_direction.resize(n);
|
||||
|
||||
MotionBlurProvider * const cb = (MotionBlurProvider *) irr_driver->
|
||||
getCallback(ES_MOTIONBLUR);
|
||||
|
||||
for(unsigned int i=0; i<n; i++)
|
||||
{
|
||||
m_boost_time[i] = 0.0f;
|
||||
@ -137,7 +116,7 @@ void PostProcessing::reset()
|
||||
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);
|
||||
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;
|
||||
|
||||
@ -145,57 +124,51 @@ void PostProcessing::reset()
|
||||
+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
|
||||
const 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.7f*tex_height;
|
||||
|
||||
setMotionBlurCenterY(i, 0.2f);
|
||||
|
||||
cb->setDirection(i, m_direction[i].X, m_direction[i].Y);
|
||||
cb->setMaxHeight(i, m_vertices[i].v1.TCoords.Y);
|
||||
} // 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()
|
||||
void PostProcessing::setMotionBlurCenterY(const u32 num, const float y)
|
||||
{
|
||||
if(!m_supported || !UserConfigParams::m_postprocess_enabled)
|
||||
return;
|
||||
MotionBlurProvider * const cb = (MotionBlurProvider *) irr_driver->
|
||||
getCallback(ES_MOTIONBLUR);
|
||||
|
||||
bool any_boost = false;
|
||||
for(unsigned int i=0; i<m_boost_time.size(); i++)
|
||||
any_boost |= m_boost_time[i]>0.0f;
|
||||
const float tex_height = m_vertices[num].v1.TCoords.Y - m_vertices[num].v0.TCoords.Y;
|
||||
m_center[num].Y = m_vertices[num].v0.TCoords.Y + y * tex_height;
|
||||
|
||||
// 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(!any_boost)
|
||||
{
|
||||
m_used_pp_this_frame = false;
|
||||
return;
|
||||
}
|
||||
cb->setCenter(num, m_center[num].X, m_center[num].Y);
|
||||
}
|
||||
|
||||
m_used_pp_this_frame = true;
|
||||
irr_driver->getVideoDriver()->setRenderTarget(m_render_target, true, true);
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Setup some PP data.
|
||||
*/
|
||||
void PostProcessing::begin()
|
||||
{
|
||||
m_any_boost = false;
|
||||
for (u32 i = 0; i < m_boost_time.size(); i++)
|
||||
m_any_boost |= m_boost_time[i] > 0.01f;
|
||||
} // beginCapture
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Restore the framebuffer render target.
|
||||
*/
|
||||
void PostProcessing::endCapture()
|
||||
{
|
||||
if(!m_supported || !UserConfigParams::m_postprocess_enabled ||
|
||||
!m_used_pp_this_frame)
|
||||
return;
|
||||
|
||||
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)
|
||||
{
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
m_boost_time[camera_index] = 0.75f;
|
||||
|
||||
MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver->
|
||||
getCallback(ES_MOTIONBLUR);
|
||||
cb->setBoostTime(camera_index, m_boost_time[camera_index]);
|
||||
}
|
||||
} // giveBoost
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -204,75 +177,590 @@ void PostProcessing::giveBoost(unsigned int camera_index)
|
||||
*/
|
||||
void PostProcessing::update(float dt)
|
||||
{
|
||||
for(unsigned int i=0; i<m_boost_time.size(); i++)
|
||||
if (!irr_driver->isGLSL())
|
||||
return;
|
||||
|
||||
MotionBlurProvider* const cb =
|
||||
(MotionBlurProvider*) irr_driver->getCallback(ES_MOTIONBLUR);
|
||||
|
||||
if (cb == NULL) return;
|
||||
|
||||
for (unsigned int i=0; i<m_boost_time.size(); i++)
|
||||
{
|
||||
if (m_boost_time[i] > 0.0f)
|
||||
{
|
||||
m_boost_time[i] -= dt;
|
||||
if (m_boost_time[i] < 0.0f) m_boost_time[i] = 0.0f;
|
||||
}
|
||||
|
||||
cb->setBoostTime(i, m_boost_time[i]);
|
||||
}
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Render the post-processed scene, solids only, color to color, no stencil */
|
||||
void PostProcessing::renderSolid(const u32 cam)
|
||||
{
|
||||
if (irr_driver->isGLSL()) return;
|
||||
|
||||
// Early out: do nothing if at all possible
|
||||
if (UserConfigParams::m_ssao < 1 && !World::getWorld()->getTrack()->isFogEnabled())
|
||||
return;
|
||||
|
||||
static u8 tick = 0;
|
||||
|
||||
IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
drv->setTransform(ETS_WORLD, core::IdentityMatrix);
|
||||
drv->setTransform(ETS_VIEW, core::IdentityMatrix);
|
||||
drv->setTransform(ETS_PROJECTION, core::IdentityMatrix);
|
||||
|
||||
GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver->
|
||||
getCallback(ES_GAUSSIAN3H);
|
||||
|
||||
const TypeRTT curssao = tick ? RTT_SSAO2 : RTT_SSAO1;
|
||||
|
||||
if (World::getWorld()->getTrack()->isFogEnabled())
|
||||
{
|
||||
m_material.MaterialType = irr_driver->getShader(ES_FOG);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_DEPTH));
|
||||
|
||||
// Overlay
|
||||
m_material.BlendOperation = EBO_ADD;
|
||||
m_material.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false);
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
m_material.BlendOperation = EBO_NONE;
|
||||
m_material.MaterialTypeParam = 0;
|
||||
}
|
||||
|
||||
if (UserConfigParams::m_ssao == 1) // SSAO low
|
||||
{
|
||||
m_material.MaterialType = irr_driver->getShader(ES_SSAO);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL));
|
||||
m_material.setTexture(1, irr_driver->getRTT(tick ? RTT_SSAO1 : RTT_SSAO2));
|
||||
|
||||
drv->setRenderTarget(irr_driver->getRTT(curssao), true, false,
|
||||
SColor(255, 255, 255, 255));
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
// Blur it to reduce noise.
|
||||
{
|
||||
gacb->setResolution(UserConfigParams::m_width / 4,
|
||||
UserConfigParams::m_height / 4);
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V);
|
||||
m_material.setTexture(0, irr_driver->getRTT(curssao));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2));
|
||||
drv->setRenderTarget(irr_driver->getRTT(curssao), false, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
}
|
||||
|
||||
// Overlay
|
||||
m_material.MaterialType = EMT_ONETEXTURE_BLEND;
|
||||
m_material.setTexture(0, irr_driver->getRTT(curssao));
|
||||
m_material.setTexture(1, 0);
|
||||
m_material.BlendOperation = EBO_ADD;
|
||||
m_material.MaterialTypeParam = pack_textureBlendFunc(EBF_DST_COLOR, EBF_ZERO);
|
||||
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false);
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
m_material.BlendOperation = EBO_NONE;
|
||||
m_material.MaterialTypeParam = 0;
|
||||
|
||||
} else if (UserConfigParams::m_ssao == 2) // SSAO high
|
||||
{
|
||||
m_material.MaterialType = irr_driver->getShader(ES_SSAO);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL));
|
||||
m_material.setTexture(1, irr_driver->getRTT(tick ? RTT_SSAO1 : RTT_SSAO2));
|
||||
|
||||
drv->setRenderTarget(irr_driver->getRTT(curssao), true, false,
|
||||
SColor(255, 255, 255, 255));
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
// Blur it to reduce noise.
|
||||
{
|
||||
gacb->setResolution(UserConfigParams::m_width,
|
||||
UserConfigParams::m_height);
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6V);
|
||||
m_material.setTexture(0, irr_driver->getRTT(curssao));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6H);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3));
|
||||
drv->setRenderTarget(irr_driver->getRTT(curssao), false, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
}
|
||||
|
||||
// Overlay
|
||||
m_material.MaterialType = EMT_ONETEXTURE_BLEND;
|
||||
m_material.setTexture(0, irr_driver->getRTT(curssao));
|
||||
m_material.setTexture(1, 0);
|
||||
m_material.BlendOperation = EBO_ADD;
|
||||
m_material.MaterialTypeParam = pack_textureBlendFunc(EBF_DST_COLOR, EBF_ZERO);
|
||||
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false);
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
m_material.BlendOperation = EBO_NONE;
|
||||
m_material.MaterialTypeParam = 0;
|
||||
}
|
||||
|
||||
tick++;
|
||||
tick %= 2;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Render the post-processed scene */
|
||||
void PostProcessing::render()
|
||||
{
|
||||
if(!m_supported || !UserConfigParams::m_postprocess_enabled)
|
||||
return;
|
||||
if (!irr_driver->isGLSL()) return;
|
||||
|
||||
if (!m_used_pp_this_frame)
|
||||
IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
drv->setTransform(ETS_WORLD, core::IdentityMatrix);
|
||||
drv->setTransform(ETS_VIEW, core::IdentityMatrix);
|
||||
drv->setTransform(ETS_PROJECTION, core::IdentityMatrix);
|
||||
|
||||
MotionBlurProvider * const mocb = (MotionBlurProvider *) irr_driver->
|
||||
getCallback(ES_MOTIONBLUR);
|
||||
GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver->
|
||||
getCallback(ES_GAUSSIAN3H);
|
||||
|
||||
const u32 cams = Camera::getNumCameras();
|
||||
for(u32 cam = 0; cam < cams; cam++)
|
||||
{
|
||||
return;
|
||||
scene::ICameraSceneNode * const camnode =
|
||||
Camera::getCamera(cam)->getCameraSceneNode();
|
||||
mocb->setCurrentCamera(cam);
|
||||
ITexture *in = irr_driver->getRTT(RTT_COLOR);
|
||||
ITexture *out = irr_driver->getRTT(RTT_TMP1);
|
||||
// Each effect uses these as named, and sets them up for the next effect.
|
||||
// This allows chaining effects where some may be disabled.
|
||||
|
||||
// As the original color shouldn't be touched, the first effect can't be disabled.
|
||||
|
||||
if (1) // bloom
|
||||
{
|
||||
// Blit the base to tmp1
|
||||
m_material.MaterialType = EMT_SOLID;
|
||||
m_material.setTexture(0, in);
|
||||
drv->setRenderTarget(out, true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
const bool globalbloom = World::getWorld()->getTrack()->getBloom();
|
||||
|
||||
BloomPowerProvider * const bloomcb = (BloomPowerProvider *)
|
||||
irr_driver->
|
||||
getCallback(ES_BLOOM_POWER);
|
||||
|
||||
if (globalbloom)
|
||||
{
|
||||
const float threshold = World::getWorld()->getTrack()->getBloomThreshold();
|
||||
((BloomProvider *) irr_driver->getCallback(ES_BLOOM))->setThreshold(threshold);
|
||||
|
||||
// Catch bright areas, and progressively minify
|
||||
m_material.MaterialType = irr_driver->getShader(ES_BLOOM);
|
||||
m_material.setTexture(0, in);
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
}
|
||||
|
||||
u16 indices[6] = {0, 1, 2, 3, 0, 2};
|
||||
// Do we have any forced bloom nodes? If so, draw them now
|
||||
const std::vector<IrrDriver::BloomData> &blooms = irr_driver->getForcedBloom();
|
||||
const u32 bloomsize = blooms.size();
|
||||
|
||||
for(m_current_camera=0; m_current_camera<Camera::getNumCameras();
|
||||
m_current_camera++)
|
||||
if (!globalbloom && bloomsize)
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false);
|
||||
|
||||
|
||||
if (globalbloom || bloomsize)
|
||||
{
|
||||
// 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);
|
||||
// Clear the alpha to a suitable value, stencil
|
||||
glClearColor(0, 0, 0, 0.1);
|
||||
glColorMask(0, 0, 0, 1);
|
||||
|
||||
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glColorMask(1, 1, 1, 1);
|
||||
|
||||
// The forced-bloom objects are drawn again, to know which pixels to pick.
|
||||
// While it's more drawcalls, there's a cost to using four MRTs over three,
|
||||
// and there shouldn't be many such objects in a track.
|
||||
// The stencil is already in use for the glow. The alpha channel is best
|
||||
// reserved for other use (specular, etc).
|
||||
//
|
||||
// They are drawn with depth and color writes off, giving 4x-8x drawing speed.
|
||||
if (bloomsize)
|
||||
{
|
||||
const core::aabbox3df &cambox = camnode->
|
||||
getViewFrustum()->
|
||||
getBoundingBox();
|
||||
|
||||
irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID);
|
||||
SOverrideMaterial &overridemat = drv->getOverrideMaterial();
|
||||
overridemat.EnablePasses = ESNRP_SOLID;
|
||||
overridemat.EnableFlags = EMF_MATERIAL_TYPE | EMF_ZWRITE_ENABLE | EMF_COLOR_MASK;
|
||||
overridemat.Enabled = true;
|
||||
|
||||
overridemat.Material.MaterialType = irr_driver->getShader(ES_BLOOM_POWER);
|
||||
overridemat.Material.ZWriteEnable = false;
|
||||
overridemat.Material.ColorMask = ECP_ALPHA;
|
||||
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glStencilFunc(GL_ALWAYS, 1, ~0);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
camnode->render();
|
||||
|
||||
for (u32 i = 0; i < bloomsize; i++)
|
||||
{
|
||||
scene::ISceneNode * const cur = blooms[i].node;
|
||||
|
||||
// Quick box-based culling
|
||||
const core::aabbox3df nodebox = cur->getTransformedBoundingBox();
|
||||
if (!nodebox.intersectsWithBox(cambox))
|
||||
continue;
|
||||
|
||||
bloomcb->setPower(blooms[i].power);
|
||||
|
||||
cur->render();
|
||||
}
|
||||
|
||||
// Second pass for transparents. No-op for solids.
|
||||
irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_TRANSPARENT);
|
||||
for (u32 i = 0; i < bloomsize; i++)
|
||||
{
|
||||
scene::ISceneNode * const cur = blooms[i].node;
|
||||
|
||||
// Quick box-based culling
|
||||
const core::aabbox3df nodebox = cur->getTransformedBoundingBox();
|
||||
if (!nodebox.intersectsWithBox(cambox))
|
||||
continue;
|
||||
|
||||
bloomcb->setPower(blooms[i].power);
|
||||
|
||||
cur->render();
|
||||
}
|
||||
|
||||
overridemat.Enabled = 0;
|
||||
overridemat.EnablePasses = 0;
|
||||
|
||||
// Ok, we have the stencil; now use it to blit from color to bloom tex
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_EQUAL, 1, ~0);
|
||||
m_material.MaterialType = EMT_SOLID;
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_COLOR));
|
||||
|
||||
// Just in case.
|
||||
glColorMask(1, 1, 1, 0);
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), false, false);
|
||||
|
||||
m_material.ColorMask = ECP_RGB;
|
||||
drawQuad(cam, m_material);
|
||||
m_material.ColorMask = ECP_ALL;
|
||||
|
||||
glColorMask(1, 1, 1, 1);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
} // end forced bloom
|
||||
|
||||
// To half
|
||||
m_material.MaterialType = EMT_SOLID;
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_HALF1), true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
// To quarter
|
||||
m_material.MaterialType = EMT_SOLID;
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_HALF1));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
// To eighth
|
||||
m_material.MaterialType = EMT_SOLID;
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
// Blur it for distribution.
|
||||
{
|
||||
gacb->setResolution(UserConfigParams::m_width / 8,
|
||||
UserConfigParams::m_height / 8);
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6V);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH1));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH2), true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6H);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH2));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), false, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
}
|
||||
|
||||
// Additively blend on top of tmp1
|
||||
m_material.BlendOperation = EBO_ADD;
|
||||
m_material.MaterialType = irr_driver->getShader(ES_BLOOM_BLEND);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH1));
|
||||
drv->setRenderTarget(out, false, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
m_material.BlendOperation = EBO_NONE;
|
||||
} // end if bloom
|
||||
|
||||
in = irr_driver->getRTT(RTT_TMP1);
|
||||
out = irr_driver->getRTT(RTT_TMP2);
|
||||
}
|
||||
|
||||
if (World::getWorld()->getTrack()->hasGodRays() && m_sunpixels > 30) // god rays
|
||||
{
|
||||
// Grab the sky
|
||||
drv->setRenderTarget(out, true, false);
|
||||
irr_driver->getSceneManager()->drawAll(ESNRP_SKY_BOX);
|
||||
|
||||
// Set the sun's color
|
||||
ColorizeProvider * const colcb = (ColorizeProvider *) irr_driver->getCallback(ES_COLORIZE);
|
||||
const SColor col = World::getWorld()->getTrack()->getSunColor();
|
||||
colcb->setColor(col.getRed() / 255.0f, col.getGreen() / 255.0f, col.getBlue() / 255.0f);
|
||||
|
||||
// The sun interposer
|
||||
IMeshSceneNode * const sun = irr_driver->getSunInterposer();
|
||||
sun->getMaterial(0).ColorMask = ECP_ALL;
|
||||
irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA);
|
||||
irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID);
|
||||
|
||||
sun->render();
|
||||
|
||||
sun->getMaterial(0).ColorMask = ECP_NONE;
|
||||
|
||||
// Fade to quarter
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GODFADE);
|
||||
m_material.setTexture(0, out);
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
// Blur
|
||||
{
|
||||
gacb->setResolution(UserConfigParams::m_width / 4,
|
||||
UserConfigParams::m_height / 4);
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
}
|
||||
|
||||
// Calculate the sun's position in texcoords
|
||||
const core::vector3df pos = sun->getPosition();
|
||||
float ndc[4];
|
||||
core::matrix4 trans = camnode->getProjectionMatrix();
|
||||
trans *= camnode->getViewMatrix();
|
||||
|
||||
trans.transformVect(ndc, pos);
|
||||
|
||||
const float texh = m_vertices[cam].v1.TCoords.Y - m_vertices[cam].v0.TCoords.Y;
|
||||
const float texw = m_vertices[cam].v3.TCoords.X - m_vertices[cam].v0.TCoords.X;
|
||||
|
||||
const float sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw;
|
||||
const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh;
|
||||
|
||||
((GodRayProvider *) irr_driver->getCallback(ES_GODRAY))->
|
||||
setSunPosition(sunx, suny);
|
||||
|
||||
// Rays please
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GODRAY);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
// Blur
|
||||
{
|
||||
gacb->setResolution(UserConfigParams::m_width / 4,
|
||||
UserConfigParams::m_height / 4);
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1));
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), false, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
}
|
||||
|
||||
// Overlay
|
||||
m_material.MaterialType = EMT_TRANSPARENT_ADD_COLOR;
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2));
|
||||
drv->setRenderTarget(in, false, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
}
|
||||
|
||||
if (UserConfigParams::m_motionblur && m_any_boost) // motion blur
|
||||
{
|
||||
// Calculate the kart's Y position on screen
|
||||
const core::vector3df pos =
|
||||
Camera::getCamera(cam)->getKart()->getNode()->getPosition();
|
||||
float ndc[4];
|
||||
core::matrix4 trans = camnode->getProjectionMatrix();
|
||||
trans *= camnode->getViewMatrix();
|
||||
|
||||
trans.transformVect(ndc, pos);
|
||||
const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f;
|
||||
setMotionBlurCenterY(cam, karty);
|
||||
|
||||
|
||||
m_material.MaterialType = irr_driver->getShader(ES_MOTIONBLUR);
|
||||
m_material.setTexture(0, in);
|
||||
drv->setRenderTarget(out, true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
ITexture *tmp = in;
|
||||
in = out;
|
||||
out = tmp;
|
||||
}
|
||||
|
||||
if (irr_driver->getDisplacingNodes().size()) // Displacement
|
||||
{
|
||||
m_material.MaterialType = irr_driver->getShader(ES_PPDISPLACE);
|
||||
m_material.setFlag(EMF_BILINEAR_FILTER, false);
|
||||
m_material.setTexture(0, in);
|
||||
m_material.setTexture(1, irr_driver->getRTT(RTT_DISPLACE));
|
||||
drv->setRenderTarget(out, true, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
m_material.setTexture(1, 0);
|
||||
m_material.setFlag(EMF_BILINEAR_FILTER, true);
|
||||
|
||||
ITexture *tmp = in;
|
||||
in = out;
|
||||
out = tmp;
|
||||
}
|
||||
|
||||
if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
|
||||
{
|
||||
drv->setRenderTarget(out, false, false);
|
||||
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
glStencilFunc(GL_ALWAYS, 1, ~0);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
||||
// Pass 1: color edge detection
|
||||
m_material.setFlag(EMF_BILINEAR_FILTER, false);
|
||||
m_material.setFlag(EMF_TRILINEAR_FILTER, false);
|
||||
m_material.MaterialType = irr_driver->getShader(ES_MLAA_COLOR1);
|
||||
m_material.setTexture(0, in);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
m_material.setFlag(EMF_BILINEAR_FILTER, true);
|
||||
m_material.setFlag(EMF_TRILINEAR_FILTER, true);
|
||||
|
||||
glStencilFunc(GL_EQUAL, 1, ~0);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
|
||||
// Pass 2: blend weights
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false);
|
||||
|
||||
m_material.MaterialType = irr_driver->getShader(ES_MLAA_BLEND2);
|
||||
m_material.setTexture(0, out);
|
||||
m_material.setTexture(1, m_areamap);
|
||||
m_material.TextureLayer[1].BilinearFilter = false;
|
||||
m_material.TextureLayer[1].TrilinearFilter = false;
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
m_material.TextureLayer[1].BilinearFilter = true;
|
||||
m_material.TextureLayer[1].TrilinearFilter = true;
|
||||
m_material.setTexture(1, 0);
|
||||
|
||||
// Pass 3: gather
|
||||
drv->setRenderTarget(in, false, false);
|
||||
|
||||
m_material.setFlag(EMF_BILINEAR_FILTER, false);
|
||||
m_material.setFlag(EMF_TRILINEAR_FILTER, false);
|
||||
m_material.MaterialType = irr_driver->getShader(ES_MLAA_NEIGH3);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3));
|
||||
m_material.setTexture(1, irr_driver->getRTT(RTT_COLOR));
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
|
||||
m_material.setFlag(EMF_BILINEAR_FILTER, true);
|
||||
m_material.setFlag(EMF_TRILINEAR_FILTER, true);
|
||||
m_material.setTexture(1, 0);
|
||||
|
||||
// Done.
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
// Final blit
|
||||
|
||||
if (irr_driver->getNormals())
|
||||
{
|
||||
m_material.MaterialType = irr_driver->getShader(ES_FLIP);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL));
|
||||
} else if (irr_driver->getSSAOViz())
|
||||
{
|
||||
m_material.MaterialType = irr_driver->getShader(ES_FLIP);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO1));
|
||||
} else if (irr_driver->getShadowViz())
|
||||
{
|
||||
m_material.MaterialType = irr_driver->getShader(ES_FLIP);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_SHADOW));
|
||||
} else
|
||||
{
|
||||
m_material.MaterialType = irr_driver->getShader(ES_FLIP);
|
||||
m_material.setTexture(0, in);
|
||||
}
|
||||
|
||||
drv->setRenderTarget(ERT_FRAME_BUFFER, false, false);
|
||||
|
||||
drawQuad(cam, m_material);
|
||||
}
|
||||
} // render
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Implement IShaderConstantsSetCallback. Shader constants setter for
|
||||
* post-processing */
|
||||
void PostProcessing::OnSetConstants(video::IMaterialRendererServices *services,
|
||||
s32 user_data)
|
||||
void PostProcessing::drawQuad(u32 cam, const SMaterial &mat)
|
||||
{
|
||||
// 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);
|
||||
const u16 indices[6] = {0, 1, 2, 3, 0, 2};
|
||||
IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
// Scale the boost time to get a usable boost amount:
|
||||
float boost_amount = m_boost_time[m_current_camera] * 0.7f;
|
||||
drv->setTransform(ETS_WORLD, core::IdentityMatrix);
|
||||
drv->setTransform(ETS_VIEW, core::IdentityMatrix);
|
||||
drv->setTransform(ETS_PROJECTION, core::IdentityMatrix);
|
||||
|
||||
// Especially for single screen the top of the screen is less blurred
|
||||
// in the fragment shader by multiplying the blurr factor by
|
||||
// (max_tex_height - texcoords.t), where max_tex_height is the maximum
|
||||
// texture coordinate (1.0 or 0.5). In split screen this factor is too
|
||||
// small (half the value compared with non-split screen), so we
|
||||
// multiply this by 2.
|
||||
if(m_boost_time.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
|
||||
drv->setMaterial(mat);
|
||||
drv->drawIndexedTriangleList(&(m_vertices[cam].v0),
|
||||
4, indices, 2);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2011-2013 the SuperTuxKart team
|
||||
// Copyright (C) 2013 Joerg Henrichs
|
||||
// Copyright (C) 2011-2013 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
|
||||
@ -34,61 +33,58 @@ using namespace irr;
|
||||
/** \brief Handles post processing, eg motion blur
|
||||
* \ingroup graphics
|
||||
*/
|
||||
class PostProcessing : public video::IShaderConstantSetCallBack
|
||||
class PostProcessing: public IReferenceCounted
|
||||
{
|
||||
private:
|
||||
video::ITexture *m_render_target;
|
||||
/** Material to be used when blurring is used. */
|
||||
video::SMaterial m_blur_material;
|
||||
|
||||
bool m_supported;
|
||||
video::SMaterial m_material;
|
||||
|
||||
/** Boost time, how long the boost should be displayed. This also
|
||||
* affects the strength of the effect: longer boost time will
|
||||
* have a stronger effect. */
|
||||
std::vector<float> m_boost_time;
|
||||
|
||||
bool m_any_boost;
|
||||
|
||||
/** 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;
|
||||
|
||||
video::ITexture *m_areamap;
|
||||
|
||||
u32 m_sunpixels;
|
||||
|
||||
void setMotionBlurCenterY(const u32 num, const float y);
|
||||
|
||||
public:
|
||||
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 begin();
|
||||
void update(float dt);
|
||||
|
||||
/** Render the post-processed scene, solids only, color to color, no stencil */
|
||||
void renderSolid(const u32 cam);
|
||||
|
||||
/** Render the post-processed scene */
|
||||
void render();
|
||||
|
||||
/** Is the hardware able to use post-processing? */
|
||||
inline bool isSupported() const {return m_supported;}
|
||||
/** Draw the quad for this camera */
|
||||
void drawQuad(u32 cam, const video::SMaterial &mat);
|
||||
|
||||
/** Use motion blur for a short time */
|
||||
void giveBoost(unsigned int cam_index);
|
||||
|
||||
/** Implement IShaderConstantsSetCallback. Shader constants setter for post-processing */
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *services, s32 user_data);
|
||||
void setSunPixels(const u32 in) { m_sunpixels = in; }
|
||||
};
|
||||
|
||||
#endif // HEADER_POST_PROCESSING_HPP
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user