mirror of
https://github.com/hyblocker/OpenVR-SpaceCalibrator.git
synced 2026-10-17 16:01:37 +02:00
feat: add support for loading images
This commit is contained in:
7 files changed
+351
-1
No files matched your search
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "platform.h"
|
||||
#include <inttypes.h>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
// tell GLFW to NOT include OpenGL as it'll conflict with GLAD in the OpenGL backend
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
@@ -20,6 +22,16 @@ namespace spacecal {
|
||||
typedef uintptr_t RenderHandle_t;
|
||||
constexpr RenderHandle_t k_INVALID_RENDER_HANDLE = (RenderHandle_t)-1;
|
||||
|
||||
typedef uintptr_t TextureHandle_t;
|
||||
constexpr TextureHandle_t k_INVALID_TEXTURE_HANDLE = (TextureHandle_t)-1;
|
||||
|
||||
struct TextureData_t {
|
||||
TextureHandle_t hTexture = k_INVALID_TEXTURE_HANDLE;
|
||||
uint32_t dwWidth = 0;
|
||||
uint32_t dwHeight = 0;
|
||||
uintptr_t hInternalData = (uintptr_t)-1; // index, for vulkan
|
||||
};
|
||||
|
||||
class IRenderContext {
|
||||
public:
|
||||
virtual ~IRenderContext() = default;
|
||||
@@ -35,6 +47,10 @@ namespace spacecal {
|
||||
virtual void present(int width, int height) = 0;
|
||||
|
||||
virtual vr::Texture_t getVRTexture() = 0;
|
||||
|
||||
virtual TextureData_t loadTexture(const std::string& szFilePath) = 0;
|
||||
inline TextureData_t loadTexture(const std::filesystem::path& path) { return loadTexture(path.string()); }
|
||||
virtual void destroyTexture(TextureData_t hTexture) = 0;
|
||||
};
|
||||
|
||||
bool isGraphicsApiSupported(GraphicsBackend gfxApi);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <imgui/backends/imgui_impl_dx11.h>
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include <stb_image.h>
|
||||
|
||||
namespace spacecal {
|
||||
namespace renderer {
|
||||
@@ -223,6 +224,63 @@ namespace spacecal {
|
||||
SAFE_RELEASE(m_mainRenderTargetView);
|
||||
SAFE_RELEASE(m_pBackBuffer);
|
||||
}
|
||||
|
||||
TextureData_t Renderer_DX11::loadTexture(const std::string& szFilePath) {
|
||||
ID3D11ShaderResourceView* pSrv = nullptr;
|
||||
|
||||
int image_width, image_height, nrChannels;
|
||||
unsigned char* textureData = stbi_load(szFilePath.c_str(), &image_width, &image_height, &nrChannels, STBI_rgb_alpha);
|
||||
if (textureData) {
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Width = image_width;
|
||||
desc.Height = image_height;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
|
||||
ID3D11Texture2D* pTexture = NULL;
|
||||
D3D11_SUBRESOURCE_DATA subResource;
|
||||
subResource.pSysMem = textureData;
|
||||
subResource.SysMemPitch = desc.Width * 4;
|
||||
subResource.SysMemSlicePitch = 0;
|
||||
m_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
||||
|
||||
// Create texture view
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||
m_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &pSrv);
|
||||
SAFE_RELEASE(pTexture);
|
||||
stbi_image_free(textureData);
|
||||
} else {
|
||||
LOG_WARN("Failed to load texture from {}...", szFilePath);
|
||||
}
|
||||
|
||||
TextureHandle_t hHandle = pSrv == nullptr ? k_INVALID_TEXTURE_HANDLE : (TextureHandle_t)pSrv;
|
||||
TextureData_t data = {
|
||||
.hTexture = hHandle,
|
||||
.dwWidth = (uint32_t) image_width,
|
||||
.dwHeight = (uint32_t) image_height,
|
||||
.hInternalData = (uintptr_t)-1,
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void Renderer_DX11::destroyTexture(TextureData_t hTexture) {
|
||||
if (hTexture.hTexture != k_INVALID_TEXTURE_HANDLE) {
|
||||
ID3D11ShaderResourceView* pSrv = (ID3D11ShaderResourceView*) hTexture.hTexture;
|
||||
SAFE_RELEASE(pSrv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@ namespace spacecal {
|
||||
void present(int width, int height) override;
|
||||
|
||||
vr::Texture_t getVRTexture() override;
|
||||
|
||||
TextureData_t loadTexture(const std::string& szFilePath) override;
|
||||
void destroyTexture(TextureData_t hTexture) override;
|
||||
private:
|
||||
IDXGIAdapter* get_dxgi_adapter_by_index_or_luid(int32_t adapterIndex, uint64_t dwLuid);
|
||||
bool create_d3d_device(HWND hWnd);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <imgui/backends/imgui_impl_opengl3.h>
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include <stb_image.h>
|
||||
|
||||
namespace spacecal {
|
||||
namespace renderer {
|
||||
@@ -122,5 +123,42 @@ namespace spacecal {
|
||||
};
|
||||
return vrTexture;
|
||||
}
|
||||
|
||||
TextureData_t Renderer_OpenGL::loadTexture(const std::string& szFilePath) {
|
||||
GLuint hGlTexture = 0;
|
||||
glGenTextures(1, &hGlTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, hGlTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
int width, height, nrChannels;
|
||||
unsigned char* textureData = stbi_load(szFilePath.c_str(), &width, &height, &nrChannels, STBI_rgb_alpha);
|
||||
if (textureData) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
stbi_image_free(textureData);
|
||||
} else {
|
||||
LOG_WARN("OpenGL Failed to load texture from {}...", szFilePath);
|
||||
glDeleteTextures(1, &hGlTexture);
|
||||
hGlTexture = 0;
|
||||
}
|
||||
TextureHandle_t hHandle = hGlTexture == 0 ? k_INVALID_TEXTURE_HANDLE : (TextureHandle_t)hGlTexture;
|
||||
TextureData_t data = {
|
||||
.hTexture = hHandle,
|
||||
.dwWidth = (uint32_t) width,
|
||||
.dwHeight = (uint32_t)height,
|
||||
.hInternalData = (uintptr_t)-1,
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void Renderer_OpenGL::destroyTexture(TextureData_t hTexture) {
|
||||
if (hTexture.hTexture != k_INVALID_TEXTURE_HANDLE) {
|
||||
GLuint hGlTexture = (GLuint) hTexture.hTexture;
|
||||
glDeleteTextures(1, &hGlTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,9 @@ namespace spacecal {
|
||||
void present(int width, int height) override;
|
||||
|
||||
vr::Texture_t getVRTexture() override;
|
||||
|
||||
TextureData_t loadTexture(const std::string& szFilePath) override;
|
||||
void destroyTexture(TextureData_t hTexture) override;
|
||||
private:
|
||||
GLFWwindow* m_window = nullptr;
|
||||
GLuint m_fboHandle = 0;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <volk.h>
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include <stb_image.h>
|
||||
|
||||
namespace spacecal {
|
||||
namespace renderer {
|
||||
@@ -156,7 +157,8 @@ namespace spacecal {
|
||||
instance_extensions.push_back(openvr_instance_extensions[i].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_loadedTextureData.reserve(64);
|
||||
return setupVulkan(instance_extensions);
|
||||
}
|
||||
|
||||
@@ -537,5 +539,219 @@ namespace spacecal {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t Renderer_Vulkan::findMemoryType(uint32_t type_filter, VkMemoryPropertyFlags properties) {
|
||||
VkPhysicalDeviceMemoryProperties mem_properties;
|
||||
vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &mem_properties);
|
||||
|
||||
for (uint32_t i = 0; i < mem_properties.memoryTypeCount; i++)
|
||||
if ((type_filter & (1 << i)) && (mem_properties.memoryTypes[i].propertyFlags & properties) == properties)
|
||||
return i;
|
||||
|
||||
return 0xFFFFFFFF; // Unable to find memoryType
|
||||
}
|
||||
|
||||
TextureData_t Renderer_Vulkan::loadTexture(const std::string& szFilePath) {
|
||||
int width, height, nrChannels;
|
||||
uintptr_t dwInternalDataIdx = (uintptr_t) -1;
|
||||
VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
|
||||
|
||||
unsigned char* textureData = stbi_load(szFilePath.c_str(), &width, &height, &nrChannels, STBI_rgb_alpha);
|
||||
if (textureData) {
|
||||
size_t image_size = width * height * nrChannels;
|
||||
VkResult err;
|
||||
|
||||
VkTextureData_t tex_data = {};
|
||||
|
||||
// Create the Vulkan image.
|
||||
{
|
||||
VkImageCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
info.imageType = VK_IMAGE_TYPE_2D;
|
||||
info.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
info.extent.width = width;
|
||||
info.extent.height = height;
|
||||
info.extent.depth = 1;
|
||||
info.mipLevels = 1;
|
||||
info.arrayLayers = 1;
|
||||
info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
info.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
err = vkCreateImage(m_device, &info, m_allocator, &tex_data.Image);
|
||||
check_vk_result(err);
|
||||
VkMemoryRequirements req;
|
||||
vkGetImageMemoryRequirements(m_device, tex_data.Image, &req);
|
||||
VkMemoryAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
alloc_info.allocationSize = req.size;
|
||||
alloc_info.memoryTypeIndex = findMemoryType(req.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
err = vkAllocateMemory(m_device, &alloc_info, m_allocator, &tex_data.ImageMemory);
|
||||
check_vk_result(err);
|
||||
err = vkBindImageMemory(m_device, tex_data.Image, tex_data.ImageMemory, 0);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
// Create the Image View
|
||||
{
|
||||
VkImageViewCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
info.image = tex_data.Image;
|
||||
info.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
info.format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||
info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
info.subresourceRange.levelCount = 1;
|
||||
info.subresourceRange.layerCount = 1;
|
||||
err = vkCreateImageView(m_device, &info, m_allocator, &tex_data.ImageView);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
// Create Image View Descriptor Set
|
||||
// (note: before 1.92.8 this also took a Sampler. See Wiki history)
|
||||
descriptorSet = ImGui_ImplVulkan_AddTexture(tex_data.ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
// Create Upload Buffer
|
||||
{
|
||||
VkBufferCreateInfo buffer_info = {};
|
||||
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
buffer_info.size = image_size;
|
||||
buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
err = vkCreateBuffer(m_device, &buffer_info, m_allocator, &tex_data.UploadBuffer);
|
||||
check_vk_result(err);
|
||||
VkMemoryRequirements req;
|
||||
vkGetBufferMemoryRequirements(m_device, tex_data.UploadBuffer, &req);
|
||||
VkMemoryAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
alloc_info.allocationSize = req.size;
|
||||
alloc_info.memoryTypeIndex = findMemoryType(req.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||
err = vkAllocateMemory(m_device, &alloc_info, m_allocator, &tex_data.UploadBufferMemory);
|
||||
check_vk_result(err);
|
||||
err = vkBindBufferMemory(m_device, tex_data.UploadBuffer, tex_data.UploadBufferMemory, 0);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
// Upload to Buffer:
|
||||
{
|
||||
void* map = NULL;
|
||||
err = vkMapMemory(m_device, tex_data.UploadBufferMemory, 0, image_size, 0, &map);
|
||||
check_vk_result(err);
|
||||
memcpy(map, textureData, image_size);
|
||||
VkMappedMemoryRange range[1] = {};
|
||||
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||
range[0].memory = tex_data.UploadBufferMemory;
|
||||
range[0].size = image_size;
|
||||
err = vkFlushMappedMemoryRanges(m_device, 1, range);
|
||||
check_vk_result(err);
|
||||
vkUnmapMemory(m_device, tex_data.UploadBufferMemory);
|
||||
}
|
||||
|
||||
// Release image memory using stb
|
||||
stbi_image_free(textureData);
|
||||
|
||||
// Create a command buffer that will perform following steps when hit in the command queue.
|
||||
// TODO: this works in the example, but may need input if this is an acceptable way to access the pool/create the command buffer.
|
||||
VkCommandPool command_pool = m_mainWindowData.Frames[m_mainWindowData.FrameIndex].CommandPool;
|
||||
VkCommandBuffer command_buffer;
|
||||
{
|
||||
VkCommandBufferAllocateInfo alloc_info{};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
alloc_info.commandPool = command_pool;
|
||||
alloc_info.commandBufferCount = 1;
|
||||
|
||||
err = vkAllocateCommandBuffers(m_device, &alloc_info, &command_buffer);
|
||||
check_vk_result(err);
|
||||
|
||||
VkCommandBufferBeginInfo begin_info = {};
|
||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
err = vkBeginCommandBuffer(command_buffer, &begin_info);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
// Copy to Image
|
||||
{
|
||||
VkImageMemoryBarrier copy_barrier[1] = {};
|
||||
copy_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
copy_barrier[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
copy_barrier[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
copy_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
copy_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
copy_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
copy_barrier[0].image = tex_data.Image;
|
||||
copy_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
copy_barrier[0].subresourceRange.levelCount = 1;
|
||||
copy_barrier[0].subresourceRange.layerCount = 1;
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, copy_barrier);
|
||||
|
||||
VkBufferImageCopy region = {};
|
||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.imageSubresource.layerCount = 1;
|
||||
region.imageExtent.width = width;
|
||||
region.imageExtent.height = height;
|
||||
region.imageExtent.depth = 1;
|
||||
vkCmdCopyBufferToImage(command_buffer, tex_data.UploadBuffer, tex_data.Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
VkImageMemoryBarrier use_barrier[1] = {};
|
||||
use_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
use_barrier[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
use_barrier[0].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
use_barrier[0].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
use_barrier[0].newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
use_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
use_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
use_barrier[0].image = tex_data.Image;
|
||||
use_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
use_barrier[0].subresourceRange.levelCount = 1;
|
||||
use_barrier[0].subresourceRange.layerCount = 1;
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, use_barrier);
|
||||
}
|
||||
|
||||
// End command buffer
|
||||
{
|
||||
VkSubmitInfo end_info = {};
|
||||
end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
end_info.commandBufferCount = 1;
|
||||
end_info.pCommandBuffers = &command_buffer;
|
||||
err = vkEndCommandBuffer(command_buffer);
|
||||
check_vk_result(err);
|
||||
err = vkQueueSubmit(m_queue, 1, &end_info, VK_NULL_HANDLE);
|
||||
check_vk_result(err);
|
||||
err = vkDeviceWaitIdle(m_device);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
dwInternalDataIdx = m_loadedTextureData.size();
|
||||
m_loadedTextureData.push_back(tex_data);
|
||||
} else {
|
||||
LOG_WARN("Failed to load texture from {}...", szFilePath);
|
||||
}
|
||||
|
||||
TextureData_t data = {
|
||||
.hTexture = descriptorSet == VK_NULL_HANDLE ? k_INVALID_TEXTURE_HANDLE : (TextureHandle_t) descriptorSet,
|
||||
.dwWidth = (uint32_t)width,
|
||||
.dwHeight = (uint32_t)height,
|
||||
.hInternalData = dwInternalDataIdx,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
void Renderer_Vulkan::destroyTexture(TextureData_t hTexture) {
|
||||
if (hTexture.hInternalData != (uintptr_t) -1) {
|
||||
VkTextureData_t& tex_data = m_loadedTextureData[hTexture.hInternalData];
|
||||
|
||||
vkFreeMemory(m_device, tex_data.UploadBufferMemory, nullptr);
|
||||
vkDestroyBuffer(m_device, tex_data.UploadBuffer, nullptr);
|
||||
vkDestroyImageView(m_device, tex_data.ImageView, nullptr);
|
||||
vkDestroyImage(m_device, tex_data.Image, nullptr);
|
||||
vkFreeMemory(m_device, tex_data.ImageMemory, nullptr);
|
||||
}
|
||||
if (hTexture.hTexture != k_INVALID_TEXTURE_HANDLE) {
|
||||
VkDescriptorSet descriptorSet = (VkDescriptorSet)hTexture.hTexture;
|
||||
ImGui_ImplVulkan_RemoveTexture(descriptorSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,11 +25,15 @@ namespace spacecal {
|
||||
void present(int width, int height) override;
|
||||
|
||||
vr::Texture_t getVRTexture() override;
|
||||
|
||||
TextureData_t loadTexture(const std::string& szFilePath) override;
|
||||
void destroyTexture(TextureData_t hTexture) override;
|
||||
|
||||
private:
|
||||
bool setupVulkan(ImVector<const char*> instance_extensions);
|
||||
bool getOpenvrVulkanInstanceExtensionsRequired(std::vector<std::string>& outInstanceExtensionList);
|
||||
bool getOpenvrVulkanDeviceExtensionsRequired(VkPhysicalDevice pPhysicalDevice, std::vector<std::string>& outDeviceExtensionList);
|
||||
uint32_t findMemoryType(uint32_t type_filter, VkMemoryPropertyFlags properties);
|
||||
private:
|
||||
GLFWwindow* m_window = nullptr;
|
||||
int m_width = 0;
|
||||
@@ -50,6 +54,18 @@ namespace spacecal {
|
||||
bool m_swapChainRebuild = false;
|
||||
|
||||
vr::VRVulkanTextureData_t m_vrTextureData = {};
|
||||
|
||||
// auxiliary data
|
||||
struct VkTextureData_t {
|
||||
// VkDescriptorSet DS; --> this is TextureHandle_t
|
||||
VkImageView ImageView = VK_NULL_HANDLE;
|
||||
VkImage Image = VK_NULL_HANDLE;
|
||||
VkDeviceMemory ImageMemory = VK_NULL_HANDLE;
|
||||
VkBuffer UploadBuffer = VK_NULL_HANDLE;
|
||||
VkDeviceMemory UploadBufferMemory = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
std::vector<VkTextureData_t> m_loadedTextureData;
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user