Created
October 11, 2025 12:59
-
-
Save ranjian0/34e46a27e0529edbf2da6ddcf216be9e to your computer and use it in GitHub Desktop.
SDL3_D3D_Examples
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 <SDL3/SDL.h> | |
| #include <d3d11.h> | |
| #include <d3dcompiler.h> | |
| #include <iostream> | |
| #pragma comment(lib, "d3d11.lib") | |
| #pragma comment(lib, "d3dcompiler.lib") | |
| // Simple vertex structure | |
| struct Vertex { | |
| float x, y, z; | |
| float r, g, b; | |
| }; | |
| // Vertex shader source | |
| const char* vsSource = R"( | |
| struct VS_INPUT { | |
| float3 pos : POSITION; | |
| float3 color : COLOR; | |
| }; | |
| struct VS_OUTPUT { | |
| float4 pos : SV_POSITION; | |
| float4 color : COLOR; | |
| }; | |
| VS_OUTPUT main(VS_INPUT input) { | |
| VS_OUTPUT output; | |
| output.pos = float4(input.pos, 1.0f); | |
| output.color = float4(input.color, 1.0f); | |
| return output; | |
| } | |
| )"; | |
| // Pixel shader source | |
| const char* psSource = R"( | |
| float4 main(float4 pos : SV_POSITION, float4 color : COLOR) : SV_TARGET { | |
| return color; | |
| } | |
| )"; | |
| int main(int argc, char* argv[]) { | |
| if (!SDL_Init(SDL_INIT_VIDEO)) { | |
| std::cerr << "Failed to initialize SDL: " << SDL_GetError() << std::endl; | |
| return -1; | |
| } | |
| SDL_Window* window = SDL_CreateWindow("D3D11 Triangle with SDL3", 800, 600, 0); | |
| if (!window) { | |
| std::cerr << "Failed to create window: " << SDL_GetError() << std::endl; | |
| SDL_Quit(); | |
| return -1; | |
| } | |
| HWND hwnd = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr); | |
| if (!hwnd) { | |
| std::cerr << "Failed to get native window handle: " << SDL_GetError() << std::endl; | |
| SDL_DestroyWindow(window); | |
| SDL_Quit(); | |
| return -1; | |
| } | |
| // --- Direct3D 11 Initialization --- | |
| ID3D11Device* device = nullptr; | |
| ID3D11DeviceContext* context = nullptr; | |
| IDXGISwapChain* swapChain = nullptr; | |
| ID3D11RenderTargetView* renderTargetView = nullptr; | |
| DXGI_SWAP_CHAIN_DESC scd = {}; | |
| scd.BufferCount = 1; | |
| scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; | |
| scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; | |
| scd.OutputWindow = hwnd; | |
| scd.SampleDesc.Count = 1; | |
| scd.Windowed = TRUE; | |
| HRESULT hr = D3D11CreateDeviceAndSwapChain( | |
| nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, | |
| D3D11_SDK_VERSION, &scd, &swapChain, &device, nullptr, &context); | |
| if (FAILED(hr)) { | |
| std::cerr << "D3D11CreateDeviceAndSwapChain failed." << std::endl; | |
| // Cleanup SDL | |
| return -1; | |
| } | |
| ID3D11Texture2D* pBackBuffer = nullptr; | |
| swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); | |
| device->CreateRenderTargetView(pBackBuffer, nullptr, &renderTargetView); | |
| pBackBuffer->Release(); | |
| context->OMSetRenderTargets(1, &renderTargetView, nullptr); | |
| // --- Shader and Vertex Buffer Creation --- | |
| ID3DBlob* vsBlob = nullptr; | |
| ID3DBlob* errorBlob = nullptr; | |
| D3DCompile(vsSource, strlen(vsSource), nullptr, nullptr, nullptr, "main", "vs_5_0", 0, 0, &vsBlob, &errorBlob); | |
| if (errorBlob) { | |
| std::cerr << "Vertex shader compilation error: " << (char*)errorBlob->GetBufferPointer() << std::endl; | |
| // Cleanup | |
| return -1; | |
| } | |
| ID3DBlob* psBlob = nullptr; | |
| D3DCompile(psSource, strlen(psSource), nullptr, nullptr, nullptr, "main", "ps_5_0", 0, 0, &psBlob, &errorBlob); | |
| if (errorBlob) { | |
| std::cerr << "Pixel shader compilation error: " << (char*)errorBlob->GetBufferPointer() << std::endl; | |
| // Cleanup | |
| return -1; | |
| } | |
| ID3D11VertexShader* vertexShader = nullptr; | |
| ID3D11PixelShader* pixelShader = nullptr; | |
| device->CreateVertexShader(vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), nullptr, &vertexShader); | |
| device->CreatePixelShader(psBlob->GetBufferPointer(), psBlob->GetBufferSize(), nullptr, &pixelShader); | |
| Vertex vertices[] = { | |
| { 0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f }, | |
| { 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f }, | |
| { -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f } | |
| }; | |
| D3D11_BUFFER_DESC bd = {}; | |
| bd.Usage = D3D11_USAGE_DEFAULT; | |
| bd.ByteWidth = sizeof(Vertex) * 3; | |
| bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; | |
| D3D11_SUBRESOURCE_DATA sd = {}; | |
| sd.pSysMem = vertices; | |
| ID3D11Buffer* vertexBuffer = nullptr; | |
| device->CreateBuffer(&bd, &sd, &vertexBuffer); | |
| // --- Input Layout --- | |
| D3D11_INPUT_ELEMENT_DESC ied[] = { | |
| {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, | |
| {"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0} | |
| }; | |
| ID3D11InputLayout* inputLayout = nullptr; | |
| device->CreateInputLayout(ied, 2, vsBlob->GetBufferPointer(), vsBlob->GetBufferSize(), &inputLayout); | |
| // --- Main Loop --- | |
| bool running = true; | |
| while (running) { | |
| SDL_Event event; | |
| while (SDL_PollEvent(&event)) { | |
| if (event.type == SDL_EVENT_QUIT) { | |
| running = false; | |
| } | |
| } | |
| // --- Rendering --- | |
| float clearColor[] = { 0.1f, 0.1f, 0.1f, 1.0f }; | |
| context->ClearRenderTargetView(renderTargetView, clearColor); | |
| UINT stride = sizeof(Vertex); | |
| UINT offset = 0; | |
| context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); | |
| context->IASetInputLayout(inputLayout); | |
| context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); | |
| context->VSSetShader(vertexShader, nullptr, 0); | |
| context->PSSetShader(pixelShader, nullptr, 0); | |
| D3D11_VIEWPORT viewport = {}; | |
| viewport.Width = 800; | |
| viewport.Height = 600; | |
| viewport.MaxDepth = 1.0f; | |
| context->RSSetViewports(1, &viewport); | |
| context->Draw(3, 0); | |
| swapChain->Present(1, 0); | |
| } | |
| // --- Cleanup --- | |
| vertexShader->Release(); | |
| pixelShader->Release(); | |
| vsBlob->Release(); | |
| psBlob->Release(); | |
| vertexBuffer->Release(); | |
| inputLayout->Release(); | |
| renderTargetView->Release(); | |
| swapChain->Release(); | |
| context->Release(); | |
| device->Release(); | |
| SDL_DestroyWindow(window); | |
| SDL_Quit(); | |
| return 0; | |
| } |
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 <SDL3/SDL.h> | |
| #include <d3d12.h> | |
| #include <dxgi1_6.h> | |
| #include <d3dcompiler.h> | |
| #include <DirectXMath.h> | |
| #include <iostream> | |
| #include <vector> | |
| #include <wrl.h> // For Microsoft::WRL::ComPtr | |
| #pragma comment(lib, "d3d12.lib") | |
| #pragma comment(lib, "dxgi.lib") | |
| #pragma comment(lib, "d3dcompiler.lib") | |
| using namespace DirectX; | |
| using Microsoft::WRL::ComPtr; | |
| // Simple vertex structure | |
| struct Vertex { | |
| XMFLOAT3 pos; | |
| XMFLOAT4 color; | |
| }; | |
| // Global constants | |
| const UINT FrameCount = 2; // Number of back buffers (double-buffering) | |
| // D3D12 objects | |
| ComPtr<ID3D12Device> g_device; | |
| ComPtr<ID3D12CommandQueue> g_commandQueue; | |
| ComPtr<IDXGISwapChain3> g_swapChain; | |
| ComPtr<ID3D12DescriptorHeap> g_rtvHeap; | |
| ComPtr<ID3D12Resource> g_renderTargets[FrameCount]; | |
| ComPtr<ID3D12CommandAllocator> g_commandAllocator; | |
| ComPtr<ID3D12RootSignature> g_rootSignature; | |
| ComPtr<ID3D12PipelineState> g_pipelineState; | |
| ComPtr<ID3D12GraphicsCommandList> g_commandList; | |
| UINT g_rtvDescriptorSize; | |
| // Vertex buffer | |
| ComPtr<ID3D12Resource> g_vertexBuffer; | |
| D3D12_VERTEX_BUFFER_VIEW g_vertexBufferView; | |
| // Synchronization objects | |
| UINT g_frameIndex; | |
| ComPtr<ID3D12Fence> g_fence; | |
| UINT64 g_fenceValue; | |
| HANDLE g_fenceEvent; | |
| // Helper function to wait for the GPU to finish commands | |
| void WaitForPreviousFrame() { | |
| // Signal and increment the fence value. | |
| const UINT64 fence = g_fenceValue; | |
| g_commandQueue->Signal(g_fence.Get(), fence); | |
| g_fenceValue++; | |
| // Wait until the previous frame is finished. | |
| if (g_fence->GetCompletedValue() < fence) { | |
| g_fence->SetEventOnCompletion(fence, g_fenceEvent); | |
| WaitForSingleObject(g_fenceEvent, INFINITE); | |
| } | |
| g_frameIndex = g_swapChain->GetCurrentBackBufferIndex(); | |
| } | |
| int main(int argc, char* argv[]) { | |
| // --- 1. SDL Initialization and Window Creation --- | |
| if (!SDL_Init(SDL_INIT_VIDEO)) { | |
| std::cerr << "Failed to initialize SDL: " << SDL_GetError() << std::endl; | |
| return -1; | |
| } | |
| SDL_Window* window = SDL_CreateWindow("D3D12 Triangle with SDL3", 1280, 720, 0); | |
| if (!window) { | |
| std::cerr << "Failed to create window: " << SDL_GetError() << std::endl; | |
| SDL_Quit(); | |
| return -1; | |
| } | |
| HWND hwnd = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); | |
| if (!hwnd) { | |
| std::cerr << "Failed to get native window handle." << std::endl; | |
| SDL_DestroyWindow(window); | |
| SDL_Quit(); | |
| return -1; | |
| } | |
| // --- 2. D3D12 Initialization --- | |
| ComPtr<ID3D12Debug> debugController; | |
| if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) { | |
| debugController->EnableDebugLayer(); | |
| } | |
| ComPtr<IDXGIFactory4> factory; | |
| CreateDXGIFactory1(IID_PPV_ARGS(&factory)); | |
| if (FAILED(D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&g_device)))) { | |
| std::cerr << "D3D12CreateDevice failed." << std::endl; | |
| return -1; | |
| } | |
| // Create Command Queue | |
| D3D12_COMMAND_QUEUE_DESC queueDesc = {}; | |
| queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; | |
| queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; | |
| g_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&g_commandQueue)); | |
| // Create Swap Chain | |
| DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {}; | |
| swapChainDesc.BufferCount = FrameCount; | |
| swapChainDesc.Width = 1280; | |
| swapChainDesc.Height = 720; | |
| swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; | |
| swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; | |
| swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; | |
| swapChainDesc.SampleDesc.Count = 1; | |
| ComPtr<IDXGISwapChain1> swapChain; | |
| factory->CreateSwapChainForHwnd( | |
| g_commandQueue.Get(), // The command queue | |
| hwnd, | |
| &swapChainDesc, | |
| nullptr, | |
| nullptr, | |
| &swapChain | |
| ); | |
| factory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER); | |
| swapChain.As(&g_swapChain); | |
| g_frameIndex = g_swapChain->GetCurrentBackBufferIndex(); | |
| // Create RTV Descriptor Heap | |
| D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {}; | |
| rtvHeapDesc.NumDescriptors = FrameCount; | |
| rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; | |
| rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; | |
| g_device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&g_rtvHeap)); | |
| g_rtvDescriptorSize = g_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); | |
| // Create Render Target Views | |
| D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_rtvHeap->GetCPUDescriptorHandleForHeapStart(); | |
| for (UINT n = 0; n < FrameCount; n++) { | |
| g_swapChain->GetBuffer(n, IID_PPV_ARGS(&g_renderTargets[n])); | |
| g_device->CreateRenderTargetView(g_renderTargets[n].Get(), nullptr, rtvHandle); | |
| rtvHandle.ptr += g_rtvDescriptorSize; | |
| } | |
| // Create Command Allocator | |
| g_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&g_commandAllocator)); | |
| // --- 3. Create Pipeline State --- | |
| // Create an empty root signature | |
| D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc = {}; | |
| rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; | |
| ComPtr<ID3DBlob> signature; | |
| ComPtr<ID3DBlob> error; | |
| D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); | |
| g_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&g_rootSignature)); | |
| // Create shaders | |
| ComPtr<ID3DBlob> vertexShader; | |
| ComPtr<ID3DBlob> pixelShader; | |
| UINT compileFlags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; | |
| const char* shaderSource = R"( | |
| struct PSInput { | |
| float4 position : SV_POSITION; | |
| float4 color : COLOR; | |
| }; | |
| PSInput VSMain(float4 position : POSITION, float4 color : COLOR) { | |
| PSInput result; | |
| result.position = position; | |
| result.color = color; | |
| return result; | |
| } | |
| float4 PSMain(PSInput input) : SV_TARGET { | |
| return input.color; | |
| } | |
| )"; | |
| D3DCompile(shaderSource, strlen(shaderSource), nullptr, nullptr, nullptr, "VSMain", "vs_5_0", compileFlags, 0, &vertexShader, nullptr); | |
| D3DCompile(shaderSource, strlen(shaderSource), nullptr, nullptr, nullptr, "PSMain", "ps_5_0", compileFlags, 0, &pixelShader, nullptr); | |
| // Define the vertex input layout | |
| D3D12_INPUT_ELEMENT_DESC inputElementDescs[] = { | |
| { "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 } | |
| }; | |
| // Describe and create the graphics pipeline state object (PSO) | |
| D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; | |
| psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) }; | |
| psoDesc.pRootSignature = g_rootSignature.Get(); | |
| psoDesc.VS = { vertexShader->GetBufferPointer(), vertexShader->GetBufferSize() }; | |
| psoDesc.PS = { pixelShader->GetBufferPointer(), pixelShader->GetBufferSize() }; | |
| psoDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; | |
| psoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; | |
| psoDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; | |
| psoDesc.SampleMask = UINT_MAX; | |
| psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; | |
| psoDesc.NumRenderTargets = 1; | |
| psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; | |
| psoDesc.SampleDesc.Count = 1; | |
| g_device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&g_pipelineState)); | |
| // --- 4. Create Command List and Vertex Buffer --- | |
| g_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, g_commandAllocator.Get(), g_pipelineState.Get(), IID_PPV_ARGS(&g_commandList)); | |
| // Define triangle vertices | |
| Vertex triangleVertices[] = { | |
| { { 0.0f, 0.5f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, | |
| { { 0.5f, -0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, | |
| { { -0.5f, -0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } } | |
| }; | |
| const UINT vertexBufferSize = sizeof(triangleVertices); | |
| // Create the vertex buffer resource | |
| D3D12_HEAP_PROPERTIES heapProps = { D3D12_HEAP_TYPE_UPLOAD }; | |
| D3D12_RESOURCE_DESC bufferDesc = { D3D12_RESOURCE_DIMENSION_BUFFER, 0, vertexBufferSize, 1, 1, 1, DXGI_FORMAT_UNKNOWN, {1, 0}, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, D3D12_RESOURCE_FLAG_NONE }; | |
| g_device->CreateCommittedResource( | |
| &heapProps, | |
| D3D12_HEAP_FLAG_NONE, | |
| &bufferDesc, | |
| D3D12_RESOURCE_STATE_GENERIC_READ, | |
| nullptr, | |
| IID_PPV_ARGS(&g_vertexBuffer) | |
| ); | |
| // Copy the triangle data to the vertex buffer | |
| UINT8* pVertexDataBegin; | |
| D3D12_RANGE readRange = { 0, 0 }; | |
| g_vertexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pVertexDataBegin)); | |
| memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices)); | |
| g_vertexBuffer->Unmap(0, nullptr); | |
| // Initialize the vertex buffer view | |
| g_vertexBufferView.BufferLocation = g_vertexBuffer->GetGPUVirtualAddress(); | |
| g_vertexBufferView.StrideInBytes = sizeof(Vertex); | |
| g_vertexBufferView.SizeInBytes = vertexBufferSize; | |
| // Command list is created, now close it to be ready for execution | |
| g_commandList->Close(); | |
| // --- 5. Create Synchronization Objects --- | |
| g_device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&g_fence)); | |
| g_fenceValue = 1; | |
| g_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); | |
| // --- 6. Main Loop --- | |
| bool running = true; | |
| while (running) { | |
| SDL_Event event; | |
| while (SDL_PollEvent(&event)) { | |
| if (event.type == SDL_EVENT_QUIT) { | |
| running = false; | |
| } | |
| } | |
| // --- RECORD COMMANDS --- | |
| g_commandAllocator->Reset(); | |
| g_commandList->Reset(g_commandAllocator.Get(), g_pipelineState.Get()); | |
| // Set necessary states | |
| g_commandList->SetGraphicsRootSignature(g_rootSignature.Get()); | |
| D3D12_VIEWPORT viewport = { 0.0f, 0.0f, 1280.0f, 720.0f, 0.0f, 1.0f }; | |
| D3D12_RECT scissorRect = { 0, 0, 1280, 720 }; | |
| g_commandList->RSSetViewports(1, &viewport); | |
| g_commandList->RSSetScissorRects(1, &scissorRect); | |
| // Indicate that the back buffer will be used as a render target | |
| D3D12_RESOURCE_BARRIER barrier = {}; | |
| barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; | |
| barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; | |
| barrier.Transition.pResource = g_renderTargets[g_frameIndex].Get(); | |
| barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; | |
| barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; | |
| g_commandList->ResourceBarrier(1, &barrier); | |
| D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_rtvHeap->GetCPUDescriptorHandleForHeapStart(); | |
| rtvHandle.ptr += g_frameIndex * g_rtvDescriptorSize; | |
| g_commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr); | |
| // Record drawing commands | |
| const float clearColor[] = { 0.1f, 0.1f, 0.1f, 1.0f }; | |
| g_commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr); | |
| g_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); | |
| g_commandList->IASetVertexBuffers(0, 1, &g_vertexBufferView); | |
| g_commandList->DrawInstanced(3, 1, 0, 0); // Draw 3 vertices | |
| // Indicate that the back buffer will now be used to present | |
| barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; | |
| barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; | |
| g_commandList->ResourceBarrier(1, &barrier); | |
| g_commandList->Close(); | |
| // --- EXECUTE and PRESENT --- | |
| ID3D12CommandList* ppCommandLists[] = { g_commandList.Get() }; | |
| g_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); | |
| g_swapChain->Present(1, 0); | |
| WaitForPreviousFrame(); | |
| } | |
| // Wait for the GPU to be done with all resources before cleaning up. | |
| WaitForPreviousFrame(); | |
| CloseHandle(g_fenceEvent); | |
| SDL_DestroyWindow(window); | |
| SDL_Quit(); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment