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

This commit is contained in:
nixt
2014-06-12 06:29:29 +05:30
34 changed files with 488 additions and 477 deletions

BIN
data/fonts/BigDigitFont.xml Normal file → Executable file

Binary file not shown.

BIN
data/fonts/sigmar0.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -12,6 +12,7 @@ uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 InverseViewMatrix;
uniform mat4 InverseProjectionMatrix;
uniform vec2 screen;
#else
layout (std140) uniform MatrixesData
{

View File

@@ -13,6 +13,7 @@ uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 InverseViewMatrix;
uniform mat4 InverseProjectionMatrix;
uniform vec2 screen;
#else
layout (std140) uniform MatrixesData
{

View File

@@ -248,6 +248,8 @@ public:
/** Returns true if a session was saved for this player. */
bool hasSavedSession() const { return m_saved_session; }
// ------------------------------------------------------------------------
StoryModeStatus* getStoryModeStatus() { return m_story_mode_status; }
// ------------------------------------------------------------------------
/** If a session was saved, return the id of the saved user. */
int getSavedUserId() const
{

View File

@@ -83,12 +83,16 @@ enum TypeFBO
FBO_COLORS,
FBO_LOG_LUMINANCE,
FBO_MLAA_COLORS,
FBO_MLAA_BLEND,
FBO_MLAA_TMP,
FBO_TMP1_WITH_DS,
FBO_TMP2_WITH_DS,
FBO_TMP4,
FBO_LINEAR_DEPTH,
FBO_HALF1,
FBO_HALF1_R,
FBO_HALF2,
FBO_HALF2_R,
FBO_QUARTER1,
FBO_QUARTER2,
FBO_EIGHTH1,
@@ -123,6 +127,8 @@ enum QueryPerf
Q_BLOOM,
Q_TONEMAP,
Q_MOTIONBLUR,
Q_MLAA,
Q_GUI,
Q_LAST
};
@@ -139,6 +145,8 @@ enum TypeRTT
RTT_HALF1,
RTT_HALF2,
RTT_HALF1_R,
RTT_HALF2_R,
RTT_QUARTER1,
RTT_QUARTER2,
@@ -165,6 +173,8 @@ enum TypeRTT
RTT_DISPLACE,
RTT_MLAA_COLORS,
RTT_MLAA_BLEND,
RTT_MLAA_TMP,
RTT_BLOOM_1024,
RTT_BLOOM_512,

View File

@@ -137,7 +137,7 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
node->get("fog", &m_fog );
node->get("mask", &m_mask );
node->get("gloss-map", &m_gloss_map );
node->get("water-splash", &m_water_splash );
node->get("jump", &m_is_jump_texture );
node->get("has-gravity", &m_has_gravity );

View File

@@ -224,6 +224,8 @@ private:
/** If m_splatting is true, indicates the fourth splatting texture */
std::string m_splatting_texture_4;
std::string m_gloss_map;
bool m_deprecated;
void init (unsigned int index);

View File

@@ -400,7 +400,9 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
assert(in_fbo.getWidth() == auxiliary.getWidth() && in_fbo.getHeight() == auxiliary.getHeight());
float inv_width = 1.0f / in_fbo.getWidth(), inv_height = 1.0f / in_fbo.getHeight();
{
#if WIN32
if (irr_driver->getGLSLVersion() < 430)
#endif
{
auxiliary.Bind();
glUseProgram(FullScreenShader::Gaussian17TapHShader::Program);
@@ -415,8 +417,10 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
glDrawArrays(GL_TRIANGLES, 0, 3);
}
#if WIN32
else
{
glUseProgram(FullScreenShader::ComputeGaussian17TapHShader::Program);
glBindImageTexture(0, in_fbo.getRTT()[0], 0, false, 0, GL_READ_ONLY, GL_R16F);
glBindImageTexture(1, auxiliary.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_R16F);
@@ -424,9 +428,12 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
glUniform1i(FullScreenShader::ComputeGaussian17TapHShader::uniform_dest, 1);
glDispatchCompute(in_fbo.getWidth() / 8, in_fbo.getHeight() / 8, 1);
}
#endif
}
{
#if WIN32
if (irr_driver->getGLSLVersion() < 430)
#endif
{
in_fbo.Bind();
glUseProgram(FullScreenShader::Gaussian17TapVShader::Program);
@@ -441,6 +448,7 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
glDrawArrays(GL_TRIANGLES, 0, 3);
}
#if WIN32
else
{
glUseProgram(FullScreenShader::ComputeGaussian17TapVShader::Program);
@@ -450,6 +458,7 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
glUniform1i(FullScreenShader::ComputeGaussian17TapVShader::uniform_dest, 1);
glDispatchCompute(in_fbo.getWidth() / 8, in_fbo.getHeight() / 8, 1);
}
#endif
}
}
@@ -639,7 +648,7 @@ 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();
irr_driver->getFBO(FBO_TMP1_WITH_DS).Bind();
irr_driver->getFBO(FBO_MLAA_TMP).Bind();
glEnable(GL_STENCIL_TEST);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
@@ -658,11 +667,11 @@ void PostProcessing::applyMLAA()
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// Pass 2: blend weights
irr_driver->getFBO(FBO_TMP2_WITH_DS).Bind();
irr_driver->getFBO(FBO_MLAA_BLEND).Bind();
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(FullScreenShader::MLAABlendWeightSHader::Program);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_TMP1), GL_LINEAR, GL_LINEAR);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_MLAA_TMP), GL_LINEAR, GL_LINEAR);
setTexture(1, getTextureGLuint(m_areamap), GL_NEAREST, GL_NEAREST);
FullScreenShader::MLAABlendWeightSHader::setUniforms(PIXEL_SIZE, 0, 1);
@@ -670,14 +679,14 @@ void PostProcessing::applyMLAA()
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Blit in to tmp1
FrameBuffer::Blit(irr_driver->getFBO(FBO_MLAA_COLORS), irr_driver->getFBO(FBO_TMP1_WITH_DS));
FrameBuffer::Blit(irr_driver->getFBO(FBO_MLAA_COLORS), irr_driver->getFBO(FBO_MLAA_TMP));
// Pass 3: gather
irr_driver->getFBO(FBO_MLAA_COLORS).Bind();
glUseProgram(FullScreenShader::MLAAGatherSHader::Program);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_TMP1), GL_NEAREST, GL_NEAREST);
setTexture(1, irr_driver->getRenderTargetTexture(RTT_TMP2), GL_NEAREST, GL_NEAREST);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_MLAA_TMP), GL_NEAREST, GL_NEAREST);
setTexture(1, irr_driver->getRenderTargetTexture(RTT_MLAA_BLEND), GL_NEAREST, GL_NEAREST);
FullScreenShader::MLAAGatherSHader::setUniforms(PIXEL_SIZE, 0, 1);
glBindVertexArray(FullScreenShader::MLAAGatherSHader::vao);
@@ -685,7 +694,6 @@ void PostProcessing::applyMLAA()
// Done.
glDisable(GL_STENCIL_TEST);
}
// ----------------------------------------------------------------------------
@@ -850,17 +858,19 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode)
PROFILER_POP_CPU_MARKER();
}
glEnable(GL_FRAMEBUFFER_SRGB);
irr_driver->getFBO(FBO_MLAA_COLORS).Bind();
renderPassThrough(in_fbo->getRTT()[0]);
out_fbo = &irr_driver->getFBO(FBO_MLAA_COLORS);
if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
{
PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00);
glEnable(GL_FRAMEBUFFER_SRGB);
irr_driver->getFBO(FBO_MLAA_COLORS).Bind();
renderPassThrough(in_fbo->getRTT()[0]);
glDisable(GL_FRAMEBUFFER_SRGB);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_MLAA));
applyMLAA();
out_fbo = &irr_driver->getFBO(FBO_MLAA_COLORS);
PROFILER_POP_CPU_MARKER();
}
glDisable(GL_FRAMEBUFFER_SRGB);
return out_fbo;
} // render

