頂点バッファーの作成
テクニカル諏訪子 <suwako@076.moe>、2026-07-21 16:21
コミット 393ba95b351c30796335209c972042858328533b
・親 63cd403
・ファイルを見る
8個のファイル、+130 -38
| @@ -11,6 +11,7 @@ | ||
| 11 | 11 | #include <algorithm> |
| 12 | 12 | #include <limits> |
| 13 | 13 | #include <fstream> |
| 14 | +#include <array> | |
| 14 | 15 | #include <cassert> |
| 15 | 16 | |
| 16 | 17 | #include <util/root.hh> |
| @@ -37,6 +38,10 @@ | ||
| 37 | 38 | std::vector<vk::PresentModeKHR> availPresentModes; |
| 38 | 39 | GLFWwindow *window; |
| 39 | 40 | |
| 41 | + | |
| 42 | +vk::Buffer vertBuf = nullptr; | |
| 43 | +vk::DeviceMemory vertBufMem = nullptr; | |
| 44 | + | |
| 40 | 45 | #pragma region debugCallback |
| 41 | 46 | static VKAPI_ATTR vk::Bool32 VKAPI_CALL debugCallback( |
| 42 | 47 | vk::DebugUtilsMessageSeverityFlagBitsEXT severity, |
| @@ -52,6 +57,18 @@ | ||
| 52 | 57 | } |
| 53 | 58 | #pragma endregion |
| 54 | 59 | |
| 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 | + | |
| 55 | 72 | #pragma region transitionImgLayout |
| 56 | 73 | void transitionImgLayout(uint32_t imgIdx, |
| 57 | 74 | vk::ImageLayout oldLayout, |
| @@ -222,12 +239,13 @@ | ||
| 222 | 239 | |
| 223 | 240 | cmdBuf.beginRendering(renderingInfo); |
| 224 | 241 | cmdBuf.bindPipeline(vk::PipelineBindPoint::eGraphics, gfxPipeline); |
| 242 | + cmdBuf.bindVertexBuffers(0, vertBuf, {0}); | |
| 225 | 243 | cmdBuf.setViewport(0, vk::Viewport(0.f, 0.f, |
| 226 | 244 | static_cast<float>(swapChainExtent.width), |
| 227 | 245 | static_cast<float>(swapChainExtent.height), |
| 228 | 246 | 0.f, 1.f)); |
| 229 | 247 | 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); | |
| 231 | 249 | cmdBuf.endRendering(); |
| 232 | 250 | |
| 233 | 251 | transitionImgLayout(imgIdx, |
| @@ -250,9 +268,7 @@ | ||
| 250 | 268 | |
| 251 | 269 | glfwInit(); |
| 252 | 270 | glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); |
| 253 | - //glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); | |
| 254 | 271 | window = glfwCreateWindow(winWidth, winHeight, winName.c_str(), nullptr, nullptr); |
| 255 | - //glfwSetWindowUserPointer(window, this); | |
| 256 | 272 | glfwSetFramebufferSizeCallback(window, framebufferResizeCallback); |
| 257 | 273 | #pragma endregion |
| 258 | 274 | |
| @@ -474,7 +490,7 @@ | ||
| 474 | 490 | vk::DynamicState::eScissor, |
| 475 | 491 | }; |
| 476 | 492 | |
| 477 | - vk::PipelineVertexInputStateCreateInfo vertexInputInfo = {}; | |
| 493 | + vk::PipelineVertexInputStateCreateInfo vertexInputInfo = shader.GetVertexInput(); | |
| 478 | 494 | |
| 479 | 495 | vk::PipelineInputAssemblyStateCreateInfo inputAss = {}; |
| 480 | 496 | inputAss.topology = vk::PrimitiveTopology::eTriangleList; |
| @@ -576,6 +592,25 @@ | ||
| 576 | 592 | vk::CommandPool cmdPool = device.createCommandPool(poolInfo); |
| 577 | 593 | #pragma endregion |
| 578 | 594 | |
| 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 | + | |
| 579 | 614 | #pragma region commandbuffers |
| 580 | 615 | vk::CommandBufferAllocateInfo allocInfo = {}; |
| 581 | 616 | allocInfo.commandPool = cmdPool; |
| @@ -692,6 +727,8 @@ | ||
| 692 | 727 | #pragma region destroy |
| 693 | 728 | if (device) device.waitIdle(); |
| 694 | 729 | if (cmdPool) device.destroyCommandPool(cmdPool); |
| 730 | + if (vertBuf) device.destroyBuffer(vertBuf); | |
| 731 | + if (vertBufMem) device.freeMemory(vertBufMem); | |
| 695 | 732 | if (gfxPipeline) device.destroyPipeline(gfxPipeline); |
| 696 | 733 | if (pipelineLayout) device.destroyPipelineLayout(pipelineLayout); |
| 697 | 734 | 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 | +}; | |
| 6 | 5 | |
| 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 | - | |
| 13 | 6 | struct VertexOutput { |
| 14 | 7 | float3 color; |
| 15 | 8 | float4 sv_position: SV_Position; |
| 16 | 9 | }; |
| 17 | 10 | |
| 18 | 11 | [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; | |
| 24 | 17 | } |
| 25 | 18 | |
| 26 | 19 | [shader("fragment")] |
| @@ -2,19 +2,10 @@ | ||
| 2 | 2 | |
| 3 | 3 | layout(location = 0) out vec3 fragColor; |
| 4 | 4 | |
| 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; | |
| 10 | 7 | |
| 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 | - | |
| 17 | 8 | 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; | |
| 20 | 11 | } |
| @@ -28,6 +28,14 @@ | ||
| 28 | 28 | |
| 29 | 29 | m_ShaderStages.emplace_back(vertShaderStageInfo); |
| 30 | 30 | 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(); | |
| 31 | 39 | } |
| 32 | 40 | |
| 33 | 41 | void Shaders::Finalize() { |
| @@ -3,6 +3,7 @@ | ||
| 3 | 3 | #ifdef USING_GLSL |
| 4 | 4 | #include <util/root.hh> |
| 5 | 5 | #include <vector> |
| 6 | +#include <array> | |
| 6 | 7 | |
| 7 | 8 | class Shaders { |
| 8 | 9 | public: |
| @@ -14,11 +15,16 @@ | ||
| 14 | 15 | |
| 15 | 16 | public: |
| 16 | 17 | const std::vector<vk::PipelineShaderStageCreateInfo> GetShaderStages() const { return m_ShaderStages; } |
| 18 | + const vk::PipelineVertexInputStateCreateInfo &GetVertexInput() const { return m_VertInput; } | |
| 17 | 19 | |
| 18 | 20 | private: |
| 19 | 21 | 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{}; | |
| 23 | 29 | }; // Shaders |
| 24 | 30 | #endif // USING_GLSL |
| @@ -22,6 +22,14 @@ | ||
| 22 | 22 | |
| 23 | 23 | m_ShaderStages.emplace_back(vertShaderStageInfo); |
| 24 | 24 | 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(); | |
| 25 | 33 | } |
| 26 | 34 | |
| 27 | 35 | void Shaders::Finalize() { |
| @@ -3,6 +3,7 @@ | ||
| 3 | 3 | #ifdef USING_SLANG |
| 4 | 4 | #include <util/root.hh> |
| 5 | 5 | #include <vector> |
| 6 | +#include <array> | |
| 6 | 7 | |
| 7 | 8 | class Shaders { |
| 8 | 9 | public: |
| @@ -14,10 +15,15 @@ | ||
| 14 | 15 | |
| 15 | 16 | public: |
| 16 | 17 | const std::vector<vk::PipelineShaderStageCreateInfo> GetShaderStages() const { return m_ShaderStages; } |
| 18 | + const vk::PipelineVertexInputStateCreateInfo &GetVertexInput() const { return m_VertInput; } | |
| 17 | 19 | |
| 18 | 20 | private: |
| 19 | 21 | 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{}; | |
| 22 | 28 | }; // Shaders |
| 23 | 29 | #endif // USING_SLANG |
| @@ -22,3 +22,46 @@ | ||
| 22 | 22 | #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 |
| 23 | 23 | #include <vulkan/vulkan.hpp> |
| 24 | 24 | #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 | +}; |