195 lines
6.2 KiB
C++
195 lines
6.2 KiB
C++
#include "Material.h"
|
|
#include "Utilities.h"
|
|
#include "WICTextureLoader11.h"
|
|
|
|
using namespace DirectX;
|
|
|
|
UINT Material::init(ID3D11Device* pD3DDevice, LPCTSTR textureFileName)
|
|
{
|
|
UINT error = 0;
|
|
|
|
error = createVertexShader(pD3DDevice);
|
|
CheckError(error);
|
|
|
|
error = createPixelShader(pD3DDevice);
|
|
CheckError(error);
|
|
|
|
error = createMatrixBuffer(pD3DDevice);
|
|
CheckError(error);
|
|
|
|
error = createTextureAndSamplerState(pD3DDevice, textureFileName);
|
|
CheckError(error);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Material::render(ID3D11DeviceContext* pD3DDeviceContext)
|
|
{
|
|
// set shader stages
|
|
pD3DDeviceContext->VSSetShader(_pVertexShader, nullptr, 0);
|
|
pD3DDeviceContext->PSSetShader(_pPixelShader, nullptr, 0);
|
|
|
|
// set input layout
|
|
pD3DDeviceContext->IASetInputLayout(_pInputLayout);
|
|
|
|
// set shader resources
|
|
pD3DDeviceContext->VSSetConstantBuffers(0, 1, &_pMatrixBuffer);
|
|
|
|
// set texture
|
|
pD3DDeviceContext->PSSetShaderResources(0, 1, &_pTexture);
|
|
|
|
// set sampler state
|
|
pD3DDeviceContext->PSSetSamplers(0, 1, &_pSamplerState);
|
|
}
|
|
|
|
void Material::deInit()
|
|
{
|
|
safeRelease(_pSamplerState);
|
|
safeRelease(_pTexture);
|
|
safeRelease(_pMatrixBuffer);
|
|
safeRelease(_pInputLayout);
|
|
safeRelease(_pPixelShader);
|
|
safeRelease(_pVertexShader);
|
|
}
|
|
|
|
void Material::setMatrixBuffer(ID3D11DeviceContext* pD3DDeviceContext, const XMFLOAT4X4& worldMatrix, const XMFLOAT4X4& viewMatrix, const XMFLOAT4X4& projectionMatrix)
|
|
{
|
|
// unpack matrix data
|
|
XMMATRIX w = XMLoadFloat4x4(&worldMatrix);
|
|
XMMATRIX v = XMLoadFloat4x4(&viewMatrix);
|
|
XMMATRIX p = XMLoadFloat4x4(&projectionMatrix);
|
|
|
|
XMMATRIX wvp = w * v * p;
|
|
|
|
// set matrix data
|
|
D3D11_MAPPED_SUBRESOURCE bufferData = {};
|
|
HRESULT hr = pD3DDeviceContext->Map(_pMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &bufferData);
|
|
if (FAILED(hr)) return;
|
|
|
|
MatrixBuffer* matrixBuffer = static_cast<MatrixBuffer*>(bufferData.pData);
|
|
|
|
XMStoreFloat4x4(static_cast<XMFLOAT4X4*>(&matrixBuffer->WorldViewProjectionMatrix), XMMatrixTranspose(wvp));
|
|
XMStoreFloat4x4(static_cast<XMFLOAT4X4*>(&matrixBuffer->WorldMatrix), XMMatrixTranspose(w));
|
|
|
|
pD3DDeviceContext->Unmap(_pMatrixBuffer, 0);
|
|
}
|
|
|
|
UINT Material::createVertexShader(ID3D11Device* pD3DDevice)
|
|
{
|
|
HRESULT hr = {};
|
|
ID3DBlob* pCompiledShaderCode = nullptr;
|
|
|
|
// part 1 get compiled shader code
|
|
|
|
// option 1: load high level shader code & compile
|
|
//hr = D3DCompileFromFile(
|
|
// L"ColorVertexShader.hlsl", // shader file name
|
|
// nullptr, // optional macro defines
|
|
// nullptr, // pre compiled included shader code
|
|
// "main", // shader entry point (start function)
|
|
// "vs_4_0", // shader type & version
|
|
// 0, 0, // optional flags
|
|
// &pCompiledShaderCode, // compiled shader code memory
|
|
// nullptr // error messages
|
|
//);
|
|
|
|
// option 2: load compiled shader code
|
|
//hr = D3DReadFileToBlob(L"ColorVertexShader.cso", &pCompiledShaderCode);
|
|
//hr = D3DReadFileToBlob(L"TextureVertexShader.cso", &pCompiledShaderCode);
|
|
hr = D3DReadFileToBlob(L"LightingVertexShader.cso", &pCompiledShaderCode);
|
|
|
|
CheckFailed(hr, 60);
|
|
|
|
// part 2 create vertex shader object
|
|
hr = pD3DDevice->CreateVertexShader(pCompiledShaderCode->GetBufferPointer(), pCompiledShaderCode->GetBufferSize(), nullptr, &_pVertexShader);
|
|
CheckFailed(hr, 62);
|
|
|
|
UINT error = createInputLayout(pD3DDevice, pCompiledShaderCode);
|
|
CheckError(error);
|
|
|
|
safeRelease(pCompiledShaderCode);
|
|
|
|
return 0;
|
|
}
|
|
|
|
UINT Material::createPixelShader(ID3D11Device* pD3DDevice)
|
|
{
|
|
HRESULT hr = {};
|
|
ID3DBlob* pCompiledShaderCode = nullptr;
|
|
|
|
//hr = D3DReadFileToBlob(L"ColorPixelShader.cso", &pCompiledShaderCode);
|
|
//hr = D3DReadFileToBlob(L"TexturePixelShader.cso", &pCompiledShaderCode);
|
|
hr = D3DReadFileToBlob(L"LightingPixelShader.cso", &pCompiledShaderCode);
|
|
CheckFailed(hr, 64);
|
|
|
|
hr = pD3DDevice->CreatePixelShader(pCompiledShaderCode->GetBufferPointer(), pCompiledShaderCode->GetBufferSize(), nullptr, &_pPixelShader);
|
|
CheckFailed(hr, 66);
|
|
|
|
safeRelease(pCompiledShaderCode);
|
|
|
|
return 0;
|
|
}
|
|
|
|
UINT Material::createInputLayout(ID3D11Device* pD3DDevice, ID3DBlob* pCompiledVertexShaderCode)
|
|
{
|
|
// https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics
|
|
D3D11_INPUT_ELEMENT_DESC elements[4] = {};
|
|
|
|
// position
|
|
elements[0].SemanticName = "POSITION";
|
|
elements[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
|
|
|
|
// normal
|
|
elements[1].SemanticName = "NORMAL";
|
|
elements[1].Format = DXGI_FORMAT_R32G32B32_FLOAT;
|
|
elements[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
|
|
|
|
// uv
|
|
elements[2].SemanticName = "TEXCOORD";
|
|
elements[2].Format = DXGI_FORMAT_R32G32_FLOAT;
|
|
elements[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
|
|
|
|
// color
|
|
elements[3].SemanticName = "COLOR";
|
|
elements[3].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
|
elements[3].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
|
|
|
|
HRESULT hr = pD3DDevice->CreateInputLayout(elements, std::size(elements), pCompiledVertexShaderCode->GetBufferPointer(), pCompiledVertexShaderCode->GetBufferSize(), &_pInputLayout);
|
|
CheckFailed(hr, 68);
|
|
|
|
return 0;
|
|
}
|
|
|
|
UINT Material::createMatrixBuffer(ID3D11Device* pD3DDevice)
|
|
{
|
|
D3D11_BUFFER_DESC desc = {};
|
|
desc.ByteWidth = sizeof(MatrixBuffer);
|
|
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
|
desc.Usage = D3D11_USAGE_DYNAMIC;
|
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
|
|
|
HRESULT hr = pD3DDevice->CreateBuffer(&desc, nullptr, &_pMatrixBuffer);
|
|
CheckFailed(hr, 61);
|
|
|
|
return 0;
|
|
}
|
|
|
|
UINT Material::createTextureAndSamplerState(ID3D11Device* pD3DDevice, LPCTSTR textureFileName)
|
|
{
|
|
// load texture
|
|
HRESULT hr = CreateWICTextureFromFile(pD3DDevice, textureFileName, nullptr, &_pTexture);
|
|
CheckFailed(hr, 63);
|
|
|
|
// create sampler state
|
|
D3D11_SAMPLER_DESC samplerDesc = {};
|
|
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
|
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
|
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; // CAUTION: has to be set always
|
|
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
|
|
|
hr = pD3DDevice->CreateSamplerState(&samplerDesc, &_pSamplerState);
|
|
CheckFailed(hr, 65);
|
|
|
|
return 0;
|
|
}
|