View File

@@ -187,13 +187,10 @@ void IrrDriver::renderGLSL(float dt)
{
FrameBuffer *fbo = m_post_processing->render(camnode);
if (!UserConfigParams::m_mlaa) // MLAA_COLORS already in srgb space
glEnable(GL_FRAMEBUFFER_SRGB);
if (irr_driver->getNormals())
irr_driver->getFBO(FBO_NORMAL_AND_DEPTHS).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
else if (irr_driver->getSSAOViz())
irr_driver->getFBO(FBO_SSAO).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
irr_driver->getFBO(FBO_HALF1_R).BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
else if (irr_driver->getRSM())
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -202,9 +199,6 @@ void IrrDriver::renderGLSL(float dt)
}
else
fbo->BlitToDefault(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
if (!UserConfigParams::m_mlaa)
glDisable(GL_FRAMEBUFFER_SRGB);
}
else
glDisable(GL_FRAMEBUFFER_SRGB);
@@ -235,10 +229,13 @@ void IrrDriver::renderGLSL(float dt)
PROFILER_POP_CPU_MARKER();
} // for i<getNumKarts
PROFILER_PUSH_CPU_MARKER("GUIEngine", 0x75, 0x75, 0x75);
// Either render the gui, or the global elements of the race gui.
GUIEngine::render(dt);
PROFILER_POP_CPU_MARKER();
{
ScopedGPUTimer Timer(getGPUTimer(Q_GUI));
PROFILER_PUSH_CPU_MARKER("GUIEngine", 0x75, 0x75, 0x75);
// Either render the gui, or the global elements of the race gui.
GUIEngine::render(dt);
PROFILER_POP_CPU_MARKER();
}
// Render the profiler
if(UserConfigParams::m_profiler_enabled)
@@ -600,7 +597,7 @@ void IrrDriver::renderSolidSecondPass()
GroupedSM<SM_UNTEXTURED>::reset();
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);
setTexture(2, m_rtts->getRenderTarget(RTT_HALF1_R), GL_LINEAR, GL_LINEAR);
{
@@ -1020,7 +1017,7 @@ void IrrDriver::renderLights(unsigned pointlightcount)
}
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
if (World::getWorld() && World::getWorld()->getTrack()->hasShadows() && SkyboxCubeMap && UserConfigParams::m_gi)
if (World::getWorld() && World::getWorld()->getTrack()->hasShadows() && SkyboxCubeMap)
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
// Render sunlight if and only if track supports shadow
@@ -1045,7 +1042,9 @@ void IrrDriver::renderSSAO()
glClear(GL_COLOR_BUFFER_BIT);
m_post_processing->renderSSAO();
// Blur it to reduce noise.
m_post_processing->renderGaussian17TapBlur(irr_driver->getFBO(FBO_SSAO), irr_driver->getFBO(FBO_TMP4));
FrameBuffer::Blit(m_rtts->getFBO(FBO_SSAO), m_rtts->getFBO(FBO_HALF1_R), GL_COLOR_BUFFER_BIT, GL_LINEAR);
m_post_processing->renderGaussian17TapBlur(irr_driver->getFBO(FBO_HALF1_R), irr_driver->getFBO(FBO_HALF2_R));
}
static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)

View File

@@ -30,7 +30,13 @@ static GLuint generateRTT3D(GLenum target, size_t w, size_t h, size_t d, GLint i
if (irr_driver->getGLSLVersion() < 420)
glTexImage3D(target, 0, internalFormat, w, h, d, 0, format, type, 0);
else
{
#if !defined(__linux__) || defined(GL_VERSION_4_2)
glTexStorage3D(target, 1, internalFormat, w, h, d);
#else
assert(false);
#endif
}
return result;
}
@@ -42,7 +48,13 @@ static GLuint generateRTT(const core::dimension2du &res, GLint internalFormat, G
if (irr_driver->getGLSLVersion() < 420)
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, res.Width, res.Height, 0, format, type, 0);
else
{
#if !defined(__linux__) || defined(GL_VERSION_4_2)
glTexStorage2D(GL_TEXTURE_2D, mipmaplevel, internalFormat, res.Width, res.Height);
#else
assert(false);
#endif
}
return result;
}
@@ -105,16 +117,20 @@ RTT::RTT(size_t width, size_t height)
RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, GL_RGBA16F, GL_RGBA, GL_FLOAT);
RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB8_ALPHA8, GL_BGR, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_MLAA_TMP] = generateRTT(res, GL_SRGB8_ALPHA8, GL_BGR, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_MLAA_BLEND] = generateRTT(res, GL_SRGB8_ALPHA8, GL_BGR, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_SSAO] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_DISPLACE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
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);
RenderTargetTextures[RTT_HALF1_R] = generateRTT(half, GL_R16F, GL_RED, GL_FLOAT);
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);
RenderTargetTextures[RTT_HALF2_R] = generateRTT(half, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_BLOOM_1024] = generateRTT(shadowsize0, GL_RGBA16F, GL_BGR, GL_FLOAT);
RenderTargetTextures[RTT_BLOOM_512] = generateRTT(shadowsize1, GL_RGBA16F, GL_BGR, GL_FLOAT);
@@ -150,6 +166,12 @@ RTT::RTT(size_t width, size_t height)
somevector.push_back(RenderTargetTextures[RTT_MLAA_COLORS]);
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_MLAA_BLEND]);
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_MLAA_TMP]);
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_TMP1]);
FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height));
somevector.clear();
@@ -165,9 +187,15 @@ RTT::RTT(size_t width, size_t height)
somevector.push_back(RenderTargetTextures[RTT_HALF1]);
FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_HALF1_R]);
FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_HALF2]);
FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_HALF2_R]);
FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_QUARTER1]);
FrameBuffers.push_back(new FrameBuffer(somevector, quarter.Width, quarter.Height));
somevector.clear();

View File

