From 84099f07ed768aa25c46d25cec1e81aa01fd713a Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Sun, 4 May 2025 05:15:31 +0200 Subject: [PATCH] WIP crafter.math --- Crafter.Graphics-Camera.cpp | 19 +- Crafter.Graphics-Camera.cppm | 18 +- Crafter.Graphics-MeshShader.cppm | 14 +- Crafter.Graphics-Types.cppm | 2 +- Crafter.Graphics-VulkanPipeline.cppm | 10 +- Crafter.Graphics-Window.cppm | 4 + Crafter.Graphics-WindowWayland.cpp | 91 ++++++++++ Crafter.Graphics-WindowWayland.cppm | 1 + camera.hpp | 256 --------------------------- main.cpp | 8 +- project.json | 26 ++- 11 files changed, 139 insertions(+), 310 deletions(-) delete mode 100644 camera.hpp diff --git a/Crafter.Graphics-Camera.cpp b/Crafter.Graphics-Camera.cpp index 88d3eeb..33c6d70 100644 --- a/Crafter.Graphics-Camera.cpp +++ b/Crafter.Graphics-Camera.cpp @@ -1,26 +1,15 @@ module; #include -#define GLM_FORCE_RADIANS -#define GLM_FORCE_DEPTH_ZERO_TO_ONE -#define GLM_ENABLE_EXPERIMENTAL -#include -#include -#include -#include #include "VulkanBuffer.h" -#include "camera.hpp" #include module Crafter.Graphics; +import Crafter.Math; using namespace Crafter; -Camera::Camera() { - old::Camera camera; - camera.type = old::Camera::CameraType::firstperson; - camera.setPerspective(90.0f, 16 / 9, 0.1f, 512.0f); - camera.setRotation(glm::vec3(180.0f, 150, 0)); - camera.setTranslation(glm::vec3(-100.0f, -130.0f, -100.0f)); - +Camera::Camera(float fov, float aspectRatio, float near, float far) { + projection = Matrix::Projection(fov, aspectRatio, near, far); + view = Matrix::Idenity(); projectionView = camera.matrices.perspective*camera.matrices.view; } \ No newline at end of file diff --git a/Crafter.Graphics-Camera.cppm b/Crafter.Graphics-Camera.cppm index 2ebdeca..06ccf6b 100644 --- a/Crafter.Graphics-Camera.cppm +++ b/Crafter.Graphics-Camera.cppm @@ -1,26 +1,18 @@ module; #include -#define GLM_FORCE_RADIANS -#define GLM_FORCE_DEPTH_ZERO_TO_ONE -#define GLM_ENABLE_EXPERIMENTAL -#include -#include -#include -#include -#include "VulkanBuffer.h" -#include "camera.hpp" export module Crafter.Graphics:Camera; import :VulkanBuffer; import Crafter.Component; +import Crafter.Math; namespace Crafter { export class Camera : public Component { public: - glm::mat4 projection; - glm::mat4 view; - glm::mat4 projectionView; - Camera(); + Matrix projection; + Matrix view; + Matrix projectionView; + Camera(float fov, float aspectRatio, float near, float far); }; } diff --git a/Crafter.Graphics-MeshShader.cppm b/Crafter.Graphics-MeshShader.cppm index 07073f6..6c9b57d 100644 --- a/Crafter.Graphics-MeshShader.cppm +++ b/Crafter.Graphics-MeshShader.cppm @@ -4,13 +4,7 @@ module; #include #include #include -#define GLM_FORCE_RADIANS -#define GLM_FORCE_DEPTH_ZERO_TO_ONE -#define GLM_ENABLE_EXPERIMENTAL -#include -#include -#include -#include +#include export module Crafter.Graphics:MeshShader; import Crafter.Component; @@ -23,10 +17,10 @@ namespace Crafter { export template class MeshShader { public: - glm::mat4 transform; + //glm::mat4 transform; ComponentRefOwning> mesh; ComponentRefOwning camera; - Buffer mvp; + Buffer mvp; std::uint32_t threadCount; MeshShader(Mesh* mesh, Camera* camera) : threadCount(std::ceil(static_cast(mesh->indexCount)/64/3)), mvp(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), mesh(mesh), camera(camera) { @@ -37,7 +31,7 @@ namespace Crafter { set.Write(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2, &mesh.component->indicies.descriptor); } void Update() { - mvp.value[0] = camera.component->projectionView*transform; + //mvp.value[0] = camera.component->projectionView*transform; } }; } diff --git a/Crafter.Graphics-Types.cppm b/Crafter.Graphics-Types.cppm index 31c4ace..d798304 100644 --- a/Crafter.Graphics-Types.cppm +++ b/Crafter.Graphics-Types.cppm @@ -29,7 +29,7 @@ namespace Crafter { float z; float w; }; - export struct Vertex_xf32_yf32_zf32_wf32_uf32_vf32 { + export struct __attribute__((packed)) VertexUV { float x; float y; float z; diff --git a/Crafter.Graphics-VulkanPipeline.cppm b/Crafter.Graphics-VulkanPipeline.cppm index 9284621..1808287 100644 --- a/Crafter.Graphics-VulkanPipeline.cppm +++ b/Crafter.Graphics-VulkanPipeline.cppm @@ -4,15 +4,7 @@ module; #include #include #include "VulkanInitializers.hpp" -#define GLM_FORCE_RADIANS -#define GLM_FORCE_DEPTH_ZERO_TO_ONE -#define GLM_ENABLE_EXPERIMENTAL -#include -#include -#include -#include #include "VulkanBuffer.h" -#include "camera.hpp" #include export module Crafter.Graphics:VulkanPipeline; @@ -157,7 +149,7 @@ namespace Crafter { // Pipeline VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vks::initializers::pipelineInputAssemblyStateCreateInfo(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0, VK_FALSE); - VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE, 0); + VkPipelineRasterizationStateCreateInfo rasterizationState = vks::initializers::pipelineRasterizationStateCreateInfo(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_CLOCKWISE, 0); VkPipelineColorBlendAttachmentState blendAttachmentState = vks::initializers::pipelineColorBlendAttachmentState(0xf, VK_FALSE); VkPipelineColorBlendStateCreateInfo colorBlendState = vks::initializers::pipelineColorBlendStateCreateInfo(1, &blendAttachmentState); VkPipelineDepthStencilStateCreateInfo depthStencilState = vks::initializers::pipelineDepthStencilStateCreateInfo(VK_TRUE, VK_TRUE, VK_COMPARE_OP_LESS_OR_EQUAL); diff --git a/Crafter.Graphics-Window.cppm b/Crafter.Graphics-Window.cppm index 19cc70e..ca5e02b 100644 --- a/Crafter.Graphics-Window.cppm +++ b/Crafter.Graphics-Window.cppm @@ -28,6 +28,10 @@ export namespace Crafter { MousePoint mouseDelta; bool mouseLeftHeld = false; bool mouseRightHeld = false; + bool heldkeys[255] = {}; + Event onKeyDown[255]; + Event onKeyHold[255]; + Event onKeyUp[255]; ComponentRefVectorOwning elements; std::string name; std::uint32_t width; diff --git a/Crafter.Graphics-WindowWayland.cpp b/Crafter.Graphics-WindowWayland.cpp index a65dd9e..daea4ae 100644 --- a/Crafter.Graphics-WindowWayland.cpp +++ b/Crafter.Graphics-WindowWayland.cpp @@ -33,6 +33,8 @@ module; #include #include #include +#include +#include module Crafter.Graphics; @@ -100,6 +102,91 @@ wl_pointer_listener WindowWayland::pointer_listener = { .axis = WindowWayland::PointerListenerHandleAxis, }; +xkb_keymap* xkb_keymap; +xkb_context* xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); +xkb_state* xkb_state; + + +void keyboard_keymap(void *data, wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) { + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { + close(fd); + fprintf(stderr, "Unsupported keymap format\n"); + return; + } + + void *map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) { + close(fd); + perror("mmap"); + return; + } + + xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + xkb_keymap = xkb_keymap_new_from_string(xkb_context, (const char *)map, XKB_KEYMAP_FORMAT_TEXT_V1,XKB_KEYMAP_COMPILE_NO_FLAGS); + munmap(map, size); + close(fd); + + xkb_state = xkb_state_new(xkb_keymap); +} + +void keyboard_enter(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface, wl_array *keys) { + +} + +void keyboard_leave(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface) { + +} + +void keyboard_key(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { + if (!xkb_state) { + return; + } + + WindowWayland* window = reinterpret_cast(data); + + xkb_keycode_t keycode = key + 8; + xkb_keysym_t keysym = xkb_state_key_get_one_sym(xkb_state, keycode); + + char utf8[8] = {0}; + int len = xkb_keysym_to_utf8(keysym, utf8, sizeof(utf8)); + if (len != 0) { + char keypress = utf8[0]; + if(state == WL_KEYBOARD_KEY_STATE_PRESSED) { + if(window->heldkeys[keypress]) { + window->onKeyHold[keypress].Invoke(); + } else{ + window->onKeyDown[keypress].Invoke(); + } + } else{ + window->onKeyUp[keypress].Invoke(); + } + + } else { + // // fallback for keys like Return, Escape, etc. + // char name[64]; + // if (xkb_keysym_get_name(keysym, name, sizeof(name)) > 0) { + // printf("Key %s pressed (non-printable or multi-char)\n", name); + // } + } +} + +void keyboard_modifiers(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { + +} + +void keyboard_repeat_info(void *data, wl_keyboard *keyboard, int32_t rate, int32_t delay) { + +} + +wl_keyboard_listener WindowWayland::keyboard_listener = { + .keymap = keyboard_keymap, + .enter = keyboard_enter, + .leave = keyboard_leave, + .key = keyboard_key, + .modifiers = keyboard_modifiers, + .repeat_info = keyboard_repeat_info, +}; + void WindowWayland::seat_handle_capabilities(void* data, wl_seat* seat, uint32_t capabilities) { WindowWayland* window = reinterpret_cast(data); window->seat = seat; @@ -107,6 +194,10 @@ void WindowWayland::seat_handle_capabilities(void* data, wl_seat* seat, uint32_t wl_pointer* pointer = wl_seat_get_pointer(seat); wl_pointer_add_listener(pointer, &pointer_listener, window); } + if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) { + wl_keyboard* keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_add_listener(keyboard, &keyboard_listener, NULL); + } } wl_seat_listener WindowWayland::seat_listener = { diff --git a/Crafter.Graphics-WindowWayland.cppm b/Crafter.Graphics-WindowWayland.cppm index 1eebf37..aa92da0 100644 --- a/Crafter.Graphics-WindowWayland.cppm +++ b/Crafter.Graphics-WindowWayland.cppm @@ -32,6 +32,7 @@ export namespace Crafter { wl_display* display = NULL; inline static wl_compositor* compositor = NULL; static wl_pointer_listener pointer_listener; + static wl_keyboard_listener keyboard_listener; static wl_seat_listener seat_listener; static wl_registry_listener registry_listener; static xdg_surface_listener xdg_surface_listener; diff --git a/camera.hpp b/camera.hpp deleted file mode 100644 index 1f93960..0000000 --- a/camera.hpp +++ /dev/null @@ -1,256 +0,0 @@ -/* -* Basic camera class providing a look-at and first-person camera -* -* Copyright (C) 2016-2024 by Sascha Willems - www.saschawillems.de -* -* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) -*/ - -#define GLM_FORCE_RADIANS -#define GLM_FORCE_DEPTH_ZERO_TO_ONE -#include -#include -#include - -namespace old { - class Camera - { - private: - float fov; - float znear, zfar; - - void updateViewMatrix() - { - glm::mat4 currentMatrix = matrices.view; - - glm::mat4 rotM = glm::mat4(1.0f); - glm::mat4 transM; - - rotM = glm::rotate(rotM, glm::radians(rotation.x * (flipY ? -1.0f : 1.0f)), glm::vec3(1.0f, 0.0f, 0.0f)); - rotM = glm::rotate(rotM, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f)); - rotM = glm::rotate(rotM, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f)); - - glm::vec3 translation = position; - if (flipY) { - translation.y *= -1.0f; - } - transM = glm::translate(glm::mat4(1.0f), translation); - - if (type == CameraType::firstperson) - { - matrices.view = rotM * transM; - } - else - { - matrices.view = transM * rotM; - } - - viewPos = glm::vec4(position, 0.0f) * glm::vec4(-1.0f, 1.0f, -1.0f, 1.0f); - - if (matrices.view != currentMatrix) { - updated = true; - } - }; - public: - enum CameraType { lookat, firstperson }; - CameraType type = CameraType::lookat; - - glm::vec3 rotation = glm::vec3(); - glm::vec3 position = glm::vec3(); - glm::vec4 viewPos = glm::vec4(); - - float rotationSpeed = 1.0f; - float movementSpeed = 1.0f; - - bool updated = true; - bool flipY = false; - - struct - { - glm::mat4 perspective; - glm::mat4 view; - } matrices; - - struct - { - bool left = false; - bool right = false; - bool up = false; - bool down = false; - } keys; - - bool moving() const - { - return keys.left || keys.right || keys.up || keys.down; - } - - float getNearClip() const { - return znear; - } - - float getFarClip() const { - return zfar; - } - - void setPerspective(float fov, float aspect, float znear, float zfar) - { - glm::mat4 currentMatrix = matrices.perspective; - this->fov = fov; - this->znear = znear; - this->zfar = zfar; - matrices.perspective = glm::perspective(glm::radians(fov), aspect, znear, zfar); - if (flipY) { - matrices.perspective[1][1] *= -1.0f; - } - if (matrices.view != currentMatrix) { - updated = true; - } - }; - - void updateAspectRatio(float aspect) - { - glm::mat4 currentMatrix = matrices.perspective; - matrices.perspective = glm::perspective(glm::radians(fov), aspect, znear, zfar); - if (flipY) { - matrices.perspective[1][1] *= -1.0f; - } - if (matrices.view != currentMatrix) { - updated = true; - } - } - - void setPosition(glm::vec3 position) - { - this->position = position; - updateViewMatrix(); - } - - void setRotation(glm::vec3 rotation) - { - this->rotation = rotation; - updateViewMatrix(); - } - - void rotate(glm::vec3 delta) - { - this->rotation += delta; - updateViewMatrix(); - } - - void setTranslation(glm::vec3 translation) - { - this->position = translation; - updateViewMatrix(); - }; - - void translate(glm::vec3 delta) - { - this->position += delta; - updateViewMatrix(); - } - - void setRotationSpeed(float rotationSpeed) - { - this->rotationSpeed = rotationSpeed; - } - - void setMovementSpeed(float movementSpeed) - { - this->movementSpeed = movementSpeed; - } - - void update(float deltaTime) - { - updated = false; - if (type == CameraType::firstperson) - { - if (moving()) - { - glm::vec3 camFront; - camFront.x = -cos(glm::radians(rotation.x)) * sin(glm::radians(rotation.y)); - camFront.y = sin(glm::radians(rotation.x)); - camFront.z = cos(glm::radians(rotation.x)) * cos(glm::radians(rotation.y)); - camFront = glm::normalize(camFront); - - float moveSpeed = deltaTime * movementSpeed; - - if (keys.up) - position += camFront * moveSpeed; - if (keys.down) - position -= camFront * moveSpeed; - if (keys.left) - position -= glm::normalize(glm::cross(camFront, glm::vec3(0.0f, 1.0f, 0.0f))) * moveSpeed; - if (keys.right) - position += glm::normalize(glm::cross(camFront, glm::vec3(0.0f, 1.0f, 0.0f))) * moveSpeed; - } - } - updateViewMatrix(); - }; - - // Update camera passing separate axis data (gamepad) - // Returns true if view or position has been changed - bool updatePad(glm::vec2 axisLeft, glm::vec2 axisRight, float deltaTime) - { - bool retVal = false; - - if (type == CameraType::firstperson) - { - // Use the common console thumbstick layout - // Left = view, right = move - - const float deadZone = 0.0015f; - const float range = 1.0f - deadZone; - - glm::vec3 camFront; - camFront.x = -cos(glm::radians(rotation.x)) * sin(glm::radians(rotation.y)); - camFront.y = sin(glm::radians(rotation.x)); - camFront.z = cos(glm::radians(rotation.x)) * cos(glm::radians(rotation.y)); - camFront = glm::normalize(camFront); - - float moveSpeed = deltaTime * movementSpeed * 2.0f; - float rotSpeed = deltaTime * rotationSpeed * 50.0f; - - // Move - if (fabsf(axisLeft.y) > deadZone) - { - float pos = (fabsf(axisLeft.y) - deadZone) / range; - position -= camFront * pos * ((axisLeft.y < 0.0f) ? -1.0f : 1.0f) * moveSpeed; - retVal = true; - } - if (fabsf(axisLeft.x) > deadZone) - { - float pos = (fabsf(axisLeft.x) - deadZone) / range; - position += glm::normalize(glm::cross(camFront, glm::vec3(0.0f, 1.0f, 0.0f))) * pos * ((axisLeft.x < 0.0f) ? -1.0f : 1.0f) * moveSpeed; - retVal = true; - } - - // Rotate - if (fabsf(axisRight.x) > deadZone) - { - float pos = (fabsf(axisRight.x) - deadZone) / range; - rotation.y += pos * ((axisRight.x < 0.0f) ? -1.0f : 1.0f) * rotSpeed; - retVal = true; - } - if (fabsf(axisRight.y) > deadZone) - { - float pos = (fabsf(axisRight.y) - deadZone) / range; - rotation.x -= pos * ((axisRight.y < 0.0f) ? -1.0f : 1.0f) * rotSpeed; - retVal = true; - } - } - else - { - // todo: move code from example base class for look-at - } - - if (retVal) - { - updateViewMatrix(); - } - - return retVal; - } - - }; -} - diff --git a/main.cpp b/main.cpp index bb68f13..3c75ade 100644 --- a/main.cpp +++ b/main.cpp @@ -27,20 +27,20 @@ int main() { WindowWaylandVulkan window("Crafter.Graphics", 1280, 720); Asset asset; - asset.LoadFull("gulch.cras"); + asset.LoadFull("cannon.cras"); Camera camera; - Mesh* mesh = Mesh::FromAssetUV(asset.entries[0].data.data()); + Mesh* mesh = Mesh::FromAssetUV(asset.entries[0].data.data()); DescriptorSet descriptors; Pipeline::GetDescriptorSet(descriptors); - MeshShader meshShader(mesh, &camera); + MeshShader meshShader(mesh, &camera); meshShader.WriteDescriptors(descriptors); meshShader.transform = glm::mat4(1.0f); meshShader.Update(); Asset asset2; - asset2.LoadFull("gulchtex.cras"); + asset2.LoadFull("texture.cras"); VkCommandBuffer cmd = window.StartInit(); VulkanTexture* txt = VulkanTexture::FromAsset(asset2.entries[0].data.data(), cmd); diff --git a/project.json b/project.json index 52bc060..00578f2 100644 --- a/project.json +++ b/project.json @@ -10,7 +10,7 @@ "build_dir": "build", "output_dir": "bin", "type":"library", - "libs": ["wayland-client", "vulkan"], + "libs": ["wayland-client", "vulkan", "xkbcommon"], "flags": ["-Wno-uninitialized"], "shaders": [ { @@ -39,7 +39,25 @@ "name": "debug", "extends": ["base"], "optimization_level": "0", - "debug": true + "debug": true, + "dependencies": [ + { + "path":"/home/jorijn/repos/Crafter/Crafter.Event/project.json", + "configuration":"debug" + }, + { + "path":"/home/jorijn/repos/Crafter/Crafter.Asset/project.json", + "configuration":"lib-debug" + }, + { + "path":"/home/jorijn/repos/Crafter/Crafter.Component/project.json", + "configuration":"debug" + }, + { + "path":"/home/jorijn/repos/Crafter/Crafter.Math/project.json", + "configuration":"debug-lib" + } + ] }, { "name": "test", @@ -58,6 +76,10 @@ { "path":"/home/jorijn/repos/Crafter/Crafter.Component/project.json", "configuration":"debug" + }, + { + "path":"/home/jorijn/repos/Crafter/Crafter.Math/project.json", + "configuration":"debug-lib" } ] },