Created
December 14, 2023 09:40
-
-
Save Kiterai/c7cfb2e79e44177e4366dc0c5615bf94 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define STB_IMAGE_IMPLEMENTATION | |
#define STB_IMAGE_WRITE_IMPLEMENTATION | |
#include "stb_image.h" | |
#include "stb_image_write.h" | |
#include <glm/glm.hpp> | |
#include <glm/gtc/matrix_transform.hpp> | |
#include <vulkan/vulkan.hpp> | |
#include <filesystem> | |
#include <fstream> | |
#include <iostream> | |
const uint32_t screenWidth = 640; | |
const uint32_t screenHeight = 640; | |
struct Vec2 { | |
float x, y; | |
}; | |
struct Vec3 { | |
float x, y, z; | |
}; | |
struct Vertex { | |
Vec3 pos; | |
Vec2 texUV; | |
}; | |
std::vector<Vertex> vertices = { | |
Vertex{Vec3{-0.5f, -0.5f, -0.5f}, Vec2{0.0, 0.0}}, | |
Vertex{Vec3{0.5f, 0.5f, -0.5f}, Vec2{1.0, 1.0}}, | |
Vertex{Vec3{-0.5f, 0.5f, -0.5f}, Vec2{0.0, 1.0}}, | |
Vertex{Vec3{0.5f, -0.5f, -0.5f}, Vec2{1.0, 0.0}}, | |
Vertex{Vec3{-0.5f, -0.5f, -0.5f}, Vec2{0.0, 0.0}}, | |
Vertex{Vec3{0.5f, -0.5f, 0.5f}, Vec2{1.0, 1.0}}, | |
Vertex{Vec3{0.5f, -0.5f, -0.5f}, Vec2{0.0, 1.0}}, | |
Vertex{Vec3{-0.5f, -0.5f, 0.5f}, Vec2{1.0, 0.0}}, | |
Vertex{Vec3{-0.5f, -0.5f, -0.5f}, Vec2{0.0, 0.0}}, | |
Vertex{Vec3{-0.5f, 0.5f, 0.5f}, Vec2{1.0, 1.0}}, | |
Vertex{Vec3{-0.5f, -0.5f, 0.5f}, Vec2{0.0, 1.0}}, | |
Vertex{Vec3{-0.5f, 0.5f, -0.5f}, Vec2{1.0, 0.0}}, | |
Vertex{Vec3{0.5f, 0.5f, 0.5f}, Vec2{0.0, 0.0}}, | |
Vertex{Vec3{-0.5f, -0.5f, 0.5f}, Vec2{1.0, 1.0}}, | |
Vertex{Vec3{0.5f, -0.5f, 0.5f}, Vec2{0.0, 1.0}}, | |
Vertex{Vec3{-0.5f, 0.5f, 0.5f}, Vec2{1.0, 0.0}}, | |
Vertex{Vec3{0.5f, 0.5f, 0.5f}, Vec2{0.0, 0.0}}, | |
Vertex{Vec3{-0.5f, 0.5f, -0.5f}, Vec2{1.0, 1.0}}, | |
Vertex{Vec3{-0.5f, 0.5f, 0.5f}, Vec2{0.0, 1.0}}, | |
Vertex{Vec3{0.5f, 0.5f, -0.5f}, Vec2{1.0, 0.0}}, | |
Vertex{Vec3{0.5f, 0.5f, 0.5f}, Vec2{0.0, 0.0}}, | |
Vertex{Vec3{0.5f, -0.5f, -0.5f}, Vec2{1.0, 1.0}}, | |
Vertex{Vec3{0.5f, 0.5f, -0.5f}, Vec2{0.0, 1.0}}, | |
Vertex{Vec3{0.5f, -0.5f, 0.5f}, Vec2{1.0, 0.0}}, | |
}; | |
std::vector<uint16_t> indices = { | |
0, 1, 2, 1, 0, 3, | |
4, 5, 6, 5, 4, 7, | |
8, 9, 10, 9, 8, 11, | |
12, 13, 14, 13, 12, 15, | |
16, 17, 18, 17, 16, 19, | |
20, 21, 22, 21, 20, 23}; | |
struct SceneData { | |
alignas(16) glm::mat4 model; | |
alignas(16) glm::mat4 view; | |
alignas(16) glm::mat4 proj; | |
}; | |
SceneData sceneData = { | |
glm::mat4(1.0f), | |
glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)), | |
glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 10.0f) | |
}; | |
int main() { | |
vk::InstanceCreateInfo createInfo; | |
vk::UniqueInstance instance; | |
instance = vk::createInstanceUnique(createInfo); | |
std::vector<vk::PhysicalDevice> physicalDevices = instance->enumeratePhysicalDevices(); | |
vk::PhysicalDevice physicalDevice; | |
bool existsSuitablePhysicalDevice = false; | |
uint32_t graphicsQueueFamilyIndex; | |
for (size_t i = 0; i < physicalDevices.size(); i++) { | |
std::vector<vk::QueueFamilyProperties> queueProps = physicalDevices[i].getQueueFamilyProperties(); | |
bool existsGraphicsQueue = false; | |
for (size_t j = 0; j < queueProps.size(); j++) { | |
if (queueProps[j].queueFlags & vk::QueueFlagBits::eGraphics) { | |
existsGraphicsQueue = true; | |
graphicsQueueFamilyIndex = j; | |
break; | |
} | |
} | |
if (existsGraphicsQueue) { | |
physicalDevice = physicalDevices[i]; | |
existsSuitablePhysicalDevice = true; | |
break; | |
} | |
} | |
if (!existsSuitablePhysicalDevice) { | |
std::cerr << "使用可能な物理デバイスがありません。" << std::endl; | |
return -1; | |
} | |
vk::DeviceCreateInfo devCreateInfo; | |
auto devRequiredExtensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME}; | |
devCreateInfo.enabledExtensionCount = devRequiredExtensions.size(); | |
devCreateInfo.ppEnabledExtensionNames = devRequiredExtensions.begin(); | |
vk::DeviceQueueCreateInfo queueCreateInfo[1]; | |
queueCreateInfo[0].queueFamilyIndex = graphicsQueueFamilyIndex; | |
queueCreateInfo[0].queueCount = 1; | |
float queuePriorities[1] = {1.0}; | |
queueCreateInfo[0].pQueuePriorities = queuePriorities; | |
devCreateInfo.pQueueCreateInfos = queueCreateInfo; | |
devCreateInfo.queueCreateInfoCount = 1; | |
vk::UniqueDevice device = physicalDevice.createDeviceUnique(devCreateInfo); | |
vk::Queue graphicsQueue = device->getQueue(graphicsQueueFamilyIndex, 0); | |
vk::CommandPoolCreateInfo cmdPoolCreateInfo; | |
cmdPoolCreateInfo.queueFamilyIndex = graphicsQueueFamilyIndex; | |
vk::UniqueCommandPool cmdPool = device->createCommandPoolUnique(cmdPoolCreateInfo); | |
vk::CommandBufferAllocateInfo cmdBufAllocInfo; | |
cmdBufAllocInfo.commandPool = cmdPool.get(); | |
cmdBufAllocInfo.commandBufferCount = 1; | |
cmdBufAllocInfo.level = vk::CommandBufferLevel::ePrimary; | |
std::vector<vk::UniqueCommandBuffer> cmdBufs = | |
device->allocateCommandBuffersUnique(cmdBufAllocInfo); | |
vk::ImageCreateInfo imgCreateInfo; | |
imgCreateInfo.imageType = vk::ImageType::e2D; | |
imgCreateInfo.extent = vk::Extent3D(screenWidth, screenHeight, 1); | |
imgCreateInfo.mipLevels = 1; | |
imgCreateInfo.arrayLayers = 1; | |
imgCreateInfo.format = vk::Format::eR8G8B8A8Unorm; | |
imgCreateInfo.tiling = vk::ImageTiling::eLinear; | |
imgCreateInfo.initialLayout = vk::ImageLayout::eUndefined; | |
imgCreateInfo.usage = vk::ImageUsageFlagBits::eColorAttachment; | |
imgCreateInfo.sharingMode = vk::SharingMode::eExclusive; | |
imgCreateInfo.samples = vk::SampleCountFlagBits::e1; | |
vk::UniqueImage image = device->createImageUnique(imgCreateInfo); | |
vk::PhysicalDeviceMemoryProperties memProps = physicalDevice.getMemoryProperties(); | |
vk::MemoryRequirements imgMemReq = device->getImageMemoryRequirements(image.get()); | |
vk::MemoryAllocateInfo imgMemAllocInfo; | |
imgMemAllocInfo.allocationSize = imgMemReq.size; | |
bool suitableMemoryTypeFound = false; | |
for (size_t i = 0; i < memProps.memoryTypeCount; i++) { | |
if (imgMemReq.memoryTypeBits & (1 << i) && | |
(memProps.memoryTypes[i].propertyFlags & vk::MemoryPropertyFlagBits::eHostVisible)) { | |
imgMemAllocInfo.memoryTypeIndex = i; | |
suitableMemoryTypeFound = true; | |
break; | |
} | |
} | |
if (!suitableMemoryTypeFound) { | |
std::cerr << "使用可能なメモリタイプがありません。" << std::endl; | |
return -1; | |
} | |
vk::UniqueDeviceMemory imgMem = device->allocateMemoryUnique(imgMemAllocInfo); | |
device->bindImageMemory(image.get(), imgMem.get(), 0); | |
vk::BufferCreateInfo vertBufferCreateInfo; | |
vertBufferCreateInfo.size = sizeof(Vertex) * vertices.size(); | |
vertBufferCreateInfo.usage = vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eTransferDst; | |
vertBufferCreateInfo.sharingMode = vk::SharingMode::eExclusive; | |
vk::UniqueBuffer vertexBuf = device->createBufferUnique(vertBufferCreateInfo); | |
vk::MemoryRequirements vertexBufMemReq = device->getBufferMemoryRequirements(vertexBuf.get()); | |
vk::MemoryAllocateInfo vertexBufMemAllocInfo; | |
vertexBufMemAllocInfo.allocationSize = vertexBufMemReq.size; | |
suitableMemoryTypeFound = false; | |
for (uint32_t i = 0; i < memProps.memoryTypeCount; i++) { | |
if (vertexBufMemReq.memoryTypeBits & (1 << i) && (memProps.memoryTypes[i].propertyFlags & vk::MemoryPropertyFlagBits::eDeviceLocal)) { | |
vertexBufMemAllocInfo.memoryTypeIndex = i; | |
suitableMemoryTypeFound = true; | |
break; | |
} | |
} | |
if (!suitableMemoryTypeFound) { | |
std::cerr << "適切なメモリタイプが存在しません。" << std::endl; | |
return -1; | |
} | |
vk::UniqueDeviceMemory vertexBufMemory = device->allocateMemoryUnique(vertexBufMemAllocInfo); | |
device->bindBufferMemory(vertexBuf.get(), vertexBufMemory.get(), 0); | |
{ | |
vk::BufferCreateInfo stagingBufferCreateInfo; | |
stagingBufferCreateInfo.size = sizeof(Vertex) * vertices.size(); | |
stagingBufferCreateInfo.usage = vk::BufferUsageFlagBits::eTransferSrc; | |
stagingBufferCreateInfo.sharingMode = vk::SharingMode::eExclusive; | |
vk::UniqueBuffer stagingBuf = device->createBufferUnique(stagingBufferCreateInfo); | |
vk::MemoryRequirements stagingBufMemReq = device->getBufferMemoryRequirements(stagingBuf.get()); | |
vk::MemoryAllocateInfo stagingBufMemAllocInfo; | |
stagingBufMemAllocInfo.allocationSize = stagingBufMemReq.size; | |
suitableMemoryTypeFound = false; | |
for (uint32_t i = 0; i < memProps.memoryTypeCount; i++) { | |
if (stagingBufMemReq.memoryTypeBits & (1 << i) && (memProps.memoryTypes[i].propertyFlags & vk::MemoryPropertyFlagBits::eHostVisible)) { | |
stagingBufMemAllocInfo.memoryTypeIndex = i; | |
suitableMemoryTypeFound = true; | |
break; | |
} | |
} | |
if (!suitableMemoryTypeFound) { | |
std::cerr << "適切なメモリタイプが存在しません。" << std::endl; | |
return -1; | |
} | |
vk::UniqueDeviceMemory stagingBufMemory = device->allocateMemoryUnique(stagingBufMemAllocInfo); | |
device->bindBufferMemory(stagingBuf.get(), stagingBufMemory.get(), 0); | |
void *pStagingBufMem = device->mapMemory(stagingBufMemory.get(), 0, sizeof(Vertex) * vertices.size()); | |
std::memcpy(pStagingBufMem, vertices.data(), sizeof(Vertex) * vertices.size()); | |
vk::MappedMemoryRange flushMemoryRange; | |
flushMemoryRange.memory = stagingBufMemory.get(); | |
flushMemoryRange.offset = 0; | |
flushMemoryRange.size = sizeof(Vertex) * vertices.size(); | |
device->flushMappedMemoryRanges({flushMemoryRange}); | |
device->unmapMemory(stagingBufMemory.get()); | |
vk::CommandPoolCreateInfo tmpCmdPoolCreateInfo; | |
tmpCmdPoolCreateInfo.queueFamilyIndex = graphicsQueueFamilyIndex; | |
tmpCmdPoolCreateInfo.flags = vk::CommandPoolCreateFlagBits::eTransient; | |
vk::UniqueCommandPool tmpCmdPool = device->createCommandPoolUnique(tmpCmdPoolCreateInfo); | |
vk::CommandBufferAllocateInfo tmpCmdBufAllocInfo; | |
tmpCmdBufAllocInfo.commandPool = tmpCmdPool.get(); | |
tmpCmdBufAllocInfo.commandBufferCount = 1; | |
tmpCmdBufAllocInfo.level = vk::CommandBufferLevel::ePrimary; | |
std::vector<vk::UniqueCommandBuffer> tmpCmdBufs = device->allocateCommandBuffersUnique(tmpCmdBufAllocInfo); | |
vk::BufferCopy bufCopy; | |
bufCopy.srcOffset = 0; | |
bufCopy.dstOffset = 0; | |
bufCopy.size = sizeof(Vertex) * vertices.size(); | |
vk::CommandBufferBeginInfo cmdBeginInfo; | |
cmdBeginInfo.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit; | |
tmpCmdBufs[0]->begin(cmdBeginInfo); | |
tmpCmdBufs[0]->copyBuffer(stagingBuf.get(), vertexBuf.get(), {bufCopy}); | |
tmpCmdBufs[0]->end(); | |
vk::CommandBuffer submitCmdBuf[1] = {tmpCmdBufs[0].get()}; | |
vk::SubmitInfo submitInfo; | |
submitInfo.commandBufferCount = 1; | |
submitInfo.pCommandBuffers = submitCmdBuf; | |
graphicsQueue.submit({submitInfo}); | |
graphicsQueue.waitIdle(); | |
} | |
vk::BufferCreateInfo indexBufferCreateInfo; | |
indexBufferCreateInfo.size = sizeof(uint16_t) * indices.size(); | |
indexBufferCreateInfo.usage = vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst; | |
indexBufferCreateInfo.sharingMode = vk::SharingMode::eExclusive; | |
vk::UniqueBuffer indexBuf = device->createBufferUnique(indexBufferCreateInfo); | |
vk::MemoryRequirements indexBufMemReq = device->getBufferMemoryRequirements(indexBuf.get()); | |
vk::MemoryAllocateInfo indexBufMemAllocInfo; | |
indexBufMemAllocInfo.allocationSize = indexBufMemReq.size; | |
suitableMemoryTypeFound = false; | |
for (uint32_t i = 0; i < memProps.memoryTypeCount; i++) { | |
if (indexBufMemReq.memoryTypeBits & (1 << i) && (memProps.memoryTypes[i].propertyFlags & vk::MemoryPropertyFlagBits::eDeviceLocal)) { | |
indexBufMemAllocInfo.memoryTypeIndex = i; | |
suitableMemoryTypeFound = true; | |
break; | |
} | |
} | |
if (!suitableMemoryTypeFound) { | |
std::cerr << "適切なメモリタイプが存在しません。" << std::endl; | |
return -1; | |
} | |
vk::UniqueDeviceMemory indexBufMemory = device->allocateMemoryUnique(indexBufMemAllocInfo); | |
device->bindBufferMemory(indexBuf.get(), indexBufMemory.get(), 0); | |
{ | |
vk::BufferCreateInfo stagingBufferCreateInfo; | |
stagingBufferCreateInfo.size = sizeof(uint16_t) * indices.size(); | |
stagingBufferCreateInfo.usage = vk::BufferUsageFlagBits::eTransferSrc; | |
stagingBufferCreateInfo.sharingMode = vk::SharingMode::eExclusive; | |
vk::UniqueBuffer stagingBuf = device->createBufferUnique(stagingBufferCreateInfo); | |
vk::MemoryRequirements stagingBufMemReq = device->getBufferMemoryRequirements(stagingBuf.get()); | |
vk::MemoryAllocateInfo stagingBufMemAllocInfo; | |
stagingBufMemAllocInfo.allocationSize = stagingBufMemReq.size; | |
suitableMemoryTypeFound = false; | |
for (uint32_t i = 0; i < memProps.memoryTypeCount; i++) { | |
if (stagingBufMemReq.memoryTypeBits & (1 << i) && (memProps.memoryTypes[i].propertyFlags & vk::MemoryPropertyFlagBits::eHostVisible)) { | |
stagingBufMemAllocInfo.memoryTypeIndex = i; | |
suitableMemoryTypeFound = true; | |
break; | |
} | |
} | |
if (!suitableMemoryTypeFound) { | |
std::cerr << "適切なメモリタイプが存在しません。" << std::endl; | |
return -1; | |
} | |
vk::UniqueDeviceMemory stagingBufMemory = device->allocateMemoryUnique(stagingBufMemAllocInfo); | |
device->bindBufferMemory(stagingBuf.get(), stagingBufMemory.get(), 0); | |
void *pStagingBufMem = device->mapMemory(stagingBufMemory.get(), 0, sizeof(uint16_t) * indices.size()); | |
std::memcpy(pStagingBufMem, indices.data(), sizeof(uint16_t) * indices.size()); | |
vk::MappedMemoryRange flushMemoryRange; | |
flushMemoryRange.memory = stagingBufMemory.get(); | |
flushMemoryRange.offset = 0; | |
flushMemoryRange.size = sizeof(uint16_t) * indices.size(); | |
device->flushMappedMemoryRanges({flushMemoryRange}); | |
device->unmapMemory(stagingBufMemory.get()); | |
vk::CommandPoolCreateInfo tmpCmdPoolCreateInfo; | |
tmpCmdPoolCreateInfo.queueFamilyIndex = graphicsQueueFamilyIndex; | |
tmpCmdPoolCreateInfo.flags = vk::CommandPoolCreateFlagBits::eTransient; | |
vk::UniqueCommandPool tmpCmdPool = device->createCommandPoolUnique(tmpCmdPoolCreateInfo); | |
vk::CommandBufferAllocateInfo tmpCmdBufAllocInfo; | |
tmpCmdBufAllocInfo.commandPool = tmpCmdPool.get(); | |
tmpCmdBufAllocInfo.commandBufferCount = 1; | |
tmpCmdBufAllocInfo.level = vk::CommandBufferLevel::ePrimary; | |
std::vector<vk::UniqueCommandBuffer> tmpCmdBufs = device->allocateCommandBuffersUnique(tmpCmdBufAllocInfo); | |
vk::BufferCopy bufCopy; | |
bufCopy.srcOffset = 0; | |
bufCopy.dstOffset = 0; | |
bufCopy.size = sizeof(uint16_t) * indices.size(); | |
vk::CommandBufferBeginInfo cmdBeginInfo; | |
cmdBeginInfo.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit; | |
tmpCmdBufs[0]->begin(cmdBeginInfo); | |
tmpCmdBufs[0]->copyBuffer(stagingBuf.get(), indexBuf.get(), {bufCopy}); | |
tmpCmdBufs[0]->end(); | |
vk::CommandBuffer submitCmdBuf[1] = {tmpCmdBufs[0].get()}; | |
vk::SubmitInfo submitInfo; | |
submitInfo.commandBufferCount = 1; | |
submitInfo.pCommandBuffers = submitCmdBuf; | |
graphicsQueue.submit({submitInfo}); | |
graphicsQueue.waitIdle(); | |
} | |
vk::BufferCreateInfo uniformBufferCreateInfo; | |
uniformBufferCreateInfo.size = sizeof(SceneData); | |
uniformBufferCreateInfo.usage = vk::BufferUsageFlagBits::eUniformBuffer; | |
uniformBufferCreateInfo.sharingMode = vk::SharingMode::eExclusive; | |
vk::UniqueBuffer uniformBuf = device->createBufferUnique(uniformBufferCreateInfo); | |
vk::MemoryRequirements uniformBufMemReq = device->getBufferMemoryRequirements(uniformBuf.get()); | |
vk::MemoryAllocateInfo uniformBufMemAllocInfo; | |
uniformBufMemAllocInfo.allocationSize = uniformBufMemReq.size; | |
suitableMemoryTypeFound = false; | |
for (uint32_t i = 0; i < memProps.memoryTypeCount; i++) { | |
if (uniformBufMemReq.memoryTypeBits & (1 << i) && | |
(memProps.memoryTypes[i].propertyFlags & vk::MemoryPropertyFlagBits::eHostVisible)) { | |
uniformBufMemAllocInfo.memoryTypeIndex = i; | |
suitableMemoryTypeFound = true; | |
break; | |
} | |
} | |
if (!suitableMemoryTypeFound) { | |
std::cerr << "適切なメモリタイプが存在しません。" << std::endl; | |
return -1; | |
} | |
vk::UniqueDeviceMemory uniformBufMemory = device->allocateMemoryUnique(uniformBufMemAllocInfo); | |
device->bindBufferMemory(uniformBuf.get(), uniformBufMemory.get(), 0); | |
{ | |
void* pUniformBufMem = device->mapMemory(uniformBufMemory.get(), 0, sizeof(SceneData)); | |
std::memcpy(pUniformBufMem, &sceneData, sizeof(SceneData)); | |
vk::MappedMemoryRange flushMemoryRange; | |
flushMemoryRange.memory = uniformBufMemory.get(); | |
flushMemoryRange.offset = 0; | |
flushMemoryRange.size = sizeof(SceneData); | |
device->flushMappedMemoryRanges({ flushMemoryRange }); | |
device->unmapMemory(uniformBufMemory.get()); | |
} | |
int imgWidth, imgHeight, imgCh; | |
auto pImgData = stbi_load("image.png", &imgWidth, &imgHeight, &imgCh, STBI_rgb_alpha); | |
if (pImgData == nullptr) { | |
std::cerr << "画像ファイルの読み込みに失敗しました。" << std::endl; | |
return -1; | |
} | |
vk::ImageCreateInfo texImgCreateInfo; | |
texImgCreateInfo.imageType = vk::ImageType::e2D; | |
texImgCreateInfo.extent = vk::Extent3D(imgWidth, imgHeight, 1); | |
texImgCreateInfo.mipLevels = 1; | |
texImgCreateInfo.arrayLayers = 1; | |
texImgCreateInfo.format = vk::Format::eR8G8B8A8Unorm; | |
texImgCreateInfo.tiling = vk::ImageTiling::eOptimal; | |
texImgCreateInfo.initialLayout = vk::ImageLayout::eUndefined; | |
texImgCreateInfo.usage = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst; | |
texImgCreateInfo.sharingMode = vk::SharingMode::eExclusive; | |
texImgCreateInfo.samples = vk::SampleCountFlagBits::e1; | |
vk::UniqueImage texImage = device->createImageUnique(texImgCreateInfo); | |
vk::MemoryRequirements texImgMemReq = device->getImageMemoryRequirements(texImage.get()); | |
vk::MemoryAllocateInfo texImgMemAllocInfo; | |
texImgMemAllocInfo.allocationSize = texImgMemReq.size; | |
suitableMemoryTypeFound = false; | |
for (size_t i = 0; i < memProps.memoryTypeCount; i++) { | |
if (texImgMemReq.memoryTypeBits & (1 << i)) { | |
texImgMemAllocInfo.memoryTypeIndex = i; | |
suitableMemoryTypeFound = true; | |
break; | |
} | |
} | |
if (!suitableMemoryTypeFound) { | |
std::cerr << "使用可能なメモリタイプがありません。" << std::endl; | |
return -1; | |
} | |
vk::UniqueDeviceMemory texImgMem = device->allocateMemoryUnique(texImgMemAllocInfo); | |
device->bindImageMemory(texImage.get(), texImgMem.get(), 0); | |
{ | |
size_t imgDataSize = 4 * imgWidth * imgHeight; | |
vk::BufferCreateInfo imgStagingBufferCreateInfo; | |
imgStagingBufferCreateInfo.size = imgDataSize; | |
imgStagingBufferCreateInfo.usage = vk::BufferUsageFlagBits::eTransferSrc; | |
imgStagingBufferCreateInfo.sharingMode = vk::SharingMode::eExclusive; | |
vk::UniqueBuffer imgStagingBuf = device->createBufferUnique(imgStagingBufferCreateInfo); | |
vk::MemoryRequirements imgStagingBufMemReq = device->getBufferMemoryRequirements(imgStagingBuf.get()); | |
vk::MemoryAllocateInfo imgStagingBufMemAllocInfo; | |
imgStagingBufMemAllocInfo.allocationSize = imgStagingBufMemReq.size; | |
suitableMemoryTypeFound = false; | |
for (uint32_t i = 0; i < memProps.memoryTypeCount; i++) { | |
if (imgStagingBufMemReq.memoryTypeBits & (1 << i) && | |
(memProps.memoryTypes[i].propertyFlags & vk::MemoryPropertyFlagBits::eHostVisible)) { | |
imgStagingBufMemAllocInfo.memoryTypeIndex = i; | |
suitableMemoryTypeFound = true; | |
break; | |
} | |
} | |
if (!suitableMemoryTypeFound) { | |
std::cerr << "適切なメモリタイプが存在しません。" << std::endl; | |
return -1; | |
} | |
vk::UniqueDeviceMemory imgStagingBufMemory = device->allocateMemoryUnique(imgStagingBufMemAllocInfo); | |
device->bindBufferMemory(imgStagingBuf.get(), imgStagingBufMemory.get(), 0); | |
void *pImgStagingBufMem = device->mapMemory(imgStagingBufMemory.get(), 0, imgDataSize); | |
std::memcpy(pImgStagingBufMem, pImgData, imgDataSize); | |
vk::MappedMemoryRange flushMemoryRange; | |
flushMemoryRange.memory = imgStagingBufMemory.get(); | |
flushMemoryRange.offset = 0; | |
flushMemoryRange.size = imgDataSize; | |
device->flushMappedMemoryRanges({flushMemoryRange}); | |
device->unmapMemory(imgStagingBufMemory.get()); | |
stbi_image_free(pImgData); | |
vk::CommandPoolCreateInfo tmpCmdPoolCreateInfo; | |
tmpCmdPoolCreateInfo.queueFamilyIndex = graphicsQueueFamilyIndex; | |
tmpCmdPoolCreateInfo.flags = vk::CommandPoolCreateFlagBits::eTransient; | |
vk::UniqueCommandPool tmpCmdPool = device->createCommandPoolUnique(tmpCmdPoolCreateInfo); | |
vk::CommandBufferAllocateInfo tmpCmdBufAllocInfo; | |
tmpCmdBufAllocInfo.commandPool = tmpCmdPool.get(); | |
tmpCmdBufAllocInfo.commandBufferCount = 1; | |
tmpCmdBufAllocInfo.level = vk::CommandBufferLevel::ePrimary; | |
std::vector<vk::UniqueCommandBuffer> tmpCmdBufs = device->allocateCommandBuffersUnique(tmpCmdBufAllocInfo); | |
vk::CommandBufferBeginInfo cmdBeginInfo; | |
cmdBeginInfo.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit; | |
tmpCmdBufs[0]->begin(cmdBeginInfo); | |
{ | |
vk::ImageMemoryBarrier barrior; | |
barrior.oldLayout = vk::ImageLayout::eUndefined; | |
barrior.newLayout = vk::ImageLayout::eTransferDstOptimal; | |
barrior.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; | |
barrior.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; | |
barrior.image = texImage.get(); | |
barrior.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; | |
barrior.subresourceRange.baseMipLevel = 0; | |
barrior.subresourceRange.levelCount = 1; | |
barrior.subresourceRange.baseArrayLayer = 0; | |
barrior.subresourceRange.layerCount = 1; | |
barrior.srcAccessMask = {}; | |
barrior.dstAccessMask = vk::AccessFlagBits::eTransferWrite; | |
tmpCmdBufs[0]->pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, {barrior}); | |
} | |
vk::BufferImageCopy imgCopyRegion; | |
imgCopyRegion.bufferOffset = 0; | |
imgCopyRegion.imageSubresource.aspectMask = vk::ImageAspectFlagBits::eColor; | |
imgCopyRegion.imageSubresource.mipLevel = 0; | |
imgCopyRegion.imageSubresource.baseArrayLayer = 0; | |
imgCopyRegion.imageSubresource.layerCount = 1; | |
imgCopyRegion.imageOffset = vk::Offset3D{0, 0, 0}; | |
imgCopyRegion.imageExtent = vk::Extent3D{uint32_t(imgWidth), uint32_t(imgHeight), 1}; | |
imgCopyRegion.bufferRowLength = 0; | |
imgCopyRegion.bufferImageHeight = 0; | |
tmpCmdBufs[0]->copyBufferToImage(imgStagingBuf.get(), texImage.get(), vk::ImageLayout::eTransferDstOptimal, { imgCopyRegion }); | |
{ | |
vk::ImageMemoryBarrier barrior; | |
barrior.oldLayout = vk::ImageLayout::eTransferDstOptimal; | |
barrior.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal; | |
barrior.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; | |
barrior.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; | |
barrior.image = texImage.get(); | |
barrior.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; | |
barrior.subresourceRange.baseMipLevel = 0; | |
barrior.subresourceRange.levelCount = 1; | |
barrior.subresourceRange.baseArrayLayer = 0; | |
barrior.subresourceRange.layerCount = 1; | |
barrior.srcAccessMask = vk::AccessFlagBits::eTransferWrite; | |
barrior.dstAccessMask = vk::AccessFlagBits::eShaderRead; | |
tmpCmdBufs[0]->pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader, {}, {}, {}, {barrior}); | |
} | |
tmpCmdBufs[0]->end(); | |
vk::CommandBuffer submitCmdBuf[1] = {tmpCmdBufs[0].get()}; | |
vk::SubmitInfo submitInfo; | |
submitInfo.commandBufferCount = 1; | |
submitInfo.pCommandBuffers = submitCmdBuf; | |
graphicsQueue.submit({submitInfo}); | |
graphicsQueue.waitIdle(); | |
} | |
vk::SamplerCreateInfo samplerCreateInfo; | |
samplerCreateInfo.magFilter = vk::Filter::eNearest; | |
samplerCreateInfo.minFilter = vk::Filter::eNearest; | |
samplerCreateInfo.addressModeU = vk::SamplerAddressMode::eRepeat; | |
samplerCreateInfo.addressModeV = vk::SamplerAddressMode::eRepeat; | |
samplerCreateInfo.addressModeW = vk::SamplerAddressMode::eRepeat; | |
samplerCreateInfo.anisotropyEnable = false; | |
samplerCreateInfo.maxAnisotropy = 1.0f; | |
samplerCreateInfo.borderColor = vk::BorderColor::eIntOpaqueBlack; | |
samplerCreateInfo.unnormalizedCoordinates = false; | |
samplerCreateInfo.compareEnable = false; | |
samplerCreateInfo.compareOp = vk::CompareOp::eAlways; | |
samplerCreateInfo.mipmapMode = vk::SamplerMipmapMode::eLinear; | |
samplerCreateInfo.mipLodBias = 0.0f; | |
samplerCreateInfo.minLod = 0.0f; | |
samplerCreateInfo.maxLod = 0.0f; | |
vk::UniqueSampler sampler = device->createSamplerUnique(samplerCreateInfo); | |
vk::ImageViewCreateInfo texImgViewCreateInfo; | |
texImgViewCreateInfo.image = texImage.get(); | |
texImgViewCreateInfo.viewType = vk::ImageViewType::e2D; | |
texImgViewCreateInfo.format = vk::Format::eR8G8B8A8Unorm; | |
texImgViewCreateInfo.components.r = vk::ComponentSwizzle::eIdentity; | |
texImgViewCreateInfo.components.g = vk::ComponentSwizzle::eIdentity; | |
texImgViewCreateInfo.components.b = vk::ComponentSwizzle::eIdentity; | |
texImgViewCreateInfo.components.a = vk::ComponentSwizzle::eIdentity; | |
texImgViewCreateInfo.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; | |
texImgViewCreateInfo.subresourceRange.baseMipLevel = 0; | |
texImgViewCreateInfo.subresourceRange.levelCount = 1; | |
texImgViewCreateInfo.subresourceRange.baseArrayLayer = 0; | |
texImgViewCreateInfo.subresourceRange.layerCount = 1; | |
vk::UniqueImageView texImageView = device->createImageViewUnique(texImgViewCreateInfo); | |
vk::DescriptorSetLayoutBinding descSetLayoutBinding[2]; | |
descSetLayoutBinding[0].binding = 0; | |
descSetLayoutBinding[0].descriptorType = vk::DescriptorType::eUniformBuffer; | |
descSetLayoutBinding[0].descriptorCount = 1; | |
descSetLayoutBinding[0].stageFlags = vk::ShaderStageFlagBits::eVertex; | |
descSetLayoutBinding[1].binding = 1; | |
descSetLayoutBinding[1].descriptorType = vk::DescriptorType::eCombinedImageSampler; | |
descSetLayoutBinding[1].descriptorCount = 1; | |
descSetLayoutBinding[1].stageFlags = vk::ShaderStageFlagBits::eFragment; | |
vk::DescriptorSetLayoutCreateInfo descSetLayoutCreateInfo{}; | |
descSetLayoutCreateInfo.bindingCount = std::size(descSetLayoutBinding); | |
descSetLayoutCreateInfo.pBindings = descSetLayoutBinding; | |
vk::UniqueDescriptorSetLayout descSetLayout = device->createDescriptorSetLayoutUnique(descSetLayoutCreateInfo); | |
vk::DescriptorPoolSize descPoolSize[2]; | |
descPoolSize[0].type = vk::DescriptorType::eUniformBuffer; | |
descPoolSize[0].descriptorCount = 1; | |
descPoolSize[1].type = vk::DescriptorType::eCombinedImageSampler; | |
descPoolSize[1].descriptorCount = 1; | |
vk::DescriptorPoolCreateInfo descPoolCreateInfo; | |
descPoolCreateInfo.poolSizeCount = std::size(descPoolSize); | |
descPoolCreateInfo.pPoolSizes = descPoolSize; | |
descPoolCreateInfo.maxSets = 1; | |
vk::UniqueDescriptorPool descPool = device->createDescriptorPoolUnique(descPoolCreateInfo); | |
vk::DescriptorSetAllocateInfo descSetAllocInfo; | |
auto descSetLayouts = { descSetLayout.get() }; | |
descSetAllocInfo.descriptorPool = descPool.get(); | |
descSetAllocInfo.descriptorSetCount = descSetLayouts.size(); | |
descSetAllocInfo.pSetLayouts = descSetLayouts.begin(); | |
std::vector<vk::UniqueDescriptorSet> descSets = device->allocateDescriptorSetsUnique(descSetAllocInfo); | |
vk::WriteDescriptorSet writeDescSet; | |
writeDescSet.dstSet = descSets[0].get(); | |
writeDescSet.dstBinding = 0; | |
writeDescSet.dstArrayElement = 0; | |
writeDescSet.descriptorType = vk::DescriptorType::eUniformBuffer; | |
vk::DescriptorBufferInfo descBufInfo[1]; | |
descBufInfo[0].buffer = uniformBuf.get(); | |
descBufInfo[0].offset = 0; | |
descBufInfo[0].range = sizeof(SceneData); | |
writeDescSet.descriptorCount = 1; | |
writeDescSet.pBufferInfo = descBufInfo; | |
device->updateDescriptorSets({ writeDescSet }, {}); | |
vk::WriteDescriptorSet writeTexDescSet; | |
writeTexDescSet.dstSet = descSets[0].get(); | |
writeTexDescSet.dstBinding = 1; | |
writeTexDescSet.dstArrayElement = 0; | |
writeTexDescSet.descriptorType = vk::DescriptorType::eCombinedImageSampler; | |
vk::DescriptorImageInfo descImgInfo[1]; | |
descImgInfo[0].imageView = texImageView.get(); | |
descImgInfo[0].imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal; | |
descImgInfo[0].sampler = sampler.get(); | |
writeTexDescSet.descriptorCount = std::size(descImgInfo); | |
writeTexDescSet.pImageInfo = descImgInfo; | |
device->updateDescriptorSets({ writeTexDescSet }, {}); | |
vk::AttachmentDescription attachments[1]; | |
attachments[0].format = vk::Format::eR8G8B8A8Unorm; | |
attachments[0].samples = vk::SampleCountFlagBits::e1; | |
attachments[0].loadOp = vk::AttachmentLoadOp::eClear; | |
attachments[0].storeOp = vk::AttachmentStoreOp::eStore; | |
attachments[0].stencilLoadOp = vk::AttachmentLoadOp::eDontCare; | |
attachments[0].stencilStoreOp = vk::AttachmentStoreOp::eDontCare; | |
attachments[0].initialLayout = vk::ImageLayout::eUndefined; | |
attachments[0].finalLayout = vk::ImageLayout::ePresentSrcKHR; | |
vk::AttachmentReference subpass0_attachmentRefs[1]; | |
subpass0_attachmentRefs[0].attachment = 0; | |
subpass0_attachmentRefs[0].layout = vk::ImageLayout::eColorAttachmentOptimal; | |
vk::SubpassDescription subpasses[1]; | |
subpasses[0].pipelineBindPoint = vk::PipelineBindPoint::eGraphics; | |
subpasses[0].colorAttachmentCount = 1; | |
subpasses[0].pColorAttachments = subpass0_attachmentRefs; | |
vk::RenderPassCreateInfo renderpassCreateInfo; | |
renderpassCreateInfo.attachmentCount = 1; | |
renderpassCreateInfo.pAttachments = attachments; | |
renderpassCreateInfo.subpassCount = 1; | |
renderpassCreateInfo.pSubpasses = subpasses; | |
renderpassCreateInfo.dependencyCount = 0; | |
renderpassCreateInfo.pDependencies = nullptr; | |
vk::UniqueRenderPass renderpass = device->createRenderPassUnique(renderpassCreateInfo); | |
vk::Viewport viewports[1]; | |
viewports[0].x = 0.0; | |
viewports[0].y = 0.0; | |
viewports[0].minDepth = 0.0; | |
viewports[0].maxDepth = 1.0; | |
viewports[0].width = screenWidth; | |
viewports[0].height = screenHeight; | |
vk::Rect2D scissors[1]; | |
scissors[0].offset = vk::Offset2D{0, 0}; | |
scissors[0].extent = vk::Extent2D{screenWidth, screenHeight}; | |
vk::PipelineViewportStateCreateInfo viewportState; | |
viewportState.viewportCount = 1; | |
viewportState.pViewports = viewports; | |
viewportState.scissorCount = 1; | |
viewportState.pScissors = scissors; | |
vk::VertexInputBindingDescription vertexBindingDescription[1]; | |
vertexBindingDescription[0].binding = 0; | |
vertexBindingDescription[0].stride = sizeof(Vertex); | |
vertexBindingDescription[0].inputRate = vk::VertexInputRate::eVertex; | |
vk::VertexInputAttributeDescription vertexInputDescription[2]; | |
vertexInputDescription[0].binding = 0; | |
vertexInputDescription[0].location = 0; | |
vertexInputDescription[0].format = vk::Format::eR32G32B32Sfloat; | |
vertexInputDescription[0].offset = offsetof(Vertex, pos); | |
vertexInputDescription[1].binding = 0; | |
vertexInputDescription[1].location = 1; | |
vertexInputDescription[1].format = vk::Format::eR32G32Sfloat; | |
vertexInputDescription[1].offset = offsetof(Vertex, texUV); | |
vk::PipelineVertexInputStateCreateInfo vertexInputInfo; | |
vertexInputInfo.vertexBindingDescriptionCount = 1; | |
vertexInputInfo.pVertexBindingDescriptions = vertexBindingDescription; | |
vertexInputInfo.vertexAttributeDescriptionCount = std::size(vertexInputDescription); | |
vertexInputInfo.pVertexAttributeDescriptions = vertexInputDescription; | |
vk::PipelineInputAssemblyStateCreateInfo inputAssembly; | |
inputAssembly.topology = vk::PrimitiveTopology::eTriangleList; | |
inputAssembly.primitiveRestartEnable = false; | |
vk::PipelineRasterizationStateCreateInfo rasterizer; | |
rasterizer.depthClampEnable = false; | |
rasterizer.rasterizerDiscardEnable = false; | |
rasterizer.polygonMode = vk::PolygonMode::eFill; | |
rasterizer.lineWidth = 1.0f; | |
rasterizer.cullMode = vk::CullModeFlagBits::eBack; | |
rasterizer.frontFace = vk::FrontFace::eClockwise; | |
rasterizer.depthBiasEnable = false; | |
vk::PipelineMultisampleStateCreateInfo multisample; | |
multisample.sampleShadingEnable = false; | |
multisample.rasterizationSamples = vk::SampleCountFlagBits::e1; | |
vk::PipelineColorBlendAttachmentState blendattachment[1]; | |
blendattachment[0].colorWriteMask = vk::ColorComponentFlagBits::eA | vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB; | |
blendattachment[0].blendEnable = false; | |
vk::PipelineColorBlendStateCreateInfo blend; | |
blend.logicOpEnable = false; | |
blend.attachmentCount = 1; | |
blend.pAttachments = blendattachment; | |
auto pipelineDescSetLayouts = { descSetLayout.get() }; | |
vk::PipelineLayoutCreateInfo layoutCreateInfo; | |
layoutCreateInfo.setLayoutCount = pipelineDescSetLayouts.size(); | |
layoutCreateInfo.pSetLayouts = pipelineDescSetLayouts.begin(); | |
vk::UniquePipelineLayout pipelineLayout = device->createPipelineLayoutUnique(layoutCreateInfo); | |
size_t vertSpvFileSz = std::filesystem::file_size("shader.vert.spv"); | |
std::ifstream vertSpvFile("shader.vert.spv", std::ios_base::binary); | |
std::vector<char> vertSpvFileData(vertSpvFileSz); | |
vertSpvFile.read(vertSpvFileData.data(), vertSpvFileSz); | |
vk::ShaderModuleCreateInfo vertShaderCreateInfo; | |
vertShaderCreateInfo.codeSize = vertSpvFileSz; | |
vertShaderCreateInfo.pCode = reinterpret_cast<const uint32_t *>(vertSpvFileData.data()); | |
vk::UniqueShaderModule vertShader = device->createShaderModuleUnique(vertShaderCreateInfo); | |
size_t fragSpvFileSz = std::filesystem::file_size("shader.frag.spv"); | |
std::ifstream fragSpvFile("shader.frag.spv", std::ios_base::binary); | |
std::vector<char> fragSpvFileData(fragSpvFileSz); | |
fragSpvFile.read(fragSpvFileData.data(), fragSpvFileSz); | |
vk::ShaderModuleCreateInfo fragShaderCreateInfo; | |
fragShaderCreateInfo.codeSize = fragSpvFileSz; | |
fragShaderCreateInfo.pCode = reinterpret_cast<const uint32_t *>(fragSpvFileData.data()); | |
vk::UniqueShaderModule fragShader = device->createShaderModuleUnique(fragShaderCreateInfo); | |
vk::PipelineShaderStageCreateInfo shaderStage[2]; | |
shaderStage[0].stage = vk::ShaderStageFlagBits::eVertex; | |
shaderStage[0].module = vertShader.get(); | |
shaderStage[0].pName = "main"; | |
shaderStage[1].stage = vk::ShaderStageFlagBits::eFragment; | |
shaderStage[1].module = fragShader.get(); | |
shaderStage[1].pName = "main"; | |
vk::GraphicsPipelineCreateInfo pipelineCreateInfo; | |
pipelineCreateInfo.pViewportState = &viewportState; | |
pipelineCreateInfo.pVertexInputState = &vertexInputInfo; | |
pipelineCreateInfo.pInputAssemblyState = &inputAssembly; | |
pipelineCreateInfo.pRasterizationState = &rasterizer; | |
pipelineCreateInfo.pMultisampleState = &multisample; | |
pipelineCreateInfo.pColorBlendState = &blend; | |
pipelineCreateInfo.layout = pipelineLayout.get(); | |
pipelineCreateInfo.renderPass = renderpass.get(); | |
pipelineCreateInfo.subpass = 0; | |
pipelineCreateInfo.stageCount = 2; | |
pipelineCreateInfo.pStages = shaderStage; | |
vk::UniquePipeline pipeline = device->createGraphicsPipelineUnique(nullptr, pipelineCreateInfo).value; | |
vk::ImageViewCreateInfo imgViewCreateInfo; | |
imgViewCreateInfo.image = image.get(); | |
imgViewCreateInfo.viewType = vk::ImageViewType::e2D; | |
imgViewCreateInfo.format = vk::Format::eR8G8B8A8Unorm; | |
imgViewCreateInfo.components.r = vk::ComponentSwizzle::eIdentity; | |
imgViewCreateInfo.components.g = vk::ComponentSwizzle::eIdentity; | |
imgViewCreateInfo.components.b = vk::ComponentSwizzle::eIdentity; | |
imgViewCreateInfo.components.a = vk::ComponentSwizzle::eIdentity; | |
imgViewCreateInfo.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; | |
imgViewCreateInfo.subresourceRange.baseMipLevel = 0; | |
imgViewCreateInfo.subresourceRange.levelCount = 1; | |
imgViewCreateInfo.subresourceRange.baseArrayLayer = 0; | |
imgViewCreateInfo.subresourceRange.layerCount = 1; | |
vk::UniqueImageView imgView = device->createImageViewUnique(imgViewCreateInfo); | |
vk::ImageView frameBufAttachments[1]; | |
frameBufAttachments[0] = imgView.get(); | |
vk::FramebufferCreateInfo frameBufCreateInfo; | |
frameBufCreateInfo.width = screenWidth; | |
frameBufCreateInfo.height = screenHeight; | |
frameBufCreateInfo.layers = 1; | |
frameBufCreateInfo.renderPass = renderpass.get(); | |
frameBufCreateInfo.attachmentCount = 1; | |
frameBufCreateInfo.pAttachments = frameBufAttachments; | |
vk::UniqueFramebuffer frameBuf = device->createFramebufferUnique(frameBufCreateInfo); | |
vk::CommandBufferBeginInfo cmdBeginInfo; | |
cmdBufs[0]->begin(cmdBeginInfo); | |
vk::ClearValue clearVal[1]; | |
clearVal[0].color.float32[0] = 0.0f; | |
clearVal[0].color.float32[1] = 0.0f; | |
clearVal[0].color.float32[2] = 0.0f; | |
clearVal[0].color.float32[3] = 1.0f; | |
vk::RenderPassBeginInfo renderpassBeginInfo; | |
renderpassBeginInfo.renderPass = renderpass.get(); | |
renderpassBeginInfo.framebuffer = frameBuf.get(); | |
renderpassBeginInfo.renderArea = vk::Rect2D({ 0,0 }, { screenWidth, screenHeight }); | |
renderpassBeginInfo.clearValueCount = 1; | |
renderpassBeginInfo.pClearValues = clearVal; | |
cmdBufs[0]->beginRenderPass(renderpassBeginInfo, vk::SubpassContents::eInline); | |
cmdBufs[0]->bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline.get()); | |
cmdBufs[0]->bindVertexBuffers(0, {vertexBuf.get()}, {0}); | |
cmdBufs[0]->bindIndexBuffer(indexBuf.get(), 0, vk::IndexType::eUint16); | |
cmdBufs[0]->bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout.get(), 0, { descSets[0].get() }, {}); | |
cmdBufs[0]->drawIndexed(indices.size(), 1, 0, 0, 0); | |
cmdBufs[0]->endRenderPass(); | |
cmdBufs[0]->end(); | |
vk::CommandBuffer submitCmdBuf[1] = { cmdBufs[0].get() }; | |
vk::SubmitInfo submitInfo; | |
submitInfo.commandBufferCount = 1; | |
submitInfo.pCommandBuffers = submitCmdBuf; | |
graphicsQueue.submit({ submitInfo }, nullptr); | |
graphicsQueue.waitIdle(); | |
void* imgData = device->mapMemory(imgMem.get(), 0, imgMemReq.size); | |
stbi_write_bmp("img.bmp", screenWidth, screenHeight, 4, imgData); | |
device->unmapMemory(imgMem.get()); | |
graphicsQueue.waitIdle(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 450 | |
#extension GL_ARB_separate_shader_objects : enable | |
layout(set = 0, binding = 1) uniform sampler2D texSampler; | |
layout(location = 0) in vec2 fragmentTexUV; | |
layout(location = 0) out vec4 outColor; | |
void main() { | |
outColor = texture(texSampler, fragmentTexUV); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 450 | |
#extension GL_ARB_separate_shader_objects : enable | |
layout(set = 0, binding = 0) uniform SceneData { | |
mat4 model; | |
mat4 view; | |
mat4 proj; | |
} sceneData; | |
layout(location = 0) in vec3 inPos; | |
layout(location = 1) in vec2 inTexUV; | |
layout(location = 0) out vec2 fragmentTexUV; | |
void main() { | |
gl_Position = sceneData.proj * sceneData.view * sceneData.model * vec4(inPos, 1.0); | |
fragmentTexUV = inTexUV; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment