diff options
Diffstat (limited to 'test/src/D3D11/Scene3D.cpp')
| -rw-r--r-- | test/src/D3D11/Scene3D.cpp | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/test/src/D3D11/Scene3D.cpp b/test/src/D3D11/Scene3D.cpp new file mode 100644 index 0000000..6186019 --- /dev/null +++ b/test/src/D3D11/Scene3D.cpp @@ -0,0 +1,321 @@ +/* +* Copyright (c) 2008-2016, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "Scene3D.h" +#include "Shaders/bin/GeometryVS.h" +#include "Shaders/bin/GeometryColorNormalPS.h" +#include "Shaders/bin/GeometryColorPS.h" +#include "Shaders/bin/CopyColorPS.h" +#include "Shaders/bin/FullScreenTriangleVS.h" + +struct Scene3DVertex +{ + D3DXVECTOR3 pos; + D3DXVECTOR3 nor; +}; + +D3D11_INPUT_ELEMENT_DESC VertexLayout[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, +}; + +//----------------------------------------------------------------------------- +SceneRenderer::SceneRenderer() + : m_pInputLayout(NULL) + , m_VertexBuffer(NULL) + , m_pConstantBuffer(NULL) +{ +} + +//----------------------------------------------------------------------------- +HRESULT SceneRenderer::OnCreateDevice(ID3D11Device* pd3dDevice, bool ReversedDepthTest) +{ + HRESULT hr = S_OK; + + // Create the input layout + UINT NumElements = sizeof(VertexLayout)/sizeof(VertexLayout[0]); + V( pd3dDevice->CreateInputLayout(VertexLayout, NumElements, g_GeometryVS, sizeof(g_GeometryVS), &m_pInputLayout) ); + + // Create the floor plane + float w = 1.0f; + Scene3DVertex vertices[] = + { + { D3DXVECTOR3(-w, 0, w), D3DXVECTOR3(0.0f, 1.0f, 0.0f) }, + { D3DXVECTOR3( w, 0, w), D3DXVECTOR3(0.0f, 1.0f, 0.0f) }, + { D3DXVECTOR3( w, 0, -w), D3DXVECTOR3(0.0f, 1.0f, 0.0f) }, + { D3DXVECTOR3(-w, 0, -w), D3DXVECTOR3(0.0f, 1.0f, 0.0f) }, + }; + + D3D11_BUFFER_DESC bd; + bd.Usage = D3D11_USAGE_DEFAULT; + bd.ByteWidth = sizeof(Scene3DVertex) * 4; + bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bd.CPUAccessFlags = 0; + bd.MiscFlags = 0; + bd.StructureByteStride = 0; + D3D11_SUBRESOURCE_DATA InitData; + InitData.pSysMem = vertices; + V( pd3dDevice->CreateBuffer(&bd, &InitData, &m_VertexBuffer) ); + + // Create index buffer + DWORD indices[] = + { + 0,1,2, + 0,2,3, + }; + + bd.Usage = D3D11_USAGE_DEFAULT; + bd.ByteWidth = sizeof(DWORD) * 6; + bd.BindFlags = D3D11_BIND_INDEX_BUFFER; + bd.CPUAccessFlags = 0; + bd.MiscFlags = 0; + bd.StructureByteStride = 0; + InitData.pSysMem = indices; + V( pd3dDevice->CreateBuffer(&bd, &InitData, &m_IndexBuffer) ); + + // Create the constant buffer + static D3D11_BUFFER_DESC desc = + { + sizeof(m_Constants), //ByteWidth + D3D11_USAGE_DEFAULT, //Usage + D3D11_BIND_CONSTANT_BUFFER, //BindFlags + 0, //CPUAccessFlags + 0 //MiscFlags + }; + V( pd3dDevice->CreateBuffer(&desc, NULL, &m_pConstantBuffer) ); + + D3D11_BLEND_DESC BlendStateDesc; + BlendStateDesc.AlphaToCoverageEnable = FALSE; + BlendStateDesc.IndependentBlendEnable = TRUE; + for (int i = 0; i < 8; ++i) + { + BlendStateDesc.RenderTarget[i].BlendEnable = FALSE; + BlendStateDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + } + V( pd3dDevice->CreateBlendState(&BlendStateDesc, &m_pBlendState_Disabled) ); + + static D3D11_RASTERIZER_DESC RasterStateDesc = + {D3D11_FILL_SOLID, //FillMode + D3D11_CULL_NONE, //CullMode + 0x0, //FrontCounterClockwise + 0x0/*0.000000f*/, //DepthBias + 0.f, //DepthBiasClamp + 0.f, //SlopeScaledDepthBias + 0x1, //DepthClipEnable + 0x0, //ScissorEnable + 0x0, //MultisampleEnable + 0x0 //AntialiasedLineEnable + }; + V( pd3dDevice->CreateRasterizerState(&RasterStateDesc, &m_pRasterizerState_NoCull_NoScissor) ); + + static D3D11_DEPTH_STENCIL_DESC DepthStencilStateDesc = + {FALSE, //DepthEnable + D3D11_DEPTH_WRITE_MASK_ZERO, //DepthWriteMask + D3D11_COMPARISON_NEVER, //DepthFunc + FALSE, //StencilEnable + 0, //StencilReadMask + 0xFF, //StencilWriteMask + + {D3D11_STENCIL_OP_REPLACE, //StencilFailOp + D3D11_STENCIL_OP_REPLACE, //StencilDepthFailOp + D3D11_STENCIL_OP_REPLACE, //StencilPassOp + D3D11_COMPARISON_ALWAYS //StencilFunc + }, //FrontFace + + {D3D11_STENCIL_OP_REPLACE, //StencilFailOp + D3D11_STENCIL_OP_REPLACE, //StencilDepthFailOp + D3D11_STENCIL_OP_REPLACE, //StencilPassOp + D3D11_COMPARISON_ALWAYS //StencilFunc + } //BackFace + }; + V( pd3dDevice->CreateDepthStencilState(&DepthStencilStateDesc, &m_pDepthStencilState_Disabled) ); + + DepthStencilStateDesc.DepthEnable = TRUE; + DepthStencilStateDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + DepthStencilStateDesc.DepthFunc = ReversedDepthTest ? D3D11_COMPARISON_GREATER_EQUAL : D3D11_COMPARISON_LESS_EQUAL; + DepthStencilStateDesc.StencilEnable = TRUE; + V( pd3dDevice->CreateDepthStencilState(&DepthStencilStateDesc, &m_pDepthStencilState_Enabled) ); + + D3D11_SAMPLER_DESC samplerDesc; + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.MipLODBias = 0.0f; + samplerDesc.MaxAnisotropy = 1; + samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; + samplerDesc.BorderColor[0] = 0.f; + samplerDesc.BorderColor[1] = 0.f; + samplerDesc.BorderColor[2] = 0.f; + samplerDesc.BorderColor[3] = 0.f; + samplerDesc.MinLOD = -D3D11_FLOAT32_MAX; + samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + V( pd3dDevice->CreateSamplerState(&samplerDesc, &m_pSamplerState_PointClamp) ); + + V( pd3dDevice->CreateVertexShader(g_FullScreenTriangleVS, sizeof(g_FullScreenTriangleVS), NULL, &m_pFullScreenTriangleVS) ); + V( pd3dDevice->CreatePixelShader(g_CopyColorPS, sizeof(g_CopyColorPS), NULL, &m_pCopyColorPS) ); + + V( pd3dDevice->CreateVertexShader(g_GeometryVS, sizeof(g_GeometryVS), NULL, &m_pGeometryVS) ); + V( pd3dDevice->CreatePixelShader(g_GeometryColorNormalPS, sizeof(g_GeometryColorNormalPS), NULL, &m_pGeometryColorNormalPS) ); + V( pd3dDevice->CreatePixelShader(g_GeometryColorPS, sizeof(g_GeometryColorPS), NULL, &m_pGeometryColorPS) ); + + return S_OK; +} + +//----------------------------------------------------------------------------- +#if DUMP_GEOMETRY +void SceneRenderer::DumpGeometry(const SceneViewInfo* pSceneView, SceneMesh* pMesh) +{ + CDXUTSDKMesh &SDKMesh = pMesh->GetSDKMesh(); + + for (UINT subset = 0; subset < SDKMesh.GetNumSubsets(0); ++subset) + { + SDKMESH_SUBSET* pSubset = SDKMesh.GetSubset(0, subset); + + FILE *fp = fopen("SibenikVertices.bin", "wb"); + if (fp) + { + BYTE* pVertexData = SDKMesh.GetRawVerticesAt(0); + UINT Stride = (UINT)SDKMesh.GetVertexStride(0,0); + UINT64 NVerts = SDKMesh.GetNumVertices(0,0); + D3DXMATRIX WVMatrix = pSceneView->WorldViewMatrix; + for (UINT64 i = 0; i < NVerts; ++i) + { + D3DXVECTOR3 *v = (D3DXVECTOR3 *)(&pVertexData[i * Stride]); + D3DXVECTOR3 vCam; + D3DXVec3TransformCoord(&vCam, v, &WVMatrix); + + // Write view-space vertex position for left-handed coord systems + fwrite(&vCam, sizeof(vCam), 1, fp); + } + fclose(fp); + } + + fp = fopen("SibenikIndices.bin", "wb"); + if (fp) + { + if (SDKMesh.GetIBFormat11(0) == DXGI_FORMAT_R32_UINT) + { + UINT* pIndexData = (UINT*)SDKMesh.GetRawIndicesAt(0); + UINT64 NIndices = SDKMesh.GetNumIndices(0); + fwrite(pIndexData, sizeof(UINT), NIndices, fp); + } + fclose(fp); + exit(0); + } + } +} +#endif + +//----------------------------------------------------------------------------- +void SceneRenderer::RenderMesh(ID3D11DeviceContext* pD3DContext, const SceneViewInfo* pSceneView, SceneMesh* pMesh) +{ +#if DUMP_GEOMETRY + DumpGeometry(pSceneView, pMesh); +#endif + + pD3DContext->OMSetDepthStencilState(m_pDepthStencilState_Enabled, pSceneView->StencilRef); + pD3DContext->OMSetBlendState(m_pBlendState_Disabled, NULL, 0xFFFFFFFF); + pD3DContext->RSSetState(m_pRasterizerState_NoCull_NoScissor); + + ID3D11PixelShader* pGeometryPS = pSceneView->UseGBufferNormals ? m_pGeometryColorNormalPS : m_pGeometryColorPS; + + pD3DContext->VSSetShader(m_pGeometryVS, NULL, 0); + pD3DContext->PSSetShader(pGeometryPS, NULL, 0); + pD3DContext->VSSetConstantBuffers(0, 1, &m_pConstantBuffer); + pD3DContext->PSSetConstantBuffers(0, 1, &m_pConstantBuffer); + + // Update constant buffer + m_Constants.WorldView = pSceneView->WorldViewMatrix; + m_Constants.WorldViewProjection = m_Constants.WorldView * pSceneView->ProjectionMatrix; + m_Constants.IsWhite = float(!pMesh->UseShading()); + D3DXMatrixInverse(&m_Constants.WorldViewInverse, NULL, &m_Constants.WorldView); + pD3DContext->UpdateSubresource(m_pConstantBuffer, 0, NULL, &m_Constants, 0, 0); + + // Draw mesh + CDXUTSDKMesh &SDKMesh = pMesh->GetSDKMesh(); + ID3D11Buffer* pVB = SDKMesh.GetVB11(0,0); + ID3D11Buffer* pIB = SDKMesh.GetIB11(0); + DXGI_FORMAT IBFormat = SDKMesh.GetIBFormat11(0); + UINT Stride = (UINT)SDKMesh.GetVertexStride(0,0); + UINT Offset = 0; + pD3DContext->IASetVertexBuffers(0, 1, &pVB, &Stride, &Offset); + pD3DContext->IASetIndexBuffer(pIB, IBFormat, 0); + pD3DContext->IASetInputLayout(m_pInputLayout); + pD3DContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + for (UINT subset = 0; subset < SDKMesh.GetNumSubsets(0); ++subset) + { + SDKMESH_SUBSET* pSubset = SDKMesh.GetSubset(0, subset); + pD3DContext->DrawIndexed((UINT)pSubset->IndexCount, (UINT)pSubset->IndexStart, (UINT)pSubset->VertexStart); + } + + // Draw ground plane + if (pSceneView->AllowGroundPlane && pMesh->UseGroundPlane()) + { + D3DXMATRIX mTranslate; + D3DXMatrixTranslation(&mTranslate, 0.0f, pMesh->GetGroundHeight(), 0.0f); + + m_Constants.WorldView = mTranslate * m_Constants.WorldView; + m_Constants.WorldViewProjection = m_Constants.WorldView * pSceneView->ProjectionMatrix; + m_Constants.IsWhite = true; + D3DXMatrixInverse(&m_Constants.WorldViewInverse, NULL, &m_Constants.WorldView); + pD3DContext->UpdateSubresource(m_pConstantBuffer, 0, NULL, &m_Constants, 0, 0); + + UINT stride = sizeof(Scene3DVertex); + UINT offset = 0; + pD3DContext->IASetVertexBuffers (0, 1, &m_VertexBuffer, &stride, &offset); + pD3DContext->IASetIndexBuffer (m_IndexBuffer, DXGI_FORMAT_R32_UINT, 0); + pD3DContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + pD3DContext->IASetInputLayout (m_pInputLayout); + + pD3DContext->DrawIndexed(6, 0, 0); + } +} + +//----------------------------------------------------------------------------- +void SceneRenderer::CopyColors(ID3D11DeviceContext* pD3DContext, ID3D11ShaderResourceView *pColorSRV) +{ + pD3DContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + pD3DContext->OMSetDepthStencilState(m_pDepthStencilState_Disabled, 0); + pD3DContext->OMSetBlendState(m_pBlendState_Disabled, NULL, 0xFFFFFFFF); + pD3DContext->RSSetState(m_pRasterizerState_NoCull_NoScissor); + + pD3DContext->VSSetShader(m_pFullScreenTriangleVS, NULL, 0); + pD3DContext->VSSetConstantBuffers(0, 1, &m_pConstantBuffer); + + pD3DContext->PSSetShader(m_pCopyColorPS, NULL, 0); + pD3DContext->PSSetConstantBuffers(0, 1, &m_pConstantBuffer); + pD3DContext->PSSetSamplers(0, 1, &m_pSamplerState_PointClamp); + pD3DContext->PSSetShaderResources(0, 1, &pColorSRV); + + pD3DContext->Draw(3, 0); +} + +//----------------------------------------------------------------------------- +void SceneRenderer::OnDestroyDevice() +{ + SAFE_RELEASE(m_pInputLayout); + SAFE_RELEASE(m_pConstantBuffer); + SAFE_RELEASE(m_VertexBuffer); + SAFE_RELEASE(m_IndexBuffer); + SAFE_RELEASE(m_pBlendState_Disabled); + SAFE_RELEASE(m_pRasterizerState_NoCull_NoScissor); + SAFE_RELEASE(m_pDepthStencilState_Disabled); + SAFE_RELEASE(m_pDepthStencilState_Enabled); + SAFE_RELEASE(m_pSamplerState_PointClamp); + SAFE_RELEASE(m_pFullScreenTriangleVS); + SAFE_RELEASE(m_pCopyColorPS); + SAFE_RELEASE(m_pGeometryVS); + SAFE_RELEASE(m_pGeometryColorNormalPS); + SAFE_RELEASE(m_pGeometryColorPS); +} |