PROWAREtech

articles » current » windows » application-programming-interface » basic-directx-11-example

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;
}

PROWAREtech

Hello there! How can I help you today?
Ask any question

PROWAREtech

This site uses cookies. Cookies are simple text files stored on the user's computer. They are used for adding features and security to this site. Read the privacy policy.
CLOSE