diff --git a/CMakeLists.txt b/CMakeLists.txt index fbcf257..ce2db97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,7 +78,7 @@ if (BLAH_PLATFORM_SDL2) FetchContent_Declare( SDL2 GIT_REPOSITORY https://github.com/libsdl-org/SDL - GIT_TAG release-2.0.20 # grab latest stable release + GIT_TAG release-2.24.0 # grab latest stable release GIT_PROGRESS TRUE ) FetchContent_MakeAvailable(SDL2) diff --git a/src/app.cpp b/src/app.cpp index 5e86512..e5b4120 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -30,6 +30,16 @@ namespace u64 app_time_accumulator = 0; TargetRef app_backbuffer; + void get_drawable_size(int* w, int* h) + { + // Some renderer implementations might return their own size + if (App::Internal::renderer->get_draw_size(w, h)) + return; + + // otherwise fallback to the platform size + App::Internal::platform->get_draw_size(w, h); + } + // A dummy Target that represents the Back Buffer. // It doesn't contain any data, rather it forwards calls along to the actual BackBuffer. class BackBuffer final : public Target @@ -38,8 +48,8 @@ namespace Attachments empty_textures; Attachments& textures() override { BLAH_ASSERT(false, "Backbuffer doesn't have any textures"); return empty_textures; } const Attachments& textures() const override { BLAH_ASSERT(false, "Backbuffer doesn't have any textures"); return empty_textures; } - int width() const override { int w, h; App::Internal::platform->get_draw_size(&w, &h); return w; } - int height() const override { int w, h; App::Internal::platform->get_draw_size(&w, &h); return h; } + int width() const override { int w, h; get_drawable_size(&w, &h); return w; } + int height() const override { int w, h; get_drawable_size(&w, &h); return h; } void clear(Color color, float depth, u8 stencil, ClearMask mask) override { BLAH_ASSERT_RENDERER(); diff --git a/src/internal/platform_sdl2.cpp b/src/internal/platform_sdl2.cpp index d125ea3..56cde6e 100644 --- a/src/internal/platform_sdl2.cpp +++ b/src/internal/platform_sdl2.cpp @@ -2,6 +2,7 @@ #include "platform.h" #include "renderer.h" +#include "internal.h" #include #include #include @@ -17,7 +18,6 @@ #if _WIN32 #define WIN32_LEAN_AND_MEAN #include // for the following includes -#include // for SetProcessDPIAware #include // for ShellExecute for dir_explore #include // for SDL_SysWMinfo for D3D11 #endif @@ -133,12 +133,6 @@ SDL2_Platform::SDL2_Platform() bool SDL2_Platform::init(const Config& config) { - // Required to call this for Windows - // I'm not sure why SDL2 doesn't do this on Windows automatically? -#if _WIN32 - SetProcessDPIAware(); -#endif - // TODO: // control this via some kind of config flag #ifndef __EMSCRIPTEN__ @@ -153,6 +147,10 @@ bool SDL2_Platform::init(const Config& config) SDL_GetVersion(&version); Log::info("SDL v%i.%i.%i", version.major, version.minor, version.patch); + // Make us DPI aware on Windows + SDL_SetHint(SDL_HINT_WINDOWS_DPI_AWARENESS, "permonitorv2"); + SDL_SetHint(SDL_HINT_WINDOWS_DPI_SCALING, "1"); + // initialize SDL if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) != 0) { @@ -168,7 +166,6 @@ bool SDL2_Platform::init(const Config& config) flags |= SDL_WINDOW_OPENGL; #ifdef __EMSCRIPTEN__ - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); #else @@ -195,29 +192,6 @@ bool SDL2_Platform::init(const Config& config) return false; } - // Scale Window to monitor for High DPI displays - // Other platforms do this automatically ... Windows we need to explitely do so -#if _WIN32 - { - // find the display index - int display = SDL_GetWindowDisplayIndex(window); - float ddpi, hdpi, vdpi; - if (SDL_GetDisplayDPI(display, &ddpi, &hdpi, &vdpi) == 0) - { - // scale the window up basesd on the display DPI - float hidpiRes = 96; - float dpi = (ddpi / hidpiRes); - if (dpi != 1) - { - SDL_DisplayMode mode; - SDL_GetDesktopDisplayMode(display, &mode); - SDL_SetWindowPosition(window, (int)(mode.w - config.width * dpi) / 2, (int)(mode.h - config.height * dpi) / 2); - SDL_SetWindowSize(window, (int)(config.width * dpi), (int)(config.height * dpi)); - } - } - } -#endif - // set window properties SDL_SetWindowResizable(window, SDL_TRUE); SDL_SetWindowMinimumSize(window, 256, 256); @@ -531,13 +505,15 @@ void SDL2_Platform::set_size(int width, int height) void SDL2_Platform::get_draw_size(int* width, int* height) { - if (App::renderer().type == RendererType::OpenGL) + switch (App::renderer().type) { + case RendererType::OpenGL: SDL_GL_GetDrawableSize(window, width, height); - } - else - { + break; + case RendererType::None: + case RendererType::D3D11: SDL_GetWindowSize(window, width, height); + break; } } @@ -736,4 +712,3 @@ Platform* Platform::try_make_platform(const Config& config) } #endif // BLAH_PLATFORM_SDL2 - diff --git a/src/internal/renderer.h b/src/internal/renderer.h index ade558b..37e50bf 100644 --- a/src/internal/renderer.h +++ b/src/internal/renderer.h @@ -32,6 +32,10 @@ namespace Blah // Called after renderings ends virtual void after_render() = 0; + // Optional implementation to get the drawable backbuffer size in pixels. + // Not all implementations will use this so it can be up to the Platform. + virtual bool get_draw_size(int* w, int* h) { return false; } + // Performs a draw call virtual void render(const DrawCall& pass) = 0; diff --git a/src/internal/renderer_d3d11.cpp b/src/internal/renderer_d3d11.cpp index b38c122..8434979 100644 --- a/src/internal/renderer_d3d11.cpp +++ b/src/internal/renderer_d3d11.cpp @@ -91,7 +91,8 @@ namespace Blah ID3D11DepthStencilView* backbuffer_depth_view = nullptr; // last backbuffer size - Point last_size; + Point drawable_size; + Point last_window_size; struct StoredInputLayout { @@ -136,6 +137,7 @@ namespace Blah void update() override; void before_render() override; void after_render() override; + bool get_draw_size(int* w, int* h) override; void render(const DrawCall& pass) override; void clear_backbuffer(Color color, float depth, u8 stencil, ClearMask mask) override; TextureRef create_texture(int width, int height, TextureFormat format) override; @@ -763,7 +765,7 @@ namespace Blah bool Renderer_D3D11::init() { - last_size = Point(App::backbuffer()->width(), App::backbuffer()->height()); + last_window_size = App::get_size(); // Define Swap Chain DXGI_SWAP_CHAIN_DESC desc = {}; @@ -808,6 +810,10 @@ namespace Blah swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&frame_buffer); if (frame_buffer) { + D3D11_TEXTURE2D_DESC desc; + frame_buffer->GetDesc(&desc); + drawable_size = Point(desc.Width, desc.Height); + device->CreateRenderTargetView(frame_buffer, nullptr, &backbuffer_view); frame_buffer->Release(); } @@ -886,23 +892,30 @@ namespace Blah { HRESULT hr; - auto next_size = Point(App::backbuffer()->width(), App::backbuffer()->height()); - if (last_size != next_size) + auto next_window_size = App::get_size(); + if (last_window_size != next_window_size) { + last_window_size = next_window_size; + // release old buffer if (backbuffer_view) backbuffer_view->Release(); // perform resize - hr = swap_chain->ResizeBuffers(0, next_size.x, next_size.y, DXGI_FORMAT_B8G8R8A8_UNORM, 0); + hr = swap_chain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0); BLAH_ASSERT(SUCCEEDED(hr), "Failed to update Backbuffer on Resize"); - last_size = next_size; // get the new buffer ID3D11Texture2D* frame_buffer = nullptr; hr = swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&frame_buffer); if (SUCCEEDED(hr) && frame_buffer) { + // get backbuffer drawable size + D3D11_TEXTURE2D_DESC desc; + frame_buffer->GetDesc(&desc); + drawable_size = Point(desc.Width, desc.Height); + + // create view hr = device->CreateRenderTargetView(frame_buffer, nullptr, &backbuffer_view); BLAH_ASSERT(SUCCEEDED(hr), "Failed to update Backbuffer on Resize"); frame_buffer->Release(); @@ -910,6 +923,13 @@ namespace Blah } } + bool Renderer_D3D11::get_draw_size(int* w, int* h) + { + *w = drawable_size.x; + *h = drawable_size.y; + return true; + } + void Renderer_D3D11::after_render() { auto hr = swap_chain->Present(1, 0);