Files
GP1-DirectX/project/src/ShadowMesh.cpp
2025-01-16 14:03:28 +01:00

119 lines
4.6 KiB
C++

#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;
m_Material = material;
m_ColorEffectPtr->SetMaterial(material.get());
// 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_ColorEffectPtr->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->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->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;
}