Merge remote-tracking branch 'upstream/master' into SmoothMoveCamera

This commit is contained in:
Dk 2014-04-09 21:06:49 +05:30
commit 9f4368da08
103 changed files with 1547 additions and 1486 deletions

View File

@ -4,7 +4,7 @@ uniform sampler2D normalMap;
in vec3 tangent;
in vec3 bitangent;
in vec2 uv;
out vec2 EncodedNormal;
out vec3 EncodedNormal;
#else
varying vec3 tangent;
varying vec3 bitangent;
@ -19,12 +19,13 @@ vec2 EncodeNormal(vec3 n);
void main()
{
// normal in Tangent Space
vec3 TS_normal = 2.0 * texture (normalMap, uv).rgb - 1.0;
vec3 TS_normal = 2.0 * pow(texture(normalMap, uv).rgb, vec3(1./2.2)) - 1.0;
// Because of interpolation, we need to renormalize
vec3 Frag_tangent = normalize(tangent);
vec3 Frag_normal = normalize(cross(Frag_tangent, bitangent));
vec3 Frag_bitangent = cross(Frag_normal, Frag_tangent);
vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal;
EncodedNormal = 0.5 * EncodeNormal(normalize(FragmentNormal)) + 0.5;
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(FragmentNormal)) + 0.5;
EncodedNormal.z = 1.;
}

View File

@ -1,6 +1,9 @@
uniform sampler2D tex;
#if __VERSION__ >= 130
in vec3 nor;
out vec2 EncodedNormal;
in vec2 uv;
out vec3 EncodedNormal;
#else
varying vec3 nor;
#define EncodedNormal gl_FragColor.xy
@ -10,5 +13,7 @@ vec2 EncodeNormal(vec3 n);
void main(void)
{
EncodedNormal = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
vec4 col = texture(tex, uv);
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
EncodedNormal.z = exp2(10. * (1. - col.a) + 1.);
}

View File

@ -13,6 +13,6 @@ vec3 getLightFactor(float specMapValue);
void main(void)
{
vec4 color = texture(Albedo, uv);
vec3 LightFactor = getLightFactor(1. - color.a);
vec3 LightFactor = getLightFactor(1.);
FragColor = vec4(color.xyz * LightFactor, 1.);
}

View File

@ -3,7 +3,7 @@ uniform sampler2D tex;
#if __VERSION__ >= 130
in vec3 nor;
in vec2 uv;
out vec2 EncodedNormal;
out vec3 EncodedNormal;
#else
varying vec3 nor;
varying vec2 uv;
@ -16,6 +16,7 @@ void main() {
vec4 col = texture(tex, uv);
if (col.a < 0.5)
discard;
EncodedNormal = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
EncodedNormal.z = 1.;
}

View File

@ -13,37 +13,33 @@ out vec4 Diffuse;
out vec4 Specular;
vec3 DecodeNormal(vec2 n);
vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness);
void main() {
vec2 texc = gl_FragCoord.xy / screen;
float z = texture(dtex, texc).x;
vec3 norm = normalize(DecodeNormal(2. * texture(ntex, texc).xy - 1.));
void main()
{
vec2 texc = gl_FragCoord.xy / screen;
float z = texture(dtex, texc).x;
vec3 norm = normalize(DecodeNormal(2. * texture(ntex, texc).xy - 1.));
float roughness = texture(ntex, texc).z;
vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f;
xpos = invproj * xpos;
xpos /= xpos.w;
vec3 eyedir = normalize(xpos.xyz);
vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f;
xpos = invproj * xpos;
xpos /= xpos.w;
vec3 eyedir = -normalize(xpos.xyz);
vec3 diffuse = vec3(0.), specular = vec3(0.);
vec4 pseudocenter = ViewMatrix * vec4(center.xyz, 1.0);
pseudocenter /= pseudocenter.w;
vec3 light_pos = pseudocenter.xyz;
vec3 light_col = col.xyz;
float d = distance(light_pos, xpos.xyz);
float att = energy * 200. / (4. * 3.14 * d * d);
float spec_att = (energy + 10.) * 200. / (4. * 3.14 * d * d);
vec4 pseudocenter = ViewMatrix * vec4(center.xyz, 1.0);
pseudocenter /= pseudocenter.w;
vec3 light_pos = pseudocenter.xyz;
vec3 light_col = col.xyz;
float d = distance(light_pos, xpos.xyz);
float att = energy * 200. / (4. * 3.14 * d * d);
float spec_att = (energy + 10.) * 200. / (4. * 3.14 * d * d);
// Light Direction
vec3 L = -normalize(xpos.xyz - light_pos);
// Light Direction
vec3 L = normalize(xpos.xyz - light_pos);
float NdotL = max(0., dot(norm, L));
float NdotL = max(0.0, dot(norm, -L));
diffuse += NdotL * light_col * att;
// Reflected light dir
vec3 R = reflect(-L, norm);
float RdotE = max(0.0, dot(R, eyedir));
specular += pow(RdotE, spec) * light_col * spec_att;
Diffuse = vec4(diffuse, 1.);
Specular = vec4(specular , 1.);
Diffuse = vec4(NdotL * light_col * att, 1.);
Specular = vec4(getSpecular(norm, eyedir, L, light_col, roughness) * NdotL * spec_att, 1.);
}

View File

@ -16,23 +16,24 @@ const float zNear = 1.;
void main(void)
{
// Beyond that value, light is too attenuated
float r = 40 * Energy;
float r = 500 * Energy;
center = Position;
energy = Energy;
vec4 Center = ViewMatrix * vec4(Position, 1.);
vec4 ProjectedCornerPosition = ProjectionMatrix * (Center + r * vec4(Corner, 0., 0.));
float adjustedDepth = ProjectedCornerPosition.z;
if (Center.z > zNear) // Light is in front of the cam
{
vec3 UnitCenter = normalize(-Center.xyz);
float clampedR = min(r, Center.z - 1.);
float cosTheta = dot(UnitCenter, vec3(0., 0., -1));
float d = clampedR / cosTheta;
Center.xyz += d * UnitCenter;
adjustedDepth = max(Center.z - r, zNear);
}
else if (Center.z + r > zNear) // Light is behind the cam but in range
{
Center.z = zNear;
// TODO: Change r so that we make the screen aligned quad fits light range.
adjustedDepth = zNear;
}
ProjectedCornerPosition /= ProjectedCornerPosition.w;
ProjectedCornerPosition.zw = (ProjectionMatrix * vec4(0., 0., adjustedDepth, 1.)).zw;
ProjectedCornerPosition.xy *= ProjectedCornerPosition.w;
col = Color;
gl_Position = ProjectionMatrix * (Center + r * vec4(Corner, 0., 0.));
gl_Position = ProjectedCornerPosition;
}

View File

@ -1,4 +1,7 @@
uniform mat4 ViewProjectionMatrix[4];
layout (std140) uniform MatrixesData
{
mat4 ViewProjectionMatrix[4];
};
#if __VERSION__ >= 400
layout(triangles, invocations=4) in;

View File

@ -20,6 +20,7 @@ varying vec2 uv;
vec3 DecodeNormal(vec2 n);
vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness);
void main() {
float z = texture(dtex, uv).x;
@ -36,14 +37,15 @@ void main() {
}
vec3 norm = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
float roughness = texture(ntex, uv).z;
vec3 eyedir = -normalize(xpos.xyz);
// Normalized on the cpu
vec3 L = direction;
vec3 L = direction;
float NdotL = max(0.0, dot(norm, L));
vec3 R = reflect(L, norm);
float RdotE = max(0.0, dot(R, normalize(xpos.xyz)));
float Specular = pow(RdotE, 200);
float NdotL = max(0., dot(norm, L));
vec3 Specular = getSpecular(norm, eyedir, L, col, roughness) * NdotL;
vec3 outcol = NdotL * col;
@ -57,5 +59,5 @@ void main() {
}*/
Diff = vec4(NdotL * col, 1.);
Spec = vec4(Specular * col, 1.);
Spec = vec4(Specular, 1.);
}

View File

@ -24,6 +24,7 @@ varying vec2 uv;
vec3 DecodeNormal(vec2 n);
vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness);
float getShadowFactor(vec3 pos, float bias, int index)
{
@ -64,14 +65,16 @@ void main() {
xpos.xyz /= xpos.w;
vec3 norm = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
float roughness =texture(ntex, uv).z;
vec3 eyedir = -normalize(xpos.xyz);
// Normalized on the cpu
vec3 L = direction;
vec3 L = direction;
float NdotL = max(0., dot(norm, L));
vec3 Specular = getSpecular(norm, eyedir, L, col, roughness) * NdotL;
float NdotL = max(0.0, dot(norm, L));
vec3 R = reflect(L, norm);
float RdotE = max(0.0, dot(R, normalize(xpos.xyz)));
float Specular = pow(RdotE, 200);
vec3 outcol = NdotL * col;
@ -112,7 +115,7 @@ void main() {
else
factor = getShadowFactor(xpos.xyz, bias, 3);
Diff = vec4(factor * NdotL * col, 1.);
Spec = vec4(factor * Specular * col, 1.);
Spec = vec4(factor * Specular, 1.);
return;
// float moved = (abs(dx) + abs(dy)) * 0.5;

View File

@ -0,0 +1,11 @@
vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness)
{
// Half Light View direction
vec3 H = normalize(eyedir + lightdir);
float NdotH = max(0., dot(normal, H));
float normalisationFactor = (roughness + 2.) / 8.;
vec3 FresnelSchlick = color + (1.0f - color) * pow(1.0f - max(0., (dot(eyedir, H))), 5);
return max(pow(NdotH, roughness) * FresnelSchlick * normalisationFactor, vec3(0.));
}

View File

@ -642,6 +642,7 @@ bool CIrrDeviceMacOSX::createWindow()
NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute)CreationParams.AntiAlias,
NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)(CreationParams.Stencilbuffer?1:0),
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAOpenGLProfile, (NSOpenGLPixelFormatAttribute)NSOpenGLProfileVersion3_2Core,
(NSOpenGLPixelFormatAttribute)nil
};

View File

@ -23,6 +23,7 @@
#include "achievements/achievement_info.hpp"
#include "guiengine/dialog_queue.hpp"
#include "io/utf_writer.hpp"
#include "online/current_user.hpp"
#include "states_screens/dialogs/notification_dialog.hpp"
#include "utils/log.hpp"
#include "utils/translation.hpp"
@ -204,8 +205,17 @@ void Achievement::check()
GUIEngine::DialogQueue::get()->pushDialog(
new NotificationDialog(NotificationDialog::T_Achievements, s));
//send to server
Online::CurrentUser::get()->onAchieving(m_id);
// Sends a confirmation to the server that an achievement has been
// completed, if a user is signed in.
Online::CurrentUser *cu = Online::CurrentUser::get();
if (cu->isRegisteredUser())
{
Online::HTTPRequest * request = new Online::HTTPRequest(true);
Online::CurrentUser::setUserDetails(request, "achieving");
request->addParameter("achievementid", m_id);
request->queue();
}
m_achieved = true;
}
} // check

View File

@ -247,12 +247,12 @@ void UnlockManager::findWhatWasUnlocked(int points_before, int points_now,
{
if (c->getMode() == ChallengeData::CM_SINGLE_RACE && c->getTrackId() != "")
{
if (!PlayerManager::get()->getCurrentPlayer()->isLocked(c->getTrackId()))
if (!PlayerManager::getCurrentPlayer()->isLocked(c->getTrackId()))
tracks.push_back(c->getTrackId());
}
else if (c->getMode() == ChallengeData::CM_GRAND_PRIX && c->getGPId() != "")
{
if (!PlayerManager::get()->getCurrentPlayer()->isLocked(c->getGPId()))
if (!PlayerManager::getCurrentPlayer()->isLocked(c->getGPId()))
gps.push_back(c->getGPId());
}
}

View File

@ -71,32 +71,48 @@ void PlayerManager::load()
{
std::string filename = file_manager->getUserConfigFile("players.xml");
const XMLNode *players = file_manager->createXMLTree(filename);
if(!players)
m_player_data = file_manager->createXMLTree(filename);
if(!m_player_data)
{
Log::info("player_manager", "A new players.xml file will be created.");
return;
}
else if(players->getName()!="players")
else if(m_player_data->getName()!="players")
{
Log::info("player_manager", "The players.xml file is invalid.");
return;
}
m_current_player = NULL;
for(unsigned int i=0; i<players->getNumNodes(); i++)
for(unsigned int i=0; i<m_player_data->getNumNodes(); i++)
{
const XMLNode *player_xml = players->getNode(i);
const XMLNode *player_xml = m_player_data->getNode(i);
PlayerProfile *player = new PlayerProfile(player_xml);
m_all_players.push_back(player);
if(player->isDefault())
m_current_player = player;
}
m_all_players.insertionSort(/*start*/0, /*desc*/true);
delete players;
} // load
// ----------------------------------------------------------------------------
/** The 2nd loading stage. During this stage achievements and story mode
* data is read for each player.
*/
void PlayerManager::loadRemainingData()
{
for (unsigned int i = 0; i<m_player_data->getNumNodes(); i++)
{
const XMLNode *player_xml = m_player_data->getNode(i);
m_all_players[i].loadRemainingData(player_xml);
}
delete m_player_data;
m_player_data = NULL;
// Sort player by frequency
m_all_players.insertionSort(/*start*/0, /*desc*/true);
} // loadRemainingData
// ----------------------------------------------------------------------------
/** Saves all player profiles to players.xml.
*/

View File

@ -48,6 +48,10 @@ private:
/** A pointer to the current player. */
PlayerProfile* m_current_player;
/** Saves the XML tree from players.xml for use in the 2nd
* loading stage (loadRemainingData). */
const XMLNode *m_player_data;
void load();
PlayerManager();
~PlayerManager();
@ -72,6 +76,7 @@ public:
// ------------------------------------------------------------------------
void save();
void loadRemainingData();
unsigned int getUniqueId() const;
void addDefaultPlayer();
void addNewPlayer(const irr::core::stringw& name);
@ -81,7 +86,10 @@ public:
void enforceCurrentPlayer();
// ------------------------------------------------------------------------
/** Returns the current player. */
PlayerProfile* getCurrentPlayer() { return m_current_player; }
static PlayerProfile* getCurrentPlayer()
{
return get()->m_current_player;
} // getCurrentPlayer
// ------------------------------------------------------------------------
PlayerProfile *getPlayer(const irr::core::stringw &name);
// ------------------------------------------------------------------------
@ -100,7 +108,7 @@ public:
/** A handy shortcut funtion. */
static AchievementsStatus* getCurrentAchievementsStatus()
{
return get()->getCurrentPlayer()->getAchievementsStatus();
return PlayerManager::getCurrentPlayer()->getAchievementsStatus();
} // getCurrentAchievementsStatus
// ------------------------------------------------------------------------
/** A handy shortcut to increase points for an achievement key of the

View File

@ -50,26 +50,52 @@ PlayerProfile::PlayerProfile(const core::stringw& name, bool is_guest)
} // PlayerProfile
//------------------------------------------------------------------------------
/** Constructor to deserialize a player that was saved to a XML file.
/** Constructor to deserialize player data that was saved to a XML file. The
* constructor will only load the main player data (like name, id, saved
* online data), but not the achievements and story mode data. Reason is
* that the achievement and story mode data depends on other data to be
* read first (challenges and achievement files), which in turn can only be
* created later in the startup process (they depend on e.g. all tracks to
* be known). On the other hand, automatic login needs to happen asap
* (i.e. as soon as the network thread is started), which needs the main
* player data (i.e. the default player, and saved session data). So the
* constructor only reads this data, the rest of the player data is handled
* in loadRemainingData later in the initialisation process.
* \param node The XML node representing this player.
*/
PlayerProfile::PlayerProfile(const XMLNode* node)
{
m_saved_session = false;
m_saved_token = "";
m_saved_user_id = 0;
m_story_mode_status = NULL;
m_achievements_status = NULL;
node->get("name", &m_name );
node->get("guest", &m_is_guest_account);
node->get("use-frequency", &m_use_frequency );
node->get("unique-id", &m_unique_id );
node->get("is-default", &m_is_default );
node->get("saved-session", &m_saved_session );
node->get("saved-user", &m_saved_user_id );
node->get("saved-token", &m_saved_token );
#ifdef DEBUG
m_magic_number = 0xABCD1234;
#endif
} // PlayerProfile
//------------------------------------------------------------------------------
/** This function loads the achievement and story mode data. This
*/
void PlayerProfile::loadRemainingData(const XMLNode *node)
{
const XMLNode *xml_story_mode = node->getNode("story-mode");
m_story_mode_status = unlock_manager->createStoryModeStatus(xml_story_mode);
const XMLNode *xml_achievements = node->getNode("achievements");
m_achievements_status = AchievementsManager::get()
->createAchievementsStatus(xml_achievements);
} // PlayerProfile
->createAchievementsStatus(xml_achievements);
} // loadRemainingData
//------------------------------------------------------------------------------
/** Writes the data for this player to the specified UTFWriter.
@ -79,9 +105,15 @@ void PlayerProfile::save(UTFWriter &out)
{
out << L" <player name=\"" << m_name
<< L"\" guest=\"" << m_is_guest_account
<< L"\" use-frequency=\"" << m_use_frequency
<< L"\" is-default=\"" << m_is_default
<< L"\" unique-id=\"" << m_unique_id << L"\">\n";
<< L"\" use-frequency=\"" << m_use_frequency << L"\"\n";
out << L" is-default=\"" << m_is_default
<< L"\" unique-id=\"" << m_unique_id
<< L"\" saved-session=\"" << m_saved_session << L"\"\n";
out << L" saved-user=\"" << m_saved_user_id
<< L"\" saved-token=\"" << m_saved_token << L"\">\n";
{
assert(m_story_mode_status);
m_story_mode_status->save(out);
@ -92,6 +124,31 @@ void PlayerProfile::save(UTFWriter &out)
out << L" </player>\n";
} // save
//------------------------------------------------------------------------------
// ------------------------------------------------------------------------
/** Saves the online data, so that it will automatically re-connect
* next time this profile is loaded.
* \param user_id Id of the online profile.
* \param token Token used for authentication.
*/
void PlayerProfile::saveSession(int user_id, const std::string &token)
{
m_saved_session = true;
m_saved_user_id = user_id;
m_saved_token = token;
PlayerManager::get()->save();
} // saveSession
// ------------------------------------------------------------------------
/** Unsets any saved session data. */
void PlayerProfile::clearSession()
{
m_saved_session = false;
m_saved_user_id = 0;
m_saved_token = "";
PlayerManager::get()->save();
} // clearSession
//------------------------------------------------------------------------------
/** Increments how often that account was used. Guest accounts are not counted.
*/

View File

@ -62,6 +62,15 @@ private:
/** True if this is the default (last used) player. */
bool m_is_default;
/** True if this user has a saved session. */
bool m_saved_session;
/** If a session was saved, this will be the online user id to use. */
int m_saved_user_id;
/** The token of the saved session. */
std::string m_saved_token;
/** The complete challenge state. */
StoryModeStatus *m_story_mode_status;
@ -69,15 +78,18 @@ private:
public:
PlayerProfile(const core::stringw& name, bool is_guest = false);
PlayerProfile(const core::stringw &name, bool is_guest = false);
PlayerProfile(const XMLNode* node);
PlayerProfile(const XMLNode *node);
void save(UTFWriter &out);
void loadRemainingData(const XMLNode *node);
void incrementUseFrequency();
bool operator<(const PlayerProfile &other);
bool operator>(const PlayerProfile &other);
void raceFinished();
void saveSession(int user_id, const std::string &token);
void clearSession();
// ------------------------------------------------------------------------
~PlayerProfile()
@ -190,7 +202,24 @@ public:
{
return m_achievements_status;
} // getAchievementsStatus
// ------------------------------------------------------------------------
/** Returns true if a session was saved for this player. */
bool hasSavedSession() const { return m_saved_session; }
// ------------------------------------------------------------------------
/** If a session was saved, return the id of the saved user. */
int getSavedUserId() const
{
assert(m_saved_session);
return m_saved_user_id;
} // getSavedUserId
// ------------------------------------------------------------------------
/** If a session was saved, return the token to use. */
const std::string& getSavedToken() const
{
assert(m_saved_session);
return m_saved_token;
} // getSavedToken
// ------------------------------------------------------------------------
}; // class PlayerProfile
#endif

View File

@ -669,25 +669,6 @@ namespace UserConfigParams
&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",

View File

@ -91,35 +91,6 @@ void WaterShaderProvider::OnSetConstants(IMaterialRendererServices *srv, int)
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;
core::matrix4 ModelViewProjectionMatrix = drv->getTransform(ETS_PROJECTION);
ModelViewProjectionMatrix *= drv->getTransform(ETS_VIEW);
ModelViewProjectionMatrix *= drv->getTransform(ETS_WORLD);
core::matrix4 TransposeInverseModelView = drv->getTransform(ETS_VIEW);
TransposeInverseModelView *= drv->getTransform(ETS_WORLD);
TransposeInverseModelView.makeInverse();
TransposeInverseModelView = TransposeInverseModelView.getTransposed();
srv->setVertexShaderConstant("windDir", &wind.X, 3);
srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16);
srv->setVertexShaderConstant("TransposeInverseModelView", TransposeInverseModelView.pointer(), 16);
if (!firstdone)
{
s32 tex = 0;
srv->setVertexShaderConstant("tex", &tex, 1);
firstdone = true;
}
}
//-------------------------------------
@ -150,32 +121,6 @@ void SkyboxProvider::OnSetConstants(IMaterialRendererServices *srv, int)
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;
core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION);
ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW);
ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD);
srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16);
if (visible)
{
transparency = diff;
}
else
{
transparency = 1.0f - diff;
}
transparency = clampf(transparency, 0, 1);
srv->setVertexShaderConstant("time", &time, 1);
srv->setVertexShaderConstant("transparency", &transparency, 1);
}
//-------------------------------------
@ -244,46 +189,12 @@ void MipVizProvider::OnSetConstants(IMaterialRendererServices *srv, int)
void ColorizeProvider::OnSetConstants(IMaterialRendererServices *srv, int)
{
core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION);
ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW);
ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD);
srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16);
srv->setVertexShaderConstant("col", m_color, 3);
}
//-------------------------------------
void ObjectPassProvider::OnSetConstants(IMaterialRendererServices *srv, int)
{
core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION);
ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW);
ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD);
core::matrix4 TransposeInverseModelView = srv->getVideoDriver()->getTransform(ETS_VIEW);
TransposeInverseModelView *= srv->getVideoDriver()->getTransform(ETS_WORLD);
TransposeInverseModelView.makeInverse();
TransposeInverseModelView = TransposeInverseModelView.getTransposed();
srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16);
srv->setVertexShaderConstant("TransposeInverseModelView", TransposeInverseModelView.pointer(), 16);
srv->setVertexShaderConstant("TextureMatrix0", mat.getTextureMatrix(0).pointer(), 16);
srv->setVertexShaderConstant("TextureMatrix1", mat.getTextureMatrix(1).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);
//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);
}
}
//-------------------------------------
@ -344,83 +255,6 @@ void SunLightProvider::OnSetConstants(IMaterialRendererServices *srv, int)
//-------------------------------------
void MLAAColor1Provider::OnSetConstants(IMaterialRendererServices *srv, int)
{
core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION);
ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW);
ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD);
srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16);
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)
{
core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION);
ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW);
ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD);
srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16);
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 ShadowPassProvider::OnSetConstants(IMaterialRendererServices *srv, int)
{
@ -543,17 +377,7 @@ void ShadowGenProvider::OnSetConstants(IMaterialRendererServices *srv, int)
void DisplaceProvider::OnSetConstants(IMaterialRendererServices *srv, int)
{
core::matrix4 ProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION);
core::matrix4 ModelViewMatrix = srv->getVideoDriver()->getTransform(ETS_VIEW);
ModelViewMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD);
srv->setVertexShaderConstant("ProjectionMatrix", ProjectionMatrix.pointer(), 16);
srv->setVertexShaderConstant("ModelViewMatrix", ModelViewMatrix.pointer(), 16);
srv->setVertexShaderConstant("dir", m_dir, 2);
srv->setVertexShaderConstant("dir2", m_dir2, 2);
srv->setVertexShaderConstant("screen", m_screen, 2);
}
void DisplaceProvider::update()

View File

@ -395,7 +395,7 @@ public:
{
const video::IVideoDriver * const drv = irr_driver->getVideoDriver();
// Sun "position" is actually a direction and not a position
core::matrix4 m_view = drv->getTransform(video::ETS_VIEW);
core::matrix4 m_view = irr_driver->getViewMatrix();
m_view.makeInverse();
m_view = m_view.getTransposed();
core::vector3df pos(x, y, z);
@ -426,30 +426,6 @@ private:
//
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 ShadowPassProvider: public CallBase
{
public:

View File

@ -57,10 +57,15 @@ PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
PFNGLTEXIMAGE3DPROC glTexImage3D;
PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
#endif
static bool is_gl_init = false;
@ -197,10 +202,15 @@ void initGL()
glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribIPointer");
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenFramebuffers");
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindFramebuffer");
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)IRR_OGL_LOAD_EXTENSION("glFramebufferTexture2D");
glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glFramebufferTexture");
glTexImage3D = (PFNGLTEXIMAGE3DPROC)IRR_OGL_LOAD_EXTENSION("glTexImage3D");
glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)IRR_OGL_LOAD_EXTENSION("glGenerateMipmap");
glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)IRR_OGL_LOAD_EXTENSION("glCheckFramebufferStatus");
glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)IRR_OGL_LOAD_EXTENSION("glTexImage2DMultisample");
glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBlitFramebuffer");
glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformBlockIndex");
glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)IRR_OGL_LOAD_EXTENSION("glUniformBlockBinding");
#ifdef DEBUG
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB");
#endif
@ -305,10 +315,20 @@ void transformTexturesTosRGB(irr::video::ITexture *tex)
memcpy(data, tex->lock(), w * h * 4);
tex->unlock();
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex));
if (tex->hasAlpha())
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)data);
if (irr_driver->getGLSLVersion() < 150)
{
if (tex->hasAlpha())
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)data);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, (GLvoid *)data);
}
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, (GLvoid *)data);
{
if (tex->hasAlpha())
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)data);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, (GLvoid *)data);
}
glGenerateMipmap(GL_TEXTURE_2D);
delete[] data;
}
@ -333,6 +353,15 @@ void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum
}
}
void blitFBO(GLuint Src, GLuint Dst, size_t width, size_t height)
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, Src);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, Dst);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
static void drawTexColoredQuad(const video::ITexture *texture, const video::SColor *col, float width, float height,
float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y,
float tex_width, float tex_height)

View File

@ -74,10 +74,15 @@ extern PFNGLBUFFERSUBDATAPROC glBufferSubData;
extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
extern PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
extern PFNGLTEXIMAGE3DPROC glTexImage3D;
extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
#ifdef DEBUG
extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
#endif
@ -153,6 +158,7 @@ GLint LoadProgram(Types ... args)
GLuint getTextureGLuint(irr::video::ITexture *tex);
GLuint getDepthTexture(irr::video::ITexture *tex);
void transformTexturesTosRGB(irr::video::ITexture *tex);
void blitFBO(GLuint Src, GLuint Dst, size_t width, size_t height);
void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect<s32>& destRect,
const irr::core::rect<s32>& sourceRect, const irr::core::rect<s32>* clipRect,

View File

@ -444,7 +444,7 @@ void ParticleSystemProxy::drawFlip()
};
setTexture(0, texture, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
setTexture(1, static_cast<video::COpenGLFBOTexture *>(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))->DepthBufferTexture, GL_NEAREST, GL_NEAREST);
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
ParticleShader::FlipParticleRender::setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(), irr_driver->getInvProjMatrix(), screen[0], screen[1], 0, 1);
@ -466,7 +466,7 @@ void ParticleSystemProxy::drawNotFlip()
};
setTexture(0, texture, GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
setTexture(1, static_cast<video::COpenGLFBOTexture *>(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))->DepthBufferTexture, GL_NEAREST, GL_NEAREST);
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
ParticleShader::SimpleParticleRender::setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(),
irr_driver->getInvProjMatrix(), screen[0], screen[1], 0, 1, this);

View File

@ -455,8 +455,6 @@ void IrrDriver::initDevice()
m_mrt.clear();
m_mrt.reallocate(2);
m_mrt.push_back(m_rtts->getRTT(RTT_COLOR));
m_mrt.push_back(m_rtts->getRTT(RTT_NORMAL_AND_DEPTH));
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
gl_driver->extGlGenQueries(1, &m_lensflare_query);

View File

@ -429,7 +429,9 @@ public:
return (m_shaders == NULL ? NULL : m_shaders->m_callbacks[num]);
}
// ------------------------------------------------------------------------
inline video::ITexture* getRTT(TypeRTT which) {return m_rtts->getRTT(which);}
inline GLuint getRenderTargetTexture(TypeRTT which) { return m_rtts->getRenderTarget(which); }
inline GLuint getFBO(TypeFBO which) { return m_rtts->getFBO(which); }
inline GLuint getDepthStencilTexture() { return m_rtts->getDepthStencilTexture(); }
// ------------------------------------------------------------------------
inline bool isGLSL() const { return m_glsl; }
// ------------------------------------------------------------------------

View File

@ -205,66 +205,39 @@ void PostProcessing::update(float dt)
} // update
static
void renderBloom(ITexture *in)
void renderBloom(GLuint in)
{
const float threshold = World::getWorld()->getTrack()->getBloomThreshold();
glUseProgram(FullScreenShader::BloomShader::Program);
glBindVertexArray(FullScreenShader::BloomShader::vao);
setTexture(0, getTextureGLuint(in), GL_NEAREST, GL_NEAREST);
setTexture(0, in, GL_NEAREST, GL_NEAREST);
FullScreenShader::BloomShader::setUniforms(0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
static
void renderBloomBlend(ITexture *in)
{
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
glDisable(GL_DEPTH_TEST);
glUseProgram(FullScreenShader::BloomBlendShader::Program);
glBindVertexArray(FullScreenShader::BloomBlendShader::vao);
setTexture(0, getTextureGLuint(in), GL_LINEAR, GL_LINEAR);
FullScreenShader::BloomBlendShader::setUniforms(0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
static
void renderColorLevel(ITexture *in)
void renderColorLevel(GLuint in)
{
core::vector3df m_inlevel = World::getWorld()->getTrack()->getColorLevelIn();
core::vector2df m_outlevel = World::getWorld()->getTrack()->getColorLevelOut();
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glUseProgram(FullScreenShader::ColorLevelShader::Program);
glBindVertexArray(FullScreenShader::ColorLevelShader::vao);
glUniform3f(FullScreenShader::ColorLevelShader::uniform_inlevel, m_inlevel.X, m_inlevel.Y, m_inlevel.Z);
glUniform2f(FullScreenShader::ColorLevelShader::uniform_outlevel, m_outlevel.X, m_outlevel.Y);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(in));
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, getDepthTexture(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
setTexture(0, in, GL_NEAREST, GL_NEAREST);
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
glUniform1i(FullScreenShader::ColorLevelShader::uniform_tex, 0);
glUniform1i(FullScreenShader::ColorLevelShader::uniform_dtex, 1);
setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_LOG_LUMINANCE)), GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST);
setTexture(2, irr_driver->getRenderTargetTexture(RTT_LOG_LUMINANCE), GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST);
glUniform1i(FullScreenShader::ColorLevelShader::uniform_logluminancetex, 2);
glUniformMatrix4fv(FullScreenShader::ColorLevelShader::uniform_invprojm, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer());
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST);
}
void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff)
@ -277,7 +250,7 @@ void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSH
glUseProgram(FullScreenShader::DiffuseEnvMapShader::Program);
glBindVertexArray(FullScreenShader::DiffuseEnvMapShader::vao);
setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
core::matrix4 TVM = irr_driver->getViewMatrix().getTransposed();
FullScreenShader::DiffuseEnvMapShader::setUniforms(TVM, bSHCoeff, gSHCoeff, rSHCoeff, 0);
@ -300,8 +273,8 @@ void PostProcessing::renderSunlight()
glUseProgram(FullScreenShader::SunLightShader::Program);
glBindVertexArray(FullScreenShader::SunLightShader::vao);
setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST);
setTexture(1, getDepthTexture(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
FullScreenShader::SunLightShader::setUniforms(cb->getPosition(), irr_driver->getInvProjMatrix(), cb->getRed(), cb->getGreen(), cb->getBlue(), 0, 1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
@ -318,8 +291,8 @@ void PostProcessing::renderShadowedSunlight(const std::vector<core::matrix4> &su
glUseProgram(FullScreenShader::ShadowedSunLightShader::Program);
glBindVertexArray(FullScreenShader::ShadowedSunLightShader::vao);
setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST);
setTexture(1, getDepthTexture(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D_ARRAY, depthtex);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -334,105 +307,74 @@ void PostProcessing::renderShadowedSunlight(const std::vector<core::matrix4> &su
}
void PostProcessing::renderGaussian3Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height)
void PostProcessing::renderGaussian3Blur(GLuint in_fbo, GLuint in_tex, GLuint tmp_fbo, GLuint tmp_tex, size_t width, size_t height)
{
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
float inv_width = 1. / width, inv_height = 1. / height;
{
irr_driver->getVideoDriver()->setRenderTarget(temprtt, false, false);
glBindFramebuffer(GL_FRAMEBUFFER, tmp_fbo);
glUseProgram(FullScreenShader::Gaussian3VBlurShader::Program);
glBindVertexArray(FullScreenShader::Gaussian3VBlurShader::vao);
glUniform2f(FullScreenShader::Gaussian3VBlurShader::uniform_pixel, inv_width, inv_height);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(in));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
setTexture(0, in_tex, GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(FullScreenShader::Gaussian3VBlurShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
{
irr_driver->getVideoDriver()->setRenderTarget(in, false, false);
glBindFramebuffer(GL_FRAMEBUFFER, in_fbo);
glUseProgram(FullScreenShader::Gaussian3HBlurShader::Program);
glBindVertexArray(FullScreenShader::Gaussian3HBlurShader::vao);
glUniform2f(FullScreenShader::Gaussian3HBlurShader::uniform_pixel, inv_width, inv_height);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(temprtt));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
setTexture(0, tmp_tex, GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(FullScreenShader::Gaussian3HBlurShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST);
}
void PostProcessing::renderGaussian6Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height)
void PostProcessing::renderGaussian6Blur(GLuint in_fbo, GLuint in_tex, GLuint tmp_fbo, GLuint tmp_tex, size_t width, size_t height)
{
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
float inv_width = 1. / width, inv_height = 1. / height;
{
irr_driver->getVideoDriver()->setRenderTarget(temprtt, false, false);
glBindFramebuffer(GL_FRAMEBUFFER, tmp_fbo);
glUseProgram(FullScreenShader::Gaussian6VBlurShader::Program);
glBindVertexArray(FullScreenShader::Gaussian6VBlurShader::vao);
glUniform2f(FullScreenShader::Gaussian6VBlurShader::uniform_pixel, inv_width, inv_height);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(in));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
setTexture(0, in_tex, GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(FullScreenShader::Gaussian6VBlurShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
{
irr_driver->getVideoDriver()->setRenderTarget(in, false, false);
glBindFramebuffer(GL_FRAMEBUFFER, in_fbo);
glUseProgram(FullScreenShader::Gaussian6HBlurShader::Program);
glBindVertexArray(FullScreenShader::Gaussian6HBlurShader::vao);
glUniform2f(FullScreenShader::Gaussian6HBlurShader::uniform_pixel, inv_width, inv_height);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(temprtt));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
setTexture(0, tmp_tex, GL_LINEAR, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glUniform1i(FullScreenShader::Gaussian6HBlurShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST);
}
void PostProcessing::renderPassThrough(ITexture *tex)
{
glDisable(GL_DEPTH_TEST);
glUseProgram(FullScreenShader::PassThroughShader::Program);
glBindVertexArray(FullScreenShader::PassThroughShader::vao);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glUniform1i(FullScreenShader::PassThroughShader::uniform_texture, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
void PostProcessing::renderPassThrough(GLuint tex)
{
glDisable(GL_DEPTH_TEST);
glUseProgram(FullScreenShader::PassThroughShader::Program);
glBindVertexArray(FullScreenShader::PassThroughShader::vao);
@ -444,32 +386,18 @@ void PostProcessing::renderPassThrough(GLuint tex)
glUniform1i(FullScreenShader::PassThroughShader::uniform_texture, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
}
void PostProcessing::renderGlow(ITexture *tex)
void PostProcessing::renderGlow(unsigned tex)
{
glDisable(GL_DEPTH_TEST);
glUseProgram(FullScreenShader::GlowShader::Program);
glBindVertexArray(FullScreenShader::GlowShader::vao);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
setTexture(0, tex, GL_LINEAR, GL_LINEAR);
glUniform1i(FullScreenShader::GlowShader::uniform_tex, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
}
ITexture *noise_tex = 0;
@ -485,8 +413,8 @@ void PostProcessing::renderSSAO(const core::matrix4 &invprojm, const core::matri
glUseProgram(FullScreenShader::SSAOShader::Program);
glBindVertexArray(FullScreenShader::SSAOShader::vao);
setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST);
setTexture(1, getDepthTexture(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_LINEAR, GL_LINEAR);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
setTexture(1, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR);
setTexture(2, getTextureGLuint(noise_tex), GL_NEAREST, GL_NEAREST);
FullScreenShader::SSAOShader::setUniforms(projm, invprojm, 0, 1, 2);
@ -500,7 +428,6 @@ void PostProcessing::renderSSAO(const core::matrix4 &invprojm, const core::matri
void PostProcessing::renderFog(const core::matrix4 &ipvmat)
{
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false);
const Track * const track = World::getWorld()->getTrack();
// This function is only called once per frame - thus no need for setters.
@ -523,7 +450,7 @@ void PostProcessing::renderFog(const core::matrix4 &ipvmat)
glUseProgram(FullScreenShader::FogShader::Program);
glBindVertexArray(FullScreenShader::FogShader::vao);
setTexture(0, getDepthTexture(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST);
setTexture(0, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
FullScreenShader::FogShader::setUniforms(ipvmat, fogmax, startH, endH, start, end, col, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@ -534,7 +461,7 @@ void PostProcessing::renderFog(const core::matrix4 &ipvmat)
glDisable(GL_BLEND);
}
void PostProcessing::renderMotionBlur(unsigned cam, ITexture *in, ITexture *out)
void PostProcessing::renderMotionBlur(unsigned cam, GLuint in_rtt, GLuint out_fbo)
{
MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver->
@ -553,56 +480,38 @@ void PostProcessing::renderMotionBlur(unsigned cam, ITexture *in, ITexture *out)
const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f;
setMotionBlurCenterY(cam, karty);
irr_driver->getVideoDriver()->setRenderTarget(out, true, false);
glBindFramebuffer(GL_FRAMEBUFFER, out_fbo);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(FullScreenShader::MotionBlurShader::Program);
glBindVertexArray(FullScreenShader::MotionBlurShader::vao);
setTexture(0, getTextureGLuint(in), GL_NEAREST, GL_NEAREST);
setTexture(0, in_rtt, GL_NEAREST, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
FullScreenShader::MotionBlurShader::setUniforms(cb->getBoostTime(cam), cb->getCenter(cam), cb->getDirection(cam), 0.15, cb->getMaxHeight(cam) * 0.7, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
}
static void renderGodFade(GLuint tex, const SColor &col)
{
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glUseProgram(FullScreenShader::GodFadeShader::Program);
glBindVertexArray(FullScreenShader::GodFadeShader::vao);
setTexture(0, tex, GL_LINEAR, GL_LINEAR);
FullScreenShader::GodFadeShader::setUniforms(col, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST);
}
static void renderGodRay(GLuint tex, const core::vector2df &sunpos)
{
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glUseProgram(FullScreenShader::GodRayShader::Program);
glBindVertexArray(FullScreenShader::GodRayShader::vao);
setTexture(0, tex, GL_LINEAR, GL_LINEAR);
FullScreenShader::GodRayShader::setUniforms(sunpos, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnable(GL_DEPTH_TEST);
}
static void averageTexture(GLuint tex)
@ -614,23 +523,21 @@ static void averageTexture(GLuint tex)
static void computeLogLuminance(GLuint tex)
{
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
IVideoDriver *const drv = irr_driver->getVideoDriver();
drv->setRenderTarget(irr_driver->getRTT(RTT_LOG_LUMINANCE), false, false);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_LOG_LUMINANCE));
glUseProgram(FullScreenShader::LogLuminanceShader::Program);
glBindVertexArray(FullScreenShader::LogLuminanceShader::vao);
setTexture(0, tex, GL_LINEAR, GL_LINEAR);
FullScreenShader::LogLuminanceShader::setUniforms(0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
averageTexture(getTextureGLuint(irr_driver->getRTT(RTT_LOG_LUMINANCE)));
averageTexture(irr_driver->getRenderTargetTexture(RTT_LOG_LUMINANCE));
}
void PostProcessing::applyMLAA(video::ITexture *in, video::ITexture *out)
void PostProcessing::applyMLAA()
{
const core::vector2df &PIXEL_SIZE = core::vector2df(1.0f / UserConfigParams::m_width, 1.0f / UserConfigParams::m_height);
IVideoDriver *const drv = irr_driver->getVideoDriver();
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_TMP1_WITH_DS));
glEnable(GL_STENCIL_TEST);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
@ -638,7 +545,7 @@ void PostProcessing::applyMLAA(video::ITexture *in, video::ITexture *out)
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
// Pass 1: color edge detection
setTexture(0, getTextureGLuint(in), GL_NEAREST, GL_NEAREST);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_MLAA_COLORS), GL_NEAREST, GL_NEAREST);
glUseProgram(FullScreenShader::MLAAColorEdgeDetectionSHader::Program);
FullScreenShader::MLAAColorEdgeDetectionSHader::setUniforms(PIXEL_SIZE, 0);
@ -649,23 +556,27 @@ void PostProcessing::applyMLAA(video::ITexture *in, video::ITexture *out)
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// Pass 2: blend weights
drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_TMP2_WITH_DS));
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(FullScreenShader::MLAABlendWeightSHader::Program);
setTexture(0, getTextureGLuint(out), GL_LINEAR, GL_LINEAR);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_TMP1), GL_LINEAR, GL_LINEAR);
setTexture(1, getTextureGLuint(m_areamap), GL_NEAREST, GL_NEAREST);
FullScreenShader::MLAABlendWeightSHader::setUniforms(PIXEL_SIZE, 0, 1);
glBindVertexArray(FullScreenShader::MLAABlendWeightSHader::vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Blit in to tmp1
blitFBO(irr_driver->getFBO(FBO_MLAA_COLORS), irr_driver->getFBO(FBO_TMP1_WITH_DS), UserConfigParams::m_width, UserConfigParams::m_height);
// Pass 3: gather
drv->setRenderTarget(in, false, false);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_MLAA_COLORS));
glUseProgram(FullScreenShader::MLAAGatherSHader::Program);
setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_TMP3)), GL_NEAREST, GL_NEAREST);
setTexture(1, getTextureGLuint(irr_driver->getRTT(RTT_COLOR)), GL_NEAREST, GL_NEAREST);
FullScreenShader::MLAAGatherSHader::setUniforms(PIXEL_SIZE, 1, 0);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_TMP1), GL_NEAREST, GL_NEAREST);
setTexture(1, irr_driver->getRenderTargetTexture(RTT_TMP2), GL_NEAREST, GL_NEAREST);
FullScreenShader::MLAAGatherSHader::setUniforms(PIXEL_SIZE, 0, 1);
glBindVertexArray(FullScreenShader::MLAAGatherSHader::vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@ -682,9 +593,6 @@ void PostProcessing::render()
if (!irr_driver->isGLSL()) return;
IVideoDriver * const drv = irr_driver->getVideoDriver();
drv->setTransform(ETS_WORLD, core::IdentityMatrix);
drv->setTransform(ETS_VIEW, core::IdentityMatrix);
drv->setTransform(ETS_PROJECTION, core::IdentityMatrix);
MotionBlurProvider * const mocb = (MotionBlurProvider *) irr_driver->
getCallback(ES_MOTIONBLUR);
@ -697,70 +605,73 @@ void PostProcessing::render()
scene::ICameraSceneNode * const camnode =
Camera::getCamera(cam)->getCameraSceneNode();
mocb->setCurrentCamera(cam);
ITexture *in = irr_driver->getRTT(RTT_COLOR);
ITexture *out = irr_driver->getRTT(RTT_TMP1);
GLuint in_rtt = irr_driver->getRenderTargetTexture(RTT_TMP2), in_fbo = irr_driver->getFBO(FBO_TMP2_WITH_DS);
GLuint out_rtt = irr_driver->getRenderTargetTexture(RTT_TMP1), out_fbo = irr_driver->getFBO(FBO_TMP1_WITH_DS);
// Each effect uses these as named, and sets them up for the next effect.
// This allows chaining effects where some may be disabled.
// As the original color shouldn't be touched, the first effect can't be disabled.
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
PROFILER_PUSH_CPU_MARKER("- Bloom", 0xFF, 0x00, 0x00);
if (1) // bloom
{
// Blit the base to tmp1
drv->setRenderTarget(out, true, false);
renderPassThrough(in);
// Blit the base to tmp1
blitFBO(irr_driver->getFBO(FBO_COLORS), out_fbo, UserConfigParams::m_width, UserConfigParams::m_height);
const bool globalbloom = World::getWorld()->getTrack()->getBloom();
if (globalbloom)
{
drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false);
renderBloom(in);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_TMP2_WITH_DS));
renderBloom(out_rtt);
glClear(GL_STENCIL_BUFFER_BIT);
// To half
drv->setRenderTarget(irr_driver->getRTT(RTT_HALF1), true, false);
renderPassThrough(irr_driver->getRTT(RTT_TMP3));
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_HALF1));
glViewport(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_TMP2));
renderGaussian6Blur(irr_driver->getFBO(FBO_HALF1), irr_driver->getRenderTargetTexture(RTT_HALF1),
irr_driver->getFBO(FBO_HALF2), irr_driver->getRenderTargetTexture(RTT_HALF2), UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
// To quarter
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false);
renderPassThrough(irr_driver->getRTT(RTT_HALF1));
// To eighth
drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), true, false);
renderPassThrough(irr_driver->getRTT(RTT_QUARTER1));
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_QUARTER1));
glViewport(0, 0, UserConfigParams::m_width / 4, UserConfigParams::m_height / 4);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_HALF1));
renderGaussian6Blur(irr_driver->getFBO(FBO_QUARTER1), irr_driver->getRenderTargetTexture(RTT_QUARTER1),
irr_driver->getFBO(FBO_QUARTER2), irr_driver->getRenderTargetTexture(RTT_QUARTER2), UserConfigParams::m_width / 4, UserConfigParams::m_height / 4);
// Blur it for distribution.
renderGaussian6Blur(irr_driver->getRTT(RTT_HALF1), irr_driver->getRTT(RTT_HALF2), 2.f / UserConfigParams::m_width, 2.f / UserConfigParams::m_height);
renderGaussian6Blur(irr_driver->getRTT(RTT_QUARTER1), irr_driver->getRTT(RTT_QUARTER2), 4.f / UserConfigParams::m_width, 4.f / UserConfigParams::m_height);
renderGaussian6Blur(irr_driver->getRTT(RTT_EIGHTH1), irr_driver->getRTT(RTT_EIGHTH2), 8.f / UserConfigParams::m_width, 8.f / UserConfigParams::m_height);
// To eighth
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_EIGHTH1));
glViewport(0, 0, UserConfigParams::m_width / 8, UserConfigParams::m_height / 8);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_QUARTER1));
renderGaussian6Blur(irr_driver->getFBO(FBO_EIGHTH1), irr_driver->getRenderTargetTexture(RTT_EIGHTH1),
irr_driver->getFBO(FBO_EIGHTH2), irr_driver->getRenderTargetTexture(RTT_EIGHTH2), UserConfigParams::m_width / 8, UserConfigParams::m_height / 8);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
// Additively blend on top of tmp1
drv->setRenderTarget(out, false, false);
glBindFramebuffer(GL_FRAMEBUFFER, out_fbo);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
renderPassThrough(irr_driver->getRTT(RTT_HALF1));
renderPassThrough(irr_driver->getRTT(RTT_QUARTER1));
renderPassThrough(irr_driver->getRTT(RTT_EIGHTH1));
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_HALF1));
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_QUARTER1));
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_EIGHTH1));
glDisable(GL_BLEND);
} // end if bloom
in = irr_driver->getRTT(RTT_TMP1);
out = irr_driver->getRTT(RTT_TMP2);
}
std::swap(in_fbo, out_fbo);
std::swap(in_rtt, out_rtt);
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00);
if (m_sunpixels > 30)//World::getWorld()->getTrack()->hasGodRays() && ) // god rays
{
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
// Grab the sky
drv->setRenderTarget(out, true, false);
// irr_driver->getSceneManager()->drawAll(ESNRP_SKY_BOX);
glBindFramebuffer(GL_FRAMEBUFFER, out_fbo);
glClear(GL_COLOR_BUFFER_BIT);
irr_driver->renderSkybox();
// Set the sun's color
@ -770,25 +681,21 @@ void PostProcessing::render()
// The sun interposer
STKMeshSceneNode *sun = irr_driver->getSunInterposer();
/* sun->getMaterial(0).ColorMask = ECP_ALL;
irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID);*/
irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA);
irr_driver->setPhase(GLOW_PASS);
sun->render();
//sun->getMaterial(0).ColorMask = ECP_NONE;
glDisable(GL_DEPTH_TEST);
// Fade to quarter
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false);
renderGodFade(getTextureGLuint(out), col);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_QUARTER1));
glViewport(0, 0, UserConfigParams::m_width / 4, UserConfigParams::m_height / 4);
renderGodFade(irr_driver->getRenderTargetTexture(RTT_TMP2), col);
// Blur
renderGaussian3Blur(irr_driver->getRTT(RTT_QUARTER1),
irr_driver->getRTT(RTT_QUARTER2),
4.f / UserConfigParams::m_width,
4.f / UserConfigParams::m_height);
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER1), irr_driver->getRenderTargetTexture(RTT_QUARTER1),
irr_driver->getFBO(FBO_QUARTER2), irr_driver->getRenderTargetTexture(RTT_QUARTER2),
UserConfigParams::m_width / 4,
UserConfigParams::m_height / 4);
@ -806,81 +713,59 @@ void PostProcessing::render()
const float sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw;
const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh;
// ((GodRayProvider *) irr_driver->getCallback(ES_GODRAY))->
// setSunPosition(sunx, suny);
// Rays please
drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false);
renderGodRay(getTextureGLuint(irr_driver->getRTT(RTT_QUARTER1)), core::vector2df(sunx, suny));
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_QUARTER2));
renderGodRay(irr_driver->getRenderTargetTexture(RTT_QUARTER1), core::vector2df(sunx, suny));
// Blur
renderGaussian3Blur(irr_driver->getRTT(RTT_QUARTER2),
irr_driver->getRTT(RTT_QUARTER1),
4.f / UserConfigParams::m_width,
4.f / UserConfigParams::m_height);
renderGaussian3Blur(irr_driver->getFBO(FBO_QUARTER2), irr_driver->getRenderTargetTexture(RTT_QUARTER2),
irr_driver->getFBO(FBO_QUARTER1), irr_driver->getRenderTargetTexture(RTT_QUARTER1),
UserConfigParams::m_width / 4,
UserConfigParams::m_height / 4);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
// Blend
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
drv->setRenderTarget(in, false, false);
renderPassThrough(irr_driver->getRTT(RTT_QUARTER2));
glBindFramebuffer(GL_FRAMEBUFFER, in_fbo);
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_QUARTER2));
glDisable(GL_BLEND);
}
PROFILER_POP_CPU_MARKER();
if (UserConfigParams::m_motionblur && m_any_boost) // motion blur
{
PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00);
renderMotionBlur(cam, in, out);
ITexture *tmp = in;
in = out;
out = tmp;
renderMotionBlur(cam, in_rtt, out_fbo);
std::swap(in_fbo, out_fbo);
std::swap(in_rtt, out_rtt);
PROFILER_POP_CPU_MARKER();
}
/* m_material.MaterialType = irr_driver->getShader(ES_RAIN);
drv->setMaterial(m_material);
static_cast<irr::video::COpenGLDriver*>(drv)->setRenderStates3DMode();*/
if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
{
PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00);
glDisable(GL_BLEND);
drv->setRenderTarget(irr_driver->getRTT(RTT_FINAL_COLOR), false, false);
renderPassThrough(in);
drv->setRenderTarget(out, false, false);
applyMLAA(irr_driver->getRTT(RTT_FINAL_COLOR), out);
in = irr_driver->getRTT(RTT_FINAL_COLOR);
blitFBO(in_fbo, irr_driver->getFBO(FBO_MLAA_COLORS), UserConfigParams::m_width, UserConfigParams::m_height);
applyMLAA();
in_rtt = irr_driver->getRenderTargetTexture(RTT_MLAA_COLORS);
PROFILER_POP_CPU_MARKER();
}
computeLogLuminance(getTextureGLuint(in));
computeLogLuminance(in_rtt);
// Final blit
// TODO : Use glBlitFramebuffer
drv->setRenderTarget(ERT_FRAME_BUFFER, false, false);
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if (irr_driver->getNormals())
renderPassThrough(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH));
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH));
else if (irr_driver->getSSAOViz())
renderPassThrough(irr_driver->getRTT(RTT_SSAO));
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_SSAO));
else
renderColorLevel(in);
renderColorLevel(in_rtt);
glDisable(GL_FRAMEBUFFER_SRGB);
}
} // render
void PostProcessing::drawQuad(u32 cam, const SMaterial &mat)
{
const u16 indices[6] = {0, 1, 2, 3, 0, 2};
IVideoDriver * const drv = irr_driver->getVideoDriver();
drv->setTransform(ETS_WORLD, core::IdentityMatrix);
drv->setTransform(ETS_VIEW, core::IdentityMatrix);
drv->setTransform(ETS_PROJECTION, core::IdentityMatrix);
drv->setMaterial(mat);
drv->drawIndexedTriangleList(&(m_vertices[cam].v0),
4, indices, 2);
}

