#pragma comment(lib, "user32") #pragma comment(lib, "d3d11") #pragma comment(lib, "d3dcompiler") /////////////////////////////////////////////////////////////////////////////////////////////////// #include <windows.h> #include <d3d11.h> #include <d3dcompiler.h> /////////////////////////////////////////////////////////////////////////////////////////////////// int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { WNDCLASSA wndclass = { 0, DefWindowProcA, 0, 0, 0, 0, 0, 0, 0, "d7" }; RegisterClassA(&wndclass); HWND window = CreateWindowExA(0, "d7", 0, 0x91000000, 0, 0, 0, 0, 0, 0, 0, 0); /////////////////////////////////////////////////////////////////////////////////////////////// D3D_FEATURE_LEVEL featurelevels[] = { D3D_FEATURE_LEVEL_11_0 }; DXGI_SWAP_CHAIN_DESC swapchaindesc = {}; swapchaindesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // non-srgb for simplicity here. see other minimal gists for srgb setup swapchaindesc.SampleDesc.Count = 1; swapchaindesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapchaindesc.BufferCount = 2; swapchaindesc.OutputWindow = window; swapchaindesc.Windowed = TRUE; swapchaindesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; IDXGISwapChain* swapchain; ID3D11Device* device; ID3D11DeviceContext* devicecontext; D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT, featurelevels, ARRAYSIZE(featurelevels), D3D11_SDK_VERSION, &swapchaindesc, &swapchain, &device, nullptr, &devicecontext); swapchain->GetDesc(&swapchaindesc); // get actual dimensions (see lines 94, 98) /////////////////////////////////////////////////////////////////////////////////////////////// ID3D11Texture2D* framebuffer; swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&framebuffer); // get the swapchain's frame buffer ID3D11RenderTargetView* framebufferRTV; device->CreateRenderTargetView(framebuffer, nullptr, &framebufferRTV); // make a render target [view] from it FLOAT clearcolor[4] = { 0.1725f, 0.1725f, 0.1725f, 1.0f }; // RGBA /////////////////////////////////////////////////////////////////////////////////////////////// ID3DBlob* vertexshaderCSO; D3DCompileFromFile(L"gpu.hlsl", 0, 0, "VsMain", "vs_5_0", 0, 0, &vertexshaderCSO, 0); ID3D11VertexShader* vertexshader; device->CreateVertexShader(vertexshaderCSO->GetBufferPointer(), vertexshaderCSO->GetBufferSize(), 0, &vertexshader); D3D11_INPUT_ELEMENT_DESC inputelementdesc[] = // maps to vertexdesc struct in gpu.hlsl via semantic names ("POS", "COL") { { "POS", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // float2 position (x, y) { "COL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // float3 color (r, g, b) }; ID3D11InputLayout* inputlayout; device->CreateInputLayout(inputelementdesc, ARRAYSIZE(inputelementdesc), vertexshaderCSO->GetBufferPointer(), vertexshaderCSO->GetBufferSize(), &inputlayout); /////////////////////////////////////////////////////////////////////////////////////////////// ID3DBlob* pixelshaderCSO; D3DCompileFromFile(L"gpu.hlsl", 0, 0, "PsMain", "ps_5_0", 0, 0, &pixelshaderCSO, 0); ID3D11PixelShader* pixelshader; device->CreatePixelShader(pixelshaderCSO->GetBufferPointer(), pixelshaderCSO->GetBufferSize(), 0, &pixelshader); /////////////////////////////////////////////////////////////////////////////////////////////// D3D11_RASTERIZER_DESC rasterizerdesc = { D3D11_FILL_SOLID, D3D11_CULL_NONE }; // CULL_NONE to be agnostic of triangle winding order ID3D11RasterizerState* rasterizerstate; device->CreateRasterizerState(&rasterizerdesc, &rasterizerstate); D3D11_VIEWPORT viewport = { 0, 0, (float)swapchaindesc.BufferDesc.Width, (float)swapchaindesc.BufferDesc.Height, 0, 1 }; /////////////////////////////////////////////////////////////////////////////////////////////// float constants[2] = { 2.0f / swapchaindesc.BufferDesc.Width, -2.0f / swapchaindesc.BufferDesc.Height }; // precalc for simple screen coordinate transform in shader (instead of full-on projection matrix) D3D11_BUFFER_DESC constantbufferdesc = {}; constantbufferdesc.ByteWidth = sizeof(constants) + 0xf & 0xfffffff0; // constant buffer size must be multiple of 16 constantbufferdesc.Usage = D3D11_USAGE_IMMUTABLE; // never updated constantbufferdesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; D3D11_SUBRESOURCE_DATA constantbufferSRD = { constants }; ID3D11Buffer* constantbuffer; device->CreateBuffer(&constantbufferdesc, &constantbufferSRD, &constantbuffer); /////////////////////////////////////////////////////////////////////////////////////////////// #define MAX_VERTICES 1024 // arbitrary limit struct vertexdesc { float x, y, r, g, b; }; // float2 position, float3 color /////////////////////////////////////////////////////////////////////////////////////////////// D3D11_BUFFER_DESC vertexbufferdesc = {}; vertexbufferdesc.ByteWidth = sizeof(vertexdesc) * MAX_VERTICES; vertexbufferdesc.Usage = D3D11_USAGE_DYNAMIC; // updated every frame vertexbufferdesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; vertexbufferdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; ID3D11Buffer* vertexbuffer; device->CreateBuffer(&vertexbufferdesc, nullptr, &vertexbuffer); UINT stride = sizeof(vertexdesc); UINT offset = 0; /////////////////////////////////////////////////////////////////////////////////////////////// while (true) { MSG msg; while (PeekMessageA(&msg, nullptr, 0, 0, PM_REMOVE)) { if (msg.message == WM_KEYDOWN) return 0; // PRESS ANY KEY TO EXIT DispatchMessageA(&msg); } /////////////////////////////////////////////////////////////////////////////////////////// D3D11_MAPPED_SUBRESOURCE vertexbufferMSR; devicecontext->Map(vertexbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &vertexbufferMSR); { vertexdesc* vertex = (vertexdesc*)vertexbufferMSR.pData; vertex[0] = { 150, 100, 1.0f, 0.0f, 0.0f }; // vertex x, y, r, g, b vertex[1] = { 200, 250, 0.0f, 1.0f, 0.0f }; vertex[2] = { 100, 200, 0.0f, 0.0f, 1.0f }; } devicecontext->Unmap(vertexbuffer, 0); /////////////////////////////////////////////////////////////////////////////////////////// devicecontext->ClearRenderTargetView(framebufferRTV, clearcolor); devicecontext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); devicecontext->IASetInputLayout(inputlayout); devicecontext->IASetVertexBuffers(0, 1, &vertexbuffer, &stride, &offset); devicecontext->VSSetShader(vertexshader, nullptr, 0); devicecontext->VSSetConstantBuffers(0, 1, &constantbuffer); devicecontext->RSSetViewports(1, &viewport); devicecontext->RSSetState(rasterizerstate); devicecontext->PSSetShader(pixelshader, nullptr, 0); devicecontext->OMSetRenderTargets(1, &framebufferRTV, nullptr); /////////////////////////////////////////////////////////////////////////////////////////// devicecontext->Draw(3, 0); // draw 3 vertices /////////////////////////////////////////////////////////////////////////////////////////// swapchain->Present(1, 0); } }