Merge pull request #3 from supertuxkart/master

Update fork
This commit is contained in:
Alayan-stk-2 2018-04-13 21:57:35 +02:00 committed by GitHub
commit 607ee6ed75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 334 additions and 350 deletions

View File

@ -24,7 +24,11 @@ title_font, by Marianne Gagnon (Auria), released under CC-BY-SA 3+
screen*.png, by Marianne Gagnon (Auria), including elements from the public domain Tango icon set
Gauge and bar by Totoplus62, released under CC-BY-SA 3
speed.png by Alayan, with elements by Totoplus62, released under CC-BY-SA 3
speed*.png by Alayan, released under CC-0
gauge*.png by Alayan, released under CC-0
menu_story by tavariz91, released under CC-0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 126 KiB

View File

@ -11,13 +11,7 @@ layout(location = 1) in vec4 i_normal;
layout(location = 2) in vec4 i_color;
layout(location = 3) in vec2 i_uv;
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
layout(location = 12) in ivec2 i_misc_data;
@ -32,16 +26,14 @@ void main()
#if defined(Converts_10bit_Vector)
vec4 i_normal = convert10BitVector(i_normal_orig);
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec3 test = sin(wind_direction * (i_position.y * 0.1));
test += cos(wind_direction) * 0.7;
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin + test * i_color.r,
quaternion, i_scale.xyz, i_position);
vec3 world_normal = rotateVector(quaternion, i_normal.xyz);
i_rotation, i_scale.xyz, i_position);
vec3 world_normal = rotateVector(i_rotation, i_normal.xyz);
normal = (u_view_matrix * vec4(world_normal, 0.0)).xyz;
uv = i_uv;

View File

@ -5,13 +5,7 @@ layout(location = 0) in vec3 i_position;
layout(location = 2) in vec4 i_color;
layout(location = 3) in vec2 i_uv;
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
#stk_include "utils/get_world_location.vert"
@ -20,17 +14,10 @@ out vec2 uv;
void main()
{
#if defined(Converts_10bit_Vector)
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec3 test = sin(wind_direction * (i_position.y * 0.1));
test += cos(wind_direction) * 0.7;
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin + test * i_color.r,
quaternion, i_scale.xyz, i_position);
i_rotation, i_scale.xyz, i_position);
uv = i_uv;
gl_Position = u_shadow_projection_view_matrices[layer] * world_position;

View File

@ -17,13 +17,7 @@ layout(location = 5) in vec4 i_tangent;
layout(location = 6) in ivec4 i_joint;
layout(location = 7) in vec4 i_weight;
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
layout(location = 12) in ivec2 i_misc_data;
@ -39,7 +33,6 @@ void main()
#if defined(Converts_10bit_Vector)
vec4 i_normal = convert10BitVector(i_normal_orig);
vec4 i_tangent = convert10BitVector(i_tangent_orig);
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec4 idle_position = vec4(i_position, 1.0);
@ -104,12 +97,11 @@ void main()
skinned_position = mix(skinned_position, idle_position, step_mix);
skinned_normal = mix(skinned_normal, idle_normal, step_mix);
skinned_tangent = mix(skinned_tangent, idle_tangent, step_mix);
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
gl_Position = getWorldPosition(i_origin, quaternion, i_scale.xyz,
gl_Position = getWorldPosition(i_origin, i_rotation, i_scale.xyz,
skinned_position.xyz);
o_normal = normalize(rotateVector(quaternion, skinned_normal.xyz));
o_tangent = normalize(rotateVector(quaternion, skinned_tangent.xyz));
o_normal = normalize(rotateVector(i_rotation, skinned_normal.xyz));
o_tangent = normalize(rotateVector(i_rotation, skinned_tangent.xyz));
o_bitangent = cross(o_normal, o_tangent) * i_tangent.w;
}

View File

