This commit is contained in:
konstin
2014-07-16 15:16:11 +02:00
15 changed files with 219 additions and 172 deletions

View File

@@ -15,8 +15,9 @@ before_install:
- sudo apt-get update -qq
# Install dependencies
- sudo apt-get install build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev
# Install mesa from an other repo (a newer version is required)
- sudo apt-add-repository "deb http://archive.ubuntu.com/ubuntu quantal main restricted"
# Install mesa from an other repo (a newer version is required). Quantal is not supported anymore, saucy is only supported till July 2014,
# so we try to use trusty (precise which is what traiv uses a too old mesa version which doesn't link)
- sudo apt-add-repository "deb http://archive.ubuntu.com/ubuntu trusty main restricted"
- sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 3B4FE6ACC0B21F32
- sudo apt-get update -qq
- sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev

View File

@@ -61,7 +61,7 @@ void apply_instance(const T *Shader, const std::tuple<TupleType...> &arg)
template<typename Shader, enum E_VERTEX_TYPE VertexType, typename... TupleType>
void renderMeshes1stPass(const std::vector<GLuint> &TexUnits, std::vector<std::tuple<TupleType...> > &meshes)
{
glUseProgram(Shader::getInstance()->Program);
glUseProgram(Shader::template getInstance<Shader>()->Program);
glBindVertexArray(getVAO(VertexType));
for (unsigned i = 0; i < meshes.size(); i++)
{
@@ -80,7 +80,7 @@ void renderMeshes1stPass(const std::vector<GLuint> &TexUnits, std::vector<std::t
#endif
continue;
}
apply_instance(Shader::getInstance(), meshes[i]);
apply_instance(Shader::template getInstance<Shader>(), meshes[i]);
}
}
@@ -117,10 +117,10 @@ void IrrDriver::renderSolidFirstPass()
}
}
template<typename T, enum E_VERTEX_TYPE VertexType, typename... TupleType>
void renderMeshes2ndPass(const T *Shader, const std::vector<GLuint> &TexUnits, std::vector<std::tuple<TupleType...> > &meshes)
template<typename Shader, enum E_VERTEX_TYPE VertexType, typename... TupleType>
void renderMeshes2ndPass(const std::vector<GLuint> &TexUnits, std::vector<std::tuple<TupleType...> > &meshes)
{
glUseProgram(Shader->Program);
glUseProgram(Shader::template getInstance<Shader>()->Program);
glBindVertexArray(getVAO(VertexType));
for (unsigned i = 0; i < meshes.size(); i++)
{
@@ -150,7 +150,7 @@ void renderMeshes2ndPass(const T *Shader, const std::vector<GLuint> &TexUnits, s
#endif
continue;
}
apply_instance<T>(Shader, meshes[i]);
apply_instance(Shader::template getInstance<Shader>(), meshes[i]);
}
}
@@ -193,14 +193,14 @@ void IrrDriver::renderSolidSecondPass()
m_scene_manager->drawAll(scene::ESNRP_SOLID);
renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_STANDARD>(MeshShader::ObjectPass2ShaderInstance, { MeshShader::ObjectPass2ShaderInstance->TU_Albedo }, ListDefaultStandardSM::Arguments);
renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_TANGENTS>(MeshShader::ObjectPass2ShaderInstance, { MeshShader::ObjectPass2ShaderInstance->TU_Albedo }, ListDefaultTangentSM::Arguments);
renderMeshes2ndPass<MeshShader::ObjectRefPass2Shader, video::EVT_STANDARD>(MeshShader::ObjectRefPass2ShaderInstance, { MeshShader::ObjectRefPass2ShaderInstance->TU_Albedo }, ListAlphaRefSM::Arguments);
renderMeshes2ndPass<MeshShader::SphereMapShader, video::EVT_STANDARD>(MeshShader::SphereMapShaderInstance, { MeshShader::SphereMapShaderInstance->TU_tex }, ListSphereMapSM::Arguments);
renderMeshes2ndPass<MeshShader::ObjectUnlitShader, video::EVT_STANDARD>(MeshShader::ObjectUnlitShaderInstance, { MeshShader::ObjectUnlitShaderInstance->TU_tex }, ListUnlitSM::Arguments);
renderMeshes2ndPass<MeshShader::DetailledObjectPass2Shader, video::EVT_2TCOORDS>(MeshShader::DetailledObjectPass2ShaderInstance, { MeshShader::DetailledObjectPass2ShaderInstance->TU_Albedo, MeshShader::DetailledObjectPass2ShaderInstance->TU_detail }, ListDetailSM::Arguments);
renderMeshes2ndPass<MeshShader::SplattingShader, video::EVT_2TCOORDS>(MeshShader::SplattingShaderInstance, { 8, MeshShader::SplattingShaderInstance->TU_tex_layout, MeshShader::SplattingShaderInstance->TU_tex_detail0, MeshShader::SplattingShaderInstance->TU_tex_detail1, MeshShader::SplattingShaderInstance->TU_tex_detail2, MeshShader::SplattingShaderInstance->TU_tex_detail3 }, ListSplattingSM::Arguments);
renderMeshes2ndPass<MeshShader::GrassPass2Shader, video::EVT_STANDARD>(MeshShader::GrassPass2ShaderInstance, { MeshShader::GrassPass2ShaderInstance->TU_Albedo }, ListGrassSM::Arguments);
renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_STANDARD>({ MeshShader::ObjectPass2Shader::getInstance<MeshShader::ObjectPass2Shader>()->TU_Albedo }, ListDefaultStandardSM::Arguments);
renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_TANGENTS>({ MeshShader::ObjectPass2Shader::getInstance<MeshShader::ObjectPass2Shader>()->TU_Albedo }, ListDefaultTangentSM::Arguments);
renderMeshes2ndPass<MeshShader::ObjectRefPass2Shader, video::EVT_STANDARD>({ MeshShader::ObjectRefPass2Shader::getInstance<MeshShader::ObjectRefPass2Shader>()->TU_Albedo }, ListAlphaRefSM::Arguments);
renderMeshes2ndPass<MeshShader::SphereMapShader, video::EVT_STANDARD>({ MeshShader::SphereMapShader::getInstance<MeshShader::SphereMapShader>()->TU_tex }, ListSphereMapSM::Arguments);
renderMeshes2ndPass<MeshShader::ObjectUnlitShader, video::EVT_STANDARD>({ MeshShader::ObjectUnlitShader::getInstance<MeshShader::ObjectUnlitShader>()->TU_tex }, ListUnlitSM::Arguments);
renderMeshes2ndPass<MeshShader::DetailledObjectPass2Shader, video::EVT_2TCOORDS>({ MeshShader::DetailledObjectPass2Shader::getInstance<MeshShader::DetailledObjectPass2Shader>()->TU_Albedo, MeshShader::DetailledObjectPass2Shader::getInstance<MeshShader::DetailledObjectPass2Shader>()->TU_detail }, ListDetailSM::Arguments);
renderMeshes2ndPass<MeshShader::SplattingShader, video::EVT_2TCOORDS>({ 8, MeshShader::SplattingShader::getInstance<MeshShader::SplattingShader>()->TU_tex_layout, MeshShader::SplattingShader::getInstance<MeshShader::SplattingShader>()->TU_tex_detail0, MeshShader::SplattingShader::getInstance<MeshShader::SplattingShader>()->TU_tex_detail1, MeshShader::SplattingShader::getInstance<MeshShader::SplattingShader>()->TU_tex_detail2, MeshShader::SplattingShader::getInstance<MeshShader::SplattingShader>()->TU_tex_detail3 }, ListSplattingSM::Arguments);
renderMeshes2ndPass<MeshShader::GrassPass2Shader, video::EVT_STANDARD>({ MeshShader::GrassPass2Shader::getInstance<MeshShader::GrassPass2Shader>()->TU_Albedo }, ListGrassSM::Arguments);
}
}
@@ -227,16 +227,16 @@ void IrrDriver::renderTransparent()
if (World::getWorld() && World::getWorld()->isFogEnabled())
{
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
renderMeshes2ndPass<MeshShader::TransparentFogShader, video::EVT_STANDARD>(MeshShader::TransparentFogShaderInstance, { MeshShader::TransparentFogShaderInstance->TU_tex }, ListBlendTransparentFog::Arguments);
renderMeshes2ndPass<MeshShader::TransparentFogShader, video::EVT_STANDARD>({ MeshShader::TransparentFogShader::getInstance<MeshShader::TransparentFogShader>()->TU_tex }, ListBlendTransparentFog::Arguments);
glBlendFunc(GL_ONE, GL_ONE);
renderMeshes2ndPass<MeshShader::TransparentFogShader, video::EVT_STANDARD>(MeshShader::TransparentFogShaderInstance, { MeshShader::TransparentFogShaderInstance->TU_tex }, ListAdditiveTransparentFog::Arguments);
renderMeshes2ndPass<MeshShader::TransparentFogShader, video::EVT_STANDARD>({ MeshShader::TransparentFogShader::getInstance<MeshShader::TransparentFogShader>()->TU_tex }, ListAdditiveTransparentFog::Arguments);
}
else
{
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
renderMeshes2ndPass<MeshShader::TransparentShader, video::EVT_STANDARD>(MeshShader::TransparentShaderInstance, { MeshShader::TransparentShaderInstance->TU_tex }, ListBlendTransparent::Arguments);
renderMeshes2ndPass<MeshShader::TransparentShader, video::EVT_STANDARD>({ MeshShader::TransparentShader::getInstance<MeshShader::TransparentShader>()->TU_tex }, ListBlendTransparent::Arguments);
glBlendFunc(GL_ONE, GL_ONE);
renderMeshes2ndPass<MeshShader::TransparentShader, video::EVT_STANDARD>(MeshShader::TransparentShaderInstance, { MeshShader::TransparentShaderInstance->TU_tex }, ListAdditiveTransparent::Arguments);
renderMeshes2ndPass<MeshShader::TransparentShader, video::EVT_STANDARD>({ MeshShader::TransparentShader::getInstance<MeshShader::TransparentShader>()->TU_tex }, ListAdditiveTransparent::Arguments);
}
if (!UserConfigParams::m_dynamic_lights)
@@ -410,4 +410,4 @@ void IrrDriver::renderShadows()
drawRSM<EVT_STANDARD>(rsm_matrix, { MeshShader::RSMShader::TU_tex }, ListDefaultStandardG::Arguments);
drawRSM<EVT_2TCOORDS>(rsm_matrix, { MeshShader::RSMShader::TU_tex }, ListDefault2TCoordG::Arguments);
}
}

