Archived
1
Fork 0

Change window handles into opaque pointers

This commit is contained in:
redstrate 2021-10-12 10:22:16 -04:00
parent 91cf44a0de
commit c6bc56d033
18 changed files with 195 additions and 184 deletions

View file

@ -72,7 +72,7 @@ namespace prism {
/** Call to begin rendering for a window. /** Call to begin rendering for a window.
@param index The index of the window to begin rendering for. @param index The index of the window to begin rendering for.
*/ */
void render(int index); void render(platform::window_ptr index);
void end_frame(); void end_frame();
@ -176,18 +176,27 @@ namespace prism {
@param identifier The identifier of the new window. @param identifier The identifier of the new window.
@param extent The extent of the 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. /** Removes the window from engine management. Should be called before the window is actually closed.
@param identifier The identifier of the window to remove. @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. /** Called when the window has changed size.
@param identifier The window that has been resized. @param identifier The window that has been resized.
@param extent The new extent of the window. @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. /** Called when a key has been pressed.
@param keyCode A platform-specific key code. @param keyCode A platform-specific key code.
@ -306,7 +315,7 @@ namespace prism {
std::map<std::string, Scene*> path_to_scene; std::map<std::string, Scene*> path_to_scene;
struct Window { struct Window {
int identifier = -1; platform::window_ptr identifier = nullptr;
prism::Extent extent; prism::Extent extent;
bool quit_requested = false; bool quit_requested = false;
@ -315,7 +324,7 @@ namespace prism {
std::vector<Window*> windows; std::vector<Window*> windows;
Window* get_window(const int identifier) { Window* get_window(const platform::window_ptr identifier) {
for(auto& window : windows) { for(auto& window : windows) {
if(window->identifier == identifier) if(window->identifier == identifier)
return window; return window;

View file

@ -3,6 +3,8 @@
#include <string_view> #include <string_view>
#include <filesystem> #include <filesystem>
#include "platform.hpp"
namespace prism { namespace prism {
class imgui_backend { class imgui_backend {
public: public:
@ -10,21 +12,23 @@ namespace prism {
void begin_frame(float delta_time); 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_mouse_down(int button);
void process_key_down(unsigned int key_code); void process_key_down(unsigned int key_code);
void process_key_up(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. /**Opens a file dialog to select a file. This will not block.
@param existing Whether or not to limit to existing files. @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 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. @param openDirectory Whether or not to allow selecting directories as well.
*/ */
void open_dialog(const bool existing, std::function<void(std::string)> returnFunction, bool openDirectory = false); void open_dialog(bool existing, std::function<void(std::string)> returnFunction, bool openDirectory = false);
/**Opens a file dialog to select a save location for a file. This will not block. /**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. @param returnFunction The callback function when a file is selected or the dialog is cancelled. An empy string is returned when cancelled.

View file

@ -377,39 +377,39 @@ void engine::save_prefab(const Object root, const std::string_view path) {
out << j; 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(native_handle != nullptr);
Expects(identifier >= 0);
if(identifier == 0) {
renderer = std::make_unique<prism::renderer>(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(); auto* window = new Window();
windows.push_back(window); windows.push_back(window);
window->identifier = window_ptr;
if(platform::is_main_window(window_ptr)) {
renderer = std::make_unique<prism::renderer>(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->extent = extent;
window->render_target = renderer->allocate_render_target(drawable_extent); window->render_target = renderer->allocate_render_target(drawable_extent);
render_ready = true; render_ready = true;
} }
void engine::remove_window(const int identifier) { void engine::remove_window(const platform::window_ptr identifier) {
Expects(identifier >= 0);
utility::erase_if(windows, [identifier](Window*& w) { utility::erase_if(windows, [identifier](Window*& w) {
return w->identifier == identifier; return w->identifier == identifier;
}); });
} }
void engine::resize(const int identifier, const prism::Extent extent) { void engine::resize(const platform::window_ptr identifier, const prism::Extent extent) {
Expects(identifier >= 0);
auto window = get_window(identifier); auto window = get_window(identifier);
if (window == nullptr) if (window == nullptr)
return; return;
@ -422,6 +422,10 @@ void engine::resize(const int identifier, const prism::Extent extent) {
renderer->resize_render_target(*window->render_target, drawable_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) { void engine::process_key_down(const unsigned int keyCode) {
Expects(keyCode >= 0); Expects(keyCode >= 0);
@ -705,17 +709,15 @@ void engine::update_scene(Scene& scene) {
} }
} }
void engine::render(const int index) { void engine::render(const platform::window_ptr index) {
Expects(index >= 0);
auto window = get_window(index); auto window = get_window(index);
if(window == nullptr) if(window == nullptr)
return; return;
GFXCommandBuffer* commandbuffer = gfx->acquire_command_buffer(true); GFXCommandBuffer* commandbuffer = gfx->acquire_command_buffer(true);
if(index == 0) { if(platform::is_main_window(index)) {
imgui->render(0); imgui->render();
app->render(commandbuffer); app->render(commandbuffer);
} }

View file

@ -93,9 +93,6 @@ imgui_backend::imgui_backend() {
} }
break; break;
} }
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
main_viewport->PlatformHandle = new int(0);
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
@ -112,52 +109,61 @@ imgui_backend::imgui_backend() {
monitor.DpiScale = platform::get_monitor_dpi(); monitor.DpiScale = platform::get_monitor_dpi();
platform_io.Monitors.push_back(monitor); platform_io.Monitors.push_back(monitor);
platform_io.Platform_CreateWindow = [](ImGuiViewport* viewport) { 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_io.Platform_DestroyWindow = [](ImGuiViewport* viewport) {
platform::close_window(*(int*)viewport->PlatformHandle); platform::close_window(viewport->PlatformHandle);
}; };
platform_io.Platform_ShowWindow = [](ImGuiViewport*) {}; platform_io.Platform_ShowWindow = [](ImGuiViewport*) {};
platform_io.Platform_SetWindowPos = [](ImGuiViewport* viewport, const ImVec2 pos) { 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) { 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); return ImVec2(x, y);
}; };
platform_io.Platform_SetWindowSize = [](ImGuiViewport* viewport, const ImVec2 size) { 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) { 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); return ImVec2(x, y);
}; };
platform_io.Platform_SetWindowFocus = [](ImGuiViewport* viewport) { 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) { 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*) { platform_io.Platform_GetWindowMinimized = [](ImGuiViewport*) {
return false; return false;
}; };
platform_io.Platform_SetWindowTitle = [](ImGuiViewport* viewport, const char* title) { platform_io.Platform_SetWindowTitle = [](ImGuiViewport* viewport, const char* title) {
platform::set_window_title(*(int*)viewport->PlatformHandle, 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) { void imgui_backend::begin_frame(const float delta_time) {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -171,9 +177,9 @@ void imgui_backend::begin_frame(const float delta_time) {
::engine->get_input()->end_text_input(); ::engine->get_input()->end_text_input();
} }
} }
const auto [width, height] = platform::get_window_size(0); const auto [width, height] = platform::get_window_size(::engine->get_main_window());
const auto [dw, dh] = platform::get_window_drawable_size(0); const auto [dw, dh] = platform::get_window_drawable_size(::engine->get_main_window());
io.DisplaySize = ImVec2(width, height); io.DisplaySize = ImVec2(width, height);
io.DisplayFramebufferScale = ImVec2((float)dw / width, (float)dh / 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); dialog_function(save_dialog_data);
ImGui::EndPopup(); ImGui::EndPopup();
} }
ImGui::ShowMetricsWindow();
} }
void imgui_backend::render(int index) { void imgui_backend::render() {
Expects(index >= 0); ImGui::EndFrame();
ImGui::Render();
if(index == 0) {
ImGui::EndFrame();
ImGui::Render();
}
} }
void imgui_backend::process_key_down(unsigned int key_code) { void imgui_backend::process_key_down(unsigned int key_code) {

View file

@ -18,7 +18,7 @@ void input_system::update() {
const auto& [x, y] = platform::get_cursor_position(); const auto& [x, y] = platform::get_cursor_position();
auto& [oldX, oldY] = _last_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 xDelta = (x - oldX) / (float)width;
float yDelta = (y - oldY) / (float)height; float yDelta = (y - oldY) / (float)height;

View file

@ -5,6 +5,7 @@
#include <variant> #include <variant>
#include "shadercompiler.hpp" #include "shadercompiler.hpp"
#include "platform.hpp"
class GFXBuffer; class GFXBuffer;
class GFXPipeline; class GFXPipeline;
@ -309,15 +310,15 @@ public:
virtual bool initialize([[maybe_unused]] const GFXCreateInfo& createInfo) { return false; } virtual bool initialize([[maybe_unused]] const GFXCreateInfo& createInfo) { return false; }
virtual void initialize_view([[maybe_unused]] void* native_handle, 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 width,
[[maybe_unused]] const uint32_t height) {} [[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 width,
[[maybe_unused]] const uint32_t height) {} [[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 // buffer operations
virtual GFXBuffer* create_buffer([[maybe_unused]] void* data, 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 GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use = false) { return nullptr; }
virtual void submit([[maybe_unused]] GFXCommandBuffer* command_buffer, virtual void submit([[maybe_unused]] GFXCommandBuffer* command_buffer,
[[maybe_unused]] const int window = -1) {} [[maybe_unused]] const platform::window_ptr window = nullptr) {}
}; };

View file

@ -9,7 +9,7 @@
#include "gfx_vulkan_constants.hpp" #include "gfx_vulkan_constants.hpp"
struct NativeSurface { struct NativeSurface {
int identifier = -1; platform::window_ptr identifier = nullptr;
uint32_t surfaceWidth = -1, surfaceHeight = -1; uint32_t surfaceWidth = -1, surfaceHeight = -1;
@ -44,8 +44,8 @@ public:
bool initialize(const GFXCreateInfo& info) override; bool initialize(const GFXCreateInfo& info) override;
void initialize_view(void* native_handle, 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(int identifier, uint32_t width, uint32_t height) override; void recreate_view(platform::window_ptr identifier, uint32_t width, uint32_t height) override;
// buffer operations // buffer operations
GFXBuffer* create_buffer(void* data, GFXSize size, bool dynamic_data, GFXBufferUsage usage) override; 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; 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: private:
void createInstance(std::vector<const char*> layers, std::vector<const char*> extensions); void createInstance(std::vector<const char*> layers, std::vector<const char*> extensions);

View file

@ -228,7 +228,7 @@ bool GFXVulkan::initialize(const GFXCreateInfo& info) {
return true; 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); vkDeviceWaitIdle(device);
auto surface = new NativeSurface(); auto surface = new NativeSurface();
@ -242,7 +242,7 @@ void GFXVulkan::initialize_view(void* native_handle, const int identifier, const
native_surfaces.push_back(surface); 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); vkDeviceWaitIdle(device);
NativeSurface* found_surface = nullptr; NativeSurface* found_surface = nullptr;
@ -1198,7 +1198,7 @@ GFXCommandBuffer* GFXVulkan::acquire_command_buffer(bool for_presentation_use) {
return cmdbuf; 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; NativeSurface* current_surface = nullptr;
for(auto surface : native_surfaces) { for(auto surface : native_surfaces) {
if(surface->identifier == identifier) if(surface->identifier == identifier)
@ -1206,7 +1206,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
} }
uint32_t imageIndex = 0; uint32_t imageIndex = 0;
if(identifier != -1 && current_surface != nullptr) { if(identifier != nullptr && current_surface != nullptr) {
vkWaitForFences(device, 1, &current_surface->inFlightFences[current_surface->currentFrame], VK_TRUE, std::numeric_limits<uint64_t>::max()); vkWaitForFences(device, 1, &current_surface->inFlightFences[current_surface->currentFrame], VK_TRUE, std::numeric_limits<uint64_t>::max());
VkResult result = vkAcquireNextImageKHR(device, current_surface->swapchain, std::numeric_limits<uint64_t>::max(), current_surface->imageAvailableSemaphores[current_surface->currentFrame], VK_NULL_HANDLE, &imageIndex); VkResult result = vkAcquireNextImageKHR(device, current_surface->swapchain, std::numeric_limits<uint64_t>::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); vkEndCommandBuffer(cmd);
if(identifier == -1) { if(identifier == nullptr) {
VkSubmitInfo submitInfo = {}; VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;

View file

@ -65,14 +65,16 @@ enum class PlatformTheme {
}; };
namespace platform { namespace platform {
using window_ptr = void*;
/// Returns a human readable platform name, e.g. Linux. /// Returns a human readable platform name, e.g. Linux.
const char* get_name(); const char* get_name();
/// Returns the current platform theme. /// Returns the current platform theme.
PlatformTheme get_theme(); PlatformTheme get_theme();
/// Queries whether or not the platform supports a certain feature. /// 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. /** Opens a new window.
@param title The title of the 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. @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. @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 // for vulkan usage
void* create_native_surface(int index, void* instance); void* create_native_surface(window_ptr window, void* instance);
std::vector<const char*> get_native_surface_extension(); std::vector<const char*> get_native_surface_extension();
/** Closes a window. /** Closes a window.
@param index The window to close. @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(). /// Forces the platform to quit the application. This is not related to Engine::quit().
void force_quit(); void force_quit();
/// Gets the content scale for the window. 1.0 would be 1x scale, 2.0 would be 2x scale, etc. /// 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. /// Gets the content scale for the monitor. 1.0 would be 1x scale, 2.0 would be 2x scale, etc.
float get_monitor_dpi(); float get_monitor_dpi();
/// Get the monitor resolution. /// Get the monitor resolution.
prism::Rectangle get_monitor_resolution(); prism::Rectangle get_monitor_resolution();
@ -109,34 +114,34 @@ namespace platform {
prism::Rectangle get_monitor_work_area(); prism::Rectangle get_monitor_work_area();
/// Get the window position. /// 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. /// 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. /// 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. /// 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. /// 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. /// 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. /// 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. /// 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. /// 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. /// 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. /// Returns the current moue cursor position, relative to the window.
prism::Offset get_cursor_position(); prism::Offset get_cursor_position();
@ -145,7 +150,7 @@ namespace platform {
prism::Offset get_screen_cursor_position(); prism::Offset get_screen_cursor_position();
/// Queries whether or not the mouse button requested is pressed or not. /// 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. /// Returns the current mouse wheel delta on both axes.
std::tuple<float, float> get_wheel_delta(); std::tuple<float, float> get_wheel_delta();
@ -157,22 +162,10 @@ namespace platform {
std::tuple<float, float> get_left_stick_position(); std::tuple<float, float> get_left_stick_position();
/// On platforms that support moue capture, this will lock the mouse cursor to the window and hide it. /// 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 // 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 begin_text_input();
void end_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();
} }

View file

@ -17,7 +17,7 @@ public:
void create_render_target_resources(RenderTarget& target) override; 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: private:
void load_font(const std::string_view filename); void load_font(const std::string_view filename);

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "common.hpp" #include "common.hpp"
#include "platform.hpp"
class GFXCommandBuffer; class GFXCommandBuffer;
class Scene; class Scene;
@ -24,7 +25,7 @@ public:
[[maybe_unused]] GFXCommandBuffer* commandBuffer) {} [[maybe_unused]] GFXCommandBuffer* commandBuffer) {}
virtual void render_post([[maybe_unused]] GFXCommandBuffer* commandBuffer, virtual void render_post([[maybe_unused]] GFXCommandBuffer* commandBuffer,
[[maybe_unused]] RenderTarget& target, [[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; } virtual GFXTexture* get_requested_texture([[maybe_unused]] PassTextureType type) { return nullptr; }
}; };

View file

@ -13,6 +13,7 @@
#include "path.hpp" #include "path.hpp"
#include "shadercompiler.hpp" #include "shadercompiler.hpp"
#include "rendertarget.hpp" #include "rendertarget.hpp"
#include "platform.hpp"
namespace ui { namespace ui {
class Screen; class Screen;
@ -59,7 +60,7 @@ namespace prism {
int elementOffset = 0; 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, void render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Object camera_object, Camera& camera,
prism::Extent extent, RenderTarget& target, controller_continuity &continuity); prism::Extent extent, RenderTarget& target, controller_continuity &continuity);

View file

@ -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; ImDrawData* draw_data = nullptr;
if(index == 0) { if(platform::is_main_window(index)) {
draw_data = ImGui::GetDrawData(); draw_data = ImGui::GetDrawData();
} else { } else {
auto& io = ImGui::GetPlatformIO(); auto& io = ImGui::GetPlatformIO();
for(int i = 1; i < io.Viewports.size(); i++) { for(int i = 1; i < io.Viewports.size(); i++) {
if((io.Viewports[i]->Flags & ImGuiViewportFlags_Minimized) == 0) { if((io.Viewports[i]->Flags & ImGuiViewportFlags_Minimized) == 0) {
auto platform_handle = (int*)io.Viewports[i]->PlatformHandle; if(io.Viewports[i]->PlatformHandle == index)
if(platform_handle != nullptr && *platform_handle == index)
draw_data = io.Viewports[i]->DrawData; draw_data = io.Viewports[i]->DrawData;
} }
} }
@ -159,8 +158,8 @@ void ImGuiPass::load_font(const std::string_view filename) {
font_file->read_all(); font_file->read_all();
io.Fonts->AddFontFromMemoryTTF(font_file->cast_data<unsigned char>(), font_file->size(), 15.0 * platform::get_window_dpi(0)); io.Fonts->AddFontFromMemoryTTF(font_file->cast_data<unsigned char>(), font_file->size(), 15.0 * platform::get_window_dpi(engine->get_main_window()));
ImGui::GetIO().FontGlobalScale = 1.0 / platform::get_window_dpi(0); ImGui::GetIO().FontGlobalScale = 1.0 / platform::get_window_dpi(engine->get_main_window());
} else { } else {
prism::log("Failed to load font file for imgui!"); prism::log("Failed to load font file for imgui!");
return; return;

View file

@ -20,7 +20,6 @@
#include "dofpass.hpp" #include "dofpass.hpp"
#include "frustum.hpp" #include "frustum.hpp"
#include "shadercompiler.hpp" #include "shadercompiler.hpp"
#include "asset.hpp"
#include "debug.hpp" #include "debug.hpp"
using prism::renderer; using prism::renderer;
@ -35,12 +34,6 @@ struct GlyphInstance {
uint32_t position = 0, index = 0, instance = 0; uint32_t position = 0, index = 0, instance = 0;
}; };
struct GylphMetric {
uint32_t x0_y0, x1_y1;
float xoff, yoff;
float xoff2, yoff2;
};
struct StringInstance { struct StringInstance {
uint32_t xy; 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 extent = target.extent;
const auto render_extent = target.get_render_extent(); const auto render_extent = target.get_render_extent();
if(index > 0) { if(!platform::is_main_window(index)) {
GFXRenderPassBeginInfo beginInfo = {}; GFXRenderPassBeginInfo beginInfo = {};
beginInfo.render_area.extent = render_extent; beginInfo.render_area.extent = render_extent;

View file

@ -17,30 +17,22 @@
@APP_CLASS@* app = nullptr; @APP_CLASS@* app = nullptr;
GFX* gfx_interface = nullptr; GFX* gfx_interface = nullptr;
struct Window { std::vector<SDL_Window*> windows;
int identifier = 0; SDL_Window* main_window = nullptr;
SDL_Window* window = nullptr;
bool operator==(const Window& b) { SDL_Window* get_window(const platform::window_ptr index) {
return identifier == b.identifier && window == b.window;
}
};
std::vector<Window> windows;
Window* get_window(const int index) {
for(auto& window : windows) { for(auto& window : windows) {
if(window.identifier == index) if(window == index)
return &window; return window;
} }
return nullptr; 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) { for(auto& window : windows) {
if(SDL_GetWindowID(window.window) == id) if(SDL_GetWindowID(window) == id)
return &window; return window;
} }
return nullptr; return nullptr;
@ -85,9 +77,8 @@ bool platform::supports_feature(const PlatformFeature feature) {
return false; 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(); auto& win = windows.emplace_back();
win.identifier = windows.size() - 1;
int sdl_flags = SDL_WINDOW_VULKAN; int sdl_flags = SDL_WINDOW_VULKAN;
if(flags == WindowFlags::Borderless) 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) if(flags == WindowFlags::Resizable)
sdl_flags |= SDL_WINDOW_RESIZABLE; sdl_flags |= SDL_WINDOW_RESIZABLE;
auto resolution = platform::get_monitor_resolution();
int real_x = rect.offset.x; int real_x = rect.offset.x;
int real_y = rect.offset.y; 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; real_x = SDL_WINDOWPOS_CENTERED;
if(rect.offset.y <= -1 || rect.offset.x >= resolution.extent.height)
real_y = SDL_WINDOWPOS_CENTERED; 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(); 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); 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() { void platform::force_quit() {
SDL_Quit(); SDL_Quit();
} }
float platform::get_window_dpi(const int index) { float platform::get_window_dpi(const platform::window_ptr index) {
return 1.0; return 1.0;
} }
@ -143,59 +154,59 @@ prism::Rectangle platform::get_monitor_work_area() {
return platform::get_monitor_resolution(); 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); auto window = get_window(index);
int x, y; int x, y;
SDL_GetWindowPosition(window->window, &x, &y); SDL_GetWindowPosition(window, &x, &y);
return {(int32_t)x, (int32_t)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); auto window = get_window(index);
int width, height; int width, height;
SDL_GetWindowSize(window->window, &width, &height); SDL_GetWindowSize(window, &width, &height);
return {(uint32_t)width, (uint32_t)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); auto window = get_window(index);
int width, height; int width, height;
SDL_GetWindowSize(window->window, &width, &height); SDL_GetWindowSize(window, &width, &height);
return {(uint32_t)width, (uint32_t)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); 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); 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); 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); 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); auto window = get_window(index);
SDL_SetWindowTitle(window->window, title.data()); SDL_SetWindowTitle(window, title.data());
} }
bool platform::get_key_down(const InputButton key) { bool platform::get_key_down(const InputButton key) {
@ -257,10 +268,6 @@ void platform::capture_mouse(const bool capture) {
SDL_CaptureMouse((SDL_bool)capture); SDL_CaptureMouse((SDL_bool)capture);
} }
char* platform::translate_keycode(const unsigned int keycode) {
return const_cast<char*>(SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)keycode)));
}
void platform::begin_text_input() { void platform::begin_text_input() {
SDL_StartTextInput(); SDL_StartTextInput();
} }
@ -269,10 +276,6 @@ void platform::end_text_input() {
SDL_StopTextInput(); SDL_StopTextInput();
} }
void platform::mute_output() {}
void platform::unmute_output() {}
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); 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) { if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
auto window = get_window_by_sdl_id(event.window.windowID); auto window = get_window_by_sdl_id(event.window.windowID);
if(window != nullptr) if(window != nullptr)
engine->resize(window->identifier, {static_cast<uint32_t>(event.window.data1), static_cast<uint32_t>(event.window.data2)}); engine->resize(window, {static_cast<uint32_t>(event.window.data1), static_cast<uint32_t>(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) { } else if(event.window.event == SDL_WINDOWEVENT_CLOSE) {
engine->quit(); engine->quit();
} }
@ -358,7 +365,7 @@ int main(int argc, char* argv[]) {
engine->begin_frame(deltatime); engine->begin_frame(deltatime);
for(auto window : windows) for(auto window : windows)
engine->render(window.identifier); engine->render(window);
engine->end_frame(); engine->end_frame();
} }
@ -388,12 +395,12 @@ PlatformTheme platform::get_theme() {
} }
#endif #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); auto window = get_window(index);
VkSurfaceKHR surface; VkSurfaceKHR surface;
SDL_Vulkan_CreateSurface(window->window, (VkInstance)instance, &surface); SDL_Vulkan_CreateSurface(window, (VkInstance)instance, &surface);
return surface; return surface;
} }

View file

@ -653,7 +653,7 @@ void CommonEditor::createDockArea() {
void CommonEditor::drawViewport(Scene* scene) { void CommonEditor::drawViewport(Scene* scene) {
const auto size = ImGui::GetContentRegionAvail(); 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) if(real_size.x <= 0 || real_size.y <= 0)
return; return;
@ -1045,8 +1045,8 @@ void CommonEditor::load_options() {
} }
void CommonEditor::save_options() { void CommonEditor::save_options() {
const auto& [x, y] = platform::get_window_position(0); const auto& [x, y] = platform::get_window_position(engine->get_main_window());
const auto& [width, height] = platform::get_window_size(0); const auto& [width, height] = platform::get_window_size(engine->get_main_window());
nlohmann::json j; nlohmann::json j;
j["x"] = x; j["x"] = x;

View file

@ -3,10 +3,8 @@
#include <imgui.h> #include <imgui.h>
#include <imgui_stdlib.h> #include <imgui_stdlib.h>
#include <imgui_internal.h> #include <imgui_internal.h>
#include <nlohmann/json.hpp>
#include "engine.hpp" #include "engine.hpp"
#include "imguipass.hpp"
#include "file.hpp" #include "file.hpp"
#include "json_conversions.hpp" #include "json_conversions.hpp"
#include "platform.hpp" #include "platform.hpp"
@ -14,7 +12,6 @@
#include "sceneeditor.hpp" #include "sceneeditor.hpp"
#include "materialeditor.hpp" #include "materialeditor.hpp"
#include "prefabeditor.hpp" #include "prefabeditor.hpp"
#include "log.hpp"
std::string get_filename(const std::string path) { std::string get_filename(const std::string path) {
return path.substr(path.find_last_of("/") + 1, path.length()); 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) { void PrismEditor::renderEditor(GFXCommandBuffer* command_buffer) {
for(auto [id, render_target] : viewport_render_targets) { 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);
} }
} }

View file

@ -489,7 +489,7 @@ void ModelEditor::drawUI() {
ImGui::Begin("mcompile", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground); ImGui::Begin("mcompile", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground);
ImGui::SetWindowPos(ImVec2(0, 0)); 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...")) { if(ImGui::Button("Open model to compile...")) {
platform::open_dialog(true, [this](std::string path) { platform::open_dialog(true, [this](std::string path) {