@@ -277,11 +277,15 @@ void Shaders::loadShaders()
FullScreenShader::DepthOfFieldShader::init();
FullScreenShader::FogShader::init();
FullScreenShader::Gaussian17TapHShader::init();
#if !defined(__linux__) || defined(GL_VERSION_4_3)
FullScreenShader::ComputeGaussian17TapHShader::init();
#endif
FullScreenShader::Gaussian3HBlurShader::init();
FullScreenShader::Gaussian3VBlurShader::init();
FullScreenShader::Gaussian17TapVShader::init();
#if !defined(__linux__) || defined(GL_VERSION_4_3)
FullScreenShader::ComputeGaussian17TapVShader::init();
#endif
FullScreenShader::Gaussian6HBlurShader::init();
FullScreenShader::Gaussian6VBlurShader::init();
FullScreenShader::GlowShader::init();
@@ -1197,6 +1201,7 @@ namespace MeshShader
GLuint SphereMapShader::attrib_normal;
GLuint SphereMapShader::uniform_MM;
GLuint SphereMapShader::uniform_IMM;
GLuint SphereMapShader::uniform_ambient;
GLuint SphereMapShader::TU_tex;
void SphereMapShader::init()
@@ -1210,6 +1215,7 @@ namespace MeshShader
attrib_normal = glGetAttribLocation(Program, "Normal");
uniform_MM = glGetUniformLocation(Program, "ModelMatrix");
uniform_IMM = glGetUniformLocation(Program, "InverseModelMatrix");
uniform_ambient = glGetUniformLocation(Program, "ambient");
GLuint uniform_tex = glGetUniformLocation(Program, "tex");
GLuint uniform_Albedo = glGetUniformLocation(Program, "Albedo");
GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap");
@@ -1230,12 +1236,13 @@ namespace MeshShader
glUseProgram(0);
}
void SphereMapShader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix)
void SphereMapShader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, const SColorf &ambient)
{
if (UserConfigParams::m_ubo_disabled)
bypassUBO(Program);
glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer());
glUniformMatrix4fv(uniform_IMM, 1, GL_FALSE, InverseModelMatrix.pointer());
glUniform3f(uniform_ambient, ambient.r, ambient.g, ambient.b);
}
GLuint SplattingShader::Program;
@@ -2441,6 +2448,7 @@ namespace FullScreenShader
vao = createFullScreenVAO(Program);
}
#if !defined(__linux__) || defined(GL_VERSION_4_3)
GLuint ComputeGaussian17TapHShader::Program;
GLuint ComputeGaussian17TapHShader::uniform_source;
GLuint ComputeGaussian17TapHShader::uniform_dest;
@@ -2451,7 +2459,7 @@ namespace FullScreenShader
uniform_source = glGetUniformLocation(Program, "source");
uniform_dest = glGetUniformLocation(Program, "dest");
}
#endif
GLuint Gaussian6HBlurShader::Program;
GLuint Gaussian6HBlurShader::uniform_tex;
GLuint Gaussian6HBlurShader::uniform_pixel;
@@ -2497,6 +2505,7 @@ namespace FullScreenShader
GLuint ComputeGaussian17TapVShader::Program;
GLuint ComputeGaussian17TapVShader::uniform_source;
GLuint ComputeGaussian17TapVShader::uniform_dest;
#if !defined(__linux__) || defined(GL_VERSION_4_3)
void ComputeGaussian17TapVShader::init()
{
Program = LoadProgram(
@@ -2504,7 +2513,7 @@ namespace FullScreenShader
uniform_source = glGetUniformLocation(Program, "source");
uniform_dest = glGetUniformLocation(Program, "dest");
}
#endif
GLuint Gaussian6VBlurShader::Program;
GLuint Gaussian6VBlurShader::uniform_tex;
GLuint Gaussian6VBlurShader::uniform_pixel;

View File

@@ -250,11 +250,11 @@ class SphereMapShader
public:
static GLuint Program;
static GLuint attrib_position, attrib_normal;
static GLuint uniform_MM, uniform_IMM;
static GLuint uniform_MM, uniform_IMM, uniform_ambient;
static GLuint TU_tex;
static void init();
static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix);
static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, const video::SColorf &ambient);
};
class SplattingShader

View File

@@ -249,7 +249,7 @@ void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelMatrix, const c
}
setTexture(MeshShader::SphereMapShader::TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
MeshShader::SphereMapShader::setUniforms(ModelMatrix, InverseModelMatrix);
MeshShader::SphereMapShader::setUniforms(ModelMatrix, InverseModelMatrix, irr_driver->getSceneManager()->getAmbientLight());
assert(mesh.vao_second_pass);
glBindVertexArray(mesh.vao_second_pass);
glDrawElements(ptype, count, itype, 0);
@@ -553,8 +553,11 @@ void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelView
tmpcol.getGreen() / 255.0f,
tmpcol.getBlue() / 255.0f);
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
if (mesh.textures[0] != NULL)
{
compressTexture(mesh.textures[0], true);
setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true);
}
glUseProgram(MeshShader::TransparentFogShader::Program);
MeshShader::TransparentFogShader::setUniforms(ModelViewProjectionMatrix, TextureMatrix, fogmax, startH, endH, start, end, col, Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition(), 0);

View File

@@ -140,7 +140,7 @@ void AbstractStateManager::pushScreen(Screen* screen)
void AbstractStateManager::replaceTopMostScreen(Screen* screen)
{
assert(m_game_mode != GAME);
//assert(m_game_mode != GAME);
// you need to close any dialog before calling this
assert(!ModalDialog::isADialogActive());
@@ -156,7 +156,8 @@ void AbstractStateManager::replaceTopMostScreen(Screen* screen)
assert(m_menu_stack.size() > 0);
// Send tear-down event to previous menu
getCurrentScreen()->tearDown();
if (getCurrentScreen() != NULL)
getCurrentScreen()->tearDown();
m_menu_stack[m_menu_stack.size()-1] = name;
switchToScreen(name.c_str());

View File

@@ -687,11 +687,11 @@ namespace GUIEngine
{
IGUIEnvironment* g_env;
Skin* g_skin = NULL;
ScalableFont* g_font;
ScalableFont* g_large_font;
ScalableFont* g_title_font;
ScalableFont* g_small_font;
ScalableFont* g_digit_font;
ScalableFont *g_font;
ScalableFont *g_large_font;
ScalableFont *g_title_font;
ScalableFont *g_small_font;
ScalableFont *g_digit_font;
IrrlichtDevice* g_device;
IVideoDriver* g_driver;
@@ -1062,7 +1062,7 @@ namespace GUIEngine
ScalableFont* sfont =
new ScalableFont(g_env,
file_manager->getAssetChecked(FileManager::FONT,
"StkFont.xml",true).c_str() );
"StkFont.xml",true) );
sfont->setScale(normal_text_scale);
sfont->setKerningHeight(-5);
g_font = sfont;
@@ -1070,13 +1070,13 @@ namespace GUIEngine
ScalableFont* digit_font =
new ScalableFont(g_env,
file_manager->getAssetChecked(FileManager::FONT,
"BigDigitFont.xml",true).c_str());
"BigDigitFont.xml",true));
digit_font->lazyLoadTexture(0); // make sure the texture is loaded for this one
digit_font->setMonospaceDigits(true);
g_digit_font = digit_font;
Private::font_height = g_font->getDimension( L"X" ).Height;
ScalableFont* sfont_larger = sfont->getHollowCopy();
sfont_larger->setScale(normal_text_scale*1.4f);
sfont_larger->setKerningHeight(-5);
@@ -1097,7 +1097,7 @@ namespace GUIEngine
new ScalableFont(g_env,
file_manager->getAssetChecked(FileManager::FONT,
"title_font.xml",
true).c_str() );
true) );
sfont2->m_fallback_font = sfont;
// Because the fallback font is much smaller than the title font:
sfont2->m_fallback_font_scale = 4.0f;

View File

@@ -21,9 +21,9 @@ namespace gui
{
//! constructor
ScalableFont::ScalableFont(IGUIEnvironment *env, const io::path& filename)
: Driver(0), SpriteBank(0), Environment(env), WrongCharacter(0),
MaxHeight(0), GlobalKerningWidth(0), GlobalKerningHeight(0)
ScalableFont::ScalableFont(IGUIEnvironment *env, const std::string &filename)
: Driver(0), SpriteBank(0), Environment(env), WrongCharacter(0),
MaxHeight(0), GlobalKerningWidth(0), GlobalKerningHeight(0)
{
#ifdef _DEBUG
setDebugName("ScalableFont");
@@ -44,7 +44,7 @@ ScalableFont::ScalableFont(IGUIEnvironment *env, const io::path& filename)
// don't grab environment, to avoid circular references
Driver = Environment->getVideoDriver();
SpriteBank = Environment->addEmptySpriteBank(filename);
SpriteBank = Environment->addEmptySpriteBank(io::path(filename.c_str()));
if (SpriteBank)
SpriteBank->grab();
}
@@ -676,7 +676,6 @@ void ScalableFont::draw(const core::stringw& text,
source,
clip,
color, true);
#ifdef FONT_DEBUG
driver->draw2DLine(core::position2d<s32>(dest.UpperLeftCorner.X, dest.UpperLeftCorner.Y),
core::position2d<s32>(dest.UpperLeftCorner.X, dest.LowerRightCorner.Y),

View File

@@ -72,7 +72,7 @@ public:
int m_fallback_kerning_width;
//! constructor
ScalableFont(IGUIEnvironment* env, const io::path& filename);
ScalableFont(IGUIEnvironment* env, const std::string &filename);
/** Creates a hollow copy of this font; i.e. the underlying font data is the *same* for
* both fonts. The advantage of doing this is that you can change "view" parameters

View File

@@ -308,6 +308,10 @@ void Flyable::getLinearKartItemIntersection (const Vec3 &origin,
float fire_th = (dx*dist - dz * sqrtf(dx*dx + dz*dz - dist*dist))
/ (dx*dx + dz*dz);
if(fire_th>1)
fire_th = 1.0f;
else if (fire_th<-1.0f)
fire_th = -1.0f;
fire_th = (((dist - dx*fire_th) / dz > 0) ? -acosf(fire_th)
: acosf(fire_th));
@@ -326,8 +330,10 @@ void Flyable::getLinearKartItemIntersection (const Vec3 &origin,
fire_th += M_PI;
//createPhysics offset
assert(sqrt(a*a+b*b)!=0);
time -= forw_offset / sqrt(a*a+b*b);
assert(time!=0);
*fire_angle = fire_th;
*up_velocity = (0.5f * time * gravity) + (dy / time)
+ (gy * target_kart->getSpeed());

View File

@@ -32,6 +32,7 @@
#include "physics/physics.hpp"
#include "states_screens/credits.hpp"
#include "states_screens/cutscene_gui.hpp"
#include "states_screens/feature_unlocked.hpp"
#include "states_screens/offline_kart_selection.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "tracks/track.hpp"
@@ -367,20 +368,26 @@ void CutsceneWorld::update(float dt)
}
}
bool isOver = (m_time > m_duration);
if (isOver && (s_use_duration || m_aborted))
{
GUIEngine::CutsceneScreen* cs = dynamic_cast<GUIEngine::CutsceneScreen*>(
GUIEngine::getCurrentScreen());
if (cs != NULL)
cs->onCutsceneEnd();
}
//bool isOver = (m_time > m_duration);
//if (isOver && (s_use_duration || m_aborted))
//{
// GUIEngine::CutsceneScreen* cs = dynamic_cast<GUIEngine::CutsceneScreen*>(
// GUIEngine::getCurrentScreen());
// if (cs != NULL)
// cs->onCutsceneEnd();
//}
} // update
//-----------------------------------------------------------------------------
void CutsceneWorld::enterRaceOverState()
{
GUIEngine::CutsceneScreen* cs = dynamic_cast<GUIEngine::CutsceneScreen*>(
GUIEngine::getCurrentScreen());
if (cs != NULL)
cs->onCutsceneEnd();
int partId = -1;
for (int i=0; i<(int)m_parts.size(); i++)
{
@@ -408,12 +415,52 @@ void CutsceneWorld::enterRaceOverState()
else if (m_parts.size() == 1 && m_parts[0] == "gpwin")
{
race_manager->exitRace();
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
if (race_manager->raceWasStartedFromOverworld())
OverWorld::enterOverWorld();
// 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::getCurrentPlayer()
->getRecentlyCompletedChallenges().size() > 0)
{
std::vector<const ChallengeData*> unlocked =
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
PlayerManager::getCurrentPlayer()->clearUnlocked();
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
race_manager->setNumPlayers(0);
race_manager->setNumLocalPlayers(0);
race_manager->startSingleRace("featunlocked", 999, false);
FeatureUnlockedCutScene* scene =
FeatureUnlockedCutScene::getInstance();
std::vector<std::string> parts;
parts.push_back("featunlocked");
((CutsceneWorld*)World::getWorld())->setParts(parts);
assert(unlocked.size() > 0);
scene->addTrophy(race_manager->getDifficulty());
scene->findWhatWasUnlocked(race_manager->getDifficulty());
StateManager::get()->replaceTopMostScreen(scene);
}
else
{
if (race_manager->raceWasStartedFromOverworld())
{
OverWorld::enterOverWorld();
}
else
{
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
// we assume the main menu was pushed before showing this menu
//StateManager::get()->popMenu();
}
}
}
// TODO: remove hardcoded knowledge of cutscenes, replace with scripting probably
else if (m_parts.size() == 1 && m_parts[0] == "gplose")
else if (m_parts.size() == 1 && m_parts[0] == "gplose")
{
race_manager->exitRace();
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
@@ -438,6 +485,28 @@ void CutsceneWorld::enterRaceOverState()
StateManager::get()->pushScreen( s );
}
}
// TODO: remove hardcoded knowledge of cutscenes, replace with scripting probably
else if (m_parts.size() == 1 && m_parts[0] == "featunlocked")
{
if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX)
{
// in GP mode, continue GP after viewing this screen
StateManager::get()->popMenu();
race_manager->next();
}
else
{
// back to menu or overworld
race_manager->exitRace();
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
//StateManager::get()->popMenu();
if (race_manager->raceWasStartedFromOverworld())
{
OverWorld::enterOverWorld();
}
}
}
else
{
race_manager->exitRace();

View File

@@ -794,6 +794,11 @@ void World::updateWorld(float dt)
return;
update(dt);
#ifdef DEBUG
assert(m_magic_number == 0xB01D6543);
#endif
if( (!isFinishPhase()) && isRaceOver())
{
enterRaceOverState();

View File

@@ -77,6 +77,6 @@ public:
}; // WorldWithRank
}; // WorldWithRank
#endif

View File

@@ -156,7 +156,7 @@ void FeatureUnlockedCutScene::onCutsceneEnd()
irr_driver->removeNode(m_avoid_irrlicht_bug);
m_avoid_irrlicht_bug = NULL;
#endif
m_unlocked_stuff.clearAndDeleteAll();
m_all_kart_models.clearAndDeleteAll();
@@ -353,7 +353,6 @@ void FeatureUnlockedCutScene::init()
void FeatureUnlockedCutScene::tearDown()
{
Screen::tearDown();
((CutsceneWorld*)World::getWorld())->abortCutscene();
} // tearDown
// ----------------------------------------------------------------------------
@@ -379,8 +378,6 @@ void FeatureUnlockedCutScene::onUpdate(float dt)
float progress_factor = (m_global_time - GIFT_EXIT_FROM) / (GIFT_EXIT_TO - GIFT_EXIT_FROM);
float smoothed_progress_factor = sin((progress_factor - 0.5f)*M_PI)/2.0f + 0.5f;
Log::info("smoothed_progress_factor", "%f", smoothed_progress_factor);
for (int n=0; n<unlockedStuffCount; n++)
{
if (m_unlocked_stuff[n].m_root_gift_node == NULL) continue;
@@ -546,7 +543,6 @@ void FeatureUnlockedCutScene::addUnlockedGP(const GrandPrixData* gp)
bool FeatureUnlockedCutScene::onEscapePressed()
{
((CutsceneWorld*)World::getWorld())->abortCutscene();
continueButtonPressed();
return false; // continueButtonPressed already pop'ed the menu
} // onEscapePressed
@@ -555,35 +551,20 @@ bool FeatureUnlockedCutScene::onEscapePressed()
void FeatureUnlockedCutScene::continueButtonPressed()
{
if (m_global_time < GIFT_EXIT_TO)
{
// If animation was not over yet, the button is used to skip the animation
while (m_global_time < GIFT_EXIT_TO)
{
// simulate all the steps of the animation until we reach the end
onUpdate(0.4f);
}
}
else
{
if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX)
{
// in GP mode, continue GP after viewing this screen
StateManager::get()->popMenu();
race_manager->next();
}
else
{
// back to menu or overworld
race_manager->exitRace();
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
if (race_manager->raceWasStartedFromOverworld())
{
OverWorld::enterOverWorld();
}
}
}
//if (m_global_time < GIFT_EXIT_TO)
//{
// // If animation was not over yet, the button is used to skip the animation
// while (m_global_time < GIFT_EXIT_TO)
// {
// // simulate all the steps of the animation until we reach the end
// onUpdate(0.4f);
// World::getWorld()->updateWorld(0.4f);
// }
//}
//else
//{
((CutsceneWorld*)World::getWorld())->abortCutscene();
//}
} // continueButtonPressed

View File

@@ -117,9 +117,20 @@ void GrandPrixLose::onCutsceneEnd()
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
if (unlocked.size() > 0)
{
race_manager->exitRace();
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
race_manager->setNumPlayers(0);
race_manager->setNumLocalPlayers(0);
race_manager->startSingleRace("featunlocked", 999, false);
FeatureUnlockedCutScene* scene =
FeatureUnlockedCutScene::getInstance();
std::vector<std::string> parts;
parts.push_back("featunlocked");
((CutsceneWorld*)World::getWorld())->setParts(parts);
scene->addTrophy(race_manager->getDifficulty());
scene->findWhatWasUnlocked(race_manager->getDifficulty());

View File

@@ -114,32 +114,6 @@ void GrandPrixWin::onCutsceneEnd()
m_podium_steps[0] = NULL;
m_podium_steps[1] = NULL;
m_podium_steps[2] = NULL;
// 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::getCurrentPlayer()
->getRecentlyCompletedChallenges().size() > 0)
{
std::vector<const ChallengeData*> unlocked =
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
PlayerManager::getCurrentPlayer()->clearUnlocked();
FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance();
assert(unlocked.size() > 0);
scene->addTrophy(race_manager->getDifficulty());
scene->findWhatWasUnlocked(race_manager->getDifficulty());
StateManager::get()->replaceTopMostScreen(scene);
}
else
{
// we assume the main menu was pushed before showing this menu
StateManager::get()->popMenu();
}
}
// -------------------------------------------------------------------------------------

View File

@@ -230,12 +230,14 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
*/
#if DEBUG_MENU_ITEM
if (selection == "options")
if (selection == "gpEditor")
{
// The DEBUG item
StoryModeStatus* sms = PlayerManager::getCurrentPlayer()->getStoryModeStatus();
sms->unlockFeature(const_cast<ChallengeStatus*>(sms->getChallengeStatus("gp1")),
RaceManager::DIFFICULTY_HARD);
// GP WIN
/*
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
@@ -246,9 +248,9 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
StateManager::get()->pushScreen(scene);
const std::string winners[] = { "elephpant", "nolok", "pidgin" };
scene->setKarts(winners);
*/
// GP Lose
/*
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
@@ -263,15 +265,26 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
//losers.push_back("wilber");
//losers.push_back("tux");
scene->setKarts(losers);
*/
/*
// FEATURE UNLOCKED
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
race_manager->setNumPlayers(0);
race_manager->setNumLocalPlayers(0);
race_manager->startSingleRace("featunlocked", 999, false);
FeatureUnlockedCutScene* scene =
FeatureUnlockedCutScene::getInstance();
FeatureUnlockedCutScene::getInstance();
std::vector<std::string> parts;
parts.push_back("featunlocked");
((CutsceneWorld*)World::getWorld())->setParts(parts);
scene->addTrophy(RaceManager::DIFFICULTY_EASY);
StateManager::get()->pushScreen(scene);
//StateManager::get()->pushScreen(scene);
static int i = 1;
i++;
@@ -295,7 +308,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
track_manager->getTrack("lighthouse")
->getScreenshotFile().c_str()));
textures.push_back(irr_driver->getTexture(
track_manager->getTrack("crescentcrossing")
track_manager->getTrack("startrack")
->getScreenshotFile().c_str()));
textures.push_back(irr_driver->getTexture(
track_manager->getTrack("sandtrack")
@@ -304,11 +317,11 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
track_manager->getTrack("snowmountain")
->getScreenshotFile().c_str()));
scene->addUnlockedPictures(textures, 1.0, 0.75, L"You did it");
scene->addUnlockedPictures(textures, 4.0, 3.0, L"You did it");
StateManager::get()->pushScreen(scene);
}
*/
*/
}
else
#endif

View File

@@ -89,40 +89,27 @@ RaceGUI::RaceGUI()
m_speed_bar_icon = material_manager->getMaterial("speedfore.png");
createMarkerTexture();
// Translate strings only one in constructor to avoid calling
// gettext in each frame.
//I18N: Shown at the end of a race
m_string_lap = _("Lap");
m_string_rank = _("Rank");
// Determine maximum length of the rank/lap text, in order to
// align those texts properly on the right side of the viewport.
gui::ScalableFont* font = GUIEngine::getFont();
m_rank_lap_width = font->getDimension(m_string_lap.c_str()).Width;
gui::ScalableFont* font = GUIEngine::getHighresDigitFont();
core::dimension2du area = font->getDimension(L"99:99:99");
m_timer_width = area.Width;
m_font_height = area.Height;
m_timer_width = font->getDimension(L"99:99:99").Width;
font = (race_manager->getNumLocalPlayers() > 2 ? GUIEngine::getSmallFont()
: GUIEngine::getFont());
int w;
if (race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER ||
race_manager->getMinorMode()==RaceManager::MINOR_MODE_3_STRIKES ||
race_manager->getNumLaps() > 9)
w = font->getDimension(L"99/99").Width;
m_lap_width = font->getDimension(L"99/99").Width;
else
w = font->getDimension(L"9/9").Width;
m_lap_width = font->getDimension(L"9/9").Width;
// In some split screen configuration the energy bar might be next
// to the lap display - so make the lap X/Y display large enough to
// leave space for the energy bar (16 pixels) and 10 pixels of space
// to the right (see drawEnergyMeter for details).
w += 16 + 10;
if(m_rank_lap_width < w) m_rank_lap_width = w;
w = font->getDimension(m_string_rank.c_str()).Width;
if(m_rank_lap_width < w) m_rank_lap_width = w;
// Technically we only need getNumLocalPlayers, but using the
// global kart id to find the data for a specific kart.
int n = race_manager->getNumberOfKarts();
m_animation_states.resize(n);
m_rank_animation_start_times.resize(n);
m_last_ranks.resize(n);
} // RaceGUI
//-----------------------------------------------------------------------------
@@ -130,6 +117,19 @@ RaceGUI::~RaceGUI()
{
} // ~Racegui
//-----------------------------------------------------------------------------
/** Reset the gui before a race. It initialised all rank animation related
* values back to the default.
*/
void RaceGUI::reset()
{
for(unsigned int i=0; i<race_manager->getNumberOfKarts(); i++)
{
m_animation_states[i] = AS_NONE;
m_last_ranks[i] = i+1;
}
} // reset
//-----------------------------------------------------------------------------
/** Render all global parts of the race gui, i.e. things that are only
* displayed once even in splitscreen.
@@ -201,24 +201,26 @@ void RaceGUI::renderPlayerView(const Camera *camera, float dt)
core::vector2df scaling = camera->getScaling();
const AbstractKart *kart = camera->getKart();
if(!kart) return;
drawPlungerInFace(camera, dt);
scaling *= viewport.getWidth()/800.0f; // scale race GUI along screen size
drawAllMessages (kart, viewport, scaling);
drawAllMessages(kart, viewport, scaling);
if(!World::getWorld()->isRacePhase()) return;
drawPowerupIcons (kart, viewport, scaling);
drawSpeedAndEnergy (kart, viewport, scaling);
drawPowerupIcons (kart, viewport, scaling);
drawSpeedEnergyRank(kart, viewport, scaling);
if (!m_is_tutorial)
drawRankLap (kart, viewport);
drawLap(kart, viewport, scaling);
RaceGUIBase::renderPlayerView(camera, dt);
} // renderPlayerView
//-----------------------------------------------------------------------------
/** Shows the current soccer result.
*/
void RaceGUI::drawScores()
{
SoccerWorld* soccerWorld = (SoccerWorld*)World::getWorld();
@@ -271,7 +273,8 @@ void RaceGUI::drawScores()
numLeader++;
offsetX += position.LowerRightCorner.X;
}
}
} // drawScores
//-----------------------------------------------------------------------------
/** Displays the racing time on the screen.s
*/
@@ -321,7 +324,9 @@ void RaceGUI::drawGlobalTimer()
pos += core::vector2d<s32>(0, UserConfigParams::m_height/2);
}
gui::ScalableFont* font = GUIEngine::getFont();
gui::ScalableFont* font = GUIEngine::getHighresDigitFont();
font->setShadow(video::SColor(255, 128, 0, 0));
font->setScale(1.0f);
font->draw(sw.c_str(), pos, time_color, false, false, NULL,
true /* ignore RTL */);
@@ -388,10 +393,10 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
const core::recti &viewport,
const core::vector2df &scaling)
{
float minRatio = std::min(scaling.X, scaling.Y);
float min_ratio = std::min(scaling.X, scaling.Y);
const int GAUGEWIDTH = 78;
int gauge_width = (int)(GAUGEWIDTH*minRatio);
int gauge_height = (int)(GAUGEWIDTH*minRatio);
int gauge_width = (int)(GAUGEWIDTH*min_ratio);
int gauge_height = (int)(GAUGEWIDTH*min_ratio);
float state = (float)(kart->getEnergy())
/ kart->getKartProperties()->getNitroMax();
@@ -404,14 +409,13 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
// Background
draw2DImage(m_gauge_empty,
core::rect<s32>((int)offset.X,
(int) offset.Y-gauge_height,
(int) offset.X + gauge_width,
(int)offset.Y) /* dest rect */,
core::rect<s32>(0, 0, 256, 256) /* source rect */,
NULL /* clip rect */, NULL /* colors */,
true /* alpha */);
draw2DImage(m_gauge_empty, core::rect<s32>((int)offset.X,
(int)offset.Y-gauge_height,
(int)offset.X + gauge_width,
(int)offset.Y) /* dest rect */,
core::rect<s32>(0, 0, 256, 256) /* source rect */,
NULL /* clip rect */, NULL /* colors */,
true /* alpha */);
// Target
@@ -581,22 +585,20 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, count,
index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);
}
} // drawEnergyMeter
//-----------------------------------------------------------------------------
void RaceGUI::drawSpeedAndEnergy(const AbstractKart* kart,
void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling)
{
float minRatio = std::min(scaling.X, scaling.Y);
float min_ratio = std::min(scaling.X, scaling.Y);
const int SPEEDWIDTH = 128;
int meter_width = (int)(SPEEDWIDTH*minRatio);
int meter_height = (int)(SPEEDWIDTH*minRatio);
int meter_width = (int)(SPEEDWIDTH*min_ratio);
int meter_height = (int)(SPEEDWIDTH*min_ratio);
drawEnergyMeter(viewport.LowerRightCorner.X ,
(int)(viewport.LowerRightCorner.Y),
@@ -604,8 +606,6 @@ void RaceGUI::drawSpeedAndEnergy(const AbstractKart* kart,
// First draw the meter (i.e. the background )
// -------------------------------------------------------------------------
core::vector2df offset;
offset.X = (float)(viewport.LowerRightCorner.X-meter_width) - 24.0f*scaling.X;
offset.Y = viewport.LowerRightCorner.Y-10.0f*scaling.Y;
@@ -699,40 +699,98 @@ void RaceGUI::drawSpeedAndEnergy(const AbstractKart* kart,
index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);
// Draw Speed in Numbers
// Draw rank
WorldWithRank *world = dynamic_cast<WorldWithRank*>(World::getWorld());
core::recti pos;
pos.UpperLeftCorner.X=(int)(offset.X + 0.5f*meter_width);
pos.UpperLeftCorner.Y=(int)(offset.Y - 0.62f*meter_height);
pos.LowerRightCorner.X=(int)(offset.X + 0.8f*meter_width);
pos.LowerRightCorner.Y=(int)(offset.X - 0.5f*meter_height);
if (world && world->displayRank())
{
core::recti pos;
pos.UpperLeftCorner.X = (int)(offset.X + 0.5f*meter_width);
pos.UpperLeftCorner.Y = (int)(offset.Y - 0.62f*meter_height);
pos.LowerRightCorner.X = (int)(offset.X + 0.8f*meter_width);
pos.LowerRightCorner.Y = (int)(offset.X - 0.5f*meter_height);
gui::ScalableFont* font;
gui::ScalableFont* font = GUIEngine::getHighresDigitFont();
if (pos.getWidth() > 55)
font = GUIEngine::getLargeFont();
else if (pos.getWidth() > 40)
font = GUIEngine::getFont();
else
font = GUIEngine::getSmallFont();
int id = kart->getWorldKartId();
static video::SColor color = video::SColor(255, 255, 255, 255);
std::ostringstream oss;
oss << (int)(speed*10);
if(m_animation_states[id] == AS_NONE)
{
if(m_last_ranks[id]!=kart->getPosition())
{
m_rank_animation_start_times[id] = world->getTime();
m_animation_states[id] = AS_SMALLER;
}
}
font->draw(oss.str().c_str(), pos, color);
float scale = 1.0f;
int rank = kart->getPosition();
const float DURATION = 0.8f;
if(m_animation_states[id] == AS_SMALLER)
{
scale = 1.0f - (world->getTime()-m_rank_animation_start_times[id])
/ DURATION;
rank = m_last_ranks[id];
if(scale<0)
{
m_animation_states[id] = AS_BIGGER;
m_rank_animation_start_times[id] = world->getTime();
// Store the new rank
m_last_ranks[id] = kart->getPosition();
scale = 0.0f;
}
}
else if(m_animation_states[id] == AS_BIGGER)
{
scale = (world->getTime() - m_rank_animation_start_times[id])
/ DURATION;
rank = m_last_ranks[id];
if(scale>1.0f)
{
m_animation_states[id] = AS_NONE;
scale = 1.0f;
}
}
}
else
{
m_last_ranks[id] = kart->getPosition();
}
font->setScale(min_ratio * scale);
font->setShadow(video::SColor(255, 128, 0, 0));
static video::SColor color = video::SColor(255, 255, 255, 255);
std::ostringstream oss;
oss << rank; // the current font has no . :( << ".";
pos.LowerRightCorner = core::vector2di(int(offset.X+0.6f*meter_width),
int(offset.Y-0.5f*meter_height));
pos.UpperLeftCorner = core::vector2di(int(offset.X+0.6f*meter_width),
int(offset.Y-0.5f*meter_height));
font->draw(oss.str().c_str(), pos, color, true, true);
font->setScale(1.0f);
}
} // drawSpeedEnergyRank
//-----------------------------------------------------------------------------
/** Displays the rank and the lap of the kart.
* \param info Info object c
*/
void RaceGUI::drawRankLap(const AbstractKart* kart,
const core::recti &viewport)
void RaceGUI::drawLap(const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling)
{
// Don't display laps or ranks if the kart has already finished the race.
if (kart->hasFinishedRace()) return;
World *world = World::getWorld();
if (!world->raceHasLaps()) return;
const int lap = world->getKartLaps(kart->getWorldKartId());
// don't display 'lap 0/..' at the start of a race
if (lap < 0 ) return;
core::recti pos;
pos.UpperLeftCorner.Y = viewport.UpperLeftCorner.Y;
@@ -742,52 +800,20 @@ void RaceGUI::drawRankLap(const AbstractKart* kart,
if(viewport.UpperLeftCorner.Y==0 &&
viewport.LowerRightCorner.X==UserConfigParams::m_width &&
race_manager->getNumPlayers()!=3)
pos.UpperLeftCorner.Y += 40;
pos.LowerRightCorner.Y = viewport.LowerRightCorner.Y;
pos.UpperLeftCorner.Y += m_font_height;
pos.LowerRightCorner.Y = viewport.LowerRightCorner.Y+20;
pos.UpperLeftCorner.X = viewport.LowerRightCorner.X
- m_rank_lap_width - 10;
- m_lap_width - 10;
pos.LowerRightCorner.X = viewport.LowerRightCorner.X;
gui::ScalableFont* font = (race_manager->getNumLocalPlayers() > 2
? GUIEngine::getSmallFont()
: GUIEngine::getFont());
int font_height = (int)(font->getDimension(L"X").Height);
gui::ScalableFont* font = GUIEngine::getHighresDigitFont();
static video::SColor color = video::SColor(255, 255, 255, 255);
WorldWithRank *world = (WorldWithRank*)(World::getWorld());
std::ostringstream out;
out << lap + 1 << "/" << race_manager->getNumLaps();
if (world->displayRank())
{
const int rank = kart->getPosition();
font = GUIEngine::getHighresDigitFont();
font->setScale(scaling.Y < 1.0f ? 0.5f: 1.0f);
font->draw(out.str().c_str(), pos, color);
font->setScale(1.0f);
font->draw(m_string_rank.c_str(), pos, color);
pos.UpperLeftCorner.Y += font_height;
pos.LowerRightCorner.Y += font_height;
char str[256];
const unsigned int kart_amount = world->getCurrentNumKarts();
sprintf(str, "%d/%d", rank, kart_amount);
font->draw(core::stringw(str).c_str(), pos, color);
pos.UpperLeftCorner.Y += font_height;
pos.LowerRightCorner.Y += font_height;
}
// Don't display laps in follow the leader mode
if(world->raceHasLaps())
{
const int lap = world->getKartLaps(kart->getWorldKartId());
// don't display 'lap 0/...'
if(lap>=0)
{
font->draw(m_string_lap.c_str(), pos, color);
char str[256];
sprintf(str, "%d/%d", lap+1, race_manager->getNumLaps());
pos.UpperLeftCorner.Y += font_height;
pos.LowerRightCorner.Y += font_height;
font->draw(core::stringw(str).c_str(), pos, color);
pos.UpperLeftCorner.Y += font_height;
pos.LowerRightCorner.Y += font_height;
}
}
} // drawRankLap
} // drawLap

View File

@@ -44,12 +44,6 @@ private:
Material *m_speed_meter_icon;
Material *m_speed_bar_icon;
/** Translated string 'lap' displayed every frame. */
core::stringw m_string_lap;
/** Translated string 'rank' displayed every frame. */
core::stringw m_string_rank;
// Minimap related variables
// -------------------------
/** The mini map of the track. */
@@ -81,25 +75,38 @@ private:
/** Distance of map from bottom of screen. */
int m_map_bottom;
/** Maximum string length of 'rank', 'lap', '99/99'. Used to position
* the rank/lap text correctly close to the right border. */
int m_rank_lap_width;
/** Maximum lap display length (either 9/9 or 99/99). */
int m_lap_width;
/** Maximum string length for the timer */
int m_timer_width;
/** Height of the digit font. */
int m_font_height;
bool m_is_tutorial;
/** Animation state: none, getting smaller (old value),
* getting bigger (new number). */
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;
/** Stores the previous rank for each kart. Used for the rank animation. */
std::vector<int> m_last_ranks;
bool m_is_tutorial;
/* Display informat for one player on the screen. */
void drawEnergyMeter (int x, int y, const AbstractKart *kart,
const core::recti &viewport,
const core::vector2df &scaling);
void drawSpeedAndEnergy (const AbstractKart* kart,
void drawSpeedEnergyRank (const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling);
void drawLap (const AbstractKart* kart,
const core::recti &viewport,
const core::vector2df &scaling);
void drawRankLap (const AbstractKart* kart,
const core::recti &viewport);
/** Display items that are shown once only (for all karts). */
void drawGlobalMiniMap ();
@@ -111,6 +118,7 @@ public:
RaceGUI();
~RaceGUI();
virtual void reset();
virtual void renderGlobal(float dt);
virtual void renderPlayerView(const Camera *camera, float dt);

View File

@@ -273,14 +273,27 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
}
else
{
FeatureUnlockedCutScene* scene =
FeatureUnlockedCutScene::getInstance();
scene->addTrophy(race_manager->getDifficulty());
scene->findWhatWasUnlocked(race_manager->getDifficulty());
StateManager::get()->popMenu();
World::deleteWorld();
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
race_manager->setNumPlayers(0);
race_manager->setNumLocalPlayers(0);
race_manager->startSingleRace("featunlocked", 999, false);
FeatureUnlockedCutScene* scene =
FeatureUnlockedCutScene::getInstance();
scene->addTrophy(race_manager->getDifficulty());
scene->findWhatWasUnlocked(race_manager->getDifficulty());
StateManager::get()->pushScreen(scene);
race_manager->setAIKartOverride("");
std::vector<std::string> parts;
parts.push_back("featunlocked");
((CutsceneWorld*)World::getWorld())->setParts(parts);
}
return;
}
@@ -364,7 +377,7 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
// FIXME: why is this call necessary here? tearDown should be
// automatically called when the screen is left. Note that the
// NetworkKartSelectionScreen::getInstance()->tearDown(); caused #1347
KartSelectionScreen::getRunningInstance()->tearDown();
KartSelectionScreen::getRunningInstance()->tearDown();
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
if (race_manager->raceWasStartedFromOverworld())