View File

@ -81,23 +81,19 @@ public:
void renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff);
/** Blur the in texture */
void renderGaussian3Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height);
void renderGaussian6Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height);
void renderGaussian3Blur(unsigned in_fbo, unsigned in_tex, unsigned tmp_fbo, unsigned tmp_tex, size_t inv_width, size_t inv_height);
void renderGaussian6Blur(unsigned in_fbo, unsigned in_tex, unsigned tmp_fbo, unsigned tmp_tex, size_t width, size_t height);
/** Render tex. Used for blit/texture resize */
void renderPassThrough(video::ITexture *tex);
void renderPassThrough(unsigned tex);
void applyMLAA(video::ITexture *in, video::ITexture *out);
void applyMLAA();
void renderMotionBlur(unsigned cam, video::ITexture *in, video::ITexture *out);
void renderGlow(video::ITexture *tex);
void renderMotionBlur(unsigned cam, unsigned in_rtt, unsigned out_fbo);
void renderGlow(unsigned tex);
/** Render the post-processed scene */
void render();
/** Draw the quad for this camera */
void drawQuad(u32 cam, const video::SMaterial &mat);
/** Use motion blur for a short time */
void giveBoost(unsigned int cam_index);

View File

@ -119,15 +119,7 @@ void IrrDriver::renderGLSL(float dt)
// 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->begin();
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false);
m_video_driver->beginScene(/*backBuffer clear*/ true, /*zBuffer*/ true,
world->getClearColor());
// Clear normal and depth to zero
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_NORMAL_AND_DEPTH), true, false, video::SColor(0,0,0,0));
irr_driver->getVideoDriver()->enableMaterial2D();
RaceGUIBase *rg = world->getRaceGUI();
if (rg) rg->update(dt);
@ -171,6 +163,13 @@ void IrrDriver::renderGLSL(float dt)
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, true);
}*/
// Get Projection and view matrix
irr_driver->setPhase(SOLID_NORMAL_AND_DEPTH_PASS);
m_scene_manager->drawAll(scene::ESNRP_CAMERA);
irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION));
irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
irr_driver->genProjViewMatrix();
// Fire up the MRT
PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00);
renderSolidFirstPass();
@ -290,6 +289,11 @@ void IrrDriver::renderGLSL(float dt)
m_post_processing->render();
PROFILER_POP_CPU_MARKER();
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glUseProgram(0);
// Set the viewport back to the full screen for race gui
m_video_driver->setViewPort(core::recti(0, 0,
UserConfigParams::m_width,
@ -408,45 +412,44 @@ void IrrDriver::renderFixed(float dt)
void IrrDriver::renderSolidFirstPass()
{
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false);
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS));
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
glClearColor(0., 0., 0., 0.);
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_SOLID;
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST);
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
glEnable(GL_CULL_FACE);
irr_driver->setPhase(SOLID_NORMAL_AND_DEPTH_PASS);
m_scene_manager->drawAll(m_renderpass);
irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION));
irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
irr_driver->genProjViewMatrix();
m_scene_manager->drawAll(scene::ESNRP_SOLID);
}
void IrrDriver::renderSolidSecondPass()
{
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_COLORS));
SColor clearColor = World::getWorld()->getClearColor();
glClearColor(clearColor.getRed() / 255., clearColor.getGreen() / 255., clearColor.getBlue() / 255., clearColor.getAlpha() / 255.);
glClear(GL_COLOR_BUFFER_BIT);
glDepthMask(GL_FALSE);
irr_driver->setPhase(SOLID_LIT_PASS);
glEnable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST);
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_SOLID;
setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_TMP1)), GL_NEAREST, GL_NEAREST);
setTexture(1, getTextureGLuint(irr_driver->getRTT(RTT_TMP2)), GL_NEAREST, GL_NEAREST);
setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_SSAO)), GL_NEAREST, GL_NEAREST);
if (!UserConfigParams::m_ssao)
{
GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE };
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
}
m_scene_manager->drawAll(m_renderpass);
setTexture(0, m_rtts->getRenderTarget(RTT_TMP1), GL_NEAREST, GL_NEAREST);
setTexture(1, m_rtts->getRenderTarget(RTT_TMP2), GL_NEAREST, GL_NEAREST);
setTexture(2, m_rtts->getRenderTarget(RTT_SSAO), GL_NEAREST, GL_NEAREST);
m_scene_manager->drawAll(scene::ESNRP_SOLID);
}
void IrrDriver::renderTransparent()
{
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_COLORS));
irr_driver->setPhase(TRANSPARENT_PASS);
m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_TRANSPARENT;
glEnable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST);
glDepthMask(GL_FALSE);
@ -454,17 +457,16 @@ void IrrDriver::renderTransparent()
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
m_scene_manager->drawAll(m_renderpass);
m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT);
}
void IrrDriver::renderParticles()
{
m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_TRANSPARENT_EFFECT;
glDepthMask(GL_FALSE);
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
m_scene_manager->drawAll(m_renderpass);
m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
}
void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb,
@ -563,7 +565,19 @@ void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb,
glViewport(0, 0, 1024, 1024);
glClear(GL_DEPTH_BUFFER_BIT);
glDrawBuffer(GL_NONE);
size_t size = irr_driver->getShadowViewProj().size();
float *tmp = new float[16 * size];
for (unsigned i = 0; i < size; i++) {
memcpy(&tmp[16 * i], irr_driver->getShadowViewProj()[i].pointer(), 16 * sizeof(float));
}
glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO);
glBufferSubData(GL_UNIFORM_BUFFER, 0, 16 * 4 * sizeof(float), tmp);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
delete tmp;
m_scene_manager->drawAll(scene::ESNRP_SOLID);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glCullFace(GL_BACK);
camnode->setNearValue(oldnear);
@ -571,6 +585,7 @@ void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb,
camnode->render();
camera->activate();
m_scene_manager->drawAll(scene::ESNRP_CAMERA);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
//sun_ortho_matrix *= m_suncam->getViewMatrix();
@ -671,10 +686,11 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat,
int cam)
{
m_scene_manager->setCurrentRendertime(scene::ESNRP_SOLID);
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_TMP1), false, false);
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_TMP1_WITH_DS));
glClearStencil(0);
glClearColor(0, 0, 0, 0);
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
const u32 glowcount = glows.size();
ColorizeProvider * const cb = (ColorizeProvider *) m_shaders->m_callbacks[ES_COLORIZE];
@ -703,35 +719,27 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat,
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glDisable(GL_STENCIL_TEST);
// Cool, now we have the colors set up. Progressively minify.
video::SMaterial minimat;
minimat.Lighting = false;
minimat.ZWriteEnable = false;
minimat.ZBuffer = video::ECFN_ALWAYS;
minimat.setFlag(video::EMF_TRILINEAR_FILTER, true);
minimat.TextureLayer[0].TextureWrapU =
minimat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
glDisable(GL_BLEND);
// To half
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_HALF1), false, false);
m_post_processing->renderPassThrough(m_rtts->getRTT(RTT_TMP1));
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_HALF1));
glViewport(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
m_post_processing->renderPassThrough(m_rtts->getRenderTarget(RTT_TMP1));
// To quarter
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_QUARTER1), false, false);
m_post_processing->renderPassThrough(m_rtts->getRTT(RTT_HALF1));
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_QUARTER1));
glViewport(0, 0, UserConfigParams::m_width / 4, UserConfigParams::m_height / 4);
m_post_processing->renderPassThrough(m_rtts->getRenderTarget(RTT_HALF1));
// Blur it
m_post_processing->renderGaussian6Blur(m_rtts->getRTT(RTT_QUARTER1), m_rtts->getRTT(RTT_QUARTER2), 4.f / UserConfigParams::m_width, 4.f / UserConfigParams::m_height);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glStencilFunc(GL_EQUAL, 0, ~0);
glEnable(GL_STENCIL_TEST);
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false);
m_post_processing->renderGlow(m_rtts->getRTT(RTT_QUARTER1));
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_COLORS));
m_post_processing->renderGlow(m_rtts->getRenderTarget(RTT_QUARTER1));
glDisable(GL_STENCIL_TEST);
}
@ -753,8 +761,8 @@ static void renderPointLights(unsigned count)
glBindBuffer(GL_ARRAY_BUFFER, LightShader::PointLightShader::vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(LightShader::PointLightInfo), PointLightsInfo);
setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST);
setTexture(1, getDepthTexture(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_NEAREST, GL_NEAREST);
setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
LightShader::PointLightShader::setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(), irr_driver->getInvProjMatrix(), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 200, 0, 1);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
@ -769,14 +777,11 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
sun_ortho_matrix[i] *= getInvViewMatrix();
core::array<video::IRenderTarget> rtts;
// Diffuse
rtts.push_back(m_rtts->getRTT(RTT_TMP1));
// Specular
rtts.push_back(m_rtts->getRTT(RTT_TMP2));
m_video_driver->setRenderTarget(rtts, true, false,
video::SColor(0, 0, 0, 0));
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2));
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
GLenum bufs[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
gl_driver->extGlDrawBuffers(2, bufs);
glClear(GL_COLOR_BUFFER_BIT);
const u32 lightcount = m_lights.size();
const core::vector3df &campos =
@ -848,19 +853,16 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
if (SkyboxCubeMap)
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
// Handle SSAO
m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), true, false,
SColor(255, 255, 255, 255));
if(UserConfigParams::m_ssao)
if (UserConfigParams::m_ssao)
{
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_SSAO));
glClearColor(1., 1., 1., 1.);
glClear(GL_COLOR_BUFFER_BIT);
m_post_processing->renderSSAO(irr_driver->getInvProjMatrix(), irr_driver->getProjMatrix());
// Blur it to reduce noise.
if(UserConfigParams::m_ssao == 1)
m_post_processing->renderGaussian3Blur(irr_driver->getRTT(RTT_SSAO), irr_driver->getRTT(RTT_QUARTER4), 4.f / UserConfigParams::m_width, 4.f / UserConfigParams::m_height);
else if (UserConfigParams::m_ssao == 2)
m_post_processing->renderGaussian6Blur(irr_driver->getRTT(RTT_SSAO), irr_driver->getRTT(RTT_TMP4), 1.f / UserConfigParams::m_width, 1.f / UserConfigParams::m_height);
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false);
// Blur it to reduce noise.
m_post_processing->renderGaussian6Blur(irr_driver->getFBO(FBO_SSAO), irr_driver->getRenderTargetTexture(RTT_SSAO),
irr_driver->getFBO(FBO_TMP4), irr_driver->getRenderTargetTexture(RTT_TMP4), UserConfigParams::m_width, UserConfigParams::m_height);
}
}
static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)
@ -1287,8 +1289,10 @@ void IrrDriver::renderSkybox()
void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat,
int cam)
{
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_TMP4), true, false);
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_DISPLACE), true, false);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_TMP4));
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_DISPLACE));
glClear(GL_COLOR_BUFFER_BIT);
DisplaceProvider * const cb = (DisplaceProvider *)irr_driver->getCallback(ES_DISPLACE);
cb->update();
@ -1313,8 +1317,8 @@ void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat,
m_displacing[i]->render();
}
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_COLORS));
glStencilFunc(GL_EQUAL, 1, 0xFF);
m_post_processing->renderPassThrough(m_rtts->getRTT(RTT_DISPLACE));
m_post_processing->renderPassThrough(m_rtts->getRenderTarget(RTT_DISPLACE));
glDisable(GL_STENCIL_TEST);
}

View File

@ -22,6 +22,35 @@
#include "graphics/irr_driver.hpp"
#include "utils/log.hpp"
static GLuint generateRTT(const core::dimension2du &res, GLint internalFormat, GLint format, GLint type)
{
GLuint result;
glGenTextures(1, &result);
glBindTexture(GL_TEXTURE_2D, result);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, res.Width, res.Height, 0, format, type, 0);
return result;
}
static GLuint generateFBO(GLuint ColorAttachement)
{
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ColorAttachement, 0);
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(result == GL_FRAMEBUFFER_COMPLETE_EXT);
return fbo;
}
static GLuint generateFBO(GLuint ColorAttachement, GLuint DepthAttachement)
{
GLuint fbo = generateFBO(ColorAttachement);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, DepthAttachement, 0);
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(result == GL_FRAMEBUFFER_COMPLETE_EXT);
return fbo;
}
RTT::RTT()
{
initGL();
@ -44,116 +73,74 @@ RTT::RTT()
const dimension2du warpvsize(1, 512);
const dimension2du warphsize(512, 1);
// The last parameter stands for "has stencil". The name is used in the texture
// cache, and when saving textures to files as the default name.
//
// All RTTs are currently RGBA8 with stencil. The four tmp RTTs are the same size
glGenTextures(1, &DepthStencilTexture);
glBindTexture(GL_TEXTURE_2D, DepthStencilTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, res.Width, res.Height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
// All RTTs are currently RGBA16F mostly with stencil. The four tmp RTTs are the same size
// as the screen, for use in post-processing.
//
// Optionally, the collapse ones use a smaller format.
bool stencil = true;
rtts[RTT_TMP1] = drv->addRenderTargetTexture(res, "rtt.tmp1", ECF_A16B16G16R16F, stencil);
rtts[RTT_TMP2] = drv->addRenderTargetTexture(res, "rtt.tmp2", ECF_A16B16G16R16F, stencil);
rtts[RTT_TMP3] = drv->addRenderTargetTexture(res, "rtt.tmp3", ECF_A16B16G16R16F, stencil);
rtts[RTT_TMP4] = drv->addRenderTargetTexture(res, "rtt.tmp4", ECF_R16F, stencil);
rtts[RTT_NORMAL_AND_DEPTH] = drv->addRenderTargetTexture(res, "rtt.normal_and_depth", ECF_G16R16F, stencil);
rtts[RTT_COLOR] = drv->addRenderTargetTexture(res, "rtt.color", ECF_A16B16G16R16F, stencil);
rtts[RTT_FINAL_COLOR] = drv->addRenderTargetTexture(res, "rtt.finalcolor", ECF_A8R8G8B8, stencil);
rtts[RTT_LOG_LUMINANCE] = drv->addRenderTargetTexture(shadowsize0, "rtt.logluminance", ECF_R16F, stencil);
RenderTargetTextures[RTT_TMP1] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_TMP2] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_TMP3] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_TMP4] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, GL_RGB16F, GL_RGB, GL_FLOAT);
RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_LOG_LUMINANCE] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_SSAO] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_DISPLACE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
rtts[RTT_HALF1] = drv->addRenderTargetTexture(half, "rtt.half1", ECF_A16B16G16R16F, stencil);
rtts[RTT_HALF2] = drv->addRenderTargetTexture(half, "rtt.half2", ECF_A16B16G16R16F, stencil);
RenderTargetTextures[RTT_HALF1] = generateRTT(half, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_QUARTER1] = generateRTT(quarter, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_EIGHTH1] = generateRTT(eighth, GL_RGBA16F, GL_BGRA, GL_FLOAT);
rtts[RTT_QUARTER1] = drv->addRenderTargetTexture(quarter, "rtt.q1", ECF_A16B16G16R16F, stencil);
rtts[RTT_QUARTER2] = drv->addRenderTargetTexture(quarter, "rtt.q2", ECF_A16B16G16R16F, stencil);
rtts[RTT_QUARTER3] = drv->addRenderTargetTexture(quarter, "rtt.q3", ECF_A16B16G16R16F, stencil);
rtts[RTT_QUARTER4] = drv->addRenderTargetTexture(quarter, "rtt.q4", ECF_R16F, stencil);
RenderTargetTextures[RTT_HALF2] = generateRTT(half, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_QUARTER2] = generateRTT(quarter, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_EIGHTH2] = generateRTT(eighth, GL_RGBA16F, GL_BGRA, GL_FLOAT);
rtts[RTT_EIGHTH1] = drv->addRenderTargetTexture(eighth, "rtt.e1", ECF_A16B16G16R16F, stencil);
rtts[RTT_EIGHTH2] = drv->addRenderTargetTexture(eighth, "rtt.e2", ECF_A16B16G16R16F, stencil);
FrameBuffers[FBO_SSAO] = generateFBO(RenderTargetTextures[RTT_SSAO]);
// Clear this FBO to 1s so that if no SSAO is computed we can still use it.
glClearColor(1., 1., 1., 1.);
glClear(GL_COLOR_BUFFER_BIT);
rtts[RTT_SIXTEENTH1] = drv->addRenderTargetTexture(sixteenth, "rtt.s1", ECF_A16B16G16R16F, stencil);
rtts[RTT_SIXTEENTH2] = drv->addRenderTargetTexture(sixteenth, "rtt.s2", ECF_A16B16G16R16F, stencil);
FrameBuffers[FBO_NORMAL_AND_DEPTHS] = generateFBO(RenderTargetTextures[RTT_NORMAL_AND_DEPTH], DepthStencilTexture);
FrameBuffers[FBO_COLORS] = generateFBO(RenderTargetTextures[RTT_COLOR], DepthStencilTexture);
FrameBuffers[FBO_MLAA_COLORS] = generateFBO(RenderTargetTextures[RTT_MLAA_COLORS], DepthStencilTexture);
FrameBuffers[FBO_LOG_LUMINANCE] = generateFBO(RenderTargetTextures[RTT_LOG_LUMINANCE]);
FrameBuffers[FBO_TMP1_WITH_DS] = generateFBO(RenderTargetTextures[RTT_TMP1], DepthStencilTexture);
FrameBuffers[FBO_TMP2_WITH_DS] = generateFBO(RenderTargetTextures[RTT_TMP2], DepthStencilTexture);
FrameBuffers[FBO_TMP4] = generateFBO(RenderTargetTextures[RTT_TMP4], DepthStencilTexture);
FrameBuffers[FBO_DISPLACE] = generateFBO(RenderTargetTextures[RTT_DISPLACE], DepthStencilTexture);
FrameBuffers[FBO_HALF1] = generateFBO(RenderTargetTextures[RTT_HALF1]);
FrameBuffers[FBO_HALF2] = generateFBO(RenderTargetTextures[RTT_HALF2]);
FrameBuffers[FBO_QUARTER1] = generateFBO(RenderTargetTextures[RTT_QUARTER1]);
FrameBuffers[FBO_QUARTER2] = generateFBO(RenderTargetTextures[RTT_QUARTER2]);
FrameBuffers[FBO_EIGHTH1] = generateFBO(RenderTargetTextures[RTT_EIGHTH1]);
FrameBuffers[FBO_EIGHTH2] = generateFBO(RenderTargetTextures[RTT_EIGHTH2]);
rtts[RTT_SSAO] = drv->addRenderTargetTexture(ssaosize, "rtt.ssao", ECF_R16F, stencil);
FrameBuffers[FBO_COMBINED_TMP1_TMP2] = generateFBO(RenderTargetTextures[RTT_TMP1], DepthStencilTexture);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, RenderTargetTextures[RTT_TMP2], 0);
rtts[RTT_WARPV] = drv->addRenderTargetTexture(warpvsize, "rtt.warpv", ECF_A8R8G8B8, stencil);
rtts[RTT_WARPH] = drv->addRenderTargetTexture(warphsize, "rtt.warph", ECF_A8R8G8B8, stencil);
rtts[RTT_DISPLACE] = drv->addRenderTargetTexture(res, "rtt.displace", ECF_A16B16G16R16F, stencil);
if (((COpenGLDriver *) drv)->queryOpenGLFeature(COpenGLDriver::IRR_ARB_texture_rg))
if (irr_driver->getGLSLVersion() >= 150)
{
// Use optimized formats if supported
rtts[RTT_COLLAPSE] = drv->addRenderTargetTexture(shadowsize0, "rtt.collapse", ECF_R8, stencil);
rtts[RTT_COLLAPSEV] = drv->addRenderTargetTexture(warpvsize, "rtt.collapsev", ECF_R8, stencil);
rtts[RTT_COLLAPSEH] = drv->addRenderTargetTexture(warphsize, "rtt.collapseh", ECF_R8, stencil);
rtts[RTT_COLLAPSEV2] = drv->addRenderTargetTexture(warpvsize, "rtt.collapsev2", ECF_R8, stencil);
rtts[RTT_COLLAPSEH2] = drv->addRenderTargetTexture(warphsize, "rtt.collapseh2", ECF_R8, stencil);
rtts[RTT_HALF_SOFT] = drv->addRenderTargetTexture(half, "rtt.halfsoft", ECF_R8, stencil);
} else
{
rtts[RTT_COLLAPSE] = drv->addRenderTargetTexture(shadowsize0, "rtt.collapse", ECF_A8R8G8B8, stencil);
rtts[RTT_COLLAPSEV] = drv->addRenderTargetTexture(warpvsize, "rtt.collapsev", ECF_A8R8G8B8, stencil);
rtts[RTT_COLLAPSEH] = drv->addRenderTargetTexture(warphsize, "rtt.collapseh", ECF_A8R8G8B8, stencil);
rtts[RTT_COLLAPSEV2] = drv->addRenderTargetTexture(warpvsize, "rtt.collapsev2", ECF_A8R8G8B8, stencil);
rtts[RTT_COLLAPSEH2] = drv->addRenderTargetTexture(warphsize, "rtt.collapseh2", ECF_A8R8G8B8, stencil);
rtts[RTT_HALF_SOFT] = drv->addRenderTargetTexture(half, "rtt.halfsoft", ECF_A8R8G8B8, stencil);
glGenFramebuffers(1, &shadowFBO);
glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO);
glGenTextures(1, &shadowColorTex);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowColorTex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8, 1024, 1024, 4, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
glGenTextures(1, &shadowDepthTex);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowDepthTex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, 1024, 1024, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, shadowColorTex, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowDepthTex, 0);
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(result == GL_FRAMEBUFFER_COMPLETE_EXT);
}
u32 i;
for (i = 0; i < RTT_COUNT; i++)
{
if (!rtts[i])
Log::fatal("RTT", "Failed to create a RTT");
}
// Clear those that should be cleared
drv->beginScene(false, false);
drv->setRenderTarget(rtts[RTT_SSAO], true, false, SColor(255, 255, 255, 255));
drv->setRenderTarget(rtts[RTT_COLLAPSEV], true, false);
drv->setRenderTarget(rtts[RTT_COLLAPSEH], true, false);
drv->setRenderTarget(rtts[RTT_COLLAPSEV2], true, false);
drv->setRenderTarget(rtts[RTT_COLLAPSEH2], true, false);
drv->setRenderTarget(0, false, false);
drv->endScene();
if (irr_driver->getGLSLVersion() < 150)
return;
glGenFramebuffers(1, &shadowFBO);
glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO);
glGenTextures(1, &shadowColorTex);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowColorTex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8, 1024, 1024, 4, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
glGenTextures(1, &shadowDepthTex);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowDepthTex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, 1024, 1024, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, shadowColorTex, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowDepthTex, 0);
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(result == GL_FRAMEBUFFER_COMPLETE_EXT);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
RTT::~RTT()
{
u32 i;
for (i = 0; i < RTT_COUNT; i++)
{
irr_driver->removeTexture(rtts[i]);
}
}
ITexture *RTT::getRTT(TypeRTT which)
{
assert(which < RTT_COUNT);
return rtts[which];
}

