Skip to content

Commit

Permalink
Feat [Renderer]: 3D Rendering.
Browse files Browse the repository at this point in the history
Added:
Added depth buffer and depth state.
Added rasterizer state.
Added Renderer::DrawIndexed method to draw models with an index buffer.
Added Renderer::BindIndexBuffer method to bind an index buffer.

Modified:
Made the pixel shader output the color instead of the texture.
  • Loading branch information
Pixfri committed Dec 23, 2024
1 parent cd671ec commit 3d05b1a
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 19 deletions.
3 changes: 2 additions & 1 deletion Include/FlashlightEngine/EngineApplication.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ namespace FlashlightEngine {

private:
ShaderCollection m_MainShaderCollection;
std::unique_ptr<Buffer> m_TriangleVertexBuffer;
std::unique_ptr<Buffer> m_CubeVertexBuffer;
std::unique_ptr<Buffer> m_CubeIndexBuffer;

std::shared_ptr<Sampler> m_LinearSampler;
std::unique_ptr<Texture> m_FrogTexture;
Expand Down
5 changes: 5 additions & 0 deletions Include/FlashlightEngine/Renderer/Enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ namespace FlashlightEngine {
HullShader,
DomainShader
};

enum class IndexType {
UInt16,
UInt32
};
}

#endif // FL_RENDERER_ENUMS_HPP
7 changes: 7 additions & 0 deletions Include/FlashlightEngine/Renderer/Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ namespace FlashlightEngine {
VertexType vertexType,
const std::vector<UInt32>& offsets,
UInt32 startSlot = 0) const;
void BindIndexBuffer(ID3D11Buffer* buffer, IndexType indexType) const;
void BindConstantBuffers(const std::vector<ID3D11Buffer*>& buffers,
PipelineBindPoint bindPoint,
UInt32 startSlot = 0) const;
void SetPrimitiveTopology(PrimitiveTopology topology) const;
void Draw(UInt32 vertexCount, UInt32 firstVertex = 0) const;
void DrawIndexed(UInt32 indexCount, UInt32 firstIndex = 0, UInt32 baseVertex = 0) const;

[[nodiscard]] ShaderCollection CreateShaderCollection(VertexType vertexType,
const std::filesystem::path& vertexShaderPath,
Expand Down Expand Up @@ -82,7 +84,12 @@ namespace FlashlightEngine {
std::shared_ptr<Device> m_Device;
std::shared_ptr<Swapchain> m_Swapchain;

ComPtr<ID3D11DepthStencilState> m_DepthStencilState;
ComPtr<ID3D11RasterizerState> m_RasterizerState;

Float32 m_ClearColor[4] = {0.1f, 0.1f, 0.1f, 0.1f};

void CreateDepthStencilState();
};
}

Expand Down
2 changes: 2 additions & 0 deletions Include/FlashlightEngine/Renderer/Swapchain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace FlashlightEngine {

[[nodiscard]] inline ComPtr<IDXGISwapChain1> GetSwapchain() const;
[[nodiscard]] inline ComPtr<ID3D11RenderTargetView> GetRTV() const;
[[nodiscard]] inline ComPtr<ID3D11DepthStencilView> GetDSV() const;

void OnResize(UInt32 width, UInt32 height);

Expand All @@ -35,6 +36,7 @@ namespace FlashlightEngine {
private:
ComPtr<IDXGISwapChain1> m_Swapchain{nullptr};
ComPtr<ID3D11RenderTargetView> m_RenderTargetView{nullptr};
ComPtr<ID3D11DepthStencilView> m_DepthStencilView{nullptr};

std::shared_ptr<Window> m_Window{nullptr};
std::shared_ptr<Device> m_Device{nullptr};
Expand Down
4 changes: 4 additions & 0 deletions Include/FlashlightEngine/Renderer/Swapchain.inl
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ namespace FlashlightEngine {
inline ComPtr<ID3D11RenderTargetView> Swapchain::GetRTV() const {
return m_RenderTargetView;
}

inline ComPtr<ID3D11DepthStencilView> Swapchain::GetDSV() const {
return m_DepthStencilView;
}
}
5 changes: 2 additions & 3 deletions Resources/Shaders/Main.ps.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ struct VSOutput
float2 Uv: TEXCOORD0;
};

sampler Sampler : register(s0);
SamplerState Sampler : register(s0);

Texture2D Texture : register(t0);

float4 Main(VSOutput input): SV_Target
{
float4 texel = Texture.Sample(Sampler, input.Uv);
return float4(input.Color, 0.50f) * texel;
return input.Color.xyzz;
}
59 changes: 46 additions & 13 deletions Source/FlashlightEngine/EngineApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,52 @@ namespace FlashlightEngine {
);

constexpr VertexPositionColorUv vertices[] = {
{Position{0.0f, 0.5f, 0.0f}, Color{0.25f, 0.39f, 0.19f}, Uv{0.5f, 0.0f}},
{Position{0.5f, -0.5f, 0.0f}, Color{0.44f, 0.75f, 0.35f}, Uv{1.0f, 1.0f}},
{Position{-0.5f, -0.5f, 0.0f}, Color{0.38f, 0.55f, 0.20f}, Uv{0.0f, 1.0f}},
//Front
{Position{-0.5f, -0.5f, 0.5f}, Color{1.0f, 0.0f, 0.0f}, Uv{0.0f, 1.0f}},
{Position{0.5f, -0.5f, 0.5f}, Color{0.0f, 1.0f, 0.0f}, Uv{1.0f, 1.0f}},
{Position{-0.5f, 0.5f, 0.5f}, Color{0.0f, 0.0f, 1.0f}, Uv{0.0f, 0.0f}},
{Position{0.5f, 0.5f, 0.5f}, Color{1.0f, 1.0f, 0.0f}, Uv{1.0f, 0.0f}},

//Back
{Position{-0.5f, -0.5f, -0.5f}, Color{0.0f, 1.0f, 1.0f}, Uv{0.0f, 1.0f}},
{Position{0.5f, -0.5f, -0.5f}, Color{1.0f, 0.0f, 1.0f}, Uv{1.0f, 1.0f}},
{Position{-0.5f, 0.5f, -0.5f}, Color{0.0f, 0.0f, 0.0f}, Uv{0.0f, 0.0f}},
{Position{0.5f, 0.5f, -0.5f}, Color{1.0f, 1.0f, 1.0f}, Uv{1.0f, 0.0f}},
};

// RGB triangle
//constexpr VertexPositionColorUv vertices[] = {
// {Position{0.0f, 0.5f, 0.0f}, Color{1.0f, 0.0f, 0.0f}, Uv{0.5f, 0.0f}},
// {Position{0.5f, -0.5f, 0.0f}, Color{0.0f, 1.0f, 0.0f}, Uv{1.0f, 1.0f}},
// {Position{-0.5f, -0.5f, 0.0f}, Color{0.0f, 0.0f, 1.0f}, Uv{0.0f, 1.0f}},
//};
constexpr uint32_t indices[] =
{
//Top
7, 6, 2,
2, 3, 7,

//Bottom
0, 4, 5,
5, 1, 0,

//Left
0, 2, 6,
6, 4, 0,

//Right
7, 3, 1,
1, 5, 7,

//Front
3, 2, 0,
0, 1, 3,

//Back
4, 6, 7,
7, 5, 4
};

m_CubeVertexBuffer = m_Renderer->CreateBuffer(vertices, sizeof(vertices), D3D11_USAGE_IMMUTABLE,
D3D11_BIND_VERTEX_BUFFER, "Cube Vertex Buffer");

m_CubeIndexBuffer = m_Renderer->CreateBuffer(indices, sizeof(indices), D3D11_USAGE_IMMUTABLE,
D3D11_BIND_INDEX_BUFFER, "Cube Index Buffer");

m_TriangleVertexBuffer = m_Renderer->CreateBuffer(vertices, sizeof(vertices), D3D11_USAGE_IMMUTABLE,
D3D11_BIND_VERTEX_BUFFER, "Triangle Vertex Buffer");

m_PerFrameConstantBuffer = m_Renderer->CreateEmptyBuffer(sizeof(PerFrameConstantBuffer),
D3D11_USAGE_DYNAMIC,
Expand Down Expand Up @@ -111,7 +143,8 @@ namespace FlashlightEngine {

m_Renderer->UseShaderCollection(m_MainShaderCollection);

m_Renderer->BindVertexBuffers({m_TriangleVertexBuffer->GetBuffer().Get()}, VertexType::PositionColorUv, {0});
m_Renderer->BindVertexBuffers({m_CubeVertexBuffer->GetBuffer().Get()}, VertexType::PositionColorUv, {0});
m_Renderer->BindIndexBuffer(m_CubeIndexBuffer->GetBuffer().Get(), IndexType::UInt32);
m_Renderer->BindConstantBuffers({
m_PerFrameConstantBuffer->GetBuffer().Get(),
m_PerObjectConstantBuffer->GetBuffer().Get()
Expand All @@ -126,7 +159,7 @@ namespace FlashlightEngine {
m_FallbackTexture->UseTexture(0, PipelineBindPoint::PixelShader);
}

m_Renderer->Draw(3);
m_Renderer->DrawIndexed(36);

m_Renderer->EndFrame();
}
Expand Down
65 changes: 64 additions & 1 deletion Source/FlashlightEngine/Renderer/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@ namespace FlashlightEngine {

// Set the default primitive topology to be a triangle list.
SetPrimitiveTopology(PrimitiveTopology::TriangleList);

D3D11_RASTERIZER_DESC rasterizerDesc{};
rasterizerDesc.CullMode = D3D11_CULL_NONE;
rasterizerDesc.FillMode = D3D11_FILL_SOLID;

HRESULT hr = m_Device->GetDevice()->CreateRasterizerState(&rasterizerDesc, m_RasterizerState.GetAddressOf());
if (FAILED(hr)) {
spdlog::error("[DirectX] Failed to create rasterizer state. Error: {}", HResultToString(hr));
}

#if defined(FL_DEBUG) || defined(FL_FORCE_DX_DEBUG_INTERFACE)
hr = m_RasterizerState->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("Rasterizer State") - 1,
"Rasterizer State");

if (FAILED(hr)) {
spdlog::error("[DirectX] Failed to set name for rasterizer state. Error: {}", HResultToString(hr));
}
#endif

CreateDepthStencilState();
}

void Renderer::OnResize(const UInt32 width, const UInt32 height) const {
Expand All @@ -34,8 +54,12 @@ namespace FlashlightEngine {
viewport.MaxDepth = 1.0f;

deviceContext->ClearRenderTargetView(m_Swapchain->GetRTV().Get(), m_ClearColor);
deviceContext->ClearDepthStencilView(m_Swapchain->GetDSV().Get(), D3D11_CLEAR_DEPTH, 1.0f, 0);

deviceContext->RSSetViewports(1, &viewport);
deviceContext->OMSetRenderTargets(1, m_Swapchain->GetRTV().GetAddressOf(), nullptr);
deviceContext->OMSetRenderTargets(1, m_Swapchain->GetRTV().GetAddressOf(), m_Swapchain->GetDSV().Get());
deviceContext->OMSetDepthStencilState(m_DepthStencilState.Get(), 0);
deviceContext->RSSetState(m_RasterizerState.Get());
}

void Renderer::EndFrame() const {
Expand All @@ -61,6 +85,21 @@ namespace FlashlightEngine {
&stride, offsets.data());
}

void Renderer::BindIndexBuffer(ID3D11Buffer* buffer, const IndexType indexType) const {
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
switch (indexType) {
case IndexType::UInt16:
format = DXGI_FORMAT_R16_UINT;
break;
case IndexType::UInt32:
format = DXGI_FORMAT_R32_UINT;
break;
}

m_Device->GetDeviceContext()->IASetIndexBuffer(buffer, format, 0);
}


void Renderer::BindConstantBuffers(const std::vector<ID3D11Buffer*>& buffers,
const PipelineBindPoint bindPoint,
const UInt32 startSlot) const {
Expand Down Expand Up @@ -93,6 +132,10 @@ namespace FlashlightEngine {
m_Device->GetDeviceContext()->Draw(vertexCount, firstVertex);
}

void Renderer::DrawIndexed(const UInt32 indexCount, const UInt32 firstIndex, const UInt32 baseVertex) const {
m_Device->GetDeviceContext()->DrawIndexed(indexCount, firstIndex, baseVertex);
}

ShaderCollection Renderer::CreateShaderCollection(const VertexType vertexType,
const std::filesystem::path& vertexShaderPath,
const std::filesystem::path& pixelShaderPath,
Expand Down Expand Up @@ -141,4 +184,24 @@ namespace FlashlightEngine {
const std::string_view name) const {
return std::make_unique<Texture>(path, name, m_Device);
}

void Renderer::CreateDepthStencilState() {

D3D11_DEPTH_STENCIL_DESC depthStencilDesc{};
depthStencilDesc.DepthEnable = true;
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
HRESULT hr = m_Device->GetDevice()->CreateDepthStencilState(&depthStencilDesc, m_DepthStencilState.GetAddressOf());
if (FAILED(hr)) {
spdlog::error("[DirectX] Failed to create depth stencil state. Error: {}", HResultToString(hr));
}

#if defined(FL_DEBUG) || defined(FL_FORCE_DX_DEBUG_INTERFACE)
hr = m_DepthStencilState->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("Depth Stencil State") - 1,
"Depth Stencil State");
if (FAILED(hr)) {
spdlog::error("[DirectX] Failed to set name for depth stencil state. Error: {}", HResultToString(hr));
}
#endif
}
}
37 changes: 37 additions & 0 deletions Source/FlashlightEngine/Renderer/Swapchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,30 @@ namespace FlashlightEngine {
return false;
}

D3D11_TEXTURE2D_DESC texDesc{};
texDesc.Width = m_Window->GetWidth();
texDesc.Height = m_Window->GetHeight();
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.SampleDesc.Count = 1;
texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
texDesc.Format = DXGI_FORMAT_R32_TYPELESS;

ID3D11Texture2D* depthTexture = nullptr;
hr = m_Device->GetDevice()->CreateTexture2D(&texDesc, nullptr, &depthTexture);
if (FAILED(hr)) {
spdlog::error("[DirectX] Failed to create depth buffer texture. Error: {}", HResultToString(hr));
}

D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc{};
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT;
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;

hr = m_Device->GetDevice()->CreateDepthStencilView(depthTexture, &dsvDesc, m_DepthStencilView.GetAddressOf());
if (FAILED(hr)) {
spdlog::error("[DirectX] Failed to create depth stencil view. Error: {}", HResultToString(hr));
}

#if defined(FL_DEBUG) || defined(FL_FORCE_DX_DEBUG_INTERFACE)
hr = backBuffer->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("Swapchain backbuffer"), "Swapchain backbuffer");

Expand All @@ -128,6 +152,18 @@ namespace FlashlightEngine {
if (FAILED(hr)) {
spdlog::error("[DirectX] Failed to set RTV name. Error: {}", HResultToString(hr));
}

hr = depthTexture->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("Depth Buffer Texture") - 1,
"Depth Buffer Texture");
if (FAILED(hr)) {
spdlog::error("[DirectX] Failed to set name for depth buffer texture. Error: {}", HResultToString(hr));
}

hr = m_DepthStencilView->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("Depth Stencil View") - 1,
"Depth Stencil View");
if (FAILED(hr)) {
spdlog::error("[DirectX] Failed to set name for depth stencil view. Error: {}", HResultToString(hr));
}
#endif

spdlog::info("[DirectX] Render target created.");
Expand All @@ -137,5 +173,6 @@ namespace FlashlightEngine {

void Swapchain::DestroySwapchainResources() {
m_RenderTargetView.Reset();
m_DepthStencilView.Reset();
}
}
2 changes: 1 addition & 1 deletion xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ set_project(ProjectName)
add_rules("mode.debug", "mode.release")

option("override_runtime", {description = "Override VS runtime to MD in release and MDd in debug.", default = true})
option("force_validation", {description = "Force Vulkan validation layers to be enabled.", default = false})
option("force_validation", {description = "Force DirectX debug interface to be enabled.", default = false})
option("profiler", {description = "Enable the Tracy profiler.", default = false})

add_includedirs("Include")
Expand Down

0 comments on commit 3d05b1a

Please sign in to comment.