SOL9 Sample: Direct3D12ShapesWithMultipleCommandLists
|
1 Screenshot
2 Source code
/*
* Direct3D12ShapesWithMultipleCommandLists.cpp
* Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*/
// 2016/10/10
// 2017/01/28 Updated to use ModuleFileName class and caught macro.
#define COMMONCONTROLS_V6
#define WIN10
#include <sol/direct3d12/DirectX3D12MainView.h>
#include <sol/direct3d12/DirectX3D12View.h>
#include <sol/direct3d12/DirectXMatrix.h>
#include <sol/direct3d12/Direct3D12Debug.h>
#include <sol/direct3d12/Direct3D12CommandAllocator.h>
#include <sol/direct3d12/Direct3D12RenderTargetView.h>
#include <sol/direct3d12/Direct3D12DepthStencilView.h>
#include <sol/direct3d12/Direct3D12CommonDescriptorHeap.h>
#include <sol/direct3d12/Direct3D12TransformLightConstantBufferView.h>
#include <sol/direct3d12/Direct3D12RootSignature.h>
#include <sol/direct3d12/Direct3D12BarrieredGraphicsCommandList.h>
#include <sol/direct3d12/Direct3D12PipelineState.h>
#include <sol/direct3d12/D3D12RasterizerDesc.h>
#include <sol/direct3d12/D3D12BlendDesc.h>
#include <sol/direct3d12/D3D12GraphicsPipelineStateDesc.h>
#include <sol/direct3d12/D3D12ResourceBarrier.h>
#include <sol/direct3d12/D3D12TransformLight.h>
#include <sol/direct3d12/D3D12GraphicsPipelineStateDesc.h>
#include <sol/direct3d12/Direct3D12VertexBuffer.h>
#include <sol/direct3d12/Direct3D12IndexBuffer.h>
#include <sol/direct3d12/Direct3D12Synchronizer.h>
#include <sol/direct3d12/Direct3DX12Box.h>
#include <sol/direct3d12/Direct3DX12Cylinder.h>
#include <sol/direct3d12/Direct3DX12Sphere.h>
#include <sol/direct3d12/Direct3DX12Torus.h>
#include <sol/direct3d12/DirectXTransformLight.h>
#include "resource.h"
namespace SOL {
class MainView :public DirectX3D12MainView {
//Inner class
class SimpleView :public DirectX3D12View {
private:
static const int SHAPES = 2; //Sphere and Torus only.
SmartPtr<Direct3D12CommandAllocator> commandAllocator[SHAPES];
SmartPtr<Direct3D12RenderTargetView> renderTargetView;
SmartPtr<Direct3D12DepthStencilView> depthStencilView;
SmartPtr<Direct3D12RootSignature> rootSignature;
SmartPtr<Direct3D12CommonDescriptorHeap> commonDescriptorHeap;
SmartPtr<Direct3D12BarrieredGraphicsCommandList> graphicsCommandList[SHAPES];
SmartPtr<Direct3D12PipelineState> pipelineState[SHAPES];
SmartPtr<Direct3D12Synchronizer> synchronizer;
SmartPtr<Direct3DX12Shape> shapes[SHAPES];
SmartPtr<Direct3D12TransformLightConstantBufferView> constantBufferView[SHAPES];
UINT frameIndex;
DirectXTransformLight lightedConstantBuffer;
float angle;
StringT<TCHAR> directory;
private:
virtual void createWireFramePipelineState(ID3D12Device* device)
{
//Create a graphicPipelineStateDes.
D3D12GraphicsPipelineStateDesc graphicsPipelineStateDesc(*rootSignature);
UINT count = 0;
static const D3D12_INPUT_ELEMENT_DESC* inputElements = D3D12InputElements::getPosNormalDesc(count);
D3D12_FILL_MODE mode = D3D12_FILL_MODE_SOLID;
D3D12RasterizerDesc rasterDesc(D3D12_FILL_MODE_WIREFRAME, D3D12_CULL_MODE_NONE, true);
D3D12BlendDesc blendDesc;
graphicsPipelineStateDesc.setInputLayput(inputElements, count);
graphicsPipelineStateDesc.setRasterizerState(rasterDesc);
graphicsPipelineStateDesc.setBlendState(blendDesc);
//Shader and Pixel Shader for WireFrame mode.
StringT<TCHAR> vsshaderFile = getShaderFilePath(directory, _T("VertexShaderWireFrame.cso"));
StringT<TCHAR> psshaderFile = getShaderFilePath(directory, _T("PixelShaderWireFrame.cso"));
graphicsPipelineStateDesc.setVertexShader(vsshaderFile);
graphicsPipelineStateDesc.setPixelShader(psshaderFile);
pipelineState[1] = new Direct3D12PipelineState(device, graphicsPipelineStateDesc);
}
virtual void createSolidPipelineState(ID3D12Device* device)
{
//Create a graphicPipelineStateDes.
D3D12GraphicsPipelineStateDesc graphicsPipelineStateDesc(*rootSignature);
UINT count = 0;
static const D3D12_INPUT_ELEMENT_DESC* inputElements = D3D12InputElements::getPosNormalDesc(count);
D3D12RasterizerDesc rasterDesc(D3D12_FILL_MODE_SOLID, D3D12_CULL_MODE_NONE, true);
D3D12BlendDesc blendDesc;
graphicsPipelineStateDesc.setInputLayput(inputElements, count);
graphicsPipelineStateDesc.setRasterizerState(rasterDesc);
graphicsPipelineStateDesc.setBlendState(blendDesc);
//Vertex and Pixel Shader for Solid mode
StringT<TCHAR> vsshaderFile = getShaderFilePath(directory, _T("VertexShader.cso"));
StringT<TCHAR> psshaderFile = getShaderFilePath(directory, _T("PixelShader.cso"));
graphicsPipelineStateDesc.setVertexShader(vsshaderFile);
graphicsPipelineStateDesc.setPixelShader(psshaderFile);
pipelineState[0] = new Direct3D12PipelineState(device, graphicsPipelineStateDesc);
}
void setDirectXTransformLight(int i)
{
int width = 0;
int height = 0;
getClientSize(width, height);
try {
XMVECTOR eye = XMVectorSet( 0.0f, 2.0f, -8.0f, 0.0f );
XMVECTOR at = XMVectorSet( 0.0f, 0.0f, 0.0f, 0.0f );
XMVECTOR up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
lightedConstantBuffer.world = DirectXMatrix::rotationY( angle );
lightedConstantBuffer.view = DirectXMatrix::lookAtLH(eye, at, up);
lightedConstantBuffer.projection = DirectXMatrix::perspectiveFovLH( XM_PIDIV2*0.3f, width / (FLOAT)height, 0.01f, 100.0f );
lightedConstantBuffer.lightDirection = XMFLOAT4( -0.8f, 0.8f, 0.3f, 1.0f );
lightedConstantBuffer.lightColor = XMFLOAT4( 0.0f, 0.2f, 1.0f, 1.0f );
constantBufferView[i]->update(lightedConstantBuffer);
} catch (Exception& ex) {
caught(ex);
}
}
//Create a renderTargetView and a depthStencilView.
void createViews(ID3D12Device* device, IDXGISwapChain3* swapChain,
int width, int height)
{
renderTargetView = new Direct3D12RenderTargetView(device, swapChain);
depthStencilView = new Direct3D12DepthStencilView(device, width, height);
}
//Delete a renderTargetView and a depthStencilView.
void deleteViews()
{
graphicsCommandList[0]->setOMRenderTargets(0, nullptr, FALSE, nullptr);
graphicsCommandList[1]->setOMRenderTargets(0, nullptr, FALSE, nullptr);
renderTargetView = NULL;
depthStencilView = NULL;
}
void createShapes(ID3D12Device* device)
{
try {
int i = 0;
//1 Create a sphere.
{
float fRadius = 0.5f;
UINT uSlices = 20;
UINT uStacks = 20;
shapes[i++] = new Direct3DX12Sphere(device,
fRadius, uSlices, uStacks);
}
//2 Create a torus.
{
float fInnerRadius = 0.2f;
float fOuterRadius = 1.5f;
UINT uSides = 30;
UINT uRings = 30;
shapes[i ] = new Direct3DX12Torus(device,
fInnerRadius, fOuterRadius, uSides,
uRings);
}
} catch (Exception& ex) {
caught(ex);
}
}
public:
virtual void initialize()
{
int width = 0;
int height = 0;
validateClientSize(width, height);
Direct3D12Device* device = getD3D12Device();
DirectXGISwapChain3* swapChain = getSwapChain3();
Direct3D12CommandQueue* commandQueue = getCommandQueue();
try {
rootSignature = new Direct3D12RootSignature(*device);
commonDescriptorHeap = new Direct3D12CommonDescriptorHeap(*device, SHAPES);
for (int i = 0; i<SHAPES; i++) {
commandAllocator[i] = new Direct3D12CommandAllocator(*device);
graphicsCommandList[i] = new Direct3D12BarrieredGraphicsCommandList(*device, *commandAllocator[i]);
constantBufferView[i] = new Direct3D12TransformLightConstantBufferView(*device,
commonDescriptorHeap->getCPUHandle(i));
}
synchronizer = new Direct3D12Synchronizer(*device, *commandQueue);
createViews(*device, *swapChain, width, height);
//1 Create your own shape
createShapes(*device);
//2 Create a pipelineState from the cube.
createWireFramePipelineState(*device);
createSolidPipelineState(*device);
} catch (Exception& ex) {
caught(ex);
}
}
bool ready()
{
Direct3D12Device* device = getD3D12Device();
DirectXGISwapChain3* swapChain = getSwapChain3();
Direct3D12CommandQueue* commandQueue = getCommandQueue();
if (
device == nullptr ||
commandQueue == nullptr ||
swapChain == nullptr ||
renderTargetView == nullptr ||
depthStencilView == nullptr ||
rootSignature == nullptr ||
commonDescriptorHeap == nullptr ||
synchronizer == nullptr ) {
return false;
}
return true;
}
virtual void display()
{
int width = 0;
int height = 0;
validateClientSize(width, height);
if ( !ready() ) {
return;
}
Direct3D12Device* device = getD3D12Device();
DirectXGISwapChain3* swapChain = getSwapChain3();
Direct3D12CommandQueue* commandQueue = getCommandQueue();
try {
for(int i = 0; i<SHAPES; i++) {
frameIndex = swapChain->getCurrentBackBufferIndex();
graphicsCommandList[i]->startRendering(renderTargetView->getResource(frameIndex));
graphicsCommandList[i]->setGraphicsRootSignature(*rootSignature);
graphicsCommandList[i]->setDescriptorHeap(*commonDescriptorHeap);
graphicsCommandList[i]->setGraphicsRootDescriptorTable(0,
commonDescriptorHeap->getGPUHandle(0));
graphicsCommandList[i]->setPipelineState(*pipelineState[i]);
graphicsCommandList[i]->setRSViewport(width, height);
graphicsCommandList[i]->setRSScissorRect(width, height);
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = renderTargetView->getHandle(frameIndex);
//Clear renderTargetView for graphicsCommandList[0] only.
graphicsCommandList[0]->clearRenderTargetView(rtvHandle, XMColor(0.0f, 0.0f, 0.0f, 1.0f));
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = *depthStencilView;
//Clear depthStencilView for graphicsCommandList[0] only.
graphicsCommandList[0]->clearDepthStencilView(dsvHandle);
graphicsCommandList[i]->setOMRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
graphicsCommandList[i]->setGraphicsRootDescriptorTable(i,
commonDescriptorHeap->getGPUHandle(i));
graphicsCommandList[i]->setPipelineState(*pipelineState[i]);
setDirectXTransformLight(i);
shapes[i]->drawIndexedInstanced(graphicsCommandList[i]);
graphicsCommandList[i]->endRendering();
}
ID3D12GraphicsCommandList* commandList[] = {*graphicsCommandList[0], *graphicsCommandList[1]};
commandQueue->executeCommandLists(_countof(commandList), (ID3D12CommandList *const *)commandList );
swapChain->present(1, 0);
synchronizer->waitForCompletion();
} catch (Exception& ex) {
caught(ex);
}
}
virtual void resize(int width, int height)
{
Direct3D12Device* device = getD3D12Device();
DirectXGISwapChain3* swapChain = getSwapChain3();
if (device == NULL ||
swapChain == NULL) {
return ;
}
try {
deleteViews();
swapChain->resizeBuffers(width, height);
createViews(*device, *swapChain, width, height);
} catch (Exception& ex) {
caught(ex);
}
}
void render()
{
angle += 0.02f;
display();
}
void incrementAngle()
{
angle += 0.1f;
display();
}
void decrementAngle()
{
angle -= 0.1f;
display();
}
public:
//Constructor
SimpleView(DirectX3D12MainView* parent, const TCHAR* name, Args& args)
:DirectX3D12View(parent, name, args),
angle (0.6f),
frameIndex(0),
directory(_T(""))
{
directory = (const TCHAR*)args.get(XmNapplicationDirectory);
postResizeRequest();
}
~SimpleView()
{
}
};
// Inner class ends.
private:
SmartPtr<SimpleView> view;
public:
/**
* Constructor
*/
MainView(Application& applet, const TCHAR* name, Args& args)
:DirectX3D12MainView(applet, name,
args.set(XmNstyle, (ulong)WS_CLIPCHILDREN|WS_CLIPSIBLINGS) ),
view(NULL)
{
const TCHAR* directory = (const TCHAR*)args.get(XmNapplicationDirectory);
// 1 Restore the replacement of MainView
restorePlacement();
// 2 Create a view of SimpleView.
Args ar;
int width = 0;
int height = 0;
getClientSize(width, height);
ar.set(XmNwidth, width);
ar.set(XmNheight,height);
ar.set(XmNapplicationDirectory, (const TCHAR*)directory);
ar.set(XmNstyle, WS_BORDER|WS_CHILD|WS_VISIBLE);
view = new SimpleView(this, _T(""), ar);
// 3 Post a resize request to this MainView.
postResizeRequest();
}
public:
~MainView()
{
}
void resize(int width, int height)
{
if (view != nullptr) {
view -> reshape(0, 0, width, height);
}
}
virtual void keyDown(Event& event)
{
WPARAM wparam = event.getWParam();
switch(wparam) {
case VK_LEFT:
view -> decrementAngle();
break;
case VK_RIGHT:
view -> incrementAngle();
break;
}
}
};
}
//////////////////////////////////////////////
//
void Main(int argc, TCHAR** argv)
{
ModuleFileName module(argv[0]);
const TCHAR* directory = module.getDirectory();
const TCHAR* appClass = module.getAppName();
try {
Application applet(appClass, argc, argv);
Args args;
args.set(XmNwidth, 480);
args.set(XmNheight, 480);
args.set(XmNapplicationDirectory, directory);
MainView mainView(applet, appClass, args);
mainView.realize();
applet.run();
} catch (Exception& ex) {
caught(ex);
}
}
Last modified: 1 Feb 2017
Copyright (c) 2017 Antillia.com ALL RIGHTS RESERVED.