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