Created
September 1, 2021 09:49
-
-
Save dmitrykolesnikovich/2e9e11cbd9e5fa9efcd2f16fbfd5a4bc to your computer and use it in GitHub Desktop.
directx example for windows
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
#include <d3d12.h> | |
#include <dxgi1_6.h> | |
#include <d3dcompiler.h> | |
#include <DirectXMath.h> | |
#pragma comment(lib, "d3d12.lib") | |
#pragma comment(lib, "dxgi.lib") | |
#pragma comment(lib, "d3dcompiler.lib") | |
HWND MainWindowHandle; | |
bool AppExitFlag; | |
ID3D12Device *Device; | |
IDXGISwapChain3 *SwapChain; | |
ID3D12CommandQueue *CommandQueue; | |
ID3D12CommandAllocator *CommandAllocators[2]; | |
ID3D12GraphicsCommandList *CommandList; | |
ID3D12Resource *BackBufferTextures[2]; | |
D3D12_CPU_DESCRIPTOR_HANDLE BackBufferTexturesRTVs[2]; | |
ID3D12DescriptorHeap *RTDescriptorHeap; | |
ID3D12Fence *FrameSyncFences[2]; | |
HANDLE FrameSyncEvent; | |
UINT CurrentFrameIndex; | |
UINT CurrentBackBufferIndex; | |
ID3D12DescriptorHeap *CBDescriptorHeaps[2]; | |
ID3D12Resource *VertexBuffer; | |
ID3D12Resource *ConstantBuffers[2]; | |
ID3D12PipelineState *PipelineState; | |
ID3D12RootSignature *RootSignature; | |
struct ConstantBufferStruct | |
{ | |
DirectX::XMMATRIX TransformMatrix; | |
DirectX::XMFLOAT4 VertexColors[3]; | |
}; | |
void Init() | |
{ | |
IDXGIFactory3 *Factory; | |
CreateDXGIFactory2(0, __uuidof(IDXGIFactory), (void**)&Factory); | |
IDXGIAdapter *Adapter; | |
HRESULT hr = Factory->EnumAdapters(0, &Adapter); | |
IDXGIOutput *Monitor; | |
hr = Adapter->EnumOutputs(0, &Monitor); | |
UINT DisplayModesCount = 0; | |
hr = Monitor->GetDisplayModeList(DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM, 0, &DisplayModesCount, nullptr); | |
DXGI_MODE_DESC *DisplayModes = new DXGI_MODE_DESC[DisplayModesCount]; | |
hr = Monitor->GetDisplayModeList(DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM, 0, &DisplayModesCount, DisplayModes); | |
hr = D3D12CreateDevice(Adapter, D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), (void**)&Device); | |
D3D12_COMMAND_QUEUE_DESC CommandQueueDesc; | |
CommandQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAGS::D3D12_COMMAND_QUEUE_FLAG_NONE; | |
CommandQueueDesc.NodeMask = 0; | |
CommandQueueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY::D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; | |
CommandQueueDesc.Type = D3D12_COMMAND_LIST_TYPE::D3D12_COMMAND_LIST_TYPE_DIRECT; | |
hr = Device->CreateCommandQueue(&CommandQueueDesc, __uuidof(ID3D12CommandQueue), (void**)&CommandQueue); | |
hr = Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE::D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void**)&CommandAllocators[0]); | |
hr = Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE::D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void**)&CommandAllocators[1]); | |
hr = Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE::D3D12_COMMAND_LIST_TYPE_DIRECT, CommandAllocators[0], nullptr, __uuidof(ID3D12GraphicsCommandList), (void**)&CommandList); | |
hr = CommandList->Close(); | |
DXGI_SWAP_CHAIN_DESC1 SwapChainDesc; | |
SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE::DXGI_ALPHA_MODE_UNSPECIFIED; | |
SwapChainDesc.BufferCount = 2; | |
SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; | |
SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG::DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH | DXGI_SWAP_CHAIN_FLAG::DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING; | |
SwapChainDesc.Format = DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM; | |
SwapChainDesc.Height = 720; | |
SwapChainDesc.SampleDesc.Count = 1; | |
SwapChainDesc.SampleDesc.Quality = 0; | |
SwapChainDesc.Scaling = DXGI_SCALING::DXGI_SCALING_STRETCH; | |
SwapChainDesc.Stereo = FALSE; | |
SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT::DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; | |
SwapChainDesc.Width = 1280; | |
DXGI_SWAP_CHAIN_FULLSCREEN_DESC SwapChainFullScreenDesc; | |
SwapChainFullScreenDesc.RefreshRate = DisplayModes[DisplayModesCount - 1].RefreshRate; | |
SwapChainFullScreenDesc.Scaling = DXGI_MODE_SCALING::DXGI_MODE_SCALING_UNSPECIFIED; | |
SwapChainFullScreenDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER::DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; | |
SwapChainFullScreenDesc.Windowed = TRUE; | |
IDXGISwapChain1 *SwapChain1; | |
hr = Factory->CreateSwapChainForHwnd(CommandQueue, MainWindowHandle, &SwapChainDesc, &SwapChainFullScreenDesc, nullptr, &SwapChain1); | |
hr = SwapChain1->QueryInterface<IDXGISwapChain3>(&SwapChain); | |
(void)SwapChain1->Release(); | |
hr = Factory->MakeWindowAssociation(MainWindowHandle, DXGI_MWA_NO_ALT_ENTER); | |
CurrentFrameIndex = 0; | |
CurrentBackBufferIndex = SwapChain->GetCurrentBackBufferIndex(); | |
hr = Device->CreateFence(1, D3D12_FENCE_FLAGS::D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), (void**)&FrameSyncFences[0]); | |
hr = Device->CreateFence(1, D3D12_FENCE_FLAGS::D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), (void**)&FrameSyncFences[1]); | |
FrameSyncEvent = CreateEvent(NULL, FALSE, FALSE, L"FrameSyncEvent"); | |
hr = SwapChain->GetBuffer(0, __uuidof(ID3D12Resource), (void**)&BackBufferTextures[0]); | |
hr = SwapChain->GetBuffer(1, __uuidof(ID3D12Resource), (void**)&BackBufferTextures[1]); | |
D3D12_DESCRIPTOR_HEAP_DESC DescriptorHeapDesc; | |
DescriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAGS::D3D12_DESCRIPTOR_HEAP_FLAG_NONE; | |
DescriptorHeapDesc.NodeMask = 0; | |
DescriptorHeapDesc.NumDescriptors = 2; | |
DescriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE::D3D12_DESCRIPTOR_HEAP_TYPE_RTV; | |
hr = Device->CreateDescriptorHeap(&DescriptorHeapDesc, __uuidof(ID3D12DescriptorHeap), (void**)&RTDescriptorHeap); | |
BackBufferTexturesRTVs[0].ptr = RTDescriptorHeap->GetCPUDescriptorHandleForHeapStart().ptr; | |
BackBufferTexturesRTVs[1].ptr = BackBufferTexturesRTVs[0].ptr + Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE::D3D12_DESCRIPTOR_HEAP_TYPE_RTV); | |
D3D12_RENDER_TARGET_VIEW_DESC RTVDesc; | |
RTVDesc.Format = DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; | |
RTVDesc.Texture2D.MipSlice = 0; | |
RTVDesc.Texture2D.PlaneSlice = 0; | |
RTVDesc.ViewDimension = D3D12_RTV_DIMENSION::D3D12_RTV_DIMENSION_TEXTURE2D; | |
Device->CreateRenderTargetView(BackBufferTextures[0], &RTVDesc, BackBufferTexturesRTVs[0]); | |
Device->CreateRenderTargetView(BackBufferTextures[1], &RTVDesc, BackBufferTexturesRTVs[1]); | |
D3D12_RESOURCE_DESC ResourceDesc; | |
ResourceDesc.Alignment = 0; | |
ResourceDesc.DepthOrArraySize = 1; | |
ResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION::D3D12_RESOURCE_DIMENSION_BUFFER; | |
ResourceDesc.Flags = D3D12_RESOURCE_FLAGS::D3D12_RESOURCE_FLAG_NONE; | |
ResourceDesc.Format = DXGI_FORMAT::DXGI_FORMAT_UNKNOWN; | |
ResourceDesc.Height = 1; | |
ResourceDesc.Layout = D3D12_TEXTURE_LAYOUT::D3D12_TEXTURE_LAYOUT_ROW_MAJOR; | |
ResourceDesc.MipLevels = 1; | |
ResourceDesc.SampleDesc.Count = 1; | |
ResourceDesc.SampleDesc.Quality = 0; | |
ResourceDesc.Width = 3 * 2 * sizeof(float); | |
D3D12_HEAP_PROPERTIES HeapProperties; | |
HeapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY::D3D12_CPU_PAGE_PROPERTY_UNKNOWN; | |
HeapProperties.CreationNodeMask = 0; | |
HeapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL::D3D12_MEMORY_POOL_UNKNOWN; | |
HeapProperties.Type = D3D12_HEAP_TYPE::D3D12_HEAP_TYPE_DEFAULT; | |
HeapProperties.VisibleNodeMask = 0; | |
hr = Device->CreateCommittedResource(&HeapProperties, D3D12_HEAP_FLAGS::D3D12_HEAP_FLAG_NONE, &ResourceDesc, D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_COPY_DEST, nullptr, __uuidof(ID3D12Resource), (void**)&VertexBuffer); | |
HeapProperties.Type = D3D12_HEAP_TYPE::D3D12_HEAP_TYPE_UPLOAD; | |
ID3D12Resource *TemporaryBuffer; | |
hr = Device->CreateCommittedResource(&HeapProperties, D3D12_HEAP_FLAGS::D3D12_HEAP_FLAG_NONE, &ResourceDesc, D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), (void**)&TemporaryBuffer); | |
void *TemporaryBufferData; | |
hr = TemporaryBuffer->Map(0, nullptr, &TemporaryBufferData); | |
((float*)TemporaryBufferData)[0] = 0.0f; | |
((float*)TemporaryBufferData)[1] = 1.0f; | |
((float*)TemporaryBufferData)[2] = 1.0f; | |
((float*)TemporaryBufferData)[3] = -1.0f; | |
((float*)TemporaryBufferData)[4] = -1.0f; | |
((float*)TemporaryBufferData)[5] = -1.0f; | |
TemporaryBuffer->Unmap(0, nullptr); | |
ID3D12Fence *UploadSyncFence; | |
hr = Device->CreateFence(0, D3D12_FENCE_FLAGS::D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), (void**)&UploadSyncFence); | |
HANDLE UploadSyncEvent = CreateEvent(NULL, FALSE, FALSE, L"UploadSyncEvent"); | |
hr = CommandAllocators[0]->Reset(); | |
hr = CommandList->Reset(CommandAllocators[0], nullptr); | |
CommandList->CopyBufferRegion(VertexBuffer, 0, TemporaryBuffer, 0, 3 * 2 * sizeof(float)); | |
D3D12_RESOURCE_BARRIER ResourceBarrier; | |
ResourceBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAGS::D3D12_RESOURCE_BARRIER_FLAG_NONE; | |
ResourceBarrier.Transition.pResource = VertexBuffer; | |
ResourceBarrier.Transition.StateAfter = D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER; | |
ResourceBarrier.Transition.StateBefore = D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_COPY_DEST; | |
ResourceBarrier.Transition.Subresource = 0; | |
ResourceBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE::D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; | |
CommandList->ResourceBarrier(1, &ResourceBarrier); | |
hr = CommandList->Close(); | |
CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList**)&CommandList); | |
hr = CommandQueue->Signal(UploadSyncFence, 1); | |
if (UploadSyncFence->GetCompletedValue() != 1) | |
{ | |
hr = UploadSyncFence->SetEventOnCompletion(1, UploadSyncEvent); | |
DWORD WaitResult = WaitForSingleObject(UploadSyncEvent, INFINITE); | |
} | |
(void)TemporaryBuffer->Release(); | |
(void)UploadSyncFence->Release(); | |
(void)CloseHandle(UploadSyncEvent); | |
DescriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAGS::D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; | |
DescriptorHeapDesc.NodeMask = 0; | |
DescriptorHeapDesc.NumDescriptors = 90; | |
DescriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE::D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; | |
hr = Device->CreateDescriptorHeap(&DescriptorHeapDesc, __uuidof(ID3D12DescriptorHeap), (void**)&CBDescriptorHeaps[0]); | |
hr = Device->CreateDescriptorHeap(&DescriptorHeapDesc, __uuidof(ID3D12DescriptorHeap), (void**)&CBDescriptorHeaps[1]); | |
ResourceDesc.Alignment = 0; | |
ResourceDesc.DepthOrArraySize = 1; | |
ResourceDesc.Dimension = D3D12_RESOURCE_DIMENSION::D3D12_RESOURCE_DIMENSION_BUFFER; | |
ResourceDesc.Flags = D3D12_RESOURCE_FLAGS::D3D12_RESOURCE_FLAG_NONE; | |
ResourceDesc.Format = DXGI_FORMAT::DXGI_FORMAT_UNKNOWN; | |
ResourceDesc.Height = 1; | |
ResourceDesc.Layout = D3D12_TEXTURE_LAYOUT::D3D12_TEXTURE_LAYOUT_ROW_MAJOR; | |
ResourceDesc.MipLevels = 1; | |
ResourceDesc.SampleDesc.Count = 1; | |
ResourceDesc.SampleDesc.Quality = 0; | |
ResourceDesc.Width = 256 * 90; | |
HeapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY::D3D12_CPU_PAGE_PROPERTY_UNKNOWN; | |
HeapProperties.CreationNodeMask = 0; | |
HeapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL::D3D12_MEMORY_POOL_UNKNOWN; | |
HeapProperties.Type = D3D12_HEAP_TYPE::D3D12_HEAP_TYPE_UPLOAD; | |
HeapProperties.VisibleNodeMask = 0; | |
hr = Device->CreateCommittedResource(&HeapProperties, D3D12_HEAP_FLAGS::D3D12_HEAP_FLAG_NONE, &ResourceDesc, D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), (void**)&ConstantBuffers[0]); | |
hr = Device->CreateCommittedResource(&HeapProperties, D3D12_HEAP_FLAGS::D3D12_HEAP_FLAG_NONE, &ResourceDesc, D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, __uuidof(ID3D12Resource), (void**)&ConstantBuffers[1]); | |
for (UINT i = 0; i < 90; i++) | |
{ | |
D3D12_CPU_DESCRIPTOR_HANDLE Descriptor = { CBDescriptorHeaps[0]->GetCPUDescriptorHandleForHeapStart().ptr + i * Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE::D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) }; | |
D3D12_CONSTANT_BUFFER_VIEW_DESC CBVDesc; | |
CBVDesc.BufferLocation = ConstantBuffers[0]->GetGPUVirtualAddress() + i * 256; | |
CBVDesc.SizeInBytes = 256; | |
Device->CreateConstantBufferView(&CBVDesc, Descriptor); | |
Descriptor = { CBDescriptorHeaps[1]->GetCPUDescriptorHandleForHeapStart().ptr + i * Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE::D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) }; | |
CBVDesc.BufferLocation = ConstantBuffers[1]->GetGPUVirtualAddress() + i * 256; | |
CBVDesc.SizeInBytes = 256; | |
Device->CreateConstantBufferView(&CBVDesc, Descriptor); | |
} | |
D3D12_DESCRIPTOR_RANGE DescriptorRange; | |
DescriptorRange.BaseShaderRegister = 0; | |
DescriptorRange.NumDescriptors = 90; | |
DescriptorRange.OffsetInDescriptorsFromTableStart = 0; | |
DescriptorRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE::D3D12_DESCRIPTOR_RANGE_TYPE_CBV; | |
DescriptorRange.RegisterSpace = 0; | |
D3D12_ROOT_PARAMETER RootParameter; | |
RootParameter.DescriptorTable.NumDescriptorRanges = 1; | |
RootParameter.DescriptorTable.pDescriptorRanges = &DescriptorRange; | |
RootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE::D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; | |
RootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY::D3D12_SHADER_VISIBILITY_VERTEX; | |
D3D12_ROOT_SIGNATURE_DESC RootSignatureDesc; | |
RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAGS::D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; | |
RootSignatureDesc.NumParameters = 1; | |
RootSignatureDesc.NumStaticSamplers = 0; | |
RootSignatureDesc.pParameters = &RootParameter; | |
RootSignatureDesc.pStaticSamplers = nullptr; | |
ID3DBlob *RootSignatureBlob; | |
hr = D3D12SerializeRootSignature(&RootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION::D3D_ROOT_SIGNATURE_VERSION_1_0, &RootSignatureBlob, nullptr); | |
hr = Device->CreateRootSignature(0, RootSignatureBlob->GetBufferPointer(), RootSignatureBlob->GetBufferSize(), __uuidof(ID3D12RootSignature), (void**)&RootSignature); | |
(void)RootSignatureBlob->Release(); | |
ID3DBlob *VertexShaderBlob, *PixelShaderBlob; | |
hr = D3DCompileFromFile(L"Shaders.hlsl", nullptr, nullptr, "VS", "vs_5_1", D3DCOMPILE_PACK_MATRIX_ROW_MAJOR, 0, &VertexShaderBlob, nullptr); | |
hr = D3DCompileFromFile(L"Shaders.hlsl", nullptr, nullptr, "PS", "ps_5_1", D3DCOMPILE_PACK_MATRIX_ROW_MAJOR, 0, &PixelShaderBlob, nullptr); | |
D3D12_INPUT_ELEMENT_DESC InputElementDesc; | |
InputElementDesc.AlignedByteOffset = 0; | |
InputElementDesc.Format = DXGI_FORMAT::DXGI_FORMAT_R32G32_FLOAT; | |
InputElementDesc.InputSlot = 0; | |
InputElementDesc.InputSlotClass = D3D12_INPUT_CLASSIFICATION::D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; | |
InputElementDesc.InstanceDataStepRate = 0; | |
InputElementDesc.SemanticIndex = 0; | |
InputElementDesc.SemanticName = "POSITION"; | |
D3D12_GRAPHICS_PIPELINE_STATE_DESC GraphicsPipelineStateDesc; | |
ZeroMemory(&GraphicsPipelineStateDesc, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC)); | |
GraphicsPipelineStateDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE::D3D12_COLOR_WRITE_ENABLE_ALL; | |
GraphicsPipelineStateDesc.InputLayout.NumElements = 1; | |
GraphicsPipelineStateDesc.InputLayout.pInputElementDescs = &InputElementDesc; | |
GraphicsPipelineStateDesc.NumRenderTargets = 1; | |
GraphicsPipelineStateDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE::D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; | |
GraphicsPipelineStateDesc.pRootSignature = RootSignature; | |
GraphicsPipelineStateDesc.PS.BytecodeLength = PixelShaderBlob->GetBufferSize(); | |
GraphicsPipelineStateDesc.PS.pShaderBytecode = PixelShaderBlob->GetBufferPointer(); | |
GraphicsPipelineStateDesc.RasterizerState.CullMode = D3D12_CULL_MODE::D3D12_CULL_MODE_BACK; | |
GraphicsPipelineStateDesc.RasterizerState.FillMode = D3D12_FILL_MODE::D3D12_FILL_MODE_SOLID; | |
GraphicsPipelineStateDesc.RTVFormats[0] = DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; | |
GraphicsPipelineStateDesc.SampleDesc.Count = 1; | |
GraphicsPipelineStateDesc.SampleDesc.Quality = 0; | |
GraphicsPipelineStateDesc.SampleMask = D3D12_DEFAULT_SAMPLE_MASK; | |
GraphicsPipelineStateDesc.VS.BytecodeLength = VertexShaderBlob->GetBufferSize(); | |
GraphicsPipelineStateDesc.VS.pShaderBytecode = VertexShaderBlob->GetBufferPointer(); | |
hr = Device->CreateGraphicsPipelineState(&GraphicsPipelineStateDesc, __uuidof(ID3D12PipelineState), (void**)&PipelineState); | |
(void)VertexShaderBlob->Release(); | |
(void)PixelShaderBlob->Release(); | |
ULONG RefCount; | |
RefCount = Factory->Release(); | |
RefCount = Adapter->Release(); | |
RefCount = Monitor->Release(); | |
delete[] DisplayModes; | |
} | |
void Render() | |
{ | |
HRESULT hr; | |
if (FrameSyncFences[CurrentFrameIndex]->GetCompletedValue() != 1) | |
{ | |
hr = FrameSyncFences[CurrentFrameIndex]->SetEventOnCompletion(1, FrameSyncEvent); | |
DWORD WaitResult = WaitForSingleObject(FrameSyncEvent, INFINITE); | |
} | |
hr = FrameSyncFences[CurrentFrameIndex]->Signal(0); | |
hr = CommandAllocators[CurrentFrameIndex]->Reset(); | |
hr = CommandList->Reset(CommandAllocators[CurrentFrameIndex], nullptr); | |
D3D12_RESOURCE_BARRIER ResourceBarrier; | |
ResourceBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAGS::D3D12_RESOURCE_BARRIER_FLAG_NONE; | |
ResourceBarrier.Transition.pResource = BackBufferTextures[CurrentFrameIndex]; | |
ResourceBarrier.Transition.StateAfter = D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_RENDER_TARGET; | |
ResourceBarrier.Transition.StateBefore = D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_PRESENT; | |
ResourceBarrier.Transition.Subresource = 0; | |
ResourceBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE::D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; | |
CommandList->ResourceBarrier(1, &ResourceBarrier); | |
float ClearColor[4] = { 0.0f, 0.5f, 0.75f, 1.0f }; | |
CommandList->ClearRenderTargetView(BackBufferTexturesRTVs[CurrentFrameIndex], ClearColor, 0, nullptr); | |
BYTE *ConstantBufferData; | |
hr = ConstantBuffers[CurrentFrameIndex]->Map(0, nullptr, (void**)&ConstantBufferData); | |
for (UINT x = 0; x < 10; x++) | |
{ | |
for (UINT y = 0; y < 9; y++) | |
{ | |
UINT i = y * 10 + x; | |
((ConstantBufferStruct*)ConstantBufferData)->TransformMatrix = DirectX::XMMatrixScaling(1.0f / 20.0f, 1.0f / 14.0f, 1.0f) * DirectX::XMMatrixTranslation(-0.703125f + x * 0.15625f, -0.777778f + y * 0.19444f, 0.0f); | |
((ConstantBufferStruct*)ConstantBufferData)->VertexColors[0] = DirectX::XMFLOAT4(1.0f * (x / 9.0f), 0.0f, 0.0f, 1.0f); | |
((ConstantBufferStruct*)ConstantBufferData)->VertexColors[1] = DirectX::XMFLOAT4(1.0f * (y / 8.0f), 0.5f, 1.0f * (x / 9.0f), 1.0f); | |
((ConstantBufferStruct*)ConstantBufferData)->VertexColors[2] = DirectX::XMFLOAT4(0.0f, 0.0f, 1.0f * (y / 8.0f), 1.0f); | |
ConstantBufferData += 256; | |
} | |
} | |
ConstantBuffers[CurrentFrameIndex]->Unmap(0, nullptr); | |
CommandList->SetDescriptorHeaps(1, &CBDescriptorHeaps[CurrentFrameIndex]); | |
CommandList->SetGraphicsRootSignature(RootSignature); | |
CommandList->SetPipelineState(PipelineState); | |
CommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY::D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); | |
CommandList->OMSetRenderTargets(1, &BackBufferTexturesRTVs[CurrentBackBufferIndex], TRUE, nullptr); | |
D3D12_VERTEX_BUFFER_VIEW VertexBufferView; | |
VertexBufferView.BufferLocation = VertexBuffer->GetGPUVirtualAddress(); | |
VertexBufferView.SizeInBytes = 3 * 2 * sizeof(float); | |
VertexBufferView.StrideInBytes = 2 * sizeof(float); | |
CommandList->IASetVertexBuffers(0, 1, &VertexBufferView); | |
D3D12_VIEWPORT Viewport; | |
Viewport.Height = 720.0f; | |
Viewport.MaxDepth = 1.0f; | |
Viewport.MinDepth = 0.0f; | |
Viewport.TopLeftX = 0.0f; | |
Viewport.TopLeftY = 0.0f; | |
Viewport.Width = 1280.0f; | |
CommandList->RSSetViewports(1, &Viewport); | |
D3D12_RECT ScissorRect; | |
ScissorRect.bottom = 720; | |
ScissorRect.left = 0; | |
ScissorRect.right = 1280; | |
ScissorRect.top = 0; | |
CommandList->RSSetScissorRects(1, &ScissorRect); | |
D3D12_GPU_DESCRIPTOR_HANDLE Descriptor = { CBDescriptorHeaps[CurrentFrameIndex]->GetGPUDescriptorHandleForHeapStart().ptr }; | |
CommandList->SetGraphicsRootDescriptorTable(0, Descriptor); | |
CommandList->DrawInstanced(3, 90, 0, 0); | |
ResourceBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAGS::D3D12_RESOURCE_BARRIER_FLAG_NONE; | |
ResourceBarrier.Transition.pResource = BackBufferTextures[CurrentFrameIndex]; | |
ResourceBarrier.Transition.StateAfter = D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_PRESENT; | |
ResourceBarrier.Transition.StateBefore = D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_RENDER_TARGET; | |
ResourceBarrier.Transition.Subresource = 0; | |
ResourceBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE::D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; | |
CommandList->ResourceBarrier(1, &ResourceBarrier); | |
hr = CommandList->Close(); | |
CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList**)&CommandList); | |
hr = SwapChain->Present(0, DXGI_PRESENT_ALLOW_TEARING); | |
hr = CommandQueue->Signal(FrameSyncFences[CurrentFrameIndex], 1); | |
CurrentFrameIndex = (CurrentFrameIndex + 1) % 2; | |
CurrentBackBufferIndex = SwapChain->GetCurrentBackBufferIndex(); | |
} | |
void Shutdown() | |
{ | |
CurrentFrameIndex = (CurrentFrameIndex + 1) % 2; | |
HRESULT hr; | |
if (FrameSyncFences[CurrentFrameIndex]->GetCompletedValue() != 1) | |
{ | |
hr = FrameSyncFences[CurrentFrameIndex]->SetEventOnCompletion(1, FrameSyncEvent); | |
DWORD WaitResult = WaitForSingleObject(FrameSyncEvent, INFINITE); | |
} | |
ULONG RefCount; | |
RefCount = RTDescriptorHeap->Release(); | |
RefCount = CBDescriptorHeaps[0]->Release(); | |
RefCount = CBDescriptorHeaps[1]->Release(); | |
RefCount = PipelineState->Release(); | |
RefCount = RootSignature->Release(); | |
RefCount = ConstantBuffers[0]->Release(); | |
RefCount = ConstantBuffers[1]->Release(); | |
RefCount = VertexBuffer->Release(); | |
RefCount = BackBufferTextures[0]->Release(); | |
RefCount = BackBufferTextures[1]->Release(); | |
RefCount = FrameSyncFences[0]->Release(); | |
RefCount = FrameSyncFences[1]->Release(); | |
BOOL Result = CloseHandle(FrameSyncEvent); | |
RefCount = CommandList->Release(); | |
RefCount = CommandAllocators[0]->Release(); | |
RefCount = CommandAllocators[1]->Release(); | |
RefCount = CommandQueue->Release(); | |
RefCount = SwapChain->Release(); | |
RefCount = Device->Release(); | |
} | |
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) | |
{ | |
if (Msg == WM_CLOSE) | |
AppExitFlag = true; | |
return DefWindowProc(hWnd, Msg, wParam, lParam); | |
} | |
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) | |
{ | |
WNDCLASSEX WndClassEx; | |
ZeroMemory(&WndClassEx, sizeof(WNDCLASSEX)); | |
WndClassEx.cbSize = sizeof(WNDCLASSEX); | |
WndClassEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); | |
WndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW); | |
WndClassEx.hIcon = NULL; | |
WndClassEx.hIconSm = NULL; | |
WndClassEx.hInstance = hInstance; | |
WndClassEx.lpfnWndProc = &MainWindowProc; | |
WndClassEx.lpszClassName = L"MainWndClass"; | |
WndClassEx.lpszMenuName = NULL; | |
WndClassEx.style = 0; | |
ATOM Atom = RegisterClassEx(&WndClassEx); | |
DWORD WindowStyle = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; | |
RECT WindowRect; | |
WindowRect.bottom = 720; | |
WindowRect.left = 0; | |
WindowRect.right = 1280; | |
WindowRect.top = 0; | |
BOOL Result = AdjustWindowRect(&WindowRect, WindowStyle, FALSE); | |
int ScreenWidth = GetSystemMetrics(SM_CXSCREEN); | |
int ScreenHeight = GetSystemMetrics(SM_CYSCREEN); | |
int WindowWidth = WindowRect.right - WindowRect.left; | |
int WindowHeight = WindowRect.bottom - WindowRect.top; | |
int WindowLeft = ScreenWidth / 2 - WindowWidth / 2; | |
int WindowTop = ScreenHeight / 2 - WindowHeight / 2; | |
MainWindowHandle = CreateWindowEx(0, L"MainWndClass", L"Constant Buffer Test", WindowStyle, WindowLeft, WindowTop, WindowWidth, WindowHeight, NULL, NULL, hInstance, NULL); | |
Result = UpdateWindow(MainWindowHandle); | |
Result = ShowWindow(MainWindowHandle, SW_SHOW); | |
AppExitFlag = false; | |
Init(); | |
MSG Message; | |
while (!AppExitFlag) | |
{ | |
while (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) | |
{ | |
TranslateMessage(&Message); | |
DispatchMessage(&Message); | |
} | |
if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) AppExitFlag = true; | |
Render(); | |
} | |
Shutdown(); | |
Result = DestroyWindow(MainWindowHandle); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment