Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers.
- #endif
- #pragma comment(lib, "d3d12.lib")
- #pragma comment(lib, "dxgi.lib")
- #pragma comment(lib, "d3dcompiler.lib")
- #include <Vector.hpp>
- #include "Types.hpp"
- #include "Allocator.hpp"
- #include "Memory.hpp"
- #include "Thread.hpp"
- #include <d3d12.h>
- #include <dxgi1_4.h>
- #include <D3Dcompiler.h>
- #include <DirectXMath.h>
- #include "d3dx12.h"
- #include <string>
- #include <wrl.h>
- #include <windows.h>
- using namespace DirectX;
- using namespace Microsoft::WRL;
- #define SAFE_RELEASE(p) { if ( (p) ) { (p)->Release(); (p) = 0; } }
- struct ConstantBufferPerObject
- {
- XMFLOAT4X4 wvpMat;
- };
- struct Vertex
- {
- Vertex(float x, float y, float z, float r, float g, float b, float a) : pos(x, y, z), color(r, g, b, a) {}
- XMFLOAT3 pos;
- XMFLOAT4 color;
- };
- HWND hwnd = NULL;
- int32 Width = 800;
- int32 Height = 600;
- bool FullScreen = false;
- bool Running = true;
- bool InitializeWindow(HINSTANCE hInstance, int32 ShowWnd, bool fullscreen);
- bool InitD3D();
- void Update();
- void UpdatePipeline();
- void Render();
- void Cleanup();
- void WaitForPreviousFrame();
- LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
- const int32 frameBufferCount = 3;
- ComPtr<ID3D12Device> device;
- IDXGISwapChain3* swapChain;
- ID3D12CommandQueue* commandQueue;
- ID3D12DescriptorHeap* rtvDescriptorHeap;
- ID3D12Resource* renderTargets[frameBufferCount];
- ID3D12CommandAllocator* commandAllocator[frameBufferCount];
- ID3D12GraphicsCommandList* commandList;
- ID3D12Fence* fence[frameBufferCount];
- HANDLE fenceEvent;
- uint64 fenceValue[frameBufferCount];
- SIZE_T frameIndex;
- int32 rtvDescriptorSize;
- ID3D12PipelineState* pipelineStateObject;
- ID3D12RootSignature* rootSignature;
- D3D12_VIEWPORT viewport;
- D3D12_RECT scissorRect;
- ID3D12Resource* vertexBuffer;
- ID3D12Resource* indexBuffer;
- D3D12_VERTEX_BUFFER_VIEW vertexBufferView;
- D3D12_INDEX_BUFFER_VIEW indexBufferView;
- ID3D12Resource* depthStencilBuffer;
- ID3D12DescriptorHeap* dsDescriptorHeap;
- int32 ConstantBufferPerObjectAlignedSize = (sizeof(ConstantBufferPerObject) + 255) & ~255;
- ConstantBufferPerObject cbPerObject;
- ID3D12Resource* constantBufferUploadHeaps[frameBufferCount];
- uint8* cbvGPUAddress[frameBufferCount];
- XMFLOAT4X4 cameraProjMat;
- XMFLOAT4X4 cameraViewMat;
- XMFLOAT4 cameraPosition;
- XMFLOAT4 cameraTarget;
- XMFLOAT4 cameraUp;
- XMFLOAT4X4 cube1WorldMat;
- XMFLOAT4X4 cube1RotMat;
- XMFLOAT4 cube1Position;
- XMFLOAT4X4 cube2WorldMat;
- XMFLOAT4X4 cube2RotMat;
- XMFLOAT4 cube2PositionOffset;
- int32 numCubeIndices;
- struct SThreadTest
- {
- uint8 DoWork()
- {
- for (SIZE_T i = 0; i < 100; ++i)
- {
- OutputDebugStringA("thread stuff\n");
- }
- return 0;
- }
- };
- struct SThreadTest2
- {
- uint8 DoWork()
- {
- for (SIZE_T i = 0; i < 100; ++i)
- {
- OutputDebugStringA("thread stuff2\n");
- }
- return 0;
- }
- };
- int32 WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int32 nShowCmd)
- {
- using namespace Aberration::Memory;
- using namespace Aberration::OS;
- //default memory allocator, basically aligned malloc and aligned free
- IAllocator* allocator = GlobalAllocator;
- //allocate single int
- auto mem = TMemory<int>::Allocate(allocator);
- //do something with memory mem
- //free single int
- TMemory<int>::Free(allocator, mem);
- //allocate an array of 10 ints, non initialized
- auto array = TMemory<int[]>::Allocate(allocator, 10);
- //do something with memory array
- //free array of ints
- TMemory<int[]>::Free(allocator, array, 10);
- //allocate an array of 10 ints, initialized
- auto defaultinitedarray = TMemory<int[]>::Allocate(allocator, 10, 7);
- //do something with memory defaultinitedarray
- //free array of ints
- TMemory<int[]>::Free(allocator, defaultinitedarray, 10);
- Aberration::OS::FThread::FMainFunctionType ThreadMain;
- SThreadTest ThreadTest;
- ThreadMain.Bind<SThreadTest, &SThreadTest::DoWork>(&ThreadTest);
- Aberration::OS::FThread::FMainFunctionType ThreadMain2;
- SThreadTest2 ThreadTest2;
- ThreadMain2.Bind<SThreadTest2, &SThreadTest2::DoWork>(&ThreadTest2);
- //FThread TestThread;
- //auto err = TestThread.Create(ThreadMain, "test", 0);
- //FThread TestThread2;
- //err = TestThread2.Create(ThreadMain2, "test2", 0);
- /*for (SIZE_T i = 0; i < 100; ++i)
- {
- OutputDebugStringA("main thread\n");
- }
- */
- if (!InitializeWindow(hInstance, nShowCmd, FullScreen))
- {
- MessageBox(0, L"Window Initialization - Failed", L"Error", MB_OK);
- return 1;
- }
- if (!InitD3D())
- {
- MessageBox(0, L"Failed to initialize direct3d 12", L"Error", MB_OK);
- Cleanup();
- return 1;
- }
- MSG msg = MSG();
- while (Running)
- {
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- if (msg.message == WM_QUIT)
- break;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else
- {
- Update();
- Render();
- }
- }
- WaitForPreviousFrame();
- CloseHandle(fenceEvent);
- Cleanup();
- return 0;
- }
- bool InitializeWindow(HINSTANCE hInstance, int32 ShowWnd, bool fullscreen)
- {
- if (fullscreen)
- {
- HMONITOR hmon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
- MONITORINFO mi = { sizeof(mi) };
- GetMonitorInfo(hmon, &mi);
- Width = mi.rcMonitor.right - mi.rcMonitor.left;
- Height = mi.rcMonitor.bottom - mi.rcMonitor.top;
- }
- WNDCLASSEX wc;
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = WndProc;
- wc.cbClsExtra = NULL;
- wc.cbWndExtra = NULL;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = L"AberrationEngineWindowName";
- wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
- if (!RegisterClassEx(&wc))
- {
- MessageBox(NULL, L"Error registering class", L"Error", MB_OK | MB_ICONERROR);
- return false;
- }
- hwnd = CreateWindowEx(NULL, L"AberrationEngineWindowName", L"Aberration Engine", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, Width, Height, NULL, NULL, hInstance, NULL);
- if (!hwnd)
- {
- MessageBox(NULL, L"Error creating window", L"Error", MB_OK | MB_ICONERROR);
- return false;
- }
- if (fullscreen)
- {
- SetWindowLong(hwnd, GWL_STYLE, 0);
- }
- ShowWindow(hwnd, ShowWnd);
- UpdateWindow(hwnd);
- return true;
- }
- LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch (msg)
- {
- case WM_KEYDOWN:
- if (wParam == VK_ESCAPE)
- {
- if (MessageBox(0, L"Are you sure you want to exit?", L"Really?", MB_YESNO | MB_ICONQUESTION) == IDYES)
- {
- Running = false;
- DestroyWindow(hwnd);
- }
- }
- return 0;
- case WM_DESTROY:
- Running = false;
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
- bool InitD3D()
- {
- IDXGIFactory4* dxgiFactory;
- auto hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
- if (FAILED(hr))
- {
- return false;
- }
- IDXGIAdapter1* adapter;
- int32 adapterIndex = 0;
- bool adapterFound = false;
- while (dxgiFactory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND)
- {
- DXGI_ADAPTER_DESC1 desc;
- adapter->GetDesc1(&desc);
- if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
- {
- adapterIndex++;
- continue;
- }
- auto hresult = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr);
- if (SUCCEEDED(hresult))
- {
- adapterFound = true;
- break;
- }
- adapterIndex++;
- }
- if (!adapterFound)
- {
- return false;
- }
- {
- // Create the device
- auto res = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device));
- if (FAILED(res))
- {
- return false;
- }
- }
- D3D12_COMMAND_QUEUE_DESC cqDesc = {};
- cqDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
- cqDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
- if (FAILED(device->CreateCommandQueue(&cqDesc, IID_PPV_ARGS(&commandQueue))))
- {
- return false;
- }
- DXGI_MODE_DESC backBufferDesc = {};
- backBufferDesc.Width = Width;
- backBufferDesc.Height = Height;
- backBufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
- swapChainDesc.BufferCount = frameBufferCount;
- swapChainDesc.BufferDesc = backBufferDesc;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
- swapChainDesc.OutputWindow = hwnd;
- swapChainDesc.SampleDesc.Count = 1;
- swapChainDesc.Windowed = !FullScreen;
- IDXGISwapChain* tempSwapChain;
- dxgiFactory->CreateSwapChain(commandQueue, &swapChainDesc, &tempSwapChain);
- swapChain = static_cast<IDXGISwapChain3*>(tempSwapChain);
- frameIndex = swapChain->GetCurrentBackBufferIndex();
- D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = D3D12_DESCRIPTOR_HEAP_DESC();
- rtvHeapDesc.NumDescriptors = frameBufferCount;
- rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
- rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
- hr = device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&rtvDescriptorHeap));
- if (FAILED(hr))
- {
- return false;
- }
- rtvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
- D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
- for (SIZE_T i = 0; i < frameBufferCount; i++)
- {
- hr = swapChain->GetBuffer((UINT)i, IID_PPV_ARGS(&renderTargets[i]));
- if (FAILED(hr))
- {
- return false;
- }
- device->CreateRenderTargetView(renderTargets[i], nullptr, rtvHandle);
- rtvHandle.ptr += 1 * rtvDescriptorSize;
- }
- for (SIZE_T i = 0; i < frameBufferCount; i++)
- {
- if (FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&commandAllocator[i]))))
- {
- return false;
- }
- }
- if (FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAllocator[frameIndex], NULL, IID_PPV_ARGS(&commandList))))
- {
- return false;
- }
- for (SIZE_T i = 0; i < frameBufferCount; i++)
- {
- hr = device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence[i]));
- if (FAILED(hr))
- {
- return false;
- }
- fenceValue[i] = 0;
- }
- fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
- if (fenceEvent == nullptr)
- {
- return false;
- }
- D3D12_ROOT_DESCRIPTOR rootCBVDescriptor;
- rootCBVDescriptor.RegisterSpace = 0;
- rootCBVDescriptor.ShaderRegister = 0;
- D3D12_ROOT_PARAMETER rootParameters[1];
- rootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
- rootParameters[0].Descriptor = rootCBVDescriptor;
- rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
- D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc = D3D12_ROOT_SIGNATURE_DESC();
- rootSignatureDesc.NumParameters = _countof(rootParameters);
- rootSignatureDesc.pParameters = rootParameters;
- rootSignatureDesc.NumStaticSamplers = 0;
- rootSignatureDesc.pStaticSamplers = nullptr;
- rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
- D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
- D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
- D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS |
- D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS;
- ID3DBlob* signature;
- if (FAILED(D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, nullptr))) { return false; }
- if (FAILED(device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&rootSignature)))) { return false; }
- ID3DBlob* vertexShader;
- ID3DBlob* errorBuff;
- hr = D3DCompileFromFile(L"BaseShader.vs.hlsl", nullptr, nullptr, "main", "vs_5_0", D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &vertexShader, &errorBuff);
- if (FAILED(hr))
- {
- OutputDebugStringA((LPCSTR)errorBuff->GetBufferPointer());
- return false;
- }
- D3D12_SHADER_BYTECODE vertexShaderBytecode = {};
- vertexShaderBytecode.BytecodeLength = vertexShader->GetBufferSize();
- vertexShaderBytecode.pShaderBytecode = vertexShader->GetBufferPointer();
- // compile pixel shader
- ID3DBlob* pixelShader;
- hr = D3DCompileFromFile(L"BaseShader.ps.hlsl", nullptr, nullptr, "main", "ps_5_0", D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &pixelShader, &errorBuff);
- if (FAILED(hr))
- {
- OutputDebugStringA((LPCSTR)errorBuff->GetBufferPointer());
- return false;
- }
- D3D12_SHADER_BYTECODE pixelShaderBytecode = {};
- pixelShaderBytecode.BytecodeLength = pixelShader->GetBufferSize();
- pixelShaderBytecode.pShaderBytecode = pixelShader->GetBufferPointer();
- const D3D12_INPUT_ELEMENT_DESC inputLayout[] =
- {
- { "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 }
- };
- D3D12_INPUT_LAYOUT_DESC inputLayoutDesc = {};
- inputLayoutDesc.NumElements = sizeof(inputLayout) / sizeof(D3D12_INPUT_ELEMENT_DESC);
- inputLayoutDesc.pInputElementDescs = inputLayout;
- D3D12_RASTERIZER_DESC rasterDesc = D3D12_RASTERIZER_DESC();
- rasterDesc.FillMode = D3D12_FILL_MODE_SOLID;
- rasterDesc.CullMode = D3D12_CULL_MODE_BACK;
- rasterDesc.FrontCounterClockwise = FALSE;
- rasterDesc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
- rasterDesc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
- rasterDesc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
- rasterDesc.DepthClipEnable = TRUE;
- rasterDesc.MultisampleEnable = FALSE;
- rasterDesc.AntialiasedLineEnable = FALSE;
- rasterDesc.ForcedSampleCount = 0;
- rasterDesc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
- D3D12_BLEND_DESC blendDesc = D3D12_BLEND_DESC();
- blendDesc.IndependentBlendEnable = FALSE;
- const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc =
- {
- FALSE,FALSE,
- D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
- D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD,
- D3D12_LOGIC_OP_NOOP,
- D3D12_COLOR_WRITE_ENABLE_ALL,
- };
- for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
- {
- blendDesc.RenderTarget[i] = defaultRenderTargetBlendDesc;
- }
- D3D12_DEPTH_STENCIL_DESC dsDesc = D3D12_DEPTH_STENCIL_DESC();
- dsDesc.DepthEnable = TRUE;
- dsDesc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
- dsDesc.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
- dsDesc.StencilEnable = FALSE;
- dsDesc.StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK;
- dsDesc.StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK;
- const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp =
- { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS };
- dsDesc.FrontFace = defaultStencilOp;
- dsDesc.BackFace = defaultStencilOp;
- D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
- psoDesc.InputLayout = inputLayoutDesc;
- psoDesc.pRootSignature = rootSignature;
- psoDesc.VS = vertexShaderBytecode;
- psoDesc.PS = pixelShaderBytecode;
- psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
- psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
- psoDesc.SampleDesc.Count = 1;
- psoDesc.SampleMask = 0xffffffff;
- psoDesc.RasterizerState = rasterDesc;
- psoDesc.BlendState = blendDesc;
- psoDesc.NumRenderTargets = 1;
- psoDesc.DepthStencilState = dsDesc;
- // create the pso
- if (FAILED(device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pipelineStateObject))))
- {
- return false;
- }
- Vertex vList[] = {
- // front face
- { -0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f },
- { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f },
- { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
- { 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
- // right side face
- { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f },
- { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f },
- { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
- { 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
- // left side face
- { -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f },
- { -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f },
- { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
- { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
- // back face
- { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f },
- { -0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f },
- { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
- { -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
- // top face
- { -0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f },
- { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 1.0f },
- { 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
- { -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
- // bottom face
- { 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f },
- { -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f },
- { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f },
- { -0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
- };
- int32 vBufferSize = sizeof(vList);
- D3D12_HEAP_PROPERTIES heapProps = D3D12_HEAP_PROPERTIES();
- heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
- heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
- heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
- heapProps.CreationNodeMask = 1;
- heapProps.VisibleNodeMask = 1;
- D3D12_RESOURCE_DESC bufferResourceDesc = D3D12_RESOURCE_DESC();
- bufferResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
- bufferResourceDesc.Alignment = 0;
- bufferResourceDesc.Width = vBufferSize;
- bufferResourceDesc.Height = 1;
- bufferResourceDesc.DepthOrArraySize = 1;
- bufferResourceDesc.MipLevels = 1;
- bufferResourceDesc.Format = DXGI_FORMAT_UNKNOWN;
- bufferResourceDesc.SampleDesc.Count = 1;
- bufferResourceDesc.SampleDesc.Quality = 0;
- bufferResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
- bufferResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
- device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &bufferResourceDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&vertexBuffer));
- vertexBuffer->SetName(L"Vertex Buffer Resource Heap");
- ID3D12Resource* vBufferUploadHeap;
- heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
- device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &bufferResourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&vBufferUploadHeap));
- vBufferUploadHeap->SetName(L"Vertex Buffer Upload Resource Heap");
- D3D12_SUBRESOURCE_DATA vertexData = {};
- vertexData.pData = reinterpret_cast<BYTE*>(vList);
- vertexData.RowPitch = vBufferSize;
- vertexData.SlicePitch = vBufferSize;
- UpdateSubresources(commandList, vertexBuffer, vBufferUploadHeap, 0, 0, 1, &vertexData);
- D3D12_RESOURCE_BARRIER barrier = D3D12_RESOURCE_BARRIER();
- barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
- barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
- barrier.Transition.pResource = vertexBuffer;
- barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
- barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
- barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
- commandList->ResourceBarrier(1, &barrier);
- DWORD iList[] =
- {
- // ffront face
- 0, 1, 2, // first triangle
- 0, 3, 1, // second triangle
- // left face
- 4, 5, 6, // first triangle
- 4, 7, 5, // second triangle
- // right face
- 8, 9, 10, // first triangle
- 8, 11, 9, // second triangle
- // back face
- 12, 13, 14, // first triangle
- 12, 15, 13, // second triangle
- // top face
- 16, 17, 18, // first triangle
- 16, 19, 17, // second triangle
- // bottom face
- 20, 21, 22, // first triangle
- 20, 23, 21, // second triangle
- };
- int32 iBufferSize = sizeof(iList);
- numCubeIndices = sizeof(iList) / sizeof(DWORD);
- D3D12_RESOURCE_DESC indexBufferResourceDesc = D3D12_RESOURCE_DESC();
- indexBufferResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
- indexBufferResourceDesc.Alignment = 0;
- indexBufferResourceDesc.Width = iBufferSize;
- indexBufferResourceDesc.Height = 1;
- indexBufferResourceDesc.DepthOrArraySize = 1;
- indexBufferResourceDesc.MipLevels = 1;
- indexBufferResourceDesc.Format = DXGI_FORMAT_UNKNOWN;
- indexBufferResourceDesc.SampleDesc.Count = 1;
- indexBufferResourceDesc.SampleDesc.Quality = 0;
- indexBufferResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
- indexBufferResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
- heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
- device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &indexBufferResourceDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&indexBuffer));
- vertexBuffer->SetName(L"Index Buffer Resource Heap");
- ID3D12Resource* iBufferUploadHeap;
- heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
- device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &bufferResourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&iBufferUploadHeap));
- vBufferUploadHeap->SetName(L"Index Buffer Upload Resource Heap");
- D3D12_SUBRESOURCE_DATA indexData = {};
- indexData.pData = reinterpret_cast<BYTE*>(iList);
- indexData.RowPitch = iBufferSize;
- indexData.SlicePitch = iBufferSize;
- UpdateSubresources(commandList, indexBuffer, iBufferUploadHeap, 0, 0, 1, &indexData);
- D3D12_RESOURCE_BARRIER indexBufferBarrier = D3D12_RESOURCE_BARRIER();
- indexBufferBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
- indexBufferBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
- indexBufferBarrier.Transition.pResource = indexBuffer;
- indexBufferBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
- indexBufferBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER;
- indexBufferBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
- commandList->ResourceBarrier(1, &indexBufferBarrier);
- D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc = {};
- dsvHeapDesc.NumDescriptors = 1;
- dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
- dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
- if (FAILED(device->CreateDescriptorHeap(&dsvHeapDesc, IID_PPV_ARGS(&dsDescriptorHeap))))
- {
- Running = false;
- }
- D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilDesc = {};
- depthStencilDesc.Format = DXGI_FORMAT_D32_FLOAT;
- depthStencilDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
- depthStencilDesc.Flags = D3D12_DSV_FLAG_NONE;
- D3D12_CLEAR_VALUE depthOptimizedClearValue = {};
- depthOptimizedClearValue.Format = DXGI_FORMAT_D32_FLOAT;
- depthOptimizedClearValue.DepthStencil.Depth = 1.0f;
- depthOptimizedClearValue.DepthStencil.Stencil = 0;
- D3D12_RESOURCE_DESC depthstencilResourceDesc = D3D12_RESOURCE_DESC();
- depthstencilResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
- depthstencilResourceDesc.Alignment = 0;
- depthstencilResourceDesc.Width = Width;
- depthstencilResourceDesc.Height = Height;
- depthstencilResourceDesc.DepthOrArraySize = 1;
- depthstencilResourceDesc.MipLevels = 0;
- depthstencilResourceDesc.Format = DXGI_FORMAT_D32_FLOAT;
- depthstencilResourceDesc.SampleDesc.Count = 1;
- depthstencilResourceDesc.SampleDesc.Quality = 0;
- depthstencilResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
- depthstencilResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
- heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
- device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &depthstencilResourceDesc, D3D12_RESOURCE_STATE_DEPTH_WRITE, &depthOptimizedClearValue, IID_PPV_ARGS(&depthStencilBuffer));
- dsDescriptorHeap->SetName(L"Depth/Stencil Resource Heap");
- device->CreateDepthStencilView(depthStencilBuffer, &depthStencilDesc, dsDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
- for (int32 i = 0; i < frameBufferCount; ++i)
- {
- D3D12_RESOURCE_DESC constantBufferResourceDesc = D3D12_RESOURCE_DESC();
- constantBufferResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
- constantBufferResourceDesc.Alignment = 0;
- constantBufferResourceDesc.Width = 1024 * 64;
- constantBufferResourceDesc.Height = 1;
- constantBufferResourceDesc.DepthOrArraySize = 1;
- constantBufferResourceDesc.MipLevels = 1;
- constantBufferResourceDesc.Format = DXGI_FORMAT_UNKNOWN;
- constantBufferResourceDesc.SampleDesc.Count = 1;
- constantBufferResourceDesc.SampleDesc.Quality = 0;
- constantBufferResourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
- constantBufferResourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
- heapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
- hr = device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &constantBufferResourceDesc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&constantBufferUploadHeaps[i]));
- constantBufferUploadHeaps[i]->SetName(L"Constant Buffer Upload Resource Heap");
- ZeroMemory(&cbPerObject, sizeof(cbPerObject));
- D3D12_RANGE readRange = D3D12_RANGE();
- readRange.Begin = 0;
- readRange.End = 0;
- hr = constantBufferUploadHeaps[i]->Map(0, &readRange, reinterpret_cast<void**>(&cbvGPUAddress[i]));
- memcpy(cbvGPUAddress[i], &cbPerObject, sizeof(cbPerObject));
- memcpy(cbvGPUAddress[i] + ConstantBufferPerObjectAlignedSize, &cbPerObject, sizeof(cbPerObject));
- }
- commandList->Close();
- ID3D12CommandList* ppCommandLists[] = { commandList };
- commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
- fenceValue[frameIndex]++;
- hr = commandQueue->Signal(fence[frameIndex], fenceValue[frameIndex]);
- if (FAILED(hr))
- {
- Running = false;
- }
- vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress();
- vertexBufferView.StrideInBytes = sizeof(Vertex);
- vertexBufferView.SizeInBytes = vBufferSize;
- indexBufferView.BufferLocation = indexBuffer->GetGPUVirtualAddress();
- indexBufferView.Format = DXGI_FORMAT_R32_UINT;
- indexBufferView.SizeInBytes = iBufferSize;
- viewport.TopLeftX = 0;
- viewport.TopLeftY = 0;
- viewport.Width = (FLOAT)Width;
- viewport.Height = (FLOAT)Height;
- viewport.MinDepth = 0.0f;
- viewport.MaxDepth = 1.0f;
- scissorRect.left = 0;
- scissorRect.top = 0;
- scissorRect.right = (LONG)Width;
- scissorRect.bottom = (LONG)Height;
- XMMATRIX tmpMat = XMMatrixPerspectiveFovLH(45.0f*(3.14f / 180.0f), (float)Width / (float)Height, 0.1f, 1000.0f);
- XMStoreFloat4x4(&cameraProjMat, tmpMat);
- cameraPosition = XMFLOAT4(0.0f, 2.0f, -4.0f, 0.0f);
- cameraTarget = XMFLOAT4(0.0f, 0.0f, 0.0f, 0.0f);
- cameraUp = XMFLOAT4(0.0f, 1.0f, 0.0f, 0.0f);
- XMVECTOR cPos = XMLoadFloat4(&cameraPosition);
- XMVECTOR cTarg = XMLoadFloat4(&cameraTarget);
- XMVECTOR cUp = XMLoadFloat4(&cameraUp);
- tmpMat = XMMatrixLookAtLH(cPos, cTarg, cUp);
- XMStoreFloat4x4(&cameraViewMat, tmpMat);
- // first cube
- cube1Position = XMFLOAT4(0.0f, 0.0f, 0.0f, 0.0f);
- XMVECTOR posVec = XMLoadFloat4(&cube1Position);
- tmpMat = XMMatrixTranslationFromVector(posVec);
- XMStoreFloat4x4(&cube1RotMat, XMMatrixIdentity());
- XMStoreFloat4x4(&cube1WorldMat, tmpMat);
- // second cube
- cube2PositionOffset = XMFLOAT4(1.5f, 0.0f, 0.0f, 0.0f);
- posVec = XMLoadFloat4(&cube2PositionOffset) + XMLoadFloat4(&cube1Position);
- tmpMat = XMMatrixTranslationFromVector(posVec);
- XMStoreFloat4x4(&cube2RotMat, XMMatrixIdentity());
- XMStoreFloat4x4(&cube2WorldMat, tmpMat);
- return true;
- }
- void Update()
- {
- XMMATRIX rotXMat = XMMatrixRotationX(0.0001f);
- XMMATRIX rotYMat = XMMatrixRotationY(0.0002f);
- XMMATRIX rotZMat = XMMatrixRotationZ(0.0003f);
- XMMATRIX rotMat = XMLoadFloat4x4(&cube1RotMat) * rotXMat * rotYMat * rotZMat;
- XMStoreFloat4x4(&cube1RotMat, rotMat);
- XMMATRIX translationMat = XMMatrixTranslationFromVector(XMLoadFloat4(&cube1Position));
- XMMATRIX worldMat = rotMat * translationMat;
- XMStoreFloat4x4(&cube1WorldMat, worldMat);
- XMMATRIX viewMat = XMLoadFloat4x4(&cameraViewMat);
- XMMATRIX projMat = XMLoadFloat4x4(&cameraProjMat);
- XMMATRIX wvpMat = XMLoadFloat4x4(&cube1WorldMat) * viewMat * projMat;
- XMMATRIX transposed = XMMatrixTranspose(wvpMat);
- XMStoreFloat4x4(&cbPerObject.wvpMat, transposed);
- memcpy(cbvGPUAddress[frameIndex], &cbPerObject, sizeof(cbPerObject));
- rotXMat = XMMatrixRotationX(0.0003f);
- rotYMat = XMMatrixRotationY(0.0002f);
- rotZMat = XMMatrixRotationZ(0.0001f);
- rotMat = rotZMat * (XMLoadFloat4x4(&cube2RotMat) * (rotXMat * rotYMat));
- XMStoreFloat4x4(&cube2RotMat, rotMat);
- XMMATRIX translationOffsetMat = XMMatrixTranslationFromVector(XMLoadFloat4(&cube2PositionOffset));
- XMMATRIX scaleMat = XMMatrixScaling(0.5f, 0.5f, 0.5f);
- worldMat = scaleMat * translationOffsetMat * rotMat * translationMat;
- wvpMat = XMLoadFloat4x4(&cube2WorldMat) * viewMat * projMat;
- transposed = XMMatrixTranspose(wvpMat);
- XMStoreFloat4x4(&cbPerObject.wvpMat, transposed);
- memcpy(cbvGPUAddress[frameIndex] + ConstantBufferPerObjectAlignedSize, &cbPerObject, sizeof(cbPerObject));
- XMStoreFloat4x4(&cube2WorldMat, worldMat);
- }
- void UpdatePipeline()
- {
- HRESULT hr;
- WaitForPreviousFrame();
- if (FAILED(commandAllocator[frameIndex]->Reset()))
- {
- Running = false;
- }
- hr = commandList->Reset(commandAllocator[frameIndex], pipelineStateObject);
- if (FAILED(hr))
- {
- Running = false;
- }
- D3D12_RESOURCE_BARRIER renderTargetsBarrier = D3D12_RESOURCE_BARRIER();
- renderTargetsBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
- renderTargetsBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
- renderTargetsBarrier.Transition.pResource = renderTargets[frameIndex];
- renderTargetsBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
- renderTargetsBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
- renderTargetsBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
- commandList->ResourceBarrier(1, &renderTargetsBarrier);
- D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle(rtvDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
- rtvHandle.ptr += (int32)frameIndex * rtvDescriptorSize;
- D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle(dsDescriptorHeap->GetCPUDescriptorHandleForHeapStart());
- commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
- const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f };
- commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
- commandList->ClearDepthStencilView(dsDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);
- commandList->SetGraphicsRootSignature(rootSignature);
- commandList->RSSetViewports(1, &viewport);
- commandList->RSSetScissorRects(1, &scissorRect);
- commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
- commandList->IASetVertexBuffers(0, 1, &vertexBufferView);
- commandList->IASetIndexBuffer(&indexBufferView);
- //first cube
- commandList->SetGraphicsRootConstantBufferView(0, constantBufferUploadHeaps[frameIndex]->GetGPUVirtualAddress());
- commandList->DrawIndexedInstanced(numCubeIndices, 1, 0, 0, 0);
- //second cube
- commandList->SetGraphicsRootConstantBufferView(0, constantBufferUploadHeaps[frameIndex]->GetGPUVirtualAddress() + ConstantBufferPerObjectAlignedSize);
- commandList->DrawIndexedInstanced(numCubeIndices, 1, 0, 0, 0);
- D3D12_RESOURCE_BARRIER presentBarrier = D3D12_RESOURCE_BARRIER();
- presentBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
- presentBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
- presentBarrier.Transition.pResource = renderTargets[frameIndex];
- presentBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
- presentBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
- presentBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
- commandList->ResourceBarrier(1, &presentBarrier);
- hr = commandList->Close();
- if (FAILED(hr))
- {
- Running = false;
- }
- }
- void Render()
- {
- UpdatePipeline();
- ID3D12CommandList* ppCommandLists[] = { commandList };
- commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
- auto hr = commandQueue->Signal(fence[frameIndex], fenceValue[frameIndex]);
- if (FAILED(hr))
- {
- Running = false;
- }
- hr = swapChain->Present(0, 0);
- if (FAILED(hr))
- {
- Running = false;
- }
- }
- void Cleanup()
- {
- for (SIZE_T i = 0; i < frameBufferCount; ++i)
- {
- frameIndex = i;
- WaitForPreviousFrame();
- }
- BOOL fs = false;
- if (swapChain->GetFullscreenState(&fs, NULL))
- {
- swapChain->SetFullscreenState(false, NULL);
- }
- SAFE_RELEASE(swapChain);
- SAFE_RELEASE(commandQueue);
- SAFE_RELEASE(rtvDescriptorHeap);
- SAFE_RELEASE(commandList);
- for (SIZE_T i = 0; i < frameBufferCount; ++i)
- {
- SAFE_RELEASE(renderTargets[i]);
- SAFE_RELEASE(commandAllocator[i]);
- SAFE_RELEASE(fence[i]);
- };
- SAFE_RELEASE(pipelineStateObject);
- SAFE_RELEASE(rootSignature);
- SAFE_RELEASE(vertexBuffer);
- SAFE_RELEASE(indexBuffer);
- SAFE_RELEASE(depthStencilBuffer);
- SAFE_RELEASE(dsDescriptorHeap);
- for (SIZE_T i = 0; i < frameBufferCount; ++i)
- {
- SAFE_RELEASE(constantBufferUploadHeaps[i]);
- };
- }
- void WaitForPreviousFrame()
- {
- frameIndex = swapChain->GetCurrentBackBufferIndex();
- if (fence[frameIndex]->GetCompletedValue() < fenceValue[frameIndex])
- {
- auto hr = fence[frameIndex]->SetEventOnCompletion(fenceValue[frameIndex], fenceEvent);
- if (FAILED(hr))
- {
- Running = false;
- }
- WaitForSingleObject(fenceEvent, INFINITE);
- }
- fenceValue[frameIndex]++;
- }
Add Comment
Please, Sign In to add comment