開発環境 Microsoft Visual Studio Express 2013 for Windows Desktop
実行環境 Microsoft Windows 8.1 (64bit)
プロジェクトの種類 Visual C++/Win32/Win32 プロジェクト
プロジェクト名 DxTest2
アプリケーションの種類 Windows アプリケーション
追加のオプション 空のプロジェクト、SDLチェック

参考

DxTest2.cpp
#pragma comment(lib, "d3d11")
#pragma comment(lib, "d3dcompiler")
 
#include <d3d11.h>
#include <d3dcompiler.h>
 
#include <DirectXColors.h>
using namespace DirectX;
 
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
 
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
 
struct CustomVertex {
	XMFLOAT2 Position;
	XMFLOAT2 UV;
};
 
// 外部変数
ID3D11Device *pDevice;
ID3D11DeviceContext *pDeviceContext;
IDXGISwapChain *pSwapChain;
ID3D11RenderTargetView *pRenderTargetView;
ID3D11InputLayout *pVertexLayout;
ID3D11Buffer *pVertexBuffer;
 
ID3D11VertexShader *pVertexShader;
ID3D11PixelShader *pPixelShader;
 
// 関数プロトタイプ宣言
HWND InitWnd(HINSTANCE hInstance, int nCmdShow);
HRESULT InitDevice(HWND hWnd);
HRESULT CompileShaderFromFile(LPCTSTR pFileName, LPCSTR pEntrypoint, LPCSTR pTarget, ID3DBlob **ppCode);
void Render();
void CleanupDevice();
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
//==============================================================================
 
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
	// ウィンドウ初期化
	HWND hWnd = InitWnd(hInstance, nCmdShow);
	if (hWnd == NULL) {
		return 0;
	}
 
	// デバイス初期化
	if (FAILED(InitDevice(hWnd))) {
		return 0;
	}
 
	// メインループ
	MSG msg = { 0 };
	while (msg.message != WM_QUIT) {
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else {
			// 描画
			Render();
		}
	}
 
	// デバイスのクリーンアップ
	CleanupDevice();
 
	return msg.wParam;
}
 
HWND InitWnd(HINSTANCE hInstance, int nCmdShow)
{
	WNDCLASSEX wc;
	ZeroMemory(&wc, sizeof wc);
	wc.cbSize = sizeof wc;
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WndProc;
	wc.hInstance = hInstance;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.lpszClassName = L"DxTest2";
	RegisterClassEx(&wc);
 
	DWORD dwStyle = WS_OVERLAPPEDWINDOW ^ WS_MAXIMIZEBOX ^ WS_THICKFRAME;
	RECT rc = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
	AdjustWindowRect(&rc, dwStyle, FALSE);
 
	HWND hWnd = CreateWindow(
		wc.lpszClassName, L"DxTest2", dwStyle,
		CW_USEDEFAULT, 0, rc.right - rc.left, rc.bottom - rc.top,
		NULL, NULL, hInstance, NULL);
 
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
 
	return hWnd;
}
 
