verus/Verus/src/CGI/Renderer.cpp
2019-11-01 01:00:26 +03:00

187 lines
4.7 KiB
C++

#include "verus.h"
using namespace verus;
using namespace verus::CGI;
Renderer::Renderer()
{
}
Renderer::~Renderer()
{
Done();
}
PBaseRenderer Renderer::operator->()
{
VERUS_RT_ASSERT(_pBaseRenderer);
return _pBaseRenderer;
}
bool Renderer::IsLoaded()
{
return IsValidSingleton() && !!I()._pBaseRenderer;
}
void Renderer::Init(PRendererDelegate pDelegate)
{
VERUS_INIT();
VERUS_QREF_CONST_SETTINGS;
_pRendererDelegate = pDelegate;
CSZ dll = "RendererVulkan.dll";
switch (settings._gapi)
{
case 12:
{
dll = "RendererDirect3D12.dll";
VERUS_LOG_INFO("Using Direct3D 12");
}
break;
default:
VERUS_LOG_INFO("Using Vulkan");
}
BaseRendererDesc desc;
_pBaseRenderer = BaseRenderer::Load(dll, desc);
_gapi = _pBaseRenderer->GetGapi();
_commandBuffer.Init();
GeometryDesc geoDesc;
const InputElementDesc ied[] =
{
{0, offsetof(Vertex, _pos), IeType::floats, 2, IeUsage::position, 0},
InputElementDesc::End()
};
geoDesc._pInputElementDesc = ied;
const int strides[] = { sizeof(Vertex), 0 };
geoDesc._pStrides = strides;
_geoQuad.Init(geoDesc);
ShaderDesc shaderDesc;
shaderDesc._url = "[Shaders]:GenerateMips.hlsl";
_shader[S_GENERATE_MIPS].Init(shaderDesc);
_shader[S_GENERATE_MIPS]->CreateDescriptorSet(0, &_ubGenerateMips, sizeof(_ubGenerateMips), 100,
{ Sampler::linearClamp2D, Sampler::storage, Sampler::storage, Sampler::storage, Sampler::storage }, ShaderStageFlags::cs);
_shader[S_GENERATE_MIPS]->CreatePipelineLayout();
shaderDesc._url = "[Shaders]:Quad.hlsl";
_shader[S_QUAD].Init(shaderDesc);
_shader[S_QUAD]->CreateDescriptorSet(0, &_ubQuad, sizeof(_ubQuad), 100, { Sampler::linearClamp2D });
_shader[S_QUAD]->CreatePipelineLayout();
PipelineDesc pipeDesc(_shader[S_GENERATE_MIPS], "T");
_pipeGenerateMips.Init(pipeDesc);
TextureDesc texDesc;
texDesc._clearValue = Vector4(1);
texDesc._format = Format::unormD24uintS8;
texDesc._width = settings._screenSizeWidth;
texDesc._height = settings._screenSizeHeight;
_texDepthStencil.Init(texDesc);
_rpSwapChain = _pBaseRenderer->CreateRenderPass(
{ RP::Attachment("Color", Format::srgbB8G8R8A8).LoadOpClear().Layout(ImageLayout::undefined, ImageLayout::presentSrc) },
{ RP::Subpass("Sp0").Color({RP::Ref("Color", ImageLayout::colorAttachmentOptimal)}) },
{});
_rpSwapChainDepth = _pBaseRenderer->CreateRenderPass(
{
RP::Attachment("Color", Format::srgbB8G8R8A8).LoadOpClear().Layout(ImageLayout::undefined, ImageLayout::presentSrc),
RP::Attachment("Depth", Format::unormD24uintS8).LoadOpClear().Layout(ImageLayout::depthStencilAttachmentOptimal),
},
{
RP::Subpass("Sp0").Color(
{
RP::Ref("Color", ImageLayout::colorAttachmentOptimal)
}).DepthStencil(RP::Ref("Depth", ImageLayout::depthStencilAttachmentOptimal)),
},
{});
_fbSwapChain.resize(_pBaseRenderer->GetNumSwapChainBuffers());
VERUS_FOR(i, _fbSwapChain.size())
_fbSwapChain[i] = _pBaseRenderer->CreateFramebuffer(_rpSwapChain, {}, settings._screenSizeWidth, settings._screenSizeHeight, i);
_fbSwapChainDepth.resize(_pBaseRenderer->GetNumSwapChainBuffers());
VERUS_FOR(i, _fbSwapChainDepth.size())
_fbSwapChainDepth[i] = _pBaseRenderer->CreateFramebuffer(_rpSwapChainDepth, { _texDepthStencil }, settings._screenSizeWidth, settings._screenSizeHeight, i);
_ds.Init();
}
void Renderer::InitCmd()
{
const Vertex quadVerts[] =
{
glm::vec2(-1, +1), // TL.
glm::vec2(-1, -1), // BL.
glm::vec2(+1, +1), // TR.
glm::vec2(+1, -1) // BR.
};
_geoQuad->CreateVertexBuffer(VERUS_ARRAY_LENGTH(quadVerts), 0);
_geoQuad->UpdateVertexBuffer(quadVerts, 0);
}
void Renderer::Done()
{
if (_pBaseRenderer)
{
_pBaseRenderer->WaitIdle();
_ds.Done();
_texDepthStencil.Done();
_pipeGenerateMips.Done();
_shader.Done();
_geoQuad.Done();
_commandBuffer.Done();
Scene::Terrain::DoneStatic();
Scene::Mesh::DoneStatic();
_pBaseRenderer->ReleaseMe();
_pBaseRenderer = nullptr;
}
VERUS_SMART_DELETE(_pRendererDelegate);
VERUS_DONE(Renderer);
}
void Renderer::Draw()
{
if (_pRendererDelegate)
_pRendererDelegate->Renderer_OnDraw();
}
void Renderer::Present()
{
if (_pRendererDelegate)
_pRendererDelegate->Renderer_OnPresent();
_numFrames++;
VERUS_QREF_TIMER;
_fps = _fps * 0.75f + timer.GetDeltaTimeInv()*0.25f;
}
void Renderer::DrawQuad(PBaseCommandBuffer pCB)
{
if (!pCB)
pCB = &(*_commandBuffer);
pCB->BindVertexBuffers(_geoQuad);
pCB->Draw(4, 1);
}
void Renderer::OnShaderError(CSZ s)
{
throw VERUS_RUNTIME_ERROR << "Shader Error:\n" << s;
}
void Renderer::OnShaderWarning(CSZ s)
{
VERUS_LOG_WARN("Shader Warning:\n" << s);
}
float Renderer::GetWindowAspectRatio() const
{
VERUS_QREF_CONST_SETTINGS;
return static_cast<float>(settings._screenSizeWidth) / static_cast<float>(settings._screenSizeHeight);
}