#pragma comment(lib, "d3d11")
#pragma comment(lib, "d3dcompiler")
#include <d3d11.h>
#include <d3dcompiler.h>
#include <DirectXColors.h>
using namespace DirectX;
#include "shader_vs.h"
#include "shader_ps.h"
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#define WIDTH 640
#define HEIGHT 480
struct CustomVertex{
XMFLOAT2 Position;
XMFLOAT2 UV;
};
const TCHAR appname[] = L"DxTest4";
// 外部変数
ID3D11Device *pDevice;
ID3D11DeviceContext *pDeviceContext;
IDXGISwapChain *pSwapChain;
ID3D11RenderTargetView *pRenderTargetView;
ID3D11VertexShader *pVertexShader;
ID3D11InputLayout *pInputLayout;
ID3D11PixelShader *pPixelShader;
ID3D11Buffer *pVertexBuffer;
// 関数プロトタイプ宣言
HWND InitWnd(HINSTANCE hInstance);
HRESULT InitDevice(HWND hWnd);
void CleanupDevice();
void Render();
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//==============================================================================
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
HWND hWnd = InitWnd(hInstance);
if (hWnd == NULL) {
return 0;
}
if (FAILED(InitDevice(hWnd))) {
return 0;
}
ShowWindow(hWnd, nCmdShow);
MSG msg;
do {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
DispatchMessage(&msg);
}
else {
Render();
}
} while (msg.message != WM_QUIT);
CleanupDevice();
return msg.wParam;
}
HWND InitWnd(HINSTANCE hInstance)
{
WNDCLASSEX wc = { sizeof wc };
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = appname;
if (RegisterClassEx(&wc) == 0) {
return 0;
}
DWORD dwStyle = WS_OVERLAPPEDWINDOW ^ WS_MAXIMIZEBOX ^ WS_THICKFRAME;
RECT rc = { 0, 0, WIDTH, HEIGHT };
AdjustWindowRect(&rc, dwStyle, FALSE);
HWND hWnd = CreateWindow(appname, appname, dwStyle,
CW_USEDEFAULT, 0, rc.right - rc.left, rc.bottom - rc.top,
NULL, NULL, hInstance, NULL);
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 = { 0 };
sd.BufferCount = 1;
sd.BufferDesc.Width = WIDTH;
sd.BufferDesc.Height = 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)) {
MessageBox(NULL, L"D3D11CreateDeviceAndSwapChain", NULL, MB_OK);
return hr;
}
//----------------------------------------------------------------------
// レンダーターゲット
ID3D11Texture2D *pBackBuffer;
hr = pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
hr = pDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTargetView);
pBackBuffer->Release();
// output-merger
pDeviceContext->OMSetRenderTargets(1, &pRenderTargetView, NULL);
//----------------------------------------------------------------------
// ビューポート
D3D11_VIEWPORT vp = { 0 };
vp.Width = WIDTH;
vp.Height = HEIGHT;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
// rasterizer stage
pDeviceContext->RSSetViewports(1, &vp);
//----------------------------------------------------------------------
// 頂点シェーダ、入力レイアウト
hr = pDevice->CreateVertexShader(g_VS, ARRAYSIZE(g_VS), NULL, &pVertexShader);
if (FAILED(hr)) {
MessageBox(NULL, L"CreateVertexShader", NULL, MB_OK);
return hr;
}
D3D11_INPUT_ELEMENT_DESC ied[] = {
{ "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(ied, ARRAYSIZE(ied), g_VS, ARRAYSIZE(g_VS), &pInputLayout);
if (FAILED(hr)) {
MessageBox(NULL, L"CreateInputLayout", NULL, MB_OK);
return hr;
}
// input-assembler
pDeviceContext->IASetInputLayout(pInputLayout);
//----------------------------------------------------------------------
// ピクセルシェーダ
hr = pDevice->CreatePixelShader(g_PS, ARRAYSIZE(g_PS), NULL, &pPixelShader);
if (FAILED(hr)) {
MessageBox(NULL, L"CreatePixelShader", NULL, MB_OK);
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 = { sizeof vertices };
bd.Usage = D3D11_USAGE_DEFAULT;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
D3D11_SUBRESOURCE_DATA InitData = { 0 };
InitData.pSysMem = vertices;
hr = pDevice->CreateBuffer(&bd, &InitData, &pVertexBuffer);
if (FAILED(hr)) {
MessageBox(NULL, L"CreateBuffer", NULL, MB_OK);
return hr;
}
UINT stride = sizeof CustomVertex;
UINT offset = 0;
pDeviceContext->IASetVertexBuffers(0, 1, &pVertexBuffer, &stride, &offset);
//----------------------------------------------------------------------
pDeviceContext->VSSetShader(pVertexShader, NULL, 0);
pDeviceContext->PSSetShader(pPixelShader, NULL, 0);
pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
return hr;
}
void CleanupDevice()
{
if (pDeviceContext) {
pDeviceContext->ClearState();
pDeviceContext->Flush();
}
SAFE_RELEASE(pVertexBuffer);
SAFE_RELEASE(pPixelShader);
SAFE_RELEASE(pInputLayout);
SAFE_RELEASE(pVertexShader);
SAFE_RELEASE(pRenderTargetView);
SAFE_RELEASE(pSwapChain);
SAFE_RELEASE(pDeviceContext);
SAFE_RELEASE(pDevice);
}
void Render()
{
// pDeviceContext->ClearRenderTargetView(pRenderTargetView, Colors::CornflowerBlue);
pDeviceContext->Draw(4, 0);
pSwapChain->Present(0, 0);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_KEYDOWN:
switch (wParam) {
case VK_ESCAPE:
DestroyWindow(hWnd);
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}