Created
August 1, 2014 13:14
-
-
Save hirosof/812f692d7a82d588c71b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*---------------------------------------------------------------------------- | |
プログラム名:D3DDraw | |
プログラム概要:Direct3D 11の描画プログラムです | |
-------------------------------------------------------------------------------- | |
*/ | |
//インクルード | |
#include <windows.h> | |
#include <stdio.h> | |
#include <locale.h> | |
#include <vector> | |
#include <tchar.h> | |
#include <d3d11.h> | |
#include <d3dcompiler.h> | |
#include <DirectXMath.h> | |
using namespace DirectX; | |
#pragma comment(lib,"D3D11.lib") | |
#pragma comment(lib,"D3DCompiler.lib") | |
#pragma comment(lib,"winmm.lib") | |
//マニフェスト登録 | |
#pragma comment(linker,"\"/manifestdependency:type='win32' " \ | |
"name='Microsoft.Windows.Common-Controls' " \ | |
"version='6.0.0.0' " \ | |
"processorArchitecture='*' " \ | |
"publicKeyToken='6595b64144ccf1df' " \ | |
"language='*'\"") | |
//マクロ部 | |
#define PRONAME "D3DIntroduction - Draw" //プログラム名 | |
#define PROVER "1.0.1.0" //プログラムバージョン | |
#define PRONAME_TXT TEXT(PRONAME) //プログラム名(テキスト) | |
#define PROVER_TXT TEXT(PROVER) //プログラムバージョン(テキスト) | |
//プロトタイプ(基本) | |
ATOM RegistWindowClass(HINSTANCE); /* ウィンドウクラスの登録 */ | |
BOOL CreateMainWindow(HINSTANCE, int); /* ウィンドウの作成 */ | |
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); /* ウィンドウプロシージャー */ | |
BOOL OnIdle(void); | |
void OnRender(void); | |
void OnPaint(void); | |
//Direct3D関連プロトタイプ宣言 | |
BOOL InitDirect3D(void); | |
void UninitDirect3D(void); | |
BOOL CreateD3DDeviceWithSwapChain(D3D_FEATURE_LEVEL *pD3DFeatureLevels, int NumberOfFeatureLevels, DXGI_SWAP_CHAIN_DESC *psd); | |
BOOL D3DBackBuffarSetup(void); | |
BOOL D3DDepthAndStencilBufferSetup(void); | |
BOOL CheckDevice(void); | |
BOOL CompileShaderFile(void); | |
BOOL CreateShaderObjectWithConstBuffer(void); | |
BOOL InitInputAssembler(void); | |
BOOL InitRasterizer(void); | |
BOOL InitOutputManager(void); | |
BOOL UpdateConstBuffer(void); | |
//構造体宣言部 | |
struct MyD3D_VertexPositonData { | |
XMFLOAT3 Position; | |
}; | |
struct MyD3D_VertexColorData { | |
XMFLOAT3 Color; | |
}; | |
struct MyD3D_VertexBufferInterFace { | |
ID3D11Buffer *pPosition; | |
ID3D11Buffer *pColor; | |
}; | |
BOOL InitD3DVertexAndIndexBuffer(ID3D11Device *pDevice, MyD3D_VertexBufferInterFace *pvbif, ID3D11Buffer **ppIndexBuffer); | |
struct cbNeverChanges { | |
XMFLOAT4X4 Projection; | |
}; | |
struct cbChangesEveryFrame { | |
XMFLOAT4X4 View; | |
XMFLOAT3 Light; | |
FLOAT dummy; | |
}; | |
struct cbChangesEveryObject { | |
XMFLOAT4X4 World; | |
}; | |
//Direct3Dデータ構造体 | |
struct MyD3D_Data { | |
ID3D11Device *pDevice; | |
ID3D11DeviceContext *pDeviceContext; | |
IDXGISwapChain *pSwapChain; | |
ID3D11RenderTargetView *pRenderTargetView; | |
ID3D11Texture2D *pDepthStencil; | |
ID3D11DepthStencilView *pDepthStencilView; | |
D3D11_VIEWPORT ViewPort; | |
struct { | |
D3D_FEATURE_LEVEL RunningFeatureLevel; | |
}Info; | |
}; | |
struct MyD3D_DrawData { | |
MyD3D_VertexBufferInterFace Vertex; | |
ID3D11Buffer *pIndex; | |
ID3D11InputLayout *pInputLayout; | |
ID3D11RasterizerState *pRasterizerState; | |
struct { | |
ID3DBlob *pBlobVS; | |
ID3DBlob *pBlobGS; | |
ID3DBlob *pBlobPS; | |
ID3D11VertexShader *pVS; | |
ID3D11GeometryShader *pGS; | |
ID3D11PixelShader *pPS; | |
ID3D11Buffer *pVSBuffer; | |
ID3D11Buffer *pGSBuffer; | |
ID3D11Buffer *pPSBuffer; | |
}Shader; | |
struct { | |
cbNeverChanges m_NeverChanges; | |
cbChangesEveryFrame m_ChangesEveryFrame; | |
cbChangesEveryObject m_ChangesEveryObject; | |
ID3D11Buffer *pConstBuffer[3]; | |
}Index; | |
struct { | |
ID3D11BlendState *pBlendState; | |
ID3D11DepthStencilState *pDepthStencilState; | |
}OutputManager; | |
}; | |
#ifdef _DEBUG | |
//通常 | |
#define SET_CONSOLETEXTCOLOR_NORMAL SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \ | |
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY ) | |
//エラー | |
#define SET_CONSOLETEXTCOLOR_FOR_ERROR SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \ | |
FOREGROUND_RED |FOREGROUND_INTENSITY ) | |
//情報 | |
#define SET_CONSOLETEXTCOLOR_FOR_INFORMATION SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), \ | |
FOREGROUND_BLUE | FOREGROUND_GREEN|FOREGROUND_INTENSITY ) | |
#endif | |
//定数部 | |
const SIZE WindowClientSize = {640,480}; | |
const bool WindowSizeChangeByUserFlag = false; | |
//グローバル変数部 | |
TCHAR szClassName[] = PRONAME_TXT; //ウィンドウクラス名 | |
HWND hWindow = NULL; | |
HINSTANCE hInstance = NULL; | |
//Direct3Dデータ | |
MyD3D_Data D3DData = { NULL }; | |
MyD3D_DrawData D3DDrawData = { NULL }; | |
bool bInitializedD3D = false; | |
//メイン関数 | |
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { | |
MSG msg = { 0 }; | |
//インスタンスハンドルをグローバル変数にコピー | |
hInstance = hCurInst; | |
#ifdef _DEBUG | |
//デバッグモードの場合コンソールを初期化する | |
FILE *fpConsoleWriter; | |
//コンソールを割り当てる | |
AllocConsole(); | |
//コンソールのタイトルを変更する | |
SetConsoleTitle(TEXT("Direct3DApp - Debug Console")); | |
//ロケールを設定 | |
_tsetlocale(LC_ALL, TEXT("Japanese")); | |
//標準出力系関数を使用できるようにする | |
freopen_s(&fpConsoleWriter, "CONOUT$", "w", stdout); | |
//コンソールウィンドウのタイトルバーのシステムメニューを消す | |
HWND hConsole = GetConsoleWindow(); | |
int Style = GetWindowLong(hConsole, GWL_STYLE); | |
SetWindowLong(hConsole, GWL_STYLE, Style & ~WS_SYSMENU); | |
_tprintf(TEXT("%s デバッグコンソール\n\n"), PRONAME_TXT); | |
#endif | |
//ウィンドウクラスの登録 | |
if (!RegistWindowClass(hCurInst)) return FALSE; | |
//ウィンドウ作成 | |
if (!CreateMainWindow(hCurInst, nCmdShow)) return FALSE; | |
//Direct3D初期化 | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_NORMAL; | |
_tprintf(TEXT("Direct3D の初期化を行います。\n")); | |
#endif | |
if (InitDirect3D()) { | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_FOR_INFORMATION; | |
_tprintf(TEXT("Direct3D の初期化に成功しました。\n")); | |
#endif | |
bInitializedD3D = true; | |
//メッセージループ(PeekMessage版) | |
do { | |
if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) { | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
}else { | |
if (!OnIdle()) { | |
DestroyWindow(hWindow); | |
} | |
} | |
} while (msg.message != WM_QUIT); | |
}else { | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_FOR_ERROR; | |
_tprintf(TEXT("Direct3D の初期化に失敗しました。\n")); | |
MessageBox(hConsole, TEXT("Direct3Dの初期化に失敗しました。"), PRONAME_TXT, MB_ICONERROR); | |
#else | |
MessageBox(hWindow, TEXT("Direct3Dの初期化に失敗しました。"), PRONAME_TXT, MB_ICONERROR); | |
#endif | |
} | |
//Direct3D終了処理 | |
UninitDirect3D(); | |
#ifdef _DEBUG | |
FreeConsole(); | |
#endif | |
return (int)msg.wParam; | |
} | |
//ウィンドウクラス登録関数 | |
ATOM RegistWindowClass(HINSTANCE hInst) { | |
WNDCLASSEX wc; //WNDCLASSEX構造体 | |
wc.cbSize = sizeof(WNDCLASSEX); | |
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; | |
wc.lpfnWndProc = WndProc; //プロシージャ名 | |
wc.cbClsExtra = 0; | |
wc.cbWndExtra = 0; | |
wc.hInstance = hInst; //インスタンス | |
wc.hIcon = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); | |
wc.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); | |
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); | |
wc.lpszMenuName = NULL; //メニュー名 | |
wc.lpszClassName = szClassName; | |
wc.hIconSm = (HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); | |
return RegisterClassEx(&wc); | |
} | |
//メインウィンドウを作る関数 | |
BOOL CreateMainWindow(HINSTANCE hInst, int nCmdShow) { | |
HWND hwnd; | |
int WindowStyle; | |
//ウィンドウスタイル | |
WindowStyle = WS_OVERLAPPEDWINDOW; | |
//ウィンドウサイズ固定ならばオーバーラップウィンドウから | |
//サイズ変更境界と最大化ボタンを無効化にする | |
if (WindowSizeChangeByUserFlag == 0) | |
WindowStyle &= ~WS_THICKFRAME & ~WS_MAXIMIZEBOX; | |
//ウィンドウサイズを計算 | |
RECT windowRect = { 0 }; | |
windowRect.right = WindowClientSize.cx; | |
windowRect.bottom = WindowClientSize.cy; | |
if (AdjustWindowRectEx(&windowRect, WindowStyle, FALSE, NULL) == FALSE)return FALSE; | |
windowRect.right += abs(windowRect.left); | |
windowRect.bottom += abs(windowRect.top); | |
//ウィンドウ作成 | |
hwnd = | |
CreateWindowEx(NULL, | |
szClassName, | |
//タイトルバーにこの文字列が表示されます | |
PRONAME_TXT, | |
WindowStyle,//ウィンドウの種類 | |
CW_USEDEFAULT, //x座標 | |
CW_USEDEFAULT,//y座標 | |
windowRect.right, //幅 | |
windowRect.bottom,//高さ | |
NULL,//親ウィンドウのハンドル、親を作るときはNULL | |
NULL,//メニューハンドル、クラスメニューを使うときはNULL | |
hInst,//インスタンスハンドル | |
NULL); | |
if (!hwnd)return FALSE; | |
//ウィンドウ表示 | |
ShowWindow(hwnd, nCmdShow); | |
//ウィンドウ更新 | |
UpdateWindow(hwnd); | |
return TRUE; | |
} | |
//ウィンドウプロシージャ | |
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { | |
//メッセージごとの処理 | |
switch (msg) { | |
case WM_CREATE: | |
hWindow = hwnd; | |
break; | |
case WM_DESTROY: | |
PostQuitMessage(0); | |
break; | |
default: | |
return DefWindowProc(hwnd, msg, wp, lp); | |
} | |
return 0; | |
} | |
BOOL InitD3DVertexAndIndexBuffer(ID3D11Device *pDevice, MyD3D_VertexBufferInterFace *pvbif, ID3D11Buffer **ppIndexBuffer) { | |
if (!pDevice || !pvbif || !ppIndexBuffer)return FALSE; | |
//頂点バッファ | |
D3D11_BUFFER_DESC vPosBufDesc = { 0 }; | |
vPosBufDesc.Usage = D3D11_USAGE_DEFAULT; | |
vPosBufDesc.ByteWidth = sizeof(MyD3D_VertexPositonData) * 8; | |
vPosBufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; | |
MyD3D_VertexPositonData vpd[] = { | |
XMFLOAT3(-1, 1, -1), XMFLOAT3(1, 1, -1), | |
XMFLOAT3(1, -1, -1), XMFLOAT3(-1, -1, -1), | |
XMFLOAT3(-1, 1, 1), XMFLOAT3(1, 1, 1), | |
XMFLOAT3(1, -1, 1), XMFLOAT3(-1, -1, 1) | |
}; | |
D3D11_SUBRESOURCE_DATA vPosSubData = { 0 }; | |
vPosSubData.pSysMem = vpd; | |
HRESULT hr; | |
hr = pDevice->CreateBuffer(&vPosBufDesc, &vPosSubData, &pvbif->pPosition); | |
if (FAILED(hr))return FALSE; | |
//頂点色バッファ | |
D3D11_BUFFER_DESC vColorBufDesc = { 0 }; | |
vColorBufDesc.Usage = D3D11_USAGE_DEFAULT; | |
vColorBufDesc.ByteWidth = sizeof(MyD3D_VertexColorData) * 8; | |
vColorBufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; | |
MyD3D_VertexColorData vcd[] = { | |
XMFLOAT3(0, 0, 0), XMFLOAT3(0, 0, 1), | |
XMFLOAT3(0, 1, 0), XMFLOAT3(1, 0, 1), | |
XMFLOAT3(1, 0, 0), XMFLOAT3(1, 0, 1), | |
XMFLOAT3(1, 1, 0), XMFLOAT3(1, 1, 1) | |
}; | |
D3D11_SUBRESOURCE_DATA vColorSubData = { 0 }; | |
vColorSubData.pSysMem = vcd; | |
hr = pDevice->CreateBuffer(&vColorBufDesc, &vColorSubData, &pvbif->pColor); | |
if (FAILED(hr))return FALSE; | |
//インデックスバッファの作成 | |
D3D11_BUFFER_DESC vIndexBufferDesc = { 0 }; | |
vIndexBufferDesc.Usage = D3D11_USAGE_DEFAULT; | |
vIndexBufferDesc.ByteWidth = sizeof(UINT32) * 36; | |
vIndexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; | |
UINT32 IndexVertexData[] = { | |
0, 1, 3, | |
1, 2, 3, | |
1, 5, 2, | |
5, 2, 2, | |
5, 4, 6, | |
4, 7, 6, | |
4, 5, 0, | |
5, 1, 0, | |
4, 0, 7, | |
0, 3, 7, | |
3, 2, 7, | |
2, 6, 7 | |
}; | |
D3D11_SUBRESOURCE_DATA vIndexSubData = { 0 }; | |
vIndexSubData.pSysMem = IndexVertexData; | |
hr = pDevice->CreateBuffer(&vIndexBufferDesc, &vIndexSubData, ppIndexBuffer); | |
if (FAILED(hr))return FALSE; | |
return TRUE; | |
} | |
//Direct3D初期化関数 | |
BOOL InitDirect3D(void) { | |
//Direct3D 11 機能レベル(候補) | |
D3D_FEATURE_LEVEL D3DFeatureLevels[] = { D3D_FEATURE_LEVEL_11_0, | |
D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 }; | |
//Direct3D 11 機能レベル(候補)の数 | |
UINT NumberOfFeatureLevels = sizeof(D3DFeatureLevels) / sizeof(D3D_FEATURE_LEVEL); | |
//スワップチェインの初期化設定 | |
DXGI_SWAP_CHAIN_DESC sd = { 0 }; | |
sd.BufferCount = 1; | |
sd.BufferDesc.Width = WindowClientSize.cx; | |
sd.BufferDesc.Height = WindowClientSize.cy; | |
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; | |
sd.BufferDesc.RefreshRate.Numerator = 60; | |
sd.BufferDesc.RefreshRate.Denominator = 1; | |
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; | |
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; | |
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; | |
sd.SampleDesc.Count = 1; | |
sd.SampleDesc.Quality = 0; | |
sd.OutputWindow = hWindow; | |
sd.Windowed = TRUE; | |
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; | |
//Direct3D デバイスとスワップチェインの作成 | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_NORMAL; | |
_tprintf(TEXT("Direct3D デバイスの作成をします。\n")); | |
#endif | |
if (!CreateD3DDeviceWithSwapChain(D3DFeatureLevels, NumberOfFeatureLevels, &sd)) { | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_FOR_ERROR; | |
_tprintf(TEXT("Direct3D デバイスの作成に失敗しました。\n")); | |
#endif | |
return FALSE; | |
} | |
//深度・ステンシル・バッファ設定 | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_NORMAL; | |
_tprintf(TEXT("深度・ステンシル・バッファの設定をします。\n")); | |
#endif | |
if (!D3DDepthAndStencilBufferSetup()) { | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_FOR_ERROR; | |
_tprintf(TEXT("深度・ステンシル・バッファの設定に失敗しました。\n")); | |
#endif | |
return FALSE; | |
} | |
//頂点バッファとインデックスバッファの設定 | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_NORMAL; | |
_tprintf(TEXT("頂点バッファとインデックスバッファの設定をします。\n")); | |
#endif | |
if (!InitD3DVertexAndIndexBuffer(D3DData.pDevice, &D3DDrawData.Vertex, &D3DDrawData.pIndex)) { | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_FOR_ERROR; | |
_tprintf(TEXT("頂点バッファとインデックスバッファの設定に失敗しました。\n")); | |
#endif | |
return FALSE; | |
} | |
//シェーダーのコンパイル | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_NORMAL; | |
_tprintf(TEXT("シェーダーのコンパイルをします。\n")); | |
#endif | |
if (!CompileShaderFile()) { | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_FOR_ERROR; | |
_tprintf(TEXT("シェーダーのコンパイルに失敗しました。\n")); | |
#endif | |
return FALSE; | |
} | |
//シェーダーのオブジェクトを作成 | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_NORMAL; | |
_tprintf(TEXT("シェーダーオブジェクトの作成をします。\n")); | |
#endif | |
if (!CreateShaderObjectWithConstBuffer()) { | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_FOR_ERROR; | |
_tprintf(TEXT("シェーダーオブジェクトの作成に失敗しました。\n")); | |
#endif | |
return FALSE; | |
} | |
//バックバッファの設定 | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_NORMAL; | |
_tprintf(TEXT("バックバッファの設定をします。\n")); | |
#endif | |
if (!D3DBackBuffarSetup()) { | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_FOR_ERROR; | |
_tprintf(TEXT("バックバッファの設定に失敗しました。\n")); | |
#endif | |
return FALSE; | |
} | |
//入力アセンブラの設定 | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_NORMAL; | |
_tprintf(TEXT("入力アセンブラの設定をします。\n")); | |
#endif | |
if (!InitInputAssembler()) { | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_FOR_ERROR; | |
_tprintf(TEXT("入力バッファの設定に失敗しました。\n")); | |
#endif | |
return FALSE; | |
} | |
//ラスタライザの設定 | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_NORMAL; | |
_tprintf(TEXT("ラスタライザの設定をします。\n")); | |
#endif | |
if (!InitRasterizer()) { | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_FOR_ERROR; | |
_tprintf(TEXT("ラスタライザの設定に失敗しました。\n")); | |
#endif | |
return FALSE; | |
} | |
//出力マネージャの設定 | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_NORMAL; | |
_tprintf(TEXT("出力マネージャの設定をします。\n")); | |
#endif | |
if (!InitOutputManager()) { | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_FOR_ERROR; | |
_tprintf(TEXT("出力マネージャの設定に失敗しました。\n")); | |
#endif | |
return FALSE; | |
} | |
return TRUE; | |
} | |
//デバイスとスワップチェインを作成 | |
BOOL CreateD3DDeviceWithSwapChain(D3D_FEATURE_LEVEL *pD3DFeatureLevels, int NumberOfFeatureLevels, DXGI_SWAP_CHAIN_DESC *psd) { | |
//ドライバタイプ | |
D3D_DRIVER_TYPE DriverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE }; | |
HRESULT hr = E_FAIL; | |
for (int i = 0; i < (sizeof(DriverTypes) / sizeof(D3D_DRIVER_TYPE)); i++) { | |
hr = D3D11CreateDeviceAndSwapChain(NULL, | |
DriverTypes[i], | |
NULL, | |
NULL, | |
pD3DFeatureLevels, | |
NumberOfFeatureLevels, | |
D3D11_SDK_VERSION, | |
psd, | |
&D3DData.pSwapChain, | |
&D3DData.pDevice, | |
&D3DData.Info.RunningFeatureLevel, | |
&D3DData.pDeviceContext); | |
if (SUCCEEDED(hr)) break; | |
} | |
if (FAILED(hr)) return FALSE; | |
return TRUE; | |
} | |
//バックバッファの設定 | |
BOOL D3DBackBuffarSetup(void) { | |
HRESULT hr; | |
ID3D11Texture2D *pTexture; | |
hr = D3DData.pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pTexture)); | |
if (FAILED(hr)) { | |
return FALSE; | |
} | |
hr = D3DData.pDevice->CreateRenderTargetView(pTexture, NULL, &D3DData.pRenderTargetView); | |
pTexture->Release(); | |
if (FAILED(hr)) { | |
return FALSE; | |
} | |
//ビューポートの設定 | |
D3D11_VIEWPORT vp = { 0 }; | |
vp.TopLeftX = 0; | |
vp.TopLeftY = 0; | |
vp.Width = 1.0f * WindowClientSize.cx; | |
vp.Height = 1.0f * WindowClientSize.cy; | |
vp.MinDepth = 0; | |
vp.MaxDepth = 1; | |
D3DData.ViewPort = vp; | |
//定数バッファ[0]の更新 | |
XMMATRIX mat = XMMatrixPerspectiveFovLH(XMConvertToRadians(30.0f), vp.Width / vp.Height, 1.0f, 20.0f); | |
mat = XMMatrixTranspose(mat); | |
D3D11_MAPPED_SUBRESOURCE MappedRes; | |
hr = D3DData.pDeviceContext->Map(D3DDrawData.Index.pConstBuffer[0], 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedRes); | |
if (FAILED(hr))return FALSE; | |
CopyMemory(MappedRes.pData, &D3DDrawData.Index.m_NeverChanges, sizeof(cbNeverChanges)); | |
D3DData.pDeviceContext->Unmap(D3DDrawData.Index.pConstBuffer[0], 0); | |
return TRUE; | |
} | |
//深度・ステンシル・バッファ設定 | |
BOOL D3DDepthAndStencilBufferSetup(void) { | |
//深度・ステンシル テクスチャの作成 | |
D3D11_TEXTURE2D_DESC descDepth = { 0 }; | |
descDepth.Width = WindowClientSize.cx; | |
descDepth.Height = WindowClientSize.cy; | |
descDepth.MipLevels = 1; | |
descDepth.ArraySize = 1; | |
descDepth.Format = DXGI_FORMAT_D32_FLOAT; | |
descDepth.SampleDesc.Count = 1; | |
descDepth.SampleDesc.Quality = 0; | |
descDepth.Usage = D3D11_USAGE_DEFAULT; | |
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; | |
HRESULT hr = D3DData.pDevice->CreateTexture2D(&descDepth, NULL, &D3DData.pDepthStencil); | |
if (FAILED(hr))return FALSE; | |
D3D11_DEPTH_STENCIL_VIEW_DESC dsViewDesc; | |
dsViewDesc.Format = descDepth.Format; | |
dsViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; | |
dsViewDesc.Flags = 0; | |
dsViewDesc.Texture2D.MipSlice = 0; | |
hr = D3DData.pDevice->CreateDepthStencilView(D3DData.pDepthStencil, &dsViewDesc, &D3DData.pDepthStencilView); | |
if (FAILED(hr))return FALSE; | |
return TRUE; | |
} | |
//アイドル時の処理 | |
BOOL OnIdle(void) { | |
if (!CheckDevice())return FALSE; | |
if (D3DData.pSwapChain->Present(0, DXGI_PRESENT_TEST) != DXGI_STATUS_OCCLUDED) { | |
OnRender(); | |
} | |
return TRUE; | |
} | |
//デバイスの消滅の検査 | |
BOOL CheckDevice(void) { | |
HRESULT hr = D3DData.pDevice->GetDeviceRemovedReason(); | |
switch (hr) { | |
case S_OK: | |
break; | |
case DXGI_ERROR_DEVICE_HUNG: | |
case DXGI_ERROR_DEVICE_RESET: | |
//再初期化を試みる | |
UninitDirect3D(); | |
if (!InitDirect3D())return FALSE; | |
break; | |
default: | |
return FALSE; | |
} | |
return TRUE; | |
} | |
//シェーダーをコンパイル | |
BOOL CompileShaderFile(void) { | |
wchar_t ShaderFileName[] = L"myshader.hlsl"; | |
HRESULT hr; | |
ID3DBlob *pErBlob; | |
//VS | |
hr = D3DCompileFromFile(ShaderFileName, NULL, NULL, | |
"VS", "vs_4_0", | |
D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR, 0, | |
&D3DDrawData.Shader.pBlobVS, &pErBlob | |
); | |
if (FAILED(hr)) { | |
MessageBoxA(hWindow, (char*)pErBlob->GetBufferPointer(), "VS Error", 0); | |
pErBlob->Release(); | |
return FALSE; | |
} | |
//GS | |
hr = D3DCompileFromFile(ShaderFileName, NULL, NULL, | |
"GS", "gs_4_0", | |
D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR, 0, | |
&D3DDrawData.Shader.pBlobGS, &pErBlob | |
); | |
if (FAILED(hr)) { | |
MessageBoxA(hWindow, (char*)pErBlob->GetBufferPointer(), "GS Error", 0); | |
pErBlob->Release(); | |
return FALSE; | |
} | |
//PS | |
hr = D3DCompileFromFile(ShaderFileName, NULL, NULL, | |
"PS", "ps_4_0", | |
D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR, 0, | |
&D3DDrawData.Shader.pBlobPS, &pErBlob | |
); | |
if (FAILED(hr)) { | |
MessageBoxA(hWindow, (char*)pErBlob->GetBufferPointer(), "PS Error", 0); | |
pErBlob->Release(); | |
return FALSE; | |
} | |
return TRUE; | |
} | |
//シェーダーオブジェクトとその定数バッファを作成します | |
BOOL CreateShaderObjectWithConstBuffer(void) { | |
HRESULT hr; | |
hr = D3DData.pDevice->CreateVertexShader(D3DDrawData.Shader.pBlobVS->GetBufferPointer(), | |
D3DDrawData.Shader.pBlobVS->GetBufferSize(), | |
NULL, | |
&D3DDrawData.Shader.pVS | |
); | |
if (FAILED(hr))return FALSE; | |
hr = D3DData.pDevice->CreateGeometryShader(D3DDrawData.Shader.pBlobGS->GetBufferPointer(), | |
D3DDrawData.Shader.pBlobGS->GetBufferSize(), | |
NULL, | |
&D3DDrawData.Shader.pGS | |
); | |
D3DDrawData.Shader.pBlobGS->Release(); | |
D3DDrawData.Shader.pBlobGS = nullptr; | |
if (FAILED(hr))return FALSE; | |
hr = D3DData.pDevice->CreatePixelShader(D3DDrawData.Shader.pBlobPS->GetBufferPointer(), | |
D3DDrawData.Shader.pBlobPS->GetBufferSize(), | |
NULL, | |
&D3DDrawData.Shader.pPS | |
); | |
D3DDrawData.Shader.pBlobPS->Release(); | |
D3DDrawData.Shader.pBlobPS = nullptr; | |
if (FAILED(hr))return FALSE; | |
//定数バッファ | |
D3D11_BUFFER_DESC buf_desc = { 0 }; | |
buf_desc.Usage = D3D11_USAGE_DYNAMIC; | |
buf_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; | |
buf_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; | |
buf_desc.ByteWidth = sizeof(cbNeverChanges); | |
hr = D3DData.pDevice->CreateBuffer(&buf_desc, NULL, &D3DDrawData.Index.pConstBuffer[0]); | |
if (FAILED(hr))return FALSE; | |
buf_desc.ByteWidth = sizeof(cbChangesEveryFrame); | |
hr = D3DData.pDevice->CreateBuffer(&buf_desc, NULL, &D3DDrawData.Index.pConstBuffer[1]); | |
if (FAILED(hr))return FALSE; | |
buf_desc.ByteWidth = sizeof(cbChangesEveryObject); | |
hr = D3DData.pDevice->CreateBuffer(&buf_desc, NULL, &D3DDrawData.Index.pConstBuffer[2]); | |
if (FAILED(hr))return FALSE; | |
return TRUE; | |
} | |
BOOL InitInputAssembler(void) { | |
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, 1, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 } | |
}; | |
HRESULT hr = D3DData.pDevice->CreateInputLayout(layout, | |
sizeof(layout) / sizeof(D3D11_INPUT_ELEMENT_DESC), | |
D3DDrawData.Shader.pBlobVS->GetBufferPointer(), | |
D3DDrawData.Shader.pBlobVS->GetBufferSize(), | |
&D3DDrawData.pInputLayout | |
); | |
D3DDrawData.Shader.pBlobVS->Release(); | |
D3DDrawData.Shader.pBlobVS = nullptr; | |
if (FAILED(hr))return FALSE; | |
return TRUE; | |
} | |
BOOL InitRasterizer(void) { | |
D3D11_RASTERIZER_DESC RSDesc; | |
ZeroMemory(&RSDesc, sizeof(D3D11_RASTERIZER_DESC)); | |
RSDesc.FillMode = D3D11_FILL_SOLID; | |
RSDesc.CullMode = D3D11_CULL_NONE; | |
HRESULT hr = D3DData.pDevice->CreateRasterizerState(&RSDesc, &D3DDrawData.pRasterizerState); | |
if (FAILED(hr))return FALSE; | |
return TRUE; | |
} | |
BOOL InitOutputManager(void) { | |
//ブレンドステート | |
D3D11_BLEND_DESC bs; | |
ZeroMemory(&bs, sizeof(D3D11_BLEND_DESC)); | |
bs.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; | |
HRESULT hr; | |
hr = D3DData.pDevice->CreateBlendState(&bs, &D3DDrawData.OutputManager.pBlendState); | |
if (FAILED(hr))return FALSE; | |
//深度・ステンシルステート | |
D3D11_DEPTH_STENCIL_DESC ds; | |
ds.DepthEnable = TRUE; | |
ds.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; | |
ds.DepthFunc = D3D11_COMPARISON_LESS; | |
ds.StencilEnable = FALSE; | |
ds.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; | |
ds.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; | |
//Front | |
ds.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; | |
ds.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; | |
ds.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; | |
ds.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; | |
//Back | |
ds.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; | |
ds.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; | |
ds.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; | |
ds.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; | |
hr = D3DData.pDevice->CreateDepthStencilState(&ds, &D3DDrawData.OutputManager.pDepthStencilState); | |
if (FAILED(hr))return FALSE; | |
return TRUE; | |
} | |
BOOL UpdateConstBuffer(void) { | |
D3D11_VIEWPORT vp = D3DData.ViewPort; | |
HRESULT hr; | |
//定数バッファ[1]の更新 | |
XMVECTORF32 eyePos = { 0.0f, 5.0f, -5.0f, 1.0f }; | |
XMVECTORF32 focusPos = { 0, 0, 0, 1 }; | |
XMVECTORF32 upDirect = { 0, 1, 0, 1 }; | |
XMMATRIX mat; | |
mat = XMMatrixLookAtLH(eyePos, focusPos, upDirect); | |
XMStoreFloat4x4(&D3DDrawData.Index.m_ChangesEveryFrame.View, XMMatrixTranspose(mat)); | |
XMVECTOR vec; | |
XMFLOAT3 vLightPos(3.0f, 3.0f, -3.0f); | |
vec = XMVector3TransformCoord(XMLoadFloat3(&vLightPos), mat); | |
XMStoreFloat3(&D3DDrawData.Index.m_ChangesEveryFrame.Light, vec); | |
D3D11_MAPPED_SUBRESOURCE MappedRes; | |
hr = D3DData.pDeviceContext->Map(D3DDrawData.Index.pConstBuffer[1], 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedRes); | |
if (FAILED(hr))return FALSE; | |
CopyMemory(MappedRes.pData, &D3DDrawData.Index.m_ChangesEveryFrame, sizeof(cbChangesEveryFrame)); | |
D3DData.pDeviceContext->Unmap(D3DDrawData.Index.pConstBuffer[1], 0); | |
//定数バッファ[2]の更新 | |
XMMATRIX matY, matX; | |
FLOAT rotate = (FLOAT)(XM_PI * (timeGetTime() % 3000)) / 1500.0f; | |
matY = XMMatrixRotationY(rotate); | |
rotate = (FLOAT)(XM_PI *(timeGetTime() % 1500)) / 750.0f; | |
matX = XMMatrixRotationX(rotate); | |
XMStoreFloat4x4(&D3DDrawData.Index.m_ChangesEveryObject.World, XMMatrixTranspose(matY * matX)); | |
hr = D3DData.pDeviceContext->Map(D3DDrawData.Index.pConstBuffer[2], 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedRes); | |
if (FAILED(hr))return FALSE; | |
CopyMemory(MappedRes.pData, &D3DDrawData.Index.m_ChangesEveryObject, sizeof(cbChangesEveryObject)); | |
D3DData.pDeviceContext->Unmap(D3DDrawData.Index.pConstBuffer[2], 0); | |
return TRUE; | |
} | |
//描画処理 | |
void OnRender(void) { | |
float bgColor[4] = { 0.0f, 0.0f, 0.25f, 1.0f }; | |
D3DData.pDeviceContext->ClearRenderTargetView(D3DData.pRenderTargetView, bgColor); | |
D3DData.pDeviceContext->ClearDepthStencilView(D3DData.pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); | |
OnPaint(); | |
D3DData.pSwapChain->Present(0, 0); | |
} | |
//表示する内容の描画 | |
void OnPaint(void) { | |
UpdateConstBuffer(); | |
ID3D11DeviceContext *pDeviceContext = D3DData.pDeviceContext; | |
//IA設定 | |
UINT32 bufsize[2] = { sizeof(MyD3D_VertexPositonData), sizeof(MyD3D_VertexColorData) }; | |
UINT32 offsets[2] = { 0, 0 }; | |
pDeviceContext->IASetVertexBuffers(0, 2, reinterpret_cast<ID3D11Buffer**>(&D3DDrawData.Vertex), bufsize, offsets); | |
pDeviceContext->IASetIndexBuffer(D3DDrawData.pIndex, DXGI_FORMAT_R32_UINT, 0); | |
pDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); | |
pDeviceContext->IASetInputLayout(D3DDrawData.pInputLayout); | |
//シェーダーの設定 | |
//VS | |
pDeviceContext->VSSetShader(D3DDrawData.Shader.pVS, NULL, NULL); | |
pDeviceContext->VSSetConstantBuffers(0, 3, D3DDrawData.Index.pConstBuffer); | |
//GS | |
pDeviceContext->GSSetShader(D3DDrawData.Shader.pGS, NULL, NULL); | |
pDeviceContext->GSSetConstantBuffers(0, 3, D3DDrawData.Index.pConstBuffer); | |
//RS | |
pDeviceContext->RSSetViewports(1, &D3DData.ViewPort); | |
pDeviceContext->RSSetState(D3DDrawData.pRasterizerState); | |
//PS | |
pDeviceContext->PSSetShader(D3DDrawData.Shader.pPS, NULL, NULL); | |
pDeviceContext->PSSetConstantBuffers(0, 3, D3DDrawData.Index.pConstBuffer); | |
//OM | |
FLOAT bf[4] = { 0, 0, 0, 0 }; | |
pDeviceContext->OMSetBlendState(D3DDrawData.OutputManager.pBlendState, bf, 0xFFFFFFFF); | |
pDeviceContext->OMSetRenderTargets(1, &D3DData.pRenderTargetView, D3DData.pDepthStencilView); | |
pDeviceContext->OMSetDepthStencilState(D3DDrawData.OutputManager.pDepthStencilState, 0); | |
pDeviceContext->DrawIndexed(36, 0, 0); | |
} | |
//Direct3D終了処理 | |
void UninitDirect3D(void) { | |
MyD3D_Data ClearData = { 0 }; | |
MyD3D_DrawData ClearDataDraw = { 0 }; | |
std::vector<IUnknown*> cFreeTargetInterfaceArray; | |
IUnknown *pCurrentTarget; | |
if (D3DData.pDeviceContext)D3DData.pDeviceContext->ClearState(); | |
//解放するインタフェースクラスを追加 | |
cFreeTargetInterfaceArray.clear(); | |
cFreeTargetInterfaceArray.push_back(D3DData.pDepthStencilView); | |
cFreeTargetInterfaceArray.push_back(D3DData.pDepthStencil); | |
cFreeTargetInterfaceArray.push_back(D3DData.pRenderTargetView); | |
cFreeTargetInterfaceArray.push_back(D3DData.pSwapChain); | |
cFreeTargetInterfaceArray.push_back(D3DData.pDeviceContext); | |
cFreeTargetInterfaceArray.push_back(D3DData.pDevice); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Vertex.pPosition); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Vertex.pColor); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.pIndex); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Shader.pBlobGS); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Shader.pBlobPS); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Shader.pBlobVS); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Shader.pGS); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Shader.pGSBuffer); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Shader.pPS); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Shader.pPSBuffer); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Shader.pVS); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Shader.pVSBuffer); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Index.pConstBuffer[0]); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Index.pConstBuffer[1]); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.Index.pConstBuffer[2]); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.pInputLayout); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.pRasterizerState); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.OutputManager.pBlendState); | |
cFreeTargetInterfaceArray.push_back(D3DDrawData.OutputManager.pDepthStencilState); | |
//解放 | |
for (unsigned int i = 0; i < cFreeTargetInterfaceArray.size(); i++) { | |
pCurrentTarget = cFreeTargetInterfaceArray[i]; | |
if (pCurrentTarget)pCurrentTarget->Release(); | |
} | |
D3DData = ClearData; | |
D3DDrawData = ClearDataDraw; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment