diff --git a/Content/Documentation/WickedEngine-Documentation.md b/Content/Documentation/WickedEngine-Documentation.md index 0b012fb4d..0a70cabf7 100644 --- a/Content/Documentation/WickedEngine-Documentation.md +++ b/Content/Documentation/WickedEngine-Documentation.md @@ -301,6 +301,8 @@ Calls Render for the active RenderPath and wakes up scripts that are waiting for 4. Compose() Calls Compose for the active RenderPath +Note: the splash_screen texture of the application can be created before application is initialized, in this case this texture will be shown as a full screen image (with cropping, if necessary) while the engine initialization hasn't finished. The splash_screen texture will be also created automatically if a splash_screen.png file is found in the working directory. If a splash screen is not used, then the intialization logging screen will be shown at startup. + ### RenderPath [[Header]](../../WickedEngine/wiRenderPath.h) This is an empty base class that can be activated with a `Application`. It calls its Start(), Update(), FixedUpdate(), Render(), Compose(), Stop(), etc. functions as needed. Override this to perform custom gameplay or rendering logic. The RenderPath inherits from [wiCanvas](#wicanvas), and the canvas properties will be set by the [Application](#application) when the RenderPath was activated, and while the RenderPath is active.
diff --git a/Editor/GeneralWindow.cpp b/Editor/GeneralWindow.cpp index 6082c0fa4..e4b24c41f 100644 --- a/Editor/GeneralWindow.cpp +++ b/Editor/GeneralWindow.cpp @@ -519,6 +519,7 @@ void GeneralWindow::Create(EditorComponent* _editor) editor->paintToolWnd.revealTextureButton.SetColor(wi::Color::White(), wi::gui::IDLE); editor->projectCreatorWnd.iconButton.SetColor(wi::Color::White(), wi::gui::IDLE); editor->projectCreatorWnd.thumbnailButton.SetColor(wi::Color::White(), wi::gui::IDLE); + editor->projectCreatorWnd.splashScreenButton.SetColor(wi::Color::White(), wi::gui::IDLE); editor->aboutLabel.sprites[wi::gui::FOCUS] = editor->aboutLabel.sprites[wi::gui::IDLE]; int scene_id = 0; for (auto& editorscene : editor->scenes) diff --git a/Editor/ProjectCreatorWindow.cpp b/Editor/ProjectCreatorWindow.cpp index f5facd538..72ec160c4 100644 --- a/Editor/ProjectCreatorWindow.cpp +++ b/Editor/ProjectCreatorWindow.cpp @@ -26,6 +26,8 @@ void ProjectCreatorWindow::Create(EditorComponent* _editor) iconButton.SetText(""); iconButton.SetDescription("Icon: "); iconButton.SetSize(XMFLOAT2(128 * 0.5f, 128 * 0.5f)); + iconButton.font_description.params.v_align = wi::font::WIFALIGN_BOTTOM; + iconButton.font_description.params.h_align = wi::font::WIFALIGN_CENTER; iconButton.SetTooltip("The icon will be used for the executable icon."); iconButton.OnClick([this](wi::gui::EventArgs args) { if (iconResource.IsValid()) @@ -57,7 +59,9 @@ void ProjectCreatorWindow::Create(EditorComponent* _editor) thumbnailButton.Create("projectThumbnail"); thumbnailButton.SetText(""); thumbnailButton.SetDescription("Thumbnail: "); - thumbnailButton.SetSize(XMFLOAT2(480 * 0.5f, 270 * 0.5f)); + thumbnailButton.font_description.params.v_align = wi::font::WIFALIGN_BOTTOM; + thumbnailButton.font_description.params.h_align = wi::font::WIFALIGN_CENTER; + thumbnailButton.SetSize(XMFLOAT2(480 * 0.4f, 270 * 0.4f)); thumbnailButton.SetTooltip("The thumbnail will be used for displaying the project in the editor."); thumbnailButton.OnClick([this](wi::gui::EventArgs args) { if (thumbnailResource.IsValid()) @@ -86,6 +90,42 @@ void ProjectCreatorWindow::Create(EditorComponent* _editor) }); AddWidget(&thumbnailButton); + splashScreenButton.Create("projectSplashScreen"); + splashScreenButton.SetText(""); + splashScreenButton.SetDescription("Splash screen: "); + splashScreenButton.font_description.params.v_align = wi::font::WIFALIGN_BOTTOM; + splashScreenButton.font_description.params.h_align = wi::font::WIFALIGN_CENTER; + splashScreenButton.SetSize(XMFLOAT2(480 * 0.5f, 270 * 0.5f)); + splashScreenButton.SetTooltip("The splash screen will be shown while the engine is initalizing.\nIf there is a splash screen, then it will replace the intialization log display."); + splashScreenButton.OnClick([this](wi::gui::EventArgs args) { + if (splashScreenResource.IsValid()) + { + splashScreenResource = {}; + splashScreenResourceCroppedPreview = {}; + splashScreenName = {}; + splashScreenButton.SetImage(splashScreenResourceCroppedPreview); + } + else + { + wi::helper::FileDialogParams params; + params.type = wi::helper::FileDialogParams::OPEN; + params.description = "Texture"; + params.extensions = wi::resourcemanager::GetSupportedImageExtensions(); + wi::helper::FileDialog(params, [this](std::string fileName) { + wi::eventhandler::Subscribe_Once(wi::eventhandler::EVENT_THREAD_SAFE_POINT, [=](uint64_t userdata) { + wi::Resource res = wi::resourcemanager::Load(fileName); + if (!res.IsValid()) + return; + splashScreenResource = res; + splashScreenName = fileName; + splashScreenResourceCroppedPreview.SetTexture(editor->CreateThumbnail(splashScreenResource.GetTexture(), 1280, 720, true)); + splashScreenButton.SetImage(splashScreenResourceCroppedPreview); + }); + }); + } + }); + AddWidget(&splashScreenButton); + backlogColorPicker.Create("backlog color", wi::gui::Window::WindowControls::NONE); backlogColorPicker.SetSize(XMFLOAT2(256, 256)); backlogColorPicker.SetPickColor(exe_customization.backlog_color); @@ -138,7 +178,7 @@ runProcess(function() -- set up a 3D render path, so if you load a model it will be displayed local renderpath = RenderPath3D() - application.SetActivePath(renderpath) + application.SetActivePath(renderpath, 1.0, 0, 0, 0, FadeType.CrossFade) -- 1 sec cross fade -- set up a simple text that will dynamically change every frame local counter = 0 @@ -147,14 +187,14 @@ runProcess(function() -- run an endless update loop, it will run until killProcesses() is called or the application exits while true do - update() + update() -- blocks this process until next update() is signaled from Wicked Engine -- every frame the text is positioned to the center of the screen and display the value of the frame counter font.SetText("Hello World! Current frame counter = " .. counter) - font.SetSize(12) - font.SetScale(3) - font.SetPos(Vector(GetScreenWidth() * 0.5, GetScreenHeight() * 0.5)) - font.SetAlign(WIFALIGN_CENTER, WIFALIGN_CENTER) + font.SetSize(12) -- the true render size of the font (larger can increase memory usage, but improves appearance) + font.SetScale(3) -- upscaling the font by a factor of 3 without increasing the true font resolution + font.SetPos(Vector(GetScreenWidth() * 0.5, GetScreenHeight() * 0.5)) -- put to center of the screen + font.SetAlign(WIFALIGN_CENTER, WIFALIGN_CENTER) -- horizontal and vertical text align counter = counter + 1 @@ -182,6 +222,10 @@ end) { wi::helper::saveTextureToFile(thumbnailResource.GetTexture(), directory + "thumbnail.png"); } + if (splashScreenResource.IsValid()) + { + wi::helper::saveTextureToFile(splashScreenResource.GetTexture(), directory + "splash_screen.png"); + } wi::unordered_set exes; exes.insert(wi::helper::BackslashToForwardSlash(wi::helper::GetExecutablePath())); @@ -370,7 +414,7 @@ void ProjectCreatorWindow::ResizeLayout() layout.jump(); - layout.add_right(iconButton, thumbnailButton); + layout.add_right(iconButton, thumbnailButton, splashScreenButton); layout.jump(); diff --git a/Editor/ProjectCreatorWindow.h b/Editor/ProjectCreatorWindow.h index 9fcd4fd12..6672a759d 100644 --- a/Editor/ProjectCreatorWindow.h +++ b/Editor/ProjectCreatorWindow.h @@ -12,18 +12,23 @@ public: wi::gui::TextInputField projectNameInput; wi::gui::Button iconButton; wi::gui::Button thumbnailButton; + wi::gui::Button splashScreenButton; wi::gui::Button createButton; - wi::Resource iconResource; - std::string iconName; - wi::gui::ColorPicker backlogColorPicker; wi::gui::ColorPicker backgroundColorPicker; wi::gui::Button colorPreviewButton; + wi::Resource iconResource; + std::string iconName; + wi::Resource thumbnailResource; std::string thumbnailName; + wi::Resource splashScreenResource; + wi::Resource splashScreenResourceCroppedPreview; + std::string splashScreenName; + void ResizeLayout() override; }; diff --git a/WickedEngine/wiApplication.cpp b/WickedEngine/wiApplication.cpp index fbfd4dfea..3848d6516 100644 --- a/WickedEngine/wiApplication.cpp +++ b/WickedEngine/wiApplication.cpp @@ -148,8 +148,54 @@ namespace wi viewport.width = (float)swapChain.desc.width; viewport.height = (float)swapChain.desc.height; graphicsDevice->BindViewports(1, &viewport, cmd); - if (wi::initializer::IsInitializeFinished(wi::initializer::INITIALIZED_SYSTEM_FONT)) + static bool splash_screen_check = false; + if (!splash_screen.IsValid() && !splash_screen_check) { + splash_screen_check = true; + std::string splash_screen_path = wi::helper::GetCurrentPath() + "/splash_screen.png"; + if (wi::helper::FileExists(splash_screen_path)) + { + wi::Resource resource = wi::resourcemanager::Load(splash_screen_path); + if (resource.IsValid()) + { + splash_screen = resource.GetTexture(); + } + } + } + if (splash_screen.IsValid()) + { + if (wi::initializer::IsInitializeFinished(wi::initializer::INITIALIZED_SYSTEM_IMAGE)) + { + // Draw the splash screen while engine is initializing and image renderer is ready + wi::image::SetCanvas(canvas); + wi::image::Params fx; + const TextureDesc& desc = splash_screen.GetDesc(); + const float canvas_aspect = canvas.GetLogicalWidth() / canvas.GetLogicalHeight(); + const float image_aspect = float(desc.width) / float(desc.height); + if (canvas_aspect > image_aspect) + { + // display aspect is wider than image: + fx.siz.x = canvas.GetLogicalWidth(); + fx.siz.y = canvas.GetLogicalHeight() / image_aspect * canvas_aspect; + } + else + { + // image aspect is wider or equal to display + fx.siz.x = canvas.GetLogicalWidth() / canvas_aspect * image_aspect; + fx.siz.y = canvas.GetLogicalHeight(); + } + fx.pos = XMFLOAT3(canvas.GetLogicalWidth() * 0.5f, canvas.GetLogicalHeight() * 0.5f, 0); + fx.pivot = XMFLOAT2(0.5f, 0.5f); + if (colorspace != ColorSpace::SRGB) + { + fx.enableLinearOutputMapping(9); + } + wi::image::Draw(&splash_screen, fx, cmd); + } + } + else if (wi::initializer::IsInitializeFinished(wi::initializer::INITIALIZED_SYSTEM_FONT)) + { + // If there is no splash screen, the log is rendered while engine is initializing ColorSpace colorspace = graphicsDevice->GetSwapChainColorSpace(&swapChain); wi::backlog::DrawOutputText(canvas, cmd, colorspace); } @@ -170,6 +216,8 @@ namespace wi return; } + splash_screen = {}; // splash screen no longer needed after initialization, it is deleted + static bool startup_script = false; if (!startup_script) { diff --git a/WickedEngine/wiApplication.h b/WickedEngine/wiApplication.h index 13b76033c..262472f64 100644 --- a/WickedEngine/wiApplication.h +++ b/WickedEngine/wiApplication.h @@ -52,6 +52,7 @@ namespace wi wi::graphics::SwapChain swapChain; wi::Canvas canvas; wi::platform::window_type window; + wi::graphics::Texture splash_screen; // Runs the main engine loop void Run(); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 83302e827..5824e56a0 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 788; + const int revision = 789; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);