View File

@ -62,23 +62,48 @@ enum TypeRTT
RTT_HALF_SOFT,
RTT_DISPLACE,
RTT_FINAL_COLOR,
RTT_MLAA_COLORS,
RTT_COUNT
};
enum TypeFBO
{
FBO_SSAO,
FBO_NORMAL_AND_DEPTHS,
FBO_COMBINED_TMP1_TMP2,
FBO_COLORS,
FBO_LOG_LUMINANCE,
FBO_MLAA_COLORS,
FBO_TMP1_WITH_DS,
FBO_TMP2_WITH_DS,
FBO_TMP4,
FBO_HALF1,
FBO_HALF2,
FBO_QUARTER1,
FBO_QUARTER2,
FBO_EIGHTH1,
FBO_EIGHTH2,
FBO_DISPLACE,
FBO_COUNT
};
class RTT
{
public:
RTT();
~RTT();
ITexture *getRTT(TypeRTT which);
unsigned getShadowFBO() const { return shadowFBO; }
unsigned getShadowDepthTex() const { return shadowDepthTex; }
unsigned getDepthStencilTexture() const { return DepthStencilTexture; }
unsigned getRenderTarget(enum TypeRTT target) const { return RenderTargetTextures[target]; }
unsigned getFBO(enum TypeFBO fbo) { return FrameBuffers[fbo]; }
private:
ITexture *rtts[RTT_COUNT];
unsigned RenderTargetTextures[RTT_COUNT], FrameBuffers[FBO_COUNT];
unsigned DepthStencilTexture;
unsigned shadowFBO, shadowColorTex, shadowDepthTex;
};

View File

@ -42,9 +42,6 @@ Shaders::Shaders()
m_callbacks[ES_MIPVIZ] = new MipVizProvider();
m_callbacks[ES_COLORIZE] = new ColorizeProvider();
m_callbacks[ES_SUNLIGHT] = new SunLightProvider();
m_callbacks[ES_MLAA_COLOR1] = new MLAAColor1Provider();
m_callbacks[ES_MLAA_BLEND2] = new MLAABlend2Provider();
m_callbacks[ES_MLAA_NEIGH3] = new MLAANeigh3Provider();
m_callbacks[ES_SHADOWPASS] = new ShadowPassProvider();
m_callbacks[ES_SHADOW_IMPORTANCE] = new ShadowImportanceProvider();
m_callbacks[ES_COLLAPSE] = new CollapseProvider();
@ -167,6 +164,16 @@ static void initCubeVBO()
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * 6 * sizeof(int), indices, GL_STATIC_DRAW);
}
GLuint SharedObject::ViewProjectionMatrixesUBO;
static void initShadowVPMUBO()
{
glGenBuffers(1, &SharedObject::ViewProjectionMatrixesUBO);
glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO);
glBufferData(GL_UNIFORM_BUFFER, 16 * 4 * sizeof(float), 0, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
void Shaders::loadShaders()
{
const std::string &dir = file_manager->getAsset(FileManager::SHADER, "");
@ -229,13 +236,6 @@ void Shaders::loadShaders()
m_shaders[ES_SUNLIGHT] = glsl_noinput(dir + "pass.vert", dir + "pass.frag");
m_shaders[ES_MLAA_COLOR1] = glsl(dir + "pass.vert", dir + "pass.frag",
m_callbacks[ES_MLAA_COLOR1]);
m_shaders[ES_MLAA_BLEND2] = glsl(dir + "pass.vert", dir + "pass.frag",
m_callbacks[ES_MLAA_BLEND2]);
m_shaders[ES_MLAA_NEIGH3] = glsl(dir + "pass.vert", dir + "pass.frag",
m_callbacks[ES_MLAA_NEIGH3]);
m_shaders[ES_SHADOWPASS] = glsl(dir + "pass.vert", dir + "pass.frag",
m_callbacks[ES_SHADOWPASS]);
@ -295,6 +295,7 @@ void Shaders::loadShaders()
initQuadBuffer();
initBillboardVBO();
initCubeVBO();
initShadowVPMUBO();
FullScreenShader::BloomBlendShader::init();
FullScreenShader::BloomShader::init();
FullScreenShader::ColorLevelShader::init();
@ -395,8 +396,10 @@ namespace MeshShader
GLuint ObjectPass1Shader::Program;
GLuint ObjectPass1Shader::attrib_position;
GLuint ObjectPass1Shader::attrib_normal;
GLuint ObjectPass1Shader::attrib_texcoord;
GLuint ObjectPass1Shader::uniform_MVP;
GLuint ObjectPass1Shader::uniform_TIMV;
GLuint ObjectPass1Shader::uniform_tex;
void ObjectPass1Shader::init()
{
@ -406,14 +409,17 @@ namespace MeshShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_pass1.frag").c_str());
attrib_position = glGetAttribLocation(Program, "Position");
attrib_normal = glGetAttribLocation(Program, "Normal");
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView");
uniform_tex = glGetUniformLocation(Program, "tex");
}
void ObjectPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView)
void ObjectPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_tex)
{
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer());
glUniform1i(uniform_tex, TU_tex);
}
GLuint ObjectRefPass1Shader::Program;
@ -521,6 +527,7 @@ namespace MeshShader
GLuint InstancedObjectPass1Shader::attrib_scale;
GLuint InstancedObjectPass1Shader::uniform_MP;
GLuint InstancedObjectPass1Shader::uniform_VM;
GLuint InstancedObjectPass1Shader::uniform_tex;
void InstancedObjectPass1Shader::init()
{
@ -536,12 +543,14 @@ namespace MeshShader
attrib_normal = glGetAttribLocation(Program, "Normal");
uniform_MP = glGetUniformLocation(Program, "ViewProjectionMatrix");
uniform_VM = glGetUniformLocation(Program, "InverseViewMatrix");
uniform_tex = glGetUniformLocation(Program, "tex");
}
void InstancedObjectPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ViewMatrix)
void InstancedObjectPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ViewMatrix, unsigned TU_tex)
{
glUniformMatrix4fv(uniform_MP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
glUniformMatrix4fv(uniform_VM, 1, GL_FALSE, ViewMatrix.pointer());
glUniform1i(uniform_tex, TU_tex);
}
GLuint InstancedObjectRefPass1Shader::Program;
@ -1399,7 +1408,6 @@ namespace MeshShader
GLuint ShadowShader::Program;
GLuint ShadowShader::attrib_position;
GLuint ShadowShader::uniform_VP;
GLuint ShadowShader::uniform_MM;
void ShadowShader::init()
@ -1415,20 +1423,15 @@ namespace MeshShader
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str());
attrib_position = glGetAttribLocation(Program, "Position");
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix[0]");
uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
void ShadowShader::setUniforms(const core::matrix4 &ModelMatrix, const std::vector<core::matrix4> &ViewProjectionMatrix)
void ShadowShader::setUniforms(const core::matrix4 &ModelMatrix)
{
size_t size = ViewProjectionMatrix.size();
float *tmp = new float[16 * size];
for (unsigned i = 0; i < size; i++) {
memcpy(&tmp[16 * i], ViewProjectionMatrix[i].pointer(), 16 * sizeof(float));
}
glUniformMatrix4fv(uniform_VP, size, GL_FALSE, tmp);
glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
delete[] tmp;
}
GLuint InstancedShadowShader::Program;
@ -1436,7 +1439,6 @@ namespace MeshShader
GLuint InstancedShadowShader::attrib_origin;
GLuint InstancedShadowShader::attrib_orientation;
GLuint InstancedShadowShader::attrib_scale;
GLuint InstancedShadowShader::uniform_VP;
void InstancedShadowShader::init()
{
@ -1455,24 +1457,17 @@ namespace MeshShader
attrib_origin = glGetAttribLocation(Program, "Origin");
attrib_orientation = glGetAttribLocation(Program, "Orientation");
attrib_scale = glGetAttribLocation(Program, "Scale");
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix[0]");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
void InstancedShadowShader::setUniforms(const std::vector<core::matrix4> &ViewProjectionMatrix)
void InstancedShadowShader::setUniforms()
{
size_t size = ViewProjectionMatrix.size();
float *tmp = new float[16 * size];
for (unsigned i = 0; i < size; i++) {
memcpy(&tmp[16 * i], ViewProjectionMatrix[i].pointer(), 16 * sizeof(float));
}
glUniformMatrix4fv(uniform_VP, size, GL_FALSE, tmp);
delete[] tmp;
}
GLuint RefShadowShader::Program;
GLuint RefShadowShader::attrib_position;
GLuint RefShadowShader::attrib_texcoord;
GLuint RefShadowShader::uniform_VP;
GLuint RefShadowShader::uniform_MM;
GLuint RefShadowShader::uniform_tex;
@ -1491,22 +1486,16 @@ namespace MeshShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
attrib_position = glGetAttribLocation(Program, "Position");
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix[0]");
uniform_tex = glGetUniformLocation(Program, "tex");
uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
void RefShadowShader::setUniforms(const core::matrix4 &ModelMatrix, const std::vector<core::matrix4> &ViewProjectionMatrix, unsigned TU_tex)
void RefShadowShader::setUniforms(const core::matrix4 &ModelMatrix, unsigned TU_tex)
{
size_t size = ViewProjectionMatrix.size();
float *tmp = new float[16 * size];
for (unsigned i = 0; i < size; i++) {
memcpy(&tmp[16 * i], ViewProjectionMatrix[i].pointer(), 16 * sizeof(float));
}
glUniformMatrix4fv(uniform_VP, size, GL_FALSE, tmp);
glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
glUniform1i(uniform_tex, TU_tex);
delete[] tmp;
}
GLuint InstancedRefShadowShader::Program;
@ -1515,7 +1504,6 @@ namespace MeshShader
GLuint InstancedRefShadowShader::attrib_origin;
GLuint InstancedRefShadowShader::attrib_orientation;
GLuint InstancedRefShadowShader::attrib_scale;
GLuint InstancedRefShadowShader::uniform_VP;
GLuint InstancedRefShadowShader::uniform_tex;
void InstancedRefShadowShader::init()
@ -1537,20 +1525,14 @@ namespace MeshShader
attrib_origin = glGetAttribLocation(Program, "Origin");
attrib_orientation = glGetAttribLocation(Program, "Orientation");
attrib_scale = glGetAttribLocation(Program, "Scale");
uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix[0]");
uniform_tex = glGetUniformLocation(Program, "tex");
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
void InstancedRefShadowShader::setUniforms(const std::vector<core::matrix4> &ViewProjectionMatrix, unsigned TU_tex)
void InstancedRefShadowShader::setUniforms(unsigned TU_tex)
{
size_t size = ViewProjectionMatrix.size();
float *tmp = new float[16 * size];
for (unsigned i = 0; i < size; i++) {
memcpy(&tmp[16 * i], ViewProjectionMatrix[i].pointer(), 16 * sizeof(float));
}
glUniformMatrix4fv(uniform_VP, size, GL_FALSE, tmp);
glUniform1i(uniform_tex, TU_tex);
delete[] tmp;
}
GLuint GrassShadowShader::Program;
@ -1702,6 +1684,7 @@ namespace LightShader
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/pointlight.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getSpecular.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/pointlight.frag").c_str());
attrib_Position = glGetAttribLocation(Program, "Position");
attrib_Color = glGetAttribLocation(Program, "Color");
@ -2037,6 +2020,7 @@ namespace FullScreenShader
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getSpecular.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/sunlight.frag").c_str());
uniform_ntex = glGetUniformLocation(Program, "ntex");
uniform_dtex = glGetUniformLocation(Program, "dtex");
@ -2101,6 +2085,7 @@ namespace FullScreenShader
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getSpecular.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/sunlightshadow.frag").c_str());
uniform_ntex = glGetUniformLocation(Program, "ntex");
uniform_dtex = glGetUniformLocation(Program, "dtex");

View File

@ -30,6 +30,7 @@ class SharedObject
public:
static GLuint billboardvbo;
static GLuint cubevbo, cubeindexes;
static GLuint ViewProjectionMatrixesUBO;
};
namespace MeshShader
{
@ -37,11 +38,11 @@ class ObjectPass1Shader
{
public:
static GLuint Program;
static GLuint attrib_position, attrib_normal;
static GLuint uniform_MVP, uniform_TIMV;
static GLuint attrib_position, attrib_texcoord, attrib_normal;
static GLuint uniform_MVP, uniform_TIMV, uniform_tex;
static void init();
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView);
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_tex);
};
class ObjectRefPass1Shader
@ -82,10 +83,10 @@ class InstancedObjectPass1Shader
public:
static GLuint Program;
static GLuint attrib_position, attrib_normal, attrib_origin, attrib_orientation, attrib_scale;
static GLuint uniform_MP, uniform_VM;
static GLuint uniform_MP, uniform_VM, uniform_tex;
static void init();
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &ViewMatrix);
static void setUniforms(const core::matrix4 &ViewProjectionMatrix, const core::matrix4 &ViewMatrix, unsigned TU_tex);
};
class InstancedObjectRefPass1Shader
@ -326,10 +327,10 @@ class ShadowShader
public:
static GLuint Program;
static GLuint attrib_position;
static GLuint uniform_VP, uniform_MM;
static GLuint uniform_MM, uniform_ViewProjectionMatrixesUBO;
static void init();
static void setUniforms(const core::matrix4 &ModelMatrix, const std::vector<core::matrix4> &ViewProjectionMatrix);
static void setUniforms(const core::matrix4 &ModelMatrix);
};
class InstancedShadowShader
@ -337,10 +338,9 @@ class InstancedShadowShader
public:
static GLuint Program;
static GLuint attrib_position, attrib_origin, attrib_orientation, attrib_scale;
static GLuint uniform_VP;
static void init();
static void setUniforms(const std::vector<core::matrix4> &ViewProjectionMatrix);
static void setUniforms();
};
class RefShadowShader
@ -348,10 +348,10 @@ class RefShadowShader
public:
static GLuint Program;
static GLuint attrib_position, attrib_texcoord;
static GLuint uniform_VP, uniform_MM, uniform_tex;
static GLuint uniform_MM, uniform_tex;
static void init();
static void setUniforms(const core::matrix4 &ModelMatrix, const std::vector<core::matrix4> &ModelViewProjectionMatrix, unsigned TU_tex);
static void setUniforms(const core::matrix4 &ModelMatrix, unsigned TU_tex);
};
class InstancedRefShadowShader
@ -359,10 +359,10 @@ class InstancedRefShadowShader
public:
static GLuint Program;
static GLuint attrib_position, attrib_texcoord, attrib_origin, attrib_orientation, attrib_scale;
static GLuint uniform_VP, uniform_tex;
static GLuint uniform_tex;
static void init();
static void setUniforms(const std::vector<core::matrix4> &ModelViewProjectionMatrix, unsigned TU_tex);
static void setUniforms(unsigned TU_tex);
};
class GrassShadowShader
@ -834,9 +834,6 @@ public:
ACT(ES_OBJECTPASS_REF) \
ACT(ES_SUNLIGHT) \
ACT(ES_OBJECTPASS_RIMLIT) \
ACT(ES_MLAA_COLOR1) \
ACT(ES_MLAA_BLEND2) \
ACT(ES_MLAA_NEIGH3) \
ACT(ES_SHADOWPASS) \
ACT(ES_SHADOW_IMPORTANCE) \
ACT(ES_COLLAPSE) \

View File

@ -45,8 +45,8 @@ public:
mat.ZWriteEnable = false;
mat.MaterialType = irr_driver->getShader(ES_SHADOW_IMPORTANCE);
mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH));
mat.setTexture(2, irr_driver->getRTT(RTT_COLOR));
// mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH));
// mat.setTexture(2, irr_driver->getRTT(RTT_COLOR));
mat.setFlag(EMF_BILINEAR_FILTER, false);

View File

@ -116,8 +116,6 @@ void STKAnimatedMesh::render()
return;
}
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
if (firstTime)
{
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
@ -182,18 +180,12 @@ void STKAnimatedMesh::render()
// and solid only in solid pass
if (transparent != isTransparentPass)
continue;
if (RenderFromIdentity)
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
else if (Mesh->getMeshType() == scene::EAMT_SKINNED)
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((scene::SSkinMeshBuffer*)mb)->Transformation);
}
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
{
computeMVP(ModelViewProjectionMatrix);
computeTIMV(TransposeInverseModelView);
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
TransposeInverseModelView = computeTIMV(AbsoluteTransformation);
if (!GeometricMesh[FPSM_DEFAULT].empty())
glUseProgram(MeshShader::ObjectPass1Shader::Program);
@ -243,18 +235,18 @@ void STKAnimatedMesh::render()
if (!GeometricMesh[FPSM_DEFAULT].empty())
glUseProgram(MeshShader::ShadowShader::Program);
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++)
drawShadow(*GeometricMesh[FPSM_DEFAULT][i]);
drawShadow(*GeometricMesh[FPSM_DEFAULT][i], AbsoluteTransformation);
if (!GeometricMesh[FPSM_ALPHA_REF_TEXTURE].empty())
glUseProgram(MeshShader::RefShadowShader::Program);
for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++)
drawShadowRef(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i]);
drawShadowRef(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i], AbsoluteTransformation);
return;
}
if (irr_driver->getPhase() == TRANSPARENT_PASS)
{
computeMVP(ModelViewProjectionMatrix);
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
if (!TransparentMesh[TM_BUBBLE].empty())
glUseProgram(MeshShader::BubbleShader::Program);

View File

@ -8,8 +8,11 @@ STKInstancedSceneNode::STKInstancedSceneNode(irr::scene::IMesh* mesh, ISceneNode
const irr::core::vector3df& scale) :
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
{
createGLMeshes();
setAutomaticCulling(0);
if (irr_driver->isGLSL())
{
createGLMeshes();
setAutomaticCulling(0);
}
}
void STKInstancedSceneNode::cleanGL()
@ -39,7 +42,8 @@ void STKInstancedSceneNode::cleanGL()
STKInstancedSceneNode::~STKInstancedSceneNode()
{
cleanGL();
if (irr_driver->isGLSL())
cleanGL();
}
void STKInstancedSceneNode::createGLMeshes()
@ -77,9 +81,12 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
setInstanceAttribPointer<MeshShader::InstancedObjectPass1Shader>();
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedShadowShader>();
if (irr_driver->getGLSLVersion() >= 150)
{
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedShadowShader>();
}
break;
case FPSM_ALPHA_REF_TEXTURE:
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
@ -88,9 +95,12 @@ void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMateria
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
glBufferData(GL_ARRAY_BUFFER, instance_pos.size() * sizeof(float), instance_pos.data(), GL_STATIC_DRAW);
setInstanceAttribPointer<MeshShader::InstancedObjectRefPass1Shader>();
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedRefShadowShader::attrib_position, MeshShader::InstancedRefShadowShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedRefShadowShader>();
if (irr_driver->getGLSLVersion() >= 150)
{
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::InstancedRefShadowShader::attrib_position, MeshShader::InstancedRefShadowShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride);
glBindBuffer(GL_ARRAY_BUFFER, instances_vbo);
setInstanceAttribPointer<MeshShader::InstancedRefShadowShader>();
}
break;
case FPSM_GRASS:
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
@ -176,10 +186,8 @@ static void drawFSPMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjecti
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
core::matrix4 InverseViewMatrix;
irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW).getInverse(InverseViewMatrix);
MeshShader::InstancedObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, InverseViewMatrix);
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, irr_driver->getInvViewMatrix(), 0);
glBindVertexArray(mesh.vao_first_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
@ -192,8 +200,7 @@ static void drawShadowDefault(GLMesh &mesh, size_t instance_count)
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
std::vector<core::matrix4> ShadowMVP(irr_driver->getShadowViewProj());
MeshShader::InstancedShadowShader::setUniforms(ShadowMVP);
MeshShader::InstancedShadowShader::setUniforms();
assert(mesh.vao_shadow_pass);
glBindVertexArray(mesh.vao_shadow_pass);
@ -207,11 +214,8 @@ static void drawFSPMAlphaRefTexture(GLMesh &mesh, const core::matrix4 &ModelView
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
core::matrix4 InverseViewMatrix;
irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW).getInverse(InverseViewMatrix);
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedObjectRefPass1Shader::setUniforms(ModelViewProjectionMatrix, InverseViewMatrix, 0);
MeshShader::InstancedObjectRefPass1Shader::setUniforms(ModelViewProjectionMatrix, irr_driver->getInvViewMatrix(), 0);
glBindVertexArray(mesh.vao_first_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
@ -224,10 +228,8 @@ static void drawShadowAlphaRefTexture(GLMesh &mesh, size_t instance_count)
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
std::vector<core::matrix4> ShadowMVP(irr_driver->getShadowViewProj());
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedRefShadowShader::setUniforms(ShadowMVP, 0);
MeshShader::InstancedRefShadowShader::setUniforms(0);
assert(mesh.vao_shadow_pass);
glBindVertexArray(mesh.vao_shadow_pass);
@ -241,11 +243,8 @@ static void drawFSPMGrass(GLMesh &mesh, const core::matrix4 &ModelViewProjection
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
core::matrix4 InverseViewMatrix;
irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW).getInverse(InverseViewMatrix);
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::InstancedGrassPass1Shader::setUniforms(ModelViewProjectionMatrix, InverseViewMatrix, windDir, 0);
MeshShader::InstancedGrassPass1Shader::setUniforms(ModelViewProjectionMatrix, irr_driver->getInvViewMatrix(), windDir, 0);
glBindVertexArray(mesh.vao_first_pass);
glDrawElementsInstanced(ptype, count, itype, 0, instance_count);
@ -289,7 +288,7 @@ static void drawSMGrass(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMa
size_t count = mesh.IndexCount;
setTexture(MeshShader::InstancedGrassPass2Shader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
setTexture(MeshShader::InstancedGrassPass2Shader::TU_dtex, getDepthTexture(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST);
setTexture(MeshShader::InstancedGrassPass2Shader::TU_dtex, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST);
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
MeshShader::InstancedGrassPass2Shader::setUniforms(ModelViewProjectionMatrix, irr_driver->getInvViewMatrix(), irr_driver->getInvProjMatrix(), windDir, cb->getPosition());
@ -300,12 +299,18 @@ static void drawSMGrass(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMa
void STKInstancedSceneNode::render()
{
if (!irr_driver->isGLSL())
{
CMeshSceneNode::render();
return;
}
setFirstTimeMaterial();
if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS)
{
ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION);
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
ModelViewProjectionMatrix = irr_driver->getProjMatrix();
ModelViewProjectionMatrix *= irr_driver->getViewMatrix();
if (!GeometricMesh[FPSM_DEFAULT].empty())
glUseProgram(MeshShader::InstancedObjectPass1Shader::Program);

View File

@ -193,24 +193,25 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
}
void computeMVP(core::matrix4 &ModelViewProjectionMatrix)
core::matrix4 computeMVP(const core::matrix4 &ModelMatrix)
{
ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION);
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
core::matrix4 ModelViewProjectionMatrix = irr_driver->getProjMatrix();
ModelViewProjectionMatrix *= irr_driver->getViewMatrix();
ModelViewProjectionMatrix *= ModelMatrix;
return ModelViewProjectionMatrix;
}
void computeTIMV(core::matrix4 &TransposeInverseModelView)
core::matrix4 computeTIMV(const core::matrix4 &ModelMatrix)
{
TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
TransposeInverseModelView.makeInverse();
TransposeInverseModelView = TransposeInverseModelView.getTransposed();
core::matrix4 TransposeInverseModelView = irr_driver->getViewMatrix();
TransposeInverseModelView *= ModelMatrix;
TransposeInverseModelView.makeInverse();
TransposeInverseModelView = TransposeInverseModelView.getTransposed();
return TransposeInverseModelView;
}
core::vector3df getWind()
{
const core::vector3df pos = irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD).getTranslation();
const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f;
GrassShaderProvider *gsp = (GrassShaderProvider *)irr_driver->getCallback(ES_GRASS);
float m_speed = gsp->getSpeed(), m_amplitude = gsp->getAmplitude();
@ -225,7 +226,8 @@ void drawObjectPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjecti
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
MeshShader::ObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView);
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::ObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0);
assert(mesh.vao_first_pass);
glBindVertexArray(mesh.vao_first_pass);
@ -658,40 +660,29 @@ void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatr
glDrawElements(ptype, count, itype, 0);
}
void drawShadowRef(const GLMesh &mesh)
void drawShadowRef(const GLMesh &mesh, const core::matrix4 &ModelMatrix)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
std::vector<core::matrix4> ShadowMVP(irr_driver->getShadowViewProj());
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::RefShadowShader::setUniforms(irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD), ShadowMVP, 0);
MeshShader::RefShadowShader::setUniforms(ModelMatrix, 0);
assert(mesh.vao_shadow_pass);
glBindVertexArray(mesh.vao_shadow_pass);
glDrawElements(ptype, count, itype, 0);
}
void drawShadow(const GLMesh &mesh)
void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix)
{
irr_driver->IncreaseObjectCount();
GLenum ptype = mesh.PrimitiveType;
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
std::vector<core::matrix4> ShadowMVP(irr_driver->getShadowViewProj());
/* if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF))
{
setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
glUseProgram(MeshShader::GrassShadowShader::Program);
MeshShader::GrassShadowShader::setUniforms(ShadowMVP, windDir, 0);
}*/
MeshShader::ShadowShader::setUniforms(irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD), ShadowMVP);
MeshShader::ShadowShader::setUniforms(ModelMatrix);
assert(mesh.vao_shadow_pass);
glBindVertexArray(mesh.vao_shadow_pass);
@ -743,7 +734,7 @@ void initvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedM
{
case FPSM_DEFAULT:
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
MeshShader::ObjectPass1Shader::attrib_position, -1, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride);
MeshShader::ObjectPass1Shader::attrib_position, MeshShader::ObjectPass1Shader::attrib_texcoord, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride);
mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride);
break;
case FPSM_ALPHA_REF_TEXTURE:

