Add GEVulkanSkyBoxRenderer

This commit is contained in:
Benau 2022-08-21 14:09:56 +08:00
parent 5aa70333ce
commit 4f9d40f3b2
15 changed files with 487 additions and 4 deletions

View 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);
}

View 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);
}

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -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
} }

View File

@ -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);

View File

@ -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);

View File

@ -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 &&

View 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
}

View 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

View File

@ -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)
{ {

View File

@ -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

View File

@ -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