From b4d24e8f2cb4838acc0b827f007e7faa609039ba Mon Sep 17 00:00:00 2001 From: ladevieq Date: Wed, 24 Dec 2025 15:35:21 +0100 Subject: Use build.bat for building Everything is included in main.cpp Do not rely on vcpkg anymore --- src/bvh.cpp | 40 ++++++++++++++++---------------- src/camera.cpp | 10 ++++---- src/gltf.cpp | 18 +++++---------- src/mat4.cpp | 4 ++++ src/scene.cpp | 10 ++++---- src/texture.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/utils.cpp | 33 +++++++++++++++++---------- src/vec3.cpp | 50 ++++++++++++++++++++++++++++++++-------- src/vulkan-loader.cpp | 6 ++--- src/window.cpp | 63 ++++++++++++++++++++++++++++++++++++--------------- 10 files changed, 215 insertions(+), 82 deletions(-) create mode 100644 src/mat4.cpp create mode 100644 src/texture.cpp (limited to 'src') diff --git a/src/bvh.cpp b/src/bvh.cpp index aaa6a42..8e62a93 100644 --- a/src/bvh.cpp +++ b/src/bvh.cpp @@ -3,7 +3,8 @@ #include #include -#include +#include +#include // bvh::bvh(std::vector& spheres, std::vector& packed_nodes) // :spheres(spheres) { @@ -60,8 +61,8 @@ bvh::bvh(std::vector& triangles, std::vector& packed_ temp_nodes[0] = temp_node(); - temp_nodes[0].bounding_box = compute_bounds(0, triangles.size()); - subdivide(0, 0, triangles.size()); + temp_nodes[0].bounding_box = compute_bounds(0, static_cast(triangles.size())); + subdivide(0, 0, static_cast(triangles.size())); set_depth_first_order(); @@ -71,13 +72,13 @@ bvh::bvh(std::vector& triangles, std::vector& packed_ node.primitive_id = old_node.primitive_id; - node.min[0] = old_node.bounding_box.minimum.v[0]; - node.min[1] = old_node.bounding_box.minimum.v[1]; - node.min[2] = old_node.bounding_box.minimum.v[2]; + node.min[0] = old_node.bounding_box.minimum.get<0>(); + node.min[1] = old_node.bounding_box.minimum.get<1>(); + node.min[2] = old_node.bounding_box.minimum.get<2>(); - node.max[0] = old_node.bounding_box.maximum.v[0]; - node.max[1] = old_node.bounding_box.maximum.v[1]; - node.max[2] = old_node.bounding_box.maximum.v[2]; + node.max[0] = old_node.bounding_box.maximum.get<0>(); + node.max[1] = old_node.bounding_box.maximum.get<1>(); + node.max[2] = old_node.bounding_box.maximum.get<2>(); if (old_node.next_id != -1) { node.next_id = temp_nodes[old_node.next_id].df_id; @@ -89,13 +90,13 @@ bvh::bvh(std::vector& triangles, std::vector& packed_ // BVH exporter for graphviz //------------------------- void bvh::exporter() { - std::cout << "digraph bvh {\n"; + printf("digraph bvh {\n"); traverse_depth_first(temp_nodes, 0); // traverse_depth_first_ordered(-1, 0); - std::cout << "}\n"; + printf("}\n"); } bool bvh::traverse_depth_first(std::vector& nodes, int32_t id) { @@ -104,8 +105,8 @@ bool bvh::traverse_depth_first(std::vector& nodes, int32_t id) { } if (traverse_depth_first(nodes, nodes[id].left_id)) { - std::cout << id << " -> " << nodes[id].left_id << ";\n"; - std::cout << id << " -> " << nodes[id].left_id + 1 << ";\n"; + printf("%d -> %d;\n", id, nodes[id].left_id); + printf("%d -> %d;\n", id, nodes[id].left_id + 1); traverse_depth_first(nodes, nodes[id].left_id + 1); } @@ -121,17 +122,17 @@ int32_t bvh::traverse_depth_first_ordered(std::vector& nodes, int32_t int32_t left = id + 1; int32_t next_id; - std::cout << "\t " << parent_id << " -> " << id << ";\n"; + printf("\t %d -> %d;\n", parent_id, id); next_id = traverse_depth_first_ordered(nodes, id, left); if (next_id != -1) { return traverse_depth_first_ordered(nodes, id, next_id); } } else if (nodes[id].next_id != -1) { - std::cout << "\t " << parent_id << " -> " << id << ";\n"; + printf("\t %d -> %d;\n", parent_id, id); return nodes[id].next_id; } else { - std::cout << "\t " << parent_id << " -> " << id << ";\n"; + printf("\t %d -> %d;\n", parent_id, id); } return -1; @@ -148,7 +149,8 @@ aabb bvh::compute_bounds(uint32_t begin, uint32_t end) { } void bvh::subdivide(uint32_t parent_id, uint32_t begin, uint32_t end) { - const size_t count = end - begin; + assert(end > begin); + const uint32_t count = end - begin; if (count == 1) { temp_nodes[parent_id] = std::move(leafs[begin]); @@ -210,7 +212,7 @@ void bvh::subdivide(uint32_t parent_id, uint32_t begin, uint32_t end) { auto& primitive = triangles[leafs[i].primitive_id]; // auto& primitive = spheres[leafs[i].primitive_id]; auto normalized_offset = (primitive.center[split_axis] - centroid_bounds.minimum[split_axis]) / split_axis_size; - uint32_t bucket_index = normalized_offset * buckets_count; + uint32_t bucket_index = static_cast(normalized_offset * buckets_count); if (bucket_index == buckets_count) { bucket_index -= 1; } @@ -242,7 +244,7 @@ void bvh::subdivide(uint32_t parent_id, uint32_t begin, uint32_t end) { float min_cost = buckets_cost[0]; uint32_t min_cost_bucket = 0; - for (size_t bucket_index = 1; bucket_index < buckets_count - 1; bucket_index++) { + for (uint32_t bucket_index = 1; bucket_index < buckets_count - 1; bucket_index++) { if (buckets_cost[bucket_index] < min_cost) { min_cost = buckets_cost[bucket_index]; min_cost_bucket = bucket_index; diff --git a/src/camera.cpp b/src/camera.cpp index 6950fec..4c63630 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -1,5 +1,3 @@ -#include - #include "camera.hpp" #include "utils.hpp" @@ -38,8 +36,12 @@ void camera::move(const vec3& v) { } void camera::rotate_y(float theta) { - forward.v[0] = forward.v[0] * cos(theta) - forward.v[2] * sin(theta); - forward.v[2] = forward.v[0] * sin(theta) + forward.v[2] * cos(theta); + float v0 = forward.get<0>(); + float v2 = forward.get<2>(); + float new_v0 = v0 * cos(theta) - v2 * sin(theta); + float new_v2 = v0 * sin(theta) + v2 * cos(theta); + forward.set<0>(new_v0); + forward.set<2>(new_v2); forward.normalize(); right = forward.cross(vec3{ 0.0, 1.0, 0.0 }).normalize(); diff --git a/src/gltf.cpp b/src/gltf.cpp index e868357..4cdfdce 100644 --- a/src/gltf.cpp +++ b/src/gltf.cpp @@ -1,8 +1,6 @@ #include "gltf.hpp" -#include #include -#include #include #ifndef API_TEST @@ -20,10 +18,6 @@ #include "vk-renderer.hpp" #endif -#ifdef TRACY_ENABLE -#include "tracy/Tracy.hpp" -#endif - gltf::gltf(const std::filesystem::path& filepath) { auto parent_path = filepath.parent_path(); std::fstream f{ filepath }; @@ -50,7 +44,7 @@ gltf::gltf(const std::filesystem::path& filepath) { load_meshes(); auto& root_children = scene["nodes"]; - uint32_t root_children_count = scene["nodes"].size(); + size_t root_children_count = scene["nodes"].size(); root_node.children.resize(root_children_count); for (size_t child_index = 0; child_index < root_children_count; child_index++) { @@ -163,7 +157,7 @@ void gltf::load_textures(const std::filesystem::path& path) { }; graphics_command_buffer command_buffers[buffers_count]; - device.allocate_command_buffers(command_buffers, buffers_count, QueueType::GRAPHICS); + device.allocate_command_buffers(command_buffers, buffers_count, QueueType::GRAPHICS, "upload_buffer"); auto buffer_index = 0U; auto command_buffer = command_buffers[buffer_index]; auto buffer_handle = staging_buffers_handle[buffer_index]; @@ -279,10 +273,10 @@ void gltf::load_materials() { if (pbr_params.contains("baseColorFactor")) { const auto& base_color = pbr_params["baseColorFactor"]; - material.base_color.v[0] = base_color[0].get(); - material.base_color.v[1] = base_color[1].get(); - material.base_color.v[2] = base_color[2].get(); - material.base_color.v[3] = base_color[3].get(); + material.base_color.set<0>(base_color[0].get()); + material.base_color.set<1>(base_color[1].get()); + material.base_color.set<2>(base_color[2].get()); + material.base_color.arr[3] = base_color[3].get(); // Since we use a vec3 for colors we are not allowed toset fourth value with set<3> } else { material.base_color = vec3(1.f); } diff --git a/src/mat4.cpp b/src/mat4.cpp new file mode 100644 index 0000000..d74d617 --- /dev/null +++ b/src/mat4.cpp @@ -0,0 +1,4 @@ +#include "mat4.hpp" + +mat4 mat4::projection() { +} diff --git a/src/scene.cpp b/src/scene.cpp index b70026a..9d6b981 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -1,6 +1,6 @@ #include "scene.hpp" -#include +#include #include #ifdef API_TEST @@ -11,7 +11,7 @@ #include "gltf.hpp" #include "bvh.hpp" -#include "material.hpp" +// #include "material.hpp" // void scene::random_scene() { // material ground_material = { { 0.5, 0.5, 0.5 } }; @@ -146,9 +146,9 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) auto triangle_offset = triangles_offset * 3 + index_offset; - indices[triangle_offset] = (submesh_level_index_1 + vertex_offset) | (0xff000000 & (materials.size() << 8)); - indices[triangle_offset + 1] = (submesh_level_index_2 + vertex_offset) | (0xff000000 & (materials.size() << 16)); - indices[triangle_offset + 2] = (submesh_level_index_3 + vertex_offset) | (0xff000000 & (materials.size() << 24)); + indices[triangle_offset] = static_cast((submesh_level_index_1 + vertex_offset) | (0xff000000 & (materials.size() << 8))); + indices[triangle_offset + 1] = static_cast((submesh_level_index_2 + vertex_offset) | (0xff000000 & (materials.size() << 16))); + indices[triangle_offset + 2] = static_cast((submesh_level_index_3 + vertex_offset) | (0xff000000 & (materials.size() << 24))); } // const auto& albedo_image = vkrenderer::api.get_image(material.base_color_texture->device_image); diff --git a/src/texture.cpp b/src/texture.cpp new file mode 100644 index 0000000..936b380 --- /dev/null +++ b/src/texture.cpp @@ -0,0 +1,63 @@ +#include "texture.hpp" + +#include + +void Texture::create_device_image() { + VkImageCreateInfo img_create_info = {}; + img_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + img_create_info.pNext = VK_NULL_HANDLE; + img_create_info.flags = 0; + img_create_info.imageType = description.type; + img_create_info.format = description.format; + img_create_info.extent = description.size; + img_create_info.mipLevels = 1; + img_create_info.arrayLayers = 1; + img_create_info.samples = VK_SAMPLE_COUNT_1_BIT; + img_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; + img_create_info.usage = description.usages; + img_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + img_create_info.queueFamilyIndexCount = 0; + img_create_info.pQueueFamilyIndices = nullptr; + img_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + VmaAllocationCreateInfo alloc_create_info = {}; + alloc_create_info.usage = VMA_MEMORY_USAGE_GPU_ONLY; + + VKRESULT(vmaCreateImage(context.allocator, &img_create_info, &alloc_create_info, device_image, &image->alloc, &alloc_info)) + + + // image->subresource_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + // image->subresource_range.baseMipLevel = 0; + // image->subresource_range.levelCount = 1; + // image->subresource_range.baseArrayLayer = 0; + // image->subresource_range.layerCount = 1; + + // VkImageViewCreateInfo image_view_create_info = {}; + // image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + // image_view_create_info.pNext = nullptr; + // image_view_create_info.flags = 0; + // image_view_create_info.image = image->handle; + // image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + // image_view_create_info.format = format; + // image_view_create_info.components = { + // VK_COMPONENT_SWIZZLE_IDENTITY, + // VK_COMPONENT_SWIZZLE_IDENTITY, + // VK_COMPONENT_SWIZZLE_IDENTITY, + // VK_COMPONENT_SWIZZLE_IDENTITY + // }; + // image_view_create_info.subresourceRange = image->subresource_range; + + // VKRESULT(vkCreateImageView(context.device, &image_view_create_info, VK_NULL_HANDLE, &image->view)) + + // image->device_ptr = alloc_info.pMappedData; + + if ((usages & VK_IMAGE_USAGE_STORAGE_BIT) != 0U) { + image->bindless_storage_index = bindless_descriptor.allocate(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); + update_descriptor_image(image_handle, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE); + } + + if ((usages & VK_IMAGE_USAGE_SAMPLED_BIT) != 0U) { + image->bindless_sampled_index = bindless_descriptor.allocate(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); + update_descriptor_image(image_handle, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); + } +} diff --git a/src/utils.cpp b/src/utils.cpp index 9994064..ffe50b3 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -66,27 +66,30 @@ void log_last_error() { std::cerr << error_message << std::endl; } -bool watcher::watch_file(std::filesystem::path&& filepath, std::function callback) { - if (!std::filesystem::exists(filepath)) +bool watcher::watch_file(const char* filepath, watcher::func callback) { + DWORD attrib = GetFileAttributes(filepath); + if (attrib == INVALID_FILE_ATTRIBUTES) return false; - if (!watcher::watch_dir(filepath.parent_path())) + std::filesystem::path path(filepath); + if (!watcher::watch_dir(path.parent_path().string().c_str())) return false; - auto [_, is_inserted] = watcher::callbacks.emplace(filepath.filename().string(), callback); + auto [_, is_inserted] = watcher::callbacks.emplace(filepath, callback); return is_inserted; } -bool watcher::watch_dir(std::filesystem::path&& dir_path) { - if (!std::filesystem::exists(dir_path)) +bool watcher::watch_dir(const char* dir_path) { + DWORD attrib = GetFileAttributes(dir_path); + if (attrib == INVALID_FILE_ATTRIBUTES || (attrib & FILE_ATTRIBUTE_DIRECTORY) == 0U ) return false; - if (watcher::watched_dirs.find(dir_path.string()) != watcher::watched_dirs.end()) + if (watcher::watched_dirs.find(dir_path) != watcher::watched_dirs.end()) return true; - HANDLE dir_handle = CreateFileW( - dir_path.c_str(), + HANDLE dir_handle = CreateFileA( + dir_path, FILE_LIST_DIRECTORY, FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr, @@ -100,7 +103,7 @@ bool watcher::watch_dir(std::filesystem::path&& dir_path) { return false; } - auto [dir, _] = watcher::watched_dirs.emplace(dir_path.string(), watch_data{ .dir_handle = dir_handle }); + auto [dir, _] = watcher::watched_dirs.emplace(dir_path, watch_data{ .dir_handle = dir_handle, .overlapped{}, .buffer{} }); if (FAILED(ReadDirectoryChangesW(dir_handle, dir->second.buffer, sizeof(watch_data::buffer), FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, nullptr, &dir->second.overlapped, nullptr))) { log_last_error(); @@ -119,10 +122,16 @@ void watcher::pull_changes() { auto* dir_event = (PFILE_NOTIFY_INFORMATION)watch_data.buffer; do { if (dir_event->Action == FILE_ACTION_MODIFIED) { - auto w_filename = std::wstring{ dir_event->FileName, dir_event->FileNameLength / sizeof(wchar_t) }; - auto filename = std::string{w_filename.begin(), w_filename.end()}; + int len = WideCharToMultiByte(CP_UTF8, 0, dir_event->FileName, -1, NULL, 0, NULL, NULL); + + char* filename = static_cast(alloca(len)); + WideCharToMultiByte(CP_UTF8, 0, dir_event->FileName, -1, filename, len, NULL, NULL); if (callbacks.contains(filename)) callbacks[filename](); + // auto w_filename = std::wstring{ dir_event->FileName, dir_event->FileNameLength / sizeof(wchar_t) }; + // auto filename = std::string{w_filename.begin(), w_filename.end()}; + // if (callbacks.contains(filename.c_str())) + // callbacks[filename.c_str()](); } dir_event += dir_event->NextEntryOffset; diff --git a/src/vec3.cpp b/src/vec3.cpp index 73dec98..3167bc2 100644 --- a/src/vec3.cpp +++ b/src/vec3.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include #include "utils.hpp" @@ -47,22 +47,51 @@ vec3& vec3::operator/=(float numerator) { return *this; } -float vec3::operator[](const int axis) { - if (axis > 2) { + +template +float vec3::get() const { + if constexpr (axis > 2) { return std::numeric_limits::infinity(); } - return v[axis]; + return arr[axis]; + // return static_cast(_mm_extract_ps(v, 3 - axis)); +} + +template +void vec3::set(float val) { + if constexpr (axis > 2) { + assert(false); + } + + arr[axis] = val; + // return static_cast(_mm_extract_ps(v, axis)); +} + +template float vec3::get<0>(void) const; +template float vec3::get<1>(void) const; +template float vec3::get<2>(void) const; + +template void vec3::set<0>(float); +template void vec3::set<1>(float); +template void vec3::set<2>(float); + +float vec3::operator[](int axis) const { + if (axis > 2) { + assert(false); + } + + return arr[axis]; } float vec3::length() const { __m128 t = _mm_dp_ps(v, v, 0b11110001); - return std::sqrt(t[0]); + return static_cast(std::sqrt(_mm_extract_ps(t, 0))); } -float vec3::length_sq() const { return (_mm_dp_ps(v, v, 0b11110001))[0]; } +float vec3::length_sq() const { return static_cast(_mm_extract_ps(_mm_dp_ps(v, v, 0b11110001), 0)); } -float vec3::dot(const vec3& vec) const { return (_mm_dp_ps(v, vec.v, 0b11110001))[0]; } +float vec3::dot(const vec3& vec) const { return static_cast(_mm_extract_ps(_mm_dp_ps(v, vec.v, 0b11110001), 0)); } vec3 vec3::cross(const vec3& vec) const { __m128 tmp0 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3, 0, 2, 1)); @@ -90,11 +119,14 @@ vec3& vec3::normalize() { bool vec3::near_zero() const { // __m128 e = _mm_set1_ps(EPSILON); // _mm_cmplt_ps(_mm_andnot_ps(_mm_set1_ps(-0.0f), v), e); - return (fabs(v[0]) < EPSILON) && (fabs(v[1]) < EPSILON) && (fabs(v[2]) < EPSILON); + float v0 = fabs(static_cast(_mm_extract_ps(v, 0))); + float v1 = fabs(static_cast(_mm_extract_ps(v, 1))); + float v2 = fabs(static_cast(_mm_extract_ps(v, 2))); + return (v0 < EPSILON) && (v1 < EPSILON) && (v2 < EPSILON); } void vec3::print() const { - printf("%f %f %f\n", v[0], v[1], v[2]); + printf("%f %f %f\n", get<0>(), get<1>(), get<2>()); } vec3 vec3::random() { return { randd(), randd(), randd() }; } diff --git a/src/vulkan-loader.cpp b/src/vulkan-loader.cpp index 933b8f1..c799f17 100644 --- a/src/vulkan-loader.cpp +++ b/src/vulkan-loader.cpp @@ -3,9 +3,9 @@ #include #if defined(WINDOWS) -#include - -HMODULE vulkanLibrary = LoadLibrary("vulkan-1.dll"); +// extern "C" void* GetProcAddress(HMODULE, const char*); +// extern "C" HMODULE LoadLibraryA(const char*); +HMODULE vulkanLibrary = LoadLibraryA("vulkan-1.dll"); #define LoadProcAddress GetProcAddress diff --git a/src/window.cpp b/src/window.cpp index d2cc5f4..7ba3bc0 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -194,10 +194,11 @@ void message_loop(void* wnd) { ((window*)wnd)->message_loop(); } -window::window(uint32_t desired_width, uint32_t desired_height) - : width(desired_width), height(desired_height) { +window::window(uint32_t desired_width, uint32_t desired_height) + : window_class_name("default-window"), width(desired_width), height(desired_height) { auto *process_handle = GetModuleHandleA(nullptr); + WNDCLASS window_class {}; window_class.style = 0; window_class.lpfnWndProc = &window::window_procedure; window_class.cbClsExtra = 0; @@ -207,7 +208,7 @@ window::window(uint32_t desired_width, uint32_t desired_height) window_class.hCursor = nullptr; window_class.hbrBackground = nullptr; window_class.lpszMenuName = nullptr; - window_class.lpszClassName = "default-window"; + window_class.lpszClassName = window_class_name; RegisterClass(&window_class); @@ -242,7 +243,7 @@ window::window(uint32_t desired_width, uint32_t desired_height) window::~window() { DestroyWindow(handle); - UnregisterClassA(window_class.lpszClassName, GetModuleHandleA(nullptr)); + UnregisterClassA(window_class_name, GetModuleHandleA(nullptr)); } void window::message_loop() { @@ -253,7 +254,9 @@ void window::message_loop() { for (size_t virtual_key { KEYS::LSHIFT }; virtual_key < KEYS::MAX_KEYS; virtual_key++) { if (keyboard[virtual_key]) { events.push_back({ - .key = (KEYS)virtual_key, + .data { + .key = (KEYS)virtual_key, + }, .type = EVENT_TYPES::KEY_PRESS, }); } @@ -278,7 +281,7 @@ LRESULT window::message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lpar case WM_CLOSE: case WM_DESTROY: case WM_QUIT: { - events.push_back({ .type = EVENT_TYPES::QUIT }); + events.push_back({ .data {}, .type = EVENT_TYPES::QUIT }); isOpen = false; break; } @@ -287,8 +290,12 @@ LRESULT window::message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lpar height = HIWORD(lparam); events.push_back({ - .width = width, - .height = height, + .data { + .size { + .width = width, + .height = height, + }, + }, .type = EVENT_TYPES::RESIZE }); break; @@ -298,7 +305,9 @@ LRESULT window::message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lpar keyboard[wparam] = true; events.push_back({ - .key = (KEYS)wparam, + .data { + .key = (KEYS)wparam, + }, .type = EVENT_TYPES::KEY_PRESS, }); break; @@ -308,7 +317,9 @@ LRESULT window::message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lpar keyboard[wparam] = false; events.push_back({ - .key = (KEYS)wparam, + .data { + .key = (KEYS)wparam, + }, .type = EVENT_TYPES::KEY_RELEASE, }); break; @@ -316,50 +327,66 @@ LRESULT window::message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lpar case WM_LBUTTONDOWN: { events.push_back({ - .button = BUTTONS::LEFT, + .data { + .button = BUTTONS::LEFT, + }, .type = EVENT_TYPES::BUTTON_PRESS, }); break; } case WM_LBUTTONUP: { events.push_back({ - .button = BUTTONS::LEFT, + .data { + .button = BUTTONS::LEFT, + }, .type = EVENT_TYPES::BUTTON_RELEASE, }); break; } case WM_RBUTTONDOWN: { events.push_back({ - .button = BUTTONS::RIGHT, + .data { + .button = BUTTONS::RIGHT, + }, .type = EVENT_TYPES::BUTTON_PRESS, }); break; } case WM_RBUTTONUP: { events.push_back({ - .button = BUTTONS::RIGHT, + .data { + .button = BUTTONS::RIGHT, + }, .type = EVENT_TYPES::BUTTON_RELEASE, }); break; } case WM_MBUTTONDOWN: { events.push_back({ - .button = BUTTONS::MIDDLE, + .data { + .button = BUTTONS::MIDDLE, + }, .type = EVENT_TYPES::BUTTON_PRESS, }); break; } case WM_MBUTTONUP: { events.push_back({ - .button = BUTTONS::MIDDLE, + .data { + .button = BUTTONS::MIDDLE, + }, .type = EVENT_TYPES::BUTTON_RELEASE, }); break; } case WM_MOUSEMOVE: { events.push_back({ - .x = GET_X_LPARAM(lparam), - .y = GET_Y_LPARAM(lparam), + .data { + .position { + .x = GET_X_LPARAM(lparam), + .y = GET_Y_LPARAM(lparam), + }, + }, .type = EVENT_TYPES::MOUSE_MOVE, }); break; -- cgit v1.3