View File

@ -60,8 +60,8 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb);
void initvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat);
void initvaostate(GLMesh &mesh, TransparentMaterial TranspMat);
void computeMVP(core::matrix4 &ModelViewProjectionMatrix);
void computeTIMV(core::matrix4 &TransposeInverseModelView);
core::matrix4 computeMVP(const core::matrix4 &ModelViewProjectionMatrix);
core::matrix4 computeTIMV(const core::matrix4 &TransposeInverseModelView);
bool isObject(video::E_MATERIAL_TYPE type);
core::vector3df getWind();
@ -85,8 +85,8 @@ void drawObjectRimLimit(const GLMesh &mesh, const core::matrix4 &ModelViewProjec
void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix);
// Shadow pass
void drawShadowRef(const GLMesh &mesh);
void drawShadow(const GLMesh &mesh);
void drawShadowRef(const GLMesh &mesh, const core::matrix4 &ModelMatrix);
void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix);
// Forward pass (for transparents meshes)
void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix);

View File

@ -123,7 +123,7 @@ void STKMeshSceneNode::drawGlow(const GLMesh &mesh)
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
computeMVP(ModelViewProjectionMatrix);
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
MeshShader::ColorizeShader::setUniforms(ModelViewProjectionMatrix, cb->getRed(), cb->getGreen(), cb->getBlue());
assert(mesh.vao_glow_pass);
@ -141,13 +141,13 @@ void STKMeshSceneNode::drawDisplace(const GLMesh &mesh)
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
computeMVP(ModelViewProjectionMatrix);
core::matrix4 ModelViewMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
ModelViewMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
core::matrix4 ModelViewMatrix = irr_driver->getViewMatrix();
ModelViewMatrix *= AbsoluteTransformation;
// Generate displace mask
// Use RTT_TMP4 as displace mask
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_TMP4), false, false);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_TMP4));
glUseProgram(MeshShader::DisplaceMaskShader::Program);
MeshShader::DisplaceMaskShader::setUniforms(ModelViewProjectionMatrix);
@ -159,10 +159,10 @@ void STKMeshSceneNode::drawDisplace(const GLMesh &mesh)
// Render the effect
if (!displaceTex)
displaceTex = irr_driver->getTexture(FileManager::TEXTURE, "displace.png");
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_DISPLACE), false, false);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_DISPLACE));
setTexture(0, getTextureGLuint(displaceTex), GL_LINEAR, GL_LINEAR, true);
setTexture(1, getTextureGLuint(irr_driver->getRTT(RTT_TMP4)), GL_LINEAR, GL_LINEAR, true);
setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_COLOR)), GL_LINEAR, GL_LINEAR, true);
setTexture(1, irr_driver->getRenderTargetTexture(RTT_TMP4), GL_LINEAR, GL_LINEAR, true);
setTexture(2, irr_driver->getRenderTargetTexture(RTT_COLOR), GL_LINEAR, GL_LINEAR, true);
glUseProgram(MeshShader::DisplaceShader::Program);
MeshShader::DisplaceShader::setUniforms(ModelViewProjectionMatrix, ModelViewMatrix, core::vector2df(cb->getDirX(), cb->getDirY()), core::vector2df(cb->getDir2X(), cb->getDir2Y()), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0, 1, 2);
@ -175,7 +175,7 @@ void STKMeshSceneNode::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYP
{
assert(irr_driver->getPhase() == TRANSPARENT_PASS);
computeMVP(ModelViewProjectionMatrix);
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
if (type == irr_driver->getShader(ES_BUBBLES))
drawBubble(mesh, ModelViewProjectionMatrix);
@ -318,7 +318,6 @@ void STKMeshSceneNode::render()
++PassCount;
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
Box = Mesh->getBoundingBox();
setFirstTimeMaterial();
@ -335,8 +334,8 @@ void STKMeshSceneNode::render()
{
if (reload_each_frame)
glDisable(GL_CULL_FACE);
computeMVP(ModelViewProjectionMatrix);
computeTIMV(TransposeInverseModelView);
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
TransposeInverseModelView = computeTIMV(AbsoluteTransformation);
if (!GeometricMesh[FPSM_DEFAULT].empty())
glUseProgram(MeshShader::ObjectPass1Shader::Program);
@ -431,12 +430,12 @@ void STKMeshSceneNode::render()
if (!GeometricMesh[FPSM_DEFAULT].empty())
glUseProgram(MeshShader::ShadowShader::Program);
for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++)
drawShadow(*GeometricMesh[FPSM_DEFAULT][i]);
drawShadow(*GeometricMesh[FPSM_DEFAULT][i], AbsoluteTransformation);
if (!GeometricMesh[FPSM_ALPHA_REF_TEXTURE].empty())
glUseProgram(MeshShader::RefShadowShader::Program);
for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++)
drawShadowRef(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i]);
drawShadowRef(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i], AbsoluteTransformation);
if (reload_each_frame)
glEnable(GL_CULL_FACE);
@ -457,7 +456,7 @@ void STKMeshSceneNode::render()
if (irr_driver->getPhase() == TRANSPARENT_PASS)
{
computeMVP(ModelViewProjectionMatrix);
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
if (!TransparentMesh[TM_BUBBLE].empty())
glUseProgram(MeshShader::BubbleShader::Program);

View File

@ -174,6 +174,8 @@ ModalDialog::~ModalDialog()
void ModalDialog::clearWindow()
{
assert(m_irrlicht_window != NULL);
Widget* w;
for_in (w, m_widgets)
{
@ -182,8 +184,7 @@ void ModalDialog::clearWindow()
elementsWereDeleted();
m_widgets.clearAndDeleteAll();
if(m_irrlicht_window)
m_irrlicht_window->remove();
m_irrlicht_window->remove();
m_irrlicht_window = GUIEngine::getGUIEnv()->addWindow( m_area, true /* modal */ );
} // clearWindow

View File

@ -176,7 +176,7 @@ void Powerup::use()
// The player gets an achievement point for using a powerup
StateManager::ActivePlayer * player = m_owner->getController()->getPlayer();
if (m_type != PowerupManager::POWERUP_NOTHING &&
player != NULL && player->getConstProfile() == PlayerManager::get()->getCurrentPlayer())
player != NULL && player->getConstProfile() == PlayerManager::getCurrentPlayer())
{
PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_POWERUP_LOVER, "poweruplover");
}

View File

@ -806,7 +806,7 @@ void Kart::finishedRace(float time)
m_controller));
if (m_controller->isPlayerController()) // if player is on this computer
{
PlayerProfile *player = PlayerManager::get()->getCurrentPlayer();
PlayerProfile *player = PlayerManager::getCurrentPlayer();
const ChallengeStatus *challenge = player->getCurrentChallengeStatus();
// In case of a GP challenge don't make the end animation depend
// on if the challenge is fulfilled

View File

@ -355,7 +355,7 @@ bool KartPropertiesManager::kartAvailable(int kartid)
if ( kartid == *it) return false;
}
const KartProperties *kartprop = getKartById(kartid);
if( PlayerManager::get()->getCurrentPlayer()->isLocked(kartprop->getIdent()) )
if( PlayerManager::getCurrentPlayer()->isLocked(kartprop->getIdent()) )
return false;
return true;
} // kartAvailable
@ -464,7 +464,7 @@ void KartPropertiesManager::getRandomKartList(int count,
const KartProperties &kp=m_karts_properties[karts_in_group[i]];
if (!used[karts_in_group[i]] &&
m_kart_available[karts_in_group[i]] &&
!PlayerManager::get()->getCurrentPlayer()->isLocked(kp.getIdent()) )
!PlayerManager::getCurrentPlayer()->isLocked(kp.getIdent()) )
{
random_kart_queue.push_back(kp.getIdent());
}

View File

@ -416,7 +416,7 @@ void Skidding::update(float dt, bool is_on_ground,
/*fade-out-time*/ 1.0f);
StateManager::ActivePlayer *c = m_kart->getController()->getPlayer();
if (c && c->getConstProfile() == PlayerManager::get()->getCurrentPlayer())
if (c && c->getConstProfile() == PlayerManager::getCurrentPlayer())
{
PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_SKIDDING, "skidding");
}

View File

@ -694,7 +694,7 @@ int handleCmdLine()
if(CommandLine::has("--kart", &s))
{
const PlayerProfile *player = PlayerManager::get()->getCurrentPlayer();
const PlayerProfile *player = PlayerManager::getCurrentPlayer();
if(player && !player->isLocked(s))
{
@ -766,7 +766,7 @@ int handleCmdLine()
if(CommandLine::has("--track", &s) || CommandLine::has("-t", &s))
{
const PlayerProfile *player = PlayerManager::get()->getCurrentPlayer();
const PlayerProfile *player = PlayerManager::getCurrentPlayer();
if (player && !player->isLocked(s))
{
race_manager->setTrack(s);
@ -1030,6 +1030,11 @@ void initRest()
addons_manager = new AddonsManager();
Online::ProfileManager::create();
// The request manager will start the login process in case of a saved
// session, so we need to read the main data from the players.xml file.
// The rest will be read later (since the rest needs the unlock- and
// achievement managers to be created, which can only be created later).
PlayerManager::create();
Online::RequestManager::get()->startNetworkThread();
NewsManager::get(); // this will create the news manager
@ -1165,13 +1170,15 @@ int main(int argc, char *argv[] )
handleXmasMode();
// Needs the kart and track directories to load potential challenges
// in those dirs.
// in those dirs, so it can only be created after reading tracks
// and karts.
unlock_manager = new UnlockManager();
AchievementsManager::create();
// Needs the unlock manager to initialise the game slots of all players
// and the AchievementsManager to initialise the AchievementsStatus.
PlayerManager::create();
// Reading the rest of the player data needs the unlock manager to
// initialise the game slots of all players and the AchievementsManager
// to initialise the AchievementsStatus, so it is done only now.
PlayerManager::get()->loadRemainingData();
GUIEngine::addLoadingIcon( irr_driver->getTexture(FileManager::GUI,
"gui_lock.png" ) );

View File

@ -380,7 +380,7 @@ void CutsceneWorld::enterRaceOverState()
else if (race_manager->getTrackName() == "introcutscene" ||
race_manager->getTrackName() == "introcutscene2")
{
PlayerProfile *player = PlayerManager::get()->getCurrentPlayer();
PlayerProfile *player = PlayerManager::getCurrentPlayer();
if (player->isFirstTime())
{
race_manager->exitRace();

View File

@ -240,7 +240,7 @@ void LinearWorld::newLap(unsigned int kart_index)
// Reset reset-after-lap achievements
StateManager::ActivePlayer *c = kart->getController()->getPlayer();
PlayerProfile *p = PlayerManager::get()->getCurrentPlayer();
PlayerProfile *p = PlayerManager::getCurrentPlayer();
if (c && c->getConstProfile() == p)
{
p->getAchievementsStatus()->onLapEnd();

View File

@ -66,7 +66,7 @@ void OverWorld::enterOverWorld()
InputDevice* device = input_manager->getDeviceList()->getKeyboard(0);
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(PlayerManager::get()->getCurrentPlayer(),
StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
device, NULL);
if (!kart_properties_manager->getKart(UserConfigParams::m_default_kart))

View File

@ -469,7 +469,7 @@ void World::terminateRace()
{
// Retrieve the current player
StateManager::ActivePlayer* p = m_karts[i]->getController()->getPlayer();
if (p && p->getConstProfile() == PlayerManager::get()->getCurrentPlayer())
if (p && p->getConstProfile() == PlayerManager::getCurrentPlayer())
{
// Check if the player has won
if (m_karts[i]->getPosition() == winner_position && kart_amount > opponents )
@ -494,7 +494,7 @@ void World::terminateRace()
{
// Retrieve the current player
StateManager::ActivePlayer* p = m_karts[i]->getController()->getPlayer();
if (p && p->getConstProfile() == PlayerManager::get()->getCurrentPlayer())
if (p && p->getConstProfile() == PlayerManager::getCurrentPlayer())
{
// Check if the player has won
if (m_karts[i]->getPosition() == 1 )
@ -511,7 +511,7 @@ void World::terminateRace()
}
}
}
PlayerManager::get()->getCurrentPlayer()->raceFinished();
PlayerManager::getCurrentPlayer()->raceFinished();
if (m_race_gui) m_race_gui->clearAllMessages();
// we can't delete the race gui here, since it is needed in case of
@ -815,7 +815,7 @@ void World::updateWorld(float dt)
InputDevice* device = input_manager->getDeviceList()->getKeyboard(0);
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(PlayerManager::get()->getCurrentPlayer(),
StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
device, NULL);
if (!kart_properties_manager->getKart(UserConfigParams::m_default_kart))

View File

@ -19,38 +19,63 @@
#include "network/protocols/request_connection.hpp"
#include "network/protocol_manager.hpp"
#include "online/request_manager.hpp"
#include "online/servers_manager.hpp"
#include "online/current_user.hpp"
#include "config/user_config.hpp"
RequestConnection::RequestConnection(uint32_t server_id) : Protocol(NULL, PROTOCOL_SILENT)
using namespace Online;
/** Constructor. Stores the server id.
* \param server_id Id of the server.
*/
RequestConnection::RequestConnection(uint32_t server_id)
: Protocol(NULL, PROTOCOL_SILENT)
{
m_server_id = server_id;
}
} // RequestConnection
// ----------------------------------------------------------------------------
RequestConnection::~RequestConnection()
{
}
} // ~RequestConnection
// ----------------------------------------------------------------------------
/** Setup of this request, sets state to none.
*/
void RequestConnection::setup()
{
m_state = NONE;
}
} // setup
// ----------------------------------------------------------------------------
/** The callback for the server join request. It informs the server manager
* of a successful join request.
*/
void RequestConnection::ServerJoinRequest::callback()
{
if (isSuccess())
{
uint32_t server_id;
getXMLData()->get("serverid", &server_id);
ServersManager::get()->setJoinedServer(server_id);
}
} // ServerJoinRequest::callback
// ----------------------------------------------------------------------------
/** This implements a finite state machine to monitor the server join
* request asynchronously.
*/
void RequestConnection::asynchronousUpdate()
{
switch (m_state)
{
case NONE:
{
m_request = new Online::CurrentUser::ServerJoinRequest();
m_request = new ServerJoinRequest();
CurrentUser::setUserDetails(m_request, "request-connection");
m_request->setServerURL("address-management.php");
m_request->addParameter("id",Online::CurrentUser::get()->getID());
m_request->addParameter("token",Online::CurrentUser::get()->getToken());
m_request->addParameter("server_id",m_server_id);
m_request->addParameter("action","request-connection");
Online::RequestManager::get()->addRequest(m_request);
m_request->queue();
m_state = REQUEST_PENDING;
break;
}
@ -65,11 +90,14 @@ void RequestConnection::asynchronousUpdate()
{
if (rec_success == "yes")
{
Log::debug("RequestConnection", "Connection Request made successfully.");
Log::debug("RequestConnection",
"Connection Request made successfully.");
}
else
{
Log::error("RequestConnection", "Fail to make a request to connecto to server %d", m_server_id);
Log::error("RequestConnection",
"Fail to make a request to connecto to server %d",
m_server_id);
}
}
else
@ -89,5 +117,5 @@ void RequestConnection::asynchronousUpdate()
case EXITING:
break;
}
}
} // asynchronousUpdate

View File

@ -1,33 +1,52 @@
#ifndef REQUEST_CONNECTION_HPP
#define REQUEST_CONNECTION_HPP
#ifndef HEADER_REQUEST_CONNECTION_HPP
#define HEADER_REQUEST_CONNECTION_HPP
#include "network/protocol.hpp"
#include "online/current_user.hpp"
#include "online/xml_request.hpp"
class RequestConnection : public Protocol
{
protected:
/** Id of the server to join. */
uint32_t m_server_id;
/** The request to join a server. */
Online::XMLRequest *m_request;
enum STATE
{
NONE,
REQUEST_PENDING,
DONE,
EXITING
};
/** State of this connection. */
STATE m_state;
public:
// --------------------------------------------------------------------
/** A simple request class to ask to join a server.
*/
class ServerJoinRequest : public Online::XMLRequest
{
virtual void callback();
public:
RequestConnection(uint32_t server_id);
virtual ~RequestConnection();
ServerJoinRequest() : Online::XMLRequest() {}
}; // ServerJoinRequest
// --------------------------------------------------------------------
virtual bool notifyEvent(Event* event) { return true; }
virtual bool notifyEventAsynchronous(Event* event) { return true; }
virtual void setup();
virtual void update() {}
virtual void asynchronousUpdate();
protected:
uint32_t m_server_id;
Online::CurrentUser::ServerJoinRequest* m_request;
enum STATE
{
NONE,
REQUEST_PENDING,
DONE,
EXITING
};
STATE m_state;
RequestConnection(uint32_t server_id);
virtual ~RequestConnection();
};
virtual bool notifyEvent(Event* event) { return true; }
virtual bool notifyEventAsynchronous(Event* event) { return true; }
virtual void setup();
virtual void update() {}
virtual void asynchronousUpdate();
}; // RequestConnection
#endif // REQUEST_CONNECTION_HPP

View File

@ -115,7 +115,7 @@ void StartGameProtocol::update()
rki.setGlobalPlayerId(profile->race_id);
rki.setLocalPlayerId(is_me?0:1);
rki.setHostId(profile->race_id);
PlayerProfile* profile_to_use = PlayerManager::get()->getCurrentPlayer();
PlayerProfile* profile_to_use = PlayerManager::getCurrentPlayer();
assert(profile_to_use);
InputDevice* device = input_manager->getDeviceList()->getLatestUsedDevice();
int new_player_id = 0;

View File

@ -20,8 +20,6 @@
#include "online/current_user.hpp"
#include "achievements/achievements_manager.hpp"
#include "addons/addon.hpp"
#include "addons/addons_manager.hpp"
#include "config/player_manager.hpp"
#include "config/user_config.hpp"
#include "guiengine/dialog_queue.hpp"
@ -68,15 +66,20 @@ namespace Online
* to allow for shorter request creation code. It sets the name of
* the script to invokce, token, and user id.
* \param request The http request.
* \param action If not empty, the action to be set.
*/
void CurrentUser::setUserDetails(HTTPRequest *request)
void CurrentUser::setUserDetails(HTTPRequest *request,
const std::string &action)
{
CurrentUser *cu = CurrentUser::get();
assert(cu && cu->m_state == US_SIGNED_IN);
assert(cu->m_profile);
request->setServerURL("client-user.php");
request->addParameter("token", cu->m_token);
request->addParameter("userid", cu->m_profile->getID());
if (cu && cu->m_profile)
request->addParameter("userid", cu->m_profile->getID());
if(cu->m_state == US_SIGNED_IN)
request->addParameter("token", cu->m_token);
if (action.size() > 0)
request->addParameter("action", action);
} // setUserDetails
// ========================================================================
@ -94,14 +97,14 @@ namespace Online
void CurrentUser::requestSavedSession()
{
SignInRequest * request = NULL;
if(m_state == US_SIGNED_OUT && UserConfigParams::m_saved_session)
const PlayerProfile *cp = PlayerManager::getCurrentPlayer();
if (m_state == US_SIGNED_OUT && cp->hasSavedSession() )
{
request = new SignInRequest(true);
request->setServerURL("client-user.php");
request->addParameter("action","saved-session");
request->addParameter("userid", UserConfigParams::m_saved_user);
request->addParameter("token",
UserConfigParams::m_saved_token.c_str());
request->addParameter("userid", cp->getSavedUserId());
request->addParameter("token", cp->getSavedToken());
request->queue();
m_state = US_SIGNING_IN;
}
@ -176,9 +179,8 @@ namespace Online
m_state = US_SIGNED_IN;
if(saveSession())
{
UserConfigParams::m_saved_user = getID();
UserConfigParams::m_saved_token = getToken();
UserConfigParams::m_saved_session = true;
PlayerManager::getCurrentPlayer()->saveSession(getID(),
getToken() );
}
ProfileManager::get()->addPersistent(m_profile);
std::string achieved_string("");
@ -228,195 +230,9 @@ namespace Online
ProfileManager::get()->clearPersistent();
m_profile = NULL;
m_state = US_SIGNED_OUT;
UserConfigParams::m_saved_user = 0;
UserConfigParams::m_saved_token = "";
UserConfigParams::m_saved_session = false;
PlayerManager::getCurrentPlayer()->clearSession();
} // signOut
// ------------------------------------------------------------------------
CurrentUser::ServerJoinRequest*
CurrentUser::requestServerJoin(uint32_t server_id,
bool request_now)
{
assert(m_state == US_SIGNED_IN || m_state == US_GUEST);
ServerJoinRequest * request = new ServerJoinRequest();
request->setServerURL("address-management.php");
request->addParameter("action","request-connection");
request->addParameter("token", getToken());
request->addParameter("id", getID());
request->addParameter("server_id", server_id);
if (request_now)
request->queue();
return request;
} // requestServerJoin
// ------------------------------------------------------------------------
void CurrentUser::ServerJoinRequest::callback()
{
if(isSuccess())
{
uint32_t server_id;
getXMLData()->get("serverid", &server_id);
ServersManager::get()->setJoinedServer(server_id);
}
//FIXME needs changes for actual valid joining
} // ServerJoinRequest::callback
// ------------------------------------------------------------------------
const XMLRequest*
CurrentUser::requestGetAddonVote(const std::string & addon_id) const
{
assert(m_state == US_SIGNED_IN);
XMLRequest * request = new XMLRequest();
request->setServerURL("client-user.php");
request->addParameter("action", "get-addon-vote");
request->addParameter("token", getToken());
request->addParameter("userid", getID());
request->addParameter("addonid", addon_id.substr(6));
request->queue();
return request;
} // requestGetAddonVote
// ------------------------------------------------------------------------
/** A request to the server, to perform a vote on an addon.
* \param addon_id the id of the addon to vote for.
* \param rating the voted rating.
*/
const CurrentUser::SetAddonVoteRequest*
CurrentUser::requestSetAddonVote(const std::string & addon_id,
float rating) const
{
assert(m_state == US_SIGNED_IN);
CurrentUser::SetAddonVoteRequest * request =
new CurrentUser::SetAddonVoteRequest();
request->setServerURL("client-user.php");
request->addParameter("action", "set-addon-vote");
request->addParameter("token", getToken());
request->addParameter("userid", getID());
request->addParameter("addonid", addon_id.substr(6));
request->addParameter("rating", rating);
request->queue();
return request;
} // requestSetAddonVote
// ------------------------------------------------------------------------
/** Callback for the request to vote for an addon. Updates the local
* average rating.
*/
void CurrentUser::SetAddonVoteRequest::callback()
{
if(isSuccess())
{
std::string addon_id;
getXMLData()->get("addon-id", &addon_id);
float average;
getXMLData()->get("new-average", &average);
addons_manager->getAddon(Addon::createAddonId(addon_id))
->setRating(average);
}
} // SetAddonVoteRequest::callback
// ------------------------------------------------------------------------
/** A request to the server, to fetch matching results for the supplied
* search term.
* \param search_string the string to search for.
*/
XMLRequest*
CurrentUser::requestUserSearch(const core::stringw &search_string) const
{
assert(m_state == US_SIGNED_IN);
XMLRequest * request = new XMLRequest();
request->setServerURL("client-user.php");
request->addParameter("action", "user-search");
request->addParameter("token", getToken());
request->addParameter("userid", getID());
request->addParameter("search-string", search_string);
request->queue();
return request;
} // requestUserSearch
// ------------------------------------------------------------------------
void CurrentUser::requestCancelFriend(const uint32_t friend_id) const
{
assert(m_state == US_SIGNED_IN);
CurrentUser::CancelFriendRequest * request =
new CurrentUser::CancelFriendRequest();
request->setServerURL("client-user.php");
request->addParameter("action", "cancel-friend-request");
request->addParameter("token", getToken());
request->addParameter("userid", getID());
request->addParameter("friendid", friend_id);
request->queue();
} // requestCancelFriend
// ------------------------------------------------------------------------
/** Callback for the request to cancel a friend invitation. Shows a
* confirmation message and takes care of updating all the cached
* information.
*/
void CurrentUser::CancelFriendRequest::callback()
{
uint32_t id(0);
getXMLData()->get("friendid", &id);
core::stringw info_text("");
if(isSuccess())
{
CurrentUser::get()->getProfile()->removeFriend(id);
ProfileManager::get()->moveToCache(id);
ProfileManager::get()->getProfileByID(id)->deleteRelationalInfo();
OnlineProfileFriends::getInstance()->refreshFriendsList();
info_text = _("Friend request cancelled!");
}
else
info_text = getInfo();
UserInfoDialog *dia = new UserInfoDialog(id, info_text,!isSuccess(),
true);
GUIEngine::DialogQueue::get()->pushDialog(dia, true);
} // CancelFriendRequest::callback
// ------------------------------------------------------------------------
/** A request to the server, to change the password of the signed in user.
* \param current_password The active password of the currently signed in
* user.
* \param new_password The password the user wants to change to.
* \param new_password_ver Confirmation of that password. Has to be the
* exact same.
*/
void CurrentUser::requestPasswordChange(const core::stringw &current_password,
const core::stringw &new_password,
const core::stringw &new_password_ver) const
{
assert(m_state == US_SIGNED_IN);
ChangePasswordRequest * request = new ChangePasswordRequest();
request->setServerURL("client-user.php");
request->addParameter("action", "change_password");
request->addParameter("userid", getID());
request->addParameter("current", current_password);
request->addParameter("new1", new_password);
request->addParameter("new2", new_password_ver);
request->queue();
} // requestPasswordChange
// ------------------------------------------------------------------------
/** Callback for the change password request. If the matching dialog is
* still open, show a confirmation message.
*/
void CurrentUser::ChangePasswordRequest::callback()
{
if(GUIEngine::ModalDialog::isADialogActive())
{
ChangePasswordDialog * dialog =
dynamic_cast<ChangePasswordDialog*>(GUIEngine::ModalDialog
::getCurrent());
if(dialog != NULL)
{
if(isSuccess())
dialog->success();
else
dialog->error(getInfo());
}
}
} // ChangePasswordRequest::callback
// ------------------------------------------------------------------------
/** Sends a request to the server to see if any new information is
* available. (online friends, notifications, etc.).
@ -586,25 +402,6 @@ namespace Online
}
}
// ------------------------------------------------------------------------
/** Sends a confirmation to the server that an achievement has been
* completed, if a user is signed in.
* \param achievement_id the id of the achievement that got completed.
*/
void CurrentUser::onAchieving(uint32_t achievement_id) const
{
if(isRegisteredUser())
{
HTTPRequest * request = new HTTPRequest(true);
request->setServerURL("client-user.php");
request->addParameter("action", "achieving");
request->addParameter("token", getToken());
request->addParameter("userid", getID());
request->addParameter("achievementid", achievement_id);
request->queue();
}
} // onAchieving
// ------------------------------------------------------------------------
/** \return the username if signed in. */
core::stringw CurrentUser::getUserName() const

View File

@ -72,28 +72,6 @@ namespace Online
SignOutRequest() : XMLRequest(true,/*priority*/10) {}
}; // SignOutRequest
// ----------------------------------------------------------------
class ServerJoinRequest : public XMLRequest {
virtual void callback ();
public:
ServerJoinRequest() : XMLRequest() {}
}; // ServerJoinRequest
// ----------------------------------------------------------------
class SetAddonVoteRequest : public XMLRequest {
virtual void callback ();
public:
SetAddonVoteRequest() : XMLRequest() {}
}; // SetAddonVoteRequest
// ----------------------------------------------------------------
class CancelFriendRequest : public XMLRequest {
virtual void callback ();
public:
CancelFriendRequest() : XMLRequest(true) {}
}; // CancelFriendRequest
// ----------------------------------------------------------------
class PollRequest : public XMLRequest {
virtual void callback ();
@ -101,15 +79,6 @@ namespace Online
PollRequest() : XMLRequest(true) {}
}; // PollRequest
// ----------------------------------------------------------------
class ChangePasswordRequest : public XMLRequest
{
virtual void callback ();
public:
ChangePasswordRequest() : XMLRequest(true) {}
}; // ChangePasswordRequest
private:
std::string m_token;
bool m_save_session;
@ -127,7 +96,8 @@ namespace Online
/**Singleton */
static CurrentUser * get();
static void deallocate();
static void setUserDetails(HTTPRequest *request);
static void setUserDetails(HTTPRequest *request,
const std::string &action);
void requestSavedSession();
SignInRequest * requestSignIn( const irr::core::stringw &username,
@ -135,20 +105,9 @@ namespace Online
bool save_session,
bool request_now = true);
void requestSignOut();
ServerJoinRequest * requestServerJoin(uint32_t server_id, bool request_now = true);
const XMLRequest * requestGetAddonVote(const std::string & addon_id) const;
const SetAddonVoteRequest * requestSetAddonVote(const std::string & addon_id, float rating) const;
void requestFriendRequest(const uint32_t friend_id) const;
void requestCancelFriend(const uint32_t friend_id) const;
void requestPasswordChange( const irr::core::stringw &current_password,
const irr::core::stringw &new_password,
const irr::core::stringw &new_password_ver) const;
XMLRequest * requestUserSearch(const irr::core::stringw & search_string) const;
void onSTKQuit() const;
void onAchieving(uint32_t achievement_id) const;
void requestPoll() const;
irr::core::stringw getUserName() const;

View File

@ -201,21 +201,26 @@ namespace Online
{
// Avoid printing the password or token, just replace them with *s
std::string param = m_parameters;
for (unsigned int j = 0; j < 2; j++)
// List of strings whose values should not be printed. "" is the
// end indicator.
static std::string dont_print[] = { "&password=", "&token=", "&current=",
"&new1=", "&new2=", ""};
unsigned int j = 0;
while (dont_print[j].size()>0)
{
// Get the string that should be replaced.
std::string s = (j == 0 ? "&password=" : "&token=");
std::size_t pos = param.find(s);
std::size_t pos = param.find(dont_print[j]);
if (pos != std::string::npos)
{
pos += s.size();
pos += dont_print[j].size();
while (pos < param.size() && param[pos] != '&')
{
param[pos] = '*';
pos++;
} // while not end
} // if string found
} // for j < 2
j++;
} // while dont_print[j].size()>0
Log::info("HTTPRequest", "Sending %s to %s",
param.c_str(), m_url.c_str());
}

View File

@ -46,12 +46,6 @@ namespace Online
}
// ------------------------------------------------------------------------
irr::core::stringw signedInAs(const irr::core::stringw & name)
{
return irr::core::stringw(_("Signed in as : ")) + name + ".";
}
// ------------------------------------------------------------------------
irr::core::stringw joiningServer()
{
return irr::core::stringw(_("Joining server")) + loadingDots();
@ -94,13 +88,12 @@ namespace Online
// ------------------------------------------------------------------------
/**
* Shows a increasing number of dots.
* \param spaces Flag if unshowed dots should be replaced by spaces
* \param interval A float representing the time it takes to add a new dot
* \param max_dots The number of dots used. Defaults to 3.
*/
irr::core::stringw loadingDots(bool spaces, float interval, int max_dots)
irr::core::stringw loadingDots(float interval, int max_dots)
{
int nr_dots = int(floor(StkTime::getRealTime() * (1 / interval))) % (max_dots+1);
int nr_dots = int(floor(StkTime::getRealTime() / interval)) % (max_dots+1);
return irr::core::stringw((std::string(nr_dots,'.') + std::string(max_dots-nr_dots,' ')).c_str());
}
} // namespace messages

