Huge merge from trunk, part 1.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/battleAI@14659 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
@@ -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 \
|
||||
@@ -518,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 = \
|
||||
|
||||
209
src/achievements/achievement.cpp
Normal file
209
src/achievements/achievement.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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 "achievements/achievement.hpp"
|
||||
|
||||
#include "achievements/achievement_info.hpp"
|
||||
#include "guiengine/dialog_queue.hpp"
|
||||
#include "states_screens/dialogs/notification_dialog.hpp"
|
||||
#include "io/xml_writer.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
// ============================================================================
|
||||
Achievement::Achievement(const AchievementInfo * info)
|
||||
:m_achievement_info(info)
|
||||
{
|
||||
m_id = info->getID();
|
||||
m_achieved = false;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
Achievement::~Achievement()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void Achievement::onRaceEnd()
|
||||
{
|
||||
if(m_achievement_info->needsResetAfterRace())
|
||||
this->reset();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void Achievement::check()
|
||||
{
|
||||
if(m_achieved)
|
||||
return;
|
||||
|
||||
if(m_achievement_info->checkCompletion(this))
|
||||
{
|
||||
//show achievement
|
||||
GUIEngine::DialogQueue::get()->pushDialog(
|
||||
new NotificationDialog(NotificationDialog::T_Achievements,
|
||||
irr::core::stringw(_("Completed achievement")) + irr::core::stringw(" \"") + m_achievement_info->getTitle() + irr::core::stringw("\".")
|
||||
));
|
||||
//send to server
|
||||
Online::CurrentUser::get()->onAchieving(m_id);
|
||||
m_achieved = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
SingleAchievement::SingleAchievement(const AchievementInfo * info)
|
||||
: Achievement(info)
|
||||
{
|
||||
m_progress = 0;
|
||||
m_achieved = false;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void SingleAchievement::load(XMLNode * input)
|
||||
{
|
||||
std::string achieved("");
|
||||
input->get("achieved", &achieved);
|
||||
if(achieved == "true")
|
||||
{
|
||||
m_achieved = true;
|
||||
return;
|
||||
}
|
||||
input->get("value", &m_progress);
|
||||
}
|
||||
// ============================================================================
|
||||
void SingleAchievement::save(std::ofstream & out)
|
||||
{
|
||||
out << " <achievement id=\"" << m_id << "\" "
|
||||
<< "achieved=\"" << StringUtils::boolstr(m_achieved) << "\"";
|
||||
if(!m_achieved)
|
||||
{
|
||||
out << " value=\"" << StringUtils::toString(m_progress) << "\"";
|
||||
}
|
||||
out << "/>\n";
|
||||
} // save
|
||||
|
||||
// ============================================================================
|
||||
void SingleAchievement::reset()
|
||||
{
|
||||
m_progress = 0;
|
||||
} // reset
|
||||
|
||||
// ============================================================================
|
||||
void SingleAchievement::increase(int increase)
|
||||
{
|
||||
m_progress += increase;
|
||||
check();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
irr::core::stringw SingleAchievement::getProgressAsString()
|
||||
{
|
||||
return StringUtils::toWString(m_progress) + "/" + StringUtils::toWString(((SingleAchievementInfo *) m_achievement_info)->getGoalValue());
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
MapAchievement::MapAchievement(const AchievementInfo * info)
|
||||
: Achievement(info)
|
||||
{
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void MapAchievement::load(XMLNode * input)
|
||||
{
|
||||
std::string achieved("");
|
||||
input->get("achieved", &achieved);
|
||||
if(achieved == "true")
|
||||
{
|
||||
m_achieved = true;
|
||||
return;
|
||||
}
|
||||
std::vector<XMLNode*> xml_entries;
|
||||
input->getNodes("entry", xml_entries);
|
||||
for (unsigned int n=0; n < xml_entries.size(); n++)
|
||||
{
|
||||
std::string key("");
|
||||
xml_entries[n]->get("key", &key);
|
||||
int value(0);
|
||||
xml_entries[n]->get("value", &value);
|
||||
m_progress_map[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void MapAchievement::save(std::ofstream & out)
|
||||
{
|
||||
out << " <achievement id=\"" << m_id << "\" achieved=\"" << StringUtils::boolstr(m_achieved) << "\">\n";
|
||||
if(!m_achieved)
|
||||
{
|
||||
std::map<std::string, int>::iterator iter;
|
||||
for ( iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter ) {
|
||||
out << " <entry key=\"" << iter->first.c_str() << "\" value=\"" << StringUtils::toString(iter->second) << "\"/>\n";
|
||||
}
|
||||
}
|
||||
out << " </achievement>\n";
|
||||
} // save
|
||||
|
||||
// ============================================================================
|
||||
|
||||
int MapAchievement::getValue(const std::string & key)
|
||||
{
|
||||
if ( m_progress_map.find(key) != m_progress_map.end())
|
||||
return m_progress_map[key];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
void MapAchievement::reset()
|
||||
{
|
||||
std::map<std::string, int>::iterator iter;
|
||||
for ( iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter ) {
|
||||
iter->second = 0;
|
||||
}
|
||||
} // reset
|
||||
|
||||
// ============================================================================
|
||||
void MapAchievement::increase(const std::string & key, int increase)
|
||||
{
|
||||
if ( m_progress_map.find(key) != m_progress_map.end())
|
||||
{
|
||||
m_progress_map[key] += increase;
|
||||
check();
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
irr::core::stringw MapAchievement::getProgressAsString()
|
||||
{
|
||||
int progress(0);
|
||||
int goal(0);
|
||||
const std::map<std::string, int> goal_values = ((MapAchievementInfo *) m_achievement_info)->getGoalValues();
|
||||
std::map<std::string, int>::const_iterator iter;
|
||||
for ( iter = goal_values.begin(); iter != goal_values.end(); ++iter ) {
|
||||
goal += iter->second;
|
||||
progress += m_progress_map[iter->first];
|
||||
}
|
||||
return StringUtils::toWString(progress) + "/" + StringUtils::toWString(goal);
|
||||
}
|
||||
|
||||
101
src/achievements/achievement.hpp
Normal file
101
src/achievements/achievement.hpp
Normal file
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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_ACHIEVEMENT_HPP
|
||||
#define HEADER_ACHIEVEMENT_HPP
|
||||
|
||||
#include "utils/types.hpp"
|
||||
|
||||
#include <irrString.h>
|
||||
#include <string>
|
||||
#include "io/xml_node.hpp"
|
||||
|
||||
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* \brief
|
||||
* \ingroup
|
||||
*/
|
||||
class AchievementInfo;
|
||||
|
||||
class Achievement
|
||||
{
|
||||
protected:
|
||||
uint32_t m_id;
|
||||
bool m_achieved;
|
||||
const AchievementInfo * m_achievement_info;
|
||||
void check ();
|
||||
|
||||
public:
|
||||
Achievement (const AchievementInfo * info);
|
||||
virtual ~Achievement ();
|
||||
uint32_t getID () const { return m_id; }
|
||||
const AchievementInfo * getInfo () const { return m_achievement_info;}
|
||||
virtual void load (XMLNode * input) = 0;
|
||||
virtual void save (std::ofstream & out) = 0;
|
||||
virtual void reset () = 0;
|
||||
void onRaceEnd ();
|
||||
void setAchieved () {m_achieved = true; };
|
||||
virtual irr::core::stringw getProgressAsString () = 0;
|
||||
|
||||
enum AchievementType
|
||||
{
|
||||
AT_SINGLE,
|
||||
AT_MAP
|
||||
};
|
||||
|
||||
}; // class Achievement
|
||||
|
||||
class SingleAchievement : public Achievement
|
||||
{
|
||||
protected:
|
||||
int m_progress;
|
||||
|
||||
public:
|
||||
SingleAchievement (const AchievementInfo * info);
|
||||
virtual ~SingleAchievement () {};
|
||||
|
||||
void load (XMLNode * input);
|
||||
int getValue () const { return m_progress; }
|
||||
void save (std::ofstream & out);
|
||||
void increase (int increase = 1);
|
||||
void reset ();
|
||||
virtual irr::core::stringw getProgressAsString ();
|
||||
}; // class SingleAchievement
|
||||
|
||||
class MapAchievement : public Achievement
|
||||
{
|
||||
protected:
|
||||
std::map<std::string, int> m_progress_map;
|
||||
|
||||
public:
|
||||
MapAchievement (const AchievementInfo * info);
|
||||
virtual ~MapAchievement () {};
|
||||
|
||||
void load (XMLNode * input);
|
||||
int getValue (const std::string & key);
|
||||
void increase (const std::string & key, int increase = 1);
|
||||
void save (std::ofstream & out);
|
||||
void reset ();
|
||||
virtual irr::core::stringw getProgressAsString ();
|
||||
}; // class MapAchievement
|
||||
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
||||
87
src/achievements/achievement_info.cpp
Normal file
87
src/achievements/achievement_info.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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 "achievements/achievement_info.hpp"
|
||||
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "io/xml_writer.hpp"
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
// ============================================================================
|
||||
AchievementInfo::AchievementInfo(const XMLNode * input)
|
||||
{
|
||||
input->get("id", &m_id);
|
||||
input->get("title", &m_title);
|
||||
input->get("description", &m_description);
|
||||
|
||||
std::string reset_after_race("");
|
||||
input->get("reset_after_race", &reset_after_race);
|
||||
m_reset_after_race = reset_after_race == "true";
|
||||
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
SingleAchievementInfo::SingleAchievementInfo(const XMLNode * input)
|
||||
: AchievementInfo(input)
|
||||
{
|
||||
input->get("goal", &m_goal_value);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
bool SingleAchievementInfo::checkCompletion(Achievement * achievement) const
|
||||
{
|
||||
SingleAchievement * single_achievement = (SingleAchievement *) achievement;
|
||||
if(single_achievement->getValue() >= m_goal_value)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
MapAchievementInfo::MapAchievementInfo(const XMLNode * input)
|
||||
: AchievementInfo(input)
|
||||
{
|
||||
std::vector<XMLNode*> xml_entries;
|
||||
input->getNodes("entry", xml_entries);
|
||||
for (unsigned int n=0; n < xml_entries.size(); n++)
|
||||
{
|
||||
std::string key("");
|
||||
xml_entries[n]->get("key", &key);
|
||||
int goal(0);
|
||||
xml_entries[n]->get("goal", &goal);
|
||||
m_goal_values[key] = goal;
|
||||
}
|
||||
if(m_goal_values.size() != xml_entries.size())
|
||||
Log::error("MapAchievementInfo","Duplicate keys for the entries of a MapAchievement found.");
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
bool MapAchievementInfo::checkCompletion(Achievement * achievement) const
|
||||
{
|
||||
MapAchievement * map_achievement = (MapAchievement *) achievement;
|
||||
std::map<std::string, int>::const_iterator iter;
|
||||
for ( iter = m_goal_values.begin(); iter != m_goal_values.end(); iter++ ) {
|
||||
if(map_achievement->getValue(iter->first) < iter->second)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
87
src/achievements/achievement_info.hpp
Normal file
87
src/achievements/achievement_info.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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_ACHIEVEMENT_INFO_HPP
|
||||
#define HEADER_ACHIEVEMENT_INFO_HPP
|
||||
|
||||
#include "utils/types.hpp"
|
||||
|
||||
#include <irrString.h>
|
||||
#include <string>
|
||||
#include "io/xml_node.hpp"
|
||||
#include "achievements/achievement.hpp"
|
||||
|
||||
|
||||
// ============================================================================
|
||||
|
||||
class Achievement;
|
||||
|
||||
/**
|
||||
* \brief
|
||||
* \ingroup
|
||||
*/
|
||||
class AchievementInfo
|
||||
{
|
||||
protected:
|
||||
uint32_t m_id;
|
||||
irr::core::stringw m_title;
|
||||
irr::core::stringw m_description;
|
||||
bool m_reset_after_race;
|
||||
|
||||
public:
|
||||
AchievementInfo (const XMLNode * input);
|
||||
virtual ~AchievementInfo () {};
|
||||
uint32_t getID () const { return m_id; }
|
||||
irr::core::stringw getDescription () const { return m_description; }
|
||||
irr::core::stringw getTitle () const { return m_title; }
|
||||
virtual Achievement::AchievementType getType () const = 0;
|
||||
virtual bool checkCompletion (Achievement * achievement) const = 0;
|
||||
bool needsResetAfterRace() const {return m_reset_after_race; }
|
||||
}; // class AchievementInfo
|
||||
|
||||
class SingleAchievementInfo : public AchievementInfo
|
||||
{
|
||||
protected:
|
||||
int m_goal_value;
|
||||
|
||||
public:
|
||||
SingleAchievementInfo (const XMLNode * input);
|
||||
virtual ~SingleAchievementInfo () {};
|
||||
int getGoalValue () const { return m_goal_value; }
|
||||
virtual bool checkCompletion (Achievement * achievement) const;
|
||||
|
||||
virtual Achievement::AchievementType getType() const { return Achievement::AT_SINGLE; };
|
||||
}; // class SingleAchievementInfo
|
||||
|
||||
class MapAchievementInfo : public AchievementInfo
|
||||
{
|
||||
protected:
|
||||
std::map<std::string, int> m_goal_values;
|
||||
|
||||
public:
|
||||
MapAchievementInfo (const XMLNode * input);
|
||||
virtual ~MapAchievementInfo () {};
|
||||
int getGoalValue (const std::string & key) { return m_goal_values[key];}
|
||||
const std::map<std::string, int> & getGoalValues() const {return m_goal_values;}
|
||||
virtual bool checkCompletion (Achievement * achievement) const;
|
||||
virtual Achievement::AchievementType getType() const { return Achievement::AT_MAP; };
|
||||
}; // class MapAchievementInfo
|
||||
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
||||
247
src/achievements/achievements_manager.cpp
Normal file
247
src/achievements/achievements_manager.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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 "achievements/achievements_manager.hpp"
|
||||
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "io/xml_writer.hpp"
|
||||
#include "config/player.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
static AchievementsManager* achievements_manager_singleton(NULL);
|
||||
|
||||
AchievementsManager* AchievementsManager::get()
|
||||
{
|
||||
if (achievements_manager_singleton == NULL)
|
||||
achievements_manager_singleton = new AchievementsManager();
|
||||
return achievements_manager_singleton;
|
||||
}
|
||||
|
||||
void AchievementsManager::deallocate()
|
||||
{
|
||||
delete achievements_manager_singleton;
|
||||
achievements_manager_singleton = NULL;
|
||||
} // deallocate
|
||||
|
||||
// ============================================================================
|
||||
AchievementsManager::AchievementsManager()
|
||||
{
|
||||
parseDataFile();
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
void AchievementsManager::init()
|
||||
{
|
||||
parseConfigFile();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
AchievementsManager::~AchievementsManager()
|
||||
{
|
||||
save();
|
||||
m_slots.clearAndDeleteAll();
|
||||
std::map<uint32_t, AchievementInfo *>::iterator it;
|
||||
for ( it = m_achievements_info.begin(); it != m_achievements_info.end(); ++it ) {
|
||||
delete it->second;
|
||||
}
|
||||
m_achievements_info.clear();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void AchievementsManager::parseDataFile()
|
||||
{
|
||||
const std::string file_name = file_manager->getDataFile("achievements.xml");
|
||||
const XMLNode *root = file_manager->createXMLTree(file_name);
|
||||
unsigned int num_nodes = root->getNumNodes();
|
||||
for(unsigned int i = 0; i < num_nodes; i++)
|
||||
{
|
||||
const XMLNode *node = root->getNode(i);
|
||||
std::string type("");
|
||||
node->get("type", &type);
|
||||
AchievementInfo * achievement_info;
|
||||
if(type == "single")
|
||||
{
|
||||
achievement_info = new SingleAchievementInfo(node);
|
||||
}
|
||||
else if(type == "map")
|
||||
{
|
||||
achievement_info = new MapAchievementInfo(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("AchievementsManager::parseAchievements","Non-existent achievement type. Skipping - definitely results in unwanted behaviour.");
|
||||
continue;
|
||||
}
|
||||
m_achievements_info[achievement_info->getID()] = achievement_info;
|
||||
}
|
||||
if(num_nodes != m_achievements_info.size())
|
||||
Log::error("AchievementsManager::parseAchievements","Multiple achievements with the same id!");
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
void AchievementsManager::parseConfigFile()
|
||||
{
|
||||
const std::string filename=file_manager->getConfigFile("achievements.xml");
|
||||
XMLNode* root = file_manager->createXMLTree(filename);
|
||||
if(!root || root->getName() != "achievements")
|
||||
{
|
||||
Log::info("AchievementsManager", "Achievements file '%s' will be created.",filename.c_str());
|
||||
createSlotsIfNeeded();
|
||||
if (root) delete root;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<XMLNode*> xml_slots;
|
||||
root->getNodes("slot", xml_slots);
|
||||
for (unsigned int n=0; n < xml_slots.size(); n++)
|
||||
{
|
||||
AchievementsSlot * slot = new AchievementsSlot(xml_slots[n]);
|
||||
if(!slot->isValid())
|
||||
{
|
||||
Log::warn("AchievementsManager", "Found game slot with faulty or missing information. Discarding it.");
|
||||
delete slot;
|
||||
continue;
|
||||
}
|
||||
m_slots.push_back(slot);
|
||||
}
|
||||
delete root;
|
||||
} // load
|
||||
|
||||
|
||||
AchievementsSlot * AchievementsManager::createNewSlot(std::string id, bool online)
|
||||
{
|
||||
AchievementsSlot* slot = new AchievementsSlot(id, online);
|
||||
m_slots.push_back(slot);
|
||||
return slot;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Creates a slot for players that don't have one yet
|
||||
* \return true if any were created
|
||||
*/
|
||||
void AchievementsManager::createSlotsIfNeeded()
|
||||
{
|
||||
bool something_changed = false;
|
||||
|
||||
// make sure all players have at least one game slot associated
|
||||
PtrVector<PlayerProfile>& players = UserConfigParams::m_all_players;
|
||||
for (int n=0; n<players.size(); n++)
|
||||
{
|
||||
if (getSlot(players[n].getUniqueID(), false) == NULL )
|
||||
{
|
||||
createNewSlot(players[n].getUniqueID(), false);
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(something_changed){
|
||||
save();
|
||||
}
|
||||
} // UnlockManager::createSlotsIfNeeded
|
||||
|
||||
|
||||
// ============================================================================
|
||||
void AchievementsManager::save()
|
||||
{
|
||||
std::string filename = file_manager->getConfigFile("achievements.xml");
|
||||
|
||||
std::ofstream achievements_file(filename.c_str(), std::ios::out);
|
||||
|
||||
if (!achievements_file.is_open())
|
||||
{
|
||||
Log::warn("AchievementsManager::save",
|
||||
"Failed to open '%s' for writing, achievements won't be saved\n",
|
||||
filename.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
achievements_file << "<?xml version=\"1.0\"?>\n";
|
||||
achievements_file << "<achievements>\n";
|
||||
|
||||
for (int i = 0; i < m_slots.size(); i++)
|
||||
{
|
||||
m_slots[i].save(achievements_file);
|
||||
}
|
||||
|
||||
achievements_file << "</achievements>\n\n";
|
||||
achievements_file.close();
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
void AchievementsManager::onRaceEnd()
|
||||
{
|
||||
//reset all values that need to be reset
|
||||
m_active_slot->onRaceEnd();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
AchievementsSlot * AchievementsManager::getSlot(const std::string & id, bool online)
|
||||
{
|
||||
for(int i = 0; i < m_slots.size(); i++)
|
||||
{
|
||||
if(m_slots[i].isOnline() == online && m_slots[i].getID() == id)
|
||||
{
|
||||
return m_slots.get(i);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void AchievementsManager::updateCurrentPlayer()
|
||||
{
|
||||
if(Online::CurrentUser::get()->isRegisteredUser())
|
||||
{
|
||||
m_active_slot = getSlot(StringUtils::toString(Online::CurrentUser::get()->getID()), true);
|
||||
if(m_active_slot == NULL)
|
||||
{
|
||||
m_active_slot = createNewSlot(StringUtils::toString(Online::CurrentUser::get()->getID()), true);
|
||||
save();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_active_slot = getSlot(unlock_manager->getCurrentPlayer()->getUniqueID(), false);
|
||||
if(m_active_slot == NULL)
|
||||
{
|
||||
m_active_slot = createNewSlot(unlock_manager->getCurrentPlayer()->getUniqueID(), false);
|
||||
save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
AchievementInfo * AchievementsManager::getAchievementInfo(uint32_t id)
|
||||
{
|
||||
if ( m_achievements_info.find(id) != m_achievements_info.end())
|
||||
return m_achievements_info[id];
|
||||
return NULL;
|
||||
}
|
||||
70
src/achievements/achievements_manager.hpp
Normal file
70
src/achievements/achievements_manager.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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_ACHIEVEMENTS_MANAGER_HPP
|
||||
#define HEADER_ACHIEVEMENTS_MANAGER_HPP
|
||||
|
||||
#include "utils/types.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include "achievements/achievement_info.hpp"
|
||||
#include "achievements/achievements_slot.hpp"
|
||||
|
||||
|
||||
#include <irrString.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* \brief Class that takes care of online profiles
|
||||
* \ingroup online
|
||||
*/
|
||||
class AchievementsManager
|
||||
{
|
||||
private :
|
||||
AchievementsSlot * m_active_slot;
|
||||
PtrVector<AchievementsSlot> m_slots;
|
||||
std::map<uint32_t, AchievementInfo *> m_achievements_info;
|
||||
AchievementsManager ();
|
||||
~AchievementsManager ();
|
||||
AchievementsSlot * createNewSlot(std::string id, bool online);
|
||||
void parseDataFile();
|
||||
void parseConfigFile();
|
||||
|
||||
public:
|
||||
/**Singleton */
|
||||
static AchievementsManager * get();
|
||||
static void deallocate();
|
||||
|
||||
void init();
|
||||
void save();
|
||||
void onRaceEnd();
|
||||
void updateCurrentPlayer();
|
||||
AchievementsSlot * getActive() const { return m_active_slot; }
|
||||
AchievementsSlot * getSlot(const std::string & id, bool online);
|
||||
void createSlotsIfNeeded();
|
||||
AchievementInfo * getAchievementInfo(uint32_t id);
|
||||
const std::map<uint32_t, AchievementInfo *> & getAllInfo() { return m_achievements_info;}
|
||||
}; // class AchievementsManager
|
||||
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
||||
153
src/achievements/achievements_slot.cpp
Normal file
153
src/achievements/achievements_slot.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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 "achievements/achievements_slot.hpp"
|
||||
|
||||
#include "achievements/achievement_info.hpp"
|
||||
#include "achievements/achievements_manager.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "io/xml_writer.hpp"
|
||||
#include "online/current_user.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
// ============================================================================
|
||||
AchievementsSlot::AchievementsSlot(const XMLNode * input)
|
||||
{
|
||||
int fetched_user_id = input->get("user_id", &m_id);
|
||||
std::string online;
|
||||
int fetched_online = input->get("online", &online);
|
||||
if(!fetched_user_id || !fetched_online || !(online == "true" || online == "false"))
|
||||
{
|
||||
m_valid = false;
|
||||
}
|
||||
m_valid = true;
|
||||
m_online = online == "true";
|
||||
|
||||
createFreshSlot();
|
||||
|
||||
std::vector<XMLNode*> xml_achievements;
|
||||
input->getNodes("achievement", xml_achievements);
|
||||
for( unsigned int i=0; i<xml_achievements.size(); i++)
|
||||
{
|
||||
uint32_t achievement_id(0);
|
||||
xml_achievements[i]->get("id", &achievement_id);
|
||||
Achievement * achievement = getAchievement(achievement_id);
|
||||
if(achievement == NULL)
|
||||
{
|
||||
Log::warn("AchievementsSlot", "Found saved achievement data for a non-existent achievement. Discarding.");
|
||||
continue;
|
||||
}
|
||||
achievement->load(xml_achievements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
AchievementsSlot::AchievementsSlot(std::string id, bool online)
|
||||
{
|
||||
m_valid = true;
|
||||
m_online = online;
|
||||
m_id = id;
|
||||
|
||||
createFreshSlot();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
AchievementsSlot::~AchievementsSlot()
|
||||
{
|
||||
deleteAchievements();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void AchievementsSlot::deleteAchievements()
|
||||
{
|
||||
std::map<uint32_t, Achievement *>::iterator it;
|
||||
for ( it = m_achievements.begin(); it != m_achievements.end(); ++it ) {
|
||||
delete it->second;
|
||||
}
|
||||
m_achievements.clear();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void AchievementsSlot::createFreshSlot()
|
||||
{
|
||||
deleteAchievements();
|
||||
const std::map<uint32_t, AchievementInfo *> all_info = AchievementsManager::get()->getAllInfo();
|
||||
std::map<uint32_t, AchievementInfo *>::const_iterator it;
|
||||
for ( it = all_info.begin(); it != all_info.end(); ++it ) {
|
||||
Achievement::AchievementType achievement_type = it->second->getType();
|
||||
Achievement * achievement;
|
||||
if(achievement_type == Achievement::AT_SINGLE)
|
||||
{
|
||||
achievement = new SingleAchievement(it->second);
|
||||
}
|
||||
else if(achievement_type == Achievement::AT_MAP)
|
||||
{
|
||||
achievement = new MapAchievement(it->second);
|
||||
}
|
||||
m_achievements[achievement->getID()] = achievement;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void AchievementsSlot::save(std::ofstream & out)
|
||||
{
|
||||
out << " <slot user_id=\"" << m_id.c_str()
|
||||
<< "\" online=\"" << StringUtils::boolstr(m_online)
|
||||
<< "\"> \n";
|
||||
std::map<uint32_t, Achievement*>::const_iterator i;
|
||||
for(i = m_achievements.begin(); i != m_achievements.end(); i++)
|
||||
{
|
||||
if (i->second != NULL)
|
||||
i->second->save(out);
|
||||
}
|
||||
out << " </slot>\n";
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
Achievement * AchievementsSlot::getAchievement(uint32_t id)
|
||||
{
|
||||
if ( m_achievements.find(id) != m_achievements.end())
|
||||
return m_achievements[id];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void AchievementsSlot::sync(const std::vector<uint32_t> & achieved_ids)
|
||||
{
|
||||
for(unsigned int i =0; i < achieved_ids.size(); ++i)
|
||||
{
|
||||
Achievement * achievement = getAchievement(achieved_ids[i]);
|
||||
if(achievement != NULL)
|
||||
achievement->setAchieved();
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
void AchievementsSlot::onRaceEnd()
|
||||
{
|
||||
//reset all values that need to be reset
|
||||
std::map<uint32_t, Achievement *>::iterator iter;
|
||||
for ( iter = m_achievements.begin(); iter != m_achievements.end(); ++iter ) {
|
||||
iter->second->onRaceEnd();
|
||||
}
|
||||
}
|
||||
64
src/achievements/achievements_slot.hpp
Normal file
64
src/achievements/achievements_slot.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 Glenn De Jonghe
|
||||
//
|
||||
// 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_ACHIEVEMENTS_SLOT_HPP
|
||||
#define HEADER_ACHIEVEMENTS_SLOT_HPP
|
||||
|
||||
#include "utils/types.hpp"
|
||||
#include "achievements/achievement.hpp"
|
||||
#include "online/http_manager.hpp"
|
||||
|
||||
#include <irrString.h>
|
||||
#include <string>
|
||||
#include "io/xml_node.hpp"
|
||||
|
||||
|
||||
class AchievementsSlot
|
||||
{
|
||||
private:
|
||||
std::map<uint32_t, Achievement *> m_achievements;
|
||||
bool m_online;
|
||||
bool m_valid;
|
||||
std::string m_id;
|
||||
|
||||
void createFreshSlot();
|
||||
void deleteAchievements();
|
||||
|
||||
class SyncAchievementsRequest : public Online::XMLRequest {
|
||||
virtual void callback ();
|
||||
public:
|
||||
SyncAchievementsRequest() : Online::XMLRequest(true) {}
|
||||
};
|
||||
|
||||
public :
|
||||
AchievementsSlot(const XMLNode * input);
|
||||
AchievementsSlot(std::string id, bool online);
|
||||
~AchievementsSlot();
|
||||
bool isValid() const { return m_valid;}
|
||||
void save(std::ofstream & out);
|
||||
bool isOnline() const {return m_online;}
|
||||
void sync(const std::vector<uint32_t> & achieved_ids);
|
||||
void onRaceEnd();
|
||||
const std::string & getID() const {return m_id;}
|
||||
const std::map<uint32_t, Achievement *> & getAllAchievements() {return m_achievements;}
|
||||
Achievement * getAchievement(uint32_t id);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*EOF*/
|
||||
@@ -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,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
|
||||
@@ -115,7 +115,7 @@ private:
|
||||
/** Compressed size of the addon package. */
|
||||
int m_size;
|
||||
/** Rating for thsi addon package. */
|
||||
float m_rating;
|
||||
mutable float m_rating;
|
||||
/** Minimum version addon is included with. */
|
||||
std::string m_min_include_ver;
|
||||
/** Maximum version addon is included with. */
|
||||
@@ -151,6 +151,9 @@ public:
|
||||
/** Returns the rating of an addon. */
|
||||
const float getRating() const {return m_rating; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the rating of an addon. */
|
||||
void setRating(const float rating) const {m_rating = rating; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the type of the addon. */
|
||||
const std::string& getType() const { return m_type; }
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
@@ -456,22 +456,22 @@ bool AddonsManager::uninstall(const Addon &addon)
|
||||
m_addons_list.getData()[index].setInstalled(false);
|
||||
|
||||
//remove the addons directory
|
||||
bool error = false;
|
||||
// if the user deleted the data directory for an add-on with
|
||||
// filesystem tools, removeTrack/removeKart will trigger an assert
|
||||
// because the kart/track was never added in the first place
|
||||
if (file_manager->fileExists(addon.getDataDir()))
|
||||
{
|
||||
error = !file_manager->removeDirectory(addon.getDataDir());
|
||||
if(addon.getType()=="kart")
|
||||
{
|
||||
kart_properties_manager->removeKart(addon.getId());
|
||||
}
|
||||
else if(addon.getType()=="track" || addon.getType()=="arena")
|
||||
{
|
||||
track_manager->removeTrack(addon.getId());
|
||||
}
|
||||
}
|
||||
bool error = false;
|
||||
// if the user deleted the data directory for an add-on with
|
||||
// filesystem tools, removeTrack/removeKart will trigger an assert
|
||||
// because the kart/track was never added in the first place
|
||||
if (file_manager->fileExists(addon.getDataDir()))
|
||||
{
|
||||
error = !file_manager->removeDirectory(addon.getDataDir());
|
||||
if(addon.getType()=="kart")
|
||||
{
|
||||
kart_properties_manager->removeKart(addon.getId());
|
||||
}
|
||||
else if(addon.getType()=="track" || addon.getType()=="arena")
|
||||
{
|
||||
track_manager->removeTrack(addon.getId());
|
||||
}
|
||||
}
|
||||
saveInstalled();
|
||||
return !error;
|
||||
} // uninstall
|
||||
|
||||
@@ -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"
|
||||
@@ -494,19 +487,19 @@ CURLcode NetworkHttp::downloadFileInternal(Request *request)
|
||||
|
||||
curl_easy_setopt(m_curl_session, CURLOPT_URL, full_url.c_str());
|
||||
std::string uagent = (std::string)"SuperTuxKart/" + STK_VERSION;
|
||||
// Add platform to user-agent string for informational purposes.
|
||||
// Add more cases as necessary.
|
||||
#ifdef WIN32
|
||||
uagent += (std::string)" (Windows)";
|
||||
#elif defined(__APPLE__)
|
||||
uagent += (std::string)" (Macintosh)";
|
||||
#elif defined(__FreeBSD__)
|
||||
uagent += (std::string)" (FreeBSD)";
|
||||
#elif defined(linux)
|
||||
uagent += (std::string)" (Linux)";
|
||||
#else
|
||||
// Unknown system type
|
||||
#endif
|
||||
// Add platform to user-agent string for informational purposes.
|
||||
// Add more cases as necessary.
|
||||
#ifdef WIN32
|
||||
uagent += (std::string)" (Windows)";
|
||||
#elif defined(__APPLE__)
|
||||
uagent += (std::string)" (Macintosh)";
|
||||
#elif defined(__FreeBSD__)
|
||||
uagent += (std::string)" (FreeBSD)";
|
||||
#elif defined(linux)
|
||||
uagent += (std::string)" (Linux)";
|
||||
#else
|
||||
// Unknown system type
|
||||
#endif
|
||||
curl_easy_setopt(m_curl_session, CURLOPT_USERAGENT, uagent.c_str());
|
||||
curl_easy_setopt(m_curl_session, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSDATA, request);
|
||||
|
||||
@@ -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
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <vector>
|
||||
|
||||
#ifdef WIN32
|
||||
# include <winsock2.h>
|
||||
# include <WinSock2.h>
|
||||
#endif
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
@@ -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) 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,15 +19,11 @@
|
||||
#include "animations/ipo.hpp"
|
||||
|
||||
#include "io/xml_node.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
|
||||
# define isnan _isnan
|
||||
#else
|
||||
# include <math.h>
|
||||
#endif
|
||||
#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
|
||||
|
||||
@@ -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
|
||||
@@ -307,7 +307,7 @@ SFXBase* SFXManager::createSoundSource(SFXBuffer* buffer,
|
||||
// race_manager->getNumLocalPlayers(), buffer->isPositional());
|
||||
|
||||
#if HAVE_OGGVORBIS
|
||||
assert( alIsBuffer(buffer->getBufferID()) );
|
||||
//assert( alIsBuffer(buffer->getBufferID()) ); crashes on server
|
||||
SFXBase* sfx = new SFXOpenAL(buffer, positional, buffer->getGain(), owns_buffer);
|
||||
#else
|
||||
SFXBase* sfx = new DummySFX(buffer, positional, buffer->getGain(), owns_buffer);
|
||||
|
||||
@@ -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>
|
||||
// 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
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <OpenAL/al.h>
|
||||
@@ -33,16 +34,10 @@
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.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()
|
||||
{
|
||||
m_soundBuffer = buffer;
|
||||
|
||||
@@ -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
|
||||
@@ -90,17 +90,11 @@ void Challenge::setSolved(RaceManager::Difficulty d)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
const char* boolstr(bool b)
|
||||
{
|
||||
return (b ? "true" : "false");
|
||||
}
|
||||
|
||||
void Challenge::save(std::ofstream& writer)
|
||||
{
|
||||
writer << " <" << m_data->getId().c_str() << ">\n"
|
||||
<< " <easy solved=\"" << boolstr(isSolved(RaceManager::DIFFICULTY_EASY)) << "\"/>\n"
|
||||
<< " <medium solved=\"" << boolstr(isSolved(RaceManager::DIFFICULTY_MEDIUM)) << "\"/>\n"
|
||||
<< " <hard solved=\"" << boolstr(isSolved(RaceManager::DIFFICULTY_HARD)) << "\"/>\n"
|
||||
<< " <easy solved=\"" << StringUtils::boolstr(isSolved(RaceManager::DIFFICULTY_EASY)) << "\"/>\n"
|
||||
<< " <medium solved=\"" << StringUtils::boolstr(isSolved(RaceManager::DIFFICULTY_MEDIUM)) << "\"/>\n"
|
||||
<< " <hard solved=\"" << StringUtils::boolstr(isSolved(RaceManager::DIFFICULTY_HARD)) << "\"/>\n"
|
||||
<< " </" << m_data->getId().c_str() << ">\n";
|
||||
} // save
|
||||
|
||||
@@ -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
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "achievements/achievements_manager.hpp"
|
||||
#include "audio/sfx_base.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "config/player.hpp"
|
||||
@@ -204,7 +205,7 @@ const ChallengeData* UnlockManager::getChallenge(const std::string& id)
|
||||
*/
|
||||
void UnlockManager::load()
|
||||
{
|
||||
const std::string filename=file_manager->getChallengeFile("challenges.xml");
|
||||
const std::string filename=file_manager->getConfigFile("challenges.xml");
|
||||
XMLNode* root = file_manager->createXMLTree(filename);
|
||||
if(!root || root->getName() != "challenges")
|
||||
{
|
||||
@@ -263,7 +264,7 @@ void UnlockManager::load()
|
||||
|
||||
void UnlockManager::save()
|
||||
{
|
||||
std::string filename = file_manager->getChallengeFile("challenges.xml");
|
||||
std::string filename = file_manager->getConfigFile("challenges.xml");
|
||||
|
||||
std::ofstream challenge_file(filename.c_str(), std::ios::out);
|
||||
|
||||
@@ -421,6 +422,15 @@ void UnlockManager::updateActiveChallengeList()
|
||||
getCurrentSlot()->computeActive();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void UnlockManager::setCurrentSlot(std::string slotid)
|
||||
{
|
||||
m_current_game_slot = slotid;
|
||||
AchievementsManager::get()->updateCurrentPlayer();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void UnlockManager::findWhatWasUnlocked(int points_before, int points_now,
|
||||
|
||||
@@ -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
|
||||
@@ -82,8 +82,7 @@ public:
|
||||
}
|
||||
|
||||
/** \param slotid name of the player */
|
||||
void setCurrentSlot(std::string slotid) { m_current_game_slot = slotid; }
|
||||
|
||||
void setCurrentSlot(std::string slotid);
|
||||
void findWhatWasUnlocked(int pointsBefore, int pointsNow,
|
||||
std::vector<std::string>& tracks,
|
||||
std::vector<std::string>& gps);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,19 @@ 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_banana_glow_color[0] = 1.0f;
|
||||
m_banana_glow_color[1] = 1.0f;
|
||||
m_banana_glow_color[2] = 1.0f;
|
||||
m_bubblegum_glow_color[0] = 1.0f;
|
||||
m_bubblegum_glow_color[1] = 1.0f;
|
||||
m_bubblegum_glow_color[2] = 1.0f;
|
||||
|
||||
m_score_increase.clear();
|
||||
m_leader_intervals.clear();
|
||||
m_switch_items.clear();
|
||||
@@ -362,6 +375,39 @@ 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;
|
||||
}
|
||||
|
||||
if (colors->get("banana", &tmpcol))
|
||||
{
|
||||
m_banana_glow_color[0] = tmpcol.getRed() / 255.0f;
|
||||
m_banana_glow_color[1] = tmpcol.getGreen() / 255.0f;
|
||||
m_banana_glow_color[2] = tmpcol.getBlue() / 255.0f;
|
||||
}
|
||||
|
||||
if (colors->get("bubblegum", &tmpcol))
|
||||
{
|
||||
m_bubblegum_glow_color[0] = tmpcol.getRed() / 255.0f;
|
||||
m_bubblegum_glow_color[1] = tmpcol.getGreen() / 255.0f;
|
||||
m_bubblegum_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,12 @@ public:
|
||||
* be generated. */
|
||||
float m_replay_delta_angle;
|
||||
|
||||
/** Colors for glows */
|
||||
float m_nitro_glow_color[3];
|
||||
float m_box_glow_color[3];
|
||||
float m_banana_glow_color[3];
|
||||
float m_bubblegum_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
|
||||
@@ -182,6 +182,162 @@ void GroupUserConfigParam::addChild(UserConfigParam* child)
|
||||
} // addChild
|
||||
|
||||
|
||||
// ============================================================================
|
||||
template<typename T>
|
||||
ListUserConfigParam<T>::ListUserConfigParam(const char* param_name,
|
||||
const char* comment)
|
||||
{
|
||||
m_param_name = param_name;
|
||||
all_params.push_back(this);
|
||||
if(comment != NULL) m_comment = comment;
|
||||
} // ListUserConfigParam
|
||||
|
||||
// ============================================================================
|
||||
template<typename T>
|
||||
ListUserConfigParam<T>::ListUserConfigParam(const char* param_name,
|
||||
const char* comment,
|
||||
int nb_elements,
|
||||
...)
|
||||
{
|
||||
m_param_name = param_name;
|
||||
all_params.push_back(this);
|
||||
if(comment != NULL) m_comment = comment;
|
||||
|
||||
// add the default list
|
||||
va_list arguments;
|
||||
va_start ( arguments, nb_elements );
|
||||
for ( int i = 0; i < nb_elements; i++ )
|
||||
m_elements.push_back(va_arg ( arguments, T ));
|
||||
va_end ( arguments ); // Cleans up the list
|
||||
} // ListUserConfigParam
|
||||
|
||||
// ============================================================================
|
||||
template<typename T>
|
||||
ListUserConfigParam<T>::ListUserConfigParam(const char* param_name,
|
||||
GroupUserConfigParam* group,
|
||||
const char* comment)
|
||||
{
|
||||
m_param_name = param_name;
|
||||
group->addChild(this);
|
||||
if(comment != NULL) m_comment = comment;
|
||||
} // ListUserConfigParam
|
||||
|
||||
// ============================================================================
|
||||
template<typename T>
|
||||
ListUserConfigParam<T>::ListUserConfigParam(const char* param_name,
|
||||
GroupUserConfigParam* group,
|
||||
const char* comment,
|
||||
int nb_elements,
|
||||
...)
|
||||
{
|
||||
m_param_name = param_name;
|
||||
group->addChild(this);
|
||||
if(comment != NULL) m_comment = comment;
|
||||
|
||||
// add the default list
|
||||
va_list arguments;
|
||||
va_start ( arguments, nb_elements );
|
||||
for ( int i = 0; i < nb_elements; i++ )
|
||||
m_elements.push_back(va_arg ( arguments, T ));
|
||||
va_end ( arguments ); // Cleans up the list
|
||||
} // ListUserConfigParam
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void ListUserConfigParam<T>::write(XMLWriter& stream) const
|
||||
{
|
||||
const int elts_amount = m_elements.size();
|
||||
|
||||
// comment
|
||||
if(m_comment.size() > 0) stream << " <!-- " << m_comment.c_str();
|
||||
stream << L" -->\n <" << m_param_name.c_str() << "\n";
|
||||
|
||||
stream << L" Size=\"" << elts_amount << "\"\n";
|
||||
// actual elements
|
||||
for (int n=0; n<elts_amount; n++)
|
||||
{
|
||||
stream << L" " << n << "=\"" << m_elements[n] << "\"\n";
|
||||
}
|
||||
stream << L" >\n";
|
||||
stream << L" </" << m_param_name.c_str() << ">\n\n";
|
||||
} // write
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Write your own convert function depending on the type of list you use.
|
||||
void convert(std::string str, char** str2)
|
||||
{
|
||||
*str2 = (char*)(malloc(str.size()+1));
|
||||
strcpy(*str2, str.c_str());
|
||||
}
|
||||
// Write your own equals function depending on the type of list you use.
|
||||
bool equals(char* str1, char* str2)
|
||||
{
|
||||
return (strcmp(str1, str2) == 0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ListUserConfigParam<T>::findYourDataInAChildOf(const XMLNode* node)
|
||||
{
|
||||
const XMLNode* child = node->getNode( m_param_name );
|
||||
if (child == NULL)
|
||||
{
|
||||
//std::cerr << "/!\\ User Config : Couldn't find parameter group "
|
||||
// << paramName << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
int attr_count = 0;
|
||||
child->get( "Size", &attr_count);
|
||||
for (int n=0; n<attr_count; n++)
|
||||
{
|
||||
T elt;
|
||||
std::ostringstream oss;
|
||||
oss << n;
|
||||
std::string str;
|
||||
child->get( oss.str(), &str);
|
||||
convert(str, &elt);
|
||||
// check if the element is already there :
|
||||
bool there = false;
|
||||
for (unsigned int i = 0; i < m_elements.size(); i++)
|
||||
{
|
||||
if (equals(m_elements[i], elt))
|
||||
{
|
||||
there = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!there)
|
||||
{
|
||||
Log::info("ListUserConfigParam", "New data : %s, \"%s\"", str.c_str(), elt);
|
||||
m_elements.push_back(elt);
|
||||
}
|
||||
}
|
||||
|
||||
} // findYourDataInAChildOf
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void ListUserConfigParam<T>::findYourDataInAnAttributeOf(const XMLNode* node)
|
||||
{
|
||||
} // findYourDataInAnAttributeOf
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void ListUserConfigParam<T>::addElement(T element)
|
||||
{
|
||||
m_elements.push_back(element);
|
||||
} // findYourDataInAnAttributeOf
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
irr::core::stringw ListUserConfigParam<T>::toString() const
|
||||
{
|
||||
return "";
|
||||
} // toString
|
||||
|
||||
|
||||
|
||||
// ============================================================================
|
||||
IntUserConfigParam::IntUserConfigParam(int default_value,
|
||||
const char* param_name,
|
||||
@@ -717,6 +873,17 @@ 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. */
|
||||
void UserConfig::saveConfig()
|
||||
|
||||
@@ -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
|
||||
@@ -99,6 +99,45 @@ public:
|
||||
irr::core::stringw toString() const;
|
||||
}; // GroupUserConfigParam
|
||||
|
||||
// ============================================================================
|
||||
template<typename T>
|
||||
class ListUserConfigParam : public UserConfigParam
|
||||
{
|
||||
std::vector<T> m_elements;
|
||||
|
||||
public:
|
||||
ListUserConfigParam(const char* param_name,
|
||||
const char* comment = NULL);
|
||||
ListUserConfigParam(const char* param_name,
|
||||
const char* comment,
|
||||
int nb_elts,
|
||||
...);
|
||||
ListUserConfigParam(const char* param_name,
|
||||
GroupUserConfigParam* group,
|
||||
const char* comment = NULL);
|
||||
ListUserConfigParam(const char* param_name,
|
||||
GroupUserConfigParam* group,
|
||||
const char* comment,
|
||||
int nb_elts,
|
||||
...);
|
||||
|
||||
void write(XMLWriter& stream) const;
|
||||
void findYourDataInAChildOf(const XMLNode* node);
|
||||
void findYourDataInAnAttributeOf(const XMLNode* node);
|
||||
|
||||
void addElement(T element);
|
||||
|
||||
irr::core::stringw toString() const;
|
||||
|
||||
operator std::vector<T>() const
|
||||
{ return m_elements; }
|
||||
float& operator=(const std::vector<T>& v)
|
||||
{ m_elements = std::vector<T>(v); return m_elements; }
|
||||
float& operator=(const ListUserConfigParam& v)
|
||||
{ m_elements = std::vector<T>(v); return m_elements; }
|
||||
}; // ListUserConfigParam
|
||||
typedef ListUserConfigParam<char*> StringListUserConfigParam;
|
||||
|
||||
// ============================================================================
|
||||
class IntUserConfigParam : public UserConfigParam
|
||||
{
|
||||
@@ -347,31 +386,31 @@ namespace UserConfigParams
|
||||
PARAM_DEFAULT( GroupUserConfigParam("WiiMote",
|
||||
"Settings for the wiimote") );
|
||||
PARAM_PREFIX FloatUserConfigParam m_wiimote_raw_max
|
||||
PARAM_DEFAULT( FloatUserConfigParam(25.0f, "wiimote-raw-max",
|
||||
PARAM_DEFAULT( FloatUserConfigParam(20.0f, "wiimote-raw-max",
|
||||
&m_wiimote_group,
|
||||
"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_PREFIX FloatUserConfigParam m_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"));
|
||||
"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"));
|
||||
"A weight applied to the square component of mapping wiimote angle to steering angle"));
|
||||
|
||||
PARAM_PREFIX FloatUserConfigParam m_wiimote_weight_asin
|
||||
PARAM_DEFAULT( FloatUserConfigParam(0.0f, "wiimote-weight-asin",
|
||||
&m_wiimote_group,
|
||||
"A weight applied to the asin component of mapping wiimote angle to steering angle"));
|
||||
"A weight applied to the asin component of mapping wiimote angle to steering angle"));
|
||||
|
||||
PARAM_PREFIX FloatUserConfigParam m_wiimote_weight_sin
|
||||
PARAM_DEFAULT( FloatUserConfigParam(0.0f, "wiimote-weight-sin",
|
||||
&m_wiimote_group,
|
||||
"A weight applied to the sin component of mapping wiimote angle to steering angle"));
|
||||
"A weight applied to the sin component of mapping wiimote angle to steering angle"));
|
||||
|
||||
// ---- GP start order
|
||||
// ---- GP start order
|
||||
PARAM_PREFIX GroupUserConfigParam m_gp_start_order
|
||||
PARAM_DEFAULT( GroupUserConfigParam("GpStartOrder",
|
||||
"Order karts start in GP") );
|
||||
@@ -446,8 +485,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 );
|
||||
@@ -479,18 +519,49 @@ 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
|
||||
PARAM_PREFIX StringUserConfigParam m_server_address
|
||||
PARAM_DEFAULT( StringUserConfigParam("localhost", "server_adress",
|
||||
"Information about last server used") );
|
||||
PARAM_PREFIX IntUserConfigParam m_server_port
|
||||
PARAM_DEFAULT( IntUserConfigParam(2305, "server_port",
|
||||
"Information about last server used") );
|
||||
PARAM_DEFAULT( IntUserConfigParam(7321, "server_port",
|
||||
"Information about the port to listen on.") );
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_server_max_players
|
||||
PARAM_DEFAULT( IntUserConfigParam(16, "server_max_players",
|
||||
"Maximum number of players on the server.") );
|
||||
|
||||
PARAM_PREFIX StringListUserConfigParam m_stun_servers
|
||||
PARAM_DEFAULT( StringListUserConfigParam("Stun_servers", "The stun servers"
|
||||
" that will be used to know the public address.",
|
||||
24,
|
||||
"provserver.televolution.net",
|
||||
"sip1.lakedestiny.cordiaip.com",
|
||||
"stun1.voiceeclipse.net",
|
||||
"stun01.sipphone.com",
|
||||
"stun.callwithus.com",
|
||||
"stun.counterpath.net",
|
||||
"stun.endigovoip.com",
|
||||
"stun.ekiga.net",
|
||||
"stun.ideasip.com" ,
|
||||
"stun.internetcalls.com",
|
||||
"stun.ipns.com",
|
||||
"stun.noc.ams-ix.net",
|
||||
"stun.phonepower.com",
|
||||
"stun.phoneserve.com",
|
||||
"stun.rnktel.com",
|
||||
"stun.softjoys.com",
|
||||
"stunserver.org",
|
||||
"stun.sipgate.net",
|
||||
"stun.stunprotocol.org",
|
||||
"stun.voip.aebc.com",
|
||||
"stun.voipbuster.com",
|
||||
"stun.voxalot.com",
|
||||
"stun.voxgratia.org",
|
||||
"stun.xten.com") );
|
||||
|
||||
PARAM_PREFIX StringUserConfigParam m_packets_log_filename
|
||||
PARAM_DEFAULT( StringUserConfigParam("packets_log.txt", "packets_log_filename",
|
||||
"Where to log received and sent packets.") );
|
||||
|
||||
// ---- Graphic Quality
|
||||
PARAM_PREFIX GroupUserConfigParam m_graphics_quality
|
||||
@@ -509,14 +580,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") );
|
||||
@@ -534,10 +606,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,
|
||||
@@ -546,18 +620,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") );
|
||||
@@ -601,9 +684,48 @@ namespace UserConfigParams
|
||||
PARAM_DEFAULT( WStringUserConfigParam(L"", "default_player",
|
||||
"Which player to use by default (if empty, will prompt)") );
|
||||
|
||||
// ---- Internet related
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_internet_status
|
||||
PARAM_DEFAULT( IntUserConfigParam(0, "enable_internet",
|
||||
"Status of internet: 0 user "
|
||||
"wasn't asked, 1: allowed, 2: "
|
||||
"not allowed") );
|
||||
|
||||
// ---- Online gameplay related
|
||||
|
||||
PARAM_PREFIX GroupUserConfigParam m_online_group
|
||||
PARAM_DEFAULT( GroupUserConfigParam("OnlinePlay",
|
||||
"Everything related to online play.") );
|
||||
|
||||
PARAM_PREFIX StringUserConfigParam m_server_multiplayer
|
||||
PARAM_DEFAULT( StringUserConfigParam( "https://api.stkaddons.net/",
|
||||
"server_multiplayer",
|
||||
&m_online_group,
|
||||
"The server used for online multiplayer."));
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_saved_session
|
||||
PARAM_DEFAULT( BoolUserConfigParam( false,
|
||||
"saved_session",
|
||||
&m_online_group,
|
||||
"Is there a saved session?") );
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_saved_user
|
||||
PARAM_DEFAULT( IntUserConfigParam( 0,
|
||||
"saved_user",
|
||||
&m_online_group,
|
||||
"User ID of the saved session.") );
|
||||
|
||||
PARAM_PREFIX StringUserConfigParam m_saved_token
|
||||
PARAM_DEFAULT( StringUserConfigParam( "",
|
||||
"saved_token",
|
||||
&m_online_group,
|
||||
"Token of the saved session.") );
|
||||
|
||||
|
||||
// ---- Addon server related entries
|
||||
PARAM_PREFIX GroupUserConfigParam m_addon_group
|
||||
PARAM_DEFAULT( GroupUserConfigParam("AddonAndNews",
|
||||
PARAM_DEFAULT( GroupUserConfigParam("AddonAndNews",
|
||||
"Addon and news related settings") );
|
||||
|
||||
PARAM_PREFIX StringUserConfigParam m_server_addons
|
||||
@@ -634,13 +756,6 @@ namespace UserConfigParams
|
||||
"Don't show important message "
|
||||
"with this or a lower id again") );
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_internet_status
|
||||
PARAM_DEFAULT( IntUserConfigParam(0, "enable_internet",
|
||||
&m_addon_group,
|
||||
"Status of internet: 0 user "
|
||||
"wasn't asked, 1: allowed, 2: "
|
||||
"not allowed") );
|
||||
|
||||
PARAM_PREFIX TimeUserConfigParam m_addons_last_updated
|
||||
PARAM_DEFAULT( TimeUserConfigParam(0, "addon_last_updated",
|
||||
&m_addon_group,
|
||||
@@ -713,7 +828,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
|
||||
|
||||
795
src/graphics/callbacks.cpp
Normal file
795
src/graphics/callbacks.cpp
Normal file
@@ -0,0 +1,795 @@
|
||||
// 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 ColorLevelsProvider::OnSetConstants(IMaterialRendererServices *srv, int userData)
|
||||
{
|
||||
|
||||
m_inlevel = World::getWorld()->getTrack()->getColorLevelIn();
|
||||
m_outlevel = World::getWorld()->getTrack()->getColorLevelOut();
|
||||
|
||||
srv->setVertexShaderConstant("inlevel", &m_inlevel.X, 3);
|
||||
srv->setVertexShaderConstant("outlevel", &m_outlevel.X, 2);
|
||||
|
||||
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.0f - 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 = (float)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] = {
|
||||
(float)size.Width,
|
||||
(float)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);
|
||||
}
|
||||
729
src/graphics/callbacks.hpp
Normal file
729
src/graphics/callbacks.hpp
Normal file
@@ -0,0 +1,729 @@
|
||||
// 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 ColorLevelsProvider: public CallBase
|
||||
{
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
|
||||
|
||||
ColorLevelsProvider()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
core::vector3df m_inlevel;
|
||||
core::vector2df m_outlevel;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
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)!=0;
|
||||
}
|
||||
|
||||
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(int x, int 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(int x, int y)
|
||||
{
|
||||
m_res[0] = (float)x;
|
||||
m_res[1] = (float)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] = (float)UserConfigParams::m_width;
|
||||
m_screen[1] = (float)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] = (float)UserConfigParams::m_width;
|
||||
m_screen[1] = (float)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 int x, const int 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 = (int)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] = (float)UserConfigParams::m_width;
|
||||
m_screen[1] = (float)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"
|
||||
@@ -387,13 +385,21 @@ void Camera::getCameraSettings(float *above_kart, float *cam_angle,
|
||||
// Fall through to falling mode.
|
||||
case CM_FALLING:
|
||||
{
|
||||
*above_kart = 0.75f;
|
||||
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;
|
||||
@@ -447,7 +453,7 @@ void Camera::update(float dt)
|
||||
|
||||
// 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);
|
||||
@@ -509,9 +515,10 @@ void Camera::positionCamera(float dt, float above_kart, float cam_angle,
|
||||
{
|
||||
Vec3 wanted_position;
|
||||
Vec3 wanted_target = m_kart->getXYZ();
|
||||
|
||||
wanted_target.setY(wanted_target.getY()+above_kart);
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2008 Joerg Henrichs
|
||||
// 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
|
||||
@@ -16,25 +16,38 @@
|
||||
// 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_RACE_START_MESSAGE_HPP
|
||||
#define HEADER_RACE_START_MESSAGE_HPP
|
||||
#ifndef HEADER_GLOW_HPP
|
||||
#define HEADER_GLOW_HPP
|
||||
|
||||
#include "network/message.hpp"
|
||||
#include "network/remote_kart_info.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include <ISceneNode.h>
|
||||
#include <IMesh.h>
|
||||
|
||||
class RaceStartMessage : public Message
|
||||
using namespace irr;
|
||||
|
||||
// The actual node
|
||||
class GlowNode: public scene::ISceneNode
|
||||
{
|
||||
private:
|
||||
// For now this is an empty message
|
||||
public:
|
||||
RaceStartMessage() : Message(Message::MT_RACE_START)
|
||||
{
|
||||
allocate(0);
|
||||
} // RaceStartMessage
|
||||
GlowNode(scene::ISceneManager* mgr, float radius);
|
||||
~GlowNode();
|
||||
|
||||
RaceStartMessage(ENetPacket* pkt):Message(pkt, MT_RACE_START)
|
||||
virtual void render();
|
||||
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const
|
||||
{
|
||||
return box;
|
||||
}
|
||||
}; // RaceStartMessage
|
||||
|
||||
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;
|
||||
@@ -265,8 +276,8 @@ void IrrDriver::initDevice()
|
||||
if(m_modes.size()==0)
|
||||
{
|
||||
createListOfVideoModes();
|
||||
// The debug name is only set if irrlicht is compiled in debug
|
||||
// mode. So we use this to print a warning to the user.
|
||||
// The debug name is only set if irrlicht is compiled in debug
|
||||
// mode. So we use this to print a warning to the user.
|
||||
if(m_device->getDebugName())
|
||||
{
|
||||
Log::warn("irr_driver",
|
||||
@@ -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.
|
||||
@@ -856,8 +929,8 @@ scene::ISceneNode *IrrDriver::addBillboard(const core::dimension2d< f32 > size,
|
||||
m_scene_manager->addBillboardSceneNode(parent, size);
|
||||
assert(node->getMaterialCount() > 0);
|
||||
node->setMaterialTexture(0, texture);
|
||||
if(alphaTesting)
|
||||
node->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
|
||||
if(alphaTesting)
|
||||
node->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
|
||||
return node;
|
||||
} // addMesh
|
||||
|
||||
@@ -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;
|
||||
@@ -1320,7 +1422,7 @@ void IrrDriver::displayFPS()
|
||||
else
|
||||
{
|
||||
sprintf(buffer, "FPS: %i/%i/%i - %i KTris", min, fps, max,
|
||||
(int)round(kilotris));
|
||||
(int)roundf(kilotris));
|
||||
}
|
||||
|
||||
core::stringw fpsString = buffer;
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -112,8 +114,8 @@ public:
|
||||
std::vector<scene::ISceneNode*>& getAllNodes() { return m_nodes; }
|
||||
|
||||
//! OnAnimate() is called just before rendering the whole scene.
|
||||
/** This method will be called once per frame, independent
|
||||
of whether the scene node is visible or not. */
|
||||
/** This method will be called once per frame, independent
|
||||
of whether the scene node is visible or not. */
|
||||
virtual void OnAnimate(u32 timeMs);
|
||||
|
||||
virtual void OnRegisterSceneNode();
|
||||
|
||||
@@ -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,8 +86,9 @@ 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",
|
||||
s.c_str());
|
||||
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,16 +224,19 @@ 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",
|
||||
s.c_str());
|
||||
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,9 +280,8 @@ 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",
|
||||
s.c_str());
|
||||
Log::warn("material", "Unknown compositing mode '%s'",
|
||||
s.c_str());
|
||||
}
|
||||
|
||||
|
||||
@@ -661,10 +326,9 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[Material] WARNING: unknown node type '%s' for texture "
|
||||
"'%s' - ignored.\n",
|
||||
child_node->getName().c_str(), m_texname.c_str());
|
||||
Log::warn("material", "Unknown node type '%s' for texture "
|
||||
"'%s' - ignored.",
|
||||
child_node->getName().c_str(), m_texname.c_str());
|
||||
}
|
||||
|
||||
} // for i <node->getNumNodes()
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
m_texture = irr_driver->getTexture(full_path,
|
||||
isPreMul(),
|
||||
isPreDiv(),
|
||||
complain_if_not_found);
|
||||
|
||||
if (m_texture == NULL) return;
|
||||
|
||||
@@ -776,8 +440,8 @@ void Material::install(bool is_full_path, bool complain_if_not_found)
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Applying mask failed for '%s'!\n",
|
||||
m_texname.c_str());
|
||||
Log::warn("material", "Applying mask failed for '%s'!",
|
||||
m_texname.c_str());
|
||||
}
|
||||
}
|
||||
m_texture->grab();
|
||||
@@ -793,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.
|
||||
@@ -829,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;
|
||||
}
|
||||
|
||||
@@ -908,10 +558,10 @@ void Material::initParticlesEffect(const XMLNode *node)
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
fprintf(stderr, "[Material::initParticlesEffect] WARNING: Particles "
|
||||
"'%s' for material '%s' are declared but not used "
|
||||
"(no emission condition set)\n",
|
||||
base.c_str(), m_texname.c_str());
|
||||
Log::warn("material", "initParticlesEffect: Particles "
|
||||
"'%s' for material '%s' are declared but not used "
|
||||
"(no emission condition set).",
|
||||
base.c_str(), m_texname.c_str());
|
||||
}
|
||||
|
||||
for (int c=0; c<count; c++)
|
||||
@@ -926,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());
|
||||
}
|
||||
}
|
||||
@@ -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,10 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
}
|
||||
if (m_smooth_reflection_shader)
|
||||
{
|
||||
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();
|
||||
m->MaterialType = irr_driver->getShader(ES_SPHERE_MAP);
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
m->MaterialType = video::EMT_SPHERE_MAP;
|
||||
@@ -1058,6 +697,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;
|
||||
|
||||
// sphere map + alpha blending is a supported combination so in
|
||||
@@ -1071,7 +716,8 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
modes++;
|
||||
}
|
||||
}
|
||||
#if !LIGHTMAP_VISUALISATION
|
||||
}
|
||||
|
||||
if (m_lightmap)
|
||||
{
|
||||
m->MaterialType = video::EMT_LIGHTMAP;
|
||||
@@ -1082,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;
|
||||
@@ -1101,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)
|
||||
@@ -1120,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;
|
||||
|
||||
@@ -1200,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;
|
||||
m->MaterialType = irr_driver->getShader(ES_SPLATTING);
|
||||
}
|
||||
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 = video::EMT_SOLID;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (m_graphical_effect == GE_CAUSTICS && irr_driver->isGLSL())
|
||||
{
|
||||
m->MaterialType = video::EMT_SOLID;
|
||||
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.
|
||||
@@ -1274,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
|
||||
@@ -1307,70 +868,40 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
|
||||
if (m_graphical_effect == GE_WATER_SHADER)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1422,11 +953,11 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
{
|
||||
/**
|
||||
//! Texture is clamped to the last pixel
|
||||
ETC_CLAMP,
|
||||
//! Texture is clamped to the edge pixel
|
||||
ETC_CLAMP_TO_EDGE,
|
||||
//! Texture is clamped to the border pixel (if exists)
|
||||
ETC_CLAMP_TO_BORDER,
|
||||
ETC_CLAMP,
|
||||
//! Texture is clamped to the edge pixel
|
||||
ETC_CLAMP_TO_EDGE,
|
||||
//! Texture is clamped to the border pixel (if exists)
|
||||
ETC_CLAMP_TO_BORDER,
|
||||
*/
|
||||
for (unsigned int n=0; n<video::MATERIAL_MAX_TEXTURES; n++)
|
||||
{
|
||||
@@ -1465,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)
|
||||
@@ -1478,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);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1489,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);
|
||||
|
||||
@@ -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>
|
||||
@@ -174,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 = (float)((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
|
||||
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -219,7 +262,7 @@ void ParticleEmitter::update(float dt)
|
||||
|
||||
// the emission direction does not automatically follow the orientation of
|
||||
// the node so fix that manually...
|
||||
core::matrix4 transform = m_node->getAbsoluteTransformation();
|
||||
core::matrix4 transform = m_node->getAbsoluteTransformation();
|
||||
core::vector3df velocity(m_particle_type->getVelocityX(),
|
||||
m_particle_type->getVelocityY(),
|
||||
m_particle_type->getVelocityZ());
|
||||
@@ -489,7 +532,7 @@ void ParticleEmitter::setParticleType(const ParticleKind* type)
|
||||
m_node->addAffector(faa);
|
||||
faa->drop();
|
||||
}
|
||||
|
||||
|
||||
if (type->hasScaleAffector())
|
||||
{
|
||||
core::dimension2df factor = core::dimension2df(type->getScaleAffectorFactorX(),
|
||||
@@ -499,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; }
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user