147 lines
4.9 KiB
C++
147 lines
4.9 KiB
C++
#include <cassert>
|
|
#include <utility>
|
|
#include "pch.h"
|
|
#include "Mesh.h"
|
|
|
|
#include "Effects/Effect.h"
|
|
|
|
Mesh::Mesh(ID3D11Device *devicePtr, const std::vector<VertexIn> &verticesIn, const std::vector<Uint32> &indices, std::shared_ptr<Material> material, BaseEffect* effectPtr) :
|
|
m_EffectPtr(effectPtr),
|
|
m_InputLayoutPtr(nullptr),
|
|
m_VertexBufferPtr(nullptr),
|
|
m_IndexBufferPtr(nullptr),
|
|
m_VerticesIn(verticesIn),
|
|
m_Indices(indices),
|
|
m_IndicesCount(static_cast<UINT>(m_Indices.size())),
|
|
m_Material(std::move(material)) {
|
|
HRESULT result;
|
|
D3D11_BUFFER_DESC bufferDesc{};
|
|
D3D11_SUBRESOURCE_DATA subresourceData{};
|
|
|
|
m_EffectPtr->SetMaterial(m_Material.get());
|
|
|
|
//Create vertex layout
|
|
static constexpr uint32_t vertexElementCount{4};
|
|
D3D11_INPUT_ELEMENT_DESC vertexDesc[vertexElementCount]{};
|
|
|
|
vertexDesc[0].SemanticName = "POSITION";
|
|
vertexDesc[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
|
|
vertexDesc[0].AlignedByteOffset = 0;
|
|
vertexDesc[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
|
|
|
vertexDesc[1].SemanticName = "TEXCOORD";
|
|
vertexDesc[1].Format = DXGI_FORMAT_R32G32_FLOAT;
|
|
vertexDesc[1].AlignedByteOffset = offsetof(VertexIn, uv);
|
|
vertexDesc[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
|
|
|
vertexDesc[2].SemanticName = "NORMAL";
|
|
vertexDesc[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
|
|
vertexDesc[2].AlignedByteOffset = offsetof(VertexIn, normal);
|
|
vertexDesc[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
|
|
|
vertexDesc[3].SemanticName = "TANGENT";
|
|
vertexDesc[3].Format = DXGI_FORMAT_R32G32B32_FLOAT;
|
|
vertexDesc[3].AlignedByteOffset = offsetof(VertexIn, tangent);
|
|
vertexDesc[3].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
|
|
|
//Create input layout
|
|
D3DX11_PASS_DESC passDesc{};
|
|
ID3DX11EffectTechnique *techniquePtr = m_EffectPtr->GetTechniquePtr();
|
|
techniquePtr->GetPassByIndex(0)->GetDesc(&passDesc);
|
|
|
|
result = devicePtr->CreateInputLayout(
|
|
vertexDesc,
|
|
vertexElementCount,
|
|
passDesc.pIAInputSignature,
|
|
passDesc.IAInputSignatureSize,
|
|
&m_InputLayoutPtr);
|
|
|
|
assert(result == S_OK && "Creating input layout failed");
|
|
|
|
//Create vertex buffer
|
|
bufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
|
|
bufferDesc.ByteWidth = sizeof(VertexIn) * static_cast<uint32_t>(verticesIn.size());
|
|
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
|
bufferDesc.CPUAccessFlags = 0;
|
|
bufferDesc.MiscFlags = 0;
|
|
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_t) * m_IndicesCount;
|
|
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
|
bufferDesc.CPUAccessFlags = 0;
|
|
bufferDesc.MiscFlags = 0;
|
|
subresourceData.pSysMem = m_Indices.data();
|
|
result = devicePtr->CreateBuffer(&bufferDesc, &subresourceData, &m_IndexBufferPtr);
|
|
|
|
assert(result == S_OK && "Creating index buffer failed");
|
|
}
|
|
|
|
Mesh::~Mesh() {
|
|
m_InputLayoutPtr->Release();
|
|
m_InputLayoutPtr = nullptr;
|
|
|
|
m_VertexBufferPtr->Release();
|
|
m_VertexBufferPtr = nullptr;
|
|
|
|
m_IndexBufferPtr->Release();
|
|
m_IndexBufferPtr = nullptr;
|
|
|
|
delete m_EffectPtr;
|
|
m_EffectPtr = nullptr;
|
|
}
|
|
|
|
void Mesh::Render(ID3D11DeviceContext *deviceContextPtr, const Matrix &worldViewProj) const {
|
|
m_EffectPtr->SetWorldViewProjMatrix(worldViewProj);
|
|
m_EffectPtr->SetWorldMatrix(m_WorldMatrix);
|
|
//1. Set primitive topology
|
|
deviceContextPtr->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
|
|
|
//2. Set input layout
|
|
deviceContextPtr->IASetInputLayout(m_InputLayoutPtr);
|
|
|
|
//3. Set vertex buffer
|
|
constexpr UINT stride = sizeof(VertexIn);
|
|
constexpr UINT offset = 0;
|
|
deviceContextPtr->IASetVertexBuffers(0, 1, &m_VertexBufferPtr, &stride, &offset);
|
|
|
|
//4. Set index buffer
|
|
deviceContextPtr->IASetIndexBuffer(m_IndexBufferPtr, DXGI_FORMAT_R32_UINT, 0);
|
|
|
|
//5. Draw
|
|
D3DX11_TECHNIQUE_DESC techniqueDesc{};
|
|
m_EffectPtr->GetTechniquePtr()->GetDesc(&techniqueDesc);
|
|
for (UINT p{}; p < techniqueDesc.Passes; p++) {
|
|
m_EffectPtr->GetTechniquePtr()->GetPassByIndex(p)->Apply(0, deviceContextPtr);
|
|
deviceContextPtr->DrawIndexed(m_IndicesCount, 0, 0);
|
|
}
|
|
}
|
|
|
|
void Mesh::NextSamplingState() {
|
|
m_EffectPtr->NextSamplingState();
|
|
}
|
|
|
|
void Mesh::SetCameraPos(const Vector3 &pos) const {
|
|
m_EffectPtr->SetCameraPos(pos);
|
|
}
|
|
|
|
void Mesh::SetWorldMatrix(const Matrix &matrix) {
|
|
m_WorldMatrix = matrix;
|
|
}
|
|
|
|
void Mesh::ToggleNormals() {
|
|
m_EffectPtr->ToggleNormals();
|
|
}
|
|
|
|
void Mesh::SetMaterial(Material *pMaterial) {
|
|
m_Material.reset(pMaterial);
|
|
m_EffectPtr->SetMaterial(pMaterial);
|
|
}
|
|
|
|
void Mesh::CycleCullMode() {
|
|
m_EffectPtr->NextCullMode();
|
|
} |