diff --git a/Crafter.Graphics-Camera.cpp b/Crafter.Graphics-Camera.cpp new file mode 100644 index 0000000..0be2569 --- /dev/null +++ b/Crafter.Graphics-Camera.cpp @@ -0,0 +1,31 @@ +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; +using namespace Crafter; + +Camera::Camera() { + old::Camera camera; + camera.type = old::Camera::CameraType::lookat; + camera.setPerspective(60.0f, 128 / 128, 0.1f, 512.0f); + camera.setRotation(glm::vec3(0.0f, 15.0f, 0.0f)); + camera.setTranslation(glm::vec3(0.0f, 0.0f, -5.0f)); + + VulkanDevice::CreateBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &buffer, sizeof(CameraBufferData)); + VulkanDevice::CHECK_VK_RESULT(buffer.map()); + data.projection = camera.matrices.perspective; + data.view = camera.matrices.view; + data.model = glm::mat4(1.0f); + memcpy(buffer.mapped, &data, sizeof(CameraBufferData)); +} \ No newline at end of file diff --git a/Crafter.Graphics-Camera.cppm b/Crafter.Graphics-Camera.cppm new file mode 100644 index 0000000..6d3da77 --- /dev/null +++ b/Crafter.Graphics-Camera.cppm @@ -0,0 +1,29 @@ +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; + +namespace Crafter { + struct CameraBufferData { + glm::mat4 projection; + glm::mat4 model; + glm::mat4 view; + }; + export class Camera { + public: + vks::Buffer buffer; + Camera(); + private: + CameraBufferData data; + }; +} diff --git a/Crafter.Graphics-VulkanElement.cpp b/Crafter.Graphics-VulkanElement.cpp index a873b91..0089fbc 100644 --- a/Crafter.Graphics-VulkanElement.cpp +++ b/Crafter.Graphics-VulkanElement.cpp @@ -2,14 +2,24 @@ module; #include #include +#include "VulkanInitializers.hpp" module Crafter.Graphics; using namespace Crafter; -VulkanElement::VulkanElement(VkPipelineLayout pipelineLayout, VkDescriptorSet* descriptorSet, VkPipeline pipeline) : pipelineLayout(pipelineLayout), descriptorSet(descriptorSet), pipeline(pipeline) { +VulkanElement::VulkanElement(VkPipelineLayout pipelineLayout, VkPipeline pipeline) : pipelineLayout(pipelineLayout), pipeline(pipeline) { } -VulkanElement::VulkanElement(VkPipelineLayout pipelineLayout, VkDescriptorSet* descriptorSet, VkPipeline pipeline, std::uint32_t sizeX, std::uint32_t sizeY, std::uint32_t sizeZ) : pipelineLayout(pipelineLayout), descriptorSet(descriptorSet), pipeline(pipeline), sizeX(sizeX), sizeY(sizeY), sizeZ(sizeZ) { +VulkanElement::VulkanElement(VkPipelineLayout pipelineLayout, VkPipeline pipeline, std::uint32_t sizeX, std::uint32_t sizeY, std::uint32_t sizeZ) : pipelineLayout(pipelineLayout), pipeline(pipeline), sizeX(sizeX), sizeY(sizeY), sizeZ(sizeZ) { -} \ No newline at end of file +} + +void VulkanElement::WriteDescriptor(VkWriteDescriptorSet* set, std::uint32_t count) { + vkUpdateDescriptorSets(VulkanDevice::device, count, set, 0, nullptr); +} + +void VulkanElement::WriteDescriptor(std::uint32_t stage, VkDescriptorType type, std::uint32_t binding, VkDescriptorBufferInfo* buffer) { + VkWriteDescriptorSet write = vks::initializers::writeDescriptorSet(descriptorSet[stage], type, binding, buffer); + vkUpdateDescriptorSets(VulkanDevice::device, 1, &write, 0, nullptr); +} diff --git a/Crafter.Graphics-VulkanElement.cppm b/Crafter.Graphics-VulkanElement.cppm index e561d5e..16314e8 100644 --- a/Crafter.Graphics-VulkanElement.cppm +++ b/Crafter.Graphics-VulkanElement.cppm @@ -10,22 +10,14 @@ namespace Crafter { export class VulkanElement : public Component { public: VkPipelineLayout pipelineLayout; - VkDescriptorSet* descriptorSet; + VkDescriptorSet descriptorSet[2]; VkPipeline pipeline; std::uint32_t sizeX; std::uint32_t sizeY; std::uint32_t sizeZ; - VulkanElement(VkPipelineLayout pipelineLayout, VkDescriptorSet* descriptorSet, VkPipeline pipeline); - VulkanElement(VkPipelineLayout pipelineLayout, VkDescriptorSet* descriptorSet, VkPipeline pipeline, std::uint32_t sizeX, std::uint32_t sizeY, std::uint32_t sizeZ); - - template - static VulkanElement FromPipeline() { - return VulkanElement(Pipeline::pipelineLayout, &Pipeline::descriptorSet, Pipeline::pipeline); - } - - template - static VulkanElement FromPipeline(std::uint32_t sizeX, std::uint32_t sizeY, std::uint32_t sizeZ) { - return VulkanElement(Pipeline::pipelineLayout, &Pipeline::descriptorSet, Pipeline::pipeline, sizeX, sizeY, sizeZ); - } + VulkanElement(VkPipelineLayout pipelineLayout, VkPipeline pipeline); + VulkanElement(VkPipelineLayout pipelineLayout, VkPipeline pipeline, std::uint32_t sizeX, std::uint32_t sizeY, std::uint32_t sizeZ); + void WriteDescriptor(VkWriteDescriptorSet* descriptors, std::uint32_t count); + void WriteDescriptor(std::uint32_t stage, VkDescriptorType type, std::uint32_t binding, VkDescriptorBufferInfo* buffer); }; } diff --git a/Crafter.Graphics-VulkanElementFromPipeline.cppm b/Crafter.Graphics-VulkanElementFromPipeline.cppm new file mode 100644 index 0000000..fc97ec9 --- /dev/null +++ b/Crafter.Graphics-VulkanElementFromPipeline.cppm @@ -0,0 +1,22 @@ +module; + +#include +#include + +export module Crafter.Graphics:VulkanElementFromPipeline; +import Crafter.Component; +import :VulkanPipeline; +import :VulkanElement; + +namespace Crafter { + export template + class VulkanElementFromPipeline : public VulkanElement { + public: + VulkanElementFromPipeline() : VulkanElement(Pipeline::pipelineLayout, Pipeline::pipeline) { + Pipeline::GetDescriptorSet(&descriptorSet[0]); + } + VulkanElementFromPipeline(std::uint32_t sizeX, std::uint32_t sizeY, std::uint32_t sizeZ) : VulkanElement(Pipeline::pipelineLayout, Pipeline::pipeline, sizeX, sizeY, sizeZ) { + Pipeline::GetDescriptorSet(&descriptorSet[0]); + } + }; +} diff --git a/Crafter.Graphics-VulkanPipeline.cppm b/Crafter.Graphics-VulkanPipeline.cppm index 5076506..259e2a2 100644 --- a/Crafter.Graphics-VulkanPipeline.cppm +++ b/Crafter.Graphics-VulkanPipeline.cppm @@ -29,7 +29,6 @@ namespace Crafter { export template class VulkanPipeline { private: - constexpr static std::uint32_t totalDescriptorCount = MeshShader::descriptorCount+FragmentShader::descriptorCount; consteval static std::uint32_t GetUniqueDiscriptorCount() { DescriptorEntry types[] = {{VK_DESCRIPTOR_TYPE_SAMPLER, 0},{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0},{VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0},{VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 0},{VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 0},{VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 0},{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0},{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0},{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 0},{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 0},{VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 0},{VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, 0},{VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 0},{VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV, 0},{VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM, 0},{VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM, 0},{VK_DESCRIPTOR_TYPE_MUTABLE_EXT, 0},{VK_DESCRIPTOR_TYPE_PARTITIONED_ACCELERATION_STRUCTURE_NV, 0},{VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT, 0},{VK_DESCRIPTOR_TYPE_MUTABLE_VALVE, 0}}; @@ -87,18 +86,13 @@ namespace Crafter { return types; } - consteval static std::array GetDescriptorSet() { - std::array set; - std::uint32_t i = 0; - for(const DescriptorBinding& binding : MeshShader::descriptors) { - set[i] = {binding.slot, binding.type, 1, VK_SHADER_STAGE_MESH_BIT_EXT, nullptr}; - i++; - } + template + consteval static std::array GetDescriptorSet() { + std::array set; - for(const DescriptorBinding& binding : FragmentShader::descriptors) { - set[i] = {binding.slot, binding.type, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}; - i++; + for(std::uint32_t i = 0; i < Shader::descriptors.size(); i++) { + set[i] = {Shader::descriptors[i].slot, Shader::descriptors[i].type, 1, Flag, nullptr}; } return set; @@ -106,105 +100,86 @@ namespace Crafter { public: inline static VkPipeline pipeline; inline static VkPipelineLayout pipelineLayout; - inline static VkDescriptorSet descriptorSet = VK_NULL_HANDLE; - inline static VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE; inline static VkDescriptorPool descriptorPool = VK_NULL_HANDLE; - - inline static struct UniformData { - glm::mat4 projection; - glm::mat4 model; - glm::mat4 view; - } uniformData; - inline static vks::Buffer uniformBuffer; + inline static VkDescriptorSetLayout descriptorSetLayout[2]; static void CreatePipeline() { - Camera camera; - camera.type = Camera::CameraType::lookat; - camera.setPerspective(60.0f, 128 / 128, 0.1f, 512.0f); - camera.setRotation(glm::vec3(0.0f, 15.0f, 0.0f)); - camera.setTranslation(glm::vec3(0.0f, 0.0f, -5.0f)); - - VulkanDevice::CreateBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniformBuffer, sizeof(UniformData)); - VulkanDevice::CHECK_VK_RESULT(uniformBuffer.map()); - uniformData.projection = camera.matrices.perspective; - uniformData.view = camera.matrices.view; - uniformData.model = glm::mat4(1.0f); - memcpy(uniformBuffer.mapped, &uniformData, sizeof(UniformData)); + // Pool + std::array poolSizes = GetPoolSizes(); + VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(uniqueDescriptorCount, poolSizes.data(), 2); + VulkanDevice::CHECK_VK_RESULT(vkCreateDescriptorPool(VulkanDevice::device, &descriptorPoolInfo, nullptr, &descriptorPool)); - // Pool - std::array poolSizes = GetPoolSizes(); - VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(uniqueDescriptorCount, poolSizes.data(), 1); - VulkanDevice::CHECK_VK_RESULT(vkCreateDescriptorPool(VulkanDevice::device, &descriptorPoolInfo, nullptr, &descriptorPool)); + // Layout + constexpr std::array setLayoutBindingsMesh = GetDescriptorSet(); + VkDescriptorSetLayoutCreateInfo descriptorLayoutInfoMesh = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindingsMesh.data(), MeshShader::descriptorCount); + VulkanDevice::CHECK_VK_RESULT(vkCreateDescriptorSetLayout(VulkanDevice::device, &descriptorLayoutInfoMesh, nullptr, &descriptorSetLayout[0])); - // Layout - constexpr std::array setLayoutBindings = GetDescriptorSet(); - VkDescriptorSetLayoutCreateInfo descriptorLayoutInfo = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings.data(), totalDescriptorCount); - VulkanDevice::CHECK_VK_RESULT(vkCreateDescriptorSetLayout(VulkanDevice::device, &descriptorLayoutInfo, nullptr, &descriptorSetLayout)); + constexpr std::array setLayoutBindingsFragment = GetDescriptorSet(); + VkDescriptorSetLayoutCreateInfo descriptorLayoutInfoFragment = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindingsFragment.data(), FragmentShader::descriptorCount); + VulkanDevice::CHECK_VK_RESULT(vkCreateDescriptorSetLayout(VulkanDevice::device, &descriptorLayoutInfoFragment, nullptr, &descriptorSetLayout[1])); - // Set - VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout, 1); - VulkanDevice::CHECK_VK_RESULT(vkAllocateDescriptorSets(VulkanDevice::device, &allocInfo, &descriptorSet)); + // Layout + VkPipelineLayoutCreateInfo pipelineLayoutInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout[0], 2); + VulkanDevice::CHECK_VK_RESULT(vkCreatePipelineLayout(VulkanDevice::device, &pipelineLayoutInfo, nullptr, &pipelineLayout)); - std::vector modelWriteDescriptorSets = { - vks::initializers::writeDescriptorSet(descriptorSet, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffer.descriptor), - }; - vkUpdateDescriptorSets(VulkanDevice::device, static_cast(modelWriteDescriptorSets.size()), modelWriteDescriptorSets.data(), 0, nullptr); + // 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_BACK_BIT, VK_FRONT_FACE_COUNTER_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); + VkPipelineViewportStateCreateInfo viewportState = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); + VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0); + std::vector dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables); + std::array shaderStages; - // Layout - VkPipelineLayoutCreateInfo pipelineLayoutInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1); - VulkanDevice::CHECK_VK_RESULT(vkCreatePipelineLayout(VulkanDevice::device, &pipelineLayoutInfo, nullptr, &pipelineLayout)); + VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; - // 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_BACK_BIT, VK_FRONT_FACE_COUNTER_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); - VkPipelineViewportStateCreateInfo viewportState = vks::initializers::pipelineViewportStateCreateInfo(1, 1, 0); - VkPipelineMultisampleStateCreateInfo multisampleState = vks::initializers::pipelineMultisampleStateCreateInfo(VK_SAMPLE_COUNT_1_BIT, 0); - std::vector dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; - VkPipelineDynamicStateCreateInfo dynamicState = vks::initializers::pipelineDynamicStateCreateInfo(dynamicStateEnables); - std::array shaderStages; + VkPipelineRenderingCreateInfoKHR pipeline_create{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR}; + pipeline_create.pNext = VK_NULL_HANDLE; + pipeline_create.colorAttachmentCount = 1; + pipeline_create.pColorAttachmentFormats = &format; + pipeline_create.depthAttachmentFormat = VulkanDevice::depthFormat; - VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; + VkGraphicsPipelineCreateInfo pipelineCI = vks::initializers::pipelineCreateInfo(pipelineLayout, VK_NULL_HANDLE, 0); - VkPipelineRenderingCreateInfoKHR pipeline_create{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR}; - pipeline_create.pNext = VK_NULL_HANDLE; - pipeline_create.colorAttachmentCount = 1; - pipeline_create.pColorAttachmentFormats = &format; - pipeline_create.depthAttachmentFormat = VulkanDevice::depthFormat; + pipelineCI.pNext = &pipeline_create; + pipelineCI.pRasterizationState = &rasterizationState; + pipelineCI.pColorBlendState = &colorBlendState; + pipelineCI.pMultisampleState = &multisampleState; + pipelineCI.pViewportState = &viewportState; + pipelineCI.pDepthStencilState = &depthStencilState; + pipelineCI.pDynamicState = &dynamicState; + pipelineCI.stageCount = static_cast(shaderStages.size()); + pipelineCI.pStages = shaderStages.data(); - VkGraphicsPipelineCreateInfo pipelineCI = vks::initializers::pipelineCreateInfo(pipelineLayout, VK_NULL_HANDLE, 0); + // Not using a vertex shader, mesh shading doesn't require vertex input state + pipelineCI.pInputAssemblyState = nullptr; + pipelineCI.pVertexInputState = nullptr; - pipelineCI.pNext = &pipeline_create; - pipelineCI.pRasterizationState = &rasterizationState; - pipelineCI.pColorBlendState = &colorBlendState; - pipelineCI.pMultisampleState = &multisampleState; - pipelineCI.pViewportState = &viewportState; - pipelineCI.pDepthStencilState = &depthStencilState; - pipelineCI.pDynamicState = &dynamicState; - pipelineCI.stageCount = static_cast(shaderStages.size()); - pipelineCI.pStages = shaderStages.data(); - - // Not using a vertex shader, mesh shading doesn't require vertex input state - pipelineCI.pInputAssemblyState = nullptr; - pipelineCI.pVertexInputState = nullptr; - - //Mesh stage of the pipeline - shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStages[0].stage = MeshShader::_stage; - shaderStages[0].module = MeshShader::shader; - shaderStages[0].pName = MeshShader::_entrypoint.value; - shaderStages[0].flags = 0; - - // Fragment stage of the pipeline - shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shaderStages[1].stage = FragmentShader::_stage; - shaderStages[1].module = FragmentShader::shader; - shaderStages[1].pName = FragmentShader::_entrypoint.value; - shaderStages[1].flags = 0; - - VulkanDevice::CHECK_VK_RESULT(vkCreateGraphicsPipelines(VulkanDevice::device, VK_NULL_HANDLE, 1, &pipelineCI, nullptr, &pipeline)); + //Mesh stage of the pipeline + shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[0].stage = MeshShader::_stage; + shaderStages[0].module = MeshShader::shader; + shaderStages[0].pName = MeshShader::_entrypoint.value; + shaderStages[0].flags = 0; + shaderStages[0].pSpecializationInfo = nullptr; + + // Fragment stage of the pipeline + shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[1].stage = FragmentShader::_stage; + shaderStages[1].module = FragmentShader::shader; + shaderStages[1].pName = FragmentShader::_entrypoint.value; + shaderStages[1].flags = 0; + shaderStages[1].pSpecializationInfo = nullptr; + + VulkanDevice::CHECK_VK_RESULT(vkCreateGraphicsPipelines(VulkanDevice::device, VK_NULL_HANDLE, 1, &pipelineCI, nullptr, &pipeline)); } + + static void GetDescriptorSet(VkDescriptorSet* set) { + VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout[0], 2); + VulkanDevice::CHECK_VK_RESULT(vkAllocateDescriptorSets(VulkanDevice::device, &allocInfo, set)); + } }; } \ No newline at end of file diff --git a/Crafter.Graphics-WindowWaylandVulkan.cpp b/Crafter.Graphics-WindowWaylandVulkan.cpp index b9b3a07..50884a1 100644 --- a/Crafter.Graphics-WindowWaylandVulkan.cpp +++ b/Crafter.Graphics-WindowWaylandVulkan.cpp @@ -419,7 +419,7 @@ void WindowWaylandVulkan::Start() { vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); for(VulkanElement* element : vulkanElements.components) { - vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, element->pipelineLayout, 0, 1, element->descriptorSet, 0, NULL); + vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, element->pipelineLayout, 0, 2, element->descriptorSet, 0, NULL); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, element->pipeline); VulkanDevice::vkCmdDrawMeshTasksEXTProc(drawCmdBuffers[i], element->sizeX, element->sizeY, element->sizeZ); VulkanDevice::vkCmdEndRenderingKHRProc(drawCmdBuffers[i]); diff --git a/Crafter.Graphics.cppm b/Crafter.Graphics.cppm index aaa5758..c803a73 100644 --- a/Crafter.Graphics.cppm +++ b/Crafter.Graphics.cppm @@ -9,4 +9,6 @@ export import :Types; export import :VulkanDevice; export import :VulkanPipeline; export import :VulkanShader; -export import :VulkanElement; \ No newline at end of file +export import :VulkanElement; +export import :Camera; +export import :VulkanElementFromPipeline; \ No newline at end of file diff --git a/camera.hpp b/camera.hpp index 4838bde..1f93960 100644 --- a/camera.hpp +++ b/camera.hpp @@ -12,242 +12,245 @@ #include #include -class Camera -{ -private: - float fov; - float znear, zfar; - - void updateViewMatrix() +namespace old { + class Camera { - 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) + private: + float fov; + float znear, zfar; + + void updateViewMatrix() { - 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::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; - - 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; + + 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; } - 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; - } - -}; \ No newline at end of file diff --git a/main.cpp b/main.cpp index f64750f..0063ce2 100644 --- a/main.cpp +++ b/main.cpp @@ -31,12 +31,15 @@ int main() { // } + //WriteDescriptor(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &uniformBuffer.descriptor); VulkanDevice::CreateDevice(); WindowWaylandVulkan window("Crafter.Graphics", 128, 128); MeshShader::CreateShader(); FragmentShader::CreateShader(); Pipeline::CreatePipeline(); - VulkanElement test = VulkanElement::FromPipeline(3, 1, 1); + VulkanElement test = VulkanElementFromPipeline(3, 1, 1); + Camera camera; + test.WriteDescriptor(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &camera.buffer.descriptor); window.vulkanElements.AddComponent(&test); window.Start(); while(true) { diff --git a/project.json b/project.json index 9045a7e..80a729e 100644 --- a/project.json +++ b/project.json @@ -4,9 +4,9 @@ { "name": "base", "standard": "c++26", - "source_files": ["Crafter.Graphics-Window","Crafter.Graphics-WindowWayland","Crafter.Graphics-WindowWaylandWayland", "Crafter.Graphics-UiElement", "Crafter.Graphics-VulkanDevice", "Crafter.Graphics-WindowWaylandVulkan", "VulkanBuffer", "VulkanTools", "Crafter.Graphics-VulkanElement"], + "source_files": ["Crafter.Graphics-Window","Crafter.Graphics-WindowWayland","Crafter.Graphics-WindowWaylandWayland", "Crafter.Graphics-UiElement", "Crafter.Graphics-VulkanDevice", "Crafter.Graphics-WindowWaylandVulkan", "VulkanBuffer", "VulkanTools", "Crafter.Graphics-VulkanElement", "Crafter.Graphics-Camera"], "c_files": ["wayland-xdg-decoration-unstable-v1-client-protocol", "xdg-shell-protocol", "shm"], - "module_files": ["Crafter.Graphics-Window","Crafter.Graphics-WindowWayland","Crafter.Graphics-WindowWaylandWayland", "Crafter.Graphics", "Crafter.Graphics-UiElement", "Crafter.Graphics-Types", "Crafter.Graphics-VulkanDevice", "Crafter.Graphics-VulkanPipeline", "Crafter.Graphics-VulkanShader", "Crafter.Graphics-WindowWaylandVulkan", "Crafter.Graphics-VulkanElement"], + "module_files": ["Crafter.Graphics-Window","Crafter.Graphics-WindowWayland","Crafter.Graphics-WindowWaylandWayland", "Crafter.Graphics", "Crafter.Graphics-UiElement", "Crafter.Graphics-Types", "Crafter.Graphics-VulkanDevice", "Crafter.Graphics-VulkanPipeline", "Crafter.Graphics-VulkanShader", "Crafter.Graphics-WindowWaylandVulkan", "Crafter.Graphics-VulkanElement", "Crafter.Graphics-VulkanElementFromPipeline", "Crafter.Graphics-Camera"], "build_dir": "./build", "output_dir": "./bin", "type":"library",