View File

@@ -328,19 +328,10 @@ void Shaders::loadShaders()
MeshShader::InstancedObjectPass1ShaderInstance = new MeshShader::InstancedObjectPass1Shader();
MeshShader::InstancedObjectRefPass1ShaderInstance = new MeshShader::InstancedObjectRefPass1Shader();
MeshShader::InstancedGrassPass1ShaderInstance = new MeshShader::InstancedGrassPass1Shader();
MeshShader::ObjectPass2ShaderInstance = new MeshShader::ObjectPass2Shader();
MeshShader::InstancedObjectPass2ShaderInstance = new MeshShader::InstancedObjectPass2Shader();
MeshShader::InstancedObjectRefPass2ShaderInstance = new MeshShader::InstancedObjectRefPass2Shader();
MeshShader::InstancedGrassPass2ShaderInstance = new MeshShader::InstancedGrassPass2Shader();
MeshShader::DetailledObjectPass2ShaderInstance = new MeshShader::DetailledObjectPass2Shader();
MeshShader::ObjectRefPass2ShaderInstance = new MeshShader::ObjectRefPass2Shader();
MeshShader::ObjectUnlitShaderInstance = new MeshShader::ObjectUnlitShader();
MeshShader::SphereMapShaderInstance = new MeshShader::SphereMapShader();
MeshShader::SplattingShaderInstance = new MeshShader::SplattingShader();
MeshShader::GrassPass2ShaderInstance = new MeshShader::GrassPass2Shader();
MeshShader::BubbleShader::init();
MeshShader::TransparentShaderInstance = new MeshShader::TransparentShader();
MeshShader::TransparentFogShaderInstance = new MeshShader::TransparentFogShader();
MeshShader::BillboardShader::init();
LightShader::PointLightShader::init();
MeshShader::DisplaceShaderInstance = new MeshShader::DisplaceShader();

