From c67b9f18e55c12b992cdb54e4535c97386d5a437 Mon Sep 17 00:00:00 2001 From: antopilo Date: Sat, 4 Jan 2025 15:13:04 -0500 Subject: [PATCH] Now renders albedo --- Nuake/src/Rendering/Mesh/Mesh.cpp | 2 +- .../Vulkan/DescriptorAllocatorGrowable.cpp | 155 ++++++++++++++++++ .../Vulkan/DescriptorAllocatorGrowable.h | 47 ++++++ Nuake/src/Rendering/Vulkan/VkResources.h | 4 +- .../Vulkan/VulkanImage/VulkanImage.cpp | 2 +- Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp | 17 ++ Nuake/src/Rendering/Vulkan/VulkanRenderer.h | 3 + .../Rendering/Vulkan/VulkanSceneRenderer.cpp | 102 ++++++++++-- .../Rendering/Vulkan/VulkanSceneRenderer.h | 13 ++ Resources/Images/missing_texture.png | Bin 0 -> 243 bytes Resources/Shaders/Vulkan/triangle.frag | 11 +- Resources/Shaders/Vulkan/triangle.vert | 4 +- 12 files changed, 343 insertions(+), 17 deletions(-) create mode 100644 Nuake/src/Rendering/Vulkan/DescriptorAllocatorGrowable.cpp create mode 100644 Nuake/src/Rendering/Vulkan/DescriptorAllocatorGrowable.h create mode 100644 Resources/Images/missing_texture.png diff --git a/Nuake/src/Rendering/Mesh/Mesh.cpp b/Nuake/src/Rendering/Mesh/Mesh.cpp index daf13249..dbe1d103 100644 --- a/Nuake/src/Rendering/Mesh/Mesh.cpp +++ b/Nuake/src/Rendering/Mesh/Mesh.cpp @@ -203,7 +203,7 @@ namespace Nuake if (v.contains("UV") && v["UV"].contains("x") && v["UV"].contains("y")) { vertex.uv_x = v["UV"]["x"]; - vertex.uv_y = v["UV"]["x"]; + vertex.uv_y = v["UV"]["y"]; } } catch (std::exception& /*e*/) { diff --git a/Nuake/src/Rendering/Vulkan/DescriptorAllocatorGrowable.cpp b/Nuake/src/Rendering/Vulkan/DescriptorAllocatorGrowable.cpp new file mode 100644 index 00000000..817cb934 --- /dev/null +++ b/Nuake/src/Rendering/Vulkan/DescriptorAllocatorGrowable.cpp @@ -0,0 +1,155 @@ +#include "DescriptorAllocatorGrowable.h" +#include "VulkanCheck.h" + +using namespace Nuake; + +VkDescriptorPool DescriptorAllocatorGrowable::GetPool(VkDevice device) +{ + VkDescriptorPool newPool; + if (ReadyPools.size() != 0) { + newPool = ReadyPools.back(); + ReadyPools.pop_back(); + } + else { + //need to create a new pool + newPool = CreatePool(device, SetsPerPool, Ratios); + + SetsPerPool = SetsPerPool * 1.5; + if (SetsPerPool > 4092) { + SetsPerPool = 4092; + } + } + + return newPool; +} + +VkDescriptorPool DescriptorAllocatorGrowable::CreatePool(VkDevice device, uint32_t setCount, std::span poolRatios) +{ + std::vector poolSizes; + for (PoolSizeRatio ratio : poolRatios) { + poolSizes.push_back(VkDescriptorPoolSize{ + .type = ratio.Type, + .descriptorCount = uint32_t(ratio.Ratio * setCount) + }); + } + + VkDescriptorPoolCreateInfo pool_info = {}; + pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + pool_info.flags = 0; + pool_info.maxSets = setCount; + pool_info.poolSizeCount = (uint32_t)poolSizes.size(); + pool_info.pPoolSizes = poolSizes.data(); + + VkDescriptorPool newPool; + vkCreateDescriptorPool(device, &pool_info, nullptr, &newPool); + return newPool; +} + +void DescriptorAllocatorGrowable::Init(VkDevice device, uint32_t maxSets, std::span poolRatios) +{ + Ratios.clear(); + + for (auto r : poolRatios) { + Ratios.push_back(r); + } + + VkDescriptorPool newPool = CreatePool(device, maxSets, poolRatios); + + SetsPerPool = maxSets * 1.5; //grow it next allocation + + ReadyPools.push_back(newPool); +} + +void DescriptorAllocatorGrowable::ClearPools(VkDevice device) +{ + for (auto p : ReadyPools) { + vkResetDescriptorPool(device, p, 0); + } + for (auto p : FullPools) { + vkResetDescriptorPool(device, p, 0); + ReadyPools.push_back(p); + } + FullPools.clear(); +} + +void DescriptorAllocatorGrowable::DestroyPools(VkDevice device) +{ + for (auto p : ReadyPools) { + vkDestroyDescriptorPool(device, p, nullptr); + } + ReadyPools.clear(); + for (auto p : FullPools) { + vkDestroyDescriptorPool(device, p, nullptr); + } + FullPools.clear(); +} + +VkDescriptorSet DescriptorAllocatorGrowable::Allocate(VkDevice device, VkDescriptorSetLayout layout, void* pNext) +{ + //get or create a pool to allocate from + VkDescriptorPool poolToUse = GetPool(device); + + VkDescriptorSetAllocateInfo allocInfo = {}; + allocInfo.pNext = pNext; + allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + allocInfo.descriptorPool = poolToUse; + allocInfo.descriptorSetCount = 1; + allocInfo.pSetLayouts = &layout; + + VkDescriptorSet ds; + VkResult result = vkAllocateDescriptorSets(device, &allocInfo, &ds); + + //allocation failed. Try again + if (result == VK_ERROR_OUT_OF_POOL_MEMORY || result == VK_ERROR_FRAGMENTED_POOL) { + + FullPools.push_back(poolToUse); + + poolToUse = GetPool(device); + allocInfo.descriptorPool = poolToUse; + + VK_CALL(vkAllocateDescriptorSets(device, &allocInfo, &ds)); + } + + ReadyPools.push_back(poolToUse); + return ds; +} + +void Nuake::DescriptorWriter::WriteImage(int binding, VkImageView image, VkSampler sampler, VkImageLayout layout, VkDescriptorType type) +{ + VkDescriptorImageInfo& info = imageInfos.emplace_back(VkDescriptorImageInfo{ + .sampler = sampler, + .imageView = image, + .imageLayout = layout + }); + + VkWriteDescriptorSet write = { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; + + write.dstBinding = binding; + write.dstSet = VK_NULL_HANDLE; //left empty for now until we need to write it + write.descriptorCount = 1; + write.descriptorType = type; + write.pImageInfo = &info; + + writes.push_back(write); +} + +void Nuake::DescriptorWriter::WriteBuffer(int binding, VkBuffer buffer, size_t size, size_t offset, VkDescriptorType type) +{ +} + +void Nuake::DescriptorWriter::Clear() +{ + imageInfos.clear(); + writes.clear(); + bufferInfos.clear(); +} + +void Nuake::DescriptorWriter::UpdateSet(VkDevice device, VkDescriptorSet set) +{ + for (VkWriteDescriptorSet& write : writes) { + write.dstSet = set; + } + + vkUpdateDescriptorSets(device, (uint32_t)writes.size(), writes.data(), 0, nullptr); +} + diff --git a/Nuake/src/Rendering/Vulkan/DescriptorAllocatorGrowable.h b/Nuake/src/Rendering/Vulkan/DescriptorAllocatorGrowable.h new file mode 100644 index 00000000..914efa70 --- /dev/null +++ b/Nuake/src/Rendering/Vulkan/DescriptorAllocatorGrowable.h @@ -0,0 +1,47 @@ +#pragma once + +#include + +#include +#include +#include + +namespace Nuake +{ + class DescriptorAllocatorGrowable + { + public: + struct PoolSizeRatio + { + VkDescriptorType Type; + float Ratio; + }; + + void Init(VkDevice device, uint32_t initialSets, std::span poolRatios); + void ClearPools(VkDevice device); + void DestroyPools(VkDevice device); + + VkDescriptorSet Allocate(VkDevice device, VkDescriptorSetLayout layout, void* pNext = nullptr); + private: + VkDescriptorPool GetPool(VkDevice device); + VkDescriptorPool CreatePool(VkDevice device, uint32_t setCount, std::span poolRatios); + + std::vector Ratios; + std::vector FullPools; + std::vector ReadyPools; + uint32_t SetsPerPool; + }; + + class DescriptorWriter { + std::deque imageInfos; + std::deque bufferInfos; + std::vector writes; + + public: + void WriteImage(int binding, VkImageView image, VkSampler sampler, VkImageLayout layout, VkDescriptorType type); + void WriteBuffer(int binding, VkBuffer buffer, size_t size, size_t offset, VkDescriptorType type); + + void Clear(); + void UpdateSet(VkDevice device, VkDescriptorSet set); + }; +} \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/VkResources.h b/Nuake/src/Rendering/Vulkan/VkResources.h index 77477173..4726abce 100644 --- a/Nuake/src/Rendering/Vulkan/VkResources.h +++ b/Nuake/src/Rendering/Vulkan/VkResources.h @@ -7,7 +7,7 @@ #include "src/Rendering/Vulkan/VulkanAllocatedBuffer.h" #include "src/Rendering/Vulkan/VulkanImage/VulkanImage.h" #include "src/Rendering/Vulkan/VkMesh.h" - +#include "src/Rendering/Textures/TextureManager.h" namespace Nuake { @@ -120,7 +120,7 @@ namespace Nuake } Logger::Log("Mesh with ID does not exist", "vulkan", CRITICAL); - return nullptr; + return TextureManager::Get()->GetTexture2("missing_texture"); } }; } \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/VulkanImage/VulkanImage.cpp b/Nuake/src/Rendering/Vulkan/VulkanImage/VulkanImage.cpp index 17bd6da6..35082161 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanImage/VulkanImage.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanImage/VulkanImage.cpp @@ -120,7 +120,7 @@ VulkanImage::VulkanImage(ImageFormat inFormat, Vector2 inSize, ImageUsage usage) vmaCreateImage(VulkanAllocator::Get().GetAllocator(), &imgCreateInfo, &imgAllocInfo, &Image, &Allocation, nullptr); - VkImageViewCreateInfo imageViewCreateInfo; + VkImageViewCreateInfo imageViewCreateInfo = {}; if (usage == ImageUsage::Depth) { imageViewCreateInfo = VulkanInit::ImageviewCreateInfo(static_cast(inFormat), Image, VK_IMAGE_ASPECT_DEPTH_BIT); diff --git a/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp b/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp index 3f8e5bed..2dfed5d7 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp @@ -361,6 +361,21 @@ void VkRenderer::InitDescriptors() CameraBufferDescriptors = GlobalDescriptorAllocator.Allocate(Device, CameraBufferDescriptorLayout); UpdateDescriptorSets(); + + for (int i = 0; i < FRAME_OVERLAP; i++) + { + // create a descriptor pool + std::vector frame_sizes = + { + { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 3 }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3 }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4 }, + }; + + Frames[i].FrameDescriptors = DescriptorAllocatorGrowable{}; + Frames[i].FrameDescriptors.Init(Device, 1000, frame_sizes); + } } void VkRenderer::UpdateDescriptorSets() @@ -718,6 +733,8 @@ bool VkRenderer::Draw() FrameSkipped = false; + GetCurrentFrame().FrameDescriptors.ClearPools(Device); + //request image from the swapchain VkResult result = vkAcquireNextImageKHR(Device, Swapchain, 1000000000, GetCurrentFrame().SwapchainSemaphore, nullptr, &swapchainImageIndex); diff --git a/Nuake/src/Rendering/Vulkan/VulkanRenderer.h b/Nuake/src/Rendering/Vulkan/VulkanRenderer.h index 112a8be6..541c0e07 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanRenderer.h +++ b/Nuake/src/Rendering/Vulkan/VulkanRenderer.h @@ -17,6 +17,7 @@ #include "vk_mem_alloc.h" #include "VkMesh.h" +#include "DescriptorAllocatorGrowable.h" namespace Nuake { @@ -91,6 +92,8 @@ namespace Nuake VkSemaphore SwapchainSemaphore, RenderSemaphore; VkFence RenderFence; // CPU wait for next frame + DescriptorAllocatorGrowable FrameDescriptors; + DeletionQueue LocalDeletionQueue; // Local when destroying this frame }; diff --git a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp index 202054cb..8fcd085a 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.cpp @@ -10,6 +10,8 @@ #include "src/Scene/Scene.h" #include "src/Scene/Entities/Entity.h" +#include "src/Rendering/Textures/Material.h" + #include #include @@ -30,6 +32,7 @@ void VkSceneRenderer::Init() // Here we will create the pipeline for rendering a scene LoadShaders(); CreateBuffers(); + CreateSamplers(); CreateDescriptors(); CreateBasicPipeline(); @@ -47,14 +50,30 @@ void VkSceneRenderer::BeginScene(RenderContext inContext) auto& cmd = Context.CommandBuffer; auto& scene = Context.CurrentScene; auto& vk = VkRenderer::Get(); + + // Ensure the command buffer is valid + if (cmd == VK_NULL_HANDLE) { + throw std::runtime_error("Invalid command buffer"); + } + + // Ensure the draw image is valid + if (!vk.DrawImage) { + throw std::runtime_error("Draw image is not initialized"); + } VkRenderingAttachmentInfo colorAttachment = VulkanInit::AttachmentInfo(vk.DrawImage->GetImageView(), nullptr, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); VkRenderingAttachmentInfo depthAttachment = VulkanInit::DepthAttachmentInfo(vk.DepthImage->GetImageView(), VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); VkRenderingInfo renderInfo = VulkanInit::RenderingInfo(vk.DrawExtent, &colorAttachment, &depthAttachment); + + // Ensure the pipeline is valid + if (BasicPipeline == VK_NULL_HANDLE) { + throw std::runtime_error("Basic pipeline is not initialized"); + } + vkCmdBeginRendering(cmd, &renderInfo); vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, BasicPipeline); - + std::vector descriptors = { CameraBufferDescriptors, ModelBufferDescriptor }; // Bind camera settings vkCmdBindDescriptorSets( @@ -67,7 +86,7 @@ void VkSceneRenderer::BeginScene(RenderContext inContext) 0, // dynamicOffsetCount nullptr // dynamicOffsets ); - + // Set viewport VkViewport viewport = {}; viewport.x = 0; @@ -76,9 +95,9 @@ void VkSceneRenderer::BeginScene(RenderContext inContext) viewport.height = vk.DrawExtent.height; viewport.minDepth = 0.f; viewport.maxDepth = 1.f; - + vkCmdSetViewport(cmd, 0, 1, &viewport); - + VkRect2D scissor = {}; scissor.offset.x = 0; scissor.offset.y = 0; @@ -126,6 +145,22 @@ void VkSceneRenderer::DrawScene() nullptr // dynamicOffsets ); + // Bind texture descriptor set + Ref material = m->GetMaterial(); + Ref albedo = GPUResources::Get().GetTexture(material->AlbedoImage); + + //bind a texture + VkDescriptorSet imageSet = vk.GetCurrentFrame().FrameDescriptors.Allocate(vk.GetDevice(), ImageDescriptorLayout); + { + DescriptorWriter writer; + writer.WriteImage(0, albedo->GetImageView(), SamplerNearest, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); + writer.UpdateSet(vk.GetDevice(), imageSet); + } + + vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, BasicPipelineLayout, 3, 1, &imageSet, 0, nullptr); + + vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, BasicPipelineLayout, 4, 1, &SamplerDescriptor, 0, nullptr); + ModelPushConstant modelPushConstant{}; modelPushConstant.Index = ModelMatrixMapping[entity.GetID()]; vkCmdPushConstants( @@ -183,13 +218,13 @@ void VkSceneRenderer::CreateBasicPipeline() bufferRange.size = sizeOfThing; bufferRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - VkDescriptorSetLayout layouts[] = { CameraBufferDescriptorLayout, ModelBufferDescriptorLayout, TriangleBufferDescriptorLayout }; + VkDescriptorSetLayout layouts[] = { CameraBufferDescriptorLayout, ModelBufferDescriptorLayout, TriangleBufferDescriptorLayout, ImageDescriptorLayout, SamplerDescriptorLayout }; VkPipelineLayoutCreateInfo pipeline_layout_info = VulkanInit::PipelineLayoutCreateInfo(); pipeline_layout_info.pPushConstantRanges = &bufferRange; pipeline_layout_info.pushConstantRangeCount = 1; pipeline_layout_info.pSetLayouts = layouts; - pipeline_layout_info.setLayoutCount = 3; + pipeline_layout_info.setLayoutCount = 5; VK_CALL(vkCreatePipelineLayout(VkRenderer::Get().GetDevice(), &pipeline_layout_info, nullptr, &BasicPipelineLayout)); //use the triangle layout we created @@ -200,13 +235,29 @@ void VkSceneRenderer::CreateBasicPipeline() pipelineBuilder.SetPolygonMode(VK_POLYGON_MODE_FILL); pipelineBuilder.SetCullMode(VK_CULL_MODE_BACK_BIT, VK_FRONT_FACE_CLOCKWISE); pipelineBuilder.SetMultiSamplingNone(); - pipelineBuilder.EnableBlendingAlphaBlend(); + pipelineBuilder.EnableBlendingAlphaBlend(); pipelineBuilder.SetColorAttachment(static_cast(VkRenderer::Get().DrawImage->GetFormat())); pipelineBuilder.SetDepthFormat(static_cast(VkRenderer::Get().DepthImage->GetFormat())); pipelineBuilder.EnableDepthTest(true, VK_COMPARE_OP_GREATER_OR_EQUAL); + //pipelineBuilder.DisableDepthTest(); BasicPipeline = pipelineBuilder.BuildPipeline(VkRenderer::Get().GetDevice()); } +void VkSceneRenderer::CreateSamplers() +{ + auto device = VkRenderer::Get().GetDevice(); + VkSamplerCreateInfo sampler = { .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; + + sampler.magFilter = VK_FILTER_NEAREST; + sampler.minFilter = VK_FILTER_NEAREST; + + vkCreateSampler(device, &sampler, nullptr, &SamplerNearest); + + sampler.magFilter = VK_FILTER_LINEAR; + sampler.minFilter = VK_FILTER_LINEAR; + vkCreateSampler(device, &sampler, nullptr, &SamplerLinear); +} + void VkSceneRenderer::CreateDescriptors() { auto vk = VkRenderer::Get(); @@ -216,7 +267,7 @@ void VkSceneRenderer::CreateDescriptors() { DescriptorLayoutBuilder builder; builder.AddBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); - CameraBufferDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_ALL); + CameraBufferDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_VERTEX_BIT); } { @@ -227,16 +278,31 @@ void VkSceneRenderer::CreateDescriptors() } { - // Matrices + // Matrices` DescriptorLayoutBuilder builder; builder.AddBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); - ModelBufferDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_ALL); + ModelBufferDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_VERTEX_BIT); + } + + // Textures + { + DescriptorLayoutBuilder builder; + builder.AddBinding(0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE); + ImageDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_FRAGMENT_BIT); + } + + { + DescriptorLayoutBuilder builder; + builder.AddBinding(0, VK_DESCRIPTOR_TYPE_SAMPLER); + SamplerDescriptorLayout = builder.Build(device, VK_SHADER_STAGE_FRAGMENT_BIT); } auto allocator = vk.GetDescriptorAllocator(); TriangleBufferDescriptors = allocator.Allocate(device, TriangleBufferDescriptorLayout); CameraBufferDescriptors = allocator.Allocate(device, CameraBufferDescriptorLayout); ModelBufferDescriptor = allocator.Allocate(device, ModelBufferDescriptorLayout); + SamplerDescriptor = allocator.Allocate(device, SamplerDescriptorLayout); + //SamplerDescriptor = allocator.Allocate(device, SamplerDescriptorLayout); // Update descriptor set for camera VkDescriptorBufferInfo camBufferInfo{}; @@ -253,6 +319,22 @@ void VkSceneRenderer::CreateDescriptors() bufferWriteCam.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; bufferWriteCam.pBufferInfo = &camBufferInfo; vkUpdateDescriptorSets(device, 1, &bufferWriteCam, 0, nullptr); + + // Update Descriptor Set for Texture + VkDescriptorImageInfo textureInfo = {}; + textureInfo.sampler = SamplerNearest; // Your VkSampler object + textureInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + // Update Descriptor Set for Sampler + VkWriteDescriptorSet samplerWrite = {}; + samplerWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + samplerWrite.dstBinding = 0; // Binding for sampler (in shader) + samplerWrite.dstSet = SamplerDescriptor; // The allocated descriptor set for the sampler + samplerWrite.descriptorCount = 1; + samplerWrite.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + samplerWrite.pImageInfo = &textureInfo; // Sampler info (same as texture) + + vkUpdateDescriptorSets(device, 1, &samplerWrite, 0, nullptr); } void VkSceneRenderer::UpdateCameraData(const CameraData& data) diff --git a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.h b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.h index d41eb5c0..2dc7c53e 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.h +++ b/Nuake/src/Rendering/Vulkan/VulkanSceneRenderer.h @@ -51,6 +51,18 @@ namespace Nuake ModelData ModelTransforms; std::map ModelMatrixMapping; + VkSampler SamplerLinear; + VkSampler SamplerNearest; + VkDescriptorSet SamplerDescriptor; + VkDescriptorSetLayout SamplerDescriptorLayout; + + VkDescriptorSet ImageDescriptor; + VkDescriptorSetLayout ImageDescriptorLayout; + + // GBuffer render targets + //Ref GBufferAlbedo; + //Ref GBufferDepthImage; + public: VkSceneRenderer(); ~VkSceneRenderer(); @@ -67,6 +79,7 @@ namespace Nuake void LoadShaders(); void CreateBuffers(); void CreateBasicPipeline(); + void CreateSamplers(); void CreateDescriptors(); void BuildMatrixBuffer(); diff --git a/Resources/Images/missing_texture.png b/Resources/Images/missing_texture.png new file mode 100644 index 0000000000000000000000000000000000000000..95ba2cbabb7a19e029c646742e5241f69a9a1354 GIT binary patch literal 243 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ydu{YLn2z= zPTR=KWXR(>U)j)kmQKMb4Rih^wj);40|mG*7%;bL`Z-=K-N>!+=lAsgDVm#7PtRsr zvwrH#Eq53!=Ib%o%=@lcrzzTyqG@lm`KhvU*DDiS7Xki#{tu>eHVSZn(3S18RCTw% z58IrgSvtSLH7P|$Xzs+NA*{dc_U~Qa@OPfav`@;9cdD}#++}`s`2Pd(76%RxYAByy l{l4>x{H7`W{E?>^?WU_*yqb1vt2@x)44$rjF6*2UngC~`Tao|( literal 0 HcmV?d00001 diff --git a/Resources/Shaders/Vulkan/triangle.frag b/Resources/Shaders/Vulkan/triangle.frag index e2495957..4c639242 100644 --- a/Resources/Shaders/Vulkan/triangle.frag +++ b/Resources/Shaders/Vulkan/triangle.frag @@ -1,9 +1,18 @@ +[[vk::binding(0, 3)]] +Texture2D myTexture : register(t1); // Texture binding at slot t0 + +[[vk::binding(0, 4)]] +SamplerState mySampler : register(s0); // Sampler binding at slot s0 + struct PSInput { + float4 Position : SV_Position; float3 Color : TEXCOORD0; + float2 UV : TEXCOORD1; }; float4 main(PSInput input) : SV_Target { + float3 textureColor = myTexture.Sample(mySampler, input.UV); // Return color with alpha = 1.0f - return float4(input.Color, 1.0f); + return float4(textureColor, 1.0f); } \ No newline at end of file diff --git a/Resources/Shaders/Vulkan/triangle.vert b/Resources/Shaders/Vulkan/triangle.vert index 1da1f020..e54337aa 100644 --- a/Resources/Shaders/Vulkan/triangle.vert +++ b/Resources/Shaders/Vulkan/triangle.vert @@ -52,10 +52,10 @@ VSOutput main(uint vertexIndex : SV_VertexID) // Load vertex data from the buffer Vertex v = vertexBuffer[vertexIndex]; - + // Output the position of each vertex output.Position = mul(camData.proj, mul(camData.view, mul(modelData.model, float4(v.position, 1.0f)))); output.Color = normalize(float3(v.position.xyz)); - + output.UV = float2(v.uv_x, v.uv_y); return output; } \ No newline at end of file