開発環境 Microsoft Visual Studio Community 2019
実行環境 Microsoft Windows 10 Home (64bit)
プロジェクト テンプレート C++ 空のプロジェクト
プロジェクト名 dx11sample1


dx11sample1.cpp
#pragma comment(lib, "d3d11")
#pragma comment(lib, "d3dcompiler")
 
#include <Windows.h>
#include <wrl.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <DirectXMath.h>
 
using namespace Microsoft::WRL;
using namespace DirectX;
 
struct SimpleVertex {
	XMFLOAT3 Pos;
	XMFLOAT3 Color;
};
 
struct ConstantBuffer {
	XMMATRIX mWorld;
};
 
ComPtr<ID3D11Device> g_pDevice;
ComPtr<ID3D11DeviceContext> g_pContext;
ComPtr<IDXGISwapChain> g_pSwapChain;
ComPtr<ID3D11RenderTargetView> g_pRenderTargetView;
ComPtr<ID3D11VertexShader> g_pVertexShader;
ComPtr<ID3D11PixelShader> g_pPixelShader;
ComPtr<ID3D11InputLayout> g_pVertexLayout;
ComPtr<ID3D11Buffer> g_pVertexBuffer;
ComPtr<ID3D11Buffer> g_pConstantBuffer;
 
float g_theta = 0;
 
// 関数宣言
HWND InitWindow(HINSTANCE hInst);
HRESULT InitDevice(HWND hWnd);
void CleanupDevice();
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void Render();
 
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int nCmdShow)
{
	HWND hWnd = InitWindow(hInstance);
	if (!hWnd) return -1;
 
	if (FAILED(InitDevice(hWnd))) {
		CleanupDevice();
		return -1;
	}
 
	ShowWindow(hWnd, nCmdShow);
 
	MSG msg = { 0 };
	while (msg.message != WM_QUIT) {
		if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else {
			Render();
		}
	}
	CleanupDevice();
	return msg.wParam;
}
 
HWND InitWindow(HINSTANCE hInst)
{
	WNDCLASSEX wc = { sizeof WNDCLASSEX };
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WndProc;
	wc.hInstance = hInst;
	wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
	wc.hbrBackground = HBRUSH(COLOR_WINDOW + 1);
	wc.lpszClassName = L"dx11sample1";
	if (!RegisterClassEx(&wc)) return nullptr;
 
	DWORD dwStyle = WS_OVERLAPPEDWINDOW;
	RECT rc = { 0, 0, 400, 400 };
	AdjustWindowRect(&rc, dwStyle, FALSE);
 
	HWND hWnd = CreateWindow(
		wc.lpszClassName, L"dx11sample1", dwStyle,
		CW_USEDEFAULT, 0, rc.right - rc.left, rc.bottom - rc.top,
		nullptr, nullptr, hInst, nullptr);
	return hWnd;
}
 
HRESULT CompileShaderFromFile(
	LPCWSTR szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut)
{
	DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
 
	ComPtr<ID3DBlob> pErrorBlob;
	HRESULT hr = D3DCompileFromFile(szFileName, nullptr, nullptr, szEntryPoint, szShaderModel,
		dwShaderFlags, 0, ppBlobOut, &pErrorBlob);
	if (FAILED(hr)) {
		if (pErrorBlob) {
			OutputDebugStringA((LPCSTR)pErrorBlob->GetBufferPointer());
		}
		return hr;
	}
	return S_OK;
}
 
