Article by Ayman Alheraki on January 11 2026 10:35 AM
This example renders a gradient directly to the display using a compute shader embedded as a string in the C++ source.
x// Required for D3DCompile// Link the D3DCompiler library
using Microsoft::WRL::ComPtr;
// Function declarationsvoid InitializeD3D(ComPtr<ID3D11Device>& device, ComPtr<ID3D11DeviceContext>& context, ComPtr<IDXGISwapChain>& swapChain, HWND hwnd);void RenderGradient(ComPtr<ID3D11Device>& device, ComPtr<ID3D11DeviceContext>& context, ComPtr<IDXGISwapChain>& swapChain);
// Embedded compute shader as a stringconst char* GradientShaderCode = R"( RWTexture2D<float4> OutputTexture : register(u0);
[numthreads(16, 16, 1)] void CSMain(uint3 threadID : SV_DispatchThreadID) { uint width, height; OutputTexture.GetDimensions(width, height);
if (threadID.x >= width || threadID.y >= height) return;
// Generate a gradient based on screen position float u = float(threadID.x) / width; float v = float(threadID.y) / height; float4 color = float4(u, v, 0.5, 1.0); // RGB gradient with fixed alpha
OutputTexture[uint2(threadID.xy)] = color; })";
int main() { // Initialize a simple Win32 window WNDCLASS wc = {}; wc.lpfnWndProc = DefWindowProc; wc.hInstance = GetModuleHandle(nullptr); wc.lpszClassName = L"DirectComputeWindow"; RegisterClass(&wc);
HWND hwnd = CreateWindowEx(0, wc.lpszClassName, L"DirectCompute Gradient Example", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, nullptr, nullptr, wc.hInstance, nullptr);
ShowWindow(hwnd, SW_SHOW);
// Direct3D initialization ComPtr<ID3D11Device> device; ComPtr<ID3D11DeviceContext> context; ComPtr<IDXGISwapChain> swapChain;
InitializeD3D(device, context, swapChain, hwnd);
// Main render loop MSG msg = {}; while (msg.message != WM_QUIT) { if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { RenderGradient(device, context, swapChain); } }
return 0;}
void InitializeD3D(ComPtr<ID3D11Device>& device, ComPtr<ID3D11DeviceContext>& context, ComPtr<IDXGISwapChain>& swapChain, HWND hwnd) { DXGI_SWAP_CHAIN_DESC scDesc = {}; scDesc.BufferCount = 1; scDesc.BufferDesc.Width = 800; scDesc.BufferDesc.Height = 600; scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_UNORDERED_ACCESS; scDesc.OutputWindow = hwnd; scDesc.SampleDesc.Count = 1; scDesc.Windowed = TRUE;
HRESULT hr = D3D11CreateDeviceAndSwapChain( nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &scDesc, &swapChain, &device, nullptr, &context ); if (FAILED(hr)) { std::cerr << "Failed to initialize Direct3D 11." << std::endl; exit(-1); }}
void RenderGradient(ComPtr<ID3D11Device>& device, ComPtr<ID3D11DeviceContext>& context, ComPtr<IDXGISwapChain>& swapChain) { // Get back buffer ComPtr<ID3D11Texture2D> backBuffer; swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer));
// Create unordered access view ComPtr<ID3D11UnorderedAccessView> uav; device->CreateUnorderedAccessView(backBuffer.Get(), nullptr, &uav);
// Compile the embedded shader ComPtr<ID3DBlob> shaderBlob; ComPtr<ID3DBlob> errorBlob;
HRESULT hr = D3DCompile( GradientShaderCode, strlen(GradientShaderCode), nullptr, nullptr, nullptr, "CSMain", "cs_5_0", 0, 0, &shaderBlob, &errorBlob );
if (FAILED(hr)) { std::cerr << "Shader compilation failed: " << (errorBlob ? (char*)errorBlob->GetBufferPointer() : "Unknown error") << std::endl; exit(-1); }
// Create compute shader ComPtr<ID3D11ComputeShader> computeShader; device->CreateComputeShader(shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize(), nullptr, &computeShader);
// Set compute shader and UAV context->CSSetShader(computeShader.Get(), nullptr, 0); context->CSSetUnorderedAccessViews(0, 1, uav.GetAddressOf(), nullptr);
// Dispatch compute shader context->Dispatch(50, 38, 1); // Threads for 800x600 resolution
// Present to screen swapChain->Present(1, 0);}Embedded Shader Code:
The shader is included as a string in the C++ source, eliminating the need for external .hlsl files.
This ensures portability of the code as a single self-contained program.
Direct Compute Shader Compilation:
The shader is compiled at runtime using D3DCompile from the embedded string.
Efficient Pixel Manipulation:
Writes a smooth gradient directly to the display using the compute shader and Direct3D.
Add Required Libraries:
Link d3d11.lib and dxgi.lib for Direct3D functionality.
Link d3dcompiler.lib for shader compilation.
Compile and Run:
Use a compiler like MSVC to build the program.
Extend the gradient effect to include dynamic animation by introducing a time-based component.
Create complex visualizations, such as fractals or interactive patterns.
Handle user input to modify the rendering in real-time.
This example demonstrates a complete, portable C++ program that renders directly to the display using embedded GPU shader code.