View File

@@ -1,204 +0,0 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/register_screen.hpp"
#include "audio/sfx_manager.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "guiengine/widgets/text_box_widget.hpp"
#include "online/current_user.hpp"
#include "online/messages.hpp"
#include "states_screens/dialogs/registration_dialog.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "states_screens/guest_login_screen.hpp"
#include "states_screens/login_screen.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/log.hpp"
#include "utils/translation.hpp"
using namespace GUIEngine;
using namespace Online;
DEFINE_SCREEN_SINGLETON( RegisterScreen );
// -----------------------------------------------------------------------------
RegisterScreen::RegisterScreen() : Screen("online/register.stkgui")
{
} // RegisterScreen
// -----------------------------------------------------------------------------
void RegisterScreen::init()
{
// Make sure this tab is actually focused.
RibbonWidget* tabs = this->getWidget<RibbonWidget>("login_tabs");
if (tabs) tabs->select( "tab_register", PLAYER_ID_GAME_MASTER );
TextBoxWidget *password_widget = getWidget<TextBoxWidget>("password");
password_widget->setPasswordBox(true,L'*');
password_widget = getWidget<TextBoxWidget>("password_confirm");
password_widget->setPasswordBox(true,L'*');
m_info_widget = getWidget<LabelWidget>("info");
assert(m_info_widget);
m_options_widget = getWidget<RibbonWidget>("options");
assert(m_options_widget);
m_signup_request = NULL;
m_info_message_shown = false;
} // init
// -----------------------------------------------------------------------------
void RegisterScreen::doRegister()
{
core::stringw username = getWidget<TextBoxWidget>("username")->getText().trim();
core::stringw password = getWidget<TextBoxWidget>("password")->getText().trim();
core::stringw password_confirm = getWidget<TextBoxWidget>("password_confirm")
->getText().trim();
core::stringw email = getWidget<TextBoxWidget>("email")->getText().trim();
core::stringw email_confirm = getWidget<TextBoxWidget>("email_confirm")
->getText().trim();
m_info_widget->setErrorColor();
if (password != password_confirm)
{
m_info_widget->setText(_("Passwords don't match!"), false);
}
else if (email != email_confirm)
{
m_info_widget->setText(_("Emails don't match!"), false);
}
else if (username.size() < 4 || username.size() > 30)
{
m_info_widget->setText(_("Username has to be between 4 and 30 characters long!"), false);
}
else if (password.size() < 8 || password.size() > 30)
{
m_info_widget->setText(_("Password has to be between 8 and 30 characters long!"), false);
}
else if (email.size() < 4 || email.size() > 50)
{
m_info_widget->setText(_("Email has to be between 4 and 50 characters long!"), false);
}
else
{
m_info_widget->setDefaultColor();
new MessageDialog(
_("=== STK Terms and Conditions ===\n"
"You must agree to these terms in order to register an account for STK."
"Still needs actual content. Preferably in an XML document which can then be parsed to be put here.\n\n"
"By checking the box below, you are confirming that you understand these terms."
"If you have any questions or comments regarding these terms,"
"one of the members of the development team would gladly assist you."
),
MessageDialog::MESSAGE_DIALOG_OK_CANCEL, NULL, false);
return;
}
sfx_manager->quickSound( "anvil" );
} // doRegister
// -----------------------------------------------------------------------------
/** Called from the registration info dialog when 'accept' is clicked.
*/
void RegisterScreen::acceptTerms()
{
m_options_widget->setDeactivated();
core::stringw username = getWidget<TextBoxWidget>("username")->getText().trim();
core::stringw password = getWidget<TextBoxWidget>("password")->getText().trim();
core::stringw password_confirm= getWidget<TextBoxWidget>("password_confirm")->getText().trim();
core::stringw email = getWidget<TextBoxWidget>("email")->getText().trim();
m_signup_request = CurrentUser::get()->requestSignUp(username, password,
password_confirm, email);
} // acceptTerms
// -----------------------------------------------------------------------------
void RegisterScreen::onUpdate(float dt, irr::video::IVideoDriver*)
{
if(m_signup_request)
{
if(!m_options_widget->isActivated())
m_info_widget->setText(Messages::validatingInfo(), false);
if(m_signup_request->isDone())
{
if(m_signup_request->isSuccess())
{
new MessageDialog(
_("You will receive an email with further instructions "
"regarding account activation. Please be patient and be "
"sure to check your spam folder."),
MessageDialog::MESSAGE_DIALOG_OK, NULL, false);
// Set the flag that the message was shown, which will triger
// a pop of this menu and so a return to the main menu
m_info_message_shown = true;
}
else
{
// Error signing up, display error message
m_info_widget->setText(m_signup_request->getInfo(), false);
}
delete m_signup_request;
m_signup_request = NULL;
m_options_widget->setActivated();
}
}
else if(m_info_message_shown && !ModalDialog::isADialogActive())
{
// Once the info message was shown (signup was successful), but the
// message has been gone (user clicked on OK), go back to main menu
StateManager::get()->popMenu();
}
} // onUpdate
// -----------------------------------------------------------------------------
void RegisterScreen::eventCallback(Widget* widget, const std::string& name,
const int playerID)
{
if (name == "login_tabs")
{
const std::string selection =
((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER);
StateManager *sm = StateManager::get();
if (selection == "tab_login")
sm->replaceTopMostScreen(LoginScreen::getInstance());
else if (selection == "tab_guest_login")
sm->replaceTopMostScreen(GuestLoginScreen::getInstance());
}
else if (name=="options")
{
const std::string button = m_options_widget
->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if(button=="next")
{
doRegister();
}
else if(button=="cancel")
StateManager::get()->escapePressed();
}
} // eventCallback
// -----------------------------------------------------------------------------

View File

@@ -407,7 +407,9 @@ void Profiler::draw()
"Godrays",
"Bloom",
"Tonemap",
"Motion Blur"
"Motion Blur",
"MLAA",
"GUI",
};
std::ostringstream oss;
oss << Phase[hovered_gpu_marker] << " : " << hovered_gpu_marker_elapsed << " us";