View File

@ -30,7 +30,7 @@ namespace Online
*/
namespace Messages
{
irr::core::stringw loadingDots (bool spaces = true, float interval = 0.5f, int max_dots = 3);
irr::core::stringw loadingDots (float interval = 0.5f, int max_dots = 3);
irr::core::stringw signingIn ();
irr::core::stringw signingOut ();
irr::core::stringw validatingInfo ();
@ -41,7 +41,6 @@ namespace Online
irr::core::stringw fetchingFriends ();
irr::core::stringw fetchingAchievements ();
irr::core::stringw processing ();
irr::core::stringw signedInAs (const irr::core::stringw & name);
} // namespace Messages
}// namespace Online
#endif

View File

@ -154,8 +154,7 @@ void OnlineProfile::fetchAchievements()
// ------------------------------------------------------------------------
AchievementsRequest * request = new AchievementsRequest();
CurrentUser::setUserDetails(request);
request->addParameter("action", "get-achievements");
CurrentUser::setUserDetails(request, "get-achievements");
request->addParameter("visitingid", m_id);
RequestManager::get()->addRequest(request);
} // fetchAchievements
@ -207,8 +206,7 @@ void OnlineProfile::fetchFriends()
// ------------------------------------------------------------------------
FriendsListRequest * request = new FriendsListRequest();
CurrentUser::setUserDetails(request);
request->addParameter("action", "get-friends-list");
CurrentUser::setUserDetails(request, "get-friends-list");
request->addParameter("visitingid", m_id);
RequestManager::get()->addRequest(request);
} // fetchFriends

View File

@ -102,6 +102,9 @@ namespace Online
* variable has not been assigned at that stage, and the thread might
* use network_http - a very subtle race condition. So the thread can
* only be started after the assignment (in main) has been done.
* \pre PlayerManager was created and has read the main data for each
* player so that all data for automatic login is
* availale.
*/
void RequestManager::startNetworkThread()
{

View File

@ -271,7 +271,7 @@ void Physics::update(float dt)
// to the kart, and it's the current player. At this stage
// only the current player can get achievements.
if (target_kart != kart && c &&
c->getPlayer()->getConstProfile() == PlayerManager::get()->getCurrentPlayer())
c->getPlayer()->getConstProfile() == PlayerManager::getCurrentPlayer())
{
PlayerManager::increaseAchievement(AchievementInfo::ACHIEVE_ARCH_ENEMY,
target_kart->getIdent(), 1);

View File

@ -223,7 +223,7 @@ bool GrandPrixData::checkConsistency(bool chatty) const
bool GrandPrixData::isTrackAvailable(const std::string &id) const
{
return id!="fortmagma" ||
!PlayerManager::get()->getCurrentPlayer()->isLocked("fortmagma");
!PlayerManager::getCurrentPlayer()->isLocked("fortmagma");
} // isTrackAvailable
// ----------------------------------------------------------------------------

View File

@ -632,7 +632,7 @@ void RaceManager::exitRace(bool delete_world)
// were finished, and not when a race is aborted.
if (m_major_mode==MAJOR_MODE_GRAND_PRIX && m_track_number==(int)m_tracks.size())
{
PlayerManager::get()->getCurrentPlayer()->grandPrixFinished();
PlayerManager::getCurrentPlayer()->grandPrixFinished();
if(m_major_mode==MAJOR_MODE_GRAND_PRIX&& !NetworkWorld::getInstance()->isRunning())
{
//Delete saved GP

View File

@ -236,7 +236,7 @@ void ArenasScreen::buildTrackList()
if(!curr->isArena()) continue;
}
if (PlayerManager::get()->getCurrentPlayer()->isLocked(curr->getIdent()))
if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
{
w->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", curr->getScreenshotFile(), LOCKED_BADGE );
@ -266,7 +266,7 @@ void ArenasScreen::buildTrackList()
if(!curr->isArena()) continue;
}
if (PlayerManager::get()->getCurrentPlayer()->isLocked(curr->getIdent()))
if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
{
w->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", curr->getScreenshotFile(), LOCKED_BADGE );

View File

@ -138,8 +138,7 @@ void CreateServerScreen::serverCreationRequest()
{
m_server_creation_request = new ServerCreationRequest();
CurrentUser::setUserDetails(m_server_creation_request);
m_server_creation_request->addParameter("action", "create_server");
CurrentUser::setUserDetails(m_server_creation_request,"create_server");
m_server_creation_request->addParameter("name", name);
m_server_creation_request->addParameter("max_players", max_players);
m_server_creation_request->queue();

View File

@ -46,8 +46,6 @@ using namespace irr::gui;
AddonsLoading::AddonsLoading(const std::string &id)
: ModalDialog(0.8f, 0.8f)
{
m_vote_clicked = false;
m_addon = *(addons_manager->getAddon(id));
m_icon_shown = false;
m_download_request = NULL;
@ -255,18 +253,18 @@ GUIEngine::EventPropagation AddonsLoading::processEvent(const std::string& event
void AddonsLoading::voteClicked()
{
if (Online::CurrentUser::get()->isRegisteredUser())
new VoteDialog(m_addon.getId());
{
// We need to keep a copy of the addon id, since dismiss() will
// delete this object (and the copy of the addon).
std::string addon_id = m_addon.getId();
dismiss();
new VoteDialog(addon_id);
}
} // voteClicked
// ----------------------------------------------------------------------------
void AddonsLoading::onUpdate(float delta)
{
if(m_vote_clicked)
{
voteClicked();
return;
}
if(m_progress->isVisible())
{
float progress = m_download_request->getProgress();

View File

@ -55,8 +55,6 @@ private:
* to the progress of a download. */
Online::HTTPRequest *m_download_request;
bool m_vote_clicked;
public:
AddonsLoading(const std::string &addon_name);

View File

@ -33,10 +33,12 @@ using namespace irr::core;
using namespace irr::gui;
using namespace Online;
// -----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
ChangePasswordDialog::ChangePasswordDialog() :
ModalDialog(0.8f,0.7f)
/** Creates a modal dialog with given percentage of screen width and height
*/
ChangePasswordDialog::ChangePasswordDialog()
: ModalDialog(0.8f,0.7f)
{
m_self_destroy = false;
m_success = false;
@ -65,15 +67,60 @@ ChangePasswordDialog::ChangePasswordDialog() :
assert(m_submit_widget != NULL);
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
assert(m_cancel_widget != NULL);
}
} // ChangePasswordDialog
// -----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
ChangePasswordDialog::~ChangePasswordDialog()
{
}
} // ~ChangePasswordDialog
// -----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
/** Create and submit the request to the server to change the password.
* \param current_password The current password.
* \param new_password The new password.
*/
void ChangePasswordDialog::changePassword(const stringw &current_password,
const stringw &new_password )
{
// ----------------------------------------------------------------
class ChangePasswordRequest : public XMLRequest
{
/** Callback for the change password request. If the matching dialog is
* still open, show a confirmation message. */
virtual void callback()
{
if (!GUIEngine::ModalDialog::isADialogActive()) return;
ChangePasswordDialog * dialog =
dynamic_cast<ChangePasswordDialog*>(GUIEngine::ModalDialog
::getCurrent());
if (dialog)
{
if (isSuccess())
dialog->success();
else
dialog->error(getInfo());
} // if dialog
} // callback
public:
ChangePasswordRequest() : XMLRequest(true) {}
}; // ChangePasswordRequest
// ------------------------------------------------------------------------
ChangePasswordRequest * request = new ChangePasswordRequest();
CurrentUser::setUserDetails(request, "change_password");
request->addParameter("userid", CurrentUser::get()->getID());
request->addParameter("current", current_password);
// The server code expects two passwords (and verifies again that they
// are identical), so send the passwod twice.
request->addParameter("new1", new_password);
request->addParameter("new2", new_password);
request->queue();
} // changePassword
// ----------------------------------------------------------------------------
void ChangePasswordDialog::submit()
{
const stringw current_password = m_current_password_widget->getText().trim();
@ -89,7 +136,8 @@ void ChangePasswordDialog::submit()
{
sfx_manager->quickSound("anvil");
m_info_widget->setErrorColor();
m_info_widget->setText(_("Password has to be between 8 and 30 characters long!"), false);
m_info_widget->setText(_("Password has to be between 8 and 30 "
"characters long!"), false);
}
else if (new_password1 != new_password2)
{
@ -101,17 +149,21 @@ void ChangePasswordDialog::submit()
{
m_options_widget->setDeactivated();
m_info_widget->setDefaultColor();
Online::CurrentUser::get()->requestPasswordChange(current_password, new_password1, new_password2);
// We don't need to use password 2 anymore, it was already confirmed
// that both passwords are identical.
changePassword(current_password, new_password1);
}
}
} // submit
// -----------------------------------------------------------------------------
GUIEngine::EventPropagation ChangePasswordDialog::processEvent(const std::string& eventSource)
// ----------------------------------------------------------------------------
GUIEngine::EventPropagation
ChangePasswordDialog::processEvent(const std::string& eventSource)
{
if (eventSource == m_options_widget->m_properties[PROP_ID])
{
const std::string& selection = m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
const std::string& selection =
m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (selection == m_cancel_widget->m_properties[PROP_ID])
{
m_self_destroy = true;
@ -124,9 +176,9 @@ GUIEngine::EventPropagation ChangePasswordDialog::processEvent(const std::string
}
}
return GUIEngine::EVENT_LET;
}
} // processEvent
// -----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void ChangePasswordDialog::onEnterPressedInternal()
{
@ -135,18 +187,18 @@ void ChangePasswordDialog::onEnterPressedInternal()
return;
if (m_submit_widget->isActivated())
submit();
}
} // onEnterPressedInternal
// -----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
bool ChangePasswordDialog::onEscapePressed()
{
if (m_cancel_widget->isActivated())
m_self_destroy = true;
return false;
}
} // onEscapePressed
// -----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void ChangePasswordDialog::success()
{
m_info_widget->setDefaultColor();
@ -155,9 +207,9 @@ void ChangePasswordDialog::success()
m_current_password_widget->setText("");
m_new_password1_widget->setText("");
m_new_password2_widget->setText("");
}
} // success
// -----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void ChangePasswordDialog::error(const irr::core::stringw & error)
{
sfx_manager->quickSound("anvil");
@ -167,7 +219,7 @@ void ChangePasswordDialog::error(const irr::core::stringw & error)
m_current_password_widget->setText("");
m_new_password1_widget->setText("");
m_new_password2_widget->setText("");
}
} // error
// -----------------------------------------------------------------------------
@ -181,4 +233,4 @@ void ChangePasswordDialog::onUpdate(float dt)
{
ModalDialog::dismiss();
}
}
} // onUpdate

View File

@ -19,13 +19,13 @@
#ifndef HEADER_CHANGE_PASSWORD_DIALOG_HPP
#define HEADER_CHANGE_PASSWORD_DIALOG_HPP
#include <irrString.h>
#include "online/current_user.hpp"
#include "guiengine/modaldialog.hpp"
#include "guiengine/widgets.hpp"
#include <irrString.h>
/**
* \brief Dialog that allows a user to sign in
* \ingroup states_screens
@ -35,9 +35,6 @@ class ChangePasswordDialog : public GUIEngine::ModalDialog
public:
/**
* Creates a modal dialog with given percentage of screen width and height
*/
ChangePasswordDialog();
~ChangePasswordDialog();
@ -49,6 +46,8 @@ public:
virtual void onUpdate(float dt);
void success();
void error(const irr::core::stringw & error_message);
void changePassword(const irr::core::stringw &current_password,
const irr::core::stringw &new_password);
private:

View File

@ -221,7 +221,7 @@ void GPInfoDialog::onEnterPressedInternal()
std::string gp_id = m_gp_ident;
ModalDialog::dismiss();
// Disable accidentally unlocking of a challenge
PlayerManager::get()->getCurrentPlayer()->setCurrentChallenge("");
PlayerManager::getCurrentPlayer()->setCurrentChallenge("");
race_manager->startGP(grand_prix_manager->getGrandPrix(gp_id), false, false);
}

View File

@ -34,12 +34,11 @@ using namespace Online;
// -----------------------------------------------------------------------------
NotificationDialog::NotificationDialog(Type type, const core::stringw info, bool from_queue)
NotificationDialog::NotificationDialog(Type type, const core::stringw info)
: ModalDialog(0.8f,0.5f)
{
m_info = info;
m_type = type;
if(!from_queue) load();
}
void NotificationDialog::load()

View File

@ -53,7 +53,7 @@ private:
GUIEngine::IconButtonWidget * m_cancel_widget;
public:
NotificationDialog(Type type, const core::stringw info, bool from_queue = true);
NotificationDialog(Type type, const core::stringw info);
~NotificationDialog();
virtual void beforeAddingWidgets();

View File

@ -39,29 +39,38 @@ using namespace irr::gui;
using namespace irr::core;
// -----------------------------------------------------------------------------
PlayerInfoDialog::PlayerInfoDialog(PlayerProfile* player, const float w, const float h) : ModalDialog(w, h)
/** Creates a modal dialog with given percentage of screen width and height.
*/
PlayerInfoDialog::PlayerInfoDialog(PlayerProfile* player, const float w,
const float h)
: ModalDialog(w, h)
{
m_player = player;
doInit();
showRegularDialog();
}
} // PlayerInfoDialog
// -----------------------------------------------------------------------------
/** When the dialog is finished, select the just edited player again in the
* option screen.
*/
PlayerInfoDialog::~PlayerInfoDialog()
{
if (m_player != NULL)
{
OptionsScreenPlayers::getInstance()->selectPlayer( translations->fribidize(m_player->getName()) );
OptionsScreenPlayers::getInstance()->selectPlayer(
translations->fribidize(m_player->getName()) );
}
}
} // ~PlayerInfoDialog
// -----------------------------------------------------------------------------
/** Show the current data of this player.
*/
void PlayerInfoDialog::showRegularDialog()
{
clearWindow();
if (m_irrlicht_window)
clearWindow();
const int y1 = m_area.getHeight()/6;
const int y2 = m_area.getHeight()*2/6;
@ -92,7 +101,8 @@ void PlayerInfoDialog::showRegularDialog()
//I18N: In the player info dialog
widget->setText( _("Rename") );
const int textWidth = font->getDimension( widget->getText().c_str() ).Width + 40;
const int textWidth =
font->getDimension( widget->getText().c_str() ).Width + 40;
widget->m_x = m_area.getWidth()/2 - textWidth/2;
widget->m_y = y2;
@ -139,10 +149,11 @@ void PlayerInfoDialog::showRegularDialog()
}
textCtrl->setFocusForPlayer( PLAYER_ID_GAME_MASTER );
}
} // showRegularDialog
// -----------------------------------------------------------------------------
/** Changes this dialog to confirm the changes.
*/
void PlayerInfoDialog::showConfirmDialog()
{
clearWindow();
@ -156,9 +167,10 @@ void PlayerInfoDialog::showConfirmDialog()
_("Do you really want to delete player '%s' ?", m_player->getName());
if (PlayerManager::get()->getCurrentPlayer() == m_player)
if (PlayerManager::getCurrentPlayer() == m_player)
{
message = _("You cannot delete this player because it is currently in use.");
message = _("You cannot delete this player "
"because it is currently in use.");
}
core::rect< s32 > area_left(5, 0, m_area.getWidth()-5, m_area.getHeight()/2);
@ -167,11 +179,12 @@ void PlayerInfoDialog::showConfirmDialog()
// we can add irrlicht labels directly
// (more complicated uses require the use of our widget set)
IGUIStaticText* a = GUIEngine::getGUIEnv()->addStaticText( message.c_str(),
area_left, false /* border */, true /* word wrap */,
area_left, false /* border */,
true /* word wrap */,
m_irrlicht_window);
a->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
if (PlayerManager::get()->getCurrentPlayer() != m_player)
if (PlayerManager::getCurrentPlayer() != m_player)
{
ButtonWidget* widget = new ButtonWidget();
widget->m_properties[PROP_ID] = "confirmremove";
@ -212,22 +225,23 @@ void PlayerInfoDialog::showConfirmDialog()
widget->setFocusForPlayer( PLAYER_ID_GAME_MASTER );
}
}
} // showConfirmDialog
// -----------------------------------------------------------------------------
void PlayerInfoDialog::onEnterPressedInternal()
{
}
} // onEnterPressedInternal
// -----------------------------------------------------------------------------
GUIEngine::EventPropagation PlayerInfoDialog::processEvent(const std::string& eventSource)
GUIEngine::EventPropagation
PlayerInfoDialog::processEvent(const std::string& eventSource)
{
if (eventSource == "renameplayer")
{
// accept entered name
stringw playerName = textCtrl->getText().trim();
stringw player_name = textCtrl->getText().trim();
const int player_amount = PlayerManager::get()->getNumPlayers();
for(int n=0; n<player_amount; n++)
@ -235,7 +249,7 @@ GUIEngine::EventPropagation PlayerInfoDialog::processEvent(const std::string& ev
const PlayerProfile *player = PlayerManager::get()->getPlayer(n);
if (player == m_player) continue;
if (player->getName() == playerName)
if (player->getName() == player_name)
{
ButtonWidget* label = getWidget<ButtonWidget>("renameplayer");
label->setBadge(BAD_BADGE);
@ -244,9 +258,9 @@ GUIEngine::EventPropagation PlayerInfoDialog::processEvent(const std::string& ev
}
}
if (playerName.size() <= 0) return GUIEngine::EVENT_BLOCK;
if (player_name.size() <= 0) return GUIEngine::EVENT_BLOCK;
OptionsScreenPlayers::getInstance()->renamePlayer( playerName, m_player );
OptionsScreenPlayers::getInstance()->renamePlayer(player_name,m_player);
// irrLicht is too stupid to remove focus from deleted widgets
// so do it by hand
@ -292,7 +306,7 @@ GUIEngine::EventPropagation PlayerInfoDialog::processEvent(const std::string& ev
return GUIEngine::EVENT_BLOCK;
}
return GUIEngine::EVENT_LET;
}
} // processEvent
// -----------------------------------------------------------------------------

View File

@ -40,9 +40,6 @@ class PlayerInfoDialog : public GUIEngine::ModalDialog
void showRegularDialog();
void showConfirmDialog();
public:
/**
* Creates a modal dialog with given percentage of screen width and height
*/
PlayerInfoDialog(PlayerProfile* PlayerInfoDialog,
const float percentWidth, const float percentHeight);

View File

@ -57,7 +57,8 @@ RecoveryDialog::~RecoveryDialog()
void RecoveryDialog::showRecoveryInput()
{
m_show_recovery_input = false;
clearWindow();
if (m_irrlicht_window)
clearWindow();
m_phase = Input;
loadFromFile("online/recovery_input.stkgui");
@ -125,10 +126,10 @@ void RecoveryDialog::processInput()
m_info_widget->setDefaultColor();
m_options_widget->setDeactivated();
m_recovery_request = new XMLRequest();
m_recovery_request->setServerURL("client-user.php");
m_recovery_request->addParameter("action", "recovery");
// This function also works when the current user is not logged in
CurrentUser::setUserDetails(m_recovery_request, "recovery");
m_recovery_request->addParameter("username", username);
m_recovery_request->addParameter("email", email);
m_recovery_request->addParameter("email", email );
m_recovery_request->queue();
}
} // processInput

View File

@ -38,7 +38,7 @@ public:
Info = 2,
};
RecoveryDialog();
~RecoveryDialog();
virtual ~RecoveryDialog();
void onEnterPressedInternal();
GUIEngine::EventPropagation processEvent(const std::string& eventSource);

View File

@ -95,7 +95,7 @@ SelectChallengeDialog::SelectChallengeDialog(const float percentWidth,
break;
}
const ChallengeStatus* c = PlayerManager::get()->getCurrentPlayer()
const ChallengeStatus* c = PlayerManager::getCurrentPlayer()
->getChallengeStatus(challenge_id);
if (c->isSolved(RaceManager::DIFFICULTY_EASY))
@ -173,7 +173,7 @@ GUIEngine::EventPropagation SelectChallengeDialog::processEvent(const std::strin
return GUIEngine::EVENT_LET;
}
PlayerManager::get()->getCurrentPlayer()->setCurrentChallenge(m_challenge_id);
PlayerManager::getCurrentPlayer()->setCurrentChallenge(m_challenge_id);
ModalDialog::dismiss();

View File

@ -17,22 +17,20 @@
#include "states_screens/dialogs/server_info_dialog.hpp"
#include <IGUIEnvironment.h>
#include "audio/sfx_manager.hpp"
#include "guiengine/engine.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/translation.hpp"
#include "utils/string_utils.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/connect_to_server.hpp"
#include "online/current_user.hpp"
#include "online/servers_manager.hpp"
#include "online/messages.hpp"
#include "online/servers_manager.hpp"
#include "states_screens/dialogs/registration_dialog.hpp"
#include "states_screens/networking_lobby.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include <IGUIEnvironment.h>
using namespace GUIEngine;
using namespace irr;
@ -80,6 +78,7 @@ ServerInfoDialog::~ServerInfoDialog()
// -----------------------------------------------------------------------------
void ServerInfoDialog::requestJoin()
{
// FIXME - without this next line, it appears that m_server_join is completely unused.
//m_server_join_request = Online::CurrentUser::get()->requestServerJoin(m_server_id);
Online::ServersManager::get()->setJoinedServer(m_server_id);
ProtocolManager::getInstance()->requestStart(new ConnectToServer(m_server_id, m_host_id));

View File

@ -25,8 +25,9 @@
#include "guiengine/widgets/icon_button_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "online/server.hpp"
#include "network/protocols/request_connection.hpp"
#include "online/current_user.hpp"
#include "online/server.hpp"
#include "utils/types.hpp"
@ -42,7 +43,7 @@ private:
bool m_self_destroy;
bool m_enter_lobby;
bool m_from_server_creation;
const Online::CurrentUser::ServerJoinRequest * m_server_join_request;
const RequestConnection::ServerJoinRequest * m_server_join_request;
const uint32_t m_server_id;
uint32_t m_host_id;

View File

@ -252,7 +252,7 @@ void TrackInfoDialog::onEnterPressedInternal()
race_manager->setReverseTrack(reverse_track);
std::string track_ident = m_track_ident;
// Disable accidentally unlocking of a challenge
PlayerManager::get()->getCurrentPlayer()->setCurrentChallenge("");
PlayerManager::getCurrentPlayer()->setCurrentChallenge("");
ModalDialog::dismiss();
race_manager->startSingleRace(track_ident, num_laps, false);

View File

@ -169,8 +169,7 @@ void UserInfoDialog::sendFriendRequest()
// ------------------------------------------------------------------------
FriendRequest *request = new FriendRequest();
CurrentUser::setUserDetails(request);
request->addParameter("action", "friend-request");
CurrentUser::setUserDetails(request, "friend-request");
request->addParameter("friendid", m_profile->getID());
request->queue();
@ -221,8 +220,7 @@ void UserInfoDialog::acceptFriendRequest()
// ------------------------------------------------------------------------
AcceptFriendRequest *request = new AcceptFriendRequest();
CurrentUser::setUserDetails(request);
request->addParameter("action", "accept-friend-request");
CurrentUser::setUserDetails(request, "accept-friend-request");
request->addParameter("friendid", m_profile->getID());
request->queue();
m_processing = true;
@ -268,8 +266,7 @@ void UserInfoDialog::declineFriendRequest()
}; // DeclineFriendRequest
// ----------------------------------------------------------------
DeclineFriendRequest *request = new DeclineFriendRequest();
CurrentUser::setUserDetails(request);
request->addParameter("action", "decline-friend-request");
CurrentUser::setUserDetails(request, "decline-friend-request");
request->addParameter("friendid", m_profile->getID());
request->queue();
@ -316,8 +313,7 @@ void UserInfoDialog::removeExistingFriend()
int friend_id = m_profile->getID();
RemoveFriendRequest * request = new RemoveFriendRequest(friend_id);
CurrentUser::get()->setUserDetails(request);
request->addParameter("action", "remove-friend");
CurrentUser::setUserDetails(request, "remove-friend");
request->addParameter("friendid", friend_id);
request->queue();
} // removeExistingFriend
@ -327,8 +323,43 @@ void UserInfoDialog::removeExistingFriend()
*/
void UserInfoDialog::removePendingFriend()
{
CurrentUser::get()->requestCancelFriend(m_profile->getID());
class CancelFriendRequest : public XMLRequest
{
// ------------------------------------------------------------------------
/** Callback for the request to cancel a friend invitation. Shows a
* confirmation message and takes care of updating all the cached
* information.
*/
virtual void callback()
{
uint32_t id(0);
getXMLData()->get("friendid", &id);
core::stringw info_text("");
if (isSuccess())
{
CurrentUser::get()->getProfile()->removeFriend(id);
ProfileManager *pm = ProfileManager::get();
pm->moveToCache(id);
pm->getProfileByID(id)->deleteRelationalInfo();
OnlineProfileFriends::getInstance()->refreshFriendsList();
info_text = _("Friend request cancelled!");
}
else
info_text = getInfo();
UserInfoDialog *dia = new UserInfoDialog(id, info_text,
!isSuccess(), true);
GUIEngine::DialogQueue::get()->pushDialog(dia, true);
} // callback
public:
CancelFriendRequest() : XMLRequest(true) {}
}; // CancelFriendRequest
// ------------------------------------------------------------------------
CancelFriendRequest * request = new CancelFriendRequest();
CurrentUser::setUserDetails(request, "cancel-friend-request");
request->addParameter("friendid", m_profile->getID());
request->queue();
} // removePendingFriend
// -----------------------------------------------------------------------------

View File

@ -17,8 +17,7 @@
#include "states_screens/dialogs/vote_dialog.hpp"
#include <IGUIEnvironment.h>
#include "addons/addons_manager.hpp"
#include "audio/sfx_manager.hpp"
#include "guiengine/engine.hpp"
#include "states_screens/state_manager.hpp"
@ -27,6 +26,7 @@
#include "online/current_user.hpp"
#include "online/messages.hpp"
#include <IGUIEnvironment.h>
using namespace GUIEngine;
@ -35,13 +35,14 @@ using namespace irr::gui;
using namespace Online;
// -----------------------------------------------------------------------------
/** Constructor.
*/
VoteDialog::VoteDialog(const std::string & addon_id)
: ModalDialog(0.8f,0.6f), m_addon_id(addon_id)
: ModalDialog(0.8f,0.6f), m_addon_id(addon_id)
{
m_fetch_vote_request = NULL;
m_fetch_vote_request = NULL;
m_perform_vote_request = NULL;
m_self_destroy = false;
m_self_destroy = false;
loadFromFile("online/vote_dialog.stkgui");
m_info_widget = getWidget<LabelWidget>("info");
@ -57,43 +58,94 @@ VoteDialog::VoteDialog(const std::string & addon_id)
assert(m_cancel_widget != NULL);
m_options_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
m_fetch_vote_request = CurrentUser::get()->requestGetAddonVote(m_addon_id);
m_fetch_vote_request = new XMLRequest();
CurrentUser::setUserDetails(m_fetch_vote_request, "get-addon-vote");
m_fetch_vote_request->addParameter("addonid", addon_id.substr(6));
m_fetch_vote_request->queue();
m_rating_widget->setDeactivated();
m_cancel_widget->setDeactivated();
}
} // VoteDialog
// -----------------------------------------------------------------------------
/** Destructor, frees the various requests.
*/
VoteDialog::~VoteDialog()
{
delete m_fetch_vote_request;
delete m_perform_vote_request;
}
} // ~VoteDialog
// -----------------------------------------------------------------------------
/** When escape is pressed, trigger a self destroy.
*/
bool VoteDialog::onEscapePressed()
{
if (m_cancel_widget->isActivated())
m_self_destroy = true;
return false;
}
} // onEscapePressed
// ----------------------------------------------------------------------------
/** A request to the server, to perform a vote on an addon.
* \param rating the voted rating.
*/
void VoteDialog::sendVote()
{
/** A vote request. The callback will update the addon manager with the
* new average. The VoteDialog polls this request till it is finished
* to inform the user about the new average.
*/
class SetAddonVoteRequest : public XMLRequest
{
virtual void callback()
{
if (isSuccess())
{
std::string addon_id;
getXMLData()->get("addon-id", &addon_id);
float average;
getXMLData()->get("new-average", &average);
addons_manager->getAddon(Addon::createAddonId(addon_id))
->setRating(average);
} // isSuccess
} // callbac
public:
SetAddonVoteRequest() : XMLRequest() {}
}; // SetAddonVoteRequest
// ------------------------------------------------------------------------
m_perform_vote_request = new SetAddonVoteRequest();
CurrentUser::setUserDetails(m_perform_vote_request, "set-addon-vote");
m_perform_vote_request->addParameter("addonid", m_addon_id.substr(6));
m_perform_vote_request->addParameter("rating", m_rating_widget->getRating());
m_perform_vote_request->queue();
m_rating_widget->setDeactivated();
m_cancel_widget->setDeactivated();
} // sendVote
// -----------------------------------------------------------------------------
GUIEngine::EventPropagation VoteDialog::processEvent(const std::string& eventSource)
/** Callback when a user event is triggered.
* \param event Information about the event that was triggered.
*/
GUIEngine::EventPropagation VoteDialog::processEvent(const std::string& event)
{
if (eventSource == m_rating_widget->m_properties[PROP_ID])
if (event == m_rating_widget->m_properties[PROP_ID])
{
m_perform_vote_request = CurrentUser::get()->requestSetAddonVote(m_addon_id, m_rating_widget->getRating());
m_rating_widget->setDeactivated();
m_cancel_widget->setDeactivated();
sendVote();
return GUIEngine::EVENT_BLOCK;
}
if (eventSource == m_options_widget->m_properties[PROP_ID])
if (event == m_options_widget->m_properties[PROP_ID])
{
const std::string& selection = m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
const std::string& selection =
m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (selection == m_cancel_widget->m_properties[PROP_ID])
{
m_self_destroy = true;
@ -101,50 +153,66 @@ GUIEngine::EventPropagation VoteDialog::processEvent(const std::string& eventSou
}
}
return GUIEngine::EVENT_LET;
}
} // processEvent
// -----------------------------------------------------------------------------
/** Updates a potentiall still outstanding fetch vote request.
*/
void VoteDialog::updateFetchVote()
{
// No request, nothing to do
if (!m_fetch_vote_request) return;
if (!m_fetch_vote_request->isDone())
{
// request still pending
m_info_widget->setText(irr::core::stringw(_("Fetching last vote"))
+ Messages::loadingDots(), false);
return;
} // !isDone
if (m_fetch_vote_request->isSuccess())
{
m_info_widget->setDefaultColor();
std::string voted("");
m_fetch_vote_request->getXMLData()->get("voted", &voted);
if (voted == "yes")
{
float rating;
m_fetch_vote_request->getXMLData()->get("rating", &rating);
m_rating_widget->setRating(rating);
m_info_widget->setText(_("You can adapt your previous rating by "
"clicking the stars beneath."), false);
}
else if (voted == "no")
{
m_info_widget->setText(_("You have not yet voted for this addon. "
"Select your desired rating by clicking "
"the stars beneath"), false);
}
m_cancel_widget->setActivated();
m_rating_widget->setActivated();
} // isSuccess
else
{
sfx_manager->quickSound("anvil");
m_info_widget->setErrorColor();
m_info_widget->setText(m_fetch_vote_request->getInfo(), false);
m_cancel_widget->setActivated();
} // !isSuccess
delete m_fetch_vote_request;
m_fetch_vote_request = NULL;
} // updateFetchVote
// -----------------------------------------------------------------------------
/** Called every frame. Checks if any of the pending requests are finished.
* \param dt Time step size.
*/
void VoteDialog::onUpdate(float dt)
{
if(m_fetch_vote_request != NULL)
{
if(m_fetch_vote_request->isDone())
{
if(m_fetch_vote_request->isSuccess())
{
m_info_widget->setDefaultColor();
std::string voted("");
m_fetch_vote_request->getXMLData()->get("voted", &voted);
if(voted == "yes")
{
float rating;
m_fetch_vote_request->getXMLData()->get("rating", &rating);
m_rating_widget->setRating(rating);
m_info_widget->setText(_("You can adapt your previous rating by clicking the stars beneath."), false);
}
else if(voted == "no")
{
m_info_widget->setText(_("You have not yet voted for this addon. Select your desired rating by clicking the stars beneath"), false);
}
m_cancel_widget->setActivated();
m_rating_widget->setActivated();
}
else
{
sfx_manager->quickSound( "anvil" );
m_info_widget->setErrorColor();
m_info_widget->setText(m_fetch_vote_request->getInfo(), false);
m_cancel_widget->setActivated();
}
delete m_fetch_vote_request;
m_fetch_vote_request = NULL;
}
else
{
m_info_widget->setText(irr::core::stringw(_("Fetching last vote")) + Messages::loadingDots(), false);
}
}
updateFetchVote();
if(m_perform_vote_request != NULL)
{
if(m_perform_vote_request->isDone())
@ -152,9 +220,10 @@ void VoteDialog::onUpdate(float dt)
if(m_perform_vote_request->isSuccess())
{
m_info_widget->setDefaultColor();
m_info_widget->setText(_("Vote successful! You can now close the window."), false);
m_info_widget->setText(_("Vote successful! You can now close "
"the window."), false);
m_cancel_widget->setActivated();
}
} // isSuccess
else
{
sfx_manager->quickSound( "anvil" );
@ -162,15 +231,18 @@ void VoteDialog::onUpdate(float dt)
m_info_widget->setText(m_perform_vote_request->getInfo(), false);
m_cancel_widget->setActivated();
m_rating_widget->setActivated();
}
} // !isSuccess
delete m_perform_vote_request;
m_perform_vote_request = NULL;
}
} // isDone
else
{
m_info_widget->setText(irr::core::stringw(_("Performing vote")) + Messages::loadingDots(), false);
}
m_info_widget->setText(irr::core::stringw(_("Performing vote"))
+ Messages::loadingDots(), false);
} // !isDone
}
if (m_self_destroy)
ModalDialog::dismiss();
}
} // onUpdate

View File

@ -32,24 +32,40 @@
class VoteDialog : public GUIEngine::ModalDialog
{
private:
/** Stores the id of the addon being voted on. */
const std::string m_addon_id;
bool m_self_destroy;
const Online::XMLRequest * m_fetch_vote_request;
const Online::CurrentUser::SetAddonVoteRequest * m_perform_vote_request;
/** True if the dialog should be removed (which needs to be done
* in the update call each frame). */
bool m_self_destroy;
/** The request to fetch the current vote, which is submitted
* immediately when this dialog is opened. */
Online::XMLRequest * m_fetch_vote_request;
/** The request to perform a vote. */
Online::XMLRequest* m_perform_vote_request;
/** Pointer to the info widget of this dialog. */
GUIEngine::LabelWidget * m_info_widget;
/** Pointer to the rating widget of this dialog */
GUIEngine::RatingBarWidget * m_rating_widget;
/** Pointer to the options widget, which contains the canel button. */
GUIEngine::RibbonWidget * m_options_widget;
/** Pointer to the cancel button. */
GUIEngine::IconButtonWidget * m_cancel_widget;
void updateFetchVote();
void sendVote();
public:
VoteDialog(const std::string & addon_id);
~VoteDialog();
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
virtual void onUpdate(float dt);
virtual bool onEscapePressed();
};
}; // VoteDialog
#endif

View File

