頂点バッファーの作成

テクニカル諏訪子 <suwako@076.moe>、2026-07-21 16:21
コミット 393ba95b351c30796335209c972042858328533b ・親 63cd403 ・ファイルを見る

8個のファイル、+130 -38

@@ -11,6 +11,7 @@
1111 #include <algorithm>
1212 #include <limits>
1313 #include <fstream>
14+#include <array>
1415 #include <cassert>
1516
1617 #include <util/root.hh>
@@ -37,6 +38,10 @@
3738 std::vector<vk::PresentModeKHR> availPresentModes;
3839 GLFWwindow *window;
3940
41+
42+vk::Buffer vertBuf = nullptr;
43+vk::DeviceMemory vertBufMem = nullptr;
44+
4045 #pragma region debugCallback
4146 static VKAPI_ATTR vk::Bool32 VKAPI_CALL debugCallback(
4247 vk::DebugUtilsMessageSeverityFlagBitsEXT severity,
@@ -52,6 +57,18 @@
5257 }
5358 #pragma endregion
5459
60+#pragma region findMemoryType
61+uint32_t findMemoryType(uint32_t typeFilter, vk::MemoryPropertyFlags props) {
62+ vk::PhysicalDeviceMemoryProperties memProps = physicalDevice.getMemoryProperties();
63+
64+ for (uint32_t i = 0; i < memProps.memoryTypeCount; ++i) {
65+ if ((typeFilter & (1 << i)) && (memProps.memoryTypes[i].propertyFlags & props) == props) return i;
66+ }
67+
68+ return 0;
69+}
70+#pragma endregion
71+
5572 #pragma region transitionImgLayout
5673 void transitionImgLayout(uint32_t imgIdx,
5774 vk::ImageLayout oldLayout,
@@ -222,12 +239,13 @@
222239
223240 cmdBuf.beginRendering(renderingInfo);
224241 cmdBuf.bindPipeline(vk::PipelineBindPoint::eGraphics, gfxPipeline);
242+ cmdBuf.bindVertexBuffers(0, vertBuf, {0});
225243 cmdBuf.setViewport(0, vk::Viewport(0.f, 0.f,
226244 static_cast<float>(swapChainExtent.width),
227245 static_cast<float>(swapChainExtent.height),
228246 0.f, 1.f));
229247 cmdBuf.setScissor(0, vk::Rect2D(vk::Offset2D(0, 0), swapChainExtent));
230- cmdBuf.draw(3, 1, 0, 0);
248+ cmdBuf.draw(static_cast<uint32_t>(vertices.size()), 1, 0, 0);
231249 cmdBuf.endRendering();
232250
233251 transitionImgLayout(imgIdx,
@@ -250,9 +268,7 @@
250268
251269 glfwInit();
252270 glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
253- //glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
254271 window = glfwCreateWindow(winWidth, winHeight, winName.c_str(), nullptr, nullptr);
255- //glfwSetWindowUserPointer(window, this);
256272 glfwSetFramebufferSizeCallback(window, framebufferResizeCallback);
257273 #pragma endregion
258274
@@ -474,7 +490,7 @@
474490 vk::DynamicState::eScissor,
475491 };
476492
477- vk::PipelineVertexInputStateCreateInfo vertexInputInfo = {};
493+ vk::PipelineVertexInputStateCreateInfo vertexInputInfo = shader.GetVertexInput();
478494
479495 vk::PipelineInputAssemblyStateCreateInfo inputAss = {};
480496 inputAss.topology = vk::PrimitiveTopology::eTriangleList;
@@ -576,6 +592,25 @@
576592 vk::CommandPool cmdPool = device.createCommandPool(poolInfo);
577593 #pragma endregion
578594
595+#pragma region vertexBuffer
596+ vk::BufferCreateInfo bufInfo = {};
597+ bufInfo.size = sizeof(vertices[0]) * vertices.size();
598+ bufInfo.usage = vk::BufferUsageFlagBits::eVertexBuffer;
599+ bufInfo.sharingMode = vk::SharingMode::eExclusive;
600+ vertBuf = device.createBuffer(bufInfo);
601+
602+ vk::MemoryRequirements memReq = device.getBufferMemoryRequirements(vertBuf);
603+ vk::MemoryAllocateInfo memAllocInfo = {};
604+ memAllocInfo.allocationSize = memReq.size;
605+ memAllocInfo.memoryTypeIndex = findMemoryType(memReq.memoryTypeBits, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
606+ vertBufMem = device.allocateMemory(memAllocInfo);
607+ device.bindBufferMemory(vertBuf, vertBufMem, 0);
608+
609+ void *data = device.mapMemory(vertBufMem, 0, bufInfo.size);
610+ memcpy(data, vertices.data(), bufInfo.size);
611+ device.unmapMemory(vertBufMem);
612+#pragma endregion
613+
579614 #pragma region commandbuffers
580615 vk::CommandBufferAllocateInfo allocInfo = {};
581616 allocInfo.commandPool = cmdPool;
@@ -692,6 +727,8 @@
692727 #pragma region destroy
693728 if (device) device.waitIdle();
694729 if (cmdPool) device.destroyCommandPool(cmdPool);
730+ if (vertBuf) device.destroyBuffer(vertBuf);
731+ if (vertBufMem) device.freeMemory(vertBufMem);
695732 if (gfxPipeline) device.destroyPipeline(gfxPipeline);
696733 if (pipelineLayout) device.destroyPipelineLayout(pipelineLayout);
697734 shader.Finalize();
@@ -1,26 +1,19 @@
1-static float2 positions[3] = float2[](
2- float2( 0.0, -0.5),
3- float2( 0.5, 0.5),
4- float2(-0.5, 0.5),
5-);
1+struct VertexInput {
2+ float2 positions;
3+ float3 colors;
4+};
65
7-static float3 colors[3] = float3[](
8- float3(1.0, 0.0, 0.0),
9- float3(0.0, 1.0, 0.0),
10- float3(0.0, 0.0, 1.0),
11-);
12-
136 struct VertexOutput {
147 float3 color;
158 float4 sv_position: SV_Position;
169 };
1710
1811 [shader("vertex")]
19-VertexOutput vertMain(uint vid: SV_VertexID) {
20- VertexOutput out;
21- out.sv_position = float4(positions[vid], 0.0, 1.0);
22- out.color = colors[vid];
23- return out;
12+VertexOutput vertMain(VertexInput inVert) {
13+ VertexOutput outVert;
14+ outVert.sv_position = float4(inVert.positions, 0.0, 1.0);
15+ outVert.color = inVert.colors;
16+ return outVert;
2417 }
2518
2619 [shader("fragment")]
@@ -2,19 +2,10 @@
22
33 layout(location = 0) out vec3 fragColor;
44
5-vec2 pos[3] = vec2[](
6- vec2(0.0, -0.5),
7- vec2(0.5, 0.5),
8- vec2(-0.5, 0.5)
9-);
5+layout(location = 0) in vec2 pos;
6+layout(location = 1) in vec3 col;
107
11-vec3 col[3] = vec3[](
12- vec3(1.0, 0.0, 0.0),
13- vec3(0.0, 1.0, 0.0),
14- vec3(0.0, 0.0, 1.0)
15-);
16-
178 void main() {
18- gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0);
19- fragColor = col[gl_VertexIndex];
9+ gl_Position = vec4(pos, 0.0, 1.0);
10+ fragColor = col;
2011 }
@@ -28,6 +28,14 @@
2828
2929 m_ShaderStages.emplace_back(vertShaderStageInfo);
3030 m_ShaderStages.emplace_back(fragShaderStageInfo);
31+
32+ m_BindingDescription = Vertex::getBindingDescription();
33+ m_AttributeDescriptions = Vertex::getAttributeDescriptions();
34+
35+ m_VertInput.vertexBindingDescriptionCount = 1;
36+ m_VertInput.pVertexBindingDescriptions = &m_BindingDescription;
37+ m_VertInput.vertexAttributeDescriptionCount = static_cast<uint32_t>(m_AttributeDescriptions.size());
38+ m_VertInput.pVertexAttributeDescriptions = m_AttributeDescriptions.data();
3139 }
3240
3341 void Shaders::Finalize() {
@@ -3,6 +3,7 @@
33 #ifdef USING_GLSL
44 #include <util/root.hh>
55 #include <vector>
6+#include <array>
67
78 class Shaders {
89 public:
@@ -14,11 +15,16 @@
1415
1516 public:
1617 const std::vector<vk::PipelineShaderStageCreateInfo> GetShaderStages() const { return m_ShaderStages; }
18+ const vk::PipelineVertexInputStateCreateInfo &GetVertexInput() const { return m_VertInput; }
1719
1820 private:
1921 vk::Device *m_Device;
20- std::vector<vk::PipelineShaderStageCreateInfo> m_ShaderStages;
21- vk::ShaderModule m_VertShaderModule;
22- vk::ShaderModule m_FragShaderModule;
22+ std::vector<vk::PipelineShaderStageCreateInfo> m_ShaderStages{};
23+ vk::ShaderModule m_VertShaderModule = {};
24+ vk::ShaderModule m_FragShaderModule = {};
25+ vk::PipelineVertexInputStateCreateInfo m_VertInput = {};
26+
27+ vk::VertexInputBindingDescription m_BindingDescription{};
28+ std::array<vk::VertexInputAttributeDescription, 2> m_AttributeDescriptions{};
2329 }; // Shaders
2430 #endif // USING_GLSL
@@ -22,6 +22,14 @@
2222
2323 m_ShaderStages.emplace_back(vertShaderStageInfo);
2424 m_ShaderStages.emplace_back(fragShaderStageInfo);
25+
26+ m_BindingDescription = Vertex::getBindingDescription();
27+ m_AttributeDescriptions = Vertex::getAttributeDescriptions();
28+
29+ m_VertInput.vertexBindingDescriptionCount = 1;
30+ m_VertInput.pVertexBindingDescriptions = &m_BindingDescription;
31+ m_VertInput.vertexAttributeDescriptionCount = static_cast<uint32_t>(m_AttributeDescriptions.size());
32+ m_VertInput.pVertexAttributeDescriptions = m_AttributeDescriptions.data();
2533 }
2634
2735 void Shaders::Finalize() {
@@ -3,6 +3,7 @@
33 #ifdef USING_SLANG
44 #include <util/root.hh>
55 #include <vector>
6+#include <array>
67
78 class Shaders {
89 public:
@@ -14,10 +15,15 @@
1415
1516 public:
1617 const std::vector<vk::PipelineShaderStageCreateInfo> GetShaderStages() const { return m_ShaderStages; }
18+ const vk::PipelineVertexInputStateCreateInfo &GetVertexInput() const { return m_VertInput; }
1719
1820 private:
1921 vk::Device *m_Device;
20- std::vector<vk::PipelineShaderStageCreateInfo> m_ShaderStages;
21- vk::ShaderModule m_ShaderModule;
22+ std::vector<vk::PipelineShaderStageCreateInfo> m_ShaderStages{};
23+ vk::ShaderModule m_ShaderModule = {};
24+ vk::PipelineVertexInputStateCreateInfo m_VertInput = {};
25+
26+ vk::VertexInputBindingDescription m_BindingDescription{};
27+ std::array<vk::VertexInputAttributeDescription, 2> m_AttributeDescriptions{};
2228 }; // Shaders
2329 #endif // USING_SLANG
@@ -22,3 +22,46 @@
2222 #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
2323 #include <vulkan/vulkan.hpp>
2424 #pragma endregion
25+
26+#include <glm/glm.hpp>
27+
28+struct Vertex {
29+ glm::vec2 pos;
30+ glm::vec3 col;
31+
32+ static vk::VertexInputBindingDescription getBindingDescription() {
33+ vk::VertexInputBindingDescription desc;
34+ desc.binding = 0;
35+ desc.stride = sizeof(Vertex);
36+ desc.inputRate = vk::VertexInputRate::eVertex;
37+ return desc;
38+ }
39+
40+ static std::array<vk::VertexInputAttributeDescription, 2> getAttributeDescriptions() {
41+ std::array<vk::VertexInputAttributeDescription, 2> descs;
42+ {
43+ vk::VertexInputAttributeDescription desc;
44+ desc.location = 0;
45+ desc.binding = 0;
46+ desc.format = vk::Format::eR32G32Sfloat;
47+ desc.offset = offsetof(Vertex, pos);
48+ descs[0] = desc;
49+ }
50+ {
51+ vk::VertexInputAttributeDescription desc;
52+ desc.location = 1;
53+ desc.binding = 0;
54+ desc.format = vk::Format::eR32G32B32Sfloat;
55+ desc.offset = offsetof(Vertex, col);
56+ descs[1] = desc;
57+ }
58+
59+ return descs;
60+ }
61+};
62+
63+inline const std::vector<Vertex> vertices = {
64+ {{ 0.0f, -0.5f }, { 1.f, 0.f, 0.f }},
65+ {{ 0.5f, 0.5f }, { 0.f, 1.f, 0.f }},
66+ {{ -0.5f, 0.5f }, { 0.f, 0.f, 1.f }},
67+};