SOL9 Sample: Direct3D12SphereWithColorEyeAndLightPositioner
|
1 Screenshot
2 Source code
/*
* Direct3D12SphereWithColorEyeAndLightPositioner.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/Vector3.h>
#include <sol/ColorPositioner.h>
#include <sol/EyePositioner.h>
#include <sol/LightPositioner.h>
#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/Direct3D12ConstantBufferViewRootSignature.h>
#include <sol/direct3d12/Direct3D12GraphicsCommandList.h>
#include <sol/direct3d12/Direct3D12PipelineState.h>
#include <sol/direct3d12/D3D12RasterizerDesc.h>
#include <sol/direct3d12/D3D12AdditiveBlendDesc.h>
#include <sol/direct3d12/D3D12AlphaBlendDesc.h>
#include <sol/direct3d12/D3D12GraphicsPipelineStateDesc.h>
#include <sol/direct3d12/D3D12ResourceBarrier.h>
#include <sol/direct3d12/D3D12TransformLight.h>
#include <sol/direct3d12/D3D12GraphicsPipelineStateDesc.h>
#include <sol/direct3d12/Direct3D12Synchronizer.h>
#include <sol/direct3d12/Direct3DX12Sphere.h>
#include <sol/direct3d12/DirectXTransformLight.h>
#include "resource.h"
namespace SOL {
class MainView :public DirectX3D12MainView {
//Inner class
class SimpleView :public DirectX3D12View {
private:
SmartPtr<Direct3D12CommandAllocator> commandAllocator;
SmartPtr<Direct3D12RenderTargetView> renderTargetView;
SmartPtr<Direct3D12DepthStencilView> depthStencilView;
SmartPtr<Direct3D12RootSignature> rootSignature;
SmartPtr<Direct3D12CommonDescriptorHeap> commonDescriptorHeap;
SmartPtr<Direct3D12TransformLightConstantBufferView> constantBufferView;
SmartPtr<Direct3D12GraphicsCommandList> graphicsCommandList;
SmartPtr<Direct3D12PipelineState> pipelineState;
SmartPtr<Direct3D12Synchronizer> synchronizer;
SmartPtr<Direct3DX12Sphere> sphere;
UINT frameIndex;
DirectXTransformLight lightedConstantBuffer;
float angle;
StringT<TCHAR> directory;
XMFLOAT4 eye;
XMFLOAT4 at;
XMFLOAT4 up;
XMFLOAT4 lightColor;
XMFLOAT4 lightDirection;
private:
virtual void createPipelineState(ID3D12Device* device, Direct3DX12Shape* shape)
{
//Create a graphicPipelineStateDes.
D3D12GraphicsPipelineStateDesc graphicsPipelineStateDesc(*rootSignature);
UINT count = 0;
const D3D12_INPUT_ELEMENT_DESC* inputElements = sphere->getInputElementDesc(count);
D3D12RasterizerDesc rasterDesc(
D3D12_FILL_MODE_SOLID,
//D3D12_FILL_MODE_WIREFRAME,
D3D12_CULL_MODE_NONE,
true);
D3D12AlphaBlendDesc 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 setDirectXTransformLight()
{
int width = 0;
int height = 0;
getClientSize(width, height);
try {
XMVECTOR e = XMVectorSet(eye.x, eye.y, eye.z, 0.0f);
XMVECTOR a = XMVectorSet(at.x, at.y, at.z, 0.0f);
XMVECTOR u = XMVectorSet(up.x, up.y, up.z, 0.0f);
lightedConstantBuffer.world = DirectXMatrix::rotationY( angle );
lightedConstantBuffer.view = DirectXMatrix::lookAtLH( e, a, u);
lightedConstantBuffer.projection = DirectXMatrix::perspectiveFovLH( XM_PIDIV2*0.3f, width / (FLOAT)height, 0.01f, 100.0f );
lightedConstantBuffer.lightDirection = lightDirection;
lightedConstantBuffer.lightColor = lightColor;
if (constantBufferView) {
constantBufferView->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->setOMRenderTargets(0, nullptr, FALSE, nullptr);
renderTargetView = NULL;
depthStencilView = NULL;
}
public:
virtual void initialize()
{
int width = 0;
int height = 0;
validateClientSize(width, height);
Direct3D12Device* device = getD3D12Device();
DirectXGISwapChain3* swapChain = getSwapChain3();
Direct3D12CommandQueue* commandQueue = getCommandQueue();
try {
commandAllocator = new Direct3D12CommandAllocator(*device);
graphicsCommandList = new Direct3D12GraphicsCommandList(*device, *commandAllocator);
//rootSignature = new Direct3D12ConstantBufferViewRootSignature(*device);
rootSignature = new Direct3D12RootSignature(*device);
commonDescriptorHeap = new Direct3D12CommonDescriptorHeap(*device, 1);
constantBufferView = new Direct3D12TransformLightConstantBufferView(*device,
commonDescriptorHeap->getCPUHandle(CBV_HANDLE));
synchronizer = new Direct3D12Synchronizer(*device, *commandQueue);
createViews(*device, *swapChain, width, height);
//1 Create your own shape
sphere = new Direct3DX12Sphere(*device, 1.0f, 30, 30);
//2 Create a pipelineState from the cube.
createPipelineState(*device, sphere);
eye = XMFLOAT4( 0.0f, 1.0f, -8.0f, 0.0f );
at = XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f );
up = XMFLOAT4( 0.0f, 1.0f, 0.0f, 0.0f );
lightDirection = XMFLOAT4( -0.8f, 0.8f, 0.3f, 1.0f );
lightColor = XMFLOAT4( 0.3f, 0.8f, 0.0f, 1.0f );
//3 Set world, view and projection to the constantBuffer.
setDirectXTransformLight();
} 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 ||
commonDescriptorHeap == nullptr ||
constantBufferView == nullptr ||
sphere == nullptr ||
graphicsCommandList == nullptr ||
pipelineState == nullptr ||
synchronizer == 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();
//constantBufferView -> update(lightedConstantBuffer);
setDirectXTransformLight();
commandAllocator -> reset();
graphicsCommandList -> reset(*commandAllocator, *pipelineState);
frameIndex = swapChain -> getCurrentBackBufferIndex();
D3D12ResourceBarrier barrier(renderTargetView->getResource(frameIndex));
barrier.startRendering();
graphicsCommandList->resourceBarrier(1, barrier);
graphicsCommandList->setDescriptorHeap(*commonDescriptorHeap);
graphicsCommandList->setGraphicsRootSignature(*rootSignature);
graphicsCommandList->setPipelineState(*pipelineState);
graphicsCommandList->setGraphicsRootDescriptorTable(CBV_HANDLE,
commonDescriptorHeap->getGPUHandle(CBV_HANDLE) );
graphicsCommandList-> setRSViewport(width, height);
graphicsCommandList-> setRSScissorRect(width, height);
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = renderTargetView->getHandle(frameIndex);
graphicsCommandList->clearRenderTargetView(rtvHandle, XMColor(0.0f, 0.0f, 0.0f, 1.0f));
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = *depthStencilView;
graphicsCommandList->clearDepthStencilView(dsvHandle);
graphicsCommandList->setOMRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
sphere -> drawIndexedInstanced(graphicsCommandList);
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);
}
}
void setLightColor(XMFLOAT4 color)
{
lightColor = color;
setDirectXTransformLight();
invalidateAll();
update();
}
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()
{
}
void setColorPosition(int x, int y, int z)
{
lightColor.x = (float)x / 255.0f;
lightColor.y = (float)y / 255.0f;
lightColor.z = (float)z / 255.0f;
postRenderRequest();
}
void setEyePosition(int x, int y, int z)
{
eye.x = (float)x;
eye.y = (float)y;
eye.z = (float)z;
postRenderRequest();
}
void setLightPosition(int x, int y, int z)
{
lightDirection.x = (float)x;
lightDirection.y = (float)y;
lightDirection.z = (float)z;
postRenderRequest();
}
};
// Inner class ends.
private:
SmartPtr<SimpleView> view;
SmartPtr<ColorPositioner> colorPositioner;
SmartPtr<EyePositioner> eyePositioner;
SmartPtr<LightPositioner> lightPositioner;
public:
virtual long colorPositionChanged(Event& event)
{
view -> setColorPosition(colorPositioner->getX(),
colorPositioner->getY(),
colorPositioner->getZ());
return 0;
}
virtual long eyePositionChanged(Event& event)
{
view -> setEyePosition(eyePositioner->getX(),
eyePositioner->getY(),
eyePositioner->getZ());
return 0;
}
virtual long lightPositionChanged(Event& event)
{
view -> setLightPosition(lightPositioner->getX(),
lightPositioner->getY(),
lightPositioner->getZ());
return 0;
}
/**
* 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 ColorPositioner
ar.reset();
colorPositioner = new ColorPositioner(this, _T(""), ar);
int red = 42;
int green = 30;
int blue = 225;
colorPositioner->setThumbPosition(red, green, blue);
view -> setColorPosition(red, green, blue);
//4 Create EyePositioner
ar.reset();
ar.set(XmNminimum, 0);
ar.set(XmNmaximum, 40);
eyePositioner = new EyePositioner(this, _T(""), ar);
int eyeX = 8;
int eyeY = 3;
int eyeZ = 5;
eyePositioner->setThumbPosition(eyeX, eyeY, eyeZ);
view -> setEyePosition(eyeX, eyeY, eyeZ);
//5 Create LightPositioner
ar.reset();
ar.set(XmNminimum, 0);
ar.set(XmNmaximum, 40);
lightPositioner = new LightPositioner(this, _T(""), ar);
int lightX = 5;
int lightY = 0;
int lightZ = 7;
lightPositioner->setThumbPosition(lightX, lightY, lightZ);
view -> setLightPosition(lightX, lightY, lightZ);
//6 Add eventHandlers to handle positionChangeMessage for the positionas.
addEventHandler(colorPositioner->getPositionChangedMessage(), this,
(Handler)&MainView::colorPositionChanged, NULL);
addEventHandler(eyePositioner->getPositionChangedMessage(), this,
(Handler)&MainView::eyePositionChanged, NULL);
addEventHandler(lightPositioner->getPositionChangedMessage(), this,
(Handler)&MainView::lightPositionChanged, NULL);
//7 Post the position change messages.
post(WM_COLOR_POSITION_CHANGED);
post(WM_EYE_POSITION_CHANGED);
post(WM_LIGHT_POSITION_CHANGED);
// 8 Post a resize request to this MainView.
postResizeRequest();
}
public:
~MainView()
{
}
long picked(Event& event)
{
COLORREF rgb = (COLORREF)event.getLParam();
BYTE r = GetRValue(rgb);
BYTE g = GetGValue(rgb);
BYTE b = GetBValue(rgb);
XMFLOAT4 lightColor;
lightColor.x = (float)r/(float)0xff;
lightColor.y = (float)g/(float)0xff;
lightColor.z = (float)b/(float)0xff;
lightColor.w = 1.0f;
view->setLightColor(lightColor);
return 0L;
}
long size(Event& event)
{
int w, h;
event.getSize(w, h);
if (view && colorPositioner && eyePositioner && lightPositioner) {
int posw = colorPositioner->getDefaultWidth();
int posh = lightPositioner->getDefaultHeight();
view->reshape(0, 0, w - posw - 4, h);
view->postResizeRequest(w - posw - 4, h);
colorPositioner->reshape(w - posw - 2, 2, posw, posh);
eyePositioner->reshape(w - posw - 2, 4 + posh, posw, posh);
lightPositioner->reshape(w - posw - 2, 6 + posh * 2, posw, posh);
}
return 1L;
}
};
}
//////////////////////////////////////////////
//
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, 680);
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.