@ -236,7 +236,7 @@ void EasterEggScreen::buildTrackList()
if (curr->isArena() || curr->isSoccer()) continue;
if (curr->isInternal()) continue;
if (PlayerManager::get()->getCurrentPlayer()->isLocked(curr->getIdent()))
if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
{
tracks_widget->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", curr->getScreenshotFile(), LOCKED_BADGE,
@ -267,7 +267,7 @@ void EasterEggScreen::buildTrackList()
if (curr->isSoccer()) continue;
if (curr->isInternal()) continue;
if (PlayerManager::get()->getCurrentPlayer()->isLocked(curr->getIdent()))
if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
{
tracks_widget->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", curr->getScreenshotFile(), LOCKED_BADGE,

View File

@ -144,7 +144,7 @@ void FeatureUnlockedCutScene::loadedFromFile()
void FeatureUnlockedCutScene::findWhatWasUnlocked(RaceManager::Difficulty difficulty)
{
PlayerProfile *player = PlayerManager::get()->getCurrentPlayer();
PlayerProfile *player = PlayerManager::getCurrentPlayer();
int points_before = player->getPoints();
int points_now = points_before + CHALLENGE_POINTS[difficulty];
@ -410,7 +410,7 @@ void FeatureUnlockedCutScene::tearDown()
m_all_kart_models.clearAndDeleteAll();
// update point count and the list of locked/unlocked stuff
PlayerManager::get()->getCurrentPlayer()->computeActive();
PlayerManager::getCurrentPlayer()->computeActive();
} // tearDown
// ----------------------------------------------------------------------------

View File

@ -278,7 +278,7 @@ void GrandPrixLose::eventCallback(GUIEngine::Widget* widget,
race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE);
std::vector<const ChallengeData*> unlocked =
PlayerManager::get()->getCurrentPlayer()->getRecentlyCompletedChallenges();
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
if (unlocked.size() > 0)
{
@ -289,7 +289,7 @@ void GrandPrixLose::eventCallback(GUIEngine::Widget* widget,
scene->findWhatWasUnlocked(race_manager->getDifficulty());
StateManager::get()->replaceTopMostScreen(scene);
PlayerManager::get()->getCurrentPlayer()->clearUnlocked();
PlayerManager::getCurrentPlayer()->clearUnlocked();
}
else
{

View File

@ -98,7 +98,7 @@ void GrandPrixWin::loadedFromFile()
void GrandPrixWin::init()
{
Screen::init();
if (PlayerManager::get()->getCurrentPlayer()->getRecentlyCompletedChallenges().size() > 0)
if (PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges().size() > 0)
{
const core::dimension2d<u32>& frame_size = GUIEngine::getDriver()->getCurrentRenderTargetSize();
@ -406,12 +406,12 @@ void GrandPrixWin::eventCallback(GUIEngine::Widget* widget,
// un-set the GP mode so that after unlocking, it doesn't try to continue the GP
race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE);
if (PlayerManager::get()->getCurrentPlayer()
->getRecentlyCompletedChallenges().size() > 0)
if (PlayerManager::getCurrentPlayer()
->getRecentlyCompletedChallenges().size() > 0)
{
std::vector<const ChallengeData*> unlocked =
PlayerManager::get()->getCurrentPlayer()->getRecentlyCompletedChallenges();
PlayerManager::get()->getCurrentPlayer()->clearUnlocked();
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
PlayerManager::getCurrentPlayer()->clearUnlocked();
FeatureUnlockedCutScene* scene =
FeatureUnlockedCutScene::getInstance();

View File

@ -66,7 +66,7 @@ void HelpScreen1::eventCallback(Widget* widget, const std::string& name, const i
InputDevice* device = input_manager->getDeviceList()->getKeyboard(0);
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(PlayerManager::get()->getCurrentPlayer(),
StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
device, NULL);
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)

View File

@ -1104,7 +1104,7 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
kartsAreaWidget->m_y + kartsAreaWidget->m_h);
// ---- Create new active player
PlayerProfile* profile_to_use = PlayerManager::get()->getCurrentPlayer();
PlayerProfile* profile_to_use = PlayerManager::getCurrentPlayer();
if (!firstPlayer)
{
@ -2013,7 +2013,7 @@ void KartSelectionScreen::setKartsFromCurrentGroup()
{
const KartProperties* prop =
kart_properties_manager->getKartById(n);
if (PlayerManager::get()->getCurrentPlayer()->isLocked(prop->getIdent()))
if (PlayerManager::getCurrentPlayer()->isLocked(prop->getIdent()))
{
w->addItem(
_("Locked : solve active challenges to gain access "
@ -2045,7 +2045,7 @@ void KartSelectionScreen::setKartsFromCurrentGroup()
kart_properties_manager->getKartById(group[n]);
const std::string &icon_path = prop->getAbsoluteIconFile();
if (PlayerManager::get()->getCurrentPlayer()->isLocked(prop->getIdent()))
if (PlayerManager::getCurrentPlayer()->isLocked(prop->getIdent()))
{
w->addItem(
_("Locked : solve active challenges to gain access "

View File

@ -341,7 +341,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
InputDevice* device = input_manager->getDeviceList()->getKeyboard(0);
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(PlayerManager::get()->getCurrentPlayer(),
StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
device, NULL);
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
@ -364,7 +364,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
}
else if (selection == "story")
{
PlayerProfile *player = PlayerManager::get()->getCurrentPlayer();
PlayerProfile *player = PlayerManager::getCurrentPlayer();
if (player->isFirstTime())
{
StateManager::get()->enterGameState();

View File

@ -97,7 +97,7 @@ void OnlineProfileAchievements::init()
m_waiting_for_achievements = false;
m_achievements_list_widget->clear();
const std::map<uint32_t, Achievement *> & all_achievements =
PlayerManager::get()->getCurrentPlayer()->getAchievementsStatus()
PlayerManager::getCurrentPlayer()->getAchievementsStatus()
->getAllAchievements();
std::map<uint32_t, Achievement *>::const_iterator it;
for (it = all_achievements.begin(); it != all_achievements.end(); ++it)

View File

@ -29,24 +29,21 @@
#include "input/input_manager.hpp"
#include "io/file_manager.hpp"
#include "main_loop.hpp"
#include "modes/demo_world.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/connect_to_server.hpp"
#include "network/protocols/request_connection.hpp"
#include "online/messages.hpp"
#include "online/profile_manager.hpp"
#include "online/request.hpp"
#include "online/servers_manager.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "states_screens/networking_lobby.hpp"
#include "states_screens/server_selection.hpp"
#include "states_screens/create_server_screen.hpp"
#include "states_screens/online_profile_overview.hpp"
#include "online/servers_manager.hpp"
#include "online/messages.hpp"
#include "online/profile_manager.hpp"
#include "online/request.hpp"
#include "modes/demo_world.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/connect_to_server.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/connect_to_server.hpp"
using namespace GUIEngine;
using namespace Online;
@ -95,6 +92,8 @@ void OnlineScreen::loadedFromFile()
} // loadedFromFile
// ----------------------------------------------------------------------------
/** Checks if the recorded state differs from the actual state and sets it.
*/
bool OnlineScreen::hasStateChanged()
{
CurrentUser::UserState previous_state = m_recorded_state;
@ -102,7 +101,7 @@ bool OnlineScreen::hasStateChanged()
if (previous_state != m_recorded_state)
return true;
return false;
}
} // hasStateChanged
// ----------------------------------------------------------------------------
void OnlineScreen::beforeAddingWidget()
@ -130,15 +129,14 @@ void OnlineScreen::beforeAddingWidget()
} // beforeAddingWidget
// ----------------------------------------------------------------------------
void OnlineScreen::init()
{
Screen::init();
setInitialFocus();
DemoWorld::resetIdleTime();
m_online_status_widget->setText(Messages::signedInAs(CurrentUser::get()->getUserName()), false);
core::stringw m = _("Signed in as: %s.",CurrentUser::get()->getUserName());
m_online_status_widget->setText(m, false);
} // init
// ----------------------------------------------------------------------------
@ -161,8 +159,57 @@ void OnlineScreen::onUpdate(float delta)
} // onUpdate
// ----------------------------------------------------------------------------
/** Executes the quick play selection. Atm this is all blocking.
*/
void OnlineScreen::doQuickPlay()
{
// Refresh server list.
HTTPRequest* request = ServersManager::get()->refreshRequest(false);
if (request != NULL) // consider request done
{
request->executeNow();
delete request;
}
else
{
Log::error("OnlineScreen", "Could not get the server list.");
return;
}
// select first one
const Server * server = ServersManager::get()->getQuickPlay();
void OnlineScreen::eventCallback(Widget* widget, const std::string& name, const int playerID)
XMLRequest *request2 = new RequestConnection::ServerJoinRequest();
if (!request2)
{
sfx_manager->quickSound("anvil");
return;
}
CurrentUser::setUserDetails(request2, "request-connection");
request2->setServerURL("address-management.php");
request2->addParameter("server_id", server->getServerId());
request2->executeNow();
if (request2->isSuccess())
{
delete request2;
StateManager::get()->pushScreen(NetworkingLobby::getInstance());
ConnectToServer *cts = new ConnectToServer(server->getServerId(),
server->getHostId());
ProtocolManager::getInstance()->requestStart(cts);
}
else
{
sfx_manager->quickSound("anvil");
}
} // doQuickPlay
// ----------------------------------------------------------------------------
void OnlineScreen::eventCallback(Widget* widget, const std::string& name,
const int playerID)
{
if (name == m_back_widget->m_properties[PROP_ID])
{
@ -194,41 +241,7 @@ void OnlineScreen::eventCallback(Widget* widget, const std::string& name, const
}
else if (selection == m_quick_play_widget->m_properties[PROP_ID])
{
//FIXME temporary and the request join + join sequence should be placed in one method somewhere
// refresh server list
Online::ServersManager::RefreshRequest* request = ServersManager::get()->refreshRequest(false);
if (request != NULL) // consider request done
{
request->executeNow();
delete request;
}
else
{
Log::error("OnlineScreen", "Could not get the server list.");
return;
}
// select first one
const Server * server = ServersManager::get()->getQuickPlay();
Online::CurrentUser::ServerJoinRequest* request2 = Online::CurrentUser::get()->requestServerJoin( server->getServerId(), false);
if (request2)
{
request2->executeNow();
if (request2->isSuccess())
{
delete request2;
StateManager::get()->pushScreen(NetworkingLobby::getInstance());
ProtocolManager::getInstance()->requestStart(new ConnectToServer(server->getServerId(), server->getHostId()));
}
else
{
sfx_manager->quickSound( "anvil" );
}
}
else
{
sfx_manager->quickSound( "anvil" );
}
doQuickPlay();
}
} // eventCallback
@ -239,6 +252,8 @@ void OnlineScreen::tearDown()
}
// ----------------------------------------------------------------------------
/** Sets which widget has to be focused. Depends on the user state.
*/
void OnlineScreen::setInitialFocus()
{
if(m_recorded_state == CurrentUser::US_SIGNED_IN)

View File

@ -56,11 +56,10 @@ private:
Online::CurrentUser::UserState m_recorded_state;
/** \brief Checks if the recorded state differs from the actual state and sets it. */
bool hasStateChanged();
/** \brief Sets which widget has to be focused. Depends on the user state. */
void setInitialFocus();
void doQuickPlay();
public:
virtual void onUpdate(float delta) OVERRIDE;

View File

@ -191,7 +191,11 @@ void OnlineUserSearch::search()
{
if (m_search_string != "" && m_last_search_string != m_search_string)
{
m_search_request = CurrentUser::get()->requestUserSearch(m_search_string);
m_search_request = new XMLRequest();
CurrentUser::setUserDetails(m_search_request, "user-search");
m_search_request->addParameter("search-string", m_search_string);
m_search_request->queue();
m_user_list_widget->clear();
m_user_list_widget->addItem("spacer", L"");
m_user_list_widget->addItem("loading", Messages::searching());
@ -199,7 +203,7 @@ void OnlineUserSearch::search()
m_search_box_widget->setDeactivated();
m_search_button_widget->setDeactivated();
}
} // sarch
} // search
// ----------------------------------------------------------------------------

View File

@ -80,7 +80,7 @@ void OptionsScreenPlayers::init()
refreshPlayerList();
ButtonWidget* you = getWidget<ButtonWidget>("playername");
unsigned int playerID = PlayerManager::get()->getCurrentPlayer()->getUniqueID();
unsigned int playerID = PlayerManager::getCurrentPlayer()->getUniqueID();
core::stringw player_name = L"-";
const PlayerProfile* curr = PlayerManager::get()->getPlayerById(playerID);
if(curr)

View File

@ -207,7 +207,7 @@ void RaceGUIOverworld::renderPlayerView(const Camera *camera, float dt)
*/
void RaceGUIOverworld::drawTrophyPoints()
{
PlayerProfile *player = PlayerManager::get()->getCurrentPlayer();
PlayerProfile *player = PlayerManager::getCurrentPlayer();
const int points = player->getPoints();
std::string s = StringUtils::toString(points);
core::stringw sw(s.c_str());
@ -398,7 +398,7 @@ void RaceGUIOverworld::drawGlobalMiniMap()
// bool locked = (m_locked_challenges.find(c) != m_locked_challenges.end());
int state = (challenges[n].getForceField().m_is_locked ? LOCKED : OPEN);
const ChallengeStatus* c = PlayerManager::get()->getCurrentPlayer()
const ChallengeStatus* c = PlayerManager::getCurrentPlayer()
->getChallengeStatus(challenges[n].m_challenge_id);
if (c->isSolved(RaceManager::DIFFICULTY_HARD)) state = COMPLETED_HARD;
else if (c->isSolved(RaceManager::DIFFICULTY_MEDIUM)) state = COMPLETED_MEDIUM;

View File

@ -157,7 +157,7 @@ void RaceResultGUI::enableAllButtons()
// If something was unlocked
// -------------------------
int n = PlayerManager::get()->getCurrentPlayer()->getRecentlyCompletedChallenges().size();
int n = PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges().size();
if(n>0)
{
top->setText(n==1 ? _("You completed a challenge!")
@ -226,7 +226,7 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
// If something was unlocked, the 'continue' button was
// actually used to display "Show unlocked feature(s)" text.
// ---------------------------------------------------------
int n = PlayerManager::get()->getCurrentPlayer()
int n = PlayerManager::getCurrentPlayer()
->getRecentlyCompletedChallenges().size();
if(n>0)
{
@ -238,7 +238,7 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
}
std::vector<const ChallengeData*> unlocked =
PlayerManager::get()->getCurrentPlayer()->getRecentlyCompletedChallenges();
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
bool gameCompleted = false;
for (unsigned int n = 0; n < unlocked.size(); n++)
@ -250,7 +250,7 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
}
}
PlayerManager::get()->getCurrentPlayer()->clearUnlocked();
PlayerManager::getCurrentPlayer()->clearUnlocked();
if (gameCompleted)
{

View File

@ -180,7 +180,7 @@ void RaceSetupScreen::assignDifficulty()
}
else if (difficultySelection == "best")
{
if (PlayerManager::get()->getCurrentPlayer()->isLocked("difficulty_best"))
if (PlayerManager::getCurrentPlayer()->isLocked("difficulty_best"))
{
unlock_manager->playLockSound();
UserConfigParams::m_difficulty = RaceManager::DIFFICULTY_HARD;
@ -231,7 +231,7 @@ void RaceSetupScreen::init()
assert( w != NULL );
if (UserConfigParams::m_difficulty == RaceManager::DIFFICULTY_BEST &&
PlayerManager::get()->getCurrentPlayer()->isLocked("difficulty_best"))
PlayerManager::getCurrentPlayer()->isLocked("difficulty_best"))
{
w->setSelection(RaceManager::DIFFICULTY_HARD, PLAYER_ID_GAME_MASTER);
}
@ -269,7 +269,7 @@ void RaceSetupScreen::init()
name2 += _("Contains no powerups, so only your driving skills matter!");
w2->addItem( name2, IDENT_TTRIAL, RaceManager::getIconOf(RaceManager::MINOR_MODE_TIME_TRIAL));
if (PlayerManager::get()->getCurrentPlayer()->isLocked(IDENT_FTL))
if (PlayerManager::getCurrentPlayer()->isLocked(IDENT_FTL))
{
w2->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", RaceManager::getIconOf(RaceManager::MINOR_MODE_FOLLOW_LEADER), true);
@ -345,7 +345,7 @@ void RaceSetupScreen::init()
w2->registerHoverListener(m_mode_listener);
if (PlayerManager::get()->getCurrentPlayer()->isLocked("difficulty_best"))
if (PlayerManager::getCurrentPlayer()->isLocked("difficulty_best"))
{
RibbonWidget* w = getWidget<RibbonWidget>("difficulty");
assert(w != NULL);

View File

@ -55,7 +55,7 @@ void StoryModeLobbyScreen::init()
ListWidget* list = getWidget<ListWidget>("gameslots");
list->clear();
PlayerProfile *player = PlayerManager::get()->getCurrentPlayer();
PlayerProfile *player = PlayerManager::getCurrentPlayer();
if(player)
{
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());

View File

@ -238,7 +238,7 @@ void TracksScreen::init()
sshot_files.push_back("gui/main_help.png");
}
if (PlayerManager::get()->getCurrentPlayer()->isLocked(gp->getId()))
if (PlayerManager::getCurrentPlayer()->isLocked(gp->getId()))
{
gps_widget->addAnimatedItem(_("Locked!"),
"locked", sshot_files, 1.5f, LOCKED_BADGE | TROPHY_BADGE,
@ -303,7 +303,7 @@ void TracksScreen::buildTrackList()
if (curr->isArena() || curr->isSoccer()) continue;
if (curr->isInternal()) continue;
if(PlayerManager::get()->getCurrentPlayer()->isLocked(curr->getIdent()))
if(PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
{
tracks_widget->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", curr->getScreenshotFile(), LOCKED_BADGE,
@ -334,7 +334,7 @@ void TracksScreen::buildTrackList()
if (curr->isSoccer()) continue;
if (curr->isInternal()) continue;
if (PlayerManager::get()->getCurrentPlayer()->isLocked(curr->getIdent()))
if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent()))
{
tracks_widget->addItem( _("Locked : solve active challenges to gain access to more!"),
"locked", curr->getScreenshotFile(), LOCKED_BADGE,

212
src/states_screens/xx Normal file
View File

@ -0,0 +1,212 @@
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 1) // SuperTuxKart - a fun racing game with go-kart
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 2) // Copyright (C) 2013 Glenn De Jonghe
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 3) //
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 4) // This program is free software; you can redistribute it and/or
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 5) // modify it under the terms of the GNU General Public License
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 6) // as published by the Free Software Foundation; either version 3
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 7) // of the License, or (at your option) any later version.
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 8) //
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 9) // This program is distributed in the hope that it will be useful,
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 10) // but WITHOUT ANY WARRANTY; without even the implied warranty of
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 11) // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 12) // GNU General Public License for more details.
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 13) //
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 14) // You should have received a copy of the GNU General Public License
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 15) // along with this program; if not, write to the Free Software
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 16) // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 17)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 18) #include "states_screens/dialogs/recovery_dialog.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 19)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 20) #include "audio/sfx_manager.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 21) #include "guiengine/engine.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 22) #include "states_screens/state_manager.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 23) #include "utils/translation.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 24) #include "utils/string_utils.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 25) #include "online/messages.hpp"
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 26)
4d6b110e (hiker 2014-02-26 12:52:16 +1100 27) #include <IGUIEnvironment.h>
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 28)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 29) using namespace GUIEngine;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 30) using namespace irr;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 31) using namespace irr::gui;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 32) using namespace Online;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 33)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 34) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 35) /** Constructor for the recovery dialog.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 36) */
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 37) RecoveryDialog::RecoveryDialog() : ModalDialog(0.8f,0.8f)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 38) {
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 39) m_recovery_request = NULL;
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 40) m_self_destroy = false;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 41) m_show_recovery_input = true;
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 42) m_show_recovery_info = false;
8e8f02a1 (hiker 2014-04-06 01:27:04 +1100 43) doInit();
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 44) showRecoveryInput();
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 45) } // RecoveryDialog
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 46)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 47) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 48) /** Destructor, destroys the recovery request.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 49) */
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 50) RecoveryDialog::~RecoveryDialog()
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 51) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 52) delete m_recovery_request;
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 53) } //~RecoverDialog
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 54)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 55) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 56) /** Shows the input screen to get the account name and email address.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 57) */
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 58) void RecoveryDialog::showRecoveryInput()
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 59) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 60) m_show_recovery_input = false;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 61) clearWindow();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 62) m_phase = Input;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 63) loadFromFile("online/recovery_input.stkgui");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 64)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 65) m_username_widget = getWidget<TextBoxWidget>("username");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 66) assert(m_username_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 67) m_username_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 68)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 69) m_email_widget = getWidget<TextBoxWidget>("email");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 70) assert(m_email_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 71)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 72) m_info_widget = getWidget<LabelWidget>("info");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 73) assert(m_info_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 74)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 75) m_options_widget = getWidget<RibbonWidget>("options");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 76) assert(m_options_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 77) m_submit_widget = getWidget<IconButtonWidget>("submit");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 78) assert(m_submit_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 79) m_cancel_widget = getWidget<IconButtonWidget>("cancel");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 80) assert(m_cancel_widget != NULL);
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 81) } // showRecoveryInput
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 82)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 83) // -----------------------------------------------------------------------------
7cc83e14 (konstin 2014-03-29 11:33:43 +0100 84) /** Informs the user that an email will be sent.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 85) */
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 86) void RecoveryDialog::showRecoveryInfo()
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 87) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 88) m_show_recovery_info = false;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 89) clearWindow();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 90) m_phase = Info;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 91) loadFromFile("online/recovery_info.stkgui");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 92)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 93) m_info_widget = getWidget<LabelWidget>("info");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 94) assert(m_info_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 95)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 96) m_options_widget = getWidget<RibbonWidget>("options");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 97) assert(m_options_widget != NULL);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 98) m_cancel_widget = getWidget<IconButtonWidget>("cancel");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 99) assert(m_cancel_widget != NULL);
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 100) } // showRecoveryInfo
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 101)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 102) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 103) /** Let esc act as cancel.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 104) */
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 105) bool RecoveryDialog::onEscapePressed()
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 106) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 107) return m_cancel_widget->isActivated();
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 108) } // onEscapePressed
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 109)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 110) // -----------------------------------------------------------------------------
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 111)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 112) void RecoveryDialog::processInput()
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 113) {
4d6b110e (hiker 2014-02-26 12:52:16 +1100 114) const core::stringw username = m_username_widget->getText().trim();
4d6b110e (hiker 2014-02-26 12:52:16 +1100 115) const core::stringw email = m_email_widget->getText().trim();
7cc83e14 (konstin 2014-03-29 11:33:43 +0100 116) if (username.size() < 4 || username.size() > 30 ||
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 117) email.size() < 4 || email.size() > 50 )
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 118) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 119) sfx_manager->quickSound("anvil");
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 120) m_info_widget->setErrorColor();
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 121) m_info_widget->setText(_("Username and/or email address invalid."),
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 122) false);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 123) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 124) else
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 125) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 126) m_info_widget->setDefaultColor();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 127) m_options_widget->setDeactivated();
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 128) m_recovery_request = new XMLRequest();
cb959acb (hiker 2014-04-07 08:25:48 +1000 129) // This function also works when the current user is not logged in
cb959acb (hiker 2014-04-07 08:25:48 +1000 130) CurrentUser::setUserDetails(m_recovery_request, "recovery");
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 131) m_recovery_request->addParameter("username", username);
cb959acb (hiker 2014-04-07 08:25:48 +1000 132) m_recovery_request->addParameter("email", email );
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 133) m_recovery_request->queue();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 134) }
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 135) } // processInput
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 136)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 137) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 138) /** Handle a user event.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 139) */
7cc83e14 (konstin 2014-03-29 11:33:43 +0100 140) GUIEngine::EventPropagation
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 141) RecoveryDialog::processEvent(const std::string& eventSource)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 142) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 143) std::string selection;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 144) if (eventSource == m_options_widget->m_properties[PROP_ID])
7cc83e14 (konstin 2014-03-29 11:33:43 +0100 145) selection =
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 146) m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 147) else
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 148) selection = eventSource;
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 149)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 150) if (selection == m_cancel_widget->m_properties[PROP_ID])
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 151) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 152) m_self_destroy = true;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 153) return GUIEngine::EVENT_BLOCK;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 154) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 155) else if (selection == m_submit_widget->m_properties[PROP_ID])
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 156) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 157) processInput();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 158) return GUIEngine::EVENT_BLOCK;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 159) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 160) return GUIEngine::EVENT_LET;
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 161) } // processEvent
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 162)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 163) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 164) /** Called when the user pressed enter.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 165) */
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 166) void RecoveryDialog::onEnterPressedInternal()
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 167) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 168)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 169) if (GUIEngine::isFocusedForPlayer(m_options_widget, PLAYER_ID_GAME_MASTER))
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 170) return;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 171) if (m_submit_widget->isActivated())
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 172) processInput();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 173) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 174)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 175) // -----------------------------------------------------------------------------
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 176) /** This is called every frame and checks if an outstanding recovery request
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 177) * was finished. If so, it displays the results.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 178) * \param dt Time step size.
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 179) */
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 180) void RecoveryDialog::onUpdate(float dt)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 181) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 182) if(m_recovery_request != NULL)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 183) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 184) if(m_recovery_request->isDone())
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 185) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 186) if(m_recovery_request->isSuccess())
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 187) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 188) m_show_recovery_info = true;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 189) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 190) else
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 191) {
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 192) sfx_manager->quickSound( "anvil" );
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 193) m_info_widget->setErrorColor();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 194) m_info_widget->setText(m_recovery_request->getInfo(), false);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 195) m_options_widget->setActivated();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 196) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 197) delete m_recovery_request;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 198) m_recovery_request = NULL;
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 199) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 200) else
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 201) {
99e7b565 (unitraxx 2013-09-14 01:07:22 +0000 202) m_info_widget->setText(Messages::validatingInfo(), false);
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 203) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 204) }
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 205) // It's unsafe to delete from inside the event handler so we do it here
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 206) if (m_self_destroy)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 207) ModalDialog::dismiss();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 208) else if (m_show_recovery_input)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 209) showRecoveryInput();
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 210) else if (m_show_recovery_info)
4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 211) showRecoveryInfo();
6afc12c8 (hiker 2014-03-14 16:44:58 +1100 212) } // onUpdates

View File

@ -145,3 +145,10 @@ void ModelDefinitionLoader::clear()
{
m_lod_groups.clear();
}
// ----------------------------------------------------------------------------
scene::IMesh* ModelDefinitionLoader::getFirstMeshFor(const std::string& name)
{
return irr_driver->getMesh(m_lod_groups[name][0].m_model_file);
}

Some files were not shown because too many files have changed in this diff Show More