PROWAREtech
Windows API: Basic DirectX 11 Example
A very basic DirectX 11 (Direct3D) example; written in C++.
Here is a basic example of using DirectX 11 to fill the client window with a random solid color when a timer event fires. See the DirectX screen saver for another DirectX 11 demo. This example does not really dig into the three dimensional.
// *********************************************************************
// * *
// * EXAMPLE DIRECTX 11 *
// * *
// * FILL CLIENT WINDOW WITH A RANDOM SOLID COLOR EVERY HALF SECOND. *
// * *
// *********************************************************************
#ifndef UNICODE
#define UNICODE
#endif
// DirectX 11 library (this line of code works with Visual Studio; for other compilers add the d3d11 library to the linker)
#pragma comment(lib, "d3d11")
#include <windows.h>
#include <d3d11.h>
// variables for DirectX
ID3D11Device* device = NULL;
ID3D11DeviceContext* deviceContext = NULL;
IDXGISwapChain* swapChain = NULL;
ID3D11RenderTargetView* renderTargetView = NULL;
FLOAT color[] = { 0.25, 0.25, 0.25, 0.0 };
// handle window messages
LRESULT WINAPI wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_TIMER:
if (deviceContext & swapChain)
{
// fill with random color every time the timer fires
color[0] = (rand() % 100) / 100.0;
color[1] = (rand() % 100) / 100.0;
color[2] = (rand() % 100) / 100.0;
color[3] = 0.0;
deviceContext->ClearRenderTargetView(renderTargetView, color);
swapChain->Present(1, 0);
}
break;
case WM_CLOSE:
if (MessageBox(hwnd, L"Are you sure you want to close?", L"Confirm Close", MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) == IDYES)
DestroyWindow(hwnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_SIZE: // fires when window changes its size
if(deviceContext & swapChain)
{
RECT rc;
GetWindowRect(hwnd, &rc);
D3D11_VIEWPORT viewport;
viewport.MinDepth = 0;
viewport.MaxDepth = 1;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = rc.right - rc.left;
viewport.Height = rc.bottom - rc.top;
deviceContext->RSSetViewports(1u, &viewport);
// fill with the random color when user resizes window so there is no voided areas
deviceContext->ClearRenderTargetView(renderTargetView, color);
swapChain->Present(1, 0);
}
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
// start point
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HWND hwnd;
const wchar_t* windowClass = L"directX11_example";
MSG msg = {};
WNDCLASSEX wc;
wc = { sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW, wndProc, 0, 0, hInstance, (HICON)NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, windowClass, NULL };
RegisterClassEx(&wc);
hwnd = CreateWindow(wc.lpszClassName, L"DirectX 11 Example", WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_MAXIMIZE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, wc.hInstance, NULL);
// initialize DirectX
{
DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
swapChainDesc.Windowed = TRUE;
swapChainDesc.OutputWindow = hwnd;
swapChainDesc.BufferCount = 2;
swapChainDesc.BufferDesc.Width = 0;
swapChainDesc.BufferDesc.Height = 0;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
D3D_FEATURE_LEVEL featureLevel;
const D3D_FEATURE_LEVEL featureLevelArray[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_1, };
D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, featureLevelArray, 3, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, &featureLevel, &deviceContext);
ID3D11Texture2D* pBackBuffer;
swapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
device->CreateRenderTargetView(pBackBuffer, NULL, &renderTargetView);
pBackBuffer->Release();
RECT rc;
GetWindowRect(hwnd, &rc);
D3D11_VIEWPORT viewport;
viewport.MinDepth = 0;
viewport.MaxDepth = 1;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = rc.right - rc.left;
viewport.Height = rc.bottom - rc.top;
deviceContext->RSSetViewports(1u, &viewport);
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// draw the initial gray window
deviceContext->ClearRenderTargetView(renderTargetView, color);
swapChain->Present(1, 0);
SetTimer(hwnd, 0, 500, NULL); // 500ms
srand(GetTickCount());
// message loop
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
KillTimer(hwnd, 0);
// release resources
renderTargetView->Release();
renderTargetView = nullptr;
swapChain->Release();
swapChain = nullptr;
deviceContext->Release();
deviceContext = nullptr;
device->Release();
device = nullptr;
DestroyWindow(hwnd);
UnregisterClass(windowClass, hInstance);
return msg.wParam;
}
Comment