HRESULT InitDevice(HWND hWnd)
{
	HRESULT hr;
 
	UINT width = 400;
	UINT height = 400;
 
	DXGI_SWAP_CHAIN_DESC sd = { 0 };
	sd.BufferDesc.Width = width;
	sd.BufferDesc.Height = height;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;	// 符号なし正規化整数
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.BufferCount = 1;
	sd.OutputWindow = hWnd;
	sd.Windowed = TRUE;
	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
 
	D3D_FEATURE_LEVEL featureLevel;
 
	hr = D3D11CreateDeviceAndSwapChain(
		nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &sd,
		&g_pSwapChain, &g_pDevice, &featureLevel, &g_pContext);
 
	// レンダーターゲットビュー
	ComPtr<ID3D11Texture2D> pBackBuffer;
	hr = g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
	if (FAILED(hr)) return hr;
 
	hr = g_pDevice->CreateRenderTargetView(pBackBuffer.Get(), nullptr, &g_pRenderTargetView);
	if (FAILED(hr)) return hr;
 
	g_pContext->OMSetRenderTargets(1, g_pRenderTargetView.GetAddressOf(), nullptr);
 
	// ビューポート
	D3D11_VIEWPORT vp = { 0 };
	vp.Width = (FLOAT)width;
	vp.Height = (FLOAT)height;
	vp.MinDepth = 0;
	vp.MaxDepth = 1;
	g_pContext->RSSetViewports(1, &vp);
 
	// 頂点シェーダ
	ComPtr<ID3DBlob> pVSBlob;
	hr = CompileShaderFromFile(L"dx11sample1.fx", "VS", "vs_5_0", &pVSBlob);
	if (FAILED(hr)) {
		return hr;
	}
	hr = g_pDevice->CreateVertexShader(
		pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &g_pVertexShader);
	if (FAILED(hr)) return hr;
 
	// ピクセルシェーダ
	ComPtr<ID3DBlob> pPSBlob;
	hr = CompileShaderFromFile(L"dx11sample1.fx", "PS", "ps_5_0", &pPSBlob);
	if (FAILED(hr)) {
		return hr;
	}
	hr = g_pDevice->CreatePixelShader(
		pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &g_pPixelShader);
	if (FAILED(hr)) return hr;
 
	//
	g_pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
 
	// 入力レイアウト
	D3D11_INPUT_ELEMENT_DESC layout[] = {
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};
 
	hr = g_pDevice->CreateInputLayout(layout, ARRAYSIZE(layout),
		pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &g_pVertexLayout);
	if (FAILED(hr)) return hr;
 
	g_pContext->IASetInputLayout(g_pVertexLayout.Get());
 
	// 頂点バッファ
	SimpleVertex vertices[] = {
		{ XMFLOAT3(0, 0, 1), XMFLOAT3(0, 0, 1) },
		{ XMFLOAT3(0, 1, 0), XMFLOAT3(0, 1, 0) },
		{ XMFLOAT3(1, 0, 0), XMFLOAT3(1, 0, 0) },
	};
 
	D3D11_BUFFER_DESC vb = { 0 };
	vb.ByteWidth = sizeof vertices;
	vb.Usage = D3D11_USAGE_DEFAULT;
	vb.BindFlags = D3D11_BIND_VERTEX_BUFFER;
 
	D3D11_SUBRESOURCE_DATA InitData = { 0 };
	InitData.pSysMem = vertices;
 
	hr = g_pDevice->CreateBuffer(&vb, &InitData, &g_pVertexBuffer);
	if (FAILED(hr)) return hr;
 
	UINT stride = sizeof SimpleVertex;
	UINT offset = 0;
	g_pContext->IASetVertexBuffers(0, 1, g_pVertexBuffer.GetAddressOf(), &stride, &offset);
 
	// 定数バッファ
	D3D11_BUFFER_DESC cb = { 0 };
	cb.ByteWidth = sizeof ConstantBuffer;
	cb.Usage = D3D11_USAGE_DEFAULT;
	cb.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
 
	hr = g_pDevice->CreateBuffer(&cb, nullptr, &g_pConstantBuffer);
	if (FAILED(hr)) return hr;
 
	return S_OK;
}
 
void CleanupDevice()
{
	if (g_pContext) {
		g_pContext->ClearState();
	}
}
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
 
	switch (uMsg) {
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	return 0;
}
 
void Render()
{
	XMMATRIX world = XMMatrixRotationZ(g_theta);
 
	//
	float ClearColor[4] = { 0, 0, 0, 1 };
	g_pContext->ClearRenderTargetView(g_pRenderTargetView.Get(), ClearColor);
 
	ConstantBuffer cb;
	//cb.mWorld = XMMatrixTranspose(world);
	cb.mWorld = world;
	g_pContext->UpdateSubresource(g_pConstantBuffer.Get(), 0, nullptr, &cb, 0, 0);
 
	g_pContext->VSSetShader(g_pVertexShader.Get(), nullptr, 0);
	g_pContext->VSSetConstantBuffers(0, 1, g_pConstantBuffer.GetAddressOf());
	g_pContext->PSSetShader(g_pPixelShader.Get(), nullptr, 0);
	g_pContext->Draw(3, 0);
 
	g_pSwapChain->Present(1, 0);
 
	//
	g_theta += 0.01f;
}
 

dx11sample1.fx
cbuffer ConstantBuffer : register(b0)
{
    matrix World;
};
 
struct VS_INPUT
{
    float4 Pos : POSITION;
    float4 Color : COLOR;
};
 
struct PS_INPUT
{
    float4 Pos : SV_Position;
    float4 Color : COLOR;
};
 
// Vertex Shader
PS_INPUT VS(VS_INPUT input)
{
    PS_INPUT output = (PS_INPUT)0;
 
    output.Pos = mul(World, input.Pos);
    output.Color = input.Color;
    return output;
}
 
// Pixel Shader
float4 PS(PS_INPUT input) : SV_Target
{
    return input.Color;
}
 
最終更新:2020年07月08日 10:45
添付ファイル