ユニフォームバッファー(3D有効化)

テクニカル諏訪子 <suwako@076.moe>、2026-07-22 13:10
コミット 7f9eef1283348c8dde0c00b533e62748e9c5d044 ・親 4848c56 ・ファイルを見る

4個のファイル、+123 -7

@@ -13,6 +13,7 @@
1313 #include <limits>
1414 #include <fstream>
1515 #include <array>
16+#include <chrono>
1617 #include <cassert>
1718
1819 #include <util/root.hh>
@@ -28,6 +29,7 @@
2829 vk::CommandBuffer cmdBuf;
2930 vk::CommandBufferBeginInfo beginInfo;
3031 vk::Queue gfxQueue;
32+vk::PipelineLayout pipelineLayout;
3133 std::vector<vk::ImageView> swapChainImageViews;
3234 vk::Extent2D swapChainExtent;
3335 vk::Pipeline gfxPipeline;
@@ -41,11 +43,19 @@
4143 std::vector<vk::PresentModeKHR> availPresentModes;
4244 GLFWwindow *window;
4345
46+vk::DescriptorSetLayout descriptorSetLayout = nullptr;
47+vk::DescriptorPool descriptorPool = nullptr;
48+std::vector<vk::DescriptorSet> descriptorSets;
49+
4450 vk::Buffer vertBuf = nullptr;
4551 vk::DeviceMemory vertBufMem = nullptr;
4652 vk::Buffer idxBuf = nullptr;
4753 vk::DeviceMemory idxBufMem = nullptr;
4854
55+std::vector<vk::Buffer> uniformBufs;
56+std::vector<vk::DeviceMemory> uniformBufsMem;
57+std::vector<void *> uniformBufsMapped;
58+
4959 #pragma region debugCallback
5060 static VKAPI_ATTR vk::Bool32 VKAPI_CALL debugCallback(
5161 vk::DebugUtilsMessageSeverityFlagBitsEXT severity,
@@ -257,6 +267,7 @@
257267 cmdBuf.bindPipeline(vk::PipelineBindPoint::eGraphics, gfxPipeline);
258268 cmdBuf.bindVertexBuffers(0, vertBuf, {0});
259269 cmdBuf.bindIndexBuffer(idxBuf, 0, vk::IndexType::eUint16);
270+ cmdBuf.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, descriptorSets[frameIdx], nullptr);
260271 cmdBuf.setViewport(0, vk::Viewport(0.f, 0.f,
261272 static_cast<float>(swapChainExtent.width),
262273 static_cast<float>(swapChainExtent.height),
@@ -535,6 +546,20 @@
535546 createImageViews();
536547 #pragma endregion
537548
549+#pragma region descriptorSetLayout
550+ vk::DescriptorSetLayoutBinding uboLayoutBinding = {};
551+ uboLayoutBinding.binding = 0;
552+ uboLayoutBinding.descriptorType = vk::DescriptorType::eUniformBuffer;
553+ uboLayoutBinding.descriptorCount = 1;
554+ uboLayoutBinding.stageFlags = vk::ShaderStageFlagBits::eVertex;
555+
556+ vk::DescriptorSetLayoutCreateInfo layoutInfo = {};
557+ layoutInfo.bindingCount = 1;
558+ layoutInfo.pBindings = &uboLayoutBinding;
559+
560+ descriptorSetLayout = device.createDescriptorSetLayout(layoutInfo);
561+#pragma endregion
562+
538563 #pragma region gfxPipeline
539564 Shaders shader(&device);
540565 std::vector<vk::PipelineShaderStageCreateInfo> shaderStages = shader.GetShaderStages();
@@ -578,7 +603,7 @@
578603 rasterizer.rasterizerDiscardEnable = vk::False;
579604 rasterizer.polygonMode = vk::PolygonMode::eFill;
580605 rasterizer.cullMode = vk::CullModeFlagBits::eBack;
581- rasterizer.frontFace = vk::FrontFace::eClockwise;
606+ rasterizer.frontFace = vk::FrontFace::eCounterClockwise;
582607 rasterizer.depthBiasEnable = vk::False;
583608 rasterizer.lineWidth = 1.f;
584609
@@ -606,10 +631,11 @@
606631 colorBlending.pAttachments = &colorBlendAttachment;
607632
608633 vk::PipelineLayoutCreateInfo pipelineLayoutInfo = {};
609- pipelineLayoutInfo.setLayoutCount = 0;
634+ pipelineLayoutInfo.setLayoutCount = 1;
635+ pipelineLayoutInfo.pSetLayouts = &descriptorSetLayout;
610636 pipelineLayoutInfo.pushConstantRangeCount = 0;
611637
612- vk::PipelineLayout pipelineLayout = device.createPipelineLayout(pipelineLayoutInfo);
638+ pipelineLayout = device.createPipelineLayout(pipelineLayoutInfo);
613639 #pragma endregion
614640
615641 #pragma region pipelineRendering
@@ -682,6 +708,58 @@
682708 }
683709 #pragma endregion
684710
711+#pragma region uniformBuffers
712+ for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
713+ vk::DeviceSize bufSize = sizeof(UniformBufferObject);
714+ vk::MemoryPropertyFlags flags = vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent;
715+ auto [buf, bufMem] = createBuffer(bufSize, vk::BufferUsageFlagBits::eUniformBuffer, flags);
716+ uniformBufs.emplace_back(std::move(buf));
717+ uniformBufsMem.emplace_back(std::move(bufMem));
718+ uniformBufsMapped.emplace_back(device.mapMemory(uniformBufsMem.back(), 0, bufSize));
719+ }
720+#pragma endregion
721+
722+#pragma region descriptorPool
723+ vk::DescriptorPoolSize descPoolSize = {};
724+ descPoolSize.type = vk::DescriptorType::eUniformBuffer;
725+ descPoolSize.descriptorCount = MAX_FRAMES_IN_FLIGHT;
726+
727+ vk::DescriptorPoolCreateInfo descPoolInfo = {};
728+ descPoolInfo.flags = vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet;
729+ descPoolInfo.maxSets = MAX_FRAMES_IN_FLIGHT;
730+ descPoolInfo.poolSizeCount = 1;
731+ descPoolInfo.pPoolSizes = &descPoolSize;
732+
733+ descriptorPool = device.createDescriptorPool(descPoolInfo);
734+#pragma endregion
735+
736+#pragma region descriptorSets
737+ std::vector<vk::DescriptorSetLayout> layouts{MAX_FRAMES_IN_FLIGHT, descriptorSetLayout};
738+ vk::DescriptorSetAllocateInfo descAllocInfo = {};
739+ descAllocInfo.descriptorPool = descriptorPool;
740+ descAllocInfo.descriptorSetCount = static_cast<uint32_t>(layouts.size());
741+ descAllocInfo.pSetLayouts = layouts.data();
742+
743+ descriptorSets = device.allocateDescriptorSets(descAllocInfo);
744+
745+ for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
746+ vk::DescriptorBufferInfo descBufInfo = {};
747+ descBufInfo.buffer = uniformBufs[i];
748+ descBufInfo.offset = 0;
749+ descBufInfo.range = sizeof(UniformBufferObject);
750+
751+ vk::WriteDescriptorSet descWrite = {};
752+ descWrite.dstSet = descriptorSets[i];
753+ descWrite.dstBinding = 0;
754+ descWrite.dstArrayElement = 0;
755+ descWrite.descriptorCount = 1;
756+ descWrite.descriptorType = vk::DescriptorType::eUniformBuffer;
757+ descWrite.pBufferInfo = &descBufInfo;
758+
759+ device.updateDescriptorSets(descWrite, {});
760+ }
761+#pragma endregion
762+
685763 #pragma region commandbuffers
686764 vk::CommandBufferAllocateInfo allocInfo = {};
687765 allocInfo.commandPool = cmdPool;
@@ -750,6 +828,19 @@
750828
751829 vk::PipelineStageFlags waitStage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
752830
831+#pragma region updateUniformBuffer
832+ static auto startTime = std::chrono::high_resolution_clock::now();
833+ auto curTime = std::chrono::high_resolution_clock::now();
834+ float time = std::chrono::duration<float, std::chrono::seconds::period>(curTime - startTime).count();
835+
836+ UniformBufferObject ubo = {};
837+ ubo.model = rotate(glm::mat4(1.f), time * glm::radians(90.f), glm::vec3(0.f, 0.f, 1.f));
838+ ubo.view = lookAt(glm::vec3(2.f, 2.f, 2.f), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f));
839+ ubo.proj = glm::perspective(glm::radians(45.f), static_cast<float>(swapChainExtent.width) / static_cast<float>(swapChainExtent.height), .1f, 10.f);
840+ ubo.proj[1][1] *= -1; // -Y軸
841+ memcpy(uniformBufsMapped[frameIdx], &ubo, sizeof(ubo));
842+#pragma endregion
843+
753844 vk::SubmitInfo submitInfo = {};
754845 submitInfo.waitSemaphoreCount = 1;
755846 submitInfo.pWaitSemaphores = &presentCompleteSemaphores[frameIdx];
@@ -789,9 +880,13 @@
789880 if (idxBufMem) device.freeMemory(idxBufMem);
790881 if (vertBuf) device.destroyBuffer(vertBuf);
791882 if (vertBufMem) device.freeMemory(vertBufMem);
883+ for (const auto &it : uniformBufs) device.destroyBuffer(it);
884+ for (const auto &it : uniformBufsMem) device.freeMemory(it);
792885 if (gfxPipeline) device.destroyPipeline(gfxPipeline);
793886 if (pipelineLayout) device.destroyPipelineLayout(pipelineLayout);
794887 shader.Finalize();
888+ if (descriptorSetLayout) device.destroyDescriptorSetLayout(descriptorSetLayout);
889+ if (descriptorPool) device.destroyDescriptorPool(descriptorPool);
795890 cleanupSwapChain();
796891 for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) device.destroySemaphore(presentCompleteSemaphores[i]);
797892 for (size_t i = 0; i < swapChainImages.size(); ++i) device.destroySemaphore(renderFinishedSemaphores[i]);
@@ -3,15 +3,22 @@
33 float3 colors;
44 };
55
6+struct UniformBuffer {
7+ float4x4 model;
8+ float4x4 view;
9+ float4x4 proj;
10+};
11+ConstantBuffer<UniformBuffer> ubo;
12+
613 struct VertexOutput {
14+ float4 pos: SV_Position;
715 float3 color;
8- float4 sv_position: SV_Position;
916 };
1017
1118 [shader("vertex")]
1219 VertexOutput vertMain(VertexInput inVert) {
1320 VertexOutput outVert;
14- outVert.sv_position = float4(inVert.positions, 0.0, 1.0);
21+ outVert.pos = mul(ubo.proj, mul(ubo.view, mul(ubo.model, float4(inVert.positions, 0.0, 1.0))));
1522 outVert.color = inVert.colors;
1623 return outVert;
1724 }
@@ -1,11 +1,17 @@
11 #version 450
22
3-layout(location = 0) out vec3 fragColor;
3+layout(binding = 0) uniform UniformBufferObject {
4+ mat4 model;
5+ mat4 view;
6+ mat4 proj;
7+} ubo;
48
59 layout(location = 0) in vec2 pos;
610 layout(location = 1) in vec3 col;
711
12+layout(location = 0) out vec3 fragColor;
13+
814 void main() {
9- gl_Position = vec4(pos, 0.0, 1.0);
15+ gl_Position = ubo.proj * ubo.view * ubo.model * vec4(pos, 0.0, 1.0);
1016 fragColor = col;
1117 }
@@ -23,7 +23,9 @@
2323 #include <vulkan/vulkan.hpp>
2424 #pragma endregion
2525
26+#define GLM_FORCE_RADIANS
2627 #include <glm/glm.hpp>
28+#include <glm/gtc/matrix_transform.hpp>
2729
2830 struct Vertex {
2931 glm::vec2 pos;
@@ -70,4 +72,10 @@
7072 inline const std::vector<uint16_t> indices = {
7173 0, 1, 2,
7274 2, 3, 0,
75+};
76+
77+struct UniformBufferObject {
78+ glm::mat4 model;
79+ glm::mat4 view;
80+ glm::mat4 proj;
7381 };