
Added the DDS Texture Loading for future use Added the gamepad class for future use Added first child method to the scenegraph Added RGB to intensity and lerp methods to the shared methods class Added the terrain node class with normals Fixed issue with submeshnode not passing the world transform to the actual meshes
205 lines
7.7 KiB
C++
205 lines
7.7 KiB
C++
#include "SubMeshRenderer.h"
|
|
|
|
void SubMeshRenderer::SetSubMesh(shared_ptr<SubMesh> subMesh)
|
|
{
|
|
_subMesh = subMesh;
|
|
}
|
|
|
|
void SubMeshRenderer::SetWorldTransformation(FXMMATRIX worldTransformation)
|
|
{
|
|
XMStoreFloat4x4(&_worldTransformation, worldTransformation);
|
|
}
|
|
|
|
void SubMeshRenderer::SetAmbientLight(XMFLOAT4 ambientLight)
|
|
{
|
|
_ambientLight = ambientLight;
|
|
}
|
|
|
|
void SubMeshRenderer::SetDirectionalLight(FXMVECTOR lightVector, XMFLOAT4 lightColour)
|
|
{
|
|
_directionalLightColour = lightColour;
|
|
XMStoreFloat4(&_directionalLightVector, lightVector);
|
|
}
|
|
|
|
void SubMeshRenderer::SetCameraPosition(XMFLOAT4 cameraPosition)
|
|
{
|
|
_cameraPosition = cameraPosition;
|
|
}
|
|
|
|
bool SubMeshRenderer::Initialise()
|
|
{
|
|
_device = DirectXFramework::GetDXFramework()->GetDevice();
|
|
_deviceContext = DirectXFramework::GetDXFramework()->GetDeviceContext();
|
|
BuildShaders();
|
|
BuildVertexLayout();
|
|
BuildConstantBuffer();
|
|
BuildBlendState();
|
|
BuildRendererState();
|
|
return true;
|
|
}
|
|
|
|
void SubMeshRenderer::Render()
|
|
{
|
|
// Turn off back face culling while we render a mesh.
|
|
// We do this since ASSIMP does not appear to be setting the
|
|
// TWOSIDED property on materials correctly. Without turning off
|
|
// back face culling, some materials do not render correctly.
|
|
_deviceContext->RSSetState(_noCullRasteriserState.Get());
|
|
|
|
XMMATRIX projectionTransformation = DirectXFramework::GetDXFramework()->GetProjectionTransformation();
|
|
XMMATRIX viewTransformation = DirectXFramework::GetDXFramework()->GetCamera()->GetViewMatrix();
|
|
|
|
XMMATRIX completeTransformation = XMLoadFloat4x4(&_worldTransformation) * viewTransformation * projectionTransformation;
|
|
|
|
// Draw the first cube
|
|
|
|
CBUFFER cBuffer;
|
|
cBuffer.completeTransformation = completeTransformation;
|
|
cBuffer.worldTransformation = XMLoadFloat4x4(&_worldTransformation);
|
|
cBuffer.ambientColor = _ambientLight;
|
|
cBuffer.lightVector = XMVector4Normalize(XMLoadFloat4(&_directionalLightVector));
|
|
cBuffer.lightColor = _directionalLightColour;
|
|
cBuffer.cameraPosition = _cameraPosition;
|
|
|
|
_deviceContext->VSSetShader(_vertexShader.Get(), 0, 0);
|
|
_deviceContext->PSSetShader(_pixelShader.Get(), 0, 0);
|
|
_deviceContext->IASetInputLayout(_layout.Get());
|
|
|
|
// Set the blend state correctly to handle opacity
|
|
float blendFactors[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
|
_deviceContext->OMSetBlendState(_transparentBlendState.Get(), blendFactors, 0xffffffff);
|
|
|
|
shared_ptr<Material> material = _subMesh->GetMaterial();
|
|
float opacity = material->GetOpacity();
|
|
|
|
UINT stride = sizeof(VERTEX);
|
|
UINT offset = 0;
|
|
_vertexBuffer = _subMesh->GetVertexBuffer();
|
|
_deviceContext->IASetVertexBuffers(0, 1, _vertexBuffer.GetAddressOf(), &stride, &offset);
|
|
_indexBuffer = _subMesh->GetIndexBuffer();
|
|
_deviceContext->IASetIndexBuffer(_indexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
|
cBuffer.diffuseCoefficient = material->GetDiffuseColour();
|
|
cBuffer.specularCoefficient = material->GetSpecularColour();
|
|
cBuffer.shininess = material->GetShininess();
|
|
cBuffer.opacity = opacity;
|
|
// Update the constant buffer
|
|
_deviceContext->VSSetConstantBuffers(0, 1, _constantBuffer.GetAddressOf());
|
|
_deviceContext->UpdateSubresource(_constantBuffer.Get(), 0, 0, &cBuffer, 0, 0);
|
|
_texture = material->GetTexture();
|
|
_deviceContext->PSSetShaderResources(0, 1, _texture.GetAddressOf());
|
|
_deviceContext->PSSetConstantBuffers(0, 1, _constantBuffer.GetAddressOf());
|
|
_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
|
_deviceContext->DrawIndexed(static_cast<UINT>(_subMesh->GetIndexCount()), 0, 0);
|
|
|
|
// Turn back face culling back on in case another renderer
|
|
// relies on it
|
|
_deviceContext->RSSetState(_defaultRasteriserState.Get());
|
|
}
|
|
|
|
void SubMeshRenderer::Shutdown(void)
|
|
{
|
|
}
|
|
|
|
void SubMeshRenderer::BuildShaders()
|
|
{
|
|
DWORD shaderCompileFlags = 0;
|
|
#if defined( _DEBUG )
|
|
shaderCompileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
|
|
#endif
|
|
|
|
ComPtr<ID3DBlob> compilationMessages = nullptr;
|
|
|
|
//Compile vertex shader
|
|
HRESULT hr = D3DCompileFromFile(L"TexturedShaders.hlsl",
|
|
nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE,
|
|
"VShader", "vs_5_0",
|
|
shaderCompileFlags, 0,
|
|
_vertexShaderByteCode.GetAddressOf(),
|
|
compilationMessages.GetAddressOf());
|
|
|
|
if (compilationMessages.Get() != nullptr)
|
|
{
|
|
// If there were any compilation messages, display them
|
|
MessageBoxA(0, (char*)compilationMessages->GetBufferPointer(), 0, 0);
|
|
}
|
|
// Even if there are no compiler messages, check to make sure there were no other errors.
|
|
ThrowIfFailed(hr);
|
|
ThrowIfFailed(_device->CreateVertexShader(_vertexShaderByteCode->GetBufferPointer(), _vertexShaderByteCode->GetBufferSize(), NULL, _vertexShader.GetAddressOf()));
|
|
|
|
// Compile pixel shader
|
|
hr = D3DCompileFromFile(L"TexturedShaders.hlsl",
|
|
nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE,
|
|
"PShader", "ps_5_0",
|
|
shaderCompileFlags, 0,
|
|
_pixelShaderByteCode.GetAddressOf(),
|
|
compilationMessages.GetAddressOf());
|
|
|
|
if (compilationMessages.Get() != nullptr)
|
|
{
|
|
// If there were any compilation messages, display them
|
|
MessageBoxA(0, (char*)compilationMessages->GetBufferPointer(), 0, 0);
|
|
}
|
|
ThrowIfFailed(hr);
|
|
ThrowIfFailed(_device->CreatePixelShader(_pixelShaderByteCode->GetBufferPointer(), _pixelShaderByteCode->GetBufferSize(), NULL, _pixelShader.GetAddressOf()));
|
|
}
|
|
|
|
|
|
void SubMeshRenderer::BuildVertexLayout()
|
|
{
|
|
// Create the vertex input layout. This tells DirectX the format
|
|
// of each of the vertices we are sending to it.
|
|
|
|
D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
|
|
{
|
|
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
|
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
|
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
|
};
|
|
ThrowIfFailed(_device->CreateInputLayout(vertexDesc, ARRAYSIZE(vertexDesc), _vertexShaderByteCode->GetBufferPointer(), _vertexShaderByteCode->GetBufferSize(), _layout.GetAddressOf()));
|
|
}
|
|
|
|
void SubMeshRenderer::BuildConstantBuffer()
|
|
{
|
|
D3D11_BUFFER_DESC bufferDesc;
|
|
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
|
|
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
|
bufferDesc.ByteWidth = sizeof(CBUFFER);
|
|
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
|
ThrowIfFailed(_device->CreateBuffer(&bufferDesc, NULL, _constantBuffer.GetAddressOf()));
|
|
}
|
|
|
|
void SubMeshRenderer::BuildBlendState()
|
|
{
|
|
D3D11_BLEND_DESC transparentDesc = { 0 };
|
|
transparentDesc.AlphaToCoverageEnable = false;
|
|
transparentDesc.IndependentBlendEnable = false;
|
|
transparentDesc.RenderTarget[0].BlendEnable = true;
|
|
transparentDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
|
|
transparentDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
|
|
transparentDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
|
transparentDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
|
|
transparentDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
|
transparentDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
|
transparentDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
|
ThrowIfFailed(_device->CreateBlendState(&transparentDesc, _transparentBlendState.GetAddressOf()));
|
|
}
|
|
|
|
void SubMeshRenderer::BuildRendererState()
|
|
{
|
|
// Set default and no cull rasteriser states
|
|
D3D11_RASTERIZER_DESC rasteriserDesc;
|
|
rasteriserDesc.FillMode = D3D11_FILL_SOLID;
|
|
rasteriserDesc.CullMode = D3D11_CULL_BACK;
|
|
rasteriserDesc.FrontCounterClockwise = false;
|
|
rasteriserDesc.DepthBias = 0;
|
|
rasteriserDesc.SlopeScaledDepthBias = 0.0f;
|
|
rasteriserDesc.DepthBiasClamp = 0.0f;
|
|
rasteriserDesc.DepthClipEnable = true;
|
|
rasteriserDesc.ScissorEnable = false;
|
|
rasteriserDesc.MultisampleEnable = false;
|
|
rasteriserDesc.AntialiasedLineEnable = false;
|
|
ThrowIfFailed(_device->CreateRasterizerState(&rasteriserDesc, _defaultRasteriserState.GetAddressOf()));
|
|
rasteriserDesc.CullMode = D3D11_CULL_NONE;
|
|
ThrowIfFailed(_device->CreateRasterizerState(&rasteriserDesc, _noCullRasteriserState.GetAddressOf()));
|
|
}
|