Created
July 30, 2014 17:10
-
-
Save hirosof/e1c8414285183b378f6e to your computer and use it in GitHub Desktop.
Direct3D 11の基本プログラムです
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
/*---------------------------------------------------------------------------- | |
プログラム名:D3DBasic | |
プログラム概要:Direct3D 11の基本プログラムです | |
-------------------------------------------------------------------------------- | |
*/ | |
//インクルード | |
#include <windows.h> | |
#include <stdio.h> | |
#include <locale.h> | |
#include <vector> | |
#include <tchar.h> | |
#include <d3d11.h> | |
#pragma comment(lib,"D3D11.lib") | |
//マニフェスト登録 | |
#pragma comment(linker,"\"/manifestdependency:type='win32' " \ | |
"name='Microsoft.Windows.Common-Controls' " \ | |
"version='6.0.0.0' " \ | |
"processorArchitecture='*' " \ | |
"publicKeyToken='6595b64144ccf1df' " \ | |
"language='*'\"") | |
//マクロ部 | |
#define PRONAME "D3DIntroduction - Basic" //プログラム名 | |
#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); | |
//構造体宣言部 | |
//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; | |
}; | |
#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 }; | |
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; | |
} | |
//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_B8G8R8A8_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 (!D3DBackBuffarSetup()) { | |
#ifdef _DEBUG | |
SET_CONSOLETEXTCOLOR_FOR_ERROR; | |
_tprintf(TEXT("バックバッファの設定に失敗しました。\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; | |
} | |
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; | |
} | |
D3DData.pDeviceContext->OMSetRenderTargets(1, &D3DData.pRenderTargetView, NULL); | |
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; | |
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; | |
} | |
//描画処理 | |
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); | |
D3DData.pDeviceContext->RSSetViewports(1, &D3DData.ViewPort); | |
D3DData.pDeviceContext->OMSetRenderTargets(1, &D3DData.pRenderTargetView, D3DData.pDepthStencilView); | |
OnPaint(); | |
D3DData.pSwapChain->Present(0, 0); | |
} | |
//表示する内容の描画 | |
void OnPaint(void) { | |
} | |
//Direct3D終了処理 | |
void UninitDirect3D(void) { | |
MyD3D_Data ClearData = { 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); | |
//解放 | |
for (unsigned int i = 0; i < cFreeTargetInterfaceArray.size(); i++) { | |
pCurrentTarget = cFreeTargetInterfaceArray[i]; | |
if (pCurrentTarget)pCurrentTarget->Release(); | |
} | |
D3DData = ClearData; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment