Files
RenderFramework/Src/RenderFramework/SceneRenderer.cpp
T
2025-05-13 02:24:09 +03:00

308 lines
11 KiB
C++

#include "SceneRenderer.h"
#include "GameObject.h"
#include "Transform.h"
#include "Texture.h"
SceneRenderer::SceneRenderer()
{
auto renderer = LEngine::Instance()->GetRenderer();
auto device = renderer->GetLogicalDevice();
//create samplers heap
//D3D12_DESCRIPTOR_HEAP_DESC samplers_heap_desc;
//samplers_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
//samplers_heap_desc.NodeMask = 0;
//samplers_heap_desc.NumDescriptors = 1;
//samplers_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
// HR_ASSERT(device->CreateDescriptorHeap(&samplers_heap_desc, IID_PPV_ARGS(&samplers_heap)));
//samplers_heap->SetName(L"Samplers heap");
//create texture sampler
/*D3D12_SAMPLER_DESC sampler_desc = {};
sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler_desc.MinLOD = 0;
sampler_desc.MaxLOD = D3D12_FLOAT32_MAX;
sampler_desc.MipLODBias = 0.0f;
sampler_desc.MaxAnisotropy = 1;
sampler_desc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;*/
// renderer->GetDevice()->CreateSampler(&sampler_desc, samplers_heap->GetCPUDescriptorHandleForHeapStart());
}
void SceneRenderer::RenderScene(RendererPtr renderer, ScenePtr scene, CameraPtr camera, std::shared_ptr<RenderOutput> renderScreen) {
camera->aspect = (float)renderScreen->GetWidth() / (float)renderScreen->GetHeight();
renderScreen->OnPreRender(renderer);
D3D12_VIEWPORT viewport = {};
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = (float)renderScreen->GetWidth();
viewport.Height = (float)renderScreen->GetHeight();
viewport.MinDepth = 0;
viewport.MaxDepth = 1;
D3D12_RECT scissorRect = {};
scissorRect.left = 0;
scissorRect.top = 0;
scissorRect.right = renderScreen->GetWidth();
scissorRect.bottom = renderScreen->GetHeight();
// auto commandList = renderer->BeginCommandList();
// auto rt = renderScreen->GetRenderTarget(renderScreen->GetCurrentBufferIndex());
// commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(rt.Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));
// auto rtvHandle = renderScreen->GetRenderTargetDescriptor(renderScreen->GetCurrentBufferIndex());
// auto dsvHandle = renderScreen->GetDepthStencilDescriptor(renderScreen->GetCurrentBufferIndex());
// commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
//
// const float clearColor[] = { 0.1f, 0.1f, 0.14f, 1.0f };
// commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
// commandList->ClearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 0, 0, nullptr);
//renderer->EndCommandList();
// renderer->WaitCommandsQueue();
// commandList->RSSetViewports(1, &viewport);
// commandList->RSSetScissorRects(1, &scissorRect);
std::vector<ComPtr<ID3D12RootSignature>> signatures;
std::vector<ComPtr<ID3D12PipelineState>> pso;
//draw all objects
for (auto obj : scene->objects) {
auto mr = obj->GetComponent<MeshRenderer>();
if (mr != nullptr) {
auto mesh = mr->GetMesh();
if (mesh != nullptr) {
for (uint32_t i = 0; i < mesh->GetSubmeshCount(); ++i) {
auto mat = mr->GetMaterials()[i];
auto submesh = mesh->GetSubmeshes()[i];
if (mat == nullptr || submesh == nullptr) {
continue;
}
auto& params = mat->GetParametersBlock();
//params.SetShaderResource()
//set system variables
auto tf = obj->transform->GetGlobalTransform();
auto view = camera->worldToCameraMatrix();
auto proj = camera->projectionMatrix();
params.SetValue("mWorld", transpose(tf));
params.SetValue("mView", transpose(view));
params.SetValue("mProjection", transpose(proj));
auto camPos = camera->transform()->GetGlobalPosition();
params.SetValue("cameraWorldPos", float4(camPos.x(), camPos.y(), camPos.z(), 0.0f));
mat->Apply();
//create single element ranges for constant buffers
std::vector<D3D12_ROOT_PARAMETER> root_parameters;
auto compiled_params = mat->GetCompiledParameters(ShaderType::Vs);
for(auto p : compiled_params.buffers)
{
D3D12_ROOT_DESCRIPTOR rootCBVDescriptor;
rootCBVDescriptor.RegisterSpace = 0;
rootCBVDescriptor.ShaderRegister = p.bindPoint;
D3D12_ROOT_PARAMETER root_param = {};
root_param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
root_param.Descriptor = rootCBVDescriptor;
root_parameters.push_back(root_param);
}
size_t srvParamOffset = root_parameters.size();
size_t srvParamCount = 0;
// auto srvHeapAllocator = renderer->getSrvDescriptorsAllocator();
// auto srvHeap = srvHeapAllocator->getHeap();
std::vector<D3D12_DESCRIPTOR_RANGE> srvRanges[2];
//size_t srvParamCount =
//VS + PS
for(int id = 0; id < 2; ++id){
auto shader_params = mat->GetCompiledParameters((ShaderType)id);
for(auto r : shader_params.resources){
if(r.type == D3D_SIT_TEXTURE)
{
auto param = mat->GetParametersBlock().GetParameterByName(r.name);
auto texParam = std::static_pointer_cast<ShaderTextureParameter>(param);
auto tex = texParam == nullptr ? nullptr : texParam->value;
D3D12_DESCRIPTOR_RANGE range{};
range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
range.RegisterSpace = 0;
range.NumDescriptors = 1;
range.BaseShaderRegister = r.bindPoint;
// range.OffsetInDescriptorsFromTableStart = srvHeapAllocator->getDescriptorId(tex->srvDescriptor);
srvRanges[id].push_back(range);
}
}
}
//for each shader => create root table parameter
for(size_t s = 0; s < 2; ++s)
{
auto& ranges = srvRanges[s];
if(!ranges.empty())
{
D3D12_ROOT_DESCRIPTOR_TABLE srvTable;
srvTable.NumDescriptorRanges = ranges.size();
srvTable.pDescriptorRanges = &ranges[0];
D3D12_ROOT_PARAMETER srvParameter;
srvParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
srvParameter.ShaderVisibility = ((ShaderType)s == ShaderType::Vs) ? D3D12_SHADER_VISIBILITY_VERTEX : D3D12_SHADER_VISIBILITY_PIXEL;
srvParameter.DescriptorTable = srvTable;
root_parameters.push_back(srvParameter);
srvParamCount++;
}
}
// create a static sampler
D3D12_STATIC_SAMPLER_DESC sampler = {};
sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
sampler.MipLODBias = 0;
sampler.MaxAnisotropy = 0;
sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
sampler.MinLOD = 0.0f;
sampler.MaxLOD = D3D12_FLOAT32_MAX;
sampler.ShaderRegister = 0;
sampler.RegisterSpace = 0;
sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
//create root signature
// CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
// rootSignatureDesc.Init(root_parameters.size(), // we have 1 root parameter
// &root_parameters[0], // a pointer to the beginning of our root parameters array
// 1,
// &sampler,
// D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | // we can deny shader stages here for better performance
// D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
// D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
// D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS);
ComPtr<ID3DBlob> signature;
ComPtr<ID3DBlob> signatureErrors;
// auto hr = D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &signatureErrors);
// if (FAILED(hr)) {
// FatalError(L"Failed to serialize root signature");
// }
ComPtr<ID3D12RootSignature> rootSignature;
// hr = renderer->GetDevice()->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&rootSignature));
// if (FAILED(hr)) {
// FatalError(L"Failed to create root signature");
// }
signatures.push_back(rootSignature);
//create PSO
DXGI_SAMPLE_DESC sampleDesc = {};
sampleDesc.Count = 1;
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
psoDesc.pRootSignature = rootSignature.Get();
psoDesc.InputLayout = mr->GetInputLayout();
psoDesc.VS = mat->GetShader()->GetShader(ShaderType::Vs)->get_bytecode();
psoDesc.PS = mat->GetShader()->GetShader(ShaderType::Ps)->get_bytecode();
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
psoDesc.RTVFormats[0] = DXGI_FORMAT_B8G8R8A8_UNORM;
psoDesc.SampleDesc = sampleDesc;
psoDesc.SampleMask = 0xffffffff;
// psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
// psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
// psoDesc.NumRenderTargets = 1;
// psoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);
// psoDesc.DSVFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
auto device = renderer->GetLogicalDevice();
// if (FAILED(hr)) {
// FatalError(L"Failed to create PSO");
// }
ComPtr<ID3D12PipelineState> pipelineStateObject;
// hr = device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pipelineStateObject));
pipelineStateObject->SetName(L"PSO");
pso.push_back(pipelineStateObject);
//commandList = renderer->BeginCommandList();
// commandList->SetPipelineState(pipelineStateObject.Get());
// commandList->SetGraphicsRootSignature(rootSignature.Get());
// commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// auto vbView = mesh->GetVertexBufferView();
// commandList->IASetVertexBuffers(0, 1, &vbView);
// auto ibView = submesh->GetIndexBufferView();
// commandList->IASetIndexBuffer(&ibView);
//commandList->SetGraphicsRootShaderResourceView()
// ID3D12DescriptorHeap* descriptorHeaps[] = { srvHeap.Get() };
// commandList->SetDescriptorHeaps(_countof(descriptorHeaps), descriptorHeaps);
// for (size_t p = srvParamOffset; p < srvParamOffset + srvParamCount; ++p) {
// commandList->SetGraphicsRootDescriptorTable(p, srvHeap->GetGPUDescriptorHandleForHeapStart());
// }
// //apply constant buffers
// for (size_t k = 0; k < compiled_params.buffers.size(); ++k) {
// commandList->SetGraphicsRootConstantBufferView(k, compiled_params.buffers[k].buffer->GetGPUVirtualAddress());
// }
// commandList->DrawIndexedInstanced(submesh->GetIndicesCount(), 1, 0, 0, 0);
//renderer->EndCommandList();
//renderer->WaitCommandsQueue();
}
}
}
}
//commandList = renderer->BeginCommandList();
// commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(rt.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
renderer->EndCommandList();
renderer->WaitCommandsQueue();
renderScreen->Present();
//signatures.clear();
//renderer->reportLiveObjects();
scene->GetGizmos().PrepareRender();
scene->GetGizmos().DrawAll(camera);
scene->GetGizmos().Clear();
}