HRESULT InitDevice(HWND hWnd)
{
	// ドライバータイプ
	D3D_DRIVER_TYPE DriverType[] = {
		D3D_DRIVER_TYPE_HARDWARE,
//		D3D_DRIVER_TYPE_WARP,
		D3D_DRIVER_TYPE_REFERENCE,
	};
 
	// 機能レベル
	D3D_FEATURE_LEVEL FeatureLevels[] = {
		D3D_FEATURE_LEVEL_11_1,
		D3D_FEATURE_LEVEL_11_0,
//		D3D_FEATURE_LEVEL_10_1,
//		D3D_FEATURE_LEVEL_10_0,
	};
 
	// スワップチェインの設定
	DXGI_SWAP_CHAIN_DESC sd;
	ZeroMemory(&sd, sizeof sd);
	sd.BufferCount = 1;
	sd.BufferDesc.Width = WINDOW_WIDTH;
	sd.BufferDesc.Height = WINDOW_HEIGHT;
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow = hWnd;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.Windowed = TRUE;
 
	// デバイスとスワップチェインを作成
	HRESULT hr;
	for (int i = 0; i < ARRAYSIZE(DriverType); i++) {
		D3D_FEATURE_LEVEL FeatureLevel;
		hr = D3D11CreateDeviceAndSwapChain(NULL, DriverType[i], NULL, 0,
			FeatureLevels, ARRAYSIZE(FeatureLevels), D3D11_SDK_VERSION, &sd,
			&pSwapChain, &pDevice, &FeatureLevel, &pDeviceContext);
		if (SUCCEEDED(hr)) break;
	}
	if (FAILED(hr)) {
		return hr;
	}
 
	// バックバッファを取得
	ID3D11Texture2D *pBackBuffer;
	hr = pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
 
	// レンダーターゲットを生成
	hr = pDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTargetView);
	pBackBuffer->Release();
 
	// 出力マネージャにレンダーターゲットを設定
	pDeviceContext->OMSetRenderTargets(1, &pRenderTargetView, NULL);
 
	// ビューポートの設定
	D3D11_VIEWPORT vp;
	vp.Width = WINDOW_WIDTH;
	vp.Height = WINDOW_HEIGHT;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
 
	// デバイスコンテキストにビューポートを設定
	pDeviceContext->RSSetViewports(1, &vp);
 
	// 頂点シェーダをコンパイル
	ID3DBlob *pCode;
	if (FAILED(CompileShaderFromFile(L"shader.fx", "VS", "vs_5_0", &pCode))) {
		return E_FAIL;
	}
 
	// 頂点シェーダ生成
	hr = pDevice->CreateVertexShader(
		pCode->GetBufferPointer(), pCode->GetBufferSize(), NULL, &pVertexShader);
	if (FAILED(hr)) {
		return hr;
	}
 
	// 入力レイアウトの定義
	D3D11_INPUT_ELEMENT_DESC layout[] = {
		{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};
 
	// 入力レイアウトを生成
	hr = pDevice->CreateInputLayout(layout, ARRAYSIZE(layout),
		pCode->GetBufferPointer(), pCode->GetBufferSize(), &pVertexLayout);
	SAFE_RELEASE(pCode);
	if (FAILED(hr)) {
		return hr;
	}
 
	// 入力アセンブラ(input-assembler)に入力レイアウトを設定
	pDeviceContext->IASetInputLayout(pVertexLayout);
 
	// ピクセルシェーダをコンパイル
	hr = CompileShaderFromFile(L"shader.fx", "PS", "ps_5_0", &pCode);
	if (FAILED(hr)) {
		return hr;
	}
 
	// ピクセルシェーダ生成
	hr = pDevice->CreatePixelShader(
		pCode->GetBufferPointer(), pCode->GetBufferSize(), NULL, &pPixelShader);
	SAFE_RELEASE(pCode);
	if (FAILED(hr)) {
		return hr;
	}
 
	// 頂点の定義
	CustomVertex vertices[] = {
		{ XMFLOAT2(-1, 1), XMFLOAT2(0, 1) },// LU
		{ XMFLOAT2(1, 1), XMFLOAT2(1, 1) }, // RU
		{ XMFLOAT2(-1, -1), XMFLOAT2(0, 0) }, // LD
		{ XMFLOAT2(1, -1), XMFLOAT2(1, 0) }, // RD
	};
 
	// 頂点バッファの設定
	D3D11_BUFFER_DESC bd;
	ZeroMemory(&bd, sizeof bd);
	bd.ByteWidth = sizeof vertices;
	bd.Usage = D3D11_USAGE_DEFAULT;
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
 
	// サブリソースの設定
	D3D11_SUBRESOURCE_DATA InitData;
	ZeroMemory(&InitData, sizeof InitData);
	InitData.pSysMem = vertices;
 
	// 頂点バッファの生成
	hr = pDevice->CreateBuffer(&bd, &InitData, &pVertexBuffer);
	if (FAILED(hr)) {
		return hr;
	}
 
	// 入力アセンブラに頂点バッファを設定
	UINT stride = sizeof CustomVertex;
	UINT offset = 0;
	pDeviceContext->IASetVertexBuffers(0, 1, &pVertexBuffer, &stride, &offset);
 
	// プリミティブの種類を設定
	pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
 
	return S_OK;
}
 
HRESULT CompileShaderFromFile(LPCTSTR pFileName, LPCSTR pEntrypoint, LPCSTR pTarget, ID3DBlob **ppCode)
{
	ID3DBlob *pErrorMsgs;
	HRESULT hr = D3DCompileFromFile(
		pFileName, NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, pEntrypoint, pTarget,
		0, 0, ppCode, &pErrorMsgs);
	return hr;
}
 
void Render()
{
	// ビューをクリアする
	pDeviceContext->ClearRenderTargetView(pRenderTargetView, Colors::CornflowerBlue);
 
	// シェーダを設定して描画
	pDeviceContext->VSSetShader(pVertexShader, NULL, 0);
	pDeviceContext->PSSetShader(pPixelShader, NULL, 0);
 
	// 描画
	pDeviceContext->Draw(4, 0);
 
	// 描画結果を表示
	pSwapChain->Present(0, 0);
}
 
void CleanupDevice()
{
	// ステートをクリアし、デフォルト状態にする
	if (pDeviceContext) {
		pDeviceContext->ClearState();
		pDeviceContext->Flush();
	}
 
	SAFE_RELEASE(pVertexShader);
	SAFE_RELEASE(pPixelShader);
	SAFE_RELEASE(pVertexBuffer);
	SAFE_RELEASE(pVertexLayout);
 
	SAFE_RELEASE(pRenderTargetView);
	SAFE_RELEASE(pSwapChain);
	SAFE_RELEASE(pDeviceContext);
	SAFE_RELEASE(pDevice);
}
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_CHAR:
		switch (wParam)
		{
		case VK_ESCAPE:
			DestroyWindow(hWnd);
			break;
		}
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 

プロジェクトには追加しない。
カレントディレクトリに置く。
shader.fx
struct VertexIn
{
	float2 Pos : POSITION;
	float2 UV : TEXCOORD;
};
 
struct VertexOut
{
	float4 ScreenPos : SV_Position;
	float2 UV : TEXCOORD;
};
 
VertexOut VS(VertexIn input)
{
	VertexOut output;
	output.ScreenPos = float4(input.Pos, 0, 1);
	output.UV = input.UV;
	return output;
}
 
float4 PS(VertexOut input) : SV_Target
{
	float4 color;
	color = float4(input.UV, 0, 1);
	return color;
}
 
最終更新:2014年06月05日 11:58