From 22b8af7bfc5f2733dd7b0a2af2ae6f5e035487ec Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Thu, 2 Apr 2026 16:52:10 +0200 Subject: [PATCH] update --- implementations/Crafter.Graphics-Device.cpp | 9 +-- implementations/Crafter.Graphics-Window.cpp | 79 ++++++++++++++++++++- interfaces/Crafter.Graphics-Window.cppm | 10 +++ project.json | 2 +- 4 files changed, 90 insertions(+), 10 deletions(-) diff --git a/implementations/Crafter.Graphics-Device.cpp b/implementations/Crafter.Graphics-Device.cpp index 4eb86b3..acf4ca1 100644 --- a/implementations/Crafter.Graphics-Device.cpp +++ b/implementations/Crafter.Graphics-Device.cpp @@ -69,7 +69,6 @@ const char* const deviceExtensionNames[] = { "VK_KHR_acceleration_structure", "VK_KHR_deferred_host_operations", "VK_KHR_ray_tracing_pipeline", - "VK_KHR_ray_tracing_position_fetch" }; const char* const layerNames[] = { "VK_LAYER_KHRONOS_validation" @@ -605,15 +604,9 @@ void Device::Initialize() { .bufferDeviceAddress = VK_TRUE }; - VkPhysicalDeviceRayTracingPositionFetchFeaturesKHR vkPhysicalDeviceRayTracingPositionFetchFeatures { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR, - .pNext = &features12, - .rayTracingPositionFetch = VK_TRUE - }; - VkPhysicalDeviceRayTracingPipelineFeaturesKHR physicalDeviceRayTracingPipelineFeatures{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR, - .pNext = &vkPhysicalDeviceRayTracingPositionFetchFeatures, + .pNext = &features12, .rayTracingPipeline = VK_TRUE }; diff --git a/implementations/Crafter.Graphics-Window.cpp b/implementations/Crafter.Graphics-Window.cpp index 02079e9..2786b25 100644 --- a/implementations/Crafter.Graphics-Window.cpp +++ b/implementations/Crafter.Graphics-Window.cpp @@ -307,7 +307,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { element->onMouseEnter.Invoke(); } } else if(element->mouseHover) { - element->mouseHover = false + element->mouseHover = false; element->onMouseLeave.Invoke(); } } @@ -367,6 +367,14 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { break; } + case WM_SETCURSOR: { + if (LOWORD(lParam) == HTCLIENT && window->cursorHandle) { + SetCursor(window->cursorHandle); + return TRUE; + } + break; + } + default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; @@ -596,6 +604,34 @@ void Window::SetCusorImage(std::uint16_t sizeX, std::uint16_t sizeY) { wl_surface_damage(cursorSurface, 0, 0, sizeX, sizeY); wl_surface_commit(cursorSurface); #endif + #ifdef CRAFTER_GRAPHICS_WINDOW_WIN32 + if (cursorBitmap) { + DeleteObject(cursorBitmap); + } + if (cursorHandle) { + DestroyCursor(cursorHandle); + cursorHandle = nullptr; + } + + BITMAPINFO bmi = {}; + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = sizeX; + bmi.bmiHeader.biHeight = -(int)sizeY; // top-down + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + + HDC hdc = GetDC(nullptr); + cursorBitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, reinterpret_cast(&cursorRenderer.buffer[0]), nullptr, 0); + ReleaseDC(nullptr, hdc); + + if (!cursorBitmap) { + throw std::runtime_error("CreateDIBSection failed for cursor"); + } + + cursorSizeX = sizeX; + cursorSizeY = sizeY; + #endif } void Window::SetCusorImageDefault() { @@ -604,9 +640,21 @@ void Window::SetCusorImageDefault() { wl_surface_destroy(cursorSurface); cursorSurface = nullptr; #endif + #ifdef CRAFTER_GRAPHICS_WINDOW_WIN32 + if (cursorHandle) { + DestroyCursor(cursorHandle); + cursorHandle = nullptr; + } + if (cursorBitmap) { + DeleteObject(cursorBitmap); + cursorBitmap = nullptr; + } + // Setting nullptr will make WM_SETCURSOR fall through to the default + #endif } void Window::UpdateCursorImage() { + #ifdef CRAFTER_GRAPHICS_WINDOW_WAYLAND cursorRenderer.Render(0); for(std::uint32_t i = 0; i < cursorBufferOldSize / 4; i++) { std::swap(cursorRenderer.buffer[0][i].b, cursorRenderer.buffer[0][i].r); @@ -614,6 +662,35 @@ void Window::UpdateCursorImage() { wl_surface_attach(cursorSurface, cursorWlBuffer, 0, 0); wl_surface_damage(cursorSurface, 0, 0, 9999999, 99999999); wl_surface_commit(cursorSurface); + #endif + #ifdef CRAFTER_GRAPHICS_WINDOW_WIN32 + cursorRenderer.Render(0); + + // Swap R and B channels (renderer is RGBA, GDI DIB is BGRA) + for (std::uint32_t i = 0; i < (std::uint32_t)(cursorSizeX * cursorSizeY); i++) { + std::swap(cursorRenderer.buffer[0][i].r, cursorRenderer.buffer[0][i].b); + } + + // Create a mask bitmap (all zeros = fully opaque, alpha comes from color bitmap) + HBITMAP hMask = CreateBitmap(cursorSizeX, cursorSizeY, 1, 1, nullptr); + + ICONINFO ii = {}; + ii.fIcon = FALSE; + ii.xHotspot = 0; + ii.yHotspot = 0; + ii.hbmMask = hMask; + ii.hbmColor = cursorBitmap; + + if (cursorHandle) { + DestroyCursor(cursorHandle); + } + cursorHandle = (HCURSOR)CreateIconIndirect(&ii); + DeleteObject(hMask); + + if (cursorHandle) { + SetCursor(cursorHandle); + } + #endif } void Window::StartSync() { diff --git a/interfaces/Crafter.Graphics-Window.cppm b/interfaces/Crafter.Graphics-Window.cppm index ba07108..e1ba38e 100644 --- a/interfaces/Crafter.Graphics-Window.cppm +++ b/interfaces/Crafter.Graphics-Window.cppm @@ -41,6 +41,9 @@ module; #ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN #include "vulkan/vulkan.h" #endif +#ifdef CRAFTER_GRAPHICS_WINDOW_WIN32 +#include +#endif export module Crafter.Graphics:Window; import std; @@ -128,6 +131,13 @@ export namespace Crafter { void LogTiming(); #endif + #ifdef CRAFTER_GRAPHICS_WINDOW_WIN32 + HBITMAP cursorBitmap = nullptr; + HCURSOR cursorHandle = nullptr; + std::uint16_t cursorSizeX = 0; + std::uint16_t cursorSizeY = 0; + #endif + #ifdef CRAFTER_GRAPHICS_WINDOW_WAYLAND float scale; #ifdef CRAFTER_GRAPHICS_RENDERER_SOFTWARE diff --git a/project.json b/project.json index 6ba2874..19f463b 100644 --- a/project.json +++ b/project.json @@ -53,7 +53,7 @@ }, { "name": "win32", - "libs": ["kernel32", "user32"], + "libs": ["kernel32", "user32", "gdi32"], "extends": ["base"], "defines": [ {