diff --git a/engine/audio/src/audio.cpp b/engine/audio/src/audio.cpp index 63bd96e..def5158 100755 --- a/engine/audio/src/audio.cpp +++ b/engine/audio/src/audio.cpp @@ -5,9 +5,7 @@ #include #include -#include "log.hpp" #include "file.hpp" -#include "platform.hpp" constexpr int num_channels = 2; constexpr int sample_rate = 48000; @@ -57,12 +55,8 @@ static int pa_callback(const void*, void* buffer, } void audio::initialize() { - platform::mute_output(); - Pa_Initialize(); - platform::unmute_output(); - PaStream* stream; Pa_OpenDefaultStream(&stream, diff --git a/engine/core/include/console.hpp b/engine/core/include/console.hpp index 4fe6642..ce64726 100755 --- a/engine/core/include/console.hpp +++ b/engine/core/include/console.hpp @@ -14,6 +14,8 @@ namespace prism::console { }; struct console_argument { + explicit console_argument(std::string_view string) : data(string.data()) {} + explicit console_argument(bool data) : data(data) {} explicit console_argument(int data) : data(data) {} diff --git a/engine/core/include/engine.hpp b/engine/core/include/engine.hpp index 69f513a..da9063e 100755 --- a/engine/core/include/engine.hpp +++ b/engine/core/include/engine.hpp @@ -72,7 +72,7 @@ namespace prism { /** Call to begin rendering for a window. @param index The index of the window to begin rendering for. */ - void render(int index); + void render(platform::window_ptr index); void end_frame(); @@ -176,18 +176,27 @@ namespace prism { @param identifier The identifier of the new window. @param extent The extent of the window. */ - void add_window(void* native_handle, int identifier, prism::Extent extent); + void add_window(void* native_handle, platform::window_ptr window, prism::Extent extent); /** Removes the window from engine management. Should be called before the window is actually closed. @param identifier The identifier of the window to remove. */ - void remove_window(int identifier); + void remove_window(platform::window_ptr identifier); + + platform::window_ptr get_main_window() { + return windows[0]->identifier; + } /** Called when the window has changed size. @param identifier The window that has been resized. @param extent The new extent of the window. */ - void resize(int identifier, prism::Extent extent); + void resize(platform::window_ptr identifier, prism::Extent extent); + + /** Called when the window has moved. + * + */ + void move(platform::window_ptr identifier); /** Called when a key has been pressed. @param keyCode A platform-specific key code. @@ -306,7 +315,7 @@ namespace prism { std::map path_to_scene; struct Window { - int identifier = -1; + platform::window_ptr identifier = nullptr; prism::Extent extent; bool quit_requested = false; @@ -315,7 +324,7 @@ namespace prism { std::vector windows; - Window* get_window(const int identifier) { + Window* get_window(const platform::window_ptr identifier) { for(auto& window : windows) { if(window->identifier == identifier) return window; diff --git a/engine/core/include/imgui_backend.hpp b/engine/core/include/imgui_backend.hpp index 6502ac8..41a494f 100644 --- a/engine/core/include/imgui_backend.hpp +++ b/engine/core/include/imgui_backend.hpp @@ -3,6 +3,8 @@ #include #include +#include "platform.hpp" + namespace prism { class imgui_backend { public: @@ -10,21 +12,23 @@ namespace prism { void begin_frame(float delta_time); - void render(int index); + void render(); + + void process_move(platform::window_ptr identifier); void process_mouse_down(int button); void process_key_down(unsigned int key_code); void process_key_up(unsigned int key_code); - void process_text_input(const std::string_view string); + void process_text_input(std::string_view string); /**Opens a file dialog to select a file. This will not block. @param existing Whether or not to limit to existing files. @param returnFunction The callback function when a file is selected or the dialog is cancelled. An empy string is returned when cancelled. @param openDirectory Whether or not to allow selecting directories as well. */ - void open_dialog(const bool existing, std::function returnFunction, bool openDirectory = false); + void open_dialog(bool existing, std::function returnFunction, bool openDirectory = false); /**Opens a file dialog to select a save location for a file. This will not block. @param returnFunction The callback function when a file is selected or the dialog is cancelled. An empy string is returned when cancelled. diff --git a/engine/core/src/console.cpp b/engine/core/src/console.cpp index 36c666b..1b71bef 100644 --- a/engine/core/src/console.cpp +++ b/engine/core/src/console.cpp @@ -88,6 +88,8 @@ void prism::console::parse_and_invoke_command(const std::string_view command) { return console_argument(false); } else if(is_numeric(arg)) { return console_argument(std::stoi(arg.data())); + } else { + return console_argument(arg); } return std::nullopt; diff --git a/engine/core/src/engine.cpp b/engine/core/src/engine.cpp index 98ca1f9..8d86741 100755 --- a/engine/core/src/engine.cpp +++ b/engine/core/src/engine.cpp @@ -27,9 +27,14 @@ using prism::engine; engine::engine(const int argc, char* argv[]) { log("Prism Engine loading..."); + + console::register_command("echo", console::argument_format(1), [](const console::arguments& args) { + log(std::get(args[0].data)); + }); - console::register_command("test_cmd", console::argument_format(0), [](const console::arguments&) { - log("Test cmd!"); + console::register_command("platform_info", console::argument_format(0), [this](const console::arguments&) { + log("Platform: {}", platform::get_name()); + log("GFX: {}", gfx->get_name()); }); console::register_variable("rs_dynamic_resolution", render_options.dynamic_resolution); @@ -377,39 +382,39 @@ void engine::save_prefab(const Object root, const std::string_view path) { out << j; } -void engine::add_window(void* native_handle, const int identifier, const prism::Extent extent) { +void engine::add_window(void* native_handle, const platform::window_ptr window_ptr, const prism::Extent extent) { Expects(native_handle != nullptr); - Expects(identifier >= 0); - - if(identifier == 0) { - renderer = std::make_unique(gfx); - } - - const auto drawable_extent = platform::get_window_drawable_size(identifier); - - gfx->initialize_view(native_handle, identifier, drawable_extent.width, drawable_extent.height); auto* window = new Window(); windows.push_back(window); + + window->identifier = window_ptr; + + if(platform::is_main_window(window_ptr)) { + renderer = std::make_unique(gfx); + + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = ::engine->get_main_window(); + } - window->identifier = identifier; + const auto drawable_extent = platform::get_window_drawable_size(window_ptr); + + gfx->initialize_view(native_handle, window_ptr, drawable_extent.width, drawable_extent.height); + + window->extent = extent; window->render_target = renderer->allocate_render_target(drawable_extent); render_ready = true; } -void engine::remove_window(const int identifier) { - Expects(identifier >= 0); - +void engine::remove_window(const platform::window_ptr identifier) { utility::erase_if(windows, [identifier](Window*& w) { return w->identifier == identifier; }); } -void engine::resize(const int identifier, const prism::Extent extent) { - Expects(identifier >= 0); - +void engine::resize(const platform::window_ptr identifier, const prism::Extent extent) { auto window = get_window(identifier); if (window == nullptr) return; @@ -422,6 +427,10 @@ void engine::resize(const int identifier, const prism::Extent extent) { renderer->resize_render_target(*window->render_target, drawable_extent); } +void engine::move(const platform::window_ptr identifier) { + imgui->process_move(identifier); +} + void engine::process_key_down(const unsigned int keyCode) { Expects(keyCode >= 0); @@ -705,17 +714,15 @@ void engine::update_scene(Scene& scene) { } } -void engine::render(const int index) { - Expects(index >= 0); - +void engine::render(const platform::window_ptr index) { auto window = get_window(index); if(window == nullptr) return; GFXCommandBuffer* commandbuffer = gfx->acquire_command_buffer(true); - if(index == 0) { - imgui->render(0); + if(platform::is_main_window(index)) { + imgui->render(); app->render(commandbuffer); } diff --git a/engine/core/src/imgui_backend.cpp b/engine/core/src/imgui_backend.cpp index 9f61ce7..d1ad0e0 100644 --- a/engine/core/src/imgui_backend.cpp +++ b/engine/core/src/imgui_backend.cpp @@ -93,9 +93,6 @@ imgui_backend::imgui_backend() { } break; } - - ImGuiViewport* main_viewport = ImGui::GetMainViewport(); - main_viewport->PlatformHandle = new int(0); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); @@ -112,52 +109,61 @@ imgui_backend::imgui_backend() { monitor.DpiScale = platform::get_monitor_dpi(); platform_io.Monitors.push_back(monitor); - + platform_io.Platform_CreateWindow = [](ImGuiViewport* viewport) { - viewport->PlatformHandle = new int(platform::open_window("", {viewport->Pos, viewport->Size}, WindowFlags::Borderless)); + viewport->Flags = ImGuiViewportFlags_NoDecoration; + + viewport->PlatformHandle = platform::open_window("", + {viewport->Pos, viewport->Size}, WindowFlags::Borderless); }; platform_io.Platform_DestroyWindow = [](ImGuiViewport* viewport) { - platform::close_window(*(int*)viewport->PlatformHandle); + platform::close_window(viewport->PlatformHandle); }; platform_io.Platform_ShowWindow = [](ImGuiViewport*) {}; - + platform_io.Platform_SetWindowPos = [](ImGuiViewport* viewport, const ImVec2 pos) { - platform::set_window_position(*(int*)viewport->PlatformHandle, pos); + platform::set_window_position(viewport->PlatformHandle, pos); }; platform_io.Platform_GetWindowPos = [](ImGuiViewport* viewport) { - auto [x, y] = platform::get_window_position(*(int*)viewport->PlatformHandle); + auto [x, y] = platform::get_window_position(viewport->PlatformHandle); return ImVec2(x, y); }; platform_io.Platform_SetWindowSize = [](ImGuiViewport* viewport, const ImVec2 size) { - platform::set_window_size(*(int*)viewport->PlatformHandle, size); + platform::set_window_size(viewport->PlatformHandle, size); }; platform_io.Platform_GetWindowSize = [](ImGuiViewport* viewport) { - auto [x, y] = platform::get_window_size(*(int*)viewport->PlatformHandle); + auto [x, y] = platform::get_window_size(viewport->PlatformHandle); return ImVec2(x, y); }; platform_io.Platform_SetWindowFocus = [](ImGuiViewport* viewport) { - platform::set_window_focused(*(int*)viewport->PlatformHandle); + platform::set_window_focused(viewport->PlatformHandle); }; platform_io.Platform_GetWindowFocus = [](ImGuiViewport* viewport) { - return platform::is_window_focused(*(int*)viewport->PlatformHandle); + return platform::is_window_focused(viewport->PlatformHandle); }; platform_io.Platform_GetWindowMinimized = [](ImGuiViewport*) { return false; }; - platform_io.Platform_SetWindowTitle = [](ImGuiViewport* viewport, const char* title) { - platform::set_window_title(*(int*)viewport->PlatformHandle, title); + platform_io.Platform_SetWindowTitle = [](ImGuiViewport* viewport, const char* title) { + platform::set_window_title(viewport->PlatformHandle, title); }; } +void imgui_backend::process_move(platform::window_ptr identifier) { + auto viewport = ImGui::FindViewportByPlatformHandle(identifier); + if(viewport != nullptr) + viewport->PlatformRequestMove = true; +} + void imgui_backend::begin_frame(const float delta_time) { ImGuiIO& io = ImGui::GetIO(); @@ -171,9 +177,9 @@ void imgui_backend::begin_frame(const float delta_time) { ::engine->get_input()->end_text_input(); } } - - const auto [width, height] = platform::get_window_size(0); - const auto [dw, dh] = platform::get_window_drawable_size(0); + + const auto [width, height] = platform::get_window_size(::engine->get_main_window()); + const auto [dw, dh] = platform::get_window_drawable_size(::engine->get_main_window()); io.DisplaySize = ImVec2(width, height); io.DisplayFramebufferScale = ImVec2((float)dw / width, (float)dh / height); @@ -248,15 +254,13 @@ void imgui_backend::begin_frame(const float delta_time) { dialog_function(save_dialog_data); ImGui::EndPopup(); } + + ImGui::ShowMetricsWindow(); } -void imgui_backend::render(int index) { - Expects(index >= 0); - - if(index == 0) { - ImGui::EndFrame(); - ImGui::Render(); - } +void imgui_backend::render() { + ImGui::EndFrame(); + ImGui::Render(); } void imgui_backend::process_key_down(unsigned int key_code) { diff --git a/engine/core/src/input.cpp b/engine/core/src/input.cpp index 90362f0..649d24f 100755 --- a/engine/core/src/input.cpp +++ b/engine/core/src/input.cpp @@ -18,7 +18,7 @@ void input_system::update() { const auto& [x, y] = platform::get_cursor_position(); auto& [oldX, oldY] = _last_cursor_position; - const auto [width, height] = platform::get_window_size(0); + const auto [width, height] = platform::get_window_size(::engine->get_main_window()); float xDelta = (x - oldX) / (float)width; float yDelta = (y - oldY) / (float)height; diff --git a/engine/gfx/public/gfx.hpp b/engine/gfx/public/gfx.hpp index 563849c..7597f74 100755 --- a/engine/gfx/public/gfx.hpp +++ b/engine/gfx/public/gfx.hpp @@ -5,6 +5,7 @@ #include #include "shadercompiler.hpp" +#include "platform.hpp" class GFXBuffer; class GFXPipeline; @@ -309,15 +310,15 @@ public: virtual bool initialize([[maybe_unused]] const GFXCreateInfo& createInfo) { return false; } virtual void initialize_view([[maybe_unused]] void* native_handle, - [[maybe_unused]] const int identifier, + [[maybe_unused]] const platform::window_ptr identifier, [[maybe_unused]] const uint32_t width, [[maybe_unused]] const uint32_t height) {} - virtual void recreate_view([[maybe_unused]] const int identifier, + virtual void recreate_view([[maybe_unused]] const platform::window_ptr identifier, [[maybe_unused]] const uint32_t width, [[maybe_unused]] const uint32_t height) {} - virtual void remove_view([[maybe_unused]] const int identifier) {} + virtual void remove_view([[maybe_unused]] const platform::window_ptr identifier) {} // buffer operations virtual GFXBuffer* create_buffer([[maybe_unused]] void* data, @@ -362,5 +363,5 @@ public: virtual GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use = false) { return nullptr; } virtual void submit([[maybe_unused]] GFXCommandBuffer* command_buffer, - [[maybe_unused]] const int window = -1) {} + [[maybe_unused]] const platform::window_ptr window = nullptr) {} }; diff --git a/engine/gfx/vulkan/include/gfx_vulkan.hpp b/engine/gfx/vulkan/include/gfx_vulkan.hpp index c5df577..0809281 100755 --- a/engine/gfx/vulkan/include/gfx_vulkan.hpp +++ b/engine/gfx/vulkan/include/gfx_vulkan.hpp @@ -9,7 +9,7 @@ #include "gfx_vulkan_constants.hpp" struct NativeSurface { - int identifier = -1; + platform::window_ptr identifier = nullptr; uint32_t surfaceWidth = -1, surfaceHeight = -1; @@ -44,8 +44,8 @@ public: bool initialize(const GFXCreateInfo& info) override; - void initialize_view(void* native_handle, int identifier, uint32_t width, uint32_t height) override; - void recreate_view(int identifier, uint32_t width, uint32_t height) override; + void initialize_view(void* native_handle, platform::window_ptr identifier, uint32_t width, uint32_t height) override; + void recreate_view(platform::window_ptr identifier, uint32_t width, uint32_t height) override; // buffer operations GFXBuffer* create_buffer(void* data, GFXSize size, bool dynamic_data, GFXBufferUsage usage) override; @@ -78,7 +78,7 @@ public: GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use) override; - void submit(GFXCommandBuffer* command_buffer, int identifier) override; + void submit(GFXCommandBuffer* command_buffer, platform::window_ptr identifier) override; private: void createInstance(std::vector layers, std::vector extensions); diff --git a/engine/gfx/vulkan/src/gfx_vulkan.cpp b/engine/gfx/vulkan/src/gfx_vulkan.cpp index 4887331..e9a37e5 100755 --- a/engine/gfx/vulkan/src/gfx_vulkan.cpp +++ b/engine/gfx/vulkan/src/gfx_vulkan.cpp @@ -228,7 +228,7 @@ bool GFXVulkan::initialize(const GFXCreateInfo& info) { return true; } -void GFXVulkan::initialize_view(void* native_handle, const int identifier, const uint32_t width, const uint32_t height) { +void GFXVulkan::initialize_view(void* native_handle, const platform::window_ptr identifier, const uint32_t width, const uint32_t height) { vkDeviceWaitIdle(device); auto surface = new NativeSurface(); @@ -242,7 +242,7 @@ void GFXVulkan::initialize_view(void* native_handle, const int identifier, const native_surfaces.push_back(surface); } -void GFXVulkan::recreate_view(const int identifier, const uint32_t width, const uint32_t height) { +void GFXVulkan::recreate_view(const platform::window_ptr identifier, const uint32_t width, const uint32_t height) { vkDeviceWaitIdle(device); NativeSurface* found_surface = nullptr; @@ -1198,7 +1198,7 @@ GFXCommandBuffer* GFXVulkan::acquire_command_buffer(bool for_presentation_use) { return cmdbuf; } -void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) { +void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const platform::window_ptr identifier) { NativeSurface* current_surface = nullptr; for(auto surface : native_surfaces) { if(surface->identifier == identifier) @@ -1206,7 +1206,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) { } uint32_t imageIndex = 0; - if(identifier != -1 && current_surface != nullptr) { + if(identifier != nullptr && current_surface != nullptr) { vkWaitForFences(device, 1, ¤t_surface->inFlightFences[current_surface->currentFrame], VK_TRUE, std::numeric_limits::max()); VkResult result = vkAcquireNextImageKHR(device, current_surface->swapchain, std::numeric_limits::max(), current_surface->imageAvailableSemaphores[current_surface->currentFrame], VK_NULL_HANDLE, &imageIndex); @@ -1653,7 +1653,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) { vkEndCommandBuffer(cmd); - if(identifier == -1) { + if(identifier == nullptr) { VkSubmitInfo submitInfo = {}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.commandBufferCount = 1; diff --git a/engine/platform/include/platform.hpp b/engine/platform/include/platform.hpp index 1789a3b..fd86fac 100755 --- a/engine/platform/include/platform.hpp +++ b/engine/platform/include/platform.hpp @@ -65,14 +65,16 @@ enum class PlatformTheme { }; namespace platform { + using window_ptr = void*; + /// Returns a human readable platform name, e.g. Linux. const char* get_name(); - + /// Returns the current platform theme. PlatformTheme get_theme(); /// Queries whether or not the platform supports a certain feature. - bool supports_feature(const PlatformFeature feature); + bool supports_feature(PlatformFeature feature); /** Opens a new window. @param title The title of the window. @@ -82,26 +84,29 @@ namespace platform { @note On platforms that do not support the Windowing feature, calling open_window more than once is not supported. In this case, the same identifier is returned. @return A valid window identifier. */ - int open_window(const std::string_view title, const prism::Rectangle rect, const WindowFlags flags); + window_ptr open_window(std::string_view title, prism::Rectangle rect, WindowFlags flags); + + bool is_main_window(window_ptr index); // for vulkan usage - void* create_native_surface(int index, void* instance); + void* create_native_surface(window_ptr window, void* instance); + std::vector get_native_surface_extension(); /** Closes a window. @param index The window to close. */ - void close_window(const int index); + void close_window(window_ptr window); /// Forces the platform to quit the application. This is not related to Engine::quit(). void force_quit(); /// Gets the content scale for the window. 1.0 would be 1x scale, 2.0 would be 2x scale, etc. - float get_window_dpi(const int index); + float get_window_dpi(window_ptr window); /// Gets the content scale for the monitor. 1.0 would be 1x scale, 2.0 would be 2x scale, etc. float get_monitor_dpi(); - + /// Get the monitor resolution. prism::Rectangle get_monitor_resolution(); @@ -109,34 +114,34 @@ namespace platform { prism::Rectangle get_monitor_work_area(); /// Get the window position. - prism::Offset get_window_position(const int index); + prism::Offset get_window_position(window_ptr window); /// Get the window size, note that in hidpi scenarios this is the non-scaled resolution. - prism::Extent get_window_size(const int index); + prism::Extent get_window_size(window_ptr window); /// Get the window's drawable size. Always use this instead of manually multiplying the window size by the content scale. - prism::Extent get_window_drawable_size(const int index); + prism::Extent get_window_drawable_size(window_ptr window); /// Query whether or not the window is focused. - bool is_window_focused(const int index); + bool is_window_focused(window_ptr window); /// If possible, try to manually focus the window. - void set_window_focused(const int index); + void set_window_focused(window_ptr window); /// Sets the window position to the offset provided. - void set_window_position(const int index, const prism::Offset offset); + void set_window_position(window_ptr window, prism::Offset offset); /// Sets the window to the specified size. The platform will handle the subsequent resize events. - void set_window_size(const int index, const prism::Extent extent); + void set_window_size(window_ptr window, prism::Extent extent); /// Sets the window title. - void set_window_title(const int index, const std::string_view title); + void set_window_title(window_ptr window, std::string_view title); /// Queries whether or not the button is currently pressed. - bool get_key_down(const InputButton key); + bool get_key_down(InputButton key); /// If available for the InputButton, returns the platform-specific keycode. - int get_keycode(const InputButton key); + int get_keycode(InputButton key); /// Returns the current moue cursor position, relative to the window. prism::Offset get_cursor_position(); @@ -145,7 +150,7 @@ namespace platform { prism::Offset get_screen_cursor_position(); /// Queries whether or not the mouse button requested is pressed or not. - bool get_mouse_button_down(const int button); + bool get_mouse_button_down(int button); /// Returns the current mouse wheel delta on both axes. std::tuple get_wheel_delta(); @@ -157,22 +162,10 @@ namespace platform { std::tuple get_left_stick_position(); /// On platforms that support moue capture, this will lock the mouse cursor to the window and hide it. - void capture_mouse(const bool capture); + void capture_mouse(bool capture); // TODO: right now the OS intercepting and saying "We dont want text input anymore" ala software keyboards is NOT supported yet void begin_text_input(); + void end_text_input(); - - /**Translates a virtual keycode to it's character equivalent. - @note Example: translateKey(0x01) = 'a'; 0x01 in this example is a platform and language specific keycode for a key named 'a'. - @return A char pointer to the string if translated correctly. - @note Manually freeing the string returned is not needed. - */ - char* translate_keycode(const unsigned int keycode); - - /// Mute standard output - void mute_output(); - - /// Unmute standard output - void unmute_output(); } diff --git a/engine/renderer/include/imguipass.hpp b/engine/renderer/include/imguipass.hpp index 2b265a5..453e05f 100755 --- a/engine/renderer/include/imguipass.hpp +++ b/engine/renderer/include/imguipass.hpp @@ -17,7 +17,7 @@ public: void create_render_target_resources(RenderTarget& target) override; - void render_post(GFXCommandBuffer* command_buffer, RenderTarget& target, const int index) override; + void render_post(GFXCommandBuffer* command_buffer, RenderTarget& target, const platform::window_ptr index) override; private: void load_font(const std::string_view filename); diff --git a/engine/renderer/include/pass.hpp b/engine/renderer/include/pass.hpp index 1f859f4..0d85a12 100755 --- a/engine/renderer/include/pass.hpp +++ b/engine/renderer/include/pass.hpp @@ -1,6 +1,7 @@ #pragma once #include "common.hpp" +#include "platform.hpp" class GFXCommandBuffer; class Scene; @@ -24,7 +25,7 @@ public: [[maybe_unused]] GFXCommandBuffer* commandBuffer) {} virtual void render_post([[maybe_unused]] GFXCommandBuffer* commandBuffer, [[maybe_unused]] RenderTarget& target, - [[maybe_unused]] int index) {} + [[maybe_unused]] platform::window_ptr index) {} virtual GFXTexture* get_requested_texture([[maybe_unused]] PassTextureType type) { return nullptr; } }; diff --git a/engine/renderer/include/renderer.hpp b/engine/renderer/include/renderer.hpp index ef18cc2..68ac453 100755 --- a/engine/renderer/include/renderer.hpp +++ b/engine/renderer/include/renderer.hpp @@ -13,6 +13,7 @@ #include "path.hpp" #include "shadercompiler.hpp" #include "rendertarget.hpp" +#include "platform.hpp" namespace ui { class Screen; @@ -59,7 +60,7 @@ namespace prism { int elementOffset = 0; }; - void render(GFXCommandBuffer* command_buffer, Scene* scene, RenderTarget& target, int index); + void render(GFXCommandBuffer* command_buffer, Scene* scene, RenderTarget& target, platform::window_ptr index); void render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Object camera_object, Camera& camera, prism::Extent extent, RenderTarget& target, controller_continuity &continuity); diff --git a/engine/renderer/src/imguipass.cpp b/engine/renderer/src/imguipass.cpp index e9f31d8..60fb85e 100755 --- a/engine/renderer/src/imguipass.cpp +++ b/engine/renderer/src/imguipass.cpp @@ -70,16 +70,15 @@ void ImGuiPass::create_render_target_resources(RenderTarget& target) { } } -void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& target, const int index) { +void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& target, const platform::window_ptr index) { ImDrawData* draw_data = nullptr; - if(index == 0) { + if(platform::is_main_window(index)) { draw_data = ImGui::GetDrawData(); } else { auto& io = ImGui::GetPlatformIO(); for(int i = 1; i < io.Viewports.size(); i++) { if((io.Viewports[i]->Flags & ImGuiViewportFlags_Minimized) == 0) { - auto platform_handle = (int*)io.Viewports[i]->PlatformHandle; - if(platform_handle != nullptr && *platform_handle == index) + if(io.Viewports[i]->PlatformHandle == index) draw_data = io.Viewports[i]->DrawData; } } @@ -159,8 +158,8 @@ void ImGuiPass::load_font(const std::string_view filename) { font_file->read_all(); - io.Fonts->AddFontFromMemoryTTF(font_file->cast_data(), font_file->size(), 15.0 * platform::get_window_dpi(0)); - ImGui::GetIO().FontGlobalScale = 1.0 / platform::get_window_dpi(0); + io.Fonts->AddFontFromMemoryTTF(font_file->cast_data(), font_file->size(), 15.0 * platform::get_window_dpi(engine->get_main_window())); + ImGui::GetIO().FontGlobalScale = 1.0 / platform::get_window_dpi(engine->get_main_window()); } else { prism::log("Failed to load font file for imgui!"); return; diff --git a/engine/renderer/src/renderer.cpp b/engine/renderer/src/renderer.cpp index fa2440f..b32803f 100755 --- a/engine/renderer/src/renderer.cpp +++ b/engine/renderer/src/renderer.cpp @@ -20,7 +20,6 @@ #include "dofpass.hpp" #include "frustum.hpp" #include "shadercompiler.hpp" -#include "asset.hpp" #include "debug.hpp" using prism::renderer; @@ -35,12 +34,6 @@ struct GlyphInstance { uint32_t position = 0, index = 0, instance = 0; }; -struct GylphMetric { - uint32_t x0_y0, x1_y1; - float xoff, yoff; - float xoff2, yoff2; -}; - struct StringInstance { uint32_t xy; }; @@ -184,11 +177,11 @@ void renderer::recreate_all_render_targets() { } -void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarget& target, int index) { +void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarget& target, platform::window_ptr index) { const auto extent = target.extent; const auto render_extent = target.get_render_extent(); - if(index > 0) { + if(!platform::is_main_window(index)) { GFXRenderPassBeginInfo beginInfo = {}; beginInfo.render_area.extent = render_extent; diff --git a/platforms/sdl/main.cpp.in b/platforms/sdl/main.cpp.in index 7741930..ec4d6e0 100644 --- a/platforms/sdl/main.cpp.in +++ b/platforms/sdl/main.cpp.in @@ -17,30 +17,22 @@ @APP_CLASS@* app = nullptr; GFX* gfx_interface = nullptr; -struct Window { - int identifier = 0; - SDL_Window* window = nullptr; +std::vector windows; +SDL_Window* main_window = nullptr; - bool operator==(const Window& b) { - return identifier == b.identifier && window == b.window; - } -}; - -std::vector windows; - -Window* get_window(const int index) { +SDL_Window* get_window(const platform::window_ptr index) { for(auto& window : windows) { - if(window.identifier == index) - return &window; + if(window == index) + return window; } return nullptr; } -Window* get_window_by_sdl_id(const Uint32 id) { +SDL_Window* get_window_by_sdl_id(const Uint32 id) { for(auto& window : windows) { - if(SDL_GetWindowID(window.window) == id) - return &window; + if(SDL_GetWindowID(window) == id) + return window; } return nullptr; @@ -85,9 +77,8 @@ bool platform::supports_feature(const PlatformFeature feature) { return false; } -int platform::open_window(const std::string_view title, const prism::Rectangle rect, const WindowFlags flags) { +platform::window_ptr platform::open_window(const std::string_view title, const prism::Rectangle rect, const WindowFlags flags) { auto& win = windows.emplace_back(); - win.identifier = windows.size() - 1; int sdl_flags = SDL_WINDOW_VULKAN; if(flags == WindowFlags::Borderless) @@ -95,36 +86,56 @@ int platform::open_window(const std::string_view title, const prism::Rectangle r if(flags == WindowFlags::Resizable) sdl_flags |= SDL_WINDOW_RESIZABLE; + auto resolution = platform::get_monitor_resolution(); + int real_x = rect.offset.x; int real_y = rect.offset.y; - if(rect.offset.x == -1 && rect.offset.y == -1) { + + if(rect.offset.x <= -1 || rect.offset.x >= resolution.extent.width) real_x = SDL_WINDOWPOS_CENTERED; + + if(rect.offset.y <= -1 || rect.offset.x >= resolution.extent.height) real_y = SDL_WINDOWPOS_CENTERED; - } - win.window = SDL_CreateWindow(title.data(), real_x, real_y, rect.extent.width, rect.extent.height, sdl_flags); + int real_width = rect.extent.width; + int real_height = rect.extent.height; - engine->add_window((void*)&win, win.identifier, rect.extent); + if(rect.extent.width <= -1 || rect.extent.width >= resolution.extent.width) + real_width = 640; + + if(rect.extent.height <= -1 || rect.extent.height >= resolution.extent.height) + real_height = 480; + + win = SDL_CreateWindow(title.data(), real_x, real_y, real_width, real_height, sdl_flags); + + if(windows.size() == 1) + main_window = win; + + engine->add_window((void*)win, win, rect.extent); app->initialize_render(); - return win.identifier; + return win; } -void platform::close_window(const int index) { +bool platform::is_main_window(platform::window_ptr index) { + return index == main_window; +} + +void platform::close_window(const platform::window_ptr index) { auto window = get_window(index); - engine->remove_window(window->identifier); + engine->remove_window(index); - SDL_DestroyWindow(window->window); + SDL_DestroyWindow(window); - utility::erase(windows, *window); + utility::erase(windows, window); } void platform::force_quit() { SDL_Quit(); } -float platform::get_window_dpi(const int index) { +float platform::get_window_dpi(const platform::window_ptr index) { return 1.0; } @@ -143,59 +154,59 @@ prism::Rectangle platform::get_monitor_work_area() { return platform::get_monitor_resolution(); } -prism::Offset platform::get_window_position(const int index) { +prism::Offset platform::get_window_position(const platform::window_ptr index) { auto window = get_window(index); int x, y; - SDL_GetWindowPosition(window->window, &x, &y); + SDL_GetWindowPosition(window, &x, &y); return {(int32_t)x, (int32_t)y}; } -prism::Extent platform::get_window_size(const int index) { +prism::Extent platform::get_window_size(const platform::window_ptr index) { auto window = get_window(index); int width, height; - SDL_GetWindowSize(window->window, &width, &height); + SDL_GetWindowSize(window, &width, &height); return {(uint32_t)width, (uint32_t)height}; } -prism::Extent platform::get_window_drawable_size(const int index) { +prism::Extent platform::get_window_drawable_size(const platform::window_ptr index) { auto window = get_window(index); int width, height; - SDL_GetWindowSize(window->window, &width, &height); + SDL_GetWindowSize(window, &width, &height); return {(uint32_t)width, (uint32_t)height}; } -bool platform::is_window_focused(const int index) { +bool platform::is_window_focused(const platform::window_ptr index) { auto window = get_window(index); - return (SDL_GetWindowFlags(window->window) & SDL_WINDOW_INPUT_FOCUS) != 0; + return (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) != 0; } -void platform::set_window_focused(const int index) { +void platform::set_window_focused(const platform::window_ptr index) { auto window = get_window(index); - SDL_RaiseWindow(window->window); + SDL_RaiseWindow(window); } -void platform::set_window_position(const int index, const prism::Offset offset) { +void platform::set_window_position(const platform::window_ptr index, const prism::Offset offset) { auto window = get_window(index); - SDL_SetWindowPosition(window->window, offset.x, offset.y); + SDL_SetWindowPosition(window, offset.x, offset.y); } -void platform::set_window_size(const int index, const prism::Extent extent) { +void platform::set_window_size(const platform::window_ptr index, const prism::Extent extent) { auto window = get_window(index); - SDL_SetWindowSize(window->window, extent.width, extent.height); + SDL_SetWindowSize(window, extent.width, extent.height); } -void platform::set_window_title(const int index, const std::string_view title) { +void platform::set_window_title(const platform::window_ptr index, const std::string_view title) { auto window = get_window(index); - SDL_SetWindowTitle(window->window, title.data()); + SDL_SetWindowTitle(window, title.data()); } bool platform::get_key_down(const InputButton key) { @@ -257,10 +268,6 @@ void platform::capture_mouse(const bool capture) { SDL_CaptureMouse((SDL_bool)capture); } -char* platform::translate_keycode(const unsigned int keycode) { - return const_cast(SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)keycode))); -} - void platform::begin_text_input() { SDL_StartTextInput(); } @@ -269,10 +276,6 @@ void platform::end_text_input() { SDL_StopTextInput(); } -void platform::mute_output() {} - -void platform::unmute_output() {} - int main(int argc, char* argv[]) { SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); @@ -332,7 +335,11 @@ int main(int argc, char* argv[]) { if (event.window.event == SDL_WINDOWEVENT_RESIZED) { auto window = get_window_by_sdl_id(event.window.windowID); if(window != nullptr) - engine->resize(window->identifier, {static_cast(event.window.data1), static_cast(event.window.data2)}); + engine->resize(window, {static_cast(event.window.data1), static_cast(event.window.data2)}); + } else if(event.window.event == SDL_WINDOWEVENT_MOVED) { + auto window = get_window_by_sdl_id(event.window.windowID); + if(window != nullptr) + engine->move(window); } else if(event.window.event == SDL_WINDOWEVENT_CLOSE) { engine->quit(); } @@ -358,7 +365,7 @@ int main(int argc, char* argv[]) { engine->begin_frame(deltatime); for(auto window : windows) - engine->render(window.identifier); + engine->render(window); engine->end_frame(); } @@ -388,12 +395,12 @@ PlatformTheme platform::get_theme() { } #endif -void* platform::create_native_surface(int index, void* instance) { +void* platform::create_native_surface(platform::window_ptr index, void* instance) { auto window = get_window(index); VkSurfaceKHR surface; - SDL_Vulkan_CreateSurface(window->window, (VkInstance)instance, &surface); + SDL_Vulkan_CreateSurface(window, (VkInstance)instance, &surface); return surface; } diff --git a/tools/common/src/commoneditor.cpp b/tools/common/src/commoneditor.cpp index f917a70..7a71495 100755 --- a/tools/common/src/commoneditor.cpp +++ b/tools/common/src/commoneditor.cpp @@ -659,7 +659,7 @@ void CommonEditor::createDockArea() { void CommonEditor::drawViewport(Scene* scene) { const auto size = ImGui::GetContentRegionAvail(); - const auto real_size = ImVec2(size.x * platform::get_window_dpi(0), size.y * platform::get_window_dpi(0)); + const auto real_size = ImVec2(size.x * platform::get_window_dpi(engine->get_main_window()), size.y * platform::get_window_dpi(0)); if(real_size.x <= 0 || real_size.y <= 0) return; @@ -1053,8 +1053,8 @@ void CommonEditor::load_options() { } void CommonEditor::save_options() { - const auto& [x, y] = platform::get_window_position(0); - const auto& [width, height] = platform::get_window_size(0); + const auto& [x, y] = platform::get_window_position(engine->get_main_window()); + const auto& [width, height] = platform::get_window_size(engine->get_main_window()); nlohmann::json j; j["x"] = x; diff --git a/tools/editor/src/prismeditor.cpp b/tools/editor/src/prismeditor.cpp index 6eb41ea..1538403 100755 --- a/tools/editor/src/prismeditor.cpp +++ b/tools/editor/src/prismeditor.cpp @@ -3,10 +3,8 @@ #include #include #include -#include #include "engine.hpp" -#include "imguipass.hpp" #include "file.hpp" #include "json_conversions.hpp" #include "platform.hpp" @@ -14,7 +12,6 @@ #include "sceneeditor.hpp" #include "materialeditor.hpp" #include "prefabeditor.hpp" -#include "log.hpp" std::string get_filename(const std::string path) { return path.substr(path.find_last_of("/") + 1, path.length()); @@ -168,7 +165,7 @@ void PrismEditor::open_asset(const prism::path path) { void PrismEditor::renderEditor(GFXCommandBuffer* command_buffer) { for(auto [id, render_target] : viewport_render_targets) { - engine->get_renderer()->render(command_buffer, render_target.scene, *render_target.target, -1); + engine->get_renderer()->render(command_buffer, render_target.scene, *render_target.target, nullptr); } } diff --git a/tools/modelcompiler/src/modeleditor.cpp b/tools/modelcompiler/src/modeleditor.cpp index f69cb87..9a5e3cd 100755 --- a/tools/modelcompiler/src/modeleditor.cpp +++ b/tools/modelcompiler/src/modeleditor.cpp @@ -489,7 +489,7 @@ void ModelEditor::drawUI() { ImGui::Begin("mcompile", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground); ImGui::SetWindowPos(ImVec2(0, 0)); - ImGui::SetWindowSize(platform::get_window_size(0)); + ImGui::SetWindowSize(platform::get_window_size(engine->get_main_window())); if(ImGui::Button("Open model to compile...")) { platform::open_dialog(true, [this](std::string path) {