@ -17,13 +17,7 @@ layout(location = 5) in vec4 i_tangent;
#endif
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
layout(location = 11) in vec2 i_texture_trans;
layout(location = 12) in ivec2 i_misc_data;
@ -47,14 +41,12 @@ void main()
#if defined(Converts_10bit_Vector)
vec4 i_normal = convert10BitVector(i_normal_orig);
vec4 i_tangent = convert10BitVector(i_tangent_orig);
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 v_world_position = getWorldPosition(i_origin, quaternion, i_scale.xyz,
vec4 v_world_position = getWorldPosition(i_origin, i_rotation, i_scale.xyz,
i_position);
vec3 v_world_normal = rotateVector(quaternion, i_normal.xyz);
vec3 world_tangent = rotateVector(quaternion, i_tangent.xyz);
vec3 v_world_normal = rotateVector(i_rotation, i_normal.xyz);
vec3 world_tangent = rotateVector(i_rotation, i_tangent.xyz);
tangent = (u_view_matrix * vec4(world_tangent, 0.0)).xyz;
bitangent = (u_view_matrix *

View File

@ -3,13 +3,7 @@ uniform int layer;
layout(location = 0) in vec3 i_position;
layout(location = 3) in vec2 i_uv;
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
#stk_include "utils/get_world_location.vert"
@ -18,13 +12,7 @@ out vec2 uv;
void main()
{
#if defined(Converts_10bit_Vector)
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin, quaternion, i_scale.xyz,
vec4 world_position = getWorldPosition(i_origin, i_rotation, i_scale.xyz,
i_position);
uv = i_uv;
gl_Position = u_shadow_projection_view_matrices[layer] * world_position;

View File

@ -24,13 +24,7 @@ layout(location = 5) in vec4 i_tangent;
layout(location = 6) in ivec4 i_joint;
layout(location = 7) in vec4 i_weight;
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
layout(location = 11) in vec2 i_texture_trans;
layout(location = 12) in ivec2 i_misc_data;
@ -52,7 +46,6 @@ void main()
#if defined(Converts_10bit_Vector)
vec4 i_normal = convert10BitVector(i_normal_orig);
vec4 i_tangent = convert10BitVector(i_tangent_orig);
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec4 idle_position = vec4(i_position, 1.0);
@ -113,11 +106,10 @@ void main()
skinned_normal = joint_matrix * idle_normal;
skinned_tangent = joint_matrix * idle_tangent;
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin, quaternion, i_scale.xyz,
vec4 world_position = getWorldPosition(i_origin, i_rotation, i_scale.xyz,
skinned_position.xyz);
vec3 world_normal = rotateVector(quaternion, skinned_normal.xyz);
vec3 world_tangent = rotateVector(quaternion, skinned_tangent.xyz);
vec3 world_normal = rotateVector(i_rotation, skinned_normal.xyz);
vec3 world_tangent = rotateVector(i_rotation, skinned_tangent.xyz);
tangent = (u_view_matrix * vec4(world_tangent, 0.0)).xyz;
bitangent = (u_view_matrix *

View File

@ -11,13 +11,7 @@ layout(location = 3) in vec2 i_uv;
layout(location = 6) in ivec4 i_joint;
layout(location = 7) in vec4 i_weight;
layout(location = 8) in vec3 i_origin;
#if defined(Converts_10bit_Vector)
layout(location = 9) in vec4 i_rotation_orig;
#else
layout(location = 9) in vec4 i_rotation;
#endif
layout(location = 10) in vec4 i_scale;
layout(location = 12) in ivec2 i_misc_data;
@ -27,11 +21,6 @@ out vec2 uv;
void main()
{
#if defined(Converts_10bit_Vector)
vec4 i_rotation = convert10BitVector(i_rotation_orig);
#endif
vec4 idle_position = vec4(i_position, 1.0);
vec4 skinned_position = vec4(0.0);
int skinning_offset = i_misc_data.x;
@ -83,9 +72,7 @@ void main()
#endif
skinned_position = joint_matrix * idle_position;
vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w));
vec4 world_position = getWorldPosition(i_origin, quaternion, i_scale.xyz,
vec4 world_position = getWorldPosition(i_origin, i_rotation, i_scale.xyz,
skinned_position.xyz);
uv = i_uv;
gl_Position = u_shadow_projection_view_matrices[layer] * world_position;

View File

@ -1,12 +1,10 @@
<spshader>
<shader-info name="tillingMitigation" fallback-shader="solid" use-tangents="Y"/>
<first-pass vertex-shader="sp_pass.vert"
fragment-shader="sp_tilling_mitigation.frag"
skinned-mesh-shader="sp_skinning.vert">
fragment-shader="sp_tilling_mitigation.frag">
</first-pass>
<shadow-pass vertex-shader="sp_shadow.vert"
fragment-shader="white.frag"
skinned-mesh-shader="sp_skinning_shadow.vert">
fragment-shader="white.frag">
</shadow-pass>
<uniform-assigners>
<uniform-assigner name="layer"

View File

@ -1,12 +1,10 @@
<spshader>
<shader-info name="verticalMapping" fallback-shader="solid" use-tangents="Y"/>
<first-pass vertex-shader="sp_pass.vert"
fragment-shader="sp_vertical_mapping.frag"
skinned-mesh-shader="sp_skinning.vert">
fragment-shader="sp_vertical_mapping.frag">
</first-pass>
<shadow-pass vertex-shader="sp_shadow.vert"
fragment-shader="white.frag"
skinned-mesh-shader="sp_skinning_shadow.vert">
fragment-shader="white.frag">
</shadow-pass>
<uniform-assigners>
<uniform-assigner name="layer"

View File

@ -500,6 +500,11 @@ namespace UserConfigParams
PARAM_DEFAULT( BoolUserConfigParam(false, "screen_keyboard",
&m_multitouch_group,
"Enable screen keyboard.") );
PARAM_PREFIX BoolUserConfigParam m_hidpi_enabled
PARAM_DEFAULT( BoolUserConfigParam(false, "hidpi_enabled",
&m_multitouch_group,
"Enable high-DPI support.") );
// ---- GP start order
PARAM_PREFIX GroupUserConfigParam m_gp_start_order

View File

@ -18,6 +18,7 @@
#include "font/font_with_face.hpp"
#include "config/user_config.hpp"
#include "font/face_ttf.hpp"
#include "font/font_manager.hpp"
#include "font/font_settings.hpp"
@ -331,23 +332,24 @@ void FontWithFace::setDPI()
const int screen_width = irr_driver->getFrameSize().Width;
const int screen_height = irr_driver->getFrameSize().Height;
#ifdef ANDROID
float scale = screen_height / 480.0f;
m_face_dpi = getScalingFactorTwo() * getScalingFactorOne() * scale;
#else
float scale = std::max(0, screen_width - 640) / 564.0f;
// attempt to compensate for small screens
if (screen_width < 1200)
scale = std::max(0, screen_width - 640) / 750.0f;
if (screen_width < 900 || screen_height < 700)
scale = std::min(scale, 0.05f);
m_face_dpi = unsigned((getScalingFactorOne() + 0.2f * scale) *
getScalingFactorTwo());
#endif
if (UserConfigParams::m_hidpi_enabled)
{
float scale = screen_height / 480.0f;
m_face_dpi = getScalingFactorTwo() * getScalingFactorOne() * scale;
}
else
{
float scale = std::max(0, screen_width - 640) / 564.0f;
// attempt to compensate for small screens
if (screen_width < 1200)
scale = std::max(0, screen_width - 640) / 750.0f;
if (screen_width < 900 || screen_height < 700)
scale = std::min(scale, 0.05f);
m_face_dpi = unsigned((getScalingFactorOne() + 0.2f * scale) *
getScalingFactorTwo());
}
} // setDPI
// ----------------------------------------------------------------------------

View File

@ -31,13 +31,13 @@ namespace SP
class SPInstancedData
{
private:
char m_data[32];
char m_data[44];
public:
// ------------------------------------------------------------------------
SPInstancedData()
{
memset(m_data, 0, 32);
memset(m_data, 0, 44);
}
// ------------------------------------------------------------------------
SPInstancedData(const core::matrix4& model_mat,
@ -65,21 +65,19 @@ public:
rotation.W = -rotation.W;
}
memcpy(m_data, position, 12);
uint32_t _2101010 = normalizedSignedFloatsTo1010102(
{{ rotation.X, rotation.Y, rotation.Z, 0.0f }});
memcpy(m_data + 12, &_2101010, 4);
memcpy(m_data + 12, &rotation, 16);
short s[4] = { toFloat16(scale.X), toFloat16(scale.Y),
toFloat16(scale.Z), toFloat16(rotation.W) };
memcpy(m_data + 16, s, 8);
toFloat16(scale.Z), 0 };
memcpy(m_data + 28, s, 8);
short tm[2] =
{
short(texture_trans_x * 32767.0f),
short(texture_trans_y * 32767.0f)
};
memcpy(m_data + 24, tm, 4);
memcpy(m_data + 28, &skinning_offset, 2);
memcpy(m_data + 36, tm, 4);
memcpy(m_data + 40, &skinning_offset, 2);
short hue_packed = short(core::clamp(int(hue * 100.0f), 0, 100));
memcpy(m_data + 30, &hue_packed, 2);
memcpy(m_data + 42, &hue_packed, 2);
}
// ------------------------------------------------------------------------
const void* getData() const { return m_data; }

View File

@ -247,16 +247,16 @@ void SPMeshBuffer::recreateVAO(unsigned i)
#ifndef USE_GLES2
if (CVS->isARBBufferStorageUsable())
{
glBufferStorage(GL_ARRAY_BUFFER, m_gl_instance_size[i] * 32, NULL,
glBufferStorage(GL_ARRAY_BUFFER, m_gl_instance_size[i] * 44, NULL,
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
m_ins_dat_mapped_ptr[i] = glMapBufferRange(GL_ARRAY_BUFFER, 0,
m_gl_instance_size[i] * 32,
m_gl_instance_size[i] * 44,
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
}
else
#endif
{
glBufferData(GL_ARRAY_BUFFER, m_gl_instance_size[i] * 32, NULL,
glBufferData(GL_ARRAY_BUFFER, m_gl_instance_size[i] * 44, NULL,
GL_DYNAMIC_DRAW);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
@ -346,26 +346,23 @@ void SPMeshBuffer::recreateVAO(unsigned i)
glBindBuffer(GL_ARRAY_BUFFER, m_ins_array[i]);
// Origin
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 32, (void*)0);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 44, (void*)0);
glVertexAttribDivisorARB(8, 1);
// Rotation (quaternion .xyz)
// Rotation (quaternion in 4 32bit floats)
glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 4, GL_INT_2_10_10_10_REV,
GraphicsRestrictions::isDisabled
(GraphicsRestrictions::GR_CORRECT_10BIT_NORMALIZATION) ? GL_FALSE : GL_TRUE, 32,
(void*)12);
glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, 44, (void*)12);
glVertexAttribDivisorARB(9, 1);
// Scale (3 half floats and .w for quaternion .w)
// Scale (3 half floats and .w unused)
glEnableVertexAttribArray(10);
glVertexAttribPointer(10, 4, GL_HALF_FLOAT, GL_FALSE, 32, (void*)16);
glVertexAttribPointer(10, 4, GL_HALF_FLOAT, GL_FALSE, 44, (void*)28);
glVertexAttribDivisorARB(10, 1);
// Texture translation
glEnableVertexAttribArray(11);
glVertexAttribPointer(11, 2, GL_SHORT, GL_TRUE, 32, (void*)24);
glVertexAttribPointer(11, 2, GL_SHORT, GL_TRUE, 44, (void*)36);
glVertexAttribDivisorARB(11, 1);
// Misc data (skinning offset and hue change)
glEnableVertexAttribArray(12);
glVertexAttribIPointer(12, 2, GL_SHORT, 32, (void*)28);
glVertexAttribIPointer(12, 2, GL_SHORT, 44, (void*)40);
glVertexAttribDivisorARB(12, 1);
glBindVertexArray(0);
@ -400,15 +397,15 @@ void SPMeshBuffer::uploadInstanceData()
if (CVS->isARBBufferStorageUsable())
{
memcpy(m_ins_dat_mapped_ptr[i], m_ins_dat[i].data(),
m_ins_dat[i].size() * 32);
m_ins_dat[i].size() * 44);
}
else
{
glBindBuffer(GL_ARRAY_BUFFER, m_ins_array[i]);
void* ptr = glMapBufferRange(GL_ARRAY_BUFFER, 0,
m_ins_dat[i].size() * 32, GL_MAP_WRITE_BIT |
m_ins_dat[i].size() * 44, GL_MAP_WRITE_BIT |
GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
memcpy(ptr, m_ins_dat[i].data(), m_ins_dat[i].size() * 32);
memcpy(ptr, m_ins_dat[i].data(), m_ins_dat[i].size() * 44);
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}

View File

@ -184,7 +184,7 @@ void STKTextBillboard::init(core::stringw text, FontWithFace* face)
glGenBuffers(1, &m_instanced_array);
glBindBuffer(GL_ARRAY_BUFFER, m_instanced_array);
glBufferData(GL_ARRAY_BUFFER,
12 /*position*/ + 4/*quaternion*/ + 8 /*scale*/, NULL,
12 /*position*/ + 16/*quaternion*/ + 8 /*scale*/, NULL,
GL_DYNAMIC_DRAW);
for (auto& p : m_gl_tbs)
{
@ -213,20 +213,17 @@ void STKTextBillboard::init(core::stringw text, FontWithFace* face)
glBindBuffer(GL_ARRAY_BUFFER, m_instanced_array);
// Origin
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 24, (void*)0);
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, 36, (void*)0);
glVertexAttribDivisorARB(8, 1);
// Rotation (quaternion .xyz)
// Rotation (quaternion in 4 32bit floats)
glEnableVertexAttribArray(9);
glVertexAttribPointer(9, 4, GL_INT_2_10_10_10_REV,
GraphicsRestrictions::isDisabled
(GraphicsRestrictions::GR_CORRECT_10BIT_NORMALIZATION) ?
GL_FALSE : GL_TRUE, 24, (void*)12);
glVertexAttribPointer(9, 4, GL_FLOAT, GL_FALSE, 36, (void*)12);
glVertexAttribDivisorARB(9, 1);
// Scale (3 half floats and .w for quaternion .w)
// Scale (3 half floats and .w unused)
glEnableVertexAttribArray(10);
glVertexAttribPointer(10, 4, GL_HALF_FLOAT, GL_FALSE, 24, (void*)16);
glVertexAttribPointer(10, 4, GL_HALF_FLOAT, GL_FALSE, 36, (void*)28);
glVertexAttribDivisorARB(10, 1);
glBindVertexArray(0);

View File

@ -143,7 +143,7 @@ public:
{
#ifndef SERVER_ONLY
glBindBuffer(GL_ARRAY_BUFFER, m_instanced_array);
glBufferSubData(GL_ARRAY_BUFFER, 0, 24, m_instanced_data.getData());
glBufferSubData(GL_ARRAY_BUFFER, 0, 36, m_instanced_data.getData());
glBindBuffer(GL_ARRAY_BUFFER, 0);
#endif
}

View File

@ -15,6 +15,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config/user_config.hpp"
#include "font/font_manager.hpp"
#include "font/regular_face.hpp"
#include "graphics/irr_driver.hpp"
@ -151,9 +152,12 @@ void DynamicRibbonWidget::add()
unsigned int screen_height = irr_driver->getActualScreenSize().Height;
m_arrows_w = (int)(screen_height / 15);
m_arrows_w = std::max(m_arrows_w, 40);
#ifdef ANDROID
m_arrows_w *= 1.5f;
#endif
if (UserConfigParams::m_hidpi_enabled)
{
m_arrows_w *= 1.5f;
}
const int button_h = m_arrows_w;
// right arrow

View File

@ -49,6 +49,9 @@ void override_default_params()
UserConfigParams::m_screen_keyboard = true;
}
// Set bigger fonts and buttons
UserConfigParams::m_hidpi_enabled = true;
// It shouldn't matter, but STK is always run in fullscreen on android
UserConfigParams::m_fullscreen = true;

View File

@ -276,6 +276,7 @@ void RaceGUI::renderPlayerView(const Camera *camera, float dt)
drawLap(kart, viewport, scaling);
} // renderPlayerView
//-----------------------------------------------------------------------------
/** Shows the current soccer result.
*/
@ -460,7 +461,7 @@ void RaceGUI::drawGlobalMiniMap()
//-----------------------------------------------------------------------------
/** Energy meter that gets filled with nitro. This function is called from
* drawSpeedAndEnergy, which defines the correct position of the energy
* drawSpeedEnergyRank, which defines the correct position of the energy
* meter.
* \param x X position of the meter.
* \param y Y position of the meter.
@ -473,7 +474,7 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
{
#ifndef SERVER_ONLY
float min_ratio = std::min(scaling.X, scaling.Y);
const int GAUGEWIDTH = 78;
const int GAUGEWIDTH = 94;//same inner radius as the inner speedometer circle
int gauge_width = (int)(GAUGEWIDTH*min_ratio);
int gauge_height = (int)(GAUGEWIDTH*min_ratio);
@ -483,8 +484,8 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
else if (state > 1.0f) state = 1.0f;
core::vector2df offset;
offset.X = (float)(x-gauge_width) - 9.0f*scaling.X;
offset.Y = (float)y-30.0f*scaling.Y;
offset.X = (float)(x-gauge_width) - 9.5f*scaling.X;
offset.Y = (float)y-11.5f*scaling.Y;
// Background
@ -497,156 +498,58 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
NULL /* clip rect */, NULL /* colors */,
true /* alpha */);
// Target
// The positions for A to G are defined here.
// They are calculated from gauge_full.png
// They are further than the nitrometer farther position because
// the lines between them would otherwise cut through the outside circle.
const int vertices_count = 7;
if (race_manager->getCoinTarget() > 0)
{
float coin_target = (float)race_manager->getCoinTarget()
/ kart->getKartProperties()->getNitroMax();
video::S3DVertex vertices[5];
unsigned int count=2;
// There are three different polygons used, depending on
// the target. Consider the nitro-display texture:
//
// ----E-x--D (position of v,w,x vary depending on
// | nitro)
// A w
// |
// -B--v----C
// For nitro state <= r1 the triangle ABv is used, with v between B and C.
// For nitro state <= r2 the quad ABCw is used, with w between C and D.
// For nitro state > r2 the poly ABCDx is used, with x between D and E.
vertices[0].TCoords = core::vector2df(0.3f, 0.4f);
vertices[0].Pos = core::vector3df(offset.X+0.3f*gauge_width,
offset.Y-(1-0.4f)*gauge_height, 0);
vertices[1].TCoords = core::vector2df(0, 1.0f);
vertices[1].Pos = core::vector3df(offset.X, offset.Y, 0);
// The targets at which different polygons must be used.
const float r1 = 0.4f;
const float r2 = 0.65f;
if(coin_target<=r1)
{
count = 3;
float f = coin_target/r1;
vertices[2].TCoords = core::vector2df(0.08f + (1.0f-0.08f)*f, 1.0f);
vertices[2].Pos = core::vector3df(offset.X + (0.08f*gauge_width)
+ (1.0f - 0.08f)*f*gauge_width,
offset.Y,0);
}
else if(coin_target<=r2)
{
count = 4;
float f = (coin_target - r1)/(r2-r1);
vertices[2].TCoords = core::vector2df(1.0f, 1.0f);
vertices[2].Pos = core::vector3df(offset.X + gauge_width,
offset.Y, 0);
vertices[3].TCoords = core::vector2df(1.0f, (1.0f-f));
vertices[3].Pos = core::vector3df(offset.X + gauge_width,
offset.Y-f*gauge_height,0);
}
else
{
count = 5;
float f = (coin_target - r2)/(1-r2);
vertices[2].TCoords = core::vector2df(1.0, 1.0f);
vertices[2].Pos = core::vector3df(offset.X + gauge_width,
offset.Y, 0);
vertices[3].TCoords = core::vector2df(1.0,0);
vertices[3].Pos = core::vector3df(offset.X + gauge_width,
offset.Y-gauge_height, 0);
vertices[4].TCoords = core::vector2df(1.0f - f*(1-0.61f), 0);
vertices[4].Pos = core::vector3df(offset.X + gauge_width
- (1.0f-0.61f)*f*gauge_width,
offset.Y-gauge_height, 0);
}
short int index[5]={0};
for(unsigned int i=0; i<count; i++)
{
index[i]=count-i-1;
vertices[i].Color = video::SColor(255, 255, 255, 255);
}
video::SMaterial m;
m.setTexture(0, m_gauge_goal);
m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
irr_driver->getVideoDriver()->setMaterial(m);
draw2DVertexPrimitiveList(m_gauge_goal, vertices, count,
index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);
}
core::vector2df position[vertices_count];
position[0].X = 0.324f;//A
position[0].Y = 0.35f;//A
position[1].X = 0.029f;//B
position[1].Y = 0.918f;//B
position[2].X = 0.307f;//C
position[2].Y = 0.99f;//C
position[3].X = 0.589f;//D
position[3].Y = 0.932f;//D
position[4].X = 0.818f;//E
position[4].Y = 0.755f;//E
position[5].X = 0.945f;//F
position[5].Y = 0.497f;//F
position[6].X = 0.948f;//G
position[6].Y = 0.211f;//G
// The states at which different polygons must be used.
float threshold[vertices_count-2];
threshold[0] = 0.2f;
threshold[1] = 0.4f;
threshold[2] = 0.6f;
threshold[3] = 0.8f;
threshold[4] = 1.0f;
// Filling (current state)
if(state <=0) return; //Nothing to do
if (state > 0.0f)
{
video::S3DVertex vertices[5];
unsigned int count=2;
video::S3DVertex vertices[vertices_count];
// There are three different polygons used, depending on
// the nitro state. Consider the nitro-display texture:
//
// ----E-x--D (position of v,w,x vary depending on
// | nitro)
// A w
// |
// -B--v----C
// For nitro state <= r1 the triangle ABv is used, with v between B and C.
// For nitro state <= r2 the quad ABCw is used, with w between C and D.
// For nitro state > r2 the poly ABCDx is used, with x between D and E.
vertices[0].TCoords = core::vector2df(0.3f, 0.4f);
vertices[0].Pos = core::vector3df(offset.X+0.3f*gauge_width,
offset.Y-(1-0.4f)*gauge_height, 0);
vertices[1].TCoords = core::vector2df(0, 1.0f);
vertices[1].Pos = core::vector3df(offset.X, offset.Y, 0);
// The states at which different polygons must be used.
const float r1 = 0.4f;
const float r2 = 0.65f;
if(state<=r1)
//3D effect : wait for the full border to appear before drawing
for (int i=0;i<5;i++)
{
count = 3;
float f = state/r1;
vertices[2].TCoords = core::vector2df(0.08f + (1.0f-0.08f)*f, 1.0f);
vertices[2].Pos = core::vector3df(offset.X + (0.08f*gauge_width)
+ (1.0f - 0.08f)
*f*gauge_width,
offset.Y,0);
}
else if(state<=r2)
{
count = 4;
float f = (state - r1)/(r2-r1);
vertices[2].TCoords = core::vector2df(1.0f, 1.0f);
vertices[2].Pos = core::vector3df(offset.X + gauge_width,
offset.Y, 0);
vertices[3].TCoords = core::vector2df(1.0f, (1.0f-f));
vertices[3].Pos = core::vector3df(offset.X + gauge_width,
offset.Y-f*gauge_height,0);
}
else
{
count = 5;
float f = (state - r2)/(1-r2);
vertices[2].TCoords = core::vector2df(1.0, 1.0f);
vertices[2].Pos = core::vector3df(offset.X + gauge_width,
offset.Y, 0);
vertices[3].TCoords = core::vector2df(1.0,0);
vertices[3].Pos = core::vector3df(offset.X + gauge_width,
offset.Y-gauge_height, 0);
vertices[4].TCoords = core::vector2df(1.0f - f*(1-0.61f), 0);
vertices[4].Pos =
core::vector3df(offset.X + gauge_width - (1.0f-0.61f)*f*gauge_width,
offset.Y-gauge_height, 0);
if ((state-0.2f*i < 0.006f && state-0.2f*i >= 0.0f) || (0.2f*i-state < 0.003f && 0.2f*i-state >= 0.0f) )
{
state = 0.2f*i-0.003f;
break;
}
}
unsigned int count = computeVerticesForMeter(position, threshold, vertices, vertices_count,
state, gauge_width, gauge_height, offset);
short int index[5]={0};
for(unsigned int i=0; i<count; i++)
{
@ -666,6 +569,33 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart,
index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);
}
// Target
if (race_manager->getCoinTarget() > 0)
{
float coin_target = (float)race_manager->getCoinTarget()
/ kart->getKartProperties()->getNitroMax();
video::S3DVertex vertices[vertices_count];
unsigned int count = computeVerticesForMeter(position, threshold, vertices, vertices_count,
coin_target, gauge_width, gauge_height, offset);
short int index[5]={0};
for(unsigned int i=0; i<count; i++)
{
index[i]=count-i-1;
vertices[i].Color = video::SColor(255, 255, 255, 255);
}
video::SMaterial m;
m.setTexture(0, m_gauge_goal);
m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
irr_driver->getVideoDriver()->setMaterial(m);
draw2DVertexPrimitiveList(m_gauge_goal, vertices, count,
index, count-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);
}
#endif
} // drawEnergyMeter
@ -743,10 +673,10 @@ void RaceGUI::drawRank(const AbstractKart *kart,
oss << rank; // the current font has no . :( << ".";
core::recti pos;
pos.LowerRightCorner = core::vector2di(int(offset.X + 0.65f*meter_width),
int(offset.Y - 0.55f*meter_height));
pos.UpperLeftCorner = core::vector2di(int(offset.X + 0.65f*meter_width),
int(offset.Y - 0.55f*meter_height));
pos.LowerRightCorner = core::vector2di(int(offset.X + 0.64f*meter_width),
int(offset.Y - 0.49f*meter_height));
pos.UpperLeftCorner = core::vector2di(int(offset.X + 0.64f*meter_width),
int(offset.Y - 0.49f*meter_height));
static video::SColor color = video::SColor(255, 255, 255, 255);
font->draw(oss.str().c_str(), pos, color, true, true);
@ -803,65 +733,83 @@ void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart,
// Draw the actual speed bar (if the speed is >0)
// ----------------------------------------------
float speed_ratio = speed/KILOMETERS_PER_HOUR/110.0f;
float speed_ratio = speed/40.0f; //max displayed speed of 40
if(speed_ratio>1) speed_ratio = 1;
video::S3DVertex vertices[5];
unsigned int count;
// see computeVerticesForMeter for the detail of the drawing
// There are three different polygons used, depending on
// the speed ratio. Consider the speed-display texture:
//
// D----x----D (position of v,w,x vary depending on
// | speed)
// w A
// |
// C--v-B----E
// For speed ratio <= r1 the triangle ABv is used, with v between B and C.
// For speed ratio <= r2 the quad ABCw is used, with w between C and D.
// For speed ratio > r2 the poly ABCDx is used, with x between D and E.
const int vertices_count = 12;
video::S3DVertex vertices[vertices_count];
// The positions for A to J2 are defined here.
// They are calculated from speedometer.png
// A is the center of the speedometer's circle
// B2, C, D, E, F, G, H, I and J1 are points on the line
// from A to their respective 1/8th threshold division
// B2 is 36,9° clockwise from the vertical (on bottom-left)
// J1 s 70,7° clockwise from the vertical (on upper-right)
// B1 and J2 are used for correct display of the 3D effect
// They are 1,13* further than the speedometer farther position because
// the lines between them would otherwise cut through the outside circle.
core::vector2df position[vertices_count];
position[0].X = 0.546f;//A
position[0].Y = 0.566f;//A
position[1].X = 0.216f;//B1
position[1].Y = 1.036f;//B1
position[2].X = 0.201f;//B2
position[2].Y = 1.023f;//B2
position[3].X = 0.036f;//C
position[3].Y = 0.831f;//C
position[4].X = -0.029f;//D
position[4].Y = 0.589f;//D
position[5].X = 0.018f;//E
position[5].Y = 0.337f;//E
position[6].X = 0.169f;//F
position[6].Y = 0.134f;//F
position[7].X = 0.391f;//G
position[7].Y = 0.014f;//G
position[8].X = 0.642f;//H
position[8].Y = 0.0f;//H
position[9].X = 0.878f;//I
position[9].Y = 0.098f;//I
position[10].X = 1.046f;//J1
position[10].Y = 0.285f;//J1
position[11].X = 1.052f;//J2
position[11].Y = 0.297f;//J2
vertices[0].TCoords = core::vector2df(0.7f, 0.5f);
vertices[0].Pos = core::vector3df(offset.X+0.7f*meter_width,
offset.Y-0.5f*meter_height, 0);
vertices[1].TCoords = core::vector2df(0.52f, 1.0f);
vertices[1].Pos = core::vector3df(offset.X+0.52f*meter_width, offset.Y, 0);
// The speed ratios at which different triangles must be used.
// These values should be adjusted in case that the speed display
// is not linear enough. Mostly the speed values are below 0.7, it
// needs some zipper to get closer to 1.
const float r1 = 0.2f;
const float r2 = 0.6f;
if(speed_ratio<=r1)
float threshold[vertices_count-2];
threshold[0] = 0.00001f;//for the 3D margin
threshold[1] = 0.125f;
threshold[2] = 0.25f;
threshold[3] = 0.375f;
threshold[4] = 0.50f;
threshold[5] = 0.625f;
threshold[6] = 0.750f;
threshold[7] = 0.875f;
threshold[8] = 0.99999f;//for the 3D margin
threshold[9] = 1.0f;
//3D effect : wait for the full border to appear before drawing
for (int i=0;i<8;i++)
{
count = 3;
float f = speed_ratio/r1;
vertices[2].TCoords = core::vector2df(0.52f*(1-f), 1.0f);
vertices[2].Pos = core::vector3df(offset.X+ (0.52f*(1.0f-f)*meter_width),
offset.Y,0);
if ((speed_ratio-0.125f*i < 0.00625f && speed_ratio-0.125f*i >= 0.0f) || (0.125f*i-speed_ratio < 0.0045f && 0.125f*i-speed_ratio >= 0.0f) )
{
speed_ratio = 0.125f*i-0.0045f;
break;
}
}
else if(speed_ratio<=r2)
{
count = 4;
float f = (speed_ratio - r1)/(r2-r1);
vertices[2].TCoords = core::vector2df(0, 1.0f);
vertices[2].Pos = core::vector3df(offset.X, offset.Y, 0);
vertices[3].TCoords = core::vector2df(0, (1-f));
vertices[3].Pos = core::vector3df(offset.X, offset.Y-f*meter_height,0);
}
else
{
count = 5;
float f = (speed_ratio - r2)/(1-r2);
vertices[2].TCoords = core::vector2df(0, 1.0f);
vertices[2].Pos = core::vector3df(offset.X, offset.Y, 0);
vertices[3].TCoords = core::vector2df(0,0);
vertices[3].Pos = core::vector3df(offset.X, offset.Y-meter_height, 0);
vertices[4].TCoords = core::vector2df(f, 0);
vertices[4].Pos = core::vector3df(offset.X+f*meter_width,
offset.Y-meter_height, 0);
}
short int index[5];
unsigned int count = computeVerticesForMeter(position, threshold, vertices, vertices_count,
speed_ratio, meter_width, meter_height, offset);
short int index[vertices_count];
for(unsigned int i=0; i<count; i++)
{
index[i]=i;
@ -876,6 +824,100 @@ void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart,
#endif
} // drawSpeedEnergyRank
//-----------------------------------------------------------------------------
/** This function computes a polygon used for drawing the measure for a meter (speedometer, etc.)
* The variable measured by the meter is compared to the thresholds, and is then used to
* compute a point between the two points associated with the lower and upper threshold
* Then, a polygon is calculated linking all the previous points and the variable point
* which link back to the first point. This polygon is used for drawing.
*
* Consider the following example :
*
* A E
* -|
* x
* |
* -D-|
* -w-|
* |-C--|
* -B--v-|
*
* If the measure is inferior to the first threshold, the function will create a triangle ABv
* with the position of v varying proportionally on a line between B and C ;
* at B with 0 and at C when it reaches the first threshold.
* If the measure is between the first and second thresholds, the function will create a quad ABCw,
* with w varying in the same way than v.
* If the measure exceds the higher threshold, the function will return the poly ABCDE.
*
* \param position The relative positions of the vertices.
* \param threshold The thresholds at which the variable point switch from a segment to the next.
* The size of this array should be smaller by two than the position array.
* The last threshold determines the measure over which the meter is full
* \param vertices Where the results of the computation are put, for use by the calling function.
* \param vertices_count The maximum number of vertices to use. Should be superior or equal to the
* size of the arrays.
* \param measure The value of the variable measured by the meter.
* \param gauge_width The width of the meter
* \param gauge_height The height of the meter
* \param offset The offset to position the meter
*/
unsigned int RaceGUI::computeVerticesForMeter(core::vector2df position[], float threshold[], video::S3DVertex vertices[], unsigned int vertices_count,
float measure, int gauge_width, int gauge_height, core::vector2df offset)
{
//Nothing to draw ; we need at least three points to draw a triangle
if (vertices_count <= 2 || measure < 0)
{
return 0;
}
unsigned int count=2;
float f = 1.0f;
for (unsigned int i=2 ; i < vertices_count ; i++)
{
count++;
//Stop when we have found between which thresholds the measure is
if (measure < threshold[i-2])
{
if (i-2 == 0)
{
f = measure/threshold[i-2];
}
else
{
f = (measure - threshold[i-3])/(threshold[i-2]-threshold[i-3]);
}
break;
}
}
for (unsigned int i=0 ; i < count ; i++)
{
//if the measure don't fall in this segment, use the next predefined point
if (i<count-1 || (count == vertices_count && f == 1.0f))
{
vertices[i].TCoords = core::vector2df(position[i].X, position[i].Y);
vertices[i].Pos = core::vector3df(offset.X+position[i].X*gauge_width,
offset.Y-(1-position[i].Y)*gauge_height, 0);
}
//if the measure fall in this segment, compute the variable position
else
{
//f : the proportion of the next point. 1-f : the proportion of the previous point
vertices[i].TCoords = core::vector2df(position[i].X*(f)+position[i-1].X*(1.0f-f),
position[i].Y*(f)+position[i-1].Y*(1.0f-f));
vertices[i].Pos = core::vector3df(offset.X+ ((position[i].X*(f)+position[i-1].X*(1.0f-f))*gauge_width),
offset.Y-(((1-position[i].Y)*(f)+(1-position[i-1].Y)*(1.0f-f))*gauge_height),0);
}
}
//the count is used in the drawing functions
return count;
} //computeVerticesForMeter
//-----------------------------------------------------------------------------
/** Displays the rank and the lap of the kart.
* \param info Info object c

View File

@ -109,6 +109,12 @@ private:
float min_ratio, int meter_width,
int meter_height, float dt);
/* Helper function for drawing meters */
unsigned int computeVerticesForMeter(core::vector2df position[], float threshold[], video::S3DVertex vertices[],
unsigned int vertices_count, float measure, int gauge_width,
int gauge_height, core::vector2df offset);
/** Display items that are shown once only (for all karts). */
void drawGlobalMiniMap ();
void drawGlobalTimer ();

View File

@ -327,10 +327,10 @@ void RaceGUIMultitouch::draw(const AbstractKart* kart,
m_race_gui != NULL)
{
float scale = UserConfigParams::m_multitouch_scale *
(float)(irr_driver->getActualScreenSize().Height) / 720.0f;
(float)(irr_driver->getActualScreenSize().Height) / 760.0f;
m_race_gui->drawEnergyMeter(int(button->x + button->width * 1.15f),
int(button->y + button->height * 1.35f),
int(button->y + button->height * 1.15f),
kart, viewport,
core::vector2df(scale, scale));
}