View File

@@ -198,7 +198,7 @@ public:
extern InstancedGrassPass1Shader *InstancedGrassPass1ShaderInstance;
class ObjectPass2Shader : public ShaderHelper<core::matrix4, core::matrix4, video::SColorf>
class ObjectPass2Shader : public ShaderHelperSingleton<ObjectPass2Shader, core::matrix4, core::matrix4, video::SColorf>
{
public:
GLuint TU_Albedo;
@@ -206,8 +206,6 @@ public:
ObjectPass2Shader();
};
extern ObjectPass2Shader *ObjectPass2ShaderInstance;
class InstancedObjectPass2Shader : public ShaderHelper<video::SColorf>
{
public:
@@ -228,7 +226,7 @@ public:
extern InstancedObjectRefPass2Shader *InstancedObjectRefPass2ShaderInstance;
class DetailledObjectPass2Shader : public ShaderHelper<core::matrix4, video::SColorf>
class DetailledObjectPass2Shader : public ShaderHelperSingleton<DetailledObjectPass2Shader, core::matrix4, video::SColorf>
{
public:
GLuint TU_Albedo, TU_detail;
@@ -236,9 +234,7 @@ public:
DetailledObjectPass2Shader();
};
extern DetailledObjectPass2Shader *DetailledObjectPass2ShaderInstance;
class ObjectUnlitShader : public ShaderHelper<core::matrix4>
class ObjectUnlitShader : public ShaderHelperSingleton<ObjectUnlitShader, core::matrix4>
{
public:
GLuint TU_tex;
@@ -246,9 +242,7 @@ public:
ObjectUnlitShader();
};
extern ObjectUnlitShader *ObjectUnlitShaderInstance;
class ObjectRefPass2Shader : public ShaderHelper<core::matrix4, core::matrix4, video::SColorf>
class ObjectRefPass2Shader : public ShaderHelperSingleton<ObjectRefPass2Shader, core::matrix4, core::matrix4, video::SColorf>
{
public:
GLuint TU_Albedo;
@@ -256,9 +250,7 @@ public:
ObjectRefPass2Shader();
};
extern ObjectRefPass2Shader *ObjectRefPass2ShaderInstance;
class GrassPass2Shader : public ShaderHelper<core::matrix4, core::vector3df, video::SColorf>
class GrassPass2Shader : public ShaderHelperSingleton<GrassPass2Shader, core::matrix4, core::vector3df, video::SColorf>
{
public:
GLuint TU_Albedo;
@@ -266,8 +258,6 @@ public:
GrassPass2Shader();
};
extern GrassPass2Shader *GrassPass2ShaderInstance;
class InstancedGrassPass2Shader : public ShaderHelper<core::vector3df, core::vector3df, video::SColorf>
{
public:
@@ -278,7 +268,7 @@ public:
extern InstancedGrassPass2Shader *InstancedGrassPass2ShaderInstance;
class SphereMapShader : public ShaderHelper<core::matrix4, core::matrix4, video::SColorf>
class SphereMapShader : public ShaderHelperSingleton<SphereMapShader, core::matrix4, core::matrix4, video::SColorf>
{
public:
GLuint TU_tex;
@@ -286,9 +276,7 @@ public:
SphereMapShader();
};
extern SphereMapShader *SphereMapShaderInstance;
class SplattingShader : public ShaderHelper<core::matrix4, video::SColorf>
class SplattingShader : public ShaderHelperSingleton<SplattingShader, core::matrix4, video::SColorf>
{
public:
GLuint TU_tex_layout, TU_tex_detail0, TU_tex_detail1, TU_tex_detail2, TU_tex_detail3;
@@ -296,8 +284,6 @@ public:
SplattingShader();
};
extern SplattingShader *SplattingShaderInstance;
class BubbleShader
{
public:
@@ -308,7 +294,7 @@ public:
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex, float time, float transparency);
};
class TransparentShader : public ShaderHelper<core::matrix4, core::matrix4>
class TransparentShader : public ShaderHelperSingleton<TransparentShader, core::matrix4, core::matrix4>
{
public:
GLuint TU_tex;
@@ -316,9 +302,7 @@ public:
TransparentShader();
};
extern TransparentShader *TransparentShaderInstance;
class TransparentFogShader : public ShaderHelper<core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
class TransparentFogShader : public ShaderHelperSingleton<TransparentFogShader, core::matrix4, core::matrix4, float, float, float, float, float, video::SColorf>
{
public:
GLuint TU_tex;
@@ -326,8 +310,6 @@ public:
TransparentFogShader();
};
extern TransparentFogShader *TransparentFogShaderInstance;
class BillboardShader
{
public:

View File

@@ -225,7 +225,7 @@ void STKMeshSceneNode::render()
glDisable(GL_CULL_FACE);
if (update_each_frame)
updatevbo();
glUseProgram(MeshShader::ObjectPass1Shader::getInstance()->Program);
glUseProgram(MeshShader::ObjectPass1Shader::getInstance<MeshShader::ObjectPass1Shader>()->Program);
// Only untextured
for (unsigned i = 0; i < GLmeshes.size(); i++)
{
@@ -276,7 +276,7 @@ void STKMeshSceneNode::render()
glDisable(GL_CULL_FACE);
if (!spareWhiteTex)
spareWhiteTex = getUnicolorTexture(video::SColor(255, 255, 255, 255));
glUseProgram(MeshShader::ObjectPass2ShaderInstance->Program);
glUseProgram(MeshShader::ObjectPass2Shader::getInstance<MeshShader::ObjectPass2Shader>()->Program);
// Only untextured
for (unsigned i = 0; i < GLmeshes.size(); i++)
{
@@ -286,8 +286,8 @@ void STKMeshSceneNode::render()
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
setTexture(MeshShader::ObjectPass2ShaderInstance->TU_Albedo, getTextureGLuint(spareWhiteTex), GL_NEAREST, GL_NEAREST, false);
MeshShader::ObjectPass2ShaderInstance->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, irr_driver->getSceneManager()->getAmbientLight());
setTexture(MeshShader::ObjectPass2Shader::getInstance<MeshShader::ObjectPass2Shader>()->TU_Albedo, getTextureGLuint(spareWhiteTex), GL_NEAREST, GL_NEAREST, false);
MeshShader::ObjectPass2Shader::getInstance<MeshShader::ObjectPass2Shader>()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, irr_driver->getSceneManager()->getAmbientLight());
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);
@@ -350,7 +350,7 @@ void STKMeshSceneNode::render()
if (World::getWorld() && World::getWorld()->isFogEnabled())
{
glUseProgram(MeshShader::TransparentFogShaderInstance->Program);
glUseProgram(MeshShader::TransparentFogShader::getInstance<MeshShader::TransparentFogShader>()->Program);
for (unsigned i = 0; i < GLmeshes.size(); i++)
{
GLMesh &mesh = GLmeshes[i];
@@ -374,8 +374,8 @@ void STKMeshSceneNode::render()
tmpcol.getBlue() / 255.0f);
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::TransparentFogShaderInstance->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, fogmax, startH, endH, start, end, col);
setTexture(MeshShader::TransparentFogShader::getInstance<MeshShader::TransparentFogShader>()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::TransparentFogShader::getInstance<MeshShader::TransparentFogShader>()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, fogmax, startH, endH, start, end, col);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
@@ -385,7 +385,7 @@ void STKMeshSceneNode::render()
}
else
{
glUseProgram(MeshShader::TransparentShaderInstance->Program);
glUseProgram(MeshShader::TransparentShader::getInstance<MeshShader::TransparentShader>()->Program);
for (unsigned i = 0; i < GLmeshes.size(); i++)
{
irr_driver->IncreaseObjectCount();
@@ -395,9 +395,9 @@ void STKMeshSceneNode::render()
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
setTexture(MeshShader::TransparentShaderInstance->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
setTexture(MeshShader::TransparentShader::getInstance<MeshShader::TransparentShader>()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::TransparentShaderInstance->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
MeshShader::TransparentShader::getInstance<MeshShader::TransparentShader>()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
assert(mesh.vao);
glBindVertexArray(mesh.vao);
glDrawElements(ptype, count, itype, 0);

View File

@@ -37,6 +37,9 @@
// ----------------------------------------------------------------------------
/** Loads a grand prix definition from a file.
* \param filename Name of the file to load.
*/
GrandPrixData::GrandPrixData(const std::string& filename)
{
m_filename = filename;
@@ -44,18 +47,34 @@ GrandPrixData::GrandPrixData(const std::string& filename)
StringUtils::removeExtension(filename));
m_editable = (filename.find(file_manager->getGPDir(), 0) == 0);
reload();
}
} // GrandPrixData
// ----------------------------------------------------------------------------
GrandPrixData::GrandPrixData(const unsigned int number_of_tracks,
const std::string& track_group,
const RandomGPInfoDialog::REVERSED use_reverse)
/** Creates a random grand prix from the specified parameters.
* \param number_of_tracks How many tracks to select.
* \param track_group From which track group to select the tracks.
* \param use_reverse How the reverse setting is to be determined.
* \param new_tracks If true, new tracks are selected, otherwise existing
* tracks will not be changed (used to e.g. increase the number of
* tracks in an already existing random grand prix).
*
*/
void GrandPrixData::createRandomGP(const unsigned int number_of_tracks,
const std::string &track_group,
const GPReverseType use_reverse,
bool new_tracks)
{
m_filename = "Random GP - Not loaded from a file!";
m_id = "random";
m_name = "Random Grand Prix";
m_editable = false;
if(new_tracks)
{
m_tracks.clear();
m_laps.clear();
m_reversed.clear();
}
m_tracks.reserve(number_of_tracks);
m_laps.reserve(number_of_tracks);
m_reversed.reserve(number_of_tracks);
@@ -117,48 +136,64 @@ void GrandPrixData::changeTrackNumber(const unsigned int number_of_tracks,
}
// ----------------------------------------------------------------------------
void GrandPrixData::changeReverse(const RandomGPInfoDialog::REVERSED use_reverse)
/** Updates the GP data with newly decided reverse requirements.
* \param use_reverse How reverse setting for each track is to be determined.
*/
void GrandPrixData::changeReverse(const GrandPrixData::GPReverseType use_reverse)
{
for (unsigned int i = 0; i < m_tracks.size(); i++)
{
if (use_reverse == RandomGPInfoDialog::NO_REVERSE)
if (use_reverse == GP_NO_REVERSE)
m_reversed[i] = false;
else if (use_reverse == RandomGPInfoDialog::MIXED)
else if (use_reverse == GP_RANDOM_REVERSE)
if (track_manager->getTrack(m_tracks[i])->reverseAvailable())
m_reversed[i] = (rand() % 2 != 0);
else
m_reversed[i] = false;
else // all reversed
m_reversed[i] = track_manager->getTrack(m_tracks[i])->reverseAvailable();
}
}
} // for i < m_tracks.size()
} // changeReverse
// ----------------------------------------------------------------------------
/** Sets the id of this grand prix.
* \param id The new id.
*/
void GrandPrixData::setId(const std::string& id)
{
m_id = id;
}
} // setId
// ----------------------------------------------------------------------------
/** Sets the name of the grand prix.
* \param name New name.
*/
void GrandPrixData::setName(const irr::core::stringw& name)
{
m_name = name;
}
} // setName
// ----------------------------------------------------------------------------
/** Sets the filename of this grand prix.
* \param filename New filename.
*/
void GrandPrixData::setFilename(const std::string& filename)
{
m_filename = filename;
}
} // setFilename
// ----------------------------------------------------------------------------
/** Sets if this grand prix can be edited.
* \param editable New value.
*/
void GrandPrixData::setEditable(const bool editable)
{
m_editable = editable;
}
} // setEditable
// ----------------------------------------------------------------------------
/** Reloads grand prix from file.
*/
void GrandPrixData::reload()
{
m_tracks.clear();
@@ -270,6 +305,8 @@ void GrandPrixData::reload()
} // reload()
// ----------------------------------------------------------------------------
/** Saves the grand prix data to a file.
*/
bool GrandPrixData::writeToFile()
{
try
@@ -303,9 +340,12 @@ bool GrandPrixData::writeToFile()
m_filename.c_str(), e.what());
return false;
}
}
} // writeToFile
// ----------------------------------------------------------------------------
/** Checks if the grand prix data are consistent.
* \param log_error: If errors should be sent to the logger.
*/
bool GrandPrixData::checkConsistency(bool log_error) const
{
for (unsigned int i = 0; i < m_tracks.size(); i++)
@@ -323,8 +363,7 @@ bool GrandPrixData::checkConsistency(bool log_error) const
}
}
return true;
}
} // checkConsistency
// ----------------------------------------------------------------------------
/** Returns true if the track is available. This is used to test if Fort Magma
@@ -332,76 +371,99 @@ bool GrandPrixData::checkConsistency(bool log_error) const
* story mode, but will be available once all challenges are done and nolok
* is unlocked). It also prevents people from using the grand prix editor as
* a way to play tracks that still haven't been unlocked
* \param id Name of the track to test.
* \param include_locked If set to true, all tracks (including locked tracks)
* are considered to be available.
*/
bool GrandPrixData::isTrackAvailable(const std::string &id,
bool includeLocked ) const
bool include_locked ) const
{
if (includeLocked)
if (include_locked)
return true;
else if (id == "fortmagma")
return !PlayerManager::getCurrentPlayer()->isLocked("fortmagma");
else
return (!m_editable ||
!PlayerManager::get()->getCurrentPlayer()->isLocked(id));
}
} // isTrackAvailable
// ----------------------------------------------------------------------------
std::vector<std::string> GrandPrixData::getTrackNames(bool includeLocked) const
/** Returns the list of tracks that is available (i.e. unlocked) of this
* grand prix.
* \param include_locked If data for locked tracks should be included or not.
* \return A copy of the list of available tracks in this grand prix.
*/
std::vector<std::string> GrandPrixData::getTrackNames(bool include_locked) const
{
std::vector<std::string> names;
for (unsigned int i = 0; i < m_tracks.size(); i++)
{
if(isTrackAvailable(m_tracks[i], includeLocked))
if(isTrackAvailable(m_tracks[i], include_locked))
names.push_back(m_tracks[i]);
}
return names;
}
} // getTrackNames
// ----------------------------------------------------------------------------
std::vector<int> GrandPrixData::getLaps(bool includeLocked) const
/** Returns the laps for each available track of the grand prix.
* \param include_locked If data for locked tracks should be included or not.
* \return a std::vector containing the laps for each grand prix.
*/
std::vector<int> GrandPrixData::getLaps(bool include_locked) const
{
std::vector<int> laps;
for (unsigned int i = 0; i< m_tracks.size(); i++)
if(isTrackAvailable(m_tracks[i], includeLocked))
if(isTrackAvailable(m_tracks[i], include_locked))
laps.push_back(m_laps[i]);
return laps;
}
} // getLaps
// ----------------------------------------------------------------------------
std::vector<bool> GrandPrixData::getReverse(bool includeLocked) const
/** Returns the reverse setting for each available grand prix.
* \param include_locked If data for locked tracks should be included or not.
* \return A copy of alist with the reverse status for each track.
*/
std::vector<bool> GrandPrixData::getReverse(bool include_locked) const
{
std::vector<bool> reverse;
for (unsigned int i = 0; i< m_tracks.size(); i++)
if(isTrackAvailable(m_tracks[i], includeLocked))
if(isTrackAvailable(m_tracks[i], include_locked))
reverse.push_back(m_reversed[i]);
return reverse;
}
} // getReverse
// ----------------------------------------------------------------------------
/** Returns true if this grand prix can be edited.
*/
bool GrandPrixData::isEditable() const
{
return m_editable;
}
} // isEditable
// ----------------------------------------------------------------------------
/** Returns the number of tracks in this grand prix.
* \param include_locked If data for locked tracks should be included or not.
*/
unsigned int GrandPrixData::getNumberOfTracks(bool includeLocked) const
{
if (includeLocked)
return m_tracks.size();
else
return getTrackNames(false).size();
}
} // getNumberOfTracks
// ----------------------------------------------------------------------------
/** Returns the (translated) name of the track with the specified index.
*/
irr::core::stringw GrandPrixData::getTrackName(const unsigned int track) const
{
assert(track < getNumberOfTracks(true));
Track* t = track_manager->getTrack(m_tracks[track]);
assert(t != NULL);
return t->getName();
}
} // getTrackName
// ----------------------------------------------------------------------------
const std::string& GrandPrixData::getTrackId(const unsigned int track) const

