mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
Loading screen overhaul POC
The loading screen has been significantly changed: - The background image is now properly picked randomly instead of taking the `textures/logo.bmp` file, prepended by an external program such as Rainsted/Starter. - The progress bar has been moved from a floating window to a thin green line at the bottom of the loading screen. - The log window is now hidden by default. It can be turned on by setting `loadinglog` to `true` in `eu07.ini`. - There is an animated wheel icon on the loading screen, and a trivia text is displayed. New translation key: - `"Did you know"` TODO: - Load trivia from a separate file.
This commit is contained in:
@@ -136,6 +136,7 @@ set(SOURCES
|
||||
"editoruilayer.cpp"
|
||||
"editoruipanels.cpp"
|
||||
"scenarioloadermode.cpp"
|
||||
"scenarioloaderuilayer.cpp"
|
||||
"scenenodegroups.cpp"
|
||||
"simulationenvironment.cpp"
|
||||
"simulationstateserializer.cpp"
|
||||
|
||||
@@ -233,7 +233,7 @@ struct global_settings {
|
||||
std::string asVersion; // z opisem
|
||||
motiontelemetry::conf_t motiontelemetry_conf;
|
||||
std::string screenshot_dir;
|
||||
bool loading_log = true;
|
||||
bool loading_log = false;
|
||||
bool dds_upper_origin = false;
|
||||
bool captureonstart = true;
|
||||
bool render_cab = true;
|
||||
|
||||
@@ -23,9 +23,7 @@ bool launcher_mode::update()
|
||||
void launcher_mode::enter()
|
||||
{
|
||||
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
|
||||
simulation::is_ready = false;
|
||||
|
||||
Application.set_title(Global.AppName);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,17 +18,13 @@ public:
|
||||
launcher_mode();
|
||||
// methods
|
||||
// initializes internal data structures of the mode. returns: true on success, false otherwise
|
||||
bool
|
||||
init() override;
|
||||
bool init() override;
|
||||
// mode-specific update of simulation data. returns: false on error, true otherwise
|
||||
bool
|
||||
update() override;
|
||||
bool update() override;
|
||||
// maintenance method, called when the mode is activated
|
||||
void
|
||||
enter() override;
|
||||
void enter() override;
|
||||
// maintenance method, called when the mode is deactivated
|
||||
void
|
||||
exit() override;
|
||||
void exit() override;
|
||||
// input handlers
|
||||
void on_key( int Key, int Scancode, int Action, int Mods ) override;
|
||||
void on_cursor_pos( double const Horizontal, double const Vertical ) override { ; }
|
||||
|
||||
@@ -19,7 +19,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
class launcher_ui : public ui_layer {
|
||||
public:
|
||||
launcher_ui();
|
||||
bool on_key(const int Key, const int Action) override;
|
||||
bool on_key(int Key, int Action) override;
|
||||
void on_window_resize(int w, int h) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -14,7 +14,6 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "simulation.h"
|
||||
#include "simulationtime.h"
|
||||
#include "simulationenvironment.h"
|
||||
#include "Timer.h"
|
||||
#include "application.h"
|
||||
#include "scenarioloaderuilayer.h"
|
||||
#include "renderer.h"
|
||||
@@ -22,20 +21,17 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "translation.h"
|
||||
|
||||
scenarioloader_mode::scenarioloader_mode() {
|
||||
|
||||
m_userinterface = std::make_shared<scenarioloader_ui>();
|
||||
}
|
||||
|
||||
// initializes internal data structures of the mode. returns: true on success, false otherwise
|
||||
bool
|
||||
scenarioloader_mode::init() {
|
||||
bool scenarioloader_mode::init() {
|
||||
// nothing to do here
|
||||
return true;
|
||||
}
|
||||
|
||||
// mode-specific update of simulation data. returns: false on error, true otherwise
|
||||
bool
|
||||
scenarioloader_mode::update() {
|
||||
bool scenarioloader_mode::update() {
|
||||
if (!Global.ready_to_load)
|
||||
// waiting for network connection
|
||||
return true;
|
||||
@@ -69,31 +65,24 @@ scenarioloader_mode::update() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
scenarioloader_mode::is_command_processor() const {
|
||||
bool scenarioloader_mode::is_command_processor() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// maintenance method, called when the mode is activated
|
||||
void
|
||||
scenarioloader_mode::enter() {
|
||||
|
||||
void scenarioloader_mode::enter() {
|
||||
// TBD: hide cursor in fullscreen mode?
|
||||
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
|
||||
simulation::is_ready = false;
|
||||
|
||||
m_userinterface->set_background( "logo" );
|
||||
Application.set_title( Global.AppName + " (" + Global.SceneryFile + ")" );
|
||||
m_userinterface->set_progress();
|
||||
m_userinterface->set_progress(STR("Loading scenery"));
|
||||
GfxRenderer->Render();
|
||||
}
|
||||
|
||||
// maintenance method, called when the mode is deactivated
|
||||
void
|
||||
scenarioloader_mode::exit() {
|
||||
|
||||
void scenarioloader_mode::exit() {
|
||||
simulation::Time.init( Global.starting_timestamp );
|
||||
simulation::Environment.init();
|
||||
}
|
||||
|
||||
109
scenarioloaderuilayer.cpp
Normal file
109
scenarioloaderuilayer.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "scenarioloaderuilayer.h"
|
||||
|
||||
#include "Globals.h"
|
||||
#include "translation.h"
|
||||
|
||||
scenarioloader_ui::scenarioloader_ui()
|
||||
{
|
||||
m_suppress_menu = true;
|
||||
load_random_background();
|
||||
generate_gradient_tex();
|
||||
load_wheel_frames();
|
||||
|
||||
// Temorary trivia contents
|
||||
m_trivia.push_back("W trakcie przeprowadzonej rewizji technicznej wagonów kolejowych");
|
||||
m_trivia.push_back("sprawdza się również daty ostatnich napraw okresowych. Wagony, dla");
|
||||
m_trivia.push_back("których upływa termin dokonania następnej naprawy okresowej pracownik");
|
||||
m_trivia.push_back("zespołu rewizji technicznej prowadzący oględziny winien jest przekierować");
|
||||
m_trivia.push_back("do odpowiednich Zakładów Naprawczych Taboru Kolejowego lub wagonowni.");
|
||||
}
|
||||
|
||||
void scenarioloader_ui::render_()
|
||||
{
|
||||
// For some reason, ImGui windows have some padding. Offset it.
|
||||
// TODO: Find out a way to exactly adjust the position.
|
||||
constexpr int padding = 12;
|
||||
ImGui::SetNextWindowPos(ImVec2(-padding, -padding));
|
||||
ImGui::SetNextWindowSize(ImVec2(Global.window_size.x + padding * 2, Global.window_size.y + padding * 2));
|
||||
ImGui::Begin("Neo Loading Screen", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoBackground);
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
ImGui::PushFont(font_loading);
|
||||
ImGui::SetWindowFontScale(1);
|
||||
const float font_scale_mult = 48 / ImGui::GetFontSize();
|
||||
// Gradient at the lower half of the screen
|
||||
const auto tex = reinterpret_cast<ImTextureID>(m_gradient_overlay_tex);
|
||||
draw_list->AddImage(tex, ImVec2(0, Global.window_size.y / 2), ImVec2(Global.window_size.x, Global.window_size.y), ImVec2(0, 0), ImVec2(1, 1));
|
||||
// Loading label
|
||||
ImGui::SetWindowFontScale(font_scale_mult * 0.8);
|
||||
draw_list->AddText(ImVec2(200, 885), IM_COL32_WHITE, m_progresstext.c_str());
|
||||
// Loading wheel icon
|
||||
const deferred_image* img = &m_loading_wheel_frames[38];
|
||||
const auto loading_tex = img->get();
|
||||
const auto loading_size = img->size();
|
||||
draw_list->AddImage(reinterpret_cast<ImTextureID>(loading_tex), ImVec2(35, 850), ImVec2(35 + loading_size.x, 850 + loading_size.y), ImVec2(0, 0), ImVec2(1, 1));
|
||||
// Trivia header
|
||||
ImGui::SetWindowFontScale(font_scale_mult * 1);
|
||||
draw_list->AddText(ImVec2(1280 - ImGui::CalcTextSize(STR_C("Did you know")).x / 2, 770), IM_COL32_WHITE, STR_C("Did you know"));
|
||||
// Trivia content
|
||||
ImGui::SetWindowFontScale(font_scale_mult * 0.6);
|
||||
for (int i = 0; i < m_trivia.size(); i++)
|
||||
{
|
||||
std::string line = m_trivia[i];
|
||||
draw_list->AddText(ImVec2(1280 - ImGui::CalcTextSize(line.c_str()).x / 2, 825 + i * 25), IM_COL32_WHITE, line.c_str());
|
||||
}
|
||||
// Progress bar at the bottom of the screen
|
||||
const auto p1 = ImVec2(0, Global.window_size.y - 2);
|
||||
const auto p2 = ImVec2(Global.window_size.x * m_progress, Global.window_size.y);
|
||||
draw_list->AddRectFilled(p1, p2, ImColor(40, 210, 60, 255));
|
||||
ImGui::PopFont();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void scenarioloader_ui::generate_gradient_tex()
|
||||
{
|
||||
constexpr int image_width = 1;
|
||||
constexpr int image_height = 256;
|
||||
const auto image_data = new char[image_width * image_height * 4];
|
||||
for (int x = 0; x < image_width; x++)
|
||||
for (int y = 0; y < image_height; y++)
|
||||
{
|
||||
image_data[(y * image_width + x) * 4] = 0;
|
||||
image_data[(y * image_width + x) * 4 + 1] = 0;
|
||||
image_data[(y * image_width + x) * 4 + 2] = 0;
|
||||
image_data[(y * image_width + x) * 4 + 3] = clamp(static_cast<int>(pow(y / 255.f, 0.7) * 255), 0, 255);
|
||||
}
|
||||
|
||||
// Create a OpenGL texture identifier
|
||||
GLuint image_texture;
|
||||
glGenTextures(1, &image_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, image_texture);
|
||||
|
||||
// Setup filtering parameters for display
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
// Upload pixels into texture
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
|
||||
|
||||
delete[] image_data;
|
||||
|
||||
m_gradient_overlay_width = image_width;
|
||||
m_gradient_overlay_height = image_height;
|
||||
m_gradient_overlay_tex = image_texture;
|
||||
}
|
||||
|
||||
void scenarioloader_ui::load_wheel_frames()
|
||||
{
|
||||
for (int i = 0; i < 60; i++)
|
||||
m_loading_wheel_frames[i] = deferred_image("ui/loading_wheel/" + std::to_string(i + 1));
|
||||
}
|
||||
@@ -10,11 +10,18 @@ http://mozilla.org/MPL/2.0/.
|
||||
#pragma once
|
||||
|
||||
#include "uilayer.h"
|
||||
#include "launcher/deferred_image.h"
|
||||
|
||||
class scenarioloader_ui : public ui_layer {
|
||||
int m_gradient_overlay_width;
|
||||
int m_gradient_overlay_height;
|
||||
GLuint m_gradient_overlay_tex;
|
||||
deferred_image m_loading_wheel_frames[60];
|
||||
std::vector<std::string> m_trivia;
|
||||
public:
|
||||
scenarioloader_ui() : ui_layer() {
|
||||
load_random_background();
|
||||
}
|
||||
// TODO: implement mode-specific elements
|
||||
scenarioloader_ui();
|
||||
void render_() override;
|
||||
private:
|
||||
void generate_gradient_tex();
|
||||
void load_wheel_frames();
|
||||
};
|
||||
|
||||
50
uilayer.cpp
50
uilayer.cpp
@@ -29,6 +29,7 @@ GLint ui_layer::m_textureunit { GL_TEXTURE0 };
|
||||
bool ui_layer::m_cursorvisible;
|
||||
ImFont *ui_layer::font_default{nullptr};
|
||||
ImFont *ui_layer::font_mono{nullptr};
|
||||
ImFont *ui_layer::font_loading{nullptr};
|
||||
|
||||
ui_panel::ui_panel(std::string Identifier, bool const Isopen) : is_open(Isopen), m_name(std::move(Identifier)) {}
|
||||
|
||||
@@ -132,7 +133,7 @@ bool ui_layer::mouse_button_callback(int button, int action, int mods)
|
||||
return m_imguiio->WantCaptureMouse;
|
||||
}
|
||||
|
||||
void::ui_layer::load_random_background()
|
||||
void ui_layer::load_random_background()
|
||||
{
|
||||
std::vector<std::string> images;
|
||||
for (auto &f : std::filesystem::directory_iterator("textures/logo"))
|
||||
@@ -233,6 +234,8 @@ bool ui_layer::init(GLFWwindow *Window)
|
||||
font_default = m_imguiio->Fonts->AddFontFromFileTTF("fonts/dejavusans.ttf", Global.ui_fontsize, nullptr, &ranges[0]);
|
||||
if (FileExists("fonts/dejavusansmono.ttf"))
|
||||
font_mono = m_imguiio->Fonts->AddFontFromFileTTF("fonts/dejavusansmono.ttf", Global.ui_fontsize, nullptr, &ranges[0]);
|
||||
if (FileExists("fonts/bahnschrift.ttf"))
|
||||
font_loading = m_imguiio->Fonts->AddFontFromFileTTF("fonts/bahnschrift.ttf", 48, nullptr, &ranges[0]);
|
||||
|
||||
if (!font_default && !font_mono)
|
||||
font_default = font_mono = m_imguiio->Fonts->AddFontDefault();
|
||||
@@ -240,6 +243,8 @@ bool ui_layer::init(GLFWwindow *Window)
|
||||
font_default = font_mono;
|
||||
else if (!font_mono)
|
||||
font_mono = font_default;
|
||||
if (!font_loading)
|
||||
font_loading = font_default;
|
||||
|
||||
imgui_style();
|
||||
|
||||
@@ -336,7 +341,6 @@ void ui_layer::update()
|
||||
void ui_layer::render()
|
||||
{
|
||||
render_background();
|
||||
render_progress();
|
||||
render_panels();
|
||||
render_tooltip();
|
||||
render_menu();
|
||||
@@ -397,26 +401,20 @@ void ui_layer::set_cursor(int const Mode)
|
||||
m_cursorvisible = (Mode != GLFW_CURSOR_DISABLED);
|
||||
}
|
||||
|
||||
void ui_layer::set_progress(float const Progress, float const Subtaskprogress)
|
||||
void ui_layer::set_progress(std::string const &Text)
|
||||
{
|
||||
m_progress = Progress * 0.01f;
|
||||
m_subtaskprogress = Subtaskprogress * 0.01f;
|
||||
m_progresstext = Text;
|
||||
}
|
||||
|
||||
void ui_layer::set_progress(float const progress, float const subtaskprogress)
|
||||
{
|
||||
m_progress = progress * 0.01f;
|
||||
m_subtaskprogress = subtaskprogress * 0.01f;
|
||||
}
|
||||
|
||||
void ui_layer::set_background(std::string const &Filename)
|
||||
{
|
||||
if (false == Filename.empty())
|
||||
{
|
||||
m_background = GfxRenderer->Fetch_Texture(Filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_background = null_handle;
|
||||
}
|
||||
if (m_background != null_handle)
|
||||
{
|
||||
auto const &texture = GfxRenderer->Texture(m_background);
|
||||
}
|
||||
m_background = Filename.empty() ? null_handle : GfxRenderer->Fetch_Texture(Filename);
|
||||
}
|
||||
|
||||
void ui_layer::clear_panels()
|
||||
@@ -437,22 +435,6 @@ void ui_layer::add_owned_panel(ui_panel *Panel)
|
||||
m_ownedpanels.emplace_back( Panel );
|
||||
}
|
||||
|
||||
void ui_layer::render_progress()
|
||||
{
|
||||
if ((m_progress == 0.0f) && (m_subtaskprogress == 0.0f))
|
||||
return;
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(50, 50));
|
||||
ImGui::SetNextWindowSize(ImVec2(0, 0));
|
||||
ImGui::Begin(STR_C("Loading"), nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||
if (!m_progresstext.empty())
|
||||
ImGui::ProgressBar(m_progress, ImVec2(300, 0), m_progresstext.c_str());
|
||||
else
|
||||
ImGui::ProgressBar(m_progress, ImVec2(300, 0));
|
||||
ImGui::ProgressBar(m_subtaskprogress, ImVec2(300, 0));
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void ui_layer::render_panels()
|
||||
{
|
||||
for (auto *panel : m_panels)
|
||||
@@ -517,7 +499,7 @@ void ui_layer::render_menu()
|
||||
{
|
||||
glm::dvec2 mousepos = Global.cursor_pos;
|
||||
|
||||
if (!((Global.ControlPicking && mousepos.y < 50.0f) || m_imguiio->WantCaptureMouse) || m_progress != 0.0f || m_suppress_menu)
|
||||
if (!((Global.ControlPicking && mousepos.y < 50.0f) || m_imguiio->WantCaptureMouse) || m_suppress_menu)
|
||||
return;
|
||||
|
||||
if (ImGui::BeginMainMenuBar())
|
||||
|
||||
21
uilayer.h
21
uilayer.h
@@ -10,7 +10,6 @@ http://mozilla.org/MPL/2.0/.
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include "Texture.h"
|
||||
#include "widgets/popup.h"
|
||||
|
||||
@@ -102,9 +101,9 @@ public:
|
||||
static void begin_ui_frame_internal();
|
||||
//
|
||||
static void set_cursor( int Mode );
|
||||
// stores operation progress
|
||||
void set_progress( float Progress = 0.0f, float Subtaskprogress = 0.0f );
|
||||
void set_progress( std::string const &Text ) { m_progresstext = Text; }
|
||||
// loading
|
||||
void set_progress(std::string const &Text);
|
||||
void set_progress(float progress, float subtaskprogress);
|
||||
// sets the ui background texture, if any
|
||||
void set_background( std::string const &Filename = "" );
|
||||
void set_tooltip( std::string const &Tooltip ) { m_tooltip = Tooltip; }
|
||||
@@ -121,6 +120,7 @@ public:
|
||||
|
||||
static ImFont *font_default;
|
||||
static ImFont *font_mono;
|
||||
static ImFont *font_loading;
|
||||
|
||||
protected:
|
||||
// members
|
||||
@@ -132,15 +132,17 @@ protected:
|
||||
virtual void render_menu_contents();
|
||||
ui_log_panel m_logpanel { "Log", true };
|
||||
bool m_suppress_menu = false; // if `true`, the menu at the top of the window will not be present
|
||||
// progress bar config
|
||||
float m_progress { 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
||||
float m_subtaskprogress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
||||
std::string m_progresstext; // label placed over the progress bar
|
||||
|
||||
private:
|
||||
// methods
|
||||
// render() subclass details
|
||||
virtual void render_() {};
|
||||
virtual void render_() {}
|
||||
// draws background quad with specified earlier texture
|
||||
void render_background();
|
||||
// draws a progress bar in defined earlier state
|
||||
void render_progress();
|
||||
void render_tooltip();
|
||||
void render_panels();
|
||||
void render_menu();
|
||||
@@ -150,11 +152,6 @@ protected:
|
||||
// members
|
||||
static GLint m_textureunit;
|
||||
|
||||
// progress bar config. TODO: put these together into an object
|
||||
float m_progress { 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
||||
float m_subtaskprogress{ 0.0f }; // percentage of filled progres bar, to indicate lengthy operations.
|
||||
std::string m_progresstext; // label placed over the progress bar
|
||||
|
||||
texture_handle m_background { null_handle }; // path to texture used as the background. size depends on mAspect.
|
||||
std::vector<ui_panel *> m_panels;
|
||||
std::vector<std::unique_ptr<ui_panel>> m_ownedpanels;
|
||||
|
||||
Reference in New Issue
Block a user