Renderer: Add support for cubemaps
This commit is contained in:
@@ -29,7 +29,7 @@ namespace Nz
|
||||
break;
|
||||
|
||||
case ImageType::E2D:
|
||||
m_texture.TexStorage2D(params.mipmapLevel, format->internalFormat, params.width, params.height);
|
||||
m_texture.TexStorage2D(GL::TextureTarget::Target2D, params.mipmapLevel, format->internalFormat, params.width, params.height);
|
||||
break;
|
||||
|
||||
case ImageType::E2D_Array:
|
||||
@@ -39,6 +39,7 @@ namespace Nz
|
||||
break;
|
||||
|
||||
case ImageType::Cubemap:
|
||||
m_texture.TexStorage2D(GL::TextureTarget::Cubemap, params.mipmapLevel, format->internalFormat, params.width, params.height);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -86,7 +87,7 @@ namespace Nz
|
||||
break;
|
||||
|
||||
case ImageType::E2D:
|
||||
m_texture.TexSubImage2D(0, 0, 0, m_params.width, m_params.height, format->format, format->type, ptr);
|
||||
m_texture.TexSubImage2D(GL::TextureTarget::Target2D, 0, 0, 0, m_params.width, m_params.height, format->format, format->type, ptr);
|
||||
break;
|
||||
|
||||
case ImageType::E2D_Array:
|
||||
@@ -96,7 +97,17 @@ namespace Nz
|
||||
break;
|
||||
|
||||
case ImageType::Cubemap:
|
||||
{
|
||||
std::size_t faceSize = PixelFormatInfo::ComputeSize(m_params.pixelFormat, m_params.width, m_params.height, 1);
|
||||
const UInt8* facePtr = static_cast<const UInt8*>(ptr);
|
||||
|
||||
for (GL::TextureTarget face : { GL::TextureTarget::CubemapPositiveX, GL::TextureTarget::CubemapNegativeX, GL::TextureTarget::CubemapPositiveY, GL::TextureTarget::CubemapNegativeY, GL::TextureTarget::CubemapPositiveZ, GL::TextureTarget::CubemapNegativeZ })
|
||||
{
|
||||
m_texture.TexSubImage2D(face, 0, 0, 0, m_params.width, m_params.height, format->format, format->type, facePtr);
|
||||
facePtr += faceSize;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -71,4 +71,40 @@ namespace Nz
|
||||
std::shared_ptr<Image> image = Image::LoadFromStream(stream, params);
|
||||
return CreateFromImage(*image, params);
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> Texture::LoadArrayFromFile(const std::filesystem::path& filePath, const TextureParams& textureParams, const Vector2ui& atlasSize)
|
||||
{
|
||||
std::shared_ptr<Image> image = Image::LoadArrayFromFile(filePath, textureParams, atlasSize);
|
||||
return CreateFromImage(*image, textureParams);
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> Texture::LoadArrayFromMemory(const void* data, std::size_t size, const TextureParams& textureParams, const Vector2ui& atlasSize)
|
||||
{
|
||||
std::shared_ptr<Image> image = Image::LoadArrayFromMemory(data, size, textureParams, atlasSize);
|
||||
return CreateFromImage(*image, textureParams);
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> Texture::LoadArrayFromStream(Stream& stream, const TextureParams& textureParams, const Vector2ui& atlasSize)
|
||||
{
|
||||
std::shared_ptr<Image> image = Image::LoadArrayFromStream(stream, textureParams, atlasSize);
|
||||
return CreateFromImage(*image, textureParams);
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> Texture::LoadCubemapFromFile(const std::filesystem::path& filePath, const TextureParams& textureParams, const CubemapParams& cubemapParams)
|
||||
{
|
||||
std::shared_ptr<Image> image = Image::LoadCubemapFromFile(filePath, textureParams, cubemapParams);
|
||||
return CreateFromImage(*image, textureParams);
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> Texture::LoadCubemapFromMemory(const void* data, std::size_t size, const TextureParams& textureParams, const CubemapParams& cubemapParams)
|
||||
{
|
||||
std::shared_ptr<Image> image = Image::LoadCubemapFromMemory(data, size, textureParams, cubemapParams);
|
||||
return CreateFromImage(*image, textureParams);
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> Texture::LoadCubemapFromStream(Stream& stream, const TextureParams& textureParams, const CubemapParams& cubemapParams)
|
||||
{
|
||||
std::shared_ptr<Image> image = Image::LoadCubemapFromStream(stream, textureParams, cubemapParams);
|
||||
return CreateFromImage(*image, textureParams);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,6 +166,19 @@ namespace Nz::ShaderLang
|
||||
|
||||
return samplerType;
|
||||
}
|
||||
else if (identifier == "samplerCube")
|
||||
{
|
||||
Consume();
|
||||
|
||||
ShaderAst::SamplerType samplerType;
|
||||
samplerType.dim = ImageType::Cubemap;
|
||||
|
||||
Expect(Advance(), TokenType::LessThan); //< '<'
|
||||
samplerType.sampledType = ParsePrimitiveType();
|
||||
Expect(Advance(), TokenType::GreatherThan); //< '>'
|
||||
|
||||
return samplerType;
|
||||
}
|
||||
else if (identifier == "uniform")
|
||||
{
|
||||
Consume();
|
||||
|
||||
@@ -545,17 +545,32 @@ namespace Nz
|
||||
|
||||
auto SpirvConstantCache::BuildType(const ShaderAst::SamplerType& type) const -> TypePtr
|
||||
{
|
||||
//TODO
|
||||
auto imageType = Image{
|
||||
{}, //< qualifier
|
||||
{}, //< depth
|
||||
true, //< sampled
|
||||
SpirvDim::Dim2D, //< dim
|
||||
SpirvImageFormat::Unknown, //< format
|
||||
BuildType(ShaderAst::PrimitiveType::Float32), //< sampledType
|
||||
false, //< arrayed,
|
||||
false //< multisampled
|
||||
};
|
||||
Image imageType;
|
||||
imageType.sampled = true;
|
||||
imageType.sampledType = BuildType(type.sampledType);
|
||||
|
||||
switch (type.dim)
|
||||
{
|
||||
case ImageType::Cubemap:
|
||||
imageType.dim = SpirvDim::Cube;
|
||||
break;
|
||||
|
||||
case ImageType::E1D_Array:
|
||||
imageType.arrayed = true;
|
||||
case ImageType::E1D:
|
||||
imageType.dim = SpirvDim::Dim1D;
|
||||
break;
|
||||
|
||||
case ImageType::E2D_Array:
|
||||
imageType.arrayed = true;
|
||||
case ImageType::E2D:
|
||||
imageType.dim = SpirvDim::Dim2D;
|
||||
break;
|
||||
|
||||
case ImageType::E3D:
|
||||
imageType.dim = SpirvDim::Dim3D;
|
||||
break;
|
||||
}
|
||||
|
||||
return std::make_shared<Type>(SampledImage{ std::make_shared<Type>(imageType) });
|
||||
}
|
||||
|
||||
@@ -181,6 +181,8 @@ namespace Nz
|
||||
|
||||
for (auto&& stagePtr : pipelineInfo.shaderModules)
|
||||
{
|
||||
assert(stagePtr);
|
||||
|
||||
Nz::VulkanShaderModule& vulkanModule = *static_cast<Nz::VulkanShaderModule*>(stagePtr.get());
|
||||
for (auto& stage : vulkanModule.GetStages())
|
||||
{
|
||||
|
||||
@@ -110,6 +110,7 @@ namespace Nz
|
||||
NazaraAssert(params.height > 0, "Height must be over zero");
|
||||
|
||||
createInfoView.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
|
||||
createInfoView.subresourceRange.layerCount = 6;
|
||||
|
||||
createInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
createInfo.extent.width = params.width;
|
||||
@@ -168,6 +169,8 @@ namespace Nz
|
||||
bool VulkanTexture::Update(const void* ptr)
|
||||
{
|
||||
std::size_t textureSize = m_params.width * m_params.height * m_params.depth * PixelFormatInfo::GetBytesPerPixel(m_params.pixelFormat);
|
||||
if (m_params.type == ImageType::Cubemap)
|
||||
textureSize *= 6;
|
||||
|
||||
VkBufferCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
@@ -200,11 +203,26 @@ namespace Nz
|
||||
if (!copyCommandBuffer->Begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT))
|
||||
return false;
|
||||
|
||||
copyCommandBuffer->SetImageLayout(m_image, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
VkImageSubresourceLayers subresourceLayers = { //< FIXME
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
0, //< mipLevel
|
||||
0, //< baseArrayLayer
|
||||
(m_params.type == ImageType::Cubemap) ? 6 : 1 //< layerCount
|
||||
};
|
||||
|
||||
copyCommandBuffer->CopyBufferToImage(stagingBuffer, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, m_params.width, m_params.height, m_params.depth);
|
||||
VkImageSubresourceRange subresourceRange = { //< FIXME
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
0, //< baseMipLevel
|
||||
1, //< levelCount
|
||||
subresourceLayers.baseArrayLayer, //< baseArrayLayer
|
||||
subresourceLayers.layerCount //< layerCount
|
||||
};
|
||||
|
||||
copyCommandBuffer->SetImageLayout(m_image, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
copyCommandBuffer->SetImageLayout(m_image, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresourceRange);
|
||||
|
||||
copyCommandBuffer->CopyBufferToImage(stagingBuffer, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresourceLayers, m_params.width, m_params.height, m_params.depth);
|
||||
|
||||
copyCommandBuffer->SetImageLayout(m_image, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresourceRange);
|
||||
|
||||
if (!copyCommandBuffer->End())
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user