Added follow cam
Added "Controlled" mesh classes Added Global Lighting Class Added Gamepad controls Split terrain nodes into Height and Perlin classes Fixed Splitmesh node stuff
This commit is contained in:
291
Graphics2/SkyNode.cpp
Normal file
291
Graphics2/SkyNode.cpp
Normal file
@ -0,0 +1,291 @@
|
||||
#include "SkyNode.h"
|
||||
|
||||
SkyNode::SkyNode(wstring name, wstring skyCubeTextureName, float skyRadius) : SceneNode(name)
|
||||
{
|
||||
_skyCubeTextureName = skyCubeTextureName;
|
||||
_skyRadius = skyRadius;
|
||||
}
|
||||
|
||||
SkyNode::~SkyNode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool SkyNode::Initialise()
|
||||
{
|
||||
_device = DirectXFramework::GetDXFramework()->GetDevice();
|
||||
_deviceContext = DirectXFramework::GetDXFramework()->GetDeviceContext();
|
||||
|
||||
if (_device.Get() == nullptr || _deviceContext.Get() == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CreateSphere(_skyRadius, 180);
|
||||
GenerateBuffers();
|
||||
BuildShaders();
|
||||
BuildVertexLayout();
|
||||
BuildConstantBuffer();
|
||||
BuildRendererStates();
|
||||
BuildDepthStencilState();
|
||||
LoadSkyboxTexture();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkyNode::CreateSphere(float radius, size_t tessellation)
|
||||
{
|
||||
_skyDomeVerts.clear();
|
||||
_indices.clear();
|
||||
|
||||
size_t verticalSegments = tessellation;
|
||||
size_t horizontalSegments = tessellation * 2;
|
||||
|
||||
// Create rings of vertices at progressively higher latitudes.
|
||||
for (size_t i = 0; i <= verticalSegments; i++)
|
||||
{
|
||||
float v = 1 - (float)i / verticalSegments;
|
||||
|
||||
float latitude = (i * XM_PI / verticalSegments) - XM_PIDIV2;
|
||||
float dy, dxz;
|
||||
|
||||
XMScalarSinCos(&dy, &dxz, latitude);
|
||||
|
||||
// Create a single ring of vertices at this latitude.
|
||||
for (size_t j = 0; j <= horizontalSegments; j++)
|
||||
{
|
||||
float u = (float)j / horizontalSegments;
|
||||
|
||||
float longitude = j * XM_2PI / horizontalSegments;
|
||||
float dx, dz;
|
||||
|
||||
XMScalarSinCos(&dx, &dz, longitude);
|
||||
|
||||
dx *= dxz;
|
||||
dz *= dxz;
|
||||
|
||||
SkyVertex vertex;
|
||||
vertex.Position.x = dx * radius;
|
||||
vertex.Position.y = dy * radius;
|
||||
vertex.Position.z = dz * radius;
|
||||
_skyDomeVerts.push_back(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the index buffer with triangles joining each pair of latitude rings.
|
||||
size_t stride = horizontalSegments + 1;
|
||||
|
||||
for (size_t i = 0; i < verticalSegments; i++)
|
||||
{
|
||||
for (size_t j = 0; j <= horizontalSegments; j++)
|
||||
{
|
||||
size_t nextI = i + 1;
|
||||
size_t nextJ = (j + 1) % stride;
|
||||
|
||||
_indices.push_back((UINT)(i * stride + j));
|
||||
_indices.push_back((UINT)(nextI * stride + j));
|
||||
_indices.push_back((UINT)(i * stride + nextJ));
|
||||
|
||||
_indices.push_back((UINT)(i * stride + nextJ));
|
||||
_indices.push_back((UINT)(nextI * stride + j));
|
||||
_indices.push_back((UINT)(nextI * stride + nextJ));
|
||||
}
|
||||
}
|
||||
_vertexCount = (unsigned int)_skyDomeVerts.size();
|
||||
_indicesCount = (unsigned int)_indices.size();
|
||||
}
|
||||
|
||||
void SkyNode::GenerateBuffers()
|
||||
{
|
||||
// Setup the structure that specifies how big the vertex
|
||||
// buffer should be
|
||||
D3D11_BUFFER_DESC vertexBufferDescriptor;
|
||||
vertexBufferDescriptor.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
vertexBufferDescriptor.ByteWidth = sizeof(SkyVertex) * _vertexCount;
|
||||
vertexBufferDescriptor.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
vertexBufferDescriptor.CPUAccessFlags = 0;
|
||||
vertexBufferDescriptor.MiscFlags = 0;
|
||||
vertexBufferDescriptor.StructureByteStride = 0;
|
||||
|
||||
// Now set up a structure that tells DirectX where to get the
|
||||
// data for the vertices from
|
||||
D3D11_SUBRESOURCE_DATA vertexInitialisationData;
|
||||
vertexInitialisationData.pSysMem = &_skyDomeVerts[0];
|
||||
|
||||
// and create the vertex buffer
|
||||
ThrowIfFailed(_device->CreateBuffer(&vertexBufferDescriptor, &vertexInitialisationData, _vertexBuffer.GetAddressOf()));
|
||||
|
||||
// Setup the structure that specifies how big the index
|
||||
// buffer should be
|
||||
D3D11_BUFFER_DESC indexBufferDescriptor;
|
||||
indexBufferDescriptor.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
indexBufferDescriptor.ByteWidth = sizeof(UINT) * _indicesCount;
|
||||
indexBufferDescriptor.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
indexBufferDescriptor.CPUAccessFlags = 0;
|
||||
indexBufferDescriptor.MiscFlags = 0;
|
||||
indexBufferDescriptor.StructureByteStride = 0;
|
||||
|
||||
// Now set up a structure that tells DirectX where to get the
|
||||
// data for the indices from
|
||||
D3D11_SUBRESOURCE_DATA indexInitialisationData;
|
||||
indexInitialisationData.pSysMem = &_indices[0];
|
||||
|
||||
// and create the index buffer
|
||||
ThrowIfFailed(_device->CreateBuffer(&indexBufferDescriptor, &indexInitialisationData, _indexBuffer.GetAddressOf()));
|
||||
}
|
||||
|
||||
void SkyNode::Render()
|
||||
{
|
||||
XMMATRIX projectionTransformation = DirectXFramework::GetDXFramework()->GetProjectionTransformation();
|
||||
XMMATRIX viewTransformation = DirectXFramework::GetDXFramework()->GetCamera()->GetViewMatrix();
|
||||
|
||||
XMFLOAT4 cameraPosition;
|
||||
XMStoreFloat4(&cameraPosition, DirectXFramework::GetDXFramework()->GetCamera()->GetCameraPosition());
|
||||
|
||||
XMMATRIX skyWorldTransformation = XMMatrixTranslation(cameraPosition.x, cameraPosition.y, cameraPosition.z);
|
||||
XMMATRIX completeTransformation = skyWorldTransformation * viewTransformation * projectionTransformation;
|
||||
|
||||
// Draw the first cube
|
||||
SCBUFFER cBuffer;
|
||||
cBuffer.completeTransformation = completeTransformation;
|
||||
|
||||
_deviceContext->PSSetShaderResources(0, 1, _skyCubeTexture.GetAddressOf());
|
||||
|
||||
_deviceContext->VSSetShader(_vertexShader.Get(), 0, 0);
|
||||
_deviceContext->PSSetShader(_pixelShader.Get(), 0, 0);
|
||||
_deviceContext->IASetInputLayout(_layout.Get());
|
||||
|
||||
UINT stride = sizeof(SkyVertex);
|
||||
UINT offset = 0;
|
||||
_deviceContext->IASetVertexBuffers(0, 1, _vertexBuffer.GetAddressOf(), &stride, &offset);
|
||||
_deviceContext->IASetIndexBuffer(_indexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
// Update the constant buffer
|
||||
_deviceContext->VSSetConstantBuffers(0, 1, _constantBuffer.GetAddressOf());
|
||||
_deviceContext->UpdateSubresource(_constantBuffer.Get(), 0, 0, &cBuffer, 0, 0);
|
||||
_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
_deviceContext->RSSetState(_noCullRasteriserState.Get());
|
||||
_deviceContext->OMSetDepthStencilState(_stencilState.Get(), 1);
|
||||
_deviceContext->DrawIndexed(_indicesCount, 0, 0);
|
||||
_deviceContext->OMSetDepthStencilState(nullptr, 1);
|
||||
_deviceContext->RSSetState(_defaultRasteriserState.Get());
|
||||
|
||||
}
|
||||
|
||||
void SkyNode::Shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void SkyNode::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"SkyShader.hlsl",
|
||||
nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE,
|
||||
"VS", "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"SkyShader.hlsl",
|
||||
nullptr, D3D_COMPILE_STANDARD_FILE_INCLUDE,
|
||||
"PS", "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 SkyNode::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 }
|
||||
};
|
||||
ThrowIfFailed(_device->CreateInputLayout(vertexDesc, ARRAYSIZE(vertexDesc), _vertexShaderByteCode->GetBufferPointer(), _vertexShaderByteCode->GetBufferSize(), _layout.GetAddressOf()));
|
||||
}
|
||||
|
||||
void SkyNode::BuildConstantBuffer()
|
||||
{
|
||||
D3D11_BUFFER_DESC bufferDesc;
|
||||
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
|
||||
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
bufferDesc.ByteWidth = sizeof(SCBUFFER);
|
||||
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
ThrowIfFailed(_device->CreateBuffer(&bufferDesc, NULL, _constantBuffer.GetAddressOf()));
|
||||
}
|
||||
|
||||
void SkyNode::LoadSkyboxTexture()
|
||||
{
|
||||
ThrowIfFailed(CreateDDSTextureFromFile(_device.Get(),
|
||||
_skyCubeTextureName.c_str(),
|
||||
nullptr,
|
||||
_skyCubeTexture.GetAddressOf()
|
||||
));
|
||||
}
|
||||
|
||||
void SkyNode::BuildRendererStates()
|
||||
{
|
||||
// Set default and wireframe 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()));
|
||||
}
|
||||
|
||||
void SkyNode::BuildDepthStencilState()
|
||||
{
|
||||
D3D11_DEPTH_STENCIL_DESC stencilDesc;
|
||||
stencilDesc.DepthEnable = true;
|
||||
stencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||
stencilDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
|
||||
stencilDesc.StencilEnable = false;
|
||||
stencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
||||
stencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
||||
stencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||
stencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
|
||||
stencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
|
||||
stencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
|
||||
stencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||
stencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
|
||||
stencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
|
||||
stencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
|
||||
ThrowIfFailed(_device->CreateDepthStencilState(&stencilDesc, _stencilState.GetAddressOf()));
|
||||
}
|
Reference in New Issue
Block a user