diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2026-05-05 00:50:13 +0200 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2026-05-05 00:50:49 +0200 |
| commit | 37fdcb8a0f435c42f737252450626f2bd38bbd0f (patch) | |
| tree | 7eeb45a2d2d08483409a04c74fbc74fb2bbcde9f /src | |
| parent | 6818cbfe21beefc04e4a174d44a92159c34cead1 (diff) | |
Clean up around included files
Diffstat (limited to 'src')
| -rw-r--r-- | src/bvh.cpp | 9 | ||||
| -rw-r--r-- | src/camera.cpp | 1 | ||||
| -rw-r--r-- | src/gltf.cpp | 542 | ||||
| -rw-r--r-- | src/mesh.cpp | 4 | ||||
| -rw-r--r-- | src/scene.cpp | 160 | ||||
| -rw-r--r-- | src/utils.cpp | 92 | ||||
| -rw-r--r-- | src/vec3.cpp | 19 | ||||
| -rw-r--r-- | src/vulkan-loader.cpp | 4 | ||||
| -rw-r--r-- | src/window.cpp | 113 |
9 files changed, 550 insertions, 394 deletions
diff --git a/src/bvh.cpp b/src/bvh.cpp index 8e62a93..9362504 100644 --- a/src/bvh.cpp +++ b/src/bvh.cpp @@ -1,11 +1,5 @@ #include "bvh.hpp" -#include <cassert> - -#include <algorithm> -#include <cstdint> -#include <cstdio> - // bvh::bvh(std::vector<sphere>& spheres, std::vector<packed_bvh_node>& packed_nodes) // :spheres(spheres) { // packed_nodes.resize(2 * spheres.size() - 1); @@ -48,6 +42,7 @@ bvh::bvh(std::vector<triangle>& triangles, std::vector<packed_bvh_node>& packed_nodes) :triangles(triangles) { + BEGIN_MARKER(GENERATE_BVH); assert(!triangles.empty()); packed_nodes.resize(2 * triangles.size() - 1); @@ -84,6 +79,8 @@ bvh::bvh(std::vector<triangle>& triangles, std::vector<packed_bvh_node>& packed_ node.next_id = temp_nodes[old_node.next_id].df_id; } } + + END_MARKER(GENERATE_BVH); } //------------------------- diff --git a/src/camera.cpp b/src/camera.cpp index 4c63630..8139c5b 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -1,5 +1,4 @@ #include "camera.hpp" -#include "utils.hpp" camera::camera( point3 position, diff --git a/src/gltf.cpp b/src/gltf.cpp index 4cdfdce..2ddf16a 100644 --- a/src/gltf.cpp +++ b/src/gltf.cpp @@ -1,145 +1,177 @@ #include "gltf.hpp" -#include <execution> -#include <fstream> +using namespace simdjson; -#ifndef API_TEST -#define STB_IMAGE_IMPLEMENTATION -#endif -#include <stb_image.h> +ondemand::object root; -#include "utils.hpp" -#ifdef API_TEST -#include "vk-device-types.hpp" -#include "vk-device.hpp" -#include "vk-command-buffer.hpp" -#include <vk_mem_alloc.h> -#else -#include "vk-renderer.hpp" -#endif +struct accessor { + u32 view_index = 0U; + u32 count = 0U; + u32 component_type = 0U; + std::string_view type; +}; -gltf::gltf(const std::filesystem::path& filepath) { - auto parent_path = filepath.parent_path(); - std::fstream f{ filepath }; +struct buffer_view { + u32 buffer_index = 0U; + u32 length = 0U; + u32 offset = 0U; +}; - if (!f.is_open()) { - OutputDebugStringA("failed to open!"); - } - - f >> gltf_json; +// component types +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C - auto& scene = gltf_json["scenes"][0]; +#define SCALAR 0x5343414C4152 +#define VEC2 0x56454332 +#define VEC3 0x56454333 +#define VEC4 0x56454334 - auto& gltf_buffers = gltf_json["buffers"]; - auto buffer_count = gltf_buffers.size(); - buffers.resize(gltf_buffers.size()); - for (auto buffer_index{ 0U }; buffer_index < buffer_count; buffer_index++) { - auto buffer_path = parent_path / gltf_buffers[buffer_index]["uri"].get<std::string>(); - buffers[buffer_index] = read_file(buffer_path.string().c_str()); +static u32 accessor_type_to_component_count(std::string_view& type) { + if (strncmp("SCALAR", type.data(), type.size()) == 0) { + return 1U; + } else if (strncmp("VEC2", type.data(), type.size()) == 0) { + return 2U; + } else if (strncmp("VEC3", type.data(), type.size()) == 0) { + return 3U; + } else if (strncmp("VEC4", type.data(), type.size()) == 0) { + return 4U; } + assert(false); + return 0U; +} - load_textures(parent_path); - load_materials(); - - load_meshes(); - - auto& root_children = scene["nodes"]; - 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++) { - load_node(root_children[child_index].get<uint32_t>(), root_node.children[child_index]); +static u32 component_type_size(u32 type) { + switch (type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + return 1U; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + return 2U; + case GL_FLOAT: + case GL_FIXED: + return 4U; + default: assert(false); } - - f.close(); + return 0U; } -void gltf::load_node(uint32_t index, node& parent) { - const auto& gltf_node = gltf_json["nodes"][index]; +static Mesh::submesh load_primitive(ondemand::object& primitive, std::vector<struct buffer>& buffers, std::vector<struct accessor>& accessors, std::vector<struct buffer_view>& buffer_views) { + Mesh::submesh submesh; + + // indices + { + u32 indices_id = primitive["indices"].get_uint32(); + struct accessor& accessor = accessors[indices_id]; - if (gltf_node.contains("children")) { - const auto& children = gltf_node["children"]; - uint32_t children_count = gltf_node["children"]; - parent.children.resize(children_count); + struct buffer_view& view = buffer_views[accessor.view_index]; + struct buffer& buffer = buffers[view.buffer_index]; - for (size_t child_index = 0; child_index < children_count; child_index++) { - load_node(children[child_index].get<uint32_t>(), parent.children[child_index]); - } - } + submesh.indices = { + .data = &buffer.bytes[view.offset], + .length = accessor.count * accessor_type_to_component_count(accessor.type) * component_type_size(accessor.component_type), + }; - if (gltf_node.contains("mesh")) { - parent.mesh = &meshes[gltf_node["mesh"].get<uint32_t>()]; + submesh.index_count = accessor.count; } -} -void gltf::load_meshes() { - const auto& gltf_meshes = gltf_json["meshes"]; - auto meshes_count = gltf_meshes.size(); - meshes.resize(meshes_count); + // positions + { + u32 pos_id = primitive["attributes"]["POSITION"].get_uint32(); + struct accessor& accessor = accessors[pos_id]; - for (size_t mesh_index = 0; mesh_index < meshes_count; mesh_index++) { - auto& mesh = meshes[mesh_index]; - const auto& primitives = gltf_meshes[mesh_index]["primitives"]; + struct buffer_view& view = buffer_views[accessor.view_index]; + struct buffer& buffer = buffers[view.buffer_index]; - for (const auto& primitive : primitives) { - auto& material = materials[primitive["material"].get<uint32_t>()]; - mesh.add_submesh(load_primitive(primitive), material); - } + submesh.attributes[ATTRIBUTE_TYPE::POSITION] = { + .data = &buffer.bytes[view.offset], + .length = accessor.count * accessor_type_to_component_count(accessor.type) * component_type_size(accessor.component_type), + }; - Mesh::register_mesh(mesh); + submesh.vertex_count = accessor.count; } -} -Mesh::submesh gltf::load_primitive(const json& primitive) { - Mesh::submesh submesh; + u32 normal_index = 0U; + if (!primitive["attributes"]["NORMAL"].get(normal_index)) { + struct accessor& accessor = accessors[normal_index]; + u32 view_index = accessor.view_index; - submesh.indices = load_attribute(primitive["indices"]); - submesh.attributes[ATTRIBUTE_TYPE::POSITION] = load_attribute(primitive["attributes"]["POSITION"]); + struct buffer_view& view = buffer_views[view_index]; + struct buffer& buffer = buffers[view.buffer_index]; - if (primitive["attributes"].contains("NORMAL")) { - submesh.attributes[ATTRIBUTE_TYPE::NORMAL] = load_attribute(primitive["attributes"]["NORMAL"]); + submesh.attributes[ATTRIBUTE_TYPE::NORMAL] = { + .data = &buffer.bytes[view.offset], + .length = accessor.count * accessor_type_to_component_count(accessor.type) * component_type_size(accessor.component_type), + }; } - if (primitive["attributes"].contains("TEXCOORD_0")) { - submesh.attributes[ATTRIBUTE_TYPE::UV_0] = load_attribute(primitive["attributes"]["TEXCOORD_0"]); - } + u32 texcoord_index = 0U; + if (!primitive["attributes"]["TEXCOORD_0"].get(texcoord_index)) { + struct accessor& accessor = accessors[texcoord_index]; + u32 view_index = accessor.view_index; - submesh.index_count = gltf_json["accessors"][primitive["indices"].get<uint32_t>()]["count"].get<uint32_t>(); - submesh.vertex_count = gltf_json["accessors"][primitive["attributes"]["POSITION"].get<uint32_t>()]["count"].get<uint32_t>(); + struct buffer_view& view = buffer_views[view_index]; + struct buffer& buffer = buffers[view.buffer_index]; + + submesh.attributes[ATTRIBUTE_TYPE::UV_0] = { + .data = &buffer.bytes[view.offset], + .length = accessor.count * accessor_type_to_component_count(accessor.type) * component_type_size(accessor.component_type), + }; + } return submesh; } -Mesh::attribute gltf::load_attribute(uint32_t accessor_index) { - auto view_index = gltf_json["accessors"][accessor_index]["bufferView"].get<uint32_t>(); - const auto& view = gltf_json["bufferViews"][view_index]; - auto offset = view["byteOffset"].get<off_t>(); - auto& buffer = buffers[view["buffer"].get<uint32_t>()]; +static void load_textures(char* path, std::vector<handle<device_texture>>& textures, std::vector<struct buffer>& buffers, std::vector<struct buffer_view>& buffer_views, bool is_glb) { + ondemand::array gltf_images = root["images"]; + std::vector<raw_image> images(gltf_images.count_elements()); + size_t path_len = strlen(path); + char path_buffer[2048] = { 0U }; + strncpy(path_buffer, path, path_len); + BEGIN_MARKER(LOAD_TEXTURES); + u32 image_index = 0U; + for (ondemand::object gltf_image : gltf_images) { + if (is_glb) { + // TODO: consider mimeType + struct buffer_view& view = buffer_views[gltf_image["bufferView"]]; + struct buffer& buffer = buffers[view.buffer_index]; - return { - &buffer[offset], - view["byteLength"].get<size_t>() - }; -} + raw_image& image = images[image_index++]; -void gltf::load_textures(const std::filesystem::path& path) { - const auto& gltf_images = gltf_json["images"]; - auto images_count = gltf_images.size(); - std::vector<raw_image> images{ images_count }; + image.data = stbi_load_from_memory(&buffer.bytes[view.offset], view.length, &image.width, &image.height, &image.channels, 4); - std::vector<size_t> v(images_count); - std::iota(v.begin(), v.end(), 0); + } else { + std::string_view uri_view = gltf_image["uri"]; + strncpy(path_buffer + path_len, uri_view.data(), uri_view.length()); + path_buffer[path_len + uri_view.length()] = '\0'; - const auto& gltf_textures = gltf_json["textures"]; - auto textures_count = gltf_textures.size(); - textures.resize(textures_count); + raw_image& image = images[image_index++]; + image.data = stbi_load(path_buffer, &image.width, &image.height, &image.channels, 4); + } + } + END_MARKER(LOAD_TEXTURES); -#ifdef API_TEST - auto& device = vkdevice::get_render_device(); + // ondemand::array gltf_samplers = root["samplers"]; + // std::vector<handle<device_sampler>> samplers(gltf_samplers.count_elements()); + + // auto sampler = device.create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT); + // for (size_t sampler_index = 0; sampler_index < samplers_count; sampler_index++) { + // samplers[sampler_index] = vkrenderer::create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT); + // } + + vkdevice& device = vkdevice::get(); constexpr auto buffers_count = 2U; - auto total_size = images_count * 4096U * 4096 * sizeof(uint32_t); - auto buffer_size = total_size / 32U; + auto total_size = images.size() * 4096U * 4096 * sizeof(uint32_t); + // TODO: Fix nasty stuff going on + // Crash on buffer destruction + // Load wrong images + // auto buffer_size = total_size / 32U; + auto buffer_size = total_size / 2U; handle<device_buffer> staging_buffers_handle[buffers_count] = { device.create_buffer({ @@ -156,46 +188,28 @@ void gltf::load_textures(const std::filesystem::path& path) { }), }; + // TODO: Create a proper upload heap + BEGIN_MARKER(UPLOAD_TEXTURES); graphics_command_buffer command_buffers[buffers_count]; 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]; - auto buffer = device.get_buffer(buffer_handle); + device_buffer& buffer = device.get_buffer(buffer_handle); command_buffer.start(); -#endif // API_TEST - - std::for_each(std::execution::par, v.begin(), v.end(), [&](const size_t image_index) { - const auto& gltf_image = gltf_images[image_index]; - auto filepath = (path / gltf_image["uri"].get<std::string>()).string(); - auto& image = images[image_index]; - image.data = stbi_load(filepath.c_str(), &image.width, &image.height, &image.channels, 4); - }); - - // const auto &gltf_samplers = gltf_json["samplers"]; - // auto samplers_count = gltf_samplers.size(); - // std::vector<Sampler *> samplers{samplers_count}; - -#ifdef API_TEST - const auto &gltf_samplers = gltf_json["samplers"]; - auto samplers_count = gltf_samplers.size(); - std::vector<handle<device_sampler>> samplers{samplers_count}; - - // auto sampler = device.create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT); - // for (size_t sampler_index = 0; sampler_index < samplers_count; sampler_index++) { - // samplers[sampler_index] = vkrenderer::create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT); - // } - for (size_t texture_index = 0; texture_index < textures_count; texture_index++) { - auto gltf_texture = gltf_textures[texture_index]; - auto& image = images[gltf_texture["source"].get<uint32_t>()]; + ondemand::array gltf_textures = root["textures"]; + textures.resize(gltf_textures.count_elements()); + u32 texture_index = 0U; + for (ondemand::object gltf_texture: gltf_textures) { + raw_image& image = images[gltf_texture["source"]]; // if (gltf_texture.contains("sampler")) { - // auto sampler_index = gltf_texture["sampler"].get<uint32_t>(); + // u32 sampler_index = gltf_texture["sampler"].get_uint32(); // sampler = samplers[sampler_index]; // } - auto texture = device.create_texture({ + handle<device_texture> texture = device.create_texture({ .width = static_cast<uint32_t>(image.width), .height = static_cast<uint32_t>(image.height), .usages = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, @@ -203,105 +217,247 @@ void gltf::load_textures(const std::filesystem::path& path) { .type = VK_IMAGE_TYPE_2D, }); - uint64_t size = image.width * image.height * sizeof(uint32_t); - auto offset = buffer.offset; - if (offset + size > buffer_size) { + u32 size = image.width * image.height * sizeof(uint32_t); + if (buffer.allocated_size + size > buffer.size) { command_buffer.stop(); - device.submit(&command_buffer, 1 ); + device.submit(&command_buffer, 1); - buffer_index = (++buffer_index) % buffers_count; + buffer_index = (buffer_index + 1U) % buffers_count; command_buffer = command_buffers[buffer_index]; buffer_handle = staging_buffers_handle[buffer_index]; buffer = device.get_buffer(buffer_handle); buffer.reset(); - device.wait(); + // TODO: Remove the wait + // device.wait(); command_buffer.start(); - offset = 0U; } - void* ptr = buffer.allocate(size); - memcpy(ptr, image.data, size); + memcpy(buffer.allocate(size), image.data, size); command_buffer.barrier(texture, VK_PIPELINE_STAGE_2_TRANSFER_BIT, VK_ACCESS_2_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - command_buffer.copy(buffer_handle, texture, static_cast<VkDeviceSize>(offset)); + command_buffer.copy(buffer_handle, texture, static_cast<VkDeviceSize>(buffer.offset)); command_buffer.barrier(texture, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL); - textures[texture_index] = texture; + textures[texture_index++] = texture; } - command_buffer.stop(); - device.submit(&command_buffer, 1); + if (buffer.allocated_size > 0U) { + command_buffer.stop(); + device.submit(&command_buffer, 1); + } device.wait(); device.destroy_buffer(staging_buffers_handle[0]); device.destroy_buffer(staging_buffers_handle[1]); -#else - Sampler* sampler = vkrenderer::create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT); - // for (size_t sampler_index = 0; sampler_index < samplers_count; sampler_index++) { - // samplers[sampler_index] = vkrenderer::create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT); - // } + END_MARKER(UPLOAD_TEXTURES); +} - for (size_t texture_index = 0; texture_index < textures_count; texture_index++) { - auto gltf_texture = gltf_textures[texture_index]; +static void load_materials(std::vector<material>& materials, std::vector<handle<device_texture>>& textures) { + ondemand::array gltf_materials = root["materials"]; + materials.resize(gltf_materials.count_elements()); - auto& image = images[gltf_texture["source"].get<uint32_t>()]; - // if (gltf_texture.contains("sampler")) { - // auto sampler_index = gltf_texture["sampler"].get<uint32_t>(); - // sampler = samplers[sampler_index]; - // } + u32 material_index = 0U; + for (ondemand::object object: gltf_materials) { + material& material = materials[material_index++]; + material.base_color = vec3(1.f); + material.metalness = 1.f; + material.roughness = 1.f; - auto* texture = vkrenderer::create_2d_texture(static_cast<uint32_t>(image.width), static_cast<uint32_t>(image.height), VK_FORMAT_R8G8B8A8_UNORM, sampler); + ondemand::object pbr_params; + if (!object["pbrMetallicRoughness"].get(pbr_params)) { + ondemand::array base_color; + if (!pbr_params["baseColorFactor"].get(base_color)) { + u32 id = 0U; + for (double val : base_color) { + material.base_color.arr[id++] = static_cast<float>(val); + } + } - texture->update(image.data); + ondemand::object base_color_texture; + if (!pbr_params["baseColorTexture"].get(base_color_texture)) { + material.base_color_texture = textures[base_color_texture["index"]]; + } - textures[texture_index] = texture; + pbr_params["metallicFactor"].get(material.metalness); + pbr_params["roughnessFactor"].get(material.roughness); + + ondemand::object metallic_roughness_texture; + if (!pbr_params["metallicRoughnessTexture"].get(metallic_roughness_texture)) { + material.metallic_roughness_texture = textures[metallic_roughness_texture["index"]]; + } + } } -#endif } -void gltf::load_materials() { - const auto& gltf_materials = gltf_json["materials"]; - auto materials_count = gltf_materials.size(); - materials.resize(materials_count); +gltf::gltf(const char* filepath) { + BEGIN_MARKER(LOAD_GLTF); - for (size_t material_index = 0; material_index < materials_count; material_index++) { - const auto& gltf_material = gltf_materials[material_index]; - auto& material = materials[material_index]; + ondemand::parser parser; + padded_string json; + ondemand::document doc; - if (gltf_material.contains("pbrMetallicRoughness")) { - const auto& pbr_params = gltf_material["pbrMetallicRoughness"]; + const char* ext = PathFindExtensionA(filepath); - if (pbr_params.contains("baseColorFactor")) { - const auto& base_color = pbr_params["baseColorFactor"]; - material.base_color.set<0>(base_color[0].get<float>()); - material.base_color.set<1>(base_color[1].get<float>()); - material.base_color.set<2>(base_color[2].get<float>()); - material.base_color.arr[3] = base_color[3].get<float>(); // Since we use a vec3 for colors we are not allowed toset fourth value with set<3> - } else { - material.base_color = vec3(1.f); - } + char buffer_path[2048U] = { 0U }; + char* filename = nullptr; + GetFullPathNameA( filepath, 2048U, buffer_path, &filename); + size_t parent_dir_len = filename - buffer_path; - if (pbr_params.contains("baseColorTexture")) { - auto base_color_index = pbr_params["baseColorTexture"]["index"].get<uint32_t>(); - material.base_color_texture = textures[base_color_index]; - } + // TODO: Remove + is_glb = strcmp(ext, ".glb") == 0; + + if (is_glb) { + size_t filesize = 0U; + size_t read = 0U; + u8* glb_buffer = read_file(filepath, &filesize); + header = (struct glb_header*)glb_buffer; + assert(filesize == header->length); + // assert(header->magic == (u32)"glTF"); + + read += sizeof(*header); + chunks.push_back((struct glb_chunk*)(header + 1)); + read += offsetof(struct glb_chunk, data) + chunks.back()->length; + while (read != header->length) { + chunks.push_back((struct glb_chunk*)(glb_buffer + read)); + read += offsetof(struct glb_chunk, data) + chunks.back()->length; + } + + doc = parser.iterate((const char*)&chunks[0]->data[0U], chunks[0]->length, filesize); + root = doc; + + ondemand::array gltf_buffers = root["buffers"]; + assert(gltf_buffers.count_elements() == chunks.size() - 1U); + buffers.resize(gltf_buffers.count_elements()); + u32 buffer_index = 0U; + for (u32 chunk_index = 1U; chunk_index < chunks.size(); chunk_index++) { + buffers[buffer_index++] = buffer { + .bytes = chunks[chunk_index]->data, + .size = chunks[chunk_index]->length, + }; + } + } else { + json = padded_string::load(filepath); + doc = parser.iterate(json); + root = doc; - if (pbr_params.contains("metallicFactor")) { - material.metalness = pbr_params["metallicFactor"].get<float>(); - } else { - material.metalness = 1.0; + { + ondemand::array gltf_buffers = root["buffers"]; + buffers.resize(gltf_buffers.count_elements()); + u32 buffer_index = 0U; + for (ondemand::object value: gltf_buffers) { + std::string_view uri_view = value["uri"]; + strncpy(buffer_path + parent_dir_len, uri_view.data(), uri_view.length()); + buffer_path[parent_dir_len + uri_view.length()] = '\0'; + + size_t file_size = 0U; + uint8_t* bytes = read_file(buffer_path, &file_size); + buffers[buffer_index++] = { + .bytes = bytes, + .size = file_size, + }; } + } + } + + + std::vector<struct accessor> accessors; + { + ondemand::array gltf_accessors = root["accessors"]; + accessors.resize(gltf_accessors.count_elements()); + u32 accessor_index = 0U; + for (ondemand::object value: gltf_accessors) { + struct accessor& accessor = accessors[accessor_index++]; + value["bufferView"].get(accessor.view_index); + value["count"].get(accessor.count); + value["type"].get(accessor.type); + value["componentType"].get(accessor.component_type); + } + } + + std::vector<struct buffer_view> buffer_views; + { + ondemand::array gltf_views = root["bufferViews"]; + buffer_views.resize(gltf_views.count_elements()); + u32 view_index = 0U; + for (ondemand::object value: gltf_views) { + struct buffer_view& view = buffer_views[view_index++]; + value["buffer"].get(view.buffer_index); + value["byteLength"].get(view.length); + value["byteOffset"].get(view.offset); + } + } + - if (pbr_params.contains("roughnessFactor")) { - material.roughness = pbr_params["roughnessFactor"].get<float>(); - } else { - material.roughness = 1.0; + { + ondemand::array gltf_nodes = root["nodes"]; + nodes.resize(gltf_nodes.count_elements()); + + u32 node_index = 0U; + for (ondemand::object gltf_node: gltf_nodes) { + struct node& node = nodes[node_index++]; + + ondemand::array gltf_children; + if (!gltf_node["children"].get(gltf_children)) { + node.children.resize(gltf_children.count_elements()); + + u32 child_index = 0U; + for (auto child : gltf_children) { + node.children[child_index++] = child.get_uint32(); + } } - if (pbr_params.contains("metallicRoughnessTexture")) { - auto metallic_roughness_index = pbr_params["metallicRoughnessTexture"]["index"].get<uint32_t>(); - material.metallic_roughness_texture = textures[metallic_roughness_index]; + node.mesh = UINT32_MAX; + gltf_node["mesh"].get(node.mesh); + } + } + + + // root nodes + { + u32 scene_index = root["scene"].get_uint32(); + ondemand::array gltf_scene_nodes = root["scenes"].at(scene_index)["nodes"]; + root_nodes.resize(gltf_scene_nodes.count_elements()); + + u32 index = 0U; + for (auto node_index: gltf_scene_nodes) { + root_nodes[index++] = node_index.get_uint32(); + } + } + + buffer_path[parent_dir_len] = '\0'; + load_textures(buffer_path, textures, buffers, buffer_views, is_glb); + load_materials(materials, textures); + + // meshes + { + ondemand::array gltf_meshes = root["meshes"]; + meshes.resize(gltf_meshes.count_elements()); + + u32 mesh_index = 0U; + for (ondemand::object gltf_mesh: gltf_meshes) { + Mesh& mesh = meshes[mesh_index++]; + ondemand::array gltf_primitives = gltf_mesh["primitives"]; + + for (ondemand::object primitive : gltf_primitives) { + material& material = materials[primitive["material"]]; + mesh.add_submesh(load_primitive(primitive, buffers, accessors, buffer_views), material); } + + Mesh::register_mesh(mesh); } } + + END_MARKER(LOAD_GLTF); +} + +void gltf::deinit() { + for (handle<device_texture> handle: textures) { + vkdevice::get().destroy_texture(handle); + } + + for (struct buffer& buffer: buffers) { + free(buffer.bytes); + } + + free(header); } diff --git a/src/mesh.cpp b/src/mesh.cpp index 3863ca8..cbfe392 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -1,6 +1,6 @@ #include "mesh.hpp" -static std::vector<Mesh> meshes {}; +static std::vector<Mesh> registered_meshes {}; void Mesh::add_submesh(const submesh& submesh, material& material) { submeshes.emplace_back( @@ -42,5 +42,5 @@ void Mesh::add_submesh(const submesh& submesh, material& material) { } void Mesh::register_mesh(const Mesh& mesh) { - meshes.push_back(mesh); + registered_meshes.push_back(mesh); } diff --git a/src/scene.cpp b/src/scene.cpp index 9d6b981..9369eae 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -1,17 +1,5 @@ #include "scene.hpp"
-
-#include <cstdint>
-#include <queue>
-
-#ifdef API_TEST
-#include <vk_mem_alloc.h>
-#else
-#include "vk-renderer.hpp"
-#endif // API_TEST
-
-#include "gltf.hpp"
-#include "bvh.hpp"
-// #include "material.hpp"
+#include "mesh.hpp"
// void scene::random_scene() {
// material ground_material = { { 0.5, 0.5, 0.5 } };
@@ -63,15 +51,19 @@ // }
-scene::metadata::metadata(const camera &cam, uint32_t width, uint32_t height)
+metadata::metadata(const camera &cam, uint32_t width, uint32_t height)
: cam(cam), width(width), height(height) {}
scene::scene(const camera& cam, uint32_t width, uint32_t height)
- :meta(cam, width, height){
+ // :model("../models/sponza/Sponza.gltf"), meta(cam, width, height) {
+ // :model("../models/BistroInterior/BistroInterior.gltf"), meta(cam, width, height) {
+ // :model("../models/BistroExterior/BistroExterior.gltf"), meta(cam, width, height) {
+ // :model("../models/sponza-avif-hi.glb"), meta(cam, width, height) {
+ // :model("../models/main_sponza/NewSponza_Main_glTF_003.gltf"), meta(cam, width, height) {
+ // :model("../models/pkg_a_curtains/NewSponza_Curtains_glTF.gltf"), meta(cam, width, height) {
+ :model("../models/sponza.glb"), meta(cam, width, height) {
-#ifdef API_TEST
- auto& device = vkdevice::get_render_device();
-#endif
+ auto& device = vkdevice::get();
// Geometry & BVH
std::vector<uint32_t> indices;
@@ -81,51 +73,50 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) std::vector<gpu_material> materials;
std::vector<packed_bvh_node> packed_nodes;
- // auto root_node = gltf::load("../models/BistroInterior", "BistroInterior.gltf");
- auto gltf_model = gltf("../models/sponza/Sponza.gltf");
-
std::vector<triangle> triangles;
- size_t triangles_offset = 0;
- size_t vertices_offset = 0;
- std::queue<node> nodes_to_load {};
- nodes_to_load.push(gltf_model.root_node);
+ u32 triangles_offset = 0U;
+ u32 vertices_offset = 0U;
+ u32 positions_count = 0U;
+ u32 normals_count = 0U;
+ u32 uvs_count = 0U;
+ std::vector<u32> nodes_to_load = model.root_nodes;
- while(!nodes_to_load.empty()) {
- auto &node = nodes_to_load.front();
+ for (u32 cur_node_index = 0U; cur_node_index < nodes_to_load.size(); cur_node_index++) {
+ struct node &node = model.nodes[nodes_to_load[cur_node_index]];
- if (node.mesh != nullptr) {
- const auto* mesh = node.mesh;
- const auto& mesh_positions = mesh->get_attribute(ATTRIBUTE_TYPE::POSITION);
- const auto& mesh_normals = mesh->get_attribute(ATTRIBUTE_TYPE::NORMAL);
- const auto& mesh_uvs_0 = mesh->get_attribute(ATTRIBUTE_TYPE::UV_0);
- const auto& mesh_indices = mesh->get_indices();
+ if (node.mesh != UINT32_MAX) {
+ const Mesh& mesh = model.meshes[node.mesh];
+ const auto& mesh_positions = mesh.get_attribute(ATTRIBUTE_TYPE::POSITION);
+ const auto& mesh_normals = mesh.get_attribute(ATTRIBUTE_TYPE::NORMAL);
+ const auto& mesh_uvs_0 = mesh.get_attribute(ATTRIBUTE_TYPE::UV_0);
+ const auto& mesh_indices = mesh.get_indices();
- indices.resize(indices.size() + mesh_indices.size());
- positions.resize(vertices_offset + mesh_positions.size());
- normals.resize(vertices_offset + mesh_normals.size());
- uvs.resize(vertices_offset + mesh_uvs_0.size());
+ indices.resize(indices.size() + mesh_indices.size());
+ positions.resize(positions_count + mesh_positions.size());
+ normals.resize(normals_count + mesh_normals.size());
+ uvs.resize(uvs_count + mesh_uvs_0.size());
std::memcpy(
- positions.data() + vertices_offset * Mesh::attribute_components(ATTRIBUTE_TYPE::POSITION),
+ positions.data() + positions_count,
mesh_positions.data(),
- mesh_positions.size() * sizeof(float)
+ mesh_positions.size() * sizeof(mesh_positions[0U])
);
std::memcpy(
- normals.data() + vertices_offset * Mesh::attribute_components(ATTRIBUTE_TYPE::NORMAL),
+ normals.data() + normals_count,
mesh_normals.data(),
- mesh_normals.size() * sizeof(float)
+ mesh_normals.size() * sizeof(mesh_normals[0U])
);
std::memcpy(
- uvs.data() + vertices_offset * Mesh::attribute_components(ATTRIBUTE_TYPE::UV_0),
+ uvs.data() + uvs_count,
mesh_uvs_0.data(),
- mesh_uvs_0.size() * sizeof(float)
+ mesh_uvs_0.size() * sizeof(mesh_uvs_0[0U])
);
auto index_offset { 0U };
// Add offset to indices in order to have absolute indices
- for (const auto& submesh: mesh->get_submeshes()) {
+ for (const auto& submesh: mesh.get_submeshes()) {
auto vertex_offset = vertices_offset + submesh.vertex_offset;
const auto& material = submesh.material;
@@ -151,9 +142,6 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) indices[triangle_offset + 2] = static_cast<uint32_t>((submesh_level_index_3 + vertex_offset) | (0xff000000 & (materials.size() << 24)));
}
-// const auto& albedo_image = vkrenderer::api.get_image(material.base_color_texture->device_image);
-// const auto& albedo_sampler = vkrenderer::api.get_sampler(material.base_color_texture->sampler->device_sampler);
-
auto& mat = materials.emplace_back(gpu_material {
.base_color = material.base_color,
// .albedo_texture_id = albedo_image.bindless_sampled_index,
@@ -162,7 +150,6 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) .roughness = material.roughness
});
-#ifdef API_TEST
if (material.base_color_texture.id != handle<device_texture>::invalid_id) {
mat.albedo_texture_id = device.get_texture(material.base_color_texture).get_sampled_index();
// mat.albedo_texture_sampler_id = device.get_sampler(0);
@@ -172,28 +159,18 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) mat.metallic_roughness_texture_id = device.get_texture(material.metallic_roughness_texture).get_sampled_index();
// mat.metallic_roughness_texture_sampler_id = device.get_sampler(0);
}
-#else
- if (material.metallic_roughness_texture != nullptr) {
- // auto& gpu_material = materials.back();
-// const auto& metallic_roughness_image = vkrenderer::api.get_image(material.metallic_roughness_texture->device_image);
-// const auto& metallic_roughness_sampler = vkrenderer::api.get_sampler(material.metallic_roughness_texture->sampler->device_sampler);
-
-// gpu_material.metallic_roughness_texture_id = metallic_roughness_image.bindless_sampled_index;
-// gpu_material.metallic_roughness_texture_sampler_id = metallic_roughness_sampler.bindless_index;
- }
-#endif
-
}
- triangles_offset += mesh->triangle_count();
- vertices_offset += mesh->vertices_count();
+ triangles_offset += mesh.triangle_count();
+ vertices_offset += mesh.vertices_count();
+ positions_count = vertices_offset * Mesh::attribute_components(ATTRIBUTE_TYPE::POSITION);
+ normals_count = vertices_offset * Mesh::attribute_components(ATTRIBUTE_TYPE::NORMAL);
+ uvs_count = vertices_offset * Mesh::attribute_components(ATTRIBUTE_TYPE::UV_0);
}
- for (auto &new_node: node.children) {
- nodes_to_load.push(new_node);
+ for (u32 child_index: node.children) {
+ nodes_to_load.push_back(child_index);
}
-
- nodes_to_load.pop();
}
// random_scene();
@@ -201,28 +178,13 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) bvh builder(triangles, packed_nodes);
// bvh builder(spheres, packed_nodes);
-#ifdef API_TEST
- {
- scene_buffer_handle = device.create_buffer({
- .size = sizeof(meta) * 3U,
- .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
- .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
- .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
- });
-
- const auto& scene_buffer = device.get_buffer(scene_buffer_handle);
- uint8_t* ptr = static_cast<uint8_t*>(scene_buffer.mapped_ptr);
- memcpy(static_cast<void*>(ptr), &meta, sizeof(meta));
- memcpy(static_cast<void*>(ptr + sizeof(meta)), &meta, sizeof(meta));
- memcpy(static_cast<void*>(ptr + sizeof(meta) * 2U), &meta, sizeof(meta));
- }
-
{
indices_buffer_handle = device.create_buffer({
.size = indices.size() * sizeof(indices[0]),
.usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ .name = "indices",
});
const auto& indices_buffer = device.get_buffer(indices_buffer_handle);
void* ptr = indices_buffer.mapped_ptr;
@@ -235,6 +197,7 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ .name = "positions",
});
const auto& positions_buffer = device.get_buffer(positions_buffer_handle);
void* ptr = positions_buffer.mapped_ptr;
@@ -247,6 +210,7 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ .name = "normals",
});
const auto& normals_buffer = device.get_buffer(normals_buffer_handle);
void* ptr = normals_buffer.mapped_ptr;
@@ -259,6 +223,7 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ .name = "uvs",
});
const auto& uvs_buffer = device.get_buffer(uvs_buffer_handle);
void* ptr = uvs_buffer.mapped_ptr;
@@ -271,6 +236,7 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ .name = "bvh",
});
const auto& bvh_buffer = device.get_buffer(bvh_buffer_handle);
void* ptr = bvh_buffer.mapped_ptr;
@@ -283,33 +249,21 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ .name = "materials",
});
const auto& materials_buffer = device.get_buffer(materials_buffer_handle);
void* ptr = materials_buffer.mapped_ptr;
memcpy(ptr, materials.data(), materials.size() * sizeof(materials[0]));
}
-#else
- scene_buffer = vkrenderer::create_buffer(sizeof(meta) * vkrenderer::virtual_frames_count);
- scene_buffer->write(&meta, 0, sizeof(meta));
- scene_buffer->write(&meta, sizeof(meta), sizeof(meta));
- scene_buffer->write(&meta, sizeof(meta) * 2, sizeof(meta));
-
- indices_buffer = vkrenderer::create_buffer(indices.size() * sizeof(indices[0]));
- indices_buffer->write(indices.data(), 0, indices.size() * sizeof(indices[0]));
-
- positions_buffer = vkrenderer::create_buffer(positions.size() * sizeof(positions[0]));
- positions_buffer->write(positions.data(), 0, positions.size() * sizeof(positions[0]));
-
- normals_buffer = vkrenderer::create_buffer(normals.size() * sizeof(normals[0]));
- normals_buffer->write(normals.data(), 0, normals.size() * sizeof(normals[0]));
-
- uvs_buffer = vkrenderer::create_buffer(uvs.size() * sizeof(uvs[0]));
- uvs_buffer->write(uvs.data(), 0, uvs.size() * sizeof(uvs[0]));
+}
- bvh_buffer = vkrenderer::create_buffer(packed_nodes.size() * sizeof(packed_nodes[0]));
- bvh_buffer->write(packed_nodes.data(), 0, packed_nodes.size() * sizeof(packed_nodes[0]));
+void scene::deinit() {
+ vkdevice::get().destroy_buffer(indices_buffer_handle);
+ vkdevice::get().destroy_buffer(positions_buffer_handle);
+ vkdevice::get().destroy_buffer(normals_buffer_handle);
+ vkdevice::get().destroy_buffer(uvs_buffer_handle);
+ vkdevice::get().destroy_buffer(bvh_buffer_handle);
+ vkdevice::get().destroy_buffer(materials_buffer_handle);
- materials_buffer = vkrenderer::create_buffer(materials.size() * sizeof(materials[0]));
- materials_buffer->write(materials.data(), 0, materials.size() * sizeof(materials[0]));
-#endif // API_TEST
+ model.deinit();
}
diff --git a/src/utils.cpp b/src/utils.cpp index ffe50b3..4c383db 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,54 +1,46 @@ #include "utils.hpp" -#if defined(WINDOWS) -#include <windows.h> -#endif - -#include <filesystem> -#include <iostream> +#include <unordered_map> -std::vector<uint8_t> read_file(const char* path) { -#if defined(WINDOWS) - FILE* f = nullptr; - errno_t err = fopen_s(&f, path, "rb"); +uint8_t* read_file(const char* path, size_t* size) { +#if _WIN32 + HANDLE f = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (err != 0) { - std::cerr << "Cannot open file !" << std::endl; - return {}; + if (f == INVALID_HANDLE_VALUE) { + fprintf(stderr, "Cannot open file !\n"); + return nullptr; } -#elif defined(LINUX) +#elif LINUX FILE* f = fopen(path, "rb"); if (!f) { - std::cerr << "Cannot open file !" << std::endl; + fprintf(stderr, "Cannot open file !\n"); return {}; } #endif - if (fseek(f, 0, SEEK_END) != 0) { - return {}; + LARGE_INTEGER file_size = { .QuadPart = 0ULL }; + if (!GetFileSizeEx(f, &file_size)) { + return nullptr; } + *size = file_size.LowPart; - std::vector<uint8_t> file_content(ftell(f)); + void* content = malloc(*size); - if (fseek(f, 0, SEEK_SET) != 0) { - return {}; - } - - if (fread(file_content.data(), sizeof(uint8_t), file_content.size(), f) != file_content.size()) { - std::cerr << "Reading file content failed" << std::endl; - return {}; + DWORD bread = 0U; + if (!ReadFile(f, content, static_cast<DWORD>(*size), &bread, NULL) || bread != *size) { + fprintf(stderr, "Reading file content failed\n"); + return nullptr; } - fclose(f); + CloseHandle(f); - return file_content; + return (uint8_t*)content; } - -#ifdef WINDOWS +#if _WIN32 void log_last_error() { - auto error_code = GetLastError(); + DWORD error_code = GetLastError(); const char* error_message = nullptr; FormatMessageA( @@ -63,29 +55,49 @@ void log_last_error() { nullptr ); - std::cerr << error_message << std::endl; + fprintf(stderr, "%s\n", error_message); } -bool watcher::watch_file(const char* filepath, watcher::func callback) { +struct watch_data { + HANDLE dir_handle; + OVERLAPPED overlapped; + DWORD buffer[512]; +}; + +static std::unordered_map<const char*, func> callbacks; +static std::unordered_map<const char*, watch_data> watched_dirs; + +bool watch_file(const char* filepath, func callback) { DWORD attrib = GetFileAttributes(filepath); if (attrib == INVALID_FILE_ATTRIBUTES) return false; - std::filesystem::path path(filepath); - if (!watcher::watch_dir(path.parent_path().string().c_str())) + size_t buffer_size = 2048U; + char* fullpath = static_cast<char*>(malloc(buffer_size)); + char* filename = nullptr; + GetFullPathNameA( filepath, 2028, fullpath, &filename); + + size_t dir_len = filename - fullpath; + char* parent_dir = static_cast<char*>(malloc(dir_len)); + strncpy(parent_dir, fullpath, dir_len); + + free(fullpath); + + if (!watch_dir(parent_dir)) { return false; + } - auto [_, is_inserted] = watcher::callbacks.emplace(filepath, callback); + auto [_, is_inserted] = callbacks.emplace(filepath, callback); return is_inserted; } -bool watcher::watch_dir(const char* dir_path) { +bool 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) != watcher::watched_dirs.end()) + if (watched_dirs.find(dir_path) != watched_dirs.end()) return true; HANDLE dir_handle = CreateFileA( @@ -103,7 +115,7 @@ bool watcher::watch_dir(const char* dir_path) { return false; } - auto [dir, _] = watcher::watched_dirs.emplace(dir_path, watch_data{ .dir_handle = dir_handle, .overlapped{}, .buffer{} }); + auto [dir, _] = 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(); @@ -113,8 +125,8 @@ bool watcher::watch_dir(const char* dir_path) { return true; } -void watcher::pull_changes() { - for (auto& dir : watcher::watched_dirs) { +void pull_changes() { + for (auto& dir : watched_dirs) { auto& watch_data = dir.second; if (!HasOverlappedIoCompleted(&watch_data.overlapped)) continue; diff --git a/src/vec3.cpp b/src/vec3.cpp index 3167bc2..414ee73 100644 --- a/src/vec3.cpp +++ b/src/vec3.cpp @@ -1,10 +1,8 @@ -#include <cmath> -#include <cassert.> -#include <smmintrin.h> - -#include "utils.hpp" #include "vec3.hpp" +// #include <smmintrin.h> +// #include <xmmintrin.h> + vec3::vec3() : v(_mm_setzero_ps()) {} vec3::vec3(float x) : v(_mm_set1_ps(x)) {} @@ -122,7 +120,16 @@ bool vec3::near_zero() const { float v0 = fabs(static_cast<float>(_mm_extract_ps(v, 0))); float v1 = fabs(static_cast<float>(_mm_extract_ps(v, 1))); float v2 = fabs(static_cast<float>(_mm_extract_ps(v, 2))); - return (v0 < EPSILON) && (v1 < EPSILON) && (v2 < EPSILON); + return (v0 < FLT_EPSILON) && (v1 < FLT_EPSILON) && (v2 < FLT_EPSILON); +} + +bool vec3::is_zero() const { + // __m128 e = _mm_set1_ps(EPSILON); + // _mm_cmplt_ps(_mm_andnot_ps(_mm_set1_ps(-0.0f), v), e); + float v0 = fabs(static_cast<float>(_mm_extract_ps(v, 0))); + float v1 = fabs(static_cast<float>(_mm_extract_ps(v, 1))); + float v2 = fabs(static_cast<float>(_mm_extract_ps(v, 2))); + return (v0 == 0.f) && (v1 == 0.f) && (v2 == 0.f); } void vec3::print() const { diff --git a/src/vulkan-loader.cpp b/src/vulkan-loader.cpp index c799f17..399b566 100644 --- a/src/vulkan-loader.cpp +++ b/src/vulkan-loader.cpp @@ -1,8 +1,6 @@ #include "vulkan-loader.hpp" -#include <cassert> - -#if defined(WINDOWS) +#if defined(_WIN32) // extern "C" void* GetProcAddress(HMODULE, const char*); // extern "C" HMODULE LoadLibraryA(const char*); HMODULE vulkanLibrary = LoadLibraryA("vulkan-1.dll"); diff --git a/src/window.cpp b/src/window.cpp index 7ba3bc0..38c9765 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,6 +1,5 @@ #include "window.hpp" - #ifdef LINUX #include <iostream> @@ -169,10 +168,23 @@ void window::poll_events() { } } -#elif defined(WINDOWS) -#include <windowsx.h> +#elif _WIN32 +#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) +#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) -#include "utils.hpp" +HCURSOR window::cursors[CURSOR_TYPE::MAX_CURSOR] = { + LoadCursorA(NULL, IDC_ARROW), + LoadCursorA(NULL, IDC_IBEAM), + LoadCursorA(NULL, IDC_SIZEALL), + LoadCursorA(NULL, IDC_SIZENS), + LoadCursorA(NULL, IDC_SIZEWE), + LoadCursorA(NULL, IDC_SIZENESW), + LoadCursorA(NULL, IDC_SIZENWSE), + LoadCursorA(NULL, IDC_HAND), + LoadCursorA(NULL, IDC_WAIT), + LoadCursorA(NULL, IDC_APPSTARTING), + LoadCursorA(NULL, IDC_NO), +}; LRESULT CALLBACK window::window_procedure(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) { window* win = nullptr; @@ -250,29 +262,27 @@ void window::message_loop() { MSG msg {}; while(true) { - // Generate keydown events pressed keys - for (size_t virtual_key { KEYS::LSHIFT }; virtual_key < KEYS::MAX_KEYS; virtual_key++) { - if (keyboard[virtual_key]) { - events.push_back({ - .data { - .key = (KEYS)virtual_key, - }, - .type = EVENT_TYPES::KEY_PRESS, - }); - } - } - - while (PeekMessageA(&msg, nullptr, 0, 0, PM_REMOVE) != 0) { TranslateMessage(&msg); DispatchMessageA(&msg); } + for (u32 key_index = 0U; key_index <= KEY::MAX_KEY; key_index++) { + events.push_back(event { + .data { + .key = (KEY)key_index, + }, + .type = keyboard[key_index] ? EVENT_TYPE::KEY_DOWN : EVENT_TYPE::KEY_UP, + }); + } + SwitchToFiber(main_fiber); } } void window::poll_events() { + events.clear(); + SwitchToFiber(message_loop_fiber); } @@ -281,7 +291,10 @@ LRESULT window::message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lpar case WM_CLOSE: case WM_DESTROY: case WM_QUIT: { - events.push_back({ .data {}, .type = EVENT_TYPES::QUIT }); + events.push_back({ + .data {}, + .type = EVENT_TYPE::QUIT + }); isOpen = false; break; } @@ -296,86 +309,90 @@ LRESULT window::message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lpar .height = height, }, }, - .type = EVENT_TYPES::RESIZE + .type = EVENT_TYPE::RESIZE }); break; } case WM_KEYDOWN: { - keyboard[wparam] = true; - events.push_back({ .data { - .key = (KEYS)wparam, + .key = (KEY)wparam, }, - .type = EVENT_TYPES::KEY_PRESS, + .type = EVENT_TYPE::KEY_PRESS, }); + keyboard[wparam] = true; break; } case WM_KEYUP: { - keyboard[wparam] = false; - events.push_back({ .data { - .key = (KEYS)wparam, + .key = (KEY)wparam, }, - .type = EVENT_TYPES::KEY_RELEASE, + .type = EVENT_TYPE::KEY_RELEASE, }); + keyboard[wparam] = false; break; } case WM_LBUTTONDOWN: { + mouse[BUTTON::LEFT] = true; events.push_back({ .data { - .button = BUTTONS::LEFT, + .button = BUTTON::LEFT, }, - .type = EVENT_TYPES::BUTTON_PRESS, + .type = EVENT_TYPE::BUTTON_PRESS, }); break; } case WM_LBUTTONUP: { + mouse[BUTTON::LEFT] = false; events.push_back({ .data { - .button = BUTTONS::LEFT, + .button = BUTTON::LEFT, }, - .type = EVENT_TYPES::BUTTON_RELEASE, + .type = EVENT_TYPE::BUTTON_RELEASE, }); break; } case WM_RBUTTONDOWN: { + mouse[BUTTON::RIGHT] = true; events.push_back({ .data { - .button = BUTTONS::RIGHT, + .button = BUTTON::RIGHT, }, - .type = EVENT_TYPES::BUTTON_PRESS, + .type = EVENT_TYPE::BUTTON_PRESS, }); break; } case WM_RBUTTONUP: { + mouse[BUTTON::RIGHT] = false; events.push_back({ .data { - .button = BUTTONS::RIGHT, + .button = BUTTON::RIGHT, }, - .type = EVENT_TYPES::BUTTON_RELEASE, + .type = EVENT_TYPE::BUTTON_RELEASE, }); break; } case WM_MBUTTONDOWN: { + mouse[BUTTON::MIDDLE] = true; events.push_back({ .data { - .button = BUTTONS::MIDDLE, + .button = BUTTON::MIDDLE, }, - .type = EVENT_TYPES::BUTTON_PRESS, + .type = EVENT_TYPE::BUTTON_PRESS, }); break; } case WM_MBUTTONUP: { + mouse[BUTTON::MIDDLE] = false; events.push_back({ .data { - .button = BUTTONS::MIDDLE, + .button = BUTTON::MIDDLE, }, - .type = EVENT_TYPES::BUTTON_RELEASE, + .type = EVENT_TYPE::BUTTON_RELEASE, }); break; } @@ -387,7 +404,19 @@ LRESULT window::message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lpar .y = GET_Y_LPARAM(lparam), }, }, - .type = EVENT_TYPES::MOUSE_MOVE, + .type = EVENT_TYPE::MOUSE_MOVE, + }); + break; + } + case WM_MOUSEWHEEL: { + events.push_back({ + .data { + .delta { + .x = 0, + .y = GET_WHEEL_DELTA_WPARAM(wparam) / WHEEL_DELTA, + }, + }, + .type = EVENT_TYPE::MOUSE_WHEEL, }); break; } @@ -400,6 +429,10 @@ LRESULT window::message_handler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lpar return 0; } + +void window::set_cursor(enum CURSOR_TYPE type) { + SetCursor(window::cursors[type]); +} #elif defined(MACOS) window::window(uint32_t width, uint32_t height) { } |
