[WIP] Texture support
This commit is contained in:
@@ -13,7 +13,7 @@
|
|||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
#define ASSIMP_AVAILABLE
|
//#define ASSIMP_AVAILABLE
|
||||||
#endif
|
#endif
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
|||||||
24
openVulkanoCpp/Scene/Texture.hpp
Normal file
24
openVulkanoCpp/Scene/Texture.hpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "UpdateFrequency.hpp"
|
||||||
|
#include "Base/ICloseable.hpp"
|
||||||
|
|
||||||
|
namespace openVulkanoCpp::Scene
|
||||||
|
{
|
||||||
|
struct Texture
|
||||||
|
{
|
||||||
|
ICloseable* renderTexture = nullptr;
|
||||||
|
void* textureBuffer;
|
||||||
|
Math::Vector3ui resolution;
|
||||||
|
size_t size;
|
||||||
|
bool updated = true;
|
||||||
|
UpdateFrequency updateFrequency = UpdateFrequency::Never;
|
||||||
|
ICloseable* vulkanTexture = nullptr;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -34,6 +34,52 @@ namespace openVulkanoCpp::Vulkan
|
|||||||
{}, nullptr, nullptr, imgMemBarrier);
|
{}, nullptr, nullptr, imgMemBarrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Image::Init(const Device* device, const vk::Extent3D& resolution)
|
||||||
|
{
|
||||||
|
this->device = device->device;
|
||||||
|
|
||||||
|
vk::ImageCreateInfo imgCreateInfo;
|
||||||
|
imgCreateInfo.imageType = vk::ImageType::e2D;
|
||||||
|
imgCreateInfo.extent = resolution;
|
||||||
|
imgCreateInfo.mipLevels = 1;
|
||||||
|
imgCreateInfo.arrayLayers = 1;
|
||||||
|
imgCreateInfo.format = vk::Format::eR8G8B8Srgb;
|
||||||
|
imgCreateInfo.tiling = vk::ImageTiling::eOptimal;
|
||||||
|
imgCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
|
||||||
|
imgCreateInfo.usage = vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled;
|
||||||
|
imgCreateInfo.sharingMode = vk::SharingMode::eExclusive;
|
||||||
|
imgCreateInfo.samples = vk::SampleCountFlagBits::e1;
|
||||||
|
|
||||||
|
vk::ImageViewCreateInfo imgViewCreateInfo;
|
||||||
|
imgViewCreateInfo.image = image;
|
||||||
|
imgViewCreateInfo.format = imgCreateInfo.format;
|
||||||
|
imgViewCreateInfo.viewType = vk::ImageViewType::e2D;
|
||||||
|
imgViewCreateInfo.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
|
||||||
|
imgViewCreateInfo.subresourceRange.baseMipLevel = 0;
|
||||||
|
imgViewCreateInfo.subresourceRange.levelCount = 1;
|
||||||
|
imgViewCreateInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
|
imgViewCreateInfo.subresourceRange.levelCount = 1;
|
||||||
|
|
||||||
|
Init(device, imgCreateInfo, imgViewCreateInfo);
|
||||||
|
CreateSampler();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::CreateSampler()
|
||||||
|
{
|
||||||
|
vk::SamplerCreateInfo samplerCreateInfo;
|
||||||
|
samplerCreateInfo.magFilter = vk::Filter::eLinear;
|
||||||
|
samplerCreateInfo.minFilter = vk::Filter::eLinear;
|
||||||
|
samplerCreateInfo.mipmapMode = vk::SamplerMipmapMode::eLinear;
|
||||||
|
samplerCreateInfo.addressModeU = vk::SamplerAddressMode::eClampToEdge;
|
||||||
|
samplerCreateInfo.addressModeV = vk::SamplerAddressMode::eClampToEdge;
|
||||||
|
samplerCreateInfo.addressModeW = vk::SamplerAddressMode::eClampToEdge;
|
||||||
|
samplerCreateInfo.borderColor = vk::BorderColor::eFloatTransparentBlack;
|
||||||
|
samplerCreateInfo.unnormalizedCoordinates = false;
|
||||||
|
samplerCreateInfo.compareEnable = false;
|
||||||
|
|
||||||
|
sampler = this->device.createSampler(samplerCreateInfo);
|
||||||
|
}
|
||||||
|
|
||||||
void Image::Close()
|
void Image::Close()
|
||||||
{
|
{
|
||||||
if(sampler)
|
if(sampler)
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ namespace openVulkanoCpp::Vulkan
|
|||||||
*/
|
*/
|
||||||
void Init(const Device* device, const vk::ImageCreateInfo& imageCreateInfo, vk::ImageViewCreateInfo imageViewCreateInfo, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal);
|
void Init(const Device* device, const vk::ImageCreateInfo& imageCreateInfo, vk::ImageViewCreateInfo imageViewCreateInfo, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal);
|
||||||
|
|
||||||
|
void Init(const Device* device, const vk::Extent3D& resolution);
|
||||||
|
|
||||||
void SetLayout(vk::CommandBuffer& cmdBuffer, vk::ImageSubresourceRange subResourceRange, vk::ImageLayout newLayout, vk::ImageLayout oldLayout = vk::ImageLayout::eUndefined) const;
|
void SetLayout(vk::CommandBuffer& cmdBuffer, vk::ImageSubresourceRange subResourceRange, vk::ImageLayout newLayout, vk::ImageLayout oldLayout = vk::ImageLayout::eUndefined) const;
|
||||||
|
|
||||||
void SetLayout(vk::CommandBuffer& cmdBuffer, vk::ImageAspectFlags aspectMask, vk::ImageLayout newLayout, vk::ImageLayout oldLayout = vk::ImageLayout::eUndefined) const
|
void SetLayout(vk::CommandBuffer& cmdBuffer, vk::ImageAspectFlags aspectMask, vk::ImageLayout newLayout, vk::ImageLayout oldLayout = vk::ImageLayout::eUndefined) const
|
||||||
@@ -45,6 +47,8 @@ namespace openVulkanoCpp::Vulkan
|
|||||||
SetLayout(cmdBuffer, vk::ImageSubresourceRange(aspectMask, 0, 1, 0, 1), newLayout, oldLayout);
|
SetLayout(cmdBuffer, vk::ImageSubresourceRange(aspectMask, 0, 1, 0, 1), newLayout, oldLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CreateSampler();
|
||||||
|
|
||||||
void Close() override;
|
void Close() override;
|
||||||
|
|
||||||
operator bool() const { return image.operator bool(); }
|
operator bool() const { return image.operator bool(); }
|
||||||
@@ -53,5 +57,7 @@ namespace openVulkanoCpp::Vulkan
|
|||||||
vk::Image GetImage() override { return image; }
|
vk::Image GetImage() override { return image; }
|
||||||
|
|
||||||
vk::ImageView GetView() override { return view; }
|
vk::ImageView GetView() override { return view; }
|
||||||
|
|
||||||
|
~Image() override { Close(); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ namespace openVulkanoCpp::Vulkan
|
|||||||
vk::PushConstantRange camPushConstantDescFrag = { vk::ShaderStageFlagBits::eFragment, camPushConstantDesc.size, camPushConstantDesc.size };
|
vk::PushConstantRange camPushConstantDescFrag = { vk::ShaderStageFlagBits::eFragment, camPushConstantDesc.size, camPushConstantDesc.size };
|
||||||
std::array<vk::PushConstantRange, 2> camPushConstantDescs = { camPushConstantDesc, camPushConstantDescFrag };
|
std::array<vk::PushConstantRange, 2> camPushConstantDescs = { camPushConstantDesc, camPushConstantDescFrag };
|
||||||
vk::DescriptorSetLayoutBinding nodeLayoutBinding = { 0, vk::DescriptorType::eUniformBufferDynamic, 1, vk::ShaderStageFlagBits::eVertex };
|
vk::DescriptorSetLayoutBinding nodeLayoutBinding = { 0, vk::DescriptorType::eUniformBufferDynamic, 1, vk::ShaderStageFlagBits::eVertex };
|
||||||
|
//vk::DescriptorSetLayoutBinding textureLayoutBinding = { 0, vk::DescriptorType::image };
|
||||||
std::array<vk::DescriptorSetLayoutBinding, 1> layoutBindings = { nodeLayoutBinding };
|
std::array<vk::DescriptorSetLayoutBinding, 1> layoutBindings = { nodeLayoutBinding };
|
||||||
vk::DescriptorSetLayoutCreateInfo dslci = { {}, layoutBindings.size(), layoutBindings.data() };
|
vk::DescriptorSetLayoutCreateInfo dslci = { {}, layoutBindings.size(), layoutBindings.data() };
|
||||||
descriptorSetLayout = device.createDescriptorSetLayout(dslci);
|
descriptorSetLayout = device.createDescriptorSetLayout(dslci);
|
||||||
|
|||||||
@@ -6,10 +6,14 @@
|
|||||||
|
|
||||||
#include "ResourceManager.hpp"
|
#include "ResourceManager.hpp"
|
||||||
#include "Scene/Vertex.hpp"
|
#include "Scene/Vertex.hpp"
|
||||||
|
#include "Scene/Geometry.hpp"
|
||||||
|
#include "Scene/Material.hpp"
|
||||||
#include "Vulkan/Context.hpp"
|
#include "Vulkan/Context.hpp"
|
||||||
#include "Vulkan/Scene/VulkanShader.hpp"
|
#include "Vulkan/Scene/VulkanShader.hpp"
|
||||||
#include "Vulkan/Scene/VulkanGeometry.hpp"
|
#include "Vulkan/Scene/VulkanGeometry.hpp"
|
||||||
#include "Vulkan/Scene/VulkanNode.hpp"
|
#include "Vulkan/Scene/VulkanNode.hpp"
|
||||||
|
#include "Vulkan/Scene/VulkanTexture.hpp"
|
||||||
|
#include "Vulkan/Image.hpp"
|
||||||
|
|
||||||
namespace openVulkanoCpp::Vulkan
|
namespace openVulkanoCpp::Vulkan
|
||||||
{
|
{
|
||||||
@@ -115,6 +119,10 @@ namespace openVulkanoCpp::Vulkan
|
|||||||
{
|
{
|
||||||
material->shader->renderShader = CreateShader(material->shader);
|
material->shader->renderShader = CreateShader(material->shader);
|
||||||
}
|
}
|
||||||
|
if (material->texture && !material->texture->renderTexture)
|
||||||
|
{
|
||||||
|
material->texture->renderTexture = PrepareTexture(material->texture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::PrepareNode(Scene::Node* node)
|
void ResourceManager::PrepareNode(Scene::Node* node)
|
||||||
@@ -159,7 +167,7 @@ namespace openVulkanoCpp::Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ManagedBuffer* buffer = CreateBuffer(size, vk::BufferUsageFlagBits::eVertexBuffer, vk::MemoryPropertyFlagBits::eHostCoherent);
|
ManagedBuffer* buffer = CreateBuffer(size, vk::BufferUsageFlagBits::eVertexBuffer, vk::MemoryPropertyFlagBits::eHostCoherent/* | vk::MemoryPropertyFlagBits::eDeviceLocal*/);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +204,17 @@ namespace openVulkanoCpp::Vulkan
|
|||||||
toFree[currentBuffer].clear();
|
toFree[currentBuffer].clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceManager::CopyDataToImage(vk::DeviceSize size, void* data, Image* image)
|
||||||
|
{
|
||||||
|
ManagedBuffer* uploadBuffer = CreateBuffer(size, vk::BufferUsageFlagBits::eTransferSrc, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible);
|
||||||
|
uploadBuffer->Copy(data, size, 0);
|
||||||
|
|
||||||
|
vk::BufferImageCopy region(0, 0, 0, { vk::ImageAspectFlagBits::eColor, 0, 0, 1 }, { 0, 0, 0 }, image->extent);
|
||||||
|
cmdBuffers[currentBuffer].copyBufferToImage(uploadBuffer->buffer, image->image, vk::ImageLayout::eTransferDstOptimal, 1, ®ion);
|
||||||
|
|
||||||
|
FreeBuffer(uploadBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
ManagedBuffer* ResourceManager::CreateDeviceOnlyBufferWithData(vk::DeviceSize size, vk::BufferUsageFlagBits usage, void* data)
|
ManagedBuffer* ResourceManager::CreateDeviceOnlyBufferWithData(vk::DeviceSize size, vk::BufferUsageFlagBits usage, void* data)
|
||||||
{
|
{
|
||||||
ManagedBuffer* target = CreateBuffer(size, usage | vk::BufferUsageFlagBits::eTransferDst, vk::MemoryPropertyFlagBits::eDeviceLocal);
|
ManagedBuffer* target = CreateBuffer(size, usage | vk::BufferUsageFlagBits::eTransferDst, vk::MemoryPropertyFlagBits::eDeviceLocal);
|
||||||
@@ -253,4 +272,14 @@ namespace openVulkanoCpp::Vulkan
|
|||||||
shaders.push_back(vkShader);
|
shaders.push_back(vkShader);
|
||||||
return vkShader;
|
return vkShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VulkanTexture* ResourceManager::PrepareTexture(Scene::Texture* texture)
|
||||||
|
{
|
||||||
|
VulkanTexture* vkTexture = new VulkanTexture();
|
||||||
|
|
||||||
|
vkTexture->Init(this, texture);
|
||||||
|
//vkTexture->
|
||||||
|
|
||||||
|
return vkTexture;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "Base/ICloseable.hpp"
|
#include "Base/ICloseable.hpp"
|
||||||
#include "IShaderOwner.hpp"
|
#include "IShaderOwner.hpp"
|
||||||
#include "ManagedResource.hpp"
|
#include "ManagedResource.hpp"
|
||||||
|
#include "Vulkan/Image.hpp"
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
@@ -20,11 +21,13 @@ namespace openVulkanoCpp
|
|||||||
class Node;
|
class Node;
|
||||||
class Geometry;
|
class Geometry;
|
||||||
class Material;
|
class Material;
|
||||||
|
class Texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Vulkan
|
namespace Vulkan
|
||||||
{
|
{
|
||||||
class VulkanGeometry;
|
class VulkanGeometry;
|
||||||
|
class VulkanTexture;
|
||||||
|
|
||||||
class ResourceManager : virtual public ICloseable, virtual public IShaderOwner
|
class ResourceManager : virtual public ICloseable, virtual public IShaderOwner
|
||||||
{
|
{
|
||||||
@@ -68,12 +71,20 @@ namespace openVulkanoCpp
|
|||||||
|
|
||||||
void PrepareNode(Scene::Node* node);
|
void PrepareNode(Scene::Node* node);
|
||||||
|
|
||||||
|
VulkanTexture* PrepareTexture(Scene::Texture* texture);
|
||||||
|
|
||||||
void RemoveShader(VulkanShader* shader) override;
|
void RemoveShader(VulkanShader* shader) override;
|
||||||
|
|
||||||
|
void CopyDataToImage(vk::DeviceSize size, void* data, openVulkanoCpp::Vulkan::Image* image);
|
||||||
|
|
||||||
ManagedBuffer* CreateSharedMemoryBuffer(size_t size);
|
ManagedBuffer* CreateSharedMemoryBuffer(size_t size);
|
||||||
|
|
||||||
void FreeBuffer(ManagedBuffer* buffer);
|
void FreeBuffer(ManagedBuffer* buffer);
|
||||||
|
|
||||||
|
[[nodiscard]] Context* GetContext() const { return context; }
|
||||||
|
|
||||||
|
[[nodiscard]] vk::Device GetDevice() const { return device; }
|
||||||
|
|
||||||
protected: // Allocation management
|
protected: // Allocation management
|
||||||
void DoFreeBuffer(ManagedBuffer* buffer);
|
void DoFreeBuffer(ManagedBuffer* buffer);
|
||||||
|
|
||||||
|
|||||||
56
openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp
Normal file
56
openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "IRecordable.hpp"
|
||||||
|
#include "Vulkan/Image.hpp"
|
||||||
|
#include "Vulkan/Context.hpp"
|
||||||
|
#include "Vulkan/Resources/ResourceManager.hpp"
|
||||||
|
#include "Scene/Texture.hpp"
|
||||||
|
|
||||||
|
namespace openVulkanoCpp::Vulkan
|
||||||
|
{
|
||||||
|
struct VulkanTexture : IRecordable, Image
|
||||||
|
{
|
||||||
|
Scene::Texture* m_texture = nullptr;
|
||||||
|
|
||||||
|
virtual void Init(ResourceManager* resManager, Scene::Texture* texture)
|
||||||
|
{
|
||||||
|
this->m_texture = texture;
|
||||||
|
Image::Init(resManager->GetContext()->device.get(), { texture->resolution.x, texture->resolution.y, texture->resolution.z });
|
||||||
|
resManager->CopyDataToImage(m_texture->size, m_texture->textureBuffer, this);
|
||||||
|
texture->updated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) override
|
||||||
|
{
|
||||||
|
//cmdBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, )
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VulkanTextureDynamic : VulkanTexture
|
||||||
|
{
|
||||||
|
uint32_t lastUpdate = -1;
|
||||||
|
ResourceManager* resourceManager;
|
||||||
|
|
||||||
|
void Init(ResourceManager* resManager, Scene::Texture* texture) override
|
||||||
|
{
|
||||||
|
resourceManager = resManager;
|
||||||
|
VulkanTexture::Init(resourceManager, texture);
|
||||||
|
lastUpdate = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) override
|
||||||
|
{
|
||||||
|
if(bufferId != lastUpdate && m_texture->updated)
|
||||||
|
{
|
||||||
|
lastUpdate = bufferId;
|
||||||
|
resourceManager->CopyDataToImage(m_texture->size, m_texture->textureBuffer, this);
|
||||||
|
m_texture->updated = false;
|
||||||
|
}
|
||||||
|
VulkanTexture::Record(cmdBuffer, bufferId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user