SOL9 Sample: Direct3D11On12Geometry
|
1 Screenshot
2 Source code
/*
* Direct3D11On12Geometry.cpp
* Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*/
// 2016/11/29
// This is based on the sample program in
// https://github.com/Microsoft/DirectX-Graphics-Samples
// See: DirectX-Graphics-Samples-master\Samples\Desktop\D3D1211On12
// You can rotate a torus by the left and right keys, without changing geometrical shapes.
// 2016/12/05
// 2017/01/28 Updated to use ModuleFileName and caught macro.
#define COMMONCONTROLS_V6
#define WIN10
#include <sol/WCharModuleFileName.h>
#include <sol/direct3d12/DirectX3D12MainView.h>
#include <sol/direct3d12/DirectXMatrix.h>
#include <sol/direct3d12/Direct3D11On12Device.h>
#include <sol/direct3d12/Direct3D11On12WrappedResource.h>
#include <sol/direct3d12/Direct3D12CommandAllocator.h>
#include <sol/direct3d12/Direct3D12RenderTargetView.h>
#include <sol/direct3d12/Direct3D12DepthStencilView.h>
#include <sol/direct3d12/Direct3D12TransformConstantBufferView.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/D3D12Transform.h>
#include <sol/direct3d12/D3D12GraphicsPipelineStateDesc.h>
#include <sol/direct3d12/Direct3D12Synchronizer.h>
#include <sol/direct3d12/Direct3DX12Torus.h>
#include <sol/direct3d12/DirectXTransform.h>
#include <sol/direct3d12/Direct3D12CommonDescriptorHeap.h>
#include <sol/direct3d12/DirectX3D12TimerThread.h>
#include <sol/directx/Direct2D1Factory3.h>
#include <sol/directx/Direct2D1Device2.h>
#include <sol/directx/Direct2D1DeviceContext2.h>
#include <sol/directx/Direct2D1Bitmap1.h>
#include <sol/directx/Direct2D1LinearGradientBrush.h>
#include <sol/directx/Direct2D1GradientStopCollection.h>
#include <sol/dxgi/DirectXGIDevice1.h>
#include <sol/dxgi/DirectXGISurface.h>
#include <sol/directx/Direct2D1SolidColorBrush.h>
#include <sol/directx/Direct2D1LinearGradientBrush.h>
#include "resource.h"
namespace SOL {
class MainView :public DirectX3D12MainView {
private:
static const int FRAME_COUNT = 3;
private:
//Inner class starts.
//-----------------------------------------------------------------------------------------
class DirectXGeometryRenderer : public DirectXGIDevice1 {
private:
SmartPtr<Direct2D1Device2> d2d1Device2;
SmartPtr<Direct2D1DeviceContext2> d2d1DeviceContext2;
SmartPtr<Direct3D11On12WrappedResource> wrappedBackBuffers[FRAME_COUNT];
SmartPtr<Direct2D1Bitmap1> d2d1RenderTargets1[FRAME_COUNT];
SmartPtr<DirectXGIDevice1> dxgiDevice1;
SmartPtr<Direct2D1Factory3> d2d1Factory3;
SmartPtr<Direct2D1Bitmap> bitmap;
SmartPtr<Direct2D1LinearGradientBrush> linearGradientBrush;
SmartPtr<Direct2D1GradientStopCollection> gradientStops;
SmartPtr<Direct2D1SolidColorBrush> blueBrush;
SmartPtr<Direct2D1SolidColorBrush> greenBrush;
SmartPtr<Direct2D1SolidColorBrush> redBrush;
void createWrappedBackBuffers(ID3D11On12Device* d3d11On12Device,
Direct3D12RenderTargetView* renderTargetView)
{
try {
float dpiX;
float dpiY;
d2d1Factory3->getDesktopDpi(&dpiX, &dpiY);
for (UINT n = 0; n < FRAME_COUNT; n++) {
wrappedBackBuffers[n] = new Direct3D11On12WrappedResource(d3d11On12Device,
renderTargetView->getResource(n));
IDXGISurface* surface = nullptr;
wrappedBackBuffers[n]->queryInterface(IID_PPV_ARGS(&surface));
d2d1RenderTargets1[n] = new Direct2D1Bitmap1(*d2d1DeviceContext2, surface,
dpiX,
dpiY);
surface->Release();
}
}
catch (Exception& ex) {
caught(ex);
}
}
public:
//
//Inner class constructor
DirectXGeometryRenderer(ID3D11On12Device* d3d11On12Device,
Direct3D12RenderTargetView* renderTargetView)
:DirectXGIDevice1(d3d11On12Device)
{
d2d1Factory3 = new Direct2D1Factory3();
d2d1Device2 = new Direct2D1Device2(*d2d1Factory3, *this);
d2d1DeviceContext2 = new Direct2D1DeviceContext2(*d2d1Device2);
createWrappedBackBuffers(d3d11On12Device, renderTargetView);
static const D2D1_GRADIENT_STOP stops[] = {
{ 0.f,{ 0.f, 1.f, 1.f, 0.25f } },
{ 1.f,{ 0.f, 0.f, 1.f, 1.f } },
};
gradientStops = new Direct2D1GradientStopCollection(
*d2d1DeviceContext2,
stops,
CountOf(stops));
linearGradientBrush = new Direct2D1LinearGradientBrush(*d2d1DeviceContext2,
D2D1::LinearGradientBrushProperties(
D2D1::Point2F(100, 0),
D2D1::Point2F(200, 200)),
D2D1::BrushProperties(),
*gradientStops);
blueBrush = new Direct2D1SolidColorBrush(*d2d1DeviceContext2,
D2D1::ColorF(D2D1::ColorF::Blue));
greenBrush = new Direct2D1SolidColorBrush(*d2d1DeviceContext2,
D2D1::ColorF(D2D1::ColorF::Green));
redBrush = new Direct2D1SolidColorBrush(*d2d1DeviceContext2,
D2D1::ColorF(D2D1::ColorF::Red));
}
~DirectXGeometryRenderer()
{
}
void drawGeometry(int frameIndex)
{
try {
wrappedBackBuffers[frameIndex]->acquire();
d2d1DeviceContext2->setTarget(*d2d1RenderTargets1[frameIndex]);
d2d1DeviceContext2->beginDraw();
d2d1DeviceContext2->setTransform(D2D1::Matrix3x2F::Identity());
// d2d1DeviceContext2->drawRectangle(D2D1::RectF(400.0f, 500.0f, 100.0f, 100.0f), *blueBrush, 6.0f);
d2d1DeviceContext2->fillRectangle(D2D1::RectF(100.0f, 100.0f, 50.0f, 10.0f), *redBrush);
d2d1DeviceContext2->drawEllipse(D2D1::Ellipse(D2D1::Point2F(180.0f, 100.0f), 80.0f, 60.0f), *greenBrush, 2.0f);
d2d1DeviceContext2->fillEllipse(D2D1::Ellipse(D2D1::Point2F(180.0f, 200.0f), 20.0f, 20.0f), *blueBrush);
d2d1DeviceContext2->drawRoundedRectangle(D2D1::RoundedRect(D2D1::RectF(200.0f, 150.0f, 400.0f, 220.0f), 30.0f, 30.0f), *redBrush, 4.0f);
d2d1DeviceContext2->fillRoundedRectangle(D2D1::RoundedRect(D2D1::RectF(100.0f, 60.0f, 200.0f, 100.0f), 10.0f, 10.0f), *greenBrush);
d2d1DeviceContext2->drawLine(D2D1::Point2F( 10.0f, 100.0f), D2D1::Point2F(250.0f, 100.0f), *linearGradientBrush, 6.0f);
d2d1DeviceContext2->drawLine(D2D1::Point2F(250.0f, 100.0f), D2D1::Point2F(250.0f, 200.0f), *linearGradientBrush, 6.0f);
d2d1DeviceContext2->drawLine(D2D1::Point2F(250.0f, 200.0f), D2D1::Point2F( 10.0f, 100.0f), *linearGradientBrush, 6.0f);
d2d1DeviceContext2->endDraw();
wrappedBackBuffers[frameIndex]->release();
}
catch (Exception& ex) {
caught(ex);
}
}
};
//Inner class ends.
//-----------------------------------------------------------------------------------------
private:
SmartPtr<Direct3D12CommandQueue> commandQueue;
SmartPtr<Direct3D12CommandAllocator> commandAllocators[FRAME_COUNT];
SmartPtr<DirectXGISwapChain3> swapChain;
SmartPtr<Direct3D12RenderTargetView> renderTargetView;
SmartPtr<Direct3D12DepthStencilView> depthStencilView;
SmartPtr<Direct3D12RootSignature> rootSignature;
SmartPtr<Direct3D12CommonDescriptorHeap> commonDescriptorHeap;
SmartPtr<Direct3D12TransformConstantBufferView> constantBufferView;
SmartPtr<Direct3D12GraphicsCommandList> graphicsCommandList;
SmartPtr<Direct3D12PipelineState> pipelineState;
SmartPtr<Direct3D12Synchronizer> synchronizer;
SmartPtr<Direct3DX12Torus> sphere;
UINT frameIndex;
DirectXTransform worldViewProjection;
float angle;
StringT<TCHAR> directory;
SmartPtr<Direct3D11On12Device> d3d11On12Device;
SmartPtr<DirectXGeometryRenderer> geometryRenderer;
public:
virtual void createPipelineState(ID3D12Device* device)
{
//Create a graphicPipelineStateDes.
D3D12GraphicsPipelineStateDesc graphicsPipelineStateDesc(*rootSignature);
UINT count = 0;
const D3D12_INPUT_ELEMENT_DESC* inputElements = sphere->getInputElementDesc(count);
D3D12RasterizerDesc rasterDesc(D3D12_FILL_MODE_WIREFRAME, D3D12_CULL_MODE_NONE, true);
D3D12BlendDesc blendDesc;
graphicsPipelineStateDesc.setInputLayput(inputElements, count);
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);
}
void setDirectXTransform()
{
int width = 0;
int height = 0;
getClientSize(width, height);
try {
XMVECTOR eye = XMVectorSet(0.0f, 2.0f,-6.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);
worldViewProjection.world = DirectXMatrix::rotationY(angle);
worldViewProjection.view = DirectXMatrix::lookAtLH(eye, at, up);
worldViewProjection.projection = DirectXMatrix::perspectiveFovLH(XM_PIDIV2*0.3f, width / (FLOAT)height, 0.01f, 100.0f);
if (constantBufferView != nullptr) {
constantBufferView->update(worldViewProjection);
}
}
catch (Exception& ex) {
caught(ex);
}
}
public:
void deleteViews()
{
if (graphicsCommandList) {
graphicsCommandList->setOMRenderTargets(0, nullptr, FALSE, nullptr);
}
renderTargetView = nullptr;
depthStencilView = nullptr;
}
virtual void createViews()
{
int width = 0;
int height = 0;
validateClientSize(width, height);
try {
Direct3D12Device* device = getD3D12Device();
DirectXGISwapChain3* swapChain = getSwapChain3();
renderTargetView = new Direct3D12RenderTargetView(*device, *swapChain, FRAME_COUNT);
depthStencilView = new Direct3D12DepthStencilView(*device, width, height);
} catch (Exception& ex) {
caught(ex);
}
}
DirectXGISwapChain3* getSwapChain3()
{
return swapChain;
}
Direct3D12CommandQueue* getCommandQueue()
{
return commandQueue;
}
virtual void initialize()
{
int width = 0;
int height = 0;
validateClientSize(width, height);
DirectXGIFactory4* factory = getDXGIFactory4(); //From DirectX3D12MainView
Direct3D12Device* device = getD3D12Device(); //From DirectX3D12MainView
try {
commandQueue = new Direct3D12CommandQueue(*device);
for (int i = 0; i < FRAME_COUNT; i++) {
commandAllocators[i] = new Direct3D12CommandAllocator(*device);
}
swapChain = new DirectXGISwapChain3(*factory, *commandQueue, FRAME_COUNT,
getWindow(), width, height, false);
d3d11On12Device = new Direct3D11On12Device(*device, *commandQueue);
createViews();
geometryRenderer = new DirectXGeometryRenderer(*d3d11On12Device, renderTargetView);
graphicsCommandList = new Direct3D12GraphicsCommandList(*device, *commandAllocators[0]);
rootSignature = new Direct3D12RootSignature(*device);
commonDescriptorHeap = new Direct3D12CommonDescriptorHeap(*device, 1);
constantBufferView = new Direct3D12TransformConstantBufferView(*device,
commonDescriptorHeap->getCPUHandle(0) );
synchronizer = new Direct3D12Synchronizer(*device, *commandQueue);
sphere = new Direct3DX12Torus(*device, 0.2f, 0.5f, 20, 20);
createPipelineState(*device);
setDirectXTransform();
} catch (Exception& ex) {
caught(ex);
}
}
bool ready()
{
Direct3D12Device* device = getD3D12Device();
DirectXGISwapChain3* swapChain = getSwapChain3();
Direct3D12CommandQueue* commandQueue = getCommandQueue();
if (
commandQueue == nullptr ||
swapChain == nullptr ||
renderTargetView == nullptr ||
depthStencilView == nullptr ||
rootSignature == nullptr ||
commonDescriptorHeap == nullptr ||
constantBufferView == nullptr ||
graphicsCommandList == nullptr ||
pipelineState == nullptr ||
synchronizer == nullptr ||
sphere == nullptr ||
geometryRenderer == 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();
setDirectXTransform();
frameIndex = swapChain -> getCurrentBackBufferIndex();
commandAllocators[frameIndex]->reset();
graphicsCommandList->reset(*commandAllocators[frameIndex], nullptr);
D3D12ResourceBarrier barrier(renderTargetView->getResource(frameIndex));
barrier.startRendering();
graphicsCommandList->resourceBarrier(1, barrier);
graphicsCommandList->setDescriptorHeap(*commonDescriptorHeap);
graphicsCommandList->setGraphicsRootSignature(*rootSignature);
graphicsCommandList->setPipelineState(*pipelineState);
graphicsCommandList->setGraphicsRootDescriptorTable(0,
commonDescriptorHeap->getGPUHandle(0));
graphicsCommandList-> setRSViewport(0, 0, width, height);
graphicsCommandList-> setRSScissorRect(0, 0, width, height);
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = renderTargetView->getHandle(frameIndex);
graphicsCommandList->clearRenderTargetView(rtvHandle, XMColor(0.1f, 0.4f, 1.0f, 1.0f));
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = *depthStencilView;
graphicsCommandList->clearDepthStencilView(dsvHandle, D3D12_CLEAR_FLAG_DEPTH);
graphicsCommandList->setOMRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
sphere->drawIndexedInstanced(graphicsCommandList);
barrier.endRendering();
graphicsCommandList->resourceBarrier(1, barrier);
graphicsCommandList->close();
commandQueue->executeCommandList(*graphicsCommandList);
geometryRenderer -> drawGeometry(frameIndex);
d3d11On12Device->flush();
swapChain->present(1, 0);
synchronizer->waitForCompletion();
} catch (Exception& ex) {
caught(ex);
}
}
public:
/**
* Constructor
*/
MainView(Application& applet, const TCHAR* name, Args& args)
:DirectX3D12MainView(applet, name, args )
{
directory = (const TCHAR*)args.get(XmNapplicationDirectory);
angle = 1.0f;
restorePlacement();
postResizeRequest();
}
public:
~MainView()
{
}
private:
virtual void resize(int width, int height)
{
Direct3D12Device* device = getD3D12Device();
DirectXGISwapChain3* swapChain = getSwapChain3();
if (device == nullptr ||
swapChain == nullptr) {
return ;
}
try {
deleteViews();
swapChain->resizeBuffers(width, height);
createViews();
} catch (Exception& ex) {
caught(ex);
}
}
virtual void keyDown(Event& event)
{
WPARAM wparam = event.getWParam();
switch(wparam) {
case VK_LEFT:
angle += 0.1f;
display();
break;
case VK_RIGHT:
angle -= 0.1f;
display();
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, 700);
args.set(XmNheight, 480);
args.set(XmNapplicationDirectory, directory);
MainView mainv(applet, appClass, args);
mainv.realize();
applet.run();
} catch (Exception& ex) {
caught(ex);
}
}
Last modified: 1 Feb 2017
Copyright (c) 2017 Antillia.com ALL RIGHTS RESERVED.