View File

@@ -9,6 +9,10 @@ const int fontsizes[] = {4,6,8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,56,68,72
char bUsed[0x10000]={0};
/** True if pot files where given, which indicates that Asian fonts
* are to be created, and an offset needs to be used for the index. */
bool has_pot_files = false;
inline u32 getTextureSizeFromSurfaceSize(u32 size)
{
u32 ts = 0x01;
@@ -19,6 +23,7 @@ inline u32 getTextureSizeFromSurfaceSize(u32 size)
}
bool LoadPoFiles(const char* sListFileName){
has_pot_files = true;
char s[1024];
std::ifstream fin(sListFileName);
if(!fin){
@@ -57,6 +62,17 @@ bool LoadPoFiles(const char* sListFileName){
return true;
}
// ----------------------------------------------------------------------------
/** Set all characters in the given character string to be used. */
bool setUsedCharacters(const char* characters)
{
int n = strlen(characters);
for(int i=0; i<n; i++)
bUsed[characters[i]] = true;
return true;
} // setUsedCharacters
// ----------------------------------------------------------------------------
// windows specific
#ifdef _IRR_WINDOWS_
@@ -762,7 +778,8 @@ bool CFontTool::saveBitmapFont(const c8 *filename, const c8* format)
writer->writeLineBreak();
// write images and link to them
u32 offset_for_asian_fonts=100;
// Only use the offset if Asian fonts are created.
u32 offset_for_asian_fonts=has_pot_files ? 100 : 0;
for (u32 i=0; i<currentImages.size(); ++i)
{
imagename = filename;

View File

@@ -21,6 +21,7 @@
#endif
bool LoadPoFiles(const char* sListFileName);
bool setUsedCharacters(const char* characters);
namespace irr {
class CFontTool : public irr::IReferenceCounted

View File

@@ -412,7 +412,7 @@ void createGUI(IrrlichtDevice* device, CFontTool* fc)
//new
env->addCheckBox(false, core::rect<s32>(xp,yp,xp+150,yp+h),win, 201, L"Export used characters only")->setEnabled(false);
env->addCheckBox(false, core::rect<s32>(xp,yp,xp+150,yp+h),win, 201, L"Export used characters only")->setChecked(false);
yp += (s32)(h*1.5f);
env->addCheckBox(false, core::rect<s32>(xp,yp,xp+150,yp+h),win, 202, L"Exclude basic latin characters");
@@ -512,10 +512,34 @@ int main(int argc,char **argv)
createGUI(device, fc);
//new
if(argc>1 && LoadPoFiles(argv[1])){
device->getGUIEnvironment()->getRootGUIElement()->getElementFromId(201,true)->setEnabled(true);
}
for(int i=1; i<argc; i++)
{
if(!strcmp(argv[i],"-c") && i<argc-1)
{
i++;
if(setUsedCharacters(argv[i]))
{
IGUICheckBox *box =
dynamic_cast<IGUICheckBox*>(device->getGUIEnvironment()
->getRootGUIElement()
->getElementFromId(201, true));
box->setChecked(true);
}
}
else
{
// Old style: just a single parameter, assume it's a file name with pot files in it
if(LoadPoFiles(argv[i]))
{
IGUICheckBox *box =
dynamic_cast<IGUICheckBox*>(device->getGUIEnvironment()
->getRootGUIElement()
->getElementFromId(201, true));
box->setChecked(true);
}
}
} // for i <argc
while(device->run())
{