View File

@@ -24,7 +24,6 @@
#include <string>
#include <vector>
#include "states_screens/dialogs/random_gp_dialog.hpp"
#include "utils/translation.hpp"
using irr::core::stringw;
@@ -69,21 +68,35 @@ private:
*/
bool isTrackAvailable(const std::string &id, bool includeLocked) const;
public:
/** Used to define the reverse setting when creating a random GP:
* No reverse, all reverse (if available on the track), random
* selection. */
enum GPReverseType
{
GP_NO_REVERSE = 0,
GP_ALL_REVERSE = 1,
GP_RANDOM_REVERSE = 2
}; // GPReverseType
public:
#if (defined(WIN32) || defined(_WIN32)) && !defined(__MINGW32__)
# pragma warning(disable:4290)
#endif
/** Load the GrandPrixData from the given filename */
GrandPrixData(const std::string& filename);
/** Needed for simple creation of an instance of GrandPrixData */
GrandPrixData() {};
/** Creates a new random GP */
GrandPrixData(const unsigned int number_of_tracks,
const std::string& track_group,
const RandomGPInfoDialog::REVERSED use_reverse);
void changeTrackNumber(const unsigned int number_of_tracks,
const std::string& track_group);
void changeReverse(const RandomGPInfoDialog::REVERSED use_reverse);
void changeReverse(const GPReverseType use_reverse);
void createRandomGP(const unsigned int number_of_tracks,
const std::string& track_group,
const GPReverseType use_reverse,
bool new_tracks=false);
// Methods for the GP editor
void setId(const std::string& id);

