diff --git a/data/gui/License.txt b/data/gui/License.txt index 6e3474c64..6de962e91 100644 --- a/data/gui/License.txt +++ b/data/gui/License.txt @@ -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 diff --git a/data/gui/gauge_empty.png b/data/gui/gauge_empty.png index acdf74b73..bb6a0427e 100644 Binary files a/data/gui/gauge_empty.png and b/data/gui/gauge_empty.png differ diff --git a/data/gui/gauge_full.png b/data/gui/gauge_full.png index 7db7e74d4..88787641c 100644 Binary files a/data/gui/gauge_full.png and b/data/gui/gauge_full.png differ diff --git a/data/gui/gauge_full_bright.png b/data/gui/gauge_full_bright.png index fe1c55256..8df866518 100644 Binary files a/data/gui/gauge_full_bright.png and b/data/gui/gauge_full_bright.png differ diff --git a/data/gui/gauge_goal.png b/data/gui/gauge_goal.png index 51184cf66..3b8d89aa6 100644 Binary files a/data/gui/gauge_goal.png and b/data/gui/gauge_goal.png differ diff --git a/data/gui/speed.png b/data/gui/speed.png index 5655239f1..61561a305 100644 Binary files a/data/gui/speed.png and b/data/gui/speed.png differ diff --git a/data/gui/speedback.png b/data/gui/speedback.png index 25a50110f..1ea1f4c45 100644 Binary files a/data/gui/speedback.png and b/data/gui/speedback.png differ diff --git a/data/gui/speedfore.png b/data/gui/speedfore.png index 2bf8e0fdc..3bc2fe5b3 100644 Binary files a/data/gui/speedfore.png and b/data/gui/speedfore.png differ diff --git a/data/shaders/sp_grass_pass.vert b/data/shaders/sp_grass_pass.vert index 074754bea..768932f08 100644 --- a/data/shaders/sp_grass_pass.vert +++ b/data/shaders/sp_grass_pass.vert @@ -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; diff --git a/data/shaders/sp_grass_shadow.vert b/data/shaders/sp_grass_shadow.vert index af7db4ef2..b77bbddfc 100644 --- a/data/shaders/sp_grass_shadow.vert +++ b/data/shaders/sp_grass_shadow.vert @@ -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; diff --git a/data/shaders/sp_normal_visualizer.vert b/data/shaders/sp_normal_visualizer.vert index 83849ec86..38504e47a 100644 --- a/data/shaders/sp_normal_visualizer.vert +++ b/data/shaders/sp_normal_visualizer.vert @@ -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; } diff --git a/data/shaders/sp_pass.vert b/data/shaders/sp_pass.vert index ec6d7dfe0..6f49469c8 100644 --- a/data/shaders/sp_pass.vert +++ b/data/shaders/sp_pass.vert @@ -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 * diff --git a/data/shaders/sp_shadow.vert b/data/shaders/sp_shadow.vert index ec6f3c7bb..e9c7c9262 100644 --- a/data/shaders/sp_shadow.vert +++ b/data/shaders/sp_shadow.vert @@ -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; diff --git a/data/shaders/sp_skinning.vert b/data/shaders/sp_skinning.vert index af8cf21a5..e8464dc13 100644 --- a/data/shaders/sp_skinning.vert +++ b/data/shaders/sp_skinning.vert @@ -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 * diff --git a/data/shaders/sp_skinning_shadow.vert b/data/shaders/sp_skinning_shadow.vert index 96d337fb7..7f76c01d2 100644 --- a/data/shaders/sp_skinning_shadow.vert +++ b/data/shaders/sp_skinning_shadow.vert @@ -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; diff --git a/data/shaders/sps_0_solid.xml b/data/shaders/sps_00_solid.xml similarity index 100% rename from data/shaders/sps_0_solid.xml rename to data/shaders/sps_00_solid.xml diff --git a/data/shaders/sps_1_normalmap.xml b/data/shaders/sps_01_normalmap.xml similarity index 100% rename from data/shaders/sps_1_normalmap.xml rename to data/shaders/sps_01_normalmap.xml diff --git a/data/shaders/sps_2_alphatest.xml b/data/shaders/sps_02_alphatest.xml similarity index 100% rename from data/shaders/sps_2_alphatest.xml rename to data/shaders/sps_02_alphatest.xml diff --git a/data/shaders/sps_3_decal.xml b/data/shaders/sps_03_decal.xml similarity index 100% rename from data/shaders/sps_3_decal.xml rename to data/shaders/sps_03_decal.xml diff --git a/data/shaders/sps_4_grass.xml b/data/shaders/sps_04_grass.xml similarity index 100% rename from data/shaders/sps_4_grass.xml rename to data/shaders/sps_04_grass.xml diff --git a/data/shaders/sps_5_unlit.xml b/data/shaders/sps_05_unlit.xml similarity index 100% rename from data/shaders/sps_5_unlit.xml rename to data/shaders/sps_05_unlit.xml diff --git a/data/shaders/sps_6_alphablend.xml b/data/shaders/sps_06_alphablend.xml similarity index 100% rename from data/shaders/sps_6_alphablend.xml rename to data/shaders/sps_06_alphablend.xml diff --git a/data/shaders/sps_7_additive.xml b/data/shaders/sps_07_additive.xml similarity index 100% rename from data/shaders/sps_7_additive.xml rename to data/shaders/sps_07_additive.xml diff --git a/data/shaders/sps_8_ghost.xml b/data/shaders/sps_08_ghost.xml similarity index 100% rename from data/shaders/sps_8_ghost.xml rename to data/shaders/sps_08_ghost.xml diff --git a/data/shaders/sps_9_dynamicNightBloom.xml b/data/shaders/sps_09_dynamic_night_bloom.xml similarity index 100% rename from data/shaders/sps_9_dynamicNightBloom.xml rename to data/shaders/sps_09_dynamic_night_bloom.xml diff --git a/data/shaders/sps_10_tillingMitigation.xml b/data/shaders/sps_10_tillingMitigation.xml index c9691c3a5..fd58f7546 100644 --- a/data/shaders/sps_10_tillingMitigation.xml +++ b/data/shaders/sps_10_tillingMitigation.xml @@ -1,12 +1,10 @@ + fragment-shader="sp_tilling_mitigation.frag"> + fragment-shader="white.frag"> + fragment-shader="sp_vertical_mapping.frag"> + fragment-shader="white.frag"> 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 // ---------------------------------------------------------------------------- diff --git a/src/graphics/sp/sp_instanced_data.hpp b/src/graphics/sp/sp_instanced_data.hpp index 9589769cc..a5328ec30 100644 --- a/src/graphics/sp/sp_instanced_data.hpp +++ b/src/graphics/sp/sp_instanced_data.hpp @@ -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; } diff --git a/src/graphics/sp/sp_mesh_buffer.cpp b/src/graphics/sp/sp_mesh_buffer.cpp index cd4fde30f..422dd5889 100644 --- a/src/graphics/sp/sp_mesh_buffer.cpp +++ b/src/graphics/sp/sp_mesh_buffer.cpp @@ -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); } diff --git a/src/graphics/stk_text_billboard.cpp b/src/graphics/stk_text_billboard.cpp index 765dd6631..b0e7102a0 100644 --- a/src/graphics/stk_text_billboard.cpp +++ b/src/graphics/stk_text_billboard.cpp @@ -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); diff --git a/src/graphics/stk_text_billboard.hpp b/src/graphics/stk_text_billboard.hpp index 8a1063050..94d56dbb6 100644 --- a/src/graphics/stk_text_billboard.hpp +++ b/src/graphics/stk_text_billboard.hpp @@ -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 } diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.cpp b/src/guiengine/widgets/dynamic_ribbon_widget.cpp index ae7cec447..ec7e2e38c 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.cpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.cpp @@ -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 diff --git a/src/main_android.cpp b/src/main_android.cpp index 0b33ab83b..b681472dc 100644 --- a/src/main_android.cpp +++ b/src/main_android.cpp @@ -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; diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index 8074054af..6414228b9 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -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; igetVideoDriver()->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; igetCoinTarget() > 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; igetVideoDriver()->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; igetActualScreenSize().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)); }