diff --git a/Crafter.Graphics-DescriptorSet.cppm b/Crafter.Graphics-DescriptorSet.cppm new file mode 100644 index 0000000..1eb8846 --- /dev/null +++ b/Crafter.Graphics-DescriptorSet.cppm @@ -0,0 +1,166 @@ +/* +Crafter®.Graphics +Copyright (C) 2025 Catcrafts® +Catcrafts.net + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3.0 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +module; + +#include +#include +#include +#include +#include +#include "VulkanInitializers.hpp" + +export module Crafter.Graphics:DescriptorSet; +import Crafter.Event; +import :VulkanDevice; +import :VulkanShader; +import :WindowWaylandVulkan; +import :VulkanPipeline; + +namespace Crafter { + export struct DescriptorEntry { + VkDescriptorType type; + bool occured = true; + }; + + export template + class DescriptorSet { + public: + VkDescriptorSet set[2]; + inline static Event onDescriptorRefresh; + inline static std::vector sets; + inline static VkDescriptorPool descriptorPool = VK_NULL_HANDLE; + + + 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}}; + + for(const DescriptorBinding& binding : MeshShader::descriptors) { + for(DescriptorEntry& type : types) { + if(type.type == binding.type) { + type.occured = true; + } + } + } + + for(const DescriptorBinding& binding : FragmentShader::descriptors) { + for(DescriptorEntry& type : types) { + if(type.type == binding.type) { + type.occured = true; + } + } + } + + std::uint32_t size = 0; + for(DescriptorEntry& type : types) { + if(type.occured) { + size++; + } + } + + return size; + } + constexpr static std::uint32_t uniqueDescriptorCount = GetUniqueDiscriptorCount(); + + consteval static std::array GetPoolSizes() { + std::array types = {}; + for(std::uint32_t i = 0; i < uniqueDescriptorCount; i++){ + types[i].descriptorCount = 12345; + } + + for(const DescriptorBinding& binding : MeshShader::descriptors) { + bool found = false; + for(VkDescriptorPoolSize& type : types) { + if(type.type == binding.type && type.descriptorCount != 12345) { + type.descriptorCount += 1; + found = true; + } + } + if(!found) { + for(std::uint32_t i = 0; i < uniqueDescriptorCount; i++){ + if(types[i].descriptorCount == 12345) { + types[i].type = binding.type; + types[i].descriptorCount = 1; + break; + } + } + } + } + + for(const DescriptorBinding& binding : FragmentShader::descriptors) { + bool found = false; + for(VkDescriptorPoolSize& type : types) { + if(type.type == binding.type) { + type.descriptorCount += 1; + found = true; + } + } + if(!found) { + for(std::uint32_t i = 0; i < uniqueDescriptorCount; i++){ + if(types[i].descriptorCount == 12345) { + types[i].type = binding.type; + types[i].descriptorCount = 1; + break; + } + } + } + } + + return types; + } + + DescriptorSet() { + sets.push_back(this); + + if(descriptorPool != VK_NULL_HANDLE) { + vkDestroyDescriptorPool(VulkanDevice::device, descriptorPool, nullptr); + } + + std::array poolSizes = GetPoolSizes(); + for(VkDescriptorPoolSize& size : poolSizes) { + size.descriptorCount *= sets.size(); + } + VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(uniqueDescriptorCount, poolSizes.data(), sets.size()*2); + VulkanDevice::CHECK_VK_RESULT(vkCreateDescriptorPool(VulkanDevice::device, &descriptorPoolInfo, nullptr, &descriptorPool)); + + for(DescriptorSet* set : sets) { + VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &VulkanPipeline::descriptorSetLayout[0], 2); + VulkanDevice::CHECK_VK_RESULT(vkAllocateDescriptorSets(VulkanDevice::device, &allocInfo, set->set)); + } + onDescriptorRefresh.Invoke(); + } + + ~DescriptorSet() { + sets.erase(find(sets.begin(), sets.end(), this)); + } + + // void Write(VkWriteDescriptorSet* descriptors, std::uint32_t count) { + // vkUpdateDescriptorSets(VulkanDevice::device, count, descriptors, 0, nullptr); + // } + // void Write(std::uint32_t stage, VkDescriptorType type, std::uint32_t binding, VkDescriptorBufferInfo* buffer) { + // VkWriteDescriptorSet write = vks::initializers::writeDescriptorSet(set[stage], type, binding, buffer); + // vkUpdateDescriptorSets(VulkanDevice::device, 1, &write, 0, nullptr); + // } + // void Write(std::uint32_t stage, VkDescriptorType type, std::uint32_t binding, VkDescriptorImageInfo* buffer) { + // VkWriteDescriptorSet write = vks::initializers::writeDescriptorSet(set[stage], type, binding, buffer); + // vkUpdateDescriptorSets(VulkanDevice::device, 1, &write, 0, nullptr); + // } + }; +} \ No newline at end of file diff --git a/Crafter.Graphics-MeshShader.cppm b/Crafter.Graphics-MeshShader.cppm index 6c0fa84..cb9d4ca 100644 --- a/Crafter.Graphics-MeshShader.cppm +++ b/Crafter.Graphics-MeshShader.cppm @@ -25,12 +25,14 @@ module; #include #include #include +#include "VulkanInitializers.hpp" export module Crafter.Graphics:MeshShader; import Crafter.Component; import :Mesh; import :Camera; import :VulkanPipeline; +import :DescriptorSet; import Crafter.Math; namespace Crafter { @@ -50,10 +52,13 @@ namespace Crafter { ) { transform = MatrixRowMajor::Identity(); } - void WriteDescriptors(DescriptorSet& set) { - set.Write(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &mvp.descriptor); - set.Write(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, &mesh.component->verticies.descriptor); - set.Write(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2, &mesh.component->indicies.descriptor); + void WriteDescriptors(VkDescriptorSet* set) { + VkWriteDescriptorSet write[3] = { + vks::initializers::writeDescriptorSet(set[0], VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, &mvp.descriptor), + vks::initializers::writeDescriptorSet(set[0], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, &mesh.component->verticies.descriptor), + vks::initializers::writeDescriptorSet(set[0], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2, &mesh.component->indicies.descriptor) + }; + vkUpdateDescriptorSets(VulkanDevice::device, 3, &write[0], 0, nullptr); } void Update() { *mvp.value = camera.component->projectionView*transform; diff --git a/Crafter.Graphics-TextureShader.cppm b/Crafter.Graphics-TextureShader.cppm index 2fd933f..2f00b8b 100644 --- a/Crafter.Graphics-TextureShader.cppm +++ b/Crafter.Graphics-TextureShader.cppm @@ -24,11 +24,13 @@ module; #include #include #include +#include "VulkanInitializers.hpp" export module Crafter.Graphics:TextureShader; import Crafter.Component; import :VulkanTexture; import :VulkanPipeline; +import :DescriptorSet; namespace Crafter { export template @@ -61,8 +63,9 @@ namespace Crafter { imageInfo.imageView = texture->imageView; imageInfo.sampler = textureSampler; } - void WriteDescriptors(DescriptorSet& set) { - set.Write(1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0, &imageInfo); + void WriteDescriptors(VkDescriptorSet* set) { + VkWriteDescriptorSet write = vks::initializers::writeDescriptorSet(set[1], VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0, &imageInfo); + vkUpdateDescriptorSets(VulkanDevice::device, 1, &write, 0, nullptr); } }; } diff --git a/Crafter.Graphics-VulkanPipeline.cppm b/Crafter.Graphics-VulkanPipeline.cppm index dea8b66..d4058d3 100644 --- a/Crafter.Graphics-VulkanPipeline.cppm +++ b/Crafter.Graphics-VulkanPipeline.cppm @@ -33,105 +33,9 @@ import :VulkanShader; import :WindowWaylandVulkan; namespace Crafter { - struct DescriptorEntry { - VkDescriptorType type; - bool occured = true; - }; - - export struct DescriptorSet { - VkDescriptorSet set[2]; - void Write(VkWriteDescriptorSet* descriptors, std::uint32_t count) { - vkUpdateDescriptorSets(VulkanDevice::device, count, descriptors, 0, nullptr); - } - void Write(std::uint32_t stage, VkDescriptorType type, std::uint32_t binding, VkDescriptorBufferInfo* buffer) { - VkWriteDescriptorSet write = vks::initializers::writeDescriptorSet(set[stage], type, binding, buffer); - vkUpdateDescriptorSets(VulkanDevice::device, 1, &write, 0, nullptr); - } - void Write(std::uint32_t stage, VkDescriptorType type, std::uint32_t binding, VkDescriptorImageInfo* buffer) { - VkWriteDescriptorSet write = vks::initializers::writeDescriptorSet(set[stage], type, binding, buffer); - vkUpdateDescriptorSets(VulkanDevice::device, 1, &write, 0, nullptr); - } - }; - export template class VulkanPipeline { private: - 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}}; - - for(const DescriptorBinding& binding : MeshShader::descriptors) { - for(DescriptorEntry& type : types) { - if(type.type == binding.type) { - type.occured = true; - } - } - } - - for(const DescriptorBinding& binding : FragmentShader::descriptors) { - for(DescriptorEntry& type : types) { - if(type.type == binding.type) { - type.occured = true; - } - } - } - - std::uint32_t size = 0; - for(DescriptorEntry& type : types) { - if(type.occured) { - size++; - } - } - - return size; - } - constexpr static std::uint32_t uniqueDescriptorCount = GetUniqueDiscriptorCount(); - consteval static std::array GetPoolSizes() { - std::array types = {}; - for(std::uint32_t i = 0; i < uniqueDescriptorCount; i++){ - types[i].descriptorCount = 12345; - } - - for(const DescriptorBinding& binding : MeshShader::descriptors) { - bool found = false; - for(VkDescriptorPoolSize& type : types) { - if(type.type == binding.type && type.descriptorCount != 12345) { - type.descriptorCount++; - found = true; - } - } - if(!found) { - for(std::uint32_t i = 0; i < uniqueDescriptorCount; i++){ - if(types[i].descriptorCount == 12345) { - types[i].type = binding.type; - types[i].descriptorCount = 1; - break; - } - } - } - } - - for(const DescriptorBinding& binding : FragmentShader::descriptors) { - bool found = false; - for(VkDescriptorPoolSize& type : types) { - if(type.type == binding.type) { - type.descriptorCount++; - found = true; - } - } - if(!found) { - for(std::uint32_t i = 0; i < uniqueDescriptorCount; i++){ - if(types[i].descriptorCount == 12345) { - types[i].type = binding.type; - types[i].descriptorCount = 1; - break; - } - } - } - } - - return types; - } - template consteval static std::array GetDescriptorSet() { std::array set; @@ -145,15 +49,9 @@ namespace Crafter { public: inline static VkPipeline pipeline; inline static VkPipelineLayout pipelineLayout; - inline static VkDescriptorPool descriptorPool = VK_NULL_HANDLE; inline static VkDescriptorSetLayout descriptorSetLayout[2]; static void CreatePipeline() { - // Pool - std::array poolSizes = GetPoolSizes(); - VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(uniqueDescriptorCount, poolSizes.data(), 2); - 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); @@ -223,10 +121,5 @@ namespace Crafter { VulkanDevice::CHECK_VK_RESULT(vkCreateGraphicsPipelines(VulkanDevice::device, VK_NULL_HANDLE, 1, &pipelineCI, nullptr, &pipeline)); } - - static void GetDescriptorSet(DescriptorSet& set) { - VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayout[0], 2); - VulkanDevice::CHECK_VK_RESULT(vkAllocateDescriptorSets(VulkanDevice::device, &allocInfo, set.set)); - } }; } \ No newline at end of file diff --git a/Crafter.Graphics.cppm b/Crafter.Graphics.cppm index d63a66e..e7341a1 100644 --- a/Crafter.Graphics.cppm +++ b/Crafter.Graphics.cppm @@ -34,4 +34,5 @@ export import :VulkanBuffer; export import :Mesh; export import :MeshShader; export import :VulkanTexture; -export import :TextureShader; \ No newline at end of file +export import :TextureShader; +export import :DescriptorSet; \ No newline at end of file diff --git a/FragmentShaderTexture.glsl b/FragmentShaderTexture.glsl index 89b86cb..8f53446 100644 --- a/FragmentShaderTexture.glsl +++ b/FragmentShaderTexture.glsl @@ -27,4 +27,52 @@ layout(set = 1, binding = 0) uniform sampler2D texSampler; void main() { outColor = texture(texSampler, fragUV); -} \ No newline at end of file +} + +/* +float getFilledAlpha(vec2 uv, vec2 center, float radius, float fillAmount) { + vec2 dir = uv - center; + float dist = length(dir); + + // If outside the circle, return 0 + if (dist > radius) + return 0.0; + + // Normalize direction vector and compute angle + float angle = atan(dir.y, dir.x); // atan returns from -PI to PI + if (angle < 0.0) angle += 2.0 * 3.14159265359; // Convert to 0 to 2PI + + float filledAngle = fillAmount * 2.0 * 3.14159265359; + + // If the point is within the filled angle, return 1 + if (angle <= filledAngle) + return 1.0; + + return 0.0; +} +*/ + +/* +float getFilledAlphaAA(vec2 uv, vec2 center, float radius, float fillAmount, float edgeSoftness) { + vec2 dir = uv - center; + float dist = length(dir); + + // If completely outside the circle, return 0 + if (dist > radius + edgeSoftness) + return 0.0; + + // Normalize direction vector and compute angle + float angle = atan(dir.y, dir.x); // -PI to PI + if (angle < 0.0) angle += 2.0 * 3.14159265359; // Convert to 0 to 2PI + + float filledAngle = fillAmount * 2.0 * 3.14159265359; + + // Calculate smooth edge for radius + float radiusAlpha = 1.0 - smoothstep(radius, radius + edgeSoftness, dist); + + // Calculate smooth edge for angle + float angleAlpha = smoothstep(filledAngle - 0.02, filledAngle + 0.02, angle); // 0.02 rad ~ edge softness + + return radiusAlpha * angleAlpha; +} +*/ \ No newline at end of file diff --git a/main.cpp b/main.cpp index 9f1267f..dd6d0c2 100644 --- a/main.cpp +++ b/main.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include #include #include +#include "VulkanInitializers.hpp" import Crafter.Graphics; import Crafter.Asset; import Crafter.Event; @@ -45,29 +46,39 @@ int main() { Camera camera(1.57079633, 16 / 9, 0.01, 512); camera.Update(); + VkCommandBuffer cmd = window.StartInit(); Mesh* mesh = Mesh::FromAssetUV(asset.entries[0].data.data()); - DescriptorSet descriptors; - Pipeline::GetDescriptorSet(descriptors); - MeshShader meshShader(mesh, &camera); - meshShader.WriteDescriptors(descriptors); - meshShader.Update(); - Asset asset2; asset2.LoadFull("texture.cras"); - - VkCommandBuffer cmd = window.StartInit(); VulkanTexture* txt = VulkanTexture::FromAsset(asset2.entries[0].data.data(), cmd); - TextureShader texShader(txt); - texShader.WriteDescriptors(descriptors); + DescriptorSet descriptors; + EventListener bruhlistener(&descriptors.onDescriptorRefresh, [&meshShader, &texShader, &camera, &descriptors](){ + meshShader.WriteDescriptors(&descriptors.set[0]); + texShader.WriteDescriptors(&descriptors.set[0]); + }); + meshShader.WriteDescriptors(&descriptors.set[0]); + texShader.WriteDescriptors(&descriptors.set[0]); + MeshShader meshShader2(mesh, &camera); + TextureShader texShader2(txt); + DescriptorSet descriptors2; + meshShader2.WriteDescriptors(&descriptors2.set[0]); + texShader2.WriteDescriptors(&descriptors2.set[0]); + + meshShader.Update(); + meshShader2.Update(); window.FinishInit(); - EventListener listener(&window.onDraw, [&descriptors, &meshShader](VkCommandBuffer cmd){ + EventListener listener(&window.onDraw, [&descriptors, &meshShader, &descriptors2, &meshShader2](VkCommandBuffer cmd){ vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipelineLayout, 0, 2, &descriptors.set[0], 0, NULL); vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipeline); VulkanDevice::vkCmdDrawMeshTasksEXTProc(cmd, meshShader.threadCount, 1, 1); + + vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipelineLayout, 0, 2, &descriptors2.set[0], 0, NULL); + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, Pipeline::pipeline); + VulkanDevice::vkCmdDrawMeshTasksEXTProc(cmd, meshShader2.threadCount, 1, 1); }); window.Start(); diff --git a/project.json b/project.json index 472686b..f30982e 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-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-Camera", "Crafter.Graphics-VulkanBuffer", "Crafter.Graphics-Mesh", "Crafter.Graphics-MeshShader", "Crafter.Graphics-VulkanTexture", "Crafter.Graphics-TextureShader"], + "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-Camera", "Crafter.Graphics-VulkanBuffer", "Crafter.Graphics-Mesh", "Crafter.Graphics-MeshShader", "Crafter.Graphics-VulkanTexture", "Crafter.Graphics-TextureShader", "Crafter.Graphics-DescriptorSet"], "build_dir": "build", "output_dir": "bin", "type":"library",