Add file structure to code
- Rename project to CopiumEngine
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
#include "copium/sampler/ColorAttachment.h"
|
||||
|
||||
#include "copium/sampler/Image.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
ColorAttachment::ColorAttachment(Instance& instance, int width, int height)
|
||||
: Sampler{instance}
|
||||
{
|
||||
InitializeColorAttachment(width, height);
|
||||
}
|
||||
|
||||
ColorAttachment::~ColorAttachment()
|
||||
{
|
||||
for (auto&& image : images)
|
||||
vkDestroyImage(instance.GetDevice(), image, nullptr);
|
||||
for (auto&& imageMemory : imageMemories)
|
||||
vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
|
||||
for (auto&& imageView : imageViews)
|
||||
vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
|
||||
}
|
||||
|
||||
VkDescriptorImageInfo ColorAttachment::GetDescriptorImageInfo(int index) const
|
||||
{
|
||||
CP_ASSERT(index >= 0 && index < imageViews.size(), "GetDescriptorImageInfo : index out of bound for color attachment");
|
||||
|
||||
VkDescriptorImageInfo imageInfo{};
|
||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
imageInfo.sampler = sampler;
|
||||
imageInfo.imageView = imageViews[index];
|
||||
return imageInfo;
|
||||
}
|
||||
|
||||
VkImageView ColorAttachment::GetImageView(int index)
|
||||
{
|
||||
CP_ASSERT(index >= 0 && index < imageViews.size(), "GetImageView : Index out of bound");
|
||||
|
||||
return imageViews[index];
|
||||
}
|
||||
|
||||
void ColorAttachment::InitializeColorAttachment(int width, int height)
|
||||
{
|
||||
images.resize(instance.GetMaxFramesInFlight());
|
||||
imageMemories.resize(instance.GetMaxFramesInFlight());
|
||||
imageViews.resize(instance.GetMaxFramesInFlight());
|
||||
for (size_t i = 0; i < images.size(); i++)
|
||||
{
|
||||
Image::InitializeImage(instance, width, height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &images[i], &imageMemories[i]);
|
||||
imageViews[i] = Image::InitializeImageView(instance, images[i], VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/core/Instance.h"
|
||||
#include "copium/sampler/Sampler.h"
|
||||
#include "copium/util/Common.h"
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class ColorAttachment final : public Sampler
|
||||
{
|
||||
CP_DELETE_COPY_AND_MOVE_CTOR(ColorAttachment);
|
||||
private:
|
||||
std::vector<VkImage> images;
|
||||
std::vector<VkDeviceMemory> imageMemories;
|
||||
std::vector<VkImageView> imageViews;
|
||||
public:
|
||||
ColorAttachment(Instance& instance, int width, int height);
|
||||
~ColorAttachment() override;
|
||||
|
||||
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
|
||||
VkImageView GetImageView(int index);
|
||||
|
||||
private:
|
||||
void InitializeColorAttachment(int width, int height);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "copium/sampler/DepthAttachment.h"
|
||||
|
||||
#include "copium/sampler/Image.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
DepthAttachment::DepthAttachment(Instance& instance, int width, int height)
|
||||
: Sampler{instance}
|
||||
{
|
||||
InitializeDepthAttachment(width, height);
|
||||
}
|
||||
|
||||
DepthAttachment::~DepthAttachment()
|
||||
{
|
||||
vkDestroyImage(instance.GetDevice(), image, nullptr);
|
||||
vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
|
||||
vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
|
||||
}
|
||||
|
||||
VkDescriptorImageInfo DepthAttachment::GetDescriptorImageInfo(int index) const
|
||||
{
|
||||
VkDescriptorImageInfo imageInfo{};
|
||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
imageInfo.sampler = sampler;
|
||||
imageInfo.imageView = imageView;
|
||||
return imageInfo;
|
||||
}
|
||||
|
||||
VkImageView DepthAttachment::GetImageView() const
|
||||
{
|
||||
return imageView;
|
||||
}
|
||||
|
||||
void DepthAttachment::InitializeDepthAttachment(int width, int height)
|
||||
{
|
||||
VkFormat depthFormat = Image::SelectDepthFormat(instance);
|
||||
Image::InitializeImage(instance, width, height, depthFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory);
|
||||
imageView = Image::InitializeImageView(instance, image, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/core/Instance.h"
|
||||
#include "copium/sampler/Sampler.h"
|
||||
#include "copium/util/Common.h"
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class DepthAttachment final : public Sampler
|
||||
{
|
||||
CP_DELETE_COPY_AND_MOVE_CTOR(DepthAttachment);
|
||||
private:
|
||||
VkImage image;
|
||||
VkDeviceMemory imageMemory;
|
||||
VkImageView imageView;
|
||||
public:
|
||||
DepthAttachment(Instance& instance, int width, int height);
|
||||
~DepthAttachment() override;
|
||||
|
||||
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
|
||||
VkImageView GetImageView() const;
|
||||
|
||||
private:
|
||||
void InitializeDepthAttachment(int width, int height);
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
#include "copium/sampler/Image.h"
|
||||
|
||||
#include "copium/buffer/CommandBufferScoped.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
void Image::InitializeImage(Instance& instance, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage* image, VkDeviceMemory* imageMemory)
|
||||
{
|
||||
VkImageCreateInfo createInfo{};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
createInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
createInfo.extent.width = width;
|
||||
createInfo.extent.height = height;
|
||||
createInfo.extent.depth = 1;
|
||||
createInfo.mipLevels = 1;
|
||||
createInfo.arrayLayers = 1;
|
||||
createInfo.format = format;
|
||||
createInfo.tiling = tiling;
|
||||
createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
createInfo.usage = usage;
|
||||
createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
createInfo.flags = 0;
|
||||
|
||||
CP_VK_ASSERT(vkCreateImage(instance.GetDevice(), &createInfo, nullptr, image), "InitializeImage : Failed to initialize image");
|
||||
|
||||
VkMemoryRequirements memoryRequirements;
|
||||
vkGetImageMemoryRequirements(instance.GetDevice(), *image, &memoryRequirements);
|
||||
|
||||
VkMemoryAllocateInfo allocateInfo{};
|
||||
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
allocateInfo.allocationSize = memoryRequirements.size;
|
||||
allocateInfo.memoryTypeIndex = instance.FindMemoryType(memoryRequirements.memoryTypeBits, properties);
|
||||
|
||||
CP_VK_ASSERT(vkAllocateMemory(instance.GetDevice(), &allocateInfo, nullptr, imageMemory), "InitializeImage : Failed to initiallizse image memory");
|
||||
|
||||
vkBindImageMemory(instance.GetDevice(), *image, *imageMemory, 0);
|
||||
}
|
||||
|
||||
VkImageView Image::InitializeImageView(Instance& instance, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags)
|
||||
{
|
||||
VkImageView imageView;
|
||||
VkImageViewCreateInfo createInfo{};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
createInfo.image = image;
|
||||
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
createInfo.format = format;
|
||||
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
createInfo.subresourceRange.aspectMask = aspectFlags;
|
||||
createInfo.subresourceRange.baseMipLevel = 0;
|
||||
createInfo.subresourceRange.levelCount = 1;
|
||||
createInfo.subresourceRange.baseArrayLayer = 0;
|
||||
createInfo.subresourceRange.layerCount = 1;
|
||||
CP_VK_ASSERT(vkCreateImageView(instance.GetDevice(), &createInfo, nullptr, &imageView), "InitializeImageView : Failed to initialize image view");
|
||||
return imageView;
|
||||
}
|
||||
|
||||
void Image::TransitionImageLayout(Instance& instance, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout)
|
||||
{
|
||||
CommandBufferScoped commandBuffer{instance};
|
||||
|
||||
VkImageMemoryBarrier barrier{};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.oldLayout = oldLayout;
|
||||
barrier.newLayout = newLayout;
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.image = image;
|
||||
barrier.subresourceRange.baseMipLevel = 0;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
barrier.subresourceRange.baseArrayLayer = 0;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = 0;
|
||||
|
||||
VkPipelineStageFlags srcStage;
|
||||
VkPipelineStageFlags dstStage;
|
||||
|
||||
if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
|
||||
if (HasStencilComponent(format)) {
|
||||
barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
}
|
||||
|
||||
if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
|
||||
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
}
|
||||
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
|
||||
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
}
|
||||
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||
}
|
||||
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
CP_ABORT("TransitioinImageLayout : Unsupported layout transition");
|
||||
}
|
||||
|
||||
vkCmdPipelineBarrier(commandBuffer, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
}
|
||||
|
||||
void Image::CopyBufferToImage(Instance& instance, const Buffer& buffer, VkImage image, uint32_t width, uint32_t height)
|
||||
{
|
||||
CommandBufferScoped commandBuffer{instance};
|
||||
|
||||
VkBufferImageCopy region{};
|
||||
region.bufferOffset = 0;
|
||||
region.bufferRowLength = 0;
|
||||
region.bufferImageHeight = 0;
|
||||
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.mipLevel = 0;
|
||||
region.imageSubresource.baseArrayLayer = 0;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
|
||||
region.imageOffset = {0, 0, 0};
|
||||
region.imageExtent = {width, height, 1};
|
||||
|
||||
vkCmdCopyBufferToImage(commandBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
}
|
||||
|
||||
|
||||
VkFormat Image::SelectDepthFormat(Instance& instance)
|
||||
{
|
||||
return SelectSupportedFormat(instance, {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
}
|
||||
|
||||
bool Image::HasStencilComponent(VkFormat format)
|
||||
{
|
||||
return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT;
|
||||
}
|
||||
|
||||
VkFormat Image::SelectSupportedFormat(Instance& instance, const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features)
|
||||
{
|
||||
for (VkFormat format : candidates)
|
||||
{
|
||||
VkFormatProperties properties;
|
||||
vkGetPhysicalDeviceFormatProperties(instance.GetPhysicalDevice(), format, &properties);
|
||||
if (tiling == VK_IMAGE_TILING_LINEAR && (properties.linearTilingFeatures & features) == features)
|
||||
{
|
||||
return format;
|
||||
}
|
||||
else if (tiling == VK_IMAGE_TILING_OPTIMAL && (properties.optimalTilingFeatures & features) == features)
|
||||
{
|
||||
return format;
|
||||
}
|
||||
}
|
||||
CP_ABORT("SelectSupportedFormat : Failed to select supported format");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/buffer/Buffer.h"
|
||||
#include "copium/core/Instance.h"
|
||||
#include "copium/util/Common.h"
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class Image
|
||||
{
|
||||
CP_STATIC_CLASS(Image);
|
||||
public:
|
||||
static void InitializeImage(Instance& instance, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage* image, VkDeviceMemory* imageMemory);
|
||||
static VkImageView InitializeImageView(Instance& instance, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags);
|
||||
static void TransitionImageLayout(Instance& instance, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout);
|
||||
static void CopyBufferToImage(Instance& instance, const Buffer& buffer, VkImage image, uint32_t width, uint32_t height);
|
||||
static VkFormat SelectDepthFormat(Instance& instance);
|
||||
|
||||
private:
|
||||
static bool HasStencilComponent(VkFormat format);
|
||||
static VkFormat SelectSupportedFormat(Instance& instance, const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "copium/sampler/Sampler.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
Sampler::Sampler(Instance& instance)
|
||||
: instance{instance}
|
||||
{
|
||||
InitializeSampler();
|
||||
}
|
||||
|
||||
Sampler::~Sampler()
|
||||
{
|
||||
vkDestroySampler(instance.GetDevice(), sampler, nullptr);
|
||||
}
|
||||
|
||||
void Sampler::InitializeSampler()
|
||||
{
|
||||
VkPhysicalDeviceProperties properties{};
|
||||
vkGetPhysicalDeviceProperties(instance.GetPhysicalDevice(), &properties);
|
||||
|
||||
VkSamplerCreateInfo createInfo{};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
createInfo.magFilter = VK_FILTER_LINEAR;
|
||||
createInfo.minFilter = VK_FILTER_LINEAR;
|
||||
createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
createInfo.anisotropyEnable = VK_TRUE;
|
||||
createInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
|
||||
createInfo.unnormalizedCoordinates = VK_FALSE;
|
||||
createInfo.compareEnable = VK_FALSE;
|
||||
createInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
createInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
createInfo.mipLodBias = 0.0f;
|
||||
createInfo.minLod = 0.0f;
|
||||
createInfo.maxLod = 0.0f;
|
||||
|
||||
CP_VK_ASSERT(vkCreateSampler(instance.GetDevice(), &createInfo, nullptr, &sampler), "InitializeSampler : Failed to initialize texture sampler");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/core/Instance.h"
|
||||
#include "copium/util/Common.h"
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class Sampler
|
||||
{
|
||||
CP_DELETE_COPY_AND_MOVE_CTOR(Sampler);
|
||||
protected:
|
||||
Instance& instance;
|
||||
VkSampler sampler;
|
||||
public:
|
||||
Sampler(Instance& instance);
|
||||
virtual ~Sampler();
|
||||
|
||||
virtual VkDescriptorImageInfo GetDescriptorImageInfo(int index) const = 0;
|
||||
private:
|
||||
void InitializeSampler();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "copium/sampler/Texture2D.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb/stb_image.h>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
Texture2D::Texture2D(Instance& instance, const std::string& filename)
|
||||
: Sampler{instance}
|
||||
{
|
||||
InitializeTextureImage(filename);
|
||||
}
|
||||
|
||||
Texture2D::~Texture2D()
|
||||
{
|
||||
vkDestroyImage(instance.GetDevice(), image, nullptr);
|
||||
vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
|
||||
vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
|
||||
}
|
||||
|
||||
VkDescriptorImageInfo Texture2D::GetDescriptorImageInfo(int index) const
|
||||
{
|
||||
VkDescriptorImageInfo imageInfo{};
|
||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
imageInfo.sampler = sampler;
|
||||
imageInfo.imageView = imageView;
|
||||
|
||||
return imageInfo;
|
||||
}
|
||||
|
||||
void Texture2D::InitializeTextureImage(const std::string& filename)
|
||||
{
|
||||
int texWidth;
|
||||
int texHeight;
|
||||
int texChannels;
|
||||
stbi_uc* pixels = stbi_load(filename.c_str(), &texWidth, &texHeight, &texChannels, STBI_rgb_alpha);
|
||||
|
||||
CP_ASSERT(pixels, "InitializeTextureImage : Failed to load texture image");
|
||||
|
||||
VkDeviceSize bufferSize = texWidth * texHeight * 4;
|
||||
Buffer stagingBuffer{instance, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, bufferSize, 1};
|
||||
void* data = stagingBuffer.Map();
|
||||
memcpy(data, pixels, bufferSize);
|
||||
stagingBuffer.Unmap();
|
||||
stbi_image_free(pixels);
|
||||
|
||||
Image::InitializeImage(instance, texWidth, texHeight, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory);
|
||||
Image::TransitionImageLayout(instance, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
Image::CopyBufferToImage(instance, stagingBuffer, image, texWidth, texHeight);
|
||||
Image::TransitionImageLayout(instance, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
imageView = Image::InitializeImageView(instance, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "copium/buffer/CommandBufferScoped.h"
|
||||
#include "copium/core/Instance.h"
|
||||
#include "copium/sampler/Image.h"
|
||||
#include "copium/sampler/Sampler.h"
|
||||
#include "copium/util/Common.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class Texture2D final : public Sampler
|
||||
{
|
||||
CP_DELETE_COPY_AND_MOVE_CTOR(Texture2D);
|
||||
private:
|
||||
VkImage image;
|
||||
VkDeviceMemory imageMemory;
|
||||
VkImageView imageView;
|
||||
public:
|
||||
Texture2D(Instance& instance, const std::string& filename);
|
||||
~Texture2D() override;
|
||||
|
||||
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
|
||||
private:
|
||||
void InitializeTextureImage(const std::string& filename);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user