View File

@@ -34,7 +34,6 @@ const char* GrandPrixManager::SUFFIX = ".grandprix";
// ----------------------------------------------------------------------------
GrandPrixManager::GrandPrixManager()
{
m_random_gp = NULL; // better do it explicitly and avoid weird stuff
loadFiles();
} // GrandPrixManager
@@ -42,10 +41,7 @@ GrandPrixManager::GrandPrixManager()
GrandPrixManager::~GrandPrixManager()
{
for(unsigned int i=0; i<m_gp_data.size(); i++)
{
delete m_gp_data[i];
}
delete m_random_gp;
} // ~GrandPrixManager
// ----------------------------------------------------------------------------
@@ -97,7 +93,7 @@ void GrandPrixManager::load(const std::string& filename)
catch (std::runtime_error& e)
{
Log::error("GrandPrixManager",
"Ignoring grand prix %s (%s)\n", filename.c_str(), e.what());
"Ignoring Grand Prix %s (%s)\n", filename.c_str(), e.what());
}
} // load
@@ -156,9 +152,6 @@ GrandPrixData* GrandPrixManager::getGrandPrix(const std::string& s) const
// ----------------------------------------------------------------------------
GrandPrixData* GrandPrixManager::editGrandPrix(const std::string& s) const
{
if (s == "random")
return m_random_gp;
for(unsigned int i=0; i<m_gp_data.size(); i++)
{
if(m_gp_data[i]->getId() == s)

View File

@@ -22,7 +22,8 @@
#include <vector>
#include <string>
#include "race/grand_prix_data.hpp"
#include "irrlicht.h"
class GrandPrixData;
/**
* \ingroup race
@@ -47,10 +48,6 @@ private:
bool existsName(const irr::core::stringw& name) const;
public:
/** saved here by a random GP dialog to avoid dangling pinters or
* memory leaks */
GrandPrixData* m_random_gp;
GrandPrixManager();
~GrandPrixManager();
void reload();

View File

@@ -53,8 +53,8 @@ GPInfoDialog::GPInfoDialog(const std::string& gp_ident)
doInit();
m_curr_time = 0.0f;
m_gp = grand_prix_manager->getGrandPrix(gp_ident);
m_gp->checkConsistency();
m_gp = *grand_prix_manager->getGrandPrix(gp_ident);
m_gp.checkConsistency();
m_under_title = m_area.getHeight()/7;
m_over_body = m_area.getHeight()/7;
@@ -72,7 +72,7 @@ GPInfoDialog::~GPInfoDialog()
{
GUIEngine::Screen* curr_screen = GUIEngine::getCurrentScreen();
if (curr_screen->getName() == "tracks.stkgui")
static_cast<TracksScreen*>(curr_screen)->setFocusOnGP(m_gp->getId());
static_cast<TracksScreen*>(curr_screen)->setFocusOnGP(m_gp.getId());
}
// ----------------------------------------------------------------------------
@@ -81,7 +81,7 @@ void GPInfoDialog::addTitle()
{
core::rect< s32 > area_top(0, 0, m_area.getWidth(), m_under_title);
IGUIStaticText* title = GUIEngine::getGUIEnv()->addStaticText(
translations->fribidize(m_gp->getName()),
translations->fribidize(m_gp.getName()),
area_top, false, true, // border, word wrap
m_irrlicht_window);
title->setTabStop(false);
@@ -92,7 +92,7 @@ void GPInfoDialog::addTitle()
void GPInfoDialog::addTracks()
{
const std::vector<std::string> tracks = m_gp->getTrackNames();
const std::vector<std::string> tracks = m_gp.getTrackNames();
const unsigned int track_amount = tracks.size();
int height_of_one_line = std::min((m_lower_bound - m_over_body)/(track_amount+1),
@@ -185,7 +185,7 @@ void GPInfoDialog::addScreenshot()
m_screenshot_widget->m_h = m_area.getWidth()*3/8; // *(3/4)*(1/2)
}
Track* track = track_manager->getTrack(m_gp->getTrackNames()[0]);
Track* track = track_manager->getTrack(m_gp.getTrackNames()[0]);
m_screenshot_widget->m_properties[GUIEngine::PROP_ICON] = (track->getScreenshotFile().c_str());
m_screenshot_widget->setParent(m_irrlicht_window);
m_screenshot_widget->add();
@@ -203,7 +203,7 @@ void GPInfoDialog::addButtons()
SavedGrandPrix* saved_gp = SavedGrandPrix::getSavedGP( StateManager::get()
->getActivePlayerProfile(0)
->getUniqueID(),
m_gp->getId(),
m_gp.getId(),
race_manager->getDifficulty(),
race_manager->getNumberOfKarts(),
race_manager->getNumLocalPlayers());
@@ -250,7 +250,7 @@ void GPInfoDialog::addButtons()
void GPInfoDialog::onEnterPressedInternal()
{
// Save the GP id because dismiss() will destroy this instance
std::string gp_id = m_gp->getId();
std::string gp_id = m_gp.getId();
ModalDialog::dismiss();
// Disable accidentally unlocking of a challenge
PlayerManager::getCurrentPlayer()->setCurrentChallenge("");
@@ -264,7 +264,7 @@ GUIEngine::EventPropagation GPInfoDialog::processEvent(const std::string& event_
if (event_source == "start" || event_source == "continue")
{
// Save GP identifier, since dismiss will delete this object.
std::string gp_id = m_gp->getId();
std::string gp_id = m_gp.getId();
// Also create a copy of the string: it is a reference to data
// in a widget in the dialog - so if we call dismiss, this reference
// becomes invalid!
@@ -288,7 +288,7 @@ void GPInfoDialog::onUpdate(float dt)
m_curr_time += dt;
int frameAfter = (int)(m_curr_time / 1.5f);
const std::vector<std::string> tracks = m_gp->getTrackNames();
const std::vector<std::string> tracks = m_gp.getTrackNames();
if (frameAfter >= (int)tracks.size())
{
frameAfter = 0;

View File

@@ -20,7 +20,7 @@
#define HEADER_GP_INFO_DIALOG_HPP
#include "guiengine/modaldialog.hpp"
// Don't include grand_prix_data.hpp here or the compilation will fail
#include "race/grand_prix_data.hpp"
class GrandPrixData;
@@ -39,7 +39,9 @@ class GPInfoDialog : public GUIEngine::ModalDialog
protected: // Necessary for RandomGPInfoDialog
GUIEngine::IconButtonWidget* m_screenshot_widget;
float m_curr_time;
GrandPrixData* m_gp;
/** The grand prix data. */
GrandPrixData m_gp;
/** height of the separator over the body */
int m_over_body;

View File

@@ -33,11 +33,12 @@ using irr::gui::IGUIStaticText;
typedef GUIEngine::SpinnerWidget Spinner;
RandomGPInfoDialog::RandomGPInfoDialog()
{
// Defaults - loading selection from last time frrom a file would be better
m_number_of_tracks = 2; // We can assume that there are at least 2 standard tracks
m_trackgroup = "standard";
m_use_reverse = NO_REVERSE;
m_use_reverse = GrandPrixData::GP_NO_REVERSE;
doInit();
m_curr_time = 0.0f;
@@ -46,14 +47,7 @@ RandomGPInfoDialog::RandomGPInfoDialog()
m_over_body = m_area.getHeight()/7 + SPINNER_HEIGHT + 10; // 10px space
m_lower_bound = m_area.getHeight()*6/7;
// The GP manager is be used to make the GP live longer than this dialog
if (grand_prix_manager->m_random_gp)
{
delete grand_prix_manager->m_random_gp;
grand_prix_manager->m_random_gp = NULL;
}
m_gp = new GrandPrixData(m_number_of_tracks, m_trackgroup, m_use_reverse);
grand_prix_manager->m_random_gp = m_gp;
m_gp.createRandomGP(m_number_of_tracks, m_trackgroup, m_use_reverse);
addTitle();
addSpinners();
@@ -141,15 +135,17 @@ GUIEngine::EventPropagation RandomGPInfoDialog::processEvent(
{
if (eventSource == "start")
{
// Save GP data, since dismiss will delete this object.
GrandPrixData gp = m_gp;
ModalDialog::dismiss();
race_manager->startGP(grand_prix_manager->m_random_gp, false, false);
race_manager->startGP(&gp, false, false);
return GUIEngine::EVENT_BLOCK;
}
else if (eventSource == "Number of tracks")
{
// The old gp can be reused because there's only track deletion/adding
m_number_of_tracks = getWidget<Spinner>("Number of tracks")->getValue();
m_gp->changeTrackNumber(m_number_of_tracks, m_trackgroup);
m_gp.changeTrackNumber(m_number_of_tracks, m_trackgroup);
addTracks();
}
else if (eventSource == "Trackgroup")
@@ -171,22 +167,22 @@ GUIEngine::EventPropagation RandomGPInfoDialog::processEvent(
if (s->getValue() > (signed)max)
s->setValue(max);
delete m_gp;
m_gp = new GrandPrixData(m_number_of_tracks, m_trackgroup, m_use_reverse);
grand_prix_manager->m_random_gp = m_gp;
// Create a new (i.e. with new tracks) random gp, since the old
// tracks might not all belong to the newly selected group.
m_gp.createRandomGP(m_number_of_tracks, m_trackgroup, m_use_reverse,
/*new_tracks*/true);
addTracks();
}
else if (eventSource == "reverse")
{
Spinner* r = getWidget<Spinner>("reverse");
m_use_reverse = static_cast<REVERSED>(r->getValue());
m_gp->changeReverse(m_use_reverse);
m_use_reverse = static_cast<GrandPrixData::GPReverseType>(r->getValue());
m_gp.changeReverse(m_use_reverse);
}
else if (eventSource == "reload")
{
delete m_gp;
m_gp = new GrandPrixData(m_number_of_tracks, m_trackgroup, m_use_reverse);
grand_prix_manager->m_random_gp = m_gp;
m_gp.createRandomGP(m_number_of_tracks, m_trackgroup, m_use_reverse,
/*new_tracks*/true);
addTracks();
}

View File

@@ -24,17 +24,15 @@
class RandomGPInfoDialog : public GPInfoDialog
{
public:
enum REVERSED
{
NO_REVERSE = 0,
ALL_REVERSE = 1,
MIXED = 2
};
private:
/** How many tracks to pick. */
unsigned int m_number_of_tracks;
/** Name of the track group from which to pick tracks. */
std::string m_trackgroup;
REVERSED m_use_reverse;
/** How reverse settings should be determined. */
GrandPrixData::GPReverseType m_use_reverse;
public:
static const int SPINNER_HEIGHT = 40;

View File

@@ -108,7 +108,7 @@ RaceGUI::RaceGUI()
int n = race_manager->getNumberOfKarts();
m_animation_states.resize(n);
m_rank_animation_start_times.resize(n);
m_rank_animation_duration.resize(n);
m_last_ranks.resize(n);
} // RaceGUI
@@ -211,7 +211,7 @@ void RaceGUI::renderPlayerView(const Camera *camera, float dt)
if(!World::getWorld()->isRacePhase()) return;
drawPowerupIcons (kart, viewport, scaling);
drawSpeedEnergyRank(kart, viewport, scaling);
drawSpeedEnergyRank(kart, viewport, scaling, dt);
if (!m_is_tutorial)
drawLap(kart, viewport, scaling);
@@ -601,10 +601,18 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
} // drawEnergyMeter
//-----------------------------------------------------------------------------
/** Draws the rank of a player.
* \param kart The kart of the player.
* \param offset Offset of top left corner for this display (for splitscreen).
* \param min_ratio Scaling of the screen (for splitscreen).
* \param meter_width Width of the meter (inside which the rank is shown).
* \param meter_height Height of the meter (inside which the rank is shown).
* \param dt Time step size.
*/
void RaceGUI::drawRank(const AbstractKart *kart,
const core::vector2df &offset,
float min_ratio, int meter_width,
int meter_height)
int meter_height, float dt)
{
// Draw rank
WorldWithRank *world = dynamic_cast<WorldWithRank*>(World::getWorld());
@@ -617,10 +625,14 @@ void RaceGUI::drawRank(const AbstractKart *kart,
{
if (m_last_ranks[id] != kart->getPosition())
{
m_rank_animation_start_times[id] = world->getTime();
m_rank_animation_duration[id] = 0.0f;
m_animation_states[id] = AS_SMALLER;
}
}
else
{
m_rank_animation_duration[id] += dt;
}
float scale = 1.0f;
int rank = kart->getPosition();
@@ -628,13 +640,12 @@ void RaceGUI::drawRank(const AbstractKart *kart,
const float MIN_SHRINK = 0.3f;
if (m_animation_states[id] == AS_SMALLER)
{
scale = 1.0f - (world->getTime() - m_rank_animation_start_times[id])
/ DURATION;
scale = 1.0f - m_rank_animation_duration[id]/ DURATION;
rank = m_last_ranks[id];
if (scale < MIN_SHRINK)
{
m_animation_states[id] = AS_BIGGER;
m_rank_animation_start_times[id] = world->getTime();
m_rank_animation_duration[id] = 0.0f;
// Store the new rank
m_last_ranks[id] = kart->getPosition();
scale = MIN_SHRINK;
@@ -642,8 +653,7 @@ void RaceGUI::drawRank(const AbstractKart *kart,
}
else if (m_animation_states[id] == AS_BIGGER)
{
scale = (world->getTime() - m_rank_animation_start_times[id])
/ DURATION + MIN_SHRINK;
scale = m_rank_animation_duration[id] / DURATION + MIN_SHRINK;
rank = m_last_ranks[id];
if (scale > 1.0f)
{
@@ -680,10 +690,12 @@ void RaceGUI::drawRank(const AbstractKart *kart,
* \param kart The kart for which to show the data.
* \param viewport The viewport to use.
* \param scaling Which scaling to apply to the speedometer.
* \param dt Time step size.
*/
void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling)
const core::vector2df &scaling,
float dt)
{
float min_ratio = std::min(scaling.X, scaling.Y);
const int SPEEDWIDTH = 128;
@@ -712,7 +724,7 @@ void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart,
const float speed = kart->getSpeed();
drawRank(kart, offset, min_ratio, meter_width, meter_height);
drawRank(kart, offset, min_ratio, meter_width, meter_height, dt);
if(speed <=0) return; // Nothing to do if speed is negative.

View File

@@ -89,8 +89,8 @@ private:
enum AnimationState {AS_NONE, AS_SMALLER, AS_BIGGER};
std::vector<AnimationState> m_animation_states;
/** When the animation state was changed. */
std::vector<float> m_rank_animation_start_times;
/** How long the rank animation has been shown. */
std::vector<float> m_rank_animation_duration;
/** Stores the previous rank for each kart. Used for the rank animation. */
std::vector<int> m_last_ranks;
@@ -103,14 +103,14 @@ private:
const core::vector2df &scaling);
void drawSpeedEnergyRank (const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling);
const core::vector2df &scaling, float dt);
void drawLap (const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling);
void drawRank (const AbstractKart *kart,
const core::vector2df &offset,
float min_ratio, int meter_width,
int meter_height);
int meter_height, float dt);
/** Display items that are shown once only (for all karts). */
void drawGlobalMiniMap ();