#include #include #include "pch.h" #include "Mesh.h" #include "Effects/Effect.h" Mesh::Mesh(ID3D11Device *devicePtr, const std::vector &verticesIn, const std::vector &indices, std::shared_ptr 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(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(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); deviceContextPtr->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); deviceContextPtr->IASetInputLayout(m_InputLayoutPtr); constexpr UINT stride = sizeof(VertexIn); constexpr 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_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(); } BaseEffect *Mesh::GetEffect() { return m_EffectPtr; }