Temp
This commit is contained in:
@@ -5,6 +5,7 @@ set(SOURCES
|
||||
"src/Renderer.cpp"
|
||||
"src/Timer.cpp"
|
||||
"src/Mesh.cpp"
|
||||
"src/ShadowMesh.cpp"
|
||||
"src/InstancedMesh.cpp"
|
||||
"src/Camera.cpp"
|
||||
"src/Texture.cpp"
|
||||
@@ -12,21 +13,30 @@ set(SOURCES
|
||||
"src/Utils.cpp"
|
||||
"src/HitTest.cpp"
|
||||
"src/Material.cpp"
|
||||
"src/Light.cpp"
|
||||
|
||||
"src/Math/Vector2.cpp"
|
||||
"src/Math/Vector3.cpp"
|
||||
"src/Math/Vector4.cpp"
|
||||
"src/Math/Matrix.cpp"
|
||||
|
||||
"src/Effects/Effect.cpp"
|
||||
"src/Effects/BaseEffect.cpp"
|
||||
"src/Effects/FireEffect.cpp"
|
||||
"src/Effects/ShadowEffect.cpp"
|
||||
|
||||
"src/PerlinNoise.hpp"
|
||||
|
||||
"src/Buffers/DepthBuffer.cpp"
|
||||
"src/Buffers/SamplerState.cpp"
|
||||
"src/Buffers/ShadowMapBuffer.cpp"
|
||||
|
||||
"src/Scenes/BaseScene.cpp"
|
||||
"src/Scenes/MainScene.cpp"
|
||||
"src/Scenes/DioramaScene.cpp"
|
||||
"src/Scenes/InstancedScene.cpp"
|
||||
"src/Scenes/PlanetScene.cpp"
|
||||
"src/Scenes/ShadowTestScene.cpp"
|
||||
)
|
||||
|
||||
SET(INCLUDE_DIRS
|
||||
@@ -34,6 +44,7 @@ SET(INCLUDE_DIRS
|
||||
"src/Math"
|
||||
"src/Effects"
|
||||
"src/Scenes"
|
||||
"src/Buffers"
|
||||
)
|
||||
|
||||
# Create the executable
|
||||
|
||||
2
project/resources/ShadingDemo.mtl
Normal file
2
project/resources/ShadingDemo.mtl
Normal file
@@ -0,0 +1,2 @@
|
||||
# Blender 4.3.2 MTL File: 'None'
|
||||
# www.blender.org
|
||||
4158
project/resources/ShadingDemo.obj
Normal file
4158
project/resources/ShadingDemo.obj
Normal file
File diff suppressed because it is too large
Load Diff
40
project/resources/shadowEffect.fx
Normal file
40
project/resources/shadowEffect.fx
Normal file
@@ -0,0 +1,40 @@
|
||||
float4x4 gLightWorldViewProj : WorldViewProjection;
|
||||
|
||||
float4x4 gWorldViewProj: WorldViewProjection; //For compatibility sake
|
||||
|
||||
Texture2D gShadowMap : register(t0); // Shadow map texture
|
||||
SamplerState gShadowMapSampler : register(s0); // Shadow map sampler
|
||||
|
||||
struct VS_Input
|
||||
{
|
||||
float3 Position : POSITION;
|
||||
};
|
||||
|
||||
struct VS_Output
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
};
|
||||
|
||||
VS_Output VS_Shadow(VS_Input input)
|
||||
{
|
||||
VS_Output output;
|
||||
// Transform vertex position to light's clip space
|
||||
output.Position = mul(float4(input.Position, 1.0f), gLightWorldViewProj);
|
||||
return output;
|
||||
}
|
||||
|
||||
float4 PS_Shadow(VS_Output input) : SV_TARGET
|
||||
{
|
||||
// Output depth information (Z/W in clip space)
|
||||
return float4(input.Position.z / input.Position.w, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
// Technique for rendering shadow map
|
||||
technique11 DefaultTechnique
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
SetVertexShader(CompileShader(vs_5_0, VS_Shadow()));
|
||||
SetPixelShader(CompileShader(ps_5_0, PS_Shadow()));
|
||||
}
|
||||
}
|
||||
45
project/src/Buffers/DepthBuffer.cpp
Normal file
45
project/src/Buffers/DepthBuffer.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "DepthBuffer.h"
|
||||
|
||||
DepthBuffer::DepthBuffer(ID3D11Device* device, UINT width, UINT height)
|
||||
: m_device(device), m_width(width), m_height(height), m_depthBuffer(nullptr), m_depthStencilView(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
DepthBuffer::~DepthBuffer()
|
||||
{
|
||||
if (m_depthStencilView) m_depthStencilView->Release();
|
||||
if (m_depthBuffer) m_depthBuffer->Release();
|
||||
}
|
||||
|
||||
bool DepthBuffer::Initialize()
|
||||
{
|
||||
// Create a depth buffer
|
||||
D3D11_TEXTURE2D_DESC desc = {};
|
||||
desc.Width = m_width;
|
||||
desc.Height = m_height;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = DXGI_FORMAT_D32_FLOAT;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
|
||||
desc.CPUAccessFlags = 0;
|
||||
|
||||
HRESULT hr = m_device->CreateTexture2D(&desc, nullptr, &m_depthBuffer);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create DepthStencilView
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
|
||||
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT;
|
||||
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
|
||||
hr = m_device->CreateDepthStencilView(m_depthBuffer, &dsvDesc, &m_depthStencilView);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
26
project/src/Buffers/DepthBuffer.h
Normal file
26
project/src/Buffers/DepthBuffer.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef GP1_DIRECTX_DEPTHBUFFER_H
|
||||
#define GP1_DIRECTX_DEPTHBUFFER_H
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
class DepthBuffer
|
||||
{
|
||||
public:
|
||||
DepthBuffer(ID3D11Device* device, UINT width, UINT height);
|
||||
~DepthBuffer();
|
||||
|
||||
bool Initialize();
|
||||
ID3D11Texture2D* GetDepthBuffer() const { return m_depthBuffer; }
|
||||
ID3D11DepthStencilView* GetDepthStencilView() const { return m_depthStencilView; }
|
||||
|
||||
private:
|
||||
ID3D11Device* m_device;
|
||||
UINT m_width;
|
||||
UINT m_height;
|
||||
|
||||
ID3D11Texture2D* m_depthBuffer;
|
||||
ID3D11DepthStencilView* m_depthStencilView;
|
||||
};
|
||||
|
||||
|
||||
#endif //GP1_DIRECTX_DEPTHBUFFER_H
|
||||
27
project/src/Buffers/SamplerState.cpp
Normal file
27
project/src/Buffers/SamplerState.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "SamplerState.h"
|
||||
|
||||
SamplerState::SamplerState(ID3D11Device *device)
|
||||
: m_device(device), m_samplerState(nullptr) {
|
||||
}
|
||||
|
||||
SamplerState::~SamplerState() {
|
||||
if (m_samplerState) m_samplerState->Release();
|
||||
}
|
||||
|
||||
bool SamplerState::Initialize() {
|
||||
D3D11_SAMPLER_DESC samplerDesc = {};
|
||||
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
|
||||
samplerDesc.MinLOD = 0;
|
||||
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||
|
||||
HRESULT hr = m_device->CreateSamplerState(&samplerDesc, &m_samplerState);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
20
project/src/Buffers/SamplerState.h
Normal file
20
project/src/Buffers/SamplerState.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef GP1_DIRECTX_SAMPLERSTATE_H
|
||||
#define GP1_DIRECTX_SAMPLERSTATE_H
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
class SamplerState
|
||||
{
|
||||
public:
|
||||
SamplerState(ID3D11Device* device);
|
||||
~SamplerState();
|
||||
|
||||
bool Initialize();
|
||||
ID3D11SamplerState* GetSamplerState() const { return m_samplerState; }
|
||||
|
||||
private:
|
||||
ID3D11Device* m_device;
|
||||
ID3D11SamplerState* m_samplerState;
|
||||
};
|
||||
|
||||
#endif //GP1_DIRECTX_SAMPLERSTATE_H
|
||||
44
project/src/Buffers/ShadowMapBuffer.cpp
Normal file
44
project/src/Buffers/ShadowMapBuffer.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "ShadowMapBuffer.h"
|
||||
|
||||
ShadowMapBuffer::ShadowMapBuffer(ID3D11Device *device, UINT width, UINT height)
|
||||
: m_device(device), m_width(width), m_height(height), m_shaderResourceView(nullptr),
|
||||
m_depthBuffer(device, width, height), m_samplerState(device) {
|
||||
}
|
||||
|
||||
ShadowMapBuffer::~ShadowMapBuffer() {
|
||||
if (m_shaderResourceView) m_shaderResourceView->Release();
|
||||
}
|
||||
|
||||
bool ShadowMapBuffer::Initialize() {
|
||||
if (!m_depthBuffer.Initialize()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_samplerState.Initialize()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create ShaderResourceView for the depth buffer
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
||||
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
|
||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
HRESULT hr = m_device->CreateShaderResourceView(m_depthBuffer.GetDepthBuffer(), &srvDesc, &m_shaderResourceView);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShadowMapBuffer::SetRenderTarget(ID3D11DeviceContext *deviceContext) {
|
||||
deviceContext->OMSetRenderTargets(0, nullptr, m_depthBuffer.GetDepthStencilView());
|
||||
}
|
||||
|
||||
void ShadowMapBuffer::ResetRenderTarget(ID3D11DeviceContext *deviceContext) {
|
||||
ID3D11RenderTargetView *nullRTV = nullptr;
|
||||
deviceContext->OMSetRenderTargets(1, &nullRTV, nullptr);
|
||||
}
|
||||
|
||||
ID3D11DepthStencilView *ShadowMapBuffer::GetDepthStencilView() {
|
||||
return m_depthBuffer.GetDepthStencilView();
|
||||
}
|
||||
44
project/src/Buffers/ShadowMapBuffer.h
Normal file
44
project/src/Buffers/ShadowMapBuffer.h
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Created by Bram on 13/01/2025.
|
||||
//
|
||||
|
||||
#ifndef GP1_DIRECTX_SHADOWMAPBUFFER_H
|
||||
#define GP1_DIRECTX_SHADOWMAPBUFFER_H
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <DirectXMath.h>
|
||||
#include "DepthBuffer.h"
|
||||
#include "SamplerState.h"
|
||||
|
||||
class ShadowMapBuffer {
|
||||
public:
|
||||
ShadowMapBuffer(ID3D11Device *device, UINT width, UINT height);
|
||||
|
||||
~ShadowMapBuffer();
|
||||
|
||||
bool Initialize();
|
||||
|
||||
void SetRenderTarget(ID3D11DeviceContext *deviceContext);
|
||||
|
||||
void ResetRenderTarget(ID3D11DeviceContext *deviceContext);
|
||||
|
||||
// Get the depth stencil view and the sampler state
|
||||
ID3D11ShaderResourceView *GetShaderResourceView() const { return m_shaderResourceView; }
|
||||
|
||||
ID3D11SamplerState *GetSamplerState() const { return m_samplerState.GetSamplerState(); }
|
||||
|
||||
|
||||
ID3D11DepthStencilView *GetDepthStencilView();
|
||||
|
||||
private:
|
||||
ID3D11Device *m_device;
|
||||
UINT m_width;
|
||||
UINT m_height;
|
||||
|
||||
DepthBuffer m_depthBuffer;
|
||||
SamplerState m_samplerState;
|
||||
|
||||
ID3D11ShaderResourceView *m_shaderResourceView;
|
||||
};
|
||||
|
||||
#endif //GP1_DIRECTX_SHADOWMAPBUFFER_H
|
||||
@@ -54,7 +54,6 @@ ID3DX11Effect *BaseEffect::LoadEffect(ID3D11Device *devicePtr, const std::wstrin
|
||||
ss << errorsPtr[i];
|
||||
OutputDebugStringW(ss.str().c_str());
|
||||
|
||||
|
||||
errorBlobPtr->Release();
|
||||
errorBlobPtr = nullptr;
|
||||
return nullptr;
|
||||
|
||||
42
project/src/Effects/ShadowEffect.cpp
Normal file
42
project/src/Effects/ShadowEffect.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// Created by Bram on 13/01/2025.
|
||||
//
|
||||
|
||||
#include "ShadowEffect.h"
|
||||
|
||||
ShadowEffect::ShadowEffect(ID3D11Device *devicePtr, const std::wstring &filePath)
|
||||
: BaseEffect(devicePtr, filePath) {
|
||||
// Retrieve shadow-specific variables
|
||||
m_LightWorldViewProjVariable = m_EffectPtr->GetVariableByName("gLightWorldViewProj")->AsMatrix();
|
||||
if (!m_LightWorldViewProjVariable->IsValid()) {
|
||||
throw std::runtime_error("Failed to retrieve gLightWorldViewProj variable in ShadowEffect.");
|
||||
}
|
||||
|
||||
m_ShadowMapVariable = m_EffectPtr->GetVariableByName("gShadowMap")->AsShaderResource();
|
||||
if (!m_ShadowMapVariable->IsValid()) {
|
||||
throw std::runtime_error("Failed to retrieve gShadowMap variable in ShadowEffect.");
|
||||
}
|
||||
|
||||
m_ShadowMapSamplerVariable = m_EffectPtr->GetVariableByName("gShadowMapSampler")->AsSampler();
|
||||
if (!m_ShadowMapSamplerVariable->IsValid()) {
|
||||
throw std::runtime_error("Failed to retrieve gShadowMapSampler variable in ShadowEffect.");
|
||||
}
|
||||
}
|
||||
|
||||
void ShadowEffect::SetLightWorldViewProjMatrix(const Matrix &matrix) {
|
||||
if (m_LightWorldViewProjVariable) {
|
||||
m_LightWorldViewProjVariable->SetMatrix(reinterpret_cast<const float*>(&matrix));
|
||||
}
|
||||
}
|
||||
|
||||
void ShadowEffect::SetShadowMap(ID3D11ShaderResourceView *shadowMapSRV) {
|
||||
if (m_ShadowMapVariable) {
|
||||
m_ShadowMapVariable->SetResource(shadowMapSRV);
|
||||
}
|
||||
}
|
||||
void ShadowEffect::SetShadowMapSampler(ID3D11SamplerState *samplerState) {
|
||||
if (m_ShadowMapSamplerVariable) {
|
||||
m_ShadowMapSamplerVariable->SetSampler(0, samplerState);
|
||||
}
|
||||
}
|
||||
|
||||
25
project/src/Effects/ShadowEffect.h
Normal file
25
project/src/Effects/ShadowEffect.h
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
#ifndef GP1_DIRECTX_SHADOWEFFECT_H
|
||||
#define GP1_DIRECTX_SHADOWEFFECT_H
|
||||
|
||||
#include "BaseEffect.h"
|
||||
|
||||
class ShadowEffect : public BaseEffect {
|
||||
public:
|
||||
ShadowEffect(ID3D11Device* devicePtr, const std::wstring& filePath);
|
||||
|
||||
~ShadowEffect() override = default;
|
||||
|
||||
void SetLightWorldViewProjMatrix(const dae::Matrix& matrix);
|
||||
|
||||
void SetShadowMap(ID3D11ShaderResourceView* shadowMapSRV);
|
||||
|
||||
void SetShadowMapSampler(ID3D11SamplerState* samplerState);
|
||||
|
||||
private:
|
||||
ID3DX11EffectMatrixVariable* m_LightWorldViewProjVariable{nullptr};
|
||||
ID3DX11EffectShaderResourceVariable* m_ShadowMapVariable{nullptr};
|
||||
ID3DX11EffectSamplerVariable* m_ShadowMapSamplerVariable{nullptr};
|
||||
};
|
||||
|
||||
#endif //GP1_DIRECTX_SHADOWEFFECT_H
|
||||
37
project/src/Light.cpp
Normal file
37
project/src/Light.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "Light.h"
|
||||
#include <cmath>
|
||||
|
||||
Light::Light()
|
||||
: m_Position(0.0f, 10.0f, 0.0f),
|
||||
m_Target(0.0f, 0.0f, 0.0f),
|
||||
m_Up(0.0f, 1.0f, 0.0f),
|
||||
m_ViewMatrix(dae::Matrix()),
|
||||
m_ProjectionMatrix(dae::Matrix()) {}
|
||||
|
||||
void Light::SetPosition(const dae::Vector3 &position) {
|
||||
m_Position = position;
|
||||
}
|
||||
|
||||
void Light::SetTarget(const dae::Vector3 &target) {
|
||||
m_Target = target;
|
||||
}
|
||||
|
||||
void Light::SetUp(const dae::Vector3 &up) {
|
||||
m_Up = up;
|
||||
}
|
||||
|
||||
dae::Matrix Light::GetViewMatrix() const {
|
||||
return dae::Matrix::CreateLookAtLH(m_Position, m_Target, m_Up);
|
||||
}
|
||||
|
||||
dae::Matrix Light::GetProjectionMatrix(float nearPlane, float farPlane, float size) const {
|
||||
return dae::Matrix::CreateOrthographic(size, size, nearPlane, farPlane);
|
||||
}
|
||||
|
||||
dae::Matrix Light::GetViewProjectionMatrix(float nearPlane, float farPlane, float size) const {
|
||||
return GetViewMatrix() * GetProjectionMatrix(nearPlane, farPlane, size);
|
||||
}
|
||||
|
||||
void Light::Update() {
|
||||
// If the light position or target changes dynamically, this is where updates would be managed.
|
||||
}
|
||||
32
project/src/Light.h
Normal file
32
project/src/Light.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef GP1_DIRECTX_LIGHT_H
|
||||
#define GP1_DIRECTX_LIGHT_H
|
||||
|
||||
|
||||
#include "Math/Vector3.h"
|
||||
#include "Math/Matrix.h"
|
||||
|
||||
class Light {
|
||||
public:
|
||||
Light();
|
||||
~Light() = default;
|
||||
|
||||
void SetPosition(const dae::Vector3 &position);
|
||||
void SetTarget(const dae::Vector3 &target);
|
||||
void SetUp(const dae::Vector3 &up);
|
||||
|
||||
dae::Matrix GetViewMatrix() const;
|
||||
dae::Matrix GetProjectionMatrix(float nearPlane = 0.1f, float farPlane = 100.0f, float size = 20.0f) const;
|
||||
dae::Matrix GetViewProjectionMatrix(float nearPlane = 0.1f, float farPlane = 100.0f, float size = 20.0f) const;
|
||||
|
||||
void Update();
|
||||
|
||||
private:
|
||||
dae::Vector3 m_Position;
|
||||
dae::Vector3 m_Target;
|
||||
dae::Vector3 m_Up;
|
||||
|
||||
dae::Matrix m_ViewMatrix;
|
||||
dae::Matrix m_ProjectionMatrix;
|
||||
};
|
||||
|
||||
#endif //GP1_DIRECTX_LIGHT_H
|
||||
@@ -302,5 +302,14 @@ namespace dae {
|
||||
data[3] = {vector3, 1};
|
||||
}
|
||||
|
||||
Matrix Matrix::CreateOrthographic(float size, float size1, float plane, float plane1) {
|
||||
return Matrix(
|
||||
{2.f / size, 0, 0, 0},
|
||||
{0, 2.f / size1, 0, 0},
|
||||
{0, 0, 1.f / (plane1 - plane), 0},
|
||||
{0, 0, -plane / (plane1 - plane), 1}
|
||||
);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
}
|
||||
@@ -58,6 +58,8 @@ namespace dae {
|
||||
|
||||
void SetTranslation(Vector3 vector3);
|
||||
|
||||
static dae::Matrix CreateOrthographic(float size, float size1, float plane, float plane1);
|
||||
|
||||
private:
|
||||
|
||||
//Row-Major Matrix
|
||||
|
||||
@@ -140,4 +140,8 @@ void Mesh::SetMaterial(Material *pMaterial) {
|
||||
|
||||
void Mesh::CycleCullMode() {
|
||||
m_EffectPtr->NextCullMode();
|
||||
}
|
||||
}
|
||||
|
||||
BaseEffect *Mesh::GetEffect() {
|
||||
return m_EffectPtr;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ enum class PrimitiveTopology {
|
||||
|
||||
|
||||
|
||||
class Mesh final {
|
||||
class Mesh {
|
||||
public:
|
||||
Mesh(ID3D11Device *devicePtr, const std::vector<VertexIn> &verticesIn, const std::vector<Uint32> &indices,
|
||||
std::shared_ptr<Material> material, BaseEffect* effectPtr);
|
||||
@@ -53,6 +53,8 @@ public:
|
||||
void SetShouldRender(bool shouldRender) { m_ShouldRender = shouldRender; }
|
||||
bool GetShouldRender() const { return m_ShouldRender; }
|
||||
|
||||
BaseEffect *GetEffect();
|
||||
|
||||
private:
|
||||
BaseEffect *m_EffectPtr;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Scenes/DioramaScene.h"
|
||||
#include "Scenes/InstancedScene.h"
|
||||
#include "Scenes/PlanetScene.h"
|
||||
#include "Scenes/ShadowTestScene.h"
|
||||
|
||||
|
||||
namespace dae {
|
||||
@@ -36,7 +37,7 @@ namespace dae {
|
||||
|
||||
InitializeSDLRasterizer();
|
||||
|
||||
m_pScene = new MainScene();
|
||||
m_pScene = new ShadowTestScene();
|
||||
m_pScene->Initialize(m_DevicePtr, m_DeviceContextPtr, nullptr);
|
||||
|
||||
if (!m_pScene->GetMeshes().empty()) {
|
||||
@@ -136,6 +137,7 @@ namespace dae {
|
||||
m_SwapChainPtr->Present(0, 0);
|
||||
}
|
||||
|
||||
|
||||
void Renderer::RenderSDL() {
|
||||
ColorRGB ChosenClearColor = m_UseUniformClearColor ? m_UniformClearColor : m_ClearColorSoftware;
|
||||
SDL_FillRect(m_pBackBuffer, nullptr, SDL_MapRGB(m_pBackBuffer->format, ChosenClearColor.r, ChosenClearColor.g, ChosenClearColor.b));
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "HitTest.h"
|
||||
#include "Scenes/BaseScene.h"
|
||||
#include "Effects/Effect.h"
|
||||
#include "Buffers/ShadowMapBuffer.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -92,6 +93,9 @@ namespace dae
|
||||
|
||||
ColorRGB m_UniformClearColor{ ColorRGB{0.1f * 255.f, 0.1f * 255.f, 0.1 * 255.f} };
|
||||
|
||||
ShadowMapBuffer* m_pShadowMapBuffer{};
|
||||
dae::Matrix m_LightViewProjectionMatrix{};
|
||||
|
||||
|
||||
//DirectX vars
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
|
||||
virtual std::vector<Mesh*>& GetMeshes() = 0;
|
||||
virtual std::vector<std::shared_ptr<Material>>& GetMaterials() = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
83
project/src/Scenes/ShadowTestScene.cpp
Normal file
83
project/src/Scenes/ShadowTestScene.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// Created by Bram on 14/01/2025.
|
||||
//
|
||||
|
||||
#include "ShadowTestScene.h"
|
||||
#include "../Utils.h"
|
||||
#include "../Effects/ShadowEffect.h"
|
||||
#include "../Effects/Effect.h"
|
||||
|
||||
void ShadowTestScene::Initialize(ID3D11Device *DevicePtr, ID3D11DeviceContext *DeviceContextPtr, Camera *camera) {
|
||||
// Initialize shadow map buffer
|
||||
m_ShadowMapBuffer = new ShadowMapBuffer(DevicePtr, 1024, 1024); // Example resolution: 1024x1024
|
||||
m_ShadowMapBuffer->Initialize();
|
||||
// Initialize light source
|
||||
m_Light.SetPosition({0.0f, 10.0f, 0.0f});
|
||||
m_Light.SetTarget({0.0f, 0.0f, 0.0f});
|
||||
m_Light.SetUp({0.0f, 1.0f, 0.0f});
|
||||
|
||||
std::vector<VertexIn> vertices{};
|
||||
std::vector<uint32_t> indices{};
|
||||
|
||||
if(!Utils::ParseOBJNew("resources/ShadingDemo.obj", vertices, indices, true)){
|
||||
assert(true && "Model failed to load");
|
||||
}
|
||||
|
||||
|
||||
auto shadowEffect = new ShadowEffect(DevicePtr, L"resources/shadowEffect.fx");
|
||||
auto otherEffect = new Effect(DevicePtr, L"resources/SimpleDiffuse.fx");
|
||||
|
||||
auto shadowMesh = new ShadowMesh(DevicePtr, vertices, indices, std::make_shared<Material>(), shadowEffect, otherEffect);
|
||||
|
||||
|
||||
m_shadowMeshes.push_back(shadowMesh);
|
||||
// m_shadowMaterials.push_back(material);
|
||||
}
|
||||
|
||||
void ShadowTestScene::Update() {
|
||||
m_Light.Update();
|
||||
}
|
||||
|
||||
void ShadowTestScene::Render(ID3D11DeviceContext *devicePtr, ID3D11RenderTargetView *renderTargetViewPtr,
|
||||
ID3D11DepthStencilView *depthStencilViewPtr, const Camera &camera) {
|
||||
// Shadow map pass
|
||||
devicePtr->OMSetRenderTargets(0, nullptr, m_ShadowMapBuffer->GetDepthStencilView());
|
||||
devicePtr->ClearDepthStencilView(m_ShadowMapBuffer->GetDepthStencilView(), D3D11_CLEAR_DEPTH, 1.0f, 0);
|
||||
|
||||
for (auto* mesh : m_shadowMeshes) {
|
||||
Matrix lightWorldViewProj = mesh->GetWorldMatrix() * m_Light.GetViewProjectionMatrix();
|
||||
dynamic_cast<ShadowMesh*>(mesh)->RenderShadow(devicePtr, lightWorldViewProj);
|
||||
}
|
||||
|
||||
devicePtr->OMSetRenderTargets(1, &renderTargetViewPtr, depthStencilViewPtr);
|
||||
for (auto* mesh : m_shadowMeshes) {
|
||||
Matrix worldViewProj = mesh->GetWorldMatrix() * camera.GetViewProjectionMatrix();
|
||||
dynamic_cast<ShadowMesh*>(mesh)->RenderFinal(devicePtr, worldViewProj);
|
||||
}
|
||||
}
|
||||
|
||||
void ShadowTestScene::Cleanup() {
|
||||
|
||||
for (auto *mesh : m_Meshes) {
|
||||
delete mesh;
|
||||
}
|
||||
|
||||
m_Meshes.clear();
|
||||
|
||||
for (auto *mesh : m_shadowMeshes) {
|
||||
delete mesh;
|
||||
}
|
||||
|
||||
m_shadowMeshes.clear();
|
||||
|
||||
delete m_ShadowMapBuffer;
|
||||
|
||||
}
|
||||
|
||||
std::vector<Mesh *> &ShadowTestScene::GetMeshes() {
|
||||
return m_Meshes;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Material>> &ShadowTestScene::GetMaterials() {
|
||||
return m_Materials;
|
||||
}
|
||||
39
project/src/Scenes/ShadowTestScene.h
Normal file
39
project/src/Scenes/ShadowTestScene.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef GP1_DIRECTX_SHADOWTESTSCENE_H
|
||||
#define GP1_DIRECTX_SHADOWTESTSCENE_H
|
||||
|
||||
#include "BaseScene.h"
|
||||
#include "../Buffers/ShadowMapBuffer.h"
|
||||
#include "../Light.h"
|
||||
#include "../ShadowMesh.h"
|
||||
|
||||
class ShadowTestScene: public BaseScene {
|
||||
public:
|
||||
void Initialize(ID3D11Device *DevicePtr, ID3D11DeviceContext *DeviceContextPtr, Camera *camera) override;
|
||||
|
||||
void Update() override;
|
||||
|
||||
void Render(ID3D11DeviceContext *devicePtr, ID3D11RenderTargetView *renderTargetViewPtr, ID3D11DepthStencilView *depthStencilViewPtr,
|
||||
const Camera &camera) override;
|
||||
|
||||
void Cleanup() override;
|
||||
|
||||
std::vector<Mesh *> &GetMeshes() override;
|
||||
|
||||
std::vector<std::shared_ptr<Material>> &GetMaterials() override;
|
||||
|
||||
private:
|
||||
std::vector<Mesh *> m_Meshes;
|
||||
std::vector<std::shared_ptr<Material>> m_Materials;
|
||||
|
||||
std::vector<ShadowMesh *> m_shadowMeshes;
|
||||
std::vector<std::shared_ptr<Material>> m_shadowMaterials;
|
||||
|
||||
|
||||
ShadowMapBuffer *m_ShadowMapBuffer{nullptr};
|
||||
Light m_Light;
|
||||
|
||||
void RenderShadowMapToScreen(ID3D11DeviceContext *devicePtr, ID3D11RenderTargetView *renderTargetViewPtr);
|
||||
};
|
||||
|
||||
|
||||
#endif //GP1_DIRECTX_SHADOWTESTSCENE_H
|
||||
114
project/src/ShadowMesh.cpp
Normal file
114
project/src/ShadowMesh.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
#include "ShadowMesh.h"
|
||||
#include <d3d11.h>
|
||||
#include <d3dx11effect.h>
|
||||
#include <cassert>
|
||||
|
||||
ShadowMesh::ShadowMesh(ID3D11Device* devicePtr,
|
||||
const std::vector<VertexIn>& verticesIn,
|
||||
const std::vector<Uint32>& indices,
|
||||
std::shared_ptr<Material> material,
|
||||
ShadowEffect* shadowEffectPtr,
|
||||
BaseEffect* colorEffectPtr)
|
||||
: m_ShadowEffectPtr(shadowEffectPtr),
|
||||
m_ColorEffectPtr(colorEffectPtr),
|
||||
m_VerticesIn(verticesIn),
|
||||
m_Indices(indices),
|
||||
m_IndicesCount(static_cast<UINT>(indices.size())) {
|
||||
|
||||
HRESULT result;
|
||||
|
||||
// Create input layout
|
||||
D3D11_INPUT_ELEMENT_DESC vertexDesc[] = {
|
||||
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, static_cast<UINT>(offsetof(VertexIn, uv)), D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, static_cast<UINT>(offsetof(VertexIn, normal)), D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
{"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, static_cast<UINT>(offsetof(VertexIn, tangent)), D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
};
|
||||
|
||||
D3DX11_PASS_DESC passDesc;
|
||||
ID3DX11EffectTechnique* techniquePtr = m_ShadowEffectPtr->GetTechniquePtr();
|
||||
techniquePtr->GetPassByIndex(0)->GetDesc(&passDesc);
|
||||
|
||||
result = devicePtr->CreateInputLayout(vertexDesc, ARRAYSIZE(vertexDesc),
|
||||
passDesc.pIAInputSignature, passDesc.IAInputSignatureSize,
|
||||
&m_InputLayoutPtr);
|
||||
assert(result == S_OK && "Creating input layout failed");
|
||||
|
||||
// Create vertex buffer
|
||||
D3D11_BUFFER_DESC bufferDesc = {};
|
||||
bufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
bufferDesc.ByteWidth = sizeof(VertexIn) * static_cast<UINT>(verticesIn.size());
|
||||
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
bufferDesc.CPUAccessFlags = 0;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA subresourceData = {};
|
||||
subresourceData.pSysMem = verticesIn.data();
|
||||
|
||||
result = devicePtr->CreateBuffer(&bufferDesc, &subresourceData, &m_VertexBufferPtr);
|
||||
assert(result == S_OK && "Creating vertex buffer failed");
|
||||
|
||||
// Create index buffer
|
||||
bufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
bufferDesc.ByteWidth = sizeof(Uint32) * m_IndicesCount;
|
||||
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
|
||||
subresourceData.pSysMem = m_Indices.data();
|
||||
|
||||
result = devicePtr->CreateBuffer(&bufferDesc, &subresourceData, &m_IndexBufferPtr);
|
||||
assert(result == S_OK && "Creating index buffer failed");
|
||||
}
|
||||
|
||||
ShadowMesh::~ShadowMesh() {
|
||||
if (m_InputLayoutPtr) m_InputLayoutPtr->Release();
|
||||
if (m_VertexBufferPtr) m_VertexBufferPtr->Release();
|
||||
if (m_IndexBufferPtr) m_IndexBufferPtr->Release();
|
||||
|
||||
delete m_ShadowEffectPtr;
|
||||
delete m_ColorEffectPtr;
|
||||
}
|
||||
|
||||
void ShadowMesh::RenderShadow(ID3D11DeviceContext* deviceContextPtr, const Matrix& lightWorldViewProj) {
|
||||
m_ShadowEffectPtr->SetLightWorldViewProjMatrix(lightWorldViewProj);
|
||||
deviceContextPtr->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
deviceContextPtr->IASetInputLayout(m_InputLayoutPtr);
|
||||
|
||||
const UINT stride = sizeof(VertexIn);
|
||||
const UINT offset = 0;
|
||||
deviceContextPtr->IASetVertexBuffers(0, 1, &m_VertexBufferPtr, &stride, &offset);
|
||||
deviceContextPtr->IASetIndexBuffer(m_IndexBufferPtr, DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
D3DX11_TECHNIQUE_DESC techniqueDesc;
|
||||
m_ShadowEffectPtr->GetTechniquePtr()->GetDesc(&techniqueDesc);
|
||||
|
||||
for (UINT p = 0; p < techniqueDesc.Passes; ++p) {
|
||||
m_ShadowEffectPtr->GetTechniquePtr()->GetPassByIndex(p)->Apply(0, deviceContextPtr);
|
||||
deviceContextPtr->DrawIndexed(m_IndicesCount, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ShadowMesh::RenderFinal(ID3D11DeviceContext* deviceContextPtr, const Matrix& worldViewProj) {
|
||||
m_ColorEffectPtr->SetWorldViewProjMatrix(worldViewProj);
|
||||
deviceContextPtr->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
deviceContextPtr->IASetInputLayout(m_InputLayoutPtr);
|
||||
|
||||
const UINT stride = sizeof(VertexIn);
|
||||
const UINT offset = 0;
|
||||
deviceContextPtr->IASetVertexBuffers(0, 1, &m_VertexBufferPtr, &stride, &offset);
|
||||
deviceContextPtr->IASetIndexBuffer(m_IndexBufferPtr, DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
D3DX11_TECHNIQUE_DESC techniqueDesc;
|
||||
m_ColorEffectPtr->GetTechniquePtr()->GetDesc(&techniqueDesc);
|
||||
|
||||
for (UINT p = 0; p < techniqueDesc.Passes; ++p) {
|
||||
m_ColorEffectPtr->GetTechniquePtr()->GetPassByIndex(p)->Apply(0, deviceContextPtr);
|
||||
deviceContextPtr->DrawIndexed(m_IndicesCount, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ShadowMesh::SetWorldMatrix(const Matrix& matrix) {
|
||||
m_WorldMatrix = matrix;
|
||||
}
|
||||
|
||||
Matrix ShadowMesh::GetWorldMatrix() const {
|
||||
return m_WorldMatrix;
|
||||
}
|
||||
52
project/src/ShadowMesh.h
Normal file
52
project/src/ShadowMesh.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef SHADOW_MESH_H
|
||||
#define SHADOW_MESH_H
|
||||
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <d3d11.h>
|
||||
#include "Effects/ShadowEffect.h"
|
||||
#include "Material.h"
|
||||
#include "Mesh.h"
|
||||
|
||||
class ShadowMesh {
|
||||
public:
|
||||
ShadowMesh(ID3D11Device* devicePtr,
|
||||
const std::vector<VertexIn>& verticesIn,
|
||||
const std::vector<Uint32>& indices,
|
||||
std::shared_ptr<Material> material,
|
||||
ShadowEffect* shadowEffectPtr,
|
||||
BaseEffect* colorEffectPtr);
|
||||
|
||||
~ShadowMesh();
|
||||
|
||||
void RenderShadow(ID3D11DeviceContext* deviceContextPtr, const Matrix& lightWorldViewProj);
|
||||
void RenderFinal(ID3D11DeviceContext* deviceContextPtr, const Matrix& worldViewProj);
|
||||
|
||||
void SetWorldMatrix(const Matrix& matrix);
|
||||
Matrix GetWorldMatrix() const;
|
||||
|
||||
private:
|
||||
// Shadow effect
|
||||
ShadowEffect* m_ShadowEffectPtr;
|
||||
|
||||
// Color effect for final render
|
||||
BaseEffect* m_ColorEffectPtr;
|
||||
|
||||
// Buffers
|
||||
ID3D11InputLayout* m_InputLayoutPtr;
|
||||
ID3D11Buffer* m_VertexBufferPtr;
|
||||
ID3D11Buffer* m_IndexBufferPtr;
|
||||
|
||||
// Material and mesh data
|
||||
std::shared_ptr<Material> m_Material;
|
||||
std::vector<VertexIn> m_VerticesIn;
|
||||
std::vector<Uint32> m_Indices;
|
||||
|
||||
// Matrix transformations
|
||||
Matrix m_WorldMatrix;
|
||||
|
||||
// Indices count
|
||||
UINT m_IndicesCount;
|
||||
};
|
||||
|
||||
#endif // SHADOW_MESH_H
|
||||
Reference in New Issue
Block a user