SOL9 Sample: Direct3D12MainView
|
1 Screenshot
2 Source code
/*
* Direct3D12MainView.cpp
* Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*/
// 2016/10/01
// 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/Direct3d12CommandQueue.h>
#include <sol/direct3d12/Direct3D12CommandAllocator.h>
#include <sol/direct3d12/Direct3D12RenderTargetView.h>
#include <sol/direct3d12/Direct3D12DepthStencilView.h>
#include <sol/direct3d12/Direct3D12RootSignature.h>
#include <sol/direct3d12/Direct3D12GraphicsCommandList.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/Direct3D12Synchronizer.h>
#include <sol/direct3d12/D3D12GraphicsPipelineStateDesc.h>
#include <sol/direct3d12/Direct3D12VertexBuffer.h>
#include <sol/direct3d12/Direct3D12IndexBuffer.h>
#include <DirectXMath.h>
#include <sol/PushButton.h>
#include "resource.h"
using namespace DirectX;
namespace SOL {
class MainView :public DirectX3D12MainView {
//Inner class starts.
class SimpleView :public DirectX3D12View {
private:
SmartPtr<Direct3D12CommandAllocator> commandAllocator;
SmartPtr<Direct3D12RenderTargetView> renderTargetView;
SmartPtr<Direct3D12DepthStencilView> depthStencilView;
SmartPtr<Direct3D12RootSignature> rootSignature;
SmartPtr<Direct3D12GraphicsCommandList> graphicsCommandList;
SmartPtr<Direct3D12PipelineState> pipelineState;
SmartPtr<Direct3D12Synchronizer> synchronizer;
SmartPtr<Direct3D12VertexBuffer> vertexBuffer;
SmartPtr<Direct3D12IndexBuffer> indexBuffer;
UINT frameIndex;
UINT vertexCount;
StringT<TCHAR> directory;
private:
//Application specific data
virtual void createPipelineState(ID3D12Device* device)
{
//Create a graphicPipelineStateDes.
D3D12GraphicsPipelineStateDesc graphicsPipelineStateDesc(*rootSignature);
static D3D12_INPUT_ELEMENT_DESC inputElements[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
};
D3D12RasterizerDesc rasterDesc(D3D12_FILL_MODE_SOLID, D3D12_CULL_MODE_NONE, false);
D3D12BlendDesc blendDesc;
graphicsPipelineStateDesc.setInputLayput(inputElements, _countof(inputElements));
graphicsPipelineStateDesc.setRasterizerState(rasterDesc);
graphicsPipelineStateDesc.setBlendState(blendDesc);
StringT<TCHAR> vsshaderFile = getShaderFilePath(directory, _T("VertexShader.cso"));
StringT<TCHAR> psshaderFile = getShaderFilePath(directory, _T("PixelShader.cso"));
graphicsPipelineStateDesc.setVertexShader(vsshaderFile);
graphicsPipelineStateDesc.setPixelShader(psshaderFile);
pipelineState = new Direct3D12PipelineState(device, graphicsPipelineStateDesc);
}
virtual void createVertexBuffer(ID3D12Device* device)
{
typedef struct {
XMFLOAT3 pos;
XMFLOAT4 color;
} Vertex;
const Vertex vertices[] = {
//Position(x, y, z) Color(r, g, b, a)
{XMFLOAT3( 0.0f , 1.0f , 0.0f), XMFLOAT4( 1.0f, 0.0f, 0.0f, 1.0f) },
{XMFLOAT3( 1.0f , -1.0f , 0.0f), XMFLOAT4( 0.0f, 1.0f, 0.0f, 1.0f) },
{XMFLOAT3(-1.0f , -1.0f , 0.0f), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f) },
};
UINT verticesSizeInByte = sizeof(vertices);
UINT strideInByte = sizeof(Vertex);
vertexCount = _countof(vertices);
vertexBuffer = new Direct3D12VertexBuffer(device, vertices, strideInByte, verticesSizeInByte);
}
virtual void createIndexBuffer(ID3D12Device* device)
{
uint16_t indices[] = { 0, 1, 2 };
UINT indicesSizeInByte = sizeof(indices);
indexBuffer = new Direct3D12IndexBuffer(device, indices, indicesSizeInByte);
}
//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->setOMRenderTargets(0, nullptr, FALSE, nullptr);
renderTargetView = NULL;
depthStencilView = NULL;
}
public:
virtual void initialize()
{
int width = 0;
int height = 0;
validateClientSize(width, height);
//The following three objects are from the parent DirectX3D12View.
Direct3D12Device* device = getD3D12Device();
DirectXGISwapChain3* swapChain = getSwapChain3();
Direct3D12CommandQueue* commandQueue = getCommandQueue();
try {
commandAllocator = new Direct3D12CommandAllocator(*device);
graphicsCommandList = new Direct3D12GraphicsCommandList(*device, *commandAllocator);
rootSignature = new Direct3D12RootSignature(*device);
createViews(*device, *swapChain, width, height);
createPipelineState(*device);
createVertexBuffer(*device);
createIndexBuffer(*device);
synchronizer = new Direct3D12Synchronizer(*device, *commandQueue);
} catch (Exception& ex) {
caught(ex);
}
}
bool ready()
{
Direct3D12Device* device = getD3D12Device();
DirectXGISwapChain3* swapChain = getSwapChain3();
Direct3D12CommandQueue* commandQueue = getCommandQueue();
if (
device == nullptr ||
commandQueue == nullptr ||
swapChain == nullptr ||
commandAllocator == nullptr ||
renderTargetView == nullptr ||
depthStencilView == nullptr ||
rootSignature == nullptr ||
graphicsCommandList == nullptr ||
pipelineState == nullptr ||
synchronizer == nullptr ||
vertexBuffer == nullptr ||
indexBuffer == nullptr) {
return false;
}
return true;
}
virtual void display()
{
int width = 0;
int height = 0;
validateClientSize(width, height);
if ( !ready() ) {
return;
}
try {
DirectXGISwapChain3* swapChain = getSwapChain3();
Direct3D12CommandQueue* commandQueue = getCommandQueue();
commandAllocator -> reset();
graphicsCommandList -> reset(*commandAllocator, *pipelineState);
frameIndex = swapChain -> getCurrentBackBufferIndex();
D3D12ResourceBarrier barrier(renderTargetView->getResource(frameIndex));
barrier.startRendering();
graphicsCommandList->resourceBarrier(1, barrier);
graphicsCommandList->setGraphicsRootSignature(*rootSignature);
graphicsCommandList->setPipelineState(*pipelineState);
graphicsCommandList -> setRSViewport(width, height);
graphicsCommandList -> setRSScissorRect(width, height);
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = renderTargetView->getHandle(frameIndex);
graphicsCommandList->clearRenderTargetView(rtvHandle, XMColor(0.2f, 0.2f, 1.0f, 1.0f));
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = *depthStencilView;
graphicsCommandList->clearDepthStencilView(dsvHandle);
graphicsCommandList->setOMRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
graphicsCommandList->setIAPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
graphicsCommandList->setIAVertexBuffers(0, 1, *vertexBuffer);
graphicsCommandList->setIAIndexBuffer(*indexBuffer);
graphicsCommandList->drawInstanced(vertexCount, 1, 0, 0);
barrier.endRendering();
graphicsCommandList->resourceBarrier(1, barrier);
graphicsCommandList->close();
commandQueue->executeCommandList(*graphicsCommandList);
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);
}
}
public:
//Constructor
SimpleView(DirectX3D12MainView* parent, const TCHAR* name, Args& args)
:DirectX3D12View(parent, name, args),
frameIndex(0),
directory(_T(""))
{
directory = (const TCHAR*)args.get(XmNapplicationDirectory);
postResizeRequest();
}
~SimpleView()
{
}
};
// Inner class ends.
private:
SmartPtr<SimpleView> view;
SmartPtr<PushButton> quit;
static const int MARGIN = 10;
static const int WORK_AREA_WIDTH = 140;
public:
/**
* Constructor
*/
MainView(Application& applet, const TCHAR* name, Args& args)
:DirectX3D12MainView(applet, name,
args.set(XmNstyle, (ulong)WS_CLIPCHILDREN|WS_CLIPSIBLINGS) )
{
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 Create a quit PushButton.
ar.reset();
ar.set(XmNwidth, 120);
ar.set(XmNheight, 30);
quit = new PushButton(this, _T("QUIT"), ar);
quit ->addCallback(XmNactivateCallback, this,
(Callback)&MainView::exit, NULL);
// 4 Post a resize request to this MainView.
postResizeRequest();
}
public:
~MainView()
{
}
void resize(int width, int height)
{
if (view != nullptr && quit != nullptr) {
int w = width;
if (width > WORK_AREA_WIDTH) {
w = width - WORK_AREA_WIDTH;
}
if (w < 1) {
w = width;
}
view -> reshape(0, 0, w, height);
quit -> reshape(w + 2, 2, 120, 30);
}
}
};
}
//////////////////////////////////////////////
//
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.