Add GEVulkanSkyBoxRenderer
This commit is contained in:
parent
5aa70333ce
commit
4f9d40f3b2
7
data/shaders/ge_shaders/fullscreen_quad.vert
Normal file
7
data/shaders/ge_shaders/fullscreen_quad.vert
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
layout (location = 0) out vec2 f_uv;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
f_uv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||||
|
gl_Position = vec4(f_uv * 2.0 - 1.0, 1.0, 1.0);
|
||||||
|
}
|
18
data/shaders/ge_shaders/skybox.frag
Normal file
18
data/shaders/ge_shaders/skybox.frag
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
layout(push_constant) uniform Constants
|
||||||
|
{
|
||||||
|
mat4 m_inverse_projection_view_matrix;
|
||||||
|
} u_push_constants;
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 f_uv;
|
||||||
|
layout(binding = 0) uniform samplerCube f_skybox_texture;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 o_color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 uv = 2.0f * f_uv - 1.0f;
|
||||||
|
vec4 front = u_push_constants.m_inverse_projection_view_matrix * vec4(uv, -1.0, 1.0);
|
||||||
|
vec4 back = u_push_constants.m_inverse_projection_view_matrix * vec4(uv, 1.0, 1.0);
|
||||||
|
vec3 dir = back.xyz / back.w - front.xyz / front.w;
|
||||||
|
o_color = texture(f_skybox_texture, dir);
|
||||||
|
}
|
@ -5,6 +5,7 @@ layout(std140, set = 1, binding = 0) uniform CameraBuffer
|
|||||||
mat4 m_inverse_view_matrix;
|
mat4 m_inverse_view_matrix;
|
||||||
mat4 m_inverse_projection_matrix;
|
mat4 m_inverse_projection_matrix;
|
||||||
mat4 m_projection_view_matrix;
|
mat4 m_projection_view_matrix;
|
||||||
|
mat4 m_inverse_projection_view_matrix;
|
||||||
} u_camera;
|
} u_camera;
|
||||||
|
|
||||||
struct ObjectData
|
struct ObjectData
|
||||||
|
@ -85,6 +85,7 @@ set(GE_SOURCES
|
|||||||
src/ge_vulkan_mesh_scene_node.cpp
|
src/ge_vulkan_mesh_scene_node.cpp
|
||||||
src/ge_vulkan_scene_manager.cpp
|
src/ge_vulkan_scene_manager.cpp
|
||||||
src/ge_vulkan_shader_manager.cpp
|
src/ge_vulkan_shader_manager.cpp
|
||||||
|
src/ge_vulkan_skybox_renderer.cpp
|
||||||
src/ge_vulkan_texture.cpp
|
src/ge_vulkan_texture.cpp
|
||||||
src/ge_vulkan_texture_descriptor.cpp
|
src/ge_vulkan_texture_descriptor.cpp
|
||||||
src/ge_gl_texture.cpp
|
src/ge_gl_texture.cpp
|
||||||
|
@ -31,6 +31,7 @@ namespace GE
|
|||||||
{
|
{
|
||||||
GVS_MIN = 0,
|
GVS_MIN = 0,
|
||||||
GVS_NEAREST = GVS_MIN,
|
GVS_NEAREST = GVS_MIN,
|
||||||
|
GVS_SKYBOX,
|
||||||
GVS_3D_MESH_MIPMAP_2,
|
GVS_3D_MESH_MIPMAP_2,
|
||||||
GVS_3D_MESH_MIPMAP_4,
|
GVS_3D_MESH_MIPMAP_4,
|
||||||
GVS_3D_MESH_MIPMAP_16,
|
GVS_3D_MESH_MIPMAP_16,
|
||||||
|
@ -52,6 +52,9 @@ void GEVulkanCameraSceneNode::render()
|
|||||||
mat = m_ubo_data.m_projection_matrix * m_ubo_data.m_view_matrix;
|
mat = m_ubo_data.m_projection_matrix * m_ubo_data.m_view_matrix;
|
||||||
|
|
||||||
m_ubo_data.m_projection_view_matrix = mat;
|
m_ubo_data.m_projection_view_matrix = mat;
|
||||||
|
|
||||||
|
m_ubo_data.m_projection_view_matrix.getInverse(
|
||||||
|
m_ubo_data.m_inverse_projection_view_matrix);
|
||||||
} // render
|
} // render
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -14,6 +14,7 @@ irr::core::matrix4 m_projection_matrix;
|
|||||||
irr::core::matrix4 m_inverse_view_matrix;
|
irr::core::matrix4 m_inverse_view_matrix;
|
||||||
irr::core::matrix4 m_inverse_projection_matrix;
|
irr::core::matrix4 m_inverse_projection_matrix;
|
||||||
irr::core::matrix4 m_projection_view_matrix;
|
irr::core::matrix4 m_projection_view_matrix;
|
||||||
|
irr::core::matrix4 m_inverse_projection_view_matrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GEVulkanCameraSceneNode : public irr::scene::CCameraSceneNode
|
class GEVulkanCameraSceneNode : public irr::scene::CCameraSceneNode
|
||||||
@ -40,7 +41,7 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
irr::core::matrix4 getPVM() const;
|
irr::core::matrix4 getPVM() const;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void* getUBOData() const { return (void*)&m_ubo_data; }
|
const GEVulkanCameraUBO* const getUBOData() const { return &m_ubo_data; }
|
||||||
}; // GEVulkanCameraSceneNode
|
}; // GEVulkanCameraSceneNode
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -798,7 +798,8 @@ void GEVulkanDrawCall::uploadDynamicData(GEVulkanDriver* vk,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_data_uploading.emplace_back(cam->getUBOData(), sizeof(GEVulkanCameraUBO));
|
m_data_uploading.emplace_back((void*)cam->getUBOData(),
|
||||||
|
sizeof(GEVulkanCameraUBO));
|
||||||
object_data_uploading.insert(object_data_uploading.end(),
|
object_data_uploading.insert(object_data_uploading.end(),
|
||||||
m_data_uploading.begin(), m_data_uploading.end());
|
m_data_uploading.begin(), m_data_uploading.end());
|
||||||
std::swap(m_data_uploading, object_data_uploading);
|
std::swap(m_data_uploading, object_data_uploading);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "ge_vulkan_mesh_cache.hpp"
|
#include "ge_vulkan_mesh_cache.hpp"
|
||||||
#include "ge_vulkan_scene_manager.hpp"
|
#include "ge_vulkan_scene_manager.hpp"
|
||||||
#include "ge_vulkan_shader_manager.hpp"
|
#include "ge_vulkan_shader_manager.hpp"
|
||||||
|
#include "ge_vulkan_skybox_renderer.hpp"
|
||||||
#include "ge_vulkan_texture_descriptor.hpp"
|
#include "ge_vulkan_texture_descriptor.hpp"
|
||||||
|
|
||||||
#include "ISceneManager.h"
|
#include "ISceneManager.h"
|
||||||
@ -629,6 +630,7 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params,
|
|||||||
GE::setVideoDriver(this);
|
GE::setVideoDriver(this);
|
||||||
createUnicolorTextures();
|
createUnicolorTextures();
|
||||||
GEVulkan2dRenderer::init(this);
|
GEVulkan2dRenderer::init(this);
|
||||||
|
GEVulkanSkyBoxRenderer::init();
|
||||||
m_mesh_texture_descriptor = new GEVulkanTextureDescriptor(
|
m_mesh_texture_descriptor = new GEVulkanTextureDescriptor(
|
||||||
GEVulkanShaderManager::getSamplerSize(),
|
GEVulkanShaderManager::getSamplerSize(),
|
||||||
GEVulkanShaderManager::getMeshTextureLayer(),
|
GEVulkanShaderManager::getMeshTextureLayer(),
|
||||||
@ -680,6 +682,7 @@ void GEVulkanDriver::destroyVulkan()
|
|||||||
m_irrlicht_device->getSceneManager()->getMeshCache())
|
m_irrlicht_device->getSceneManager()->getMeshCache())
|
||||||
getVulkanMeshCache()->destroy();
|
getVulkanMeshCache()->destroy();
|
||||||
delete m_mesh_texture_descriptor;
|
delete m_mesh_texture_descriptor;
|
||||||
|
GEVulkanSkyBoxRenderer::destroy();
|
||||||
GEVulkan2dRenderer::destroy();
|
GEVulkan2dRenderer::destroy();
|
||||||
GEVulkanShaderManager::destroy();
|
GEVulkanShaderManager::destroy();
|
||||||
|
|
||||||
@ -1358,11 +1361,27 @@ void GEVulkanDriver::createSamplers()
|
|||||||
throw std::runtime_error("vkCreateSampler failed for GVS_NEAREST");
|
throw std::runtime_error("vkCreateSampler failed for GVS_NEAREST");
|
||||||
m_vk->samplers[GVS_NEAREST] = sampler;
|
m_vk->samplers[GVS_NEAREST] = sampler;
|
||||||
|
|
||||||
const float max_aniso = m_properties.limits.maxSamplerAnisotropy;
|
// GVS_SKYBOX
|
||||||
// GVS_3D_MESH_MIPMAP_2
|
sampler_info.anisotropyEnable = false;
|
||||||
sampler_info.magFilter = VK_FILTER_LINEAR;
|
sampler_info.magFilter = VK_FILTER_LINEAR;
|
||||||
sampler_info.minFilter = VK_FILTER_LINEAR;
|
sampler_info.minFilter = VK_FILTER_LINEAR;
|
||||||
sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||||
|
sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
result = vkCreateSampler(m_vk->device, &sampler_info, NULL,
|
||||||
|
&sampler);
|
||||||
|
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
throw std::runtime_error("vkCreateSampler failed for GVS_SKYBOX");
|
||||||
|
m_vk->samplers[GVS_SKYBOX] = sampler;
|
||||||
|
|
||||||
|
const float max_aniso = m_properties.limits.maxSamplerAnisotropy;
|
||||||
|
// GVS_3D_MESH_MIPMAP_2
|
||||||
|
sampler_info.anisotropyEnable = supported_anisotropy;
|
||||||
|
sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
|
sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
|
sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
sampler_info.maxAnisotropy = std::min(2.0f, max_aniso);
|
sampler_info.maxAnisotropy = std::min(2.0f, max_aniso);
|
||||||
result = vkCreateSampler(m_vk->device, &sampler_info, NULL,
|
result = vkCreateSampler(m_vk->device, &sampler_info, NULL,
|
||||||
&sampler);
|
&sampler);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "ge_vulkan_fbo_texture.hpp"
|
#include "ge_vulkan_fbo_texture.hpp"
|
||||||
#include "ge_vulkan_mesh_cache.hpp"
|
#include "ge_vulkan_mesh_cache.hpp"
|
||||||
#include "ge_vulkan_mesh_scene_node.hpp"
|
#include "ge_vulkan_mesh_scene_node.hpp"
|
||||||
|
#include "ge_vulkan_skybox_renderer.hpp"
|
||||||
#include "ge_vulkan_texture_descriptor.hpp"
|
#include "ge_vulkan_texture_descriptor.hpp"
|
||||||
|
|
||||||
#include "mini_glm.hpp"
|
#include "mini_glm.hpp"
|
||||||
@ -43,6 +44,7 @@ void GEVulkanSceneManager::clear()
|
|||||||
irr::scene::CSceneManager::clear();
|
irr::scene::CSceneManager::clear();
|
||||||
static_cast<GEVulkanDriver*>(getVideoDriver())
|
static_cast<GEVulkanDriver*>(getVideoDriver())
|
||||||
->getMeshTextureDescriptor()->clear();
|
->getMeshTextureDescriptor()->clear();
|
||||||
|
GEVulkanSkyBoxRenderer::destroy();
|
||||||
} // clear
|
} // clear
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -265,6 +267,12 @@ irr::u32 GEVulkanSceneManager::registerNodeForRendering(
|
|||||||
GEVulkanCameraSceneNode* cam = static_cast<
|
GEVulkanCameraSceneNode* cam = static_cast<
|
||||||
GEVulkanCameraSceneNode*>(getActiveCamera());
|
GEVulkanCameraSceneNode*>(getActiveCamera());
|
||||||
|
|
||||||
|
if (node->getType() == irr::scene::ESNT_SKY_BOX)
|
||||||
|
{
|
||||||
|
GEVulkanSkyBoxRenderer::addSkyBox(cam, node);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((node->getType() == irr::scene::ESNT_ANIMATED_MESH &&
|
if ((node->getType() == irr::scene::ESNT_ANIMATED_MESH &&
|
||||||
pass != irr::scene::ESNRP_SOLID) ||
|
pass != irr::scene::ESNRP_SOLID) ||
|
||||||
(node->getType() == irr::scene::ESNT_MESH &&
|
(node->getType() == irr::scene::ESNT_MESH &&
|
||||||
|
385
lib/graphics_engine/src/ge_vulkan_skybox_renderer.cpp
Normal file
385
lib/graphics_engine/src/ge_vulkan_skybox_renderer.cpp
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
#include "ge_vulkan_skybox_renderer.hpp"
|
||||||
|
|
||||||
|
#include "ge_main.hpp"
|
||||||
|
#include "ge_vma.hpp"
|
||||||
|
#include "ge_vulkan_array_texture.hpp"
|
||||||
|
#include "ge_vulkan_camera_scene_node.hpp"
|
||||||
|
#include "ge_vulkan_driver.hpp"
|
||||||
|
#include "ge_vulkan_features.hpp"
|
||||||
|
#include "ge_vulkan_fbo_texture.hpp"
|
||||||
|
#include "ge_vulkan_shader_manager.hpp"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace GE
|
||||||
|
{
|
||||||
|
namespace GEVulkanSkyBoxRenderer
|
||||||
|
{
|
||||||
|
// ============================================================================
|
||||||
|
irr::scene::ISceneNode* g_skybox = NULL;
|
||||||
|
std::unordered_map<GEVulkanCameraSceneNode*, bool> g_render_skybox;
|
||||||
|
|
||||||
|
GEVulkanArrayTexture* g_texture_cubemap = NULL;
|
||||||
|
bool g_updated_texture_descriptor = false;
|
||||||
|
|
||||||
|
VkDescriptorSetLayout g_descriptor_layout = VK_NULL_HANDLE;
|
||||||
|
VkDescriptorPool g_descriptor_pool = VK_NULL_HANDLE;
|
||||||
|
VkDescriptorSet g_descriptor_set = VK_NULL_HANDLE;
|
||||||
|
VkPipelineLayout g_pipeline_layout = VK_NULL_HANDLE;
|
||||||
|
VkPipeline g_graphics_pipeline = VK_NULL_HANDLE;
|
||||||
|
} // GEVulkanSkyBoxRenderer
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
void GEVulkanSkyBoxRenderer::init()
|
||||||
|
{
|
||||||
|
g_skybox = NULL;
|
||||||
|
g_render_skybox.clear();
|
||||||
|
g_descriptor_layout = VK_NULL_HANDLE;
|
||||||
|
g_descriptor_pool = VK_NULL_HANDLE;
|
||||||
|
g_descriptor_set = VK_NULL_HANDLE;
|
||||||
|
g_pipeline_layout = VK_NULL_HANDLE;
|
||||||
|
g_graphics_pipeline = VK_NULL_HANDLE;
|
||||||
|
g_updated_texture_descriptor = true;
|
||||||
|
} // init
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void GEVulkanSkyBoxRenderer::destroy()
|
||||||
|
{
|
||||||
|
GEVulkanDriver* vk = getVKDriver();
|
||||||
|
if (!vk)
|
||||||
|
return;
|
||||||
|
vk->waitIdle();
|
||||||
|
|
||||||
|
if (g_texture_cubemap != NULL)
|
||||||
|
{
|
||||||
|
g_texture_cubemap->drop();
|
||||||
|
g_texture_cubemap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_graphics_pipeline != VK_NULL_HANDLE)
|
||||||
|
vkDestroyPipeline(vk->getDevice(), g_graphics_pipeline, NULL);
|
||||||
|
g_graphics_pipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
if (g_pipeline_layout != VK_NULL_HANDLE)
|
||||||
|
vkDestroyPipelineLayout(vk->getDevice(), g_pipeline_layout, NULL);
|
||||||
|
g_pipeline_layout = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
if (g_descriptor_pool != VK_NULL_HANDLE)
|
||||||
|
vkDestroyDescriptorPool(vk->getDevice(), g_descriptor_pool, NULL);
|
||||||
|
g_descriptor_pool = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
if (g_descriptor_layout != VK_NULL_HANDLE)
|
||||||
|
{
|
||||||
|
vkDestroyDescriptorSetLayout(vk->getDevice(), g_descriptor_layout,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
g_descriptor_layout = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
g_descriptor_set = VK_NULL_HANDLE;
|
||||||
|
g_skybox = NULL;
|
||||||
|
g_render_skybox.clear();
|
||||||
|
g_updated_texture_descriptor = true;
|
||||||
|
} // destroy
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void GEVulkanSkyBoxRenderer::render(VkCommandBuffer cmd,
|
||||||
|
GEVulkanCameraSceneNode* cam)
|
||||||
|
{
|
||||||
|
if (g_render_skybox.find(cam) == g_render_skybox.end() ||
|
||||||
|
!g_render_skybox.at(cam))
|
||||||
|
return;
|
||||||
|
g_render_skybox.at(cam) = false;
|
||||||
|
|
||||||
|
if (!g_updated_texture_descriptor)
|
||||||
|
{
|
||||||
|
g_updated_texture_descriptor = true;
|
||||||
|
|
||||||
|
GEVulkanDriver* vk = getVKDriver();
|
||||||
|
VkDescriptorImageInfo info;
|
||||||
|
info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
info.sampler = vk->getSampler(GVS_SKYBOX);
|
||||||
|
info.imageView = (VkImageView)g_texture_cubemap->getTextureHandler();
|
||||||
|
|
||||||
|
VkWriteDescriptorSet write_descriptor_set = {};
|
||||||
|
write_descriptor_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
write_descriptor_set.dstBinding = 0;
|
||||||
|
write_descriptor_set.dstArrayElement = 0;
|
||||||
|
write_descriptor_set.descriptorType =
|
||||||
|
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
write_descriptor_set.descriptorCount = 1;
|
||||||
|
write_descriptor_set.pBufferInfo = 0;
|
||||||
|
write_descriptor_set.dstSet = g_descriptor_set;
|
||||||
|
write_descriptor_set.pImageInfo = &info;
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(vk->getDevice(), 1, &write_descriptor_set, 0,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, g_graphics_pipeline);
|
||||||
|
|
||||||
|
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
|
g_pipeline_layout, 0, 1, &g_descriptor_set, 0, NULL);
|
||||||
|
|
||||||
|
vkCmdPushConstants(cmd, g_pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0,
|
||||||
|
sizeof(irr::core::matrix4),
|
||||||
|
cam->getUBOData()->m_inverse_projection_view_matrix.pointer());
|
||||||
|
|
||||||
|
vkCmdDraw(cmd, 3, 1, 0, 0);
|
||||||
|
} // render
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void GEVulkanSkyBoxRenderer::addSkyBox(GEVulkanCameraSceneNode* cam,
|
||||||
|
irr::scene::ISceneNode* skybox)
|
||||||
|
{
|
||||||
|
if (skybox->getType() != irr::scene::ESNT_SKY_BOX)
|
||||||
|
return;
|
||||||
|
if (g_skybox == skybox)
|
||||||
|
{
|
||||||
|
g_render_skybox[cam] = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy();
|
||||||
|
std::vector<GEVulkanTexture*> sky_tex;
|
||||||
|
std::array<int, 6> order = {{ 1, 3, 4, 5, 2, 0}};
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
video::ITexture* tex = skybox->getMaterial(order[i]).getTexture(0);
|
||||||
|
if (!tex)
|
||||||
|
return;
|
||||||
|
sky_tex.push_back(static_cast<GEVulkanTexture*>(tex));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto swap_pixels = [](video::IImage* img, unsigned idx)
|
||||||
|
{
|
||||||
|
if (!(idx == 2 || idx == 3))
|
||||||
|
return;
|
||||||
|
unsigned width = img->getDimension().Width;
|
||||||
|
uint8_t* tmp = new uint8_t[width * width * 4];
|
||||||
|
uint32_t* tmp_array = (uint32_t*)tmp;
|
||||||
|
uint32_t* img_data = (uint32_t*)img->lock();
|
||||||
|
for (unsigned i = 0; i < width; i++)
|
||||||
|
{
|
||||||
|
for (unsigned j = 0; j < width; j++)
|
||||||
|
tmp_array[j * width + i] = img_data[i * width + (width - j - 1)];
|
||||||
|
}
|
||||||
|
uint8_t* u8_data = (uint8_t*)img->lock();
|
||||||
|
delete [] u8_data;
|
||||||
|
img->setMemory(tmp);
|
||||||
|
};
|
||||||
|
g_texture_cubemap = new GEVulkanArrayTexture(sky_tex,
|
||||||
|
VK_IMAGE_VIEW_TYPE_CUBE, swap_pixels);
|
||||||
|
g_updated_texture_descriptor = false;
|
||||||
|
|
||||||
|
g_skybox = skybox;
|
||||||
|
g_render_skybox[cam] = true;
|
||||||
|
GEVulkanDriver* vk = getVKDriver();
|
||||||
|
|
||||||
|
// g_descriptor_layout
|
||||||
|
VkDescriptorSetLayoutBinding texture_layout_binding;
|
||||||
|
texture_layout_binding.binding = 0;
|
||||||
|
texture_layout_binding.descriptorCount = 1;
|
||||||
|
texture_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
texture_layout_binding.pImmutableSamplers = NULL;
|
||||||
|
texture_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
|
||||||
|
VkDescriptorSetLayoutCreateInfo setinfo = {};
|
||||||
|
setinfo.flags = 0;
|
||||||
|
setinfo.pNext = NULL;
|
||||||
|
setinfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
|
setinfo.pBindings = &texture_layout_binding;
|
||||||
|
setinfo.bindingCount = 1;
|
||||||
|
if (vkCreateDescriptorSetLayout(vk->getDevice(), &setinfo,
|
||||||
|
NULL, &g_descriptor_layout) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("vkCreateDescriptorSetLayout failed for "
|
||||||
|
"addSkyBox");
|
||||||
|
}
|
||||||
|
|
||||||
|
// g_descriptor_pool
|
||||||
|
VkDescriptorPoolSize pool_size;
|
||||||
|
pool_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
pool_size.descriptorCount = 1;
|
||||||
|
|
||||||
|
VkDescriptorPoolCreateInfo pool_info = {};
|
||||||
|
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
|
pool_info.flags = 0;
|
||||||
|
pool_info.maxSets = 1;
|
||||||
|
pool_info.poolSizeCount = 1;
|
||||||
|
pool_info.pPoolSizes = &pool_size;
|
||||||
|
if (vkCreateDescriptorPool(vk->getDevice(), &pool_info, NULL,
|
||||||
|
&g_descriptor_pool) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("vkCreateDescriptorPool failed for "
|
||||||
|
"addSkyBox");
|
||||||
|
}
|
||||||
|
|
||||||
|
// g_descriptor_set
|
||||||
|
std::vector<VkDescriptorSetLayout> layouts(1, g_descriptor_layout);
|
||||||
|
|
||||||
|
VkDescriptorSetAllocateInfo alloc_info = {};
|
||||||
|
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||||
|
alloc_info.descriptorPool = g_descriptor_pool;
|
||||||
|
alloc_info.descriptorSetCount = layouts.size();
|
||||||
|
alloc_info.pSetLayouts = layouts.data();
|
||||||
|
|
||||||
|
if (vkAllocateDescriptorSets(vk->getDevice(), &alloc_info,
|
||||||
|
&g_descriptor_set) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("vkAllocateDescriptorSets failed for "
|
||||||
|
"addSkyBox");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// g_pipeline_layout
|
||||||
|
VkPipelineLayoutCreateInfo pipeline_layout_info = {};
|
||||||
|
pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
pipeline_layout_info.setLayoutCount = 1;
|
||||||
|
pipeline_layout_info.pSetLayouts = &g_descriptor_layout;
|
||||||
|
|
||||||
|
VkPushConstantRange push_constant;
|
||||||
|
push_constant.offset = 0;
|
||||||
|
push_constant.size = sizeof(irr::core::matrix4);
|
||||||
|
push_constant.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
pipeline_layout_info.pPushConstantRanges = &push_constant;
|
||||||
|
pipeline_layout_info.pushConstantRangeCount = 1;
|
||||||
|
|
||||||
|
if (vkCreatePipelineLayout(vk->getDevice(), &pipeline_layout_info,
|
||||||
|
NULL, &g_pipeline_layout) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("vkCreatePipelineLayout failed for "
|
||||||
|
"addSkyBox");
|
||||||
|
}
|
||||||
|
|
||||||
|
// g_graphics_pipeline
|
||||||
|
VkPipelineShaderStageCreateInfo vert_shader_stage_info = {};
|
||||||
|
vert_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
|
vert_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
vert_shader_stage_info.module = GEVulkanShaderManager::getShader("fullscreen_quad.vert");
|
||||||
|
vert_shader_stage_info.pName = "main";
|
||||||
|
|
||||||
|
VkPipelineShaderStageCreateInfo frag_shader_stage_info = {};
|
||||||
|
frag_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||||
|
frag_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
frag_shader_stage_info.module = GEVulkanShaderManager::getShader("skybox.frag");
|
||||||
|
frag_shader_stage_info.pName = "main";
|
||||||
|
|
||||||
|
std::array<VkPipelineShaderStageCreateInfo, 2> shader_stages =
|
||||||
|
{{
|
||||||
|
vert_shader_stage_info,
|
||||||
|
frag_shader_stage_info
|
||||||
|
}};
|
||||||
|
|
||||||
|
VkPipelineVertexInputStateCreateInfo vertex_input_info = {};
|
||||||
|
vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||||
|
vertex_input_info.vertexBindingDescriptionCount = 0;
|
||||||
|
vertex_input_info.vertexAttributeDescriptionCount = 0;
|
||||||
|
vertex_input_info.pVertexBindingDescriptions = NULL;
|
||||||
|
vertex_input_info.pVertexAttributeDescriptions = NULL;
|
||||||
|
|
||||||
|
VkPipelineInputAssemblyStateCreateInfo input_assembly = {};
|
||||||
|
input_assembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||||
|
input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||||
|
input_assembly.primitiveRestartEnable = VK_FALSE;
|
||||||
|
|
||||||
|
VkViewport viewport = {};
|
||||||
|
viewport.x = 0.0f;
|
||||||
|
viewport.y = 0.0f;
|
||||||
|
viewport.width = (float)vk->getSwapChainExtent().width;
|
||||||
|
viewport.height = (float)vk->getSwapChainExtent().height;
|
||||||
|
viewport.minDepth = 0.0f;
|
||||||
|
viewport.maxDepth = 1.0f;
|
||||||
|
|
||||||
|
VkRect2D scissor = {};
|
||||||
|
scissor.offset = {0, 0};
|
||||||
|
scissor.extent = vk->getSwapChainExtent();
|
||||||
|
|
||||||
|
VkPipelineViewportStateCreateInfo viewport_state = {};
|
||||||
|
viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||||
|
viewport_state.viewportCount = 1;
|
||||||
|
viewport_state.pViewports = &viewport;
|
||||||
|
viewport_state.scissorCount = 1;
|
||||||
|
viewport_state.pScissors = &scissor;
|
||||||
|
|
||||||
|
VkPipelineRasterizationStateCreateInfo rasterizer = {};
|
||||||
|
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||||
|
rasterizer.depthClampEnable = VK_FALSE;
|
||||||
|
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
||||||
|
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
||||||
|
rasterizer.lineWidth = 1.0f;
|
||||||
|
rasterizer.cullMode = VK_CULL_MODE_FRONT_BIT;
|
||||||
|
rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||||
|
rasterizer.depthBiasEnable = VK_FALSE;
|
||||||
|
|
||||||
|
VkPipelineMultisampleStateCreateInfo multisampling = {};
|
||||||
|
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||||
|
multisampling.sampleShadingEnable = VK_FALSE;
|
||||||
|
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
|
VkPipelineDepthStencilStateCreateInfo depth_stencil = {};
|
||||||
|
depth_stencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||||
|
depth_stencil.depthTestEnable = VK_TRUE;
|
||||||
|
depth_stencil.depthWriteEnable = VK_FALSE;
|
||||||
|
depth_stencil.depthCompareOp = VK_COMPARE_OP_EQUAL;
|
||||||
|
depth_stencil.depthBoundsTestEnable = VK_FALSE;
|
||||||
|
depth_stencil.stencilTestEnable = VK_FALSE;
|
||||||
|
|
||||||
|
VkPipelineColorBlendAttachmentState color_blend_attachment = {};
|
||||||
|
color_blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT |
|
||||||
|
VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT |
|
||||||
|
VK_COLOR_COMPONENT_A_BIT;
|
||||||
|
color_blend_attachment.blendEnable = VK_FALSE;
|
||||||
|
|
||||||
|
VkPipelineColorBlendStateCreateInfo color_blending = {};
|
||||||
|
color_blending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||||
|
color_blending.logicOpEnable = VK_FALSE;
|
||||||
|
color_blending.logicOp = VK_LOGIC_OP_COPY;
|
||||||
|
color_blending.attachmentCount = 1;
|
||||||
|
color_blending.pAttachments = &color_blend_attachment;
|
||||||
|
color_blending.blendConstants[0] = 0.0f;
|
||||||
|
color_blending.blendConstants[1] = 0.0f;
|
||||||
|
color_blending.blendConstants[2] = 0.0f;
|
||||||
|
color_blending.blendConstants[3] = 0.0f;
|
||||||
|
|
||||||
|
std::array<VkDynamicState, 2> dynamic_state =
|
||||||
|
{{
|
||||||
|
VK_DYNAMIC_STATE_SCISSOR,
|
||||||
|
VK_DYNAMIC_STATE_VIEWPORT
|
||||||
|
}};
|
||||||
|
|
||||||
|
VkPipelineDynamicStateCreateInfo dynamic_state_info = {};
|
||||||
|
dynamic_state_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||||
|
dynamic_state_info.dynamicStateCount = dynamic_state.size(),
|
||||||
|
dynamic_state_info.pDynamicStates = dynamic_state.data();
|
||||||
|
|
||||||
|
VkGraphicsPipelineCreateInfo pipeline_info = {};
|
||||||
|
pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||||
|
pipeline_info.stageCount = shader_stages.size();
|
||||||
|
pipeline_info.pStages = shader_stages.data();
|
||||||
|
pipeline_info.pVertexInputState = &vertex_input_info;
|
||||||
|
pipeline_info.pInputAssemblyState = &input_assembly;
|
||||||
|
pipeline_info.pViewportState = &viewport_state;
|
||||||
|
pipeline_info.pRasterizationState = &rasterizer;
|
||||||
|
pipeline_info.pMultisampleState = &multisampling;
|
||||||
|
pipeline_info.pDepthStencilState = &depth_stencil;
|
||||||
|
pipeline_info.pColorBlendState = &color_blending;
|
||||||
|
pipeline_info.pDynamicState = &dynamic_state_info;
|
||||||
|
pipeline_info.layout = g_pipeline_layout;
|
||||||
|
pipeline_info.renderPass = vk->getRTTTexture() ?
|
||||||
|
vk->getRTTTexture()->getRTTRenderPass() : vk->getRenderPass();
|
||||||
|
pipeline_info.subpass = 0;
|
||||||
|
pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
if (vkCreateGraphicsPipelines(vk->getDevice(), VK_NULL_HANDLE,
|
||||||
|
1, &pipeline_info, NULL, &g_graphics_pipeline) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("vkCreateGraphicsPipelines failed for "
|
||||||
|
"addSkyBox");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // addSkyBox
|
||||||
|
|
||||||
|
}
|
29
lib/graphics_engine/src/ge_vulkan_skybox_renderer.hpp
Normal file
29
lib/graphics_engine/src/ge_vulkan_skybox_renderer.hpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef HEADER_GE_VULKAN_SKYBOX_RENDERER_HPP
|
||||||
|
#define HEADER_GE_VULKAN_SKYBOX_RENDERER_HPP
|
||||||
|
|
||||||
|
#include "vulkan_wrapper.h"
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace scene { class ISceneNode; }
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace GE
|
||||||
|
{
|
||||||
|
class GEVulkanCameraSceneNode;
|
||||||
|
class GEVulkanDriver;
|
||||||
|
namespace GEVulkanSkyBoxRenderer
|
||||||
|
{
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void init();
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void destroy();
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void render(VkCommandBuffer, GEVulkanCameraSceneNode*);
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void addSkyBox(GEVulkanCameraSceneNode*, irr::scene::ISceneNode*);
|
||||||
|
}; // GEVulkanSkyBoxRenderer
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -100,6 +100,8 @@ public:
|
|||||||
|
|
||||||
virtual void setDeleteMemory(bool val) = 0;
|
virtual void setDeleteMemory(bool val) = 0;
|
||||||
|
|
||||||
|
virtual void setMemory(u8* memory) = 0;
|
||||||
|
|
||||||
//! get the amount of Bits per Pixel of the given color format
|
//! get the amount of Bits per Pixel of the given color format
|
||||||
static u32 getBitsPerPixelFromFormat(const ECOLOR_FORMAT format)
|
static u32 getBitsPerPixelFromFormat(const ECOLOR_FORMAT format)
|
||||||
{
|
{
|
||||||
|
@ -462,5 +462,10 @@ void CImage::setDeleteMemory(bool val)
|
|||||||
DeleteMemory = val;
|
DeleteMemory = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CImage::setMemory(u8* memory)
|
||||||
|
{
|
||||||
|
Data = memory;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace video
|
} // end namespace video
|
||||||
} // end namespace irr
|
} // end namespace irr
|
||||||
|
@ -105,6 +105,8 @@ public:
|
|||||||
|
|
||||||
virtual void setDeleteMemory(bool val);
|
virtual void setDeleteMemory(bool val);
|
||||||
|
|
||||||
|
virtual void setMemory(u8* memory);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! assumes format and size has been set and creates the rest
|
//! assumes format and size has been set and creates the rest
|
||||||
|
Loading…
Reference in New Issue
Block a user