From b369916adf0e4fe2ca5582b17c7ac1845f31aecb Mon Sep 17 00:00:00 2001 From: iris Date: Thu, 8 Dec 2022 19:26:24 +0000 Subject: [PATCH] wip --- .../d3d12_gpu_descriptor_handle_allocator.h | 5 ++ .../graphics/d3d12/d3d12_texture_manager.h | 2 +- include/iris/graphics/mesh_manager.h | 2 +- include/iris/graphics/scene.h | 3 - samples/jobs/main.cpp | 63 +++++-------------- samples/sample_browser/main.cpp | 12 ++-- .../samples/render_graph_sample.cpp | 4 +- src/core/CMakeLists.txt | 55 ++++++++-------- src/core/linux/CMakeLists.txt | 3 +- src/core/win32/CMakeLists.txt | 3 +- src/graphics/d3d12/d3d12_renderer.cpp | 2 + src/graphics/d3d12/d3d12_texture_manager.cpp | 6 ++ src/graphics/mesh_manager.cpp | 12 ++-- src/graphics/render_pipeline.cpp | 4 +- src/graphics/scene.cpp | 1 - src/graphics/texture_manager.cpp | 50 +++++++-------- src/graphics/win32/win32_window.cpp | 38 +++++++++-- 17 files changed, 139 insertions(+), 126 deletions(-) diff --git a/include/iris/graphics/d3d12/d3d12_gpu_descriptor_handle_allocator.h b/include/iris/graphics/d3d12/d3d12_gpu_descriptor_handle_allocator.h index d15b017b..ef8680b5 100644 --- a/include/iris/graphics/d3d12/d3d12_gpu_descriptor_handle_allocator.h +++ b/include/iris/graphics/d3d12/d3d12_gpu_descriptor_handle_allocator.h @@ -236,6 +236,11 @@ class D3D12GPUDescriptorHandleAllocator dynamic_indices_[frame] = static_capacity_ + (frame * dynamic_capacity_); } + void reset_static() + { + static_index_ = 0u; + } + private: /** D3D12 handle to descriptor heap. */ ::Microsoft::WRL::ComPtr<::ID3D12DescriptorHeap> descriptor_heap_; diff --git a/include/iris/graphics/d3d12/d3d12_texture_manager.h b/include/iris/graphics/d3d12/d3d12_texture_manager.h index b44c9445..2cb50258 100644 --- a/include/iris/graphics/d3d12/d3d12_texture_manager.h +++ b/include/iris/graphics/d3d12/d3d12_texture_manager.h @@ -25,7 +25,7 @@ namespace iris class D3D12TextureManager : public TextureManager { public: - ~D3D12TextureManager() override = default; + D3D12TextureManager(); protected: /** diff --git a/include/iris/graphics/mesh_manager.h b/include/iris/graphics/mesh_manager.h index afd2edd7..fbb9373e 100644 --- a/include/iris/graphics/mesh_manager.h +++ b/include/iris/graphics/mesh_manager.h @@ -78,7 +78,7 @@ class MeshManager * @returns * Mesh for sprite. */ - const Mesh *sprite(const Colour &colour); + const Mesh *sprite(const Colour &colour, float size = 0.5f); /** * Create a cube mesh. diff --git a/include/iris/graphics/scene.h b/include/iris/graphics/scene.h index 860808ae..8243d183 100644 --- a/include/iris/graphics/scene.h +++ b/include/iris/graphics/scene.h @@ -164,9 +164,6 @@ class Scene /** Collection of tuples. */ std::vector>> entities_; - /** Collection of RenderGraphs. */ - std::vector> render_graphs_; - /** Lighting rig for scene. */ LightingRig lighting_rig_; diff --git a/samples/jobs/main.cpp b/samples/jobs/main.cpp index f23b3848..70e180c8 100644 --- a/samples/jobs/main.cpp +++ b/samples/jobs/main.cpp @@ -50,18 +50,14 @@ struct Ray */ struct Sphere { - Sphere( - const iris::Vector3 &origin, - float radius, - const iris::Colour &colour) + Sphere(const iris::Vector3 &origin, float radius, const iris::Colour &colour) : origin(origin) , radius(radius) , colour(colour) { } - std::tuple intersects( - const Ray &ray) const + std::tuple intersects(const Ray &ray) const { auto L = origin - ray.origin; auto tca = L.dot(ray.direction); @@ -113,11 +109,7 @@ iris::Vector3 random_in_unit_sphere() iris::Vector3 p; do { - p = - iris::Vector3{ - dist1(generator), dist1(generator), dist1(generator)} * - 2.0 - - iris::Vector3(1, 1, 1); + p = iris::Vector3{dist1(generator), dist1(generator), dist1(generator)} * 2.0 - iris::Vector3(1, 1, 1); } while (p.dot(p) >= 1.0); return p; } @@ -165,10 +157,7 @@ iris::Colour trace(const Ray &ray, int depth) if (hit->is_metal) { auto reflect = ray.direction - normal * ray.direction.dot(normal) * 2; - newRay = { - point, - iris::Vector3::normalise( - reflect + random_in_unit_sphere() * hit->rougness)}; + newRay = {point, iris::Vector3::normalise(reflect + random_in_unit_sphere() * hit->rougness)}; newRay.origin += newRay.direction * 0.01f; } else @@ -187,22 +176,10 @@ void go(int, char **) { iris::Logger::instance().ignore_tag("js"); - scene.emplace_back( - iris::Vector3{150.0f, 0.0f, -600.0f}, - 100.0f, - iris::Colour{0.58f, 0.49f, 0.67f}); - scene.emplace_back( - iris::Vector3{-150.0f, 0.0f, -600.0f}, - 100.0f, - iris::Colour{0.99f, 0.78f, 0.84f}); - scene.emplace_back( - iris::Vector3{00.0f, 0.0f, -750.0f}, - 100.0f, - iris::Colour{1.0f, 0.87f, 0.82f}); - scene.emplace_back( - iris::Vector3{0.0f, -10100.0f, -600.0f}, - 10000.0f, - iris::Colour{1.0f, 1.0f, 1.0f}); + scene.emplace_back(iris::Vector3{150.0f, 0.0f, -600.0f}, 100.0f, iris::Colour{0.58f, 0.49f, 0.67f}); + scene.emplace_back(iris::Vector3{-150.0f, 0.0f, -600.0f}, 100.0f, iris::Colour{0.99f, 0.78f, 0.84f}); + scene.emplace_back(iris::Vector3{00.0f, 0.0f, -750.0f}, 100.0f, iris::Colour{1.0f, 0.87f, 0.82f}); + scene.emplace_back(iris::Vector3{0.0f, -10100.0f, -600.0f}, 10000.0f, iris::Colour{1.0f, 1.0f, 1.0f}); scene[2].is_metal = true; scene[2].rougness = 0.9; @@ -237,22 +214,19 @@ void go(int, char **) { pixel += trace( {{0, 0, 0}, - iris::Vector3::normalise( - {dir_x + dist1(generator), - dir_y + dist1(generator), - dir_z})}, + iris::Vector3::normalise({dir_x + dist1(generator), dir_y + dist1(generator), dir_z})}, 1); } pixel *= (1.0 / (float)samples); // clamp colours - pixels[counter + 0u] = static_cast( - (255.0f * std::max(0.0f, std::min(1.0f, (float)pixel.r)))); - pixels[counter + 1u] = static_cast( - (255.0f * std::max(0.0f, std::min(1.0f, (float)pixel.g)))); - pixels[counter + 2u] = static_cast( - (255.0f * std::max(0.0f, std::min(1.0f, (float)pixel.b)))); + pixels[counter + 0u] = + static_cast((255.0f * std::max(0.0f, std::min(1.0f, (float)pixel.r)))); + pixels[counter + 1u] = + static_cast((255.0f * std::max(0.0f, std::min(1.0f, (float)pixel.g)))); + pixels[counter + 2u] = + static_cast((255.0f * std::max(0.0f, std::min(1.0f, (float)pixel.b)))); }); counter += 3u; @@ -272,10 +246,7 @@ void go(int, char **) auto end = std::chrono::high_resolution_clock::now(); LOG_INFO( - "job_sample", - "render time: {}ms", - std::chrono::duration_cast(end - start) - .count()); + "job_sample", "render time: {}ms", std::chrono::duration_cast(end - start).count()); stbi_write_png("render.png", width, height, 3, pixels.data(), 3 * width); @@ -284,7 +255,7 @@ void go(int, char **) int main(int argc, char **argv) { - iris::start(argc, argv, go); + iris::start_debug(argc, argv, go); return 0; } diff --git a/samples/sample_browser/main.cpp b/samples/sample_browser/main.cpp index 4f331f46..b8399b22 100644 --- a/samples/sample_browser/main.cpp +++ b/samples/sample_browser/main.cpp @@ -69,7 +69,9 @@ RenderState create_render_state(iris::Window *window, iris::Camera *camera, std: auto *rg = render_pipeline->create_render_graph(); rg->render_node()->set_colour_input(rg->create(sample_target->colour_texture())); scene->create_entity( - rg, iris::Root::mesh_manager().sprite({1.0f, 1.0f, 1.0f}), iris::Transform{{0.0f}, {}, {800.0f, 800.0f, 1.0f}}); + rg, + iris::Root::mesh_manager().sprite({1.0f, 1.0f, 1.0f}, 1.0f), + iris::Transform{{0.0f}, {}, {1920.0f, 1080.0f, 1.0f}}); iris::PostProcessingDescription post_processing_description{ .bloom = {iris::BloomDescription{6.0f}}, @@ -88,7 +90,7 @@ void go(int, char **) iris::ResourceLoader::instance().set_root_directory("assets"); auto &rtm = iris::Root::render_target_manager(); - auto window = iris::Root::window_manager().create_window(800u, 800u); + auto window = iris::Root::window_manager().create_window(1920u, 1080u); std::size_t sample_number = 0u; iris::Camera camera{iris::CameraType::ORTHOGRAPHIC, window->width(), window->height()}; @@ -103,13 +105,11 @@ void go(int, char **) iris::Looper looper{ 0ms, 16ms, - [&sample = sample](auto, auto) - { + [&sample = sample](auto, auto) { sample->fixed_update(); return true; }, - [&, &sample = sample](std::chrono::microseconds elapsed, auto) - { + [&, &sample = sample](std::chrono::microseconds elapsed, auto) { auto running = true; auto event = window->pump_event(); while (event) diff --git a/samples/sample_browser/samples/render_graph_sample.cpp b/samples/sample_browser/samples/render_graph_sample.cpp index c1b53813..39c2c902 100644 --- a/samples/sample_browser/samples/render_graph_sample.cpp +++ b/samples/sample_browser/samples/render_graph_sample.cpp @@ -158,7 +158,9 @@ RenderGraphSample::RenderGraphSample(iris::Window *window, iris::RenderPipeline graph3->create(sphere1_rt->depth_texture()))); scene3->create_entity( - graph3, mesh_manager.sprite({}), iris::Transform{iris::Vector3{}, {}, iris::Vector3{800.0f, 800.0f, 1.0f}}); + graph3, + mesh_manager.sprite({}, 1.0f), + iris::Transform{iris::Vector3{}, {}, iris::Vector3{1920.0f, 1080.0f, 1.0f}}); auto *graph4 = render_pipeline.create_render_graph(); graph4->render_node()->set_colour_input(graph4->create( diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index a422b4aa..bfce88c1 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -11,33 +11,34 @@ elseif(IRIS_PLATFORM MATCHES "LINUX") endif() target_sources(iris PRIVATE - ${INCLUDE_ROOT}/auto_release.h - ${INCLUDE_ROOT}/camera.h - ${INCLUDE_ROOT}/camera_type.h - ${INCLUDE_ROOT}/colour.h - ${INCLUDE_ROOT}/data_buffer.h - ${INCLUDE_ROOT}/error_handling.h - ${INCLUDE_ROOT}/exception.h - ${INCLUDE_ROOT}/looper.h - ${INCLUDE_ROOT}/matrix4.h - ${INCLUDE_ROOT}/object_pool.h + ${INCLUDE_ROOT}/auto_release.h + ${INCLUDE_ROOT}/camera.h + ${INCLUDE_ROOT}/camera_type.h + ${INCLUDE_ROOT}/colour.h + ${INCLUDE_ROOT}/data_buffer.h + ${INCLUDE_ROOT}/error_handling.h + ${INCLUDE_ROOT}/exception.h + ${INCLUDE_ROOT}/looper.h + ${INCLUDE_ROOT}/matrix4.h + ${INCLUDE_ROOT}/object_pool.h ${INCLUDE_ROOT}/profiler.h ${INCLUDE_ROOT}/profiler_analyser.h - ${INCLUDE_ROOT}/quaternion.h - ${INCLUDE_ROOT}/random.h - ${INCLUDE_ROOT}/resource_loader.h - ${INCLUDE_ROOT}/root.h - ${INCLUDE_ROOT}/start.h - ${INCLUDE_ROOT}/static_buffer.h - ${INCLUDE_ROOT}/thread.h - ${INCLUDE_ROOT}/transform.h - ${INCLUDE_ROOT}/utils.h - ${INCLUDE_ROOT}/vector3.h - camera.cpp - exception.cpp - looper.cpp + ${INCLUDE_ROOT}/quaternion.h + ${INCLUDE_ROOT}/random.h + ${INCLUDE_ROOT}/resource_loader.h + ${INCLUDE_ROOT}/root.h + ${INCLUDE_ROOT}/start.h + ${INCLUDE_ROOT}/static_buffer.h + ${INCLUDE_ROOT}/thread.h + ${INCLUDE_ROOT}/transform.h + ${INCLUDE_ROOT}/utils.h + ${INCLUDE_ROOT}/vector3.h + camera.cpp + exception.cpp + looper.cpp profiler_analyser.cpp - random.cpp - root.cpp - transform.cpp - utils.cpp) + random.cpp + root.cpp + transform.cpp + utils.cpp +) diff --git a/src/core/linux/CMakeLists.txt b/src/core/linux/CMakeLists.txt index bf037657..b77a754d 100644 --- a/src/core/linux/CMakeLists.txt +++ b/src/core/linux/CMakeLists.txt @@ -6,4 +6,5 @@ target_sources(iris PRIVATE semaphore.cpp start.cpp static_buffer.cpp - thread.cpp) + thread.cpp +) diff --git a/src/core/win32/CMakeLists.txt b/src/core/win32/CMakeLists.txt index 07a16d0d..8d6cf4a8 100644 --- a/src/core/win32/CMakeLists.txt +++ b/src/core/win32/CMakeLists.txt @@ -5,4 +5,5 @@ target_sources(iris PRIVATE profiler.cpp semaphore.cpp start.cpp - thread.cpp) + thread.cpp +) diff --git a/src/graphics/d3d12/d3d12_renderer.cpp b/src/graphics/d3d12/d3d12_renderer.cpp index f0b03ae2..399ee9e3 100644 --- a/src/graphics/d3d12/d3d12_renderer.cpp +++ b/src/graphics/d3d12/d3d12_renderer.cpp @@ -553,6 +553,8 @@ void D3D12Renderer::do_set_render_pipeline(std::function build_queue) ::WaitForSingleObject(fence_event_, INFINITE); ++frames_[frame_index_].fence_value; + D3D12DescriptorManager::gpu_allocator(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV).reset_static(); + build_queue(); instance_data_buffers_.clear(); diff --git a/src/graphics/d3d12/d3d12_texture_manager.cpp b/src/graphics/d3d12/d3d12_texture_manager.cpp index 69b340ee..0907e86b 100644 --- a/src/graphics/d3d12/d3d12_texture_manager.cpp +++ b/src/graphics/d3d12/d3d12_texture_manager.cpp @@ -22,6 +22,12 @@ namespace iris { +D3D12TextureManager::D3D12TextureManager() +{ + static_cast(blank_texture()); + static_cast(blank_cube_map()); +} + std::unique_ptr D3D12TextureManager::do_create( const DataBuffer &data, std::uint32_t width, diff --git a/src/graphics/mesh_manager.cpp b/src/graphics/mesh_manager.cpp index 50951b2f..601ef51b 100644 --- a/src/graphics/mesh_manager.cpp +++ b/src/graphics/mesh_manager.cpp @@ -36,20 +36,20 @@ MeshManager::MeshManager(bool flip_uvs_on_load) { } -const Mesh *MeshManager::sprite(const Colour &colour) +const Mesh *MeshManager::sprite(const Colour &colour, float size) { // create a unique for this mesh std::stringstream strm{}; - strm << "!sprite" << colour; + strm << "!sprite" << colour << ":" << size; const auto id = strm.str(); if (loaded_meshes_.count(id) == 0u) { std::vector vertices{ - {{-1.0, 1.0, 0.0f}, {}, colour, {0.0f, 0.0f, 0.0f}}, - {{1.0, 1.0, 0.0f}, {}, colour, {1.0f, 0.0f, 0.0f}}, - {{1.0, -1.0, 0.0f}, {}, colour, {1.0f, 1.0f, 0.0f}}, - {{-1.0, -1.0, 0.0f}, {}, colour, {0.0f, 1.0f, 0.0f}}}; + {{-size, size, 0.0f}, {}, colour, {0.0f, 0.0f, 0.0f}}, + {{size, size, 0.0f}, {}, colour, {1.0f, 0.0f, 0.0f}}, + {{size, -size, 0.0f}, {}, colour, {1.0f, 1.0f, 0.0f}}, + {{-size, -size, 0.0f}, {}, colour, {0.0f, 1.0f, 0.0f}}}; std::vector indices{0, 2, 1, 3, 2, 0}; diff --git a/src/graphics/render_pipeline.cpp b/src/graphics/render_pipeline.cpp index ad0ef39c..385473ee 100644 --- a/src/graphics/render_pipeline.cpp +++ b/src/graphics/render_pipeline.cpp @@ -413,8 +413,8 @@ const RenderTarget *RenderPipeline::add_pass( create_render_graph_callback(rg, target); scene->create_entity( rg, - Root::mesh_manager().sprite({}), - Transform({}, {}, {static_cast(width_), static_cast(height_), 1. - 1})); + Root::mesh_manager().sprite({}, 1.0f), + Transform({}, {}, {static_cast(width_), static_cast(height_), 1.0f})); auto *pass = create_engine_render_pass(scene); pass->camera = camera; diff --git a/src/graphics/scene.cpp b/src/graphics/scene.cpp index b677519b..bc3c8c71 100644 --- a/src/graphics/scene.cpp +++ b/src/graphics/scene.cpp @@ -18,7 +18,6 @@ namespace iris { Scene::Scene(RenderGraph *default_render_graph, bool *dirty_pipeline) : entities_() - , render_graphs_() , lighting_rig_() , default_render_graph_(default_render_graph) , dirty_pipeline_(dirty_pipeline) diff --git a/src/graphics/texture_manager.cpp b/src/graphics/texture_manager.cpp index 7aa23221..5e2b9777 100644 --- a/src/graphics/texture_manager.cpp +++ b/src/graphics/texture_manager.cpp @@ -250,8 +250,9 @@ CubeMap *TextureManager::load( std::all_of( std::cbegin(parsed_sides) + 1u, std::cend(parsed_sides), - [width, height](const auto &side) - { return (std::get<1>(side) == width) && (std::get<2>(side) == height); }), + [width, height](const auto &side) { + return (std::get<1>(side) == width) && (std::get<2>(side) == height); + }), "cube map images must all have the same dimensions"); auto cube_map = do_create( @@ -373,10 +374,10 @@ void TextureManager::unload(const Texture *texture) if (texture != blank_texture()) { // find the texture that we want to unload - auto loaded = std::find_if( - std::begin(loaded_textures_), - std::end(loaded_textures_), - [texture](const auto &element) { return element.second.asset.get() == texture; }); + auto loaded = + std::find_if(std::begin(loaded_textures_), std::end(loaded_textures_), [texture](const auto &element) { + return element.second.asset.get() == texture; + }); expect(loaded != std::cend(loaded_textures_), "texture has not been loaded"); @@ -401,10 +402,10 @@ void TextureManager::unload(const CubeMap *cube_map) if (cube_map != blank_cube_map()) { // find the texture that we want to unload - auto loaded = std::find_if( - std::begin(loaded_cube_maps_), - std::end(loaded_cube_maps_), - [cube_map](const auto &element) { return element.second.asset.get() == cube_map; }); + auto loaded = + std::find_if(std::begin(loaded_cube_maps_), std::end(loaded_cube_maps_), [cube_map](const auto &element) { + return element.second.asset.get() == cube_map; + }); expect(loaded != std::cend(loaded_cube_maps_), "cube_map has not been loaded"); @@ -428,10 +429,10 @@ void TextureManager::unload(const Sampler *sampler) // don't unload the default sampler! if ((sampler != default_texture_sampler()) && (sampler != default_cube_map_sampler())) { - auto loaded = std::find_if( - std::begin(loaded_samplers_), - std::end(loaded_samplers_), - [sampler](const auto &element) { return element.second.asset.get() == sampler; }); + auto loaded = + std::find_if(std::begin(loaded_samplers_), std::end(loaded_samplers_), [sampler](const auto &element) { + return element.second.asset.get() == sampler; + }); expect(loaded != std::end(loaded_samplers_), "sampler has not been loaded"); @@ -550,10 +551,9 @@ std::vector TextureManager::textures() const std::back_inserter(textures), [](const auto &element) { return element.second.asset.get(); }); - std::sort( - std::begin(textures), - std::end(textures), - [](const Texture *a, const Texture *b) { return a->index() < b->index(); }); + std::sort(std::begin(textures), std::end(textures), [](const Texture *a, const Texture *b) { + return a->index() < b->index(); + }); return textures; } @@ -568,10 +568,9 @@ std::vector TextureManager::samplers() const std::back_inserter(samplers), [](const auto &element) { return element.second.asset.get(); }); - std::sort( - std::begin(samplers), - std::end(samplers), - [](const Sampler *a, const Sampler *b) { return a->index() < b->index(); }); + std::sort(std::begin(samplers), std::end(samplers), [](const Sampler *a, const Sampler *b) { + return a->index() < b->index(); + }); return samplers; } @@ -586,10 +585,9 @@ std::vector TextureManager::cube_maps() const std::back_inserter(cube_maps), [](const auto &element) { return element.second.asset.get(); }); - std::sort( - std::begin(cube_maps), - std::end(cube_maps), - [](const CubeMap *a, const CubeMap *b) { return a->index() < b->index(); }); + std::sort(std::begin(cube_maps), std::end(cube_maps), [](const CubeMap *a, const CubeMap *b) { + return a->index() < b->index(); + }); return cube_maps; } diff --git a/src/graphics/win32/win32_window.cpp b/src/graphics/win32/win32_window.cpp index 95c5cd89..47c99eeb 100644 --- a/src/graphics/win32/win32_window.cpp +++ b/src/graphics/win32/win32_window.cpp @@ -154,6 +154,7 @@ LRESULT CALLBACK window_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) LRESULT result = 0; static std::set pressed{}; + // static auto handle_leave = false; switch (uMsg) { @@ -185,8 +186,34 @@ LRESULT CALLBACK window_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) event_queue.emplace( iris::ScrollWheelEvent{static_cast(GET_WHEEL_DELTA_WPARAM(wParam)) / WHEEL_DELTA}); break; + // case WM_MOUSELEAVE: + // ::SetCursorPos(0, 0); + // handle_leave = false; + // break; case WM_INPUT: { + // if (!handle_leave) + //{ + // handle_leave = true; + + // TRACKMOUSEEVENT tme{}; + // tme.cbSize = sizeof(TRACKMOUSEEVENT); + // tme.dwFlags = TME_LEAVE; + // tme.hwndTrack = hWnd; + + // ::TrackMouseEvent(&tme); + //} + + static auto once = false; + + if (!once) + { + // once = true; + RECT rect{}; + ::GetWindowRect(hWnd, &rect); + ::ClipCursor(&rect); + } + UINT dwSize = sizeof(RAWINPUT); BYTE lpb[sizeof(RAWINPUT)]; @@ -312,13 +339,16 @@ Win32Window::Win32Window(std::uint32_t width, std::uint32_t height) } auto clip_rect = rect; - clip_rect.left += (screen_width / 2) - ((width_ * scale) / 2), - clip_rect.bottom += (screen_height / 2) - ((height_ * scale) / 2), - clip_rect.right += (screen_width / 2) - ((width_ * scale) / 2), - clip_rect.top += (screen_height / 2) - ((height_ * scale) / 2); + // clip_rect.left += (screen_width / 2) - ((width_ * scale) / 2), + // clip_rect.bottom += (screen_height / 2) - ((height_ * scale) / 2), + // clip_rect.right += (screen_width / 2) - ((width_ * scale) / 2), + // clip_rect.top += (screen_height / 2) - ((height_ * scale) / 2); // confine cursor to window ensure(::ClipCursor(&clip_rect) == TRUE, "could not confine cursor"); + ensure( + ::SetCursorPos(rect.left + (screen_width / 2), rect.top + (screen_height / 2)) == TRUE, + "could not centre cursor"); } std::uint32_t Win32Window::screen_scale() const