Skip to content

Instantly share code, notes, and snippets.

@hirosof
Created August 1, 2014 13:14
Show Gist options
  • Save hirosof/812f692d7a82d588c71b to your computer and use it in GitHub Desktop.
Save hirosof/812f692d7a82d588c71b to your computer and use it in GitHub Desktop.
/*----------------------------------------------------------------------------
プログラム名: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