diff --git a/Crafter.Graphics-Camera.cpp b/Crafter.Graphics-Camera.cpp index b903e29..a2a8b5f 100644 --- a/Crafter.Graphics-Camera.cpp +++ b/Crafter.Graphics-Camera.cpp @@ -15,14 +15,12 @@ module; module Crafter.Graphics; using namespace Crafter; -Camera::Camera() : buffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) { +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)); + camera.setPerspective(60.0f, 16 / 9, 0.1f, 512.0f); + camera.setRotation(glm::vec3(180.0f, 0.0f, 0.0f)); + camera.setTranslation(glm::vec3(0.0f, 0.0f, -10.0f)); - buffer.value->projection = camera.matrices.perspective; - buffer.value->view = camera.matrices.view; - buffer.value->model = glm::mat4(1.0f); + 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 a9f4648..2ebdeca 100644 --- a/Crafter.Graphics-Camera.cppm +++ b/Crafter.Graphics-Camera.cppm @@ -13,16 +13,14 @@ module; export module Crafter.Graphics:Camera; import :VulkanBuffer; +import Crafter.Component; namespace Crafter { - struct CameraBufferData { - glm::mat4 projection; - glm::mat4 model; - glm::mat4 view; - }; - export class Camera { + export class Camera : public Component { public: - Buffer buffer; + glm::mat4 projection; + glm::mat4 view; + glm::mat4 projectionView; Camera(); }; } diff --git a/Crafter.Graphics-Mesh.cppm b/Crafter.Graphics-Mesh.cppm index d423d0a..ccb18d5 100644 --- a/Crafter.Graphics-Mesh.cppm +++ b/Crafter.Graphics-Mesh.cppm @@ -2,18 +2,42 @@ module; #include #include +#include +#include export module Crafter.Graphics:Mesh; +import Crafter.Component; import :VulkanBuffer; namespace Crafter { export template - class Mesh { + class Mesh : public Component { public: + std::uint32_t vertexCount; + std::uint32_t indexCount; Buffer verticies; Buffer indicies; - Mesh(std::uint32_t vertexCount, std::uint32_t indexCount) : verticies(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexCount), indicies(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexCount) { + Mesh(std::uint32_t vertexCount, std::uint32_t indexCount) : vertexCount(vertexCount), indexCount(indexCount), verticies(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexCount), indicies(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexCount) { } + static Mesh* FromAsset(const char* asset) { + std::uint32_t vertexCount = reinterpret_cast(asset)[0]; + std::uint32_t indexCount = reinterpret_cast(asset)[1]; + Mesh* mesh = new Mesh(vertexCount, (indexCount+ 63) & ~63); + const float* verticies = reinterpret_cast(asset+sizeof(std::uint32_t)*2); + std::uint32_t counter = 0; + for(std::uint32_t i = 0; i < vertexCount*3; i+=3) { + mesh->verticies.value[counter].x = verticies[i]; + mesh->verticies.value[counter].y = verticies[i+1]; + mesh->verticies.value[counter].z = verticies[i+2]; + mesh->verticies.value[counter].w = 1.0f; + counter++; + } + memcpy(mesh->indicies.value, asset+(sizeof(std::uint32_t)*2)+(vertexCount*sizeof(float)*3), indexCount*sizeof(std::uint32_t)); + for(std::uint32_t i = indexCount; i < indexCount+(indexCount%64); i++) { + mesh->indicies.value[i] = 0;//pad indicies to nearest 64 + } + return mesh; + } }; } diff --git a/Crafter.Graphics-MeshShader.cppm b/Crafter.Graphics-MeshShader.cppm new file mode 100644 index 0000000..dbe46ec --- /dev/null +++ b/Crafter.Graphics-MeshShader.cppm @@ -0,0 +1,47 @@ +module; + +#include +#include +#include +#include +#define GLM_FORCE_RADIANS +#define GLM_FORCE_DEPTH_ZERO_TO_ONE +#define GLM_ENABLE_EXPERIMENTAL +#include +#include +#include +#include + +export module Crafter.Graphics:MeshShader; +import Crafter.Component; +import :Mesh; +import :Camera; +import :VulkanElement; + + +namespace Crafter { + export template + class MeshShader { + public: + glm::mat4 transform; + ComponentRefOwning> mesh; + ComponentRefOwning camera; + Buffer mvp; + MeshShader(Mesh* mesh, Camera* camera) : mvp(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), mesh(mesh), camera(camera) { + + } + void SetGroupSize(VulkanElement* element) { + element->sizeX = (mesh.component->indexCount/3)/64; + element->sizeY = 1; + element->sizeZ = 1; + } + void WriteDescriptors(VulkanElement* element) { + element->WriteDescriptor(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &mvp.descriptor); + element->WriteDescriptor(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, &mesh.component->verticies.descriptor); + element->WriteDescriptor(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2, &mesh.component->indicies.descriptor); + } + void Update() { + mvp.value[0] = camera.component->projectionView*transform; + } + }; +} diff --git a/Crafter.Graphics-VulkanPipeline.cppm b/Crafter.Graphics-VulkanPipeline.cppm index c7c993e..81e5040 100644 --- a/Crafter.Graphics-VulkanPipeline.cppm +++ b/Crafter.Graphics-VulkanPipeline.cppm @@ -142,7 +142,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_BACK_BIT, VK_FRONT_FACE_COUNTER_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.cppm b/Crafter.Graphics.cppm index b302da0..40cfb57 100644 --- a/Crafter.Graphics.cppm +++ b/Crafter.Graphics.cppm @@ -13,4 +13,5 @@ export import :VulkanElement; export import :Camera; export import :VulkanElementFromPipeline; export import :VulkanBuffer; -export import :Mesh; \ No newline at end of file +export import :Mesh; +export import :MeshShader; \ No newline at end of file diff --git a/main.cpp b/main.cpp index ce07ec2..6c844d5 100644 --- a/main.cpp +++ b/main.cpp @@ -2,36 +2,41 @@ #include #include #include +#define GLM_FORCE_RADIANS +#define GLM_FORCE_DEPTH_ZERO_TO_ONE +#define GLM_ENABLE_EXPERIMENTAL +#include +#include +#include +#include import Crafter.Graphics; +import Crafter.Asset; using namespace Crafter; -typedef VulkanShader<"test.spirv", "main", VK_SHADER_STAGE_MESH_BIT_EXT, 3, {{{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2}}}> MeshShader; +typedef VulkanShader<"test.spirv", "main", VK_SHADER_STAGE_MESH_BIT_EXT, 3, {{{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2}}}> MeshVulkanShader; typedef VulkanShader<"test2.spirv", "main", VK_SHADER_STAGE_FRAGMENT_BIT, 0, {}> FragmentShader; -typedef VulkanPipeline Pipeline; +typedef VulkanPipeline Pipeline; int main() { VulkanDevice::CreateDevice(); - MeshShader::CreateShader(); + MeshVulkanShader::CreateShader(); FragmentShader::CreateShader(); Pipeline::CreatePipeline(); - WindowWaylandVulkan window("Crafter.Graphics", 128, 128); + WindowWaylandVulkan window("Crafter.Graphics", 1280, 720); - VulkanElement test = VulkanElementFromPipeline(1, 1, 1); + Asset asset; + asset.LoadFull("core.cras"); Camera camera; - test.WriteDescriptor(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &camera.buffer.descriptor); + VulkanElement test = VulkanElementFromPipeline(); + Mesh* mesh = Mesh::FromAsset(asset.entries[0].data.data()); - Mesh mesh(3, 3); - mesh.verticies.value[0] = {0.0f, -1.0f, 0.0f, 1.0f}; - mesh.verticies.value[1] = {-1.0f, 1.0f, 0.0f, 1.0f}; - mesh.verticies.value[2] = {1.0f, 1.0f, 0.0f, 1.0f}; - - mesh.indicies.value[0] = 0; - mesh.indicies.value[1] = 1; - mesh.indicies.value[2] = 2; - test.WriteDescriptor(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, &mesh.verticies.descriptor); - test.WriteDescriptor(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2, &mesh.indicies.descriptor); + MeshShader meshShader(mesh, &camera); + meshShader.SetGroupSize(&test); + meshShader.WriteDescriptors(&test); + meshShader.transform = glm::mat4(1.0f); + meshShader.Update(); window.vulkanElements.AddComponent(&test); window.Start(); diff --git a/project.json b/project.json index 56c84a6..6fe0ba8 100644 --- a/project.json +++ b/project.json @@ -6,7 +6,7 @@ "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", "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", "Crafter.Graphics-VulkanElementFromPipeline", "Crafter.Graphics-Camera", "Crafter.Graphics-VulkanBuffer", "Crafter.Graphics-Mesh"], + "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", "Crafter.Graphics-VulkanBuffer", "Crafter.Graphics-Mesh", "Crafter.Graphics-MeshShader"], "build_dir": "./build", "output_dir": "./bin", "type":"library", @@ -41,6 +41,10 @@ "path":"../Crafter.Event/project.json", "configuration":"debug" }, + { + "path":"../Crafter.Asset/project.json", + "configuration":"lib-debug" + }, { "path":"/home/jorijn/repos/Crafter/Crafter.Component/project.json", "configuration":"debug" diff --git a/test.mesh b/test.mesh index 52d99ee..75ab4af 100644 --- a/test.mesh +++ b/test.mesh @@ -1,53 +1,30 @@ -/* Copyright (c) 2021, Sascha Willems - * - * SPDX-License-Identifier: MIT - * - */ - #version 450 #extension GL_EXT_mesh_shader : require layout (binding = 0) uniform UBO { - mat4 projection; - mat4 model; - mat4 view; + mat4 modelProjectionView; } ubo; layout (binding = 1) buffer VERTEX { vec4 pos[]; } vertex; + layout (binding = 2) buffer INDEX { uint index[]; } index; -layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; -layout(triangles, max_vertices = 3, max_primitives = 1) out; - -layout(location = 0) out VertexOutput -{ - vec4 color; -} vertexOutput[]; - -const vec4[3] colors = { - vec4(0.0, 1.0, 0.0, 1.0), - vec4(0.0, 0.0, 1.0, 1.0), - vec4(1.0, 0.0, 0.0, 1.0) -}; - +layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; +layout(triangles, max_vertices = 192, max_primitives = 64) out; void main() { - uint iid = gl_LocalInvocationID.x; - SetMeshOutputsEXT(3, 1); - mat4 mvp = ubo.projection * ubo.view * ubo.model; - uint triangleID = gl_LocalInvocationIndex.x * 3; - gl_MeshVerticesEXT[triangleID].gl_Position = mvp * vertex.pos[index.index[triangleID]]; - gl_MeshVerticesEXT[triangleID+1].gl_Position = mvp * vertex.pos[index.index[triangleID+1]]; - gl_MeshVerticesEXT[triangleID+2].gl_Position = mvp * vertex.pos[index.index[triangleID+2]]; - vertexOutput[triangleID].color = colors[triangleID]; - vertexOutput[triangleID+1].color = colors[triangleID+1]; - vertexOutput[triangleID+2].color = colors[triangleID+2]; - gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex.x] = uvec3(index.index[triangleID], index.index[triangleID+1], index.index[triangleID+2]); + SetMeshOutputsEXT(192, 64); + uint triangleID = ((gl_WorkGroupID.x * gl_WorkGroupSize.x) + gl_LocalInvocationIndex.x)*3; + uint localID = gl_LocalInvocationIndex.x*3; + gl_MeshVerticesEXT[localID].gl_Position = ubo.modelProjectionView * vertex.pos[index.index[triangleID]]; + gl_MeshVerticesEXT[localID+1].gl_Position = ubo.modelProjectionView * vertex.pos[index.index[triangleID+1]]; + gl_MeshVerticesEXT[localID+2].gl_Position =ubo.modelProjectionView * vertex.pos[index.index[triangleID+2]]; + gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex.x] = uvec3(localID, localID+1, localID+2); } diff --git a/test2.frag b/test2.frag index f425dd4..c434504 100644 --- a/test2.frag +++ b/test2.frag @@ -1,19 +1,8 @@ -/* Copyright (c) 2021, Sascha Willems - * - * SPDX-License-Identifier: MIT - * - */ - #version 450 - -layout (location = 0) in VertexInput { - vec4 color; -} vertexInput; layout(location = 0) out vec4 outFragColor; - void main() { - outFragColor = vertexInput.color; + outFragColor = vec4(1, 1, 1, 1); } \ No newline at end of file