#include <windows.h>
#include <d3d9.h>
#pragma comment(lib, "d3d9.lib")
//定数いろいろ
const LPCTSTR WIN_CLASS_NAME = TEXT("RDD");
const LPCTSTR WINDOW_NAME = TEXT("RozenMaidenDuoDectet!!");
const LPCTSTR TEXT_OUTPUT = TEXT("Under Constructions...");
//関数のプロトタイプ宣言
HWND createWindow(HINSTANCE hInstance, LPCTSTR className);
int resisterWindowClass(HINSTANCE hInstance, LPCTSTR className);
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);
HRESULT initD3D(HWND hWnd);
//グローバル変数
IDirect3D9* pDirect3D; //Direct3Dインターフェース。デバイスの作成、情報の取得などを担当
IDirect3DDevice9* pD3Device; //Direct3Dデバイスインターフェース。
D3DPRESENT_PARAMETERS d3dpp; //DirectXをどのように初期化するかのパラメータを格納するとこ
IDirect3DVertexBuffer9* pVertex; //頂点バッファ、VRAM上に作られる
//FVF設定で使う構造体の定義。これは決まってるので順番変えたりしちゃダメ
typedef struct tag_D3DVERTEX{
float x, y, z; //頂点座標
float rhw; //除算数、スケール変換の値。
DWORD dwColor; //頂点の色
float u, v; //テクスチャ座標
} D3DVERTEX;
//FVF設定で使うフラグの定義、D3DFVFを参照
#define FVF_CUSTOM (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)
//定数で三角形の頂点を定義しておく
//三角形の頂点の定義順は反時計回り。裏は描画しない
//スクリーン座標から見ると時計回り
const D3DVERTEX v[] = {
{600, 200, 0.0f, 1.0f, 0xFFFF0000, 0.0f, 0.0f},//右上赤色
{500, 400, 0.0f, 1.0f, 0xFF00FF00, 0.0f, 1.0f},//右下緑
{100, 100, 0.0f, 1.0f, 0xFFFF00FF, 1.0f, 0.0f},//左上紫
{200, 400, 0.0f, 1.0f, 0xFF0000FF, 1.0f, 0.0f} //左下青
};
////////////////////////////////////////////////////////////////////////////
// ウィンドウプロシージャ
////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){
HDC hdc;
PAINTSTRUCT ps;
switch(msg){
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
if(pD3Device == NULL)
return 0;
//白で塗りつぶす
pD3Device->Clear(0, NULL, D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0xFF, 0xFF, 0xFF), 1.0, 0);
pD3Device->BeginScene(); //描画開始
//ストリームソースに頂点バッファをセットする
pD3Device->SetStreamSource(0, //ストリーム番号、今は0を指定
pVertex, //頂点バッファコンポーネントへのポインタ
0, //頂点データの書き始めを指定、ヘッダ分ずらせる
sizeof(D3DVERTEX)); //1頂点分のサイズを指定
//頂点バッファのフォーマットをセット
pD3Device->SetFVF(FVF_CUSTOM);
//描画
pD3Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, //ポリゴンの頂点の結び方を指定、D3DPRIMITIVETYPE参照
0, //描画を開始する最初の頂点番号
2); //描画するポリゴン数
pD3Device->EndScene(); //描画終了
pD3Device->Present(NULL, NULL, NULL, NULL);
return 0;
case WM_SIZE:
if(!pD3Device)
return 0;
d3dpp.BackBufferWidth = LOWORD(lp);
d3dpp.BackBufferHeight = HIWORD(lp);
pD3Device->Reset(&d3dpp);
return 0;
}
return DefWindowProc(hWnd, msg, wp, lp);
}
/////////////////////////////////////////////////////////////////////////
// エントリポイント
/////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR lpCmdLine, int nCmdShow)
{
HWND hWnd; //ウィンドウのIDを保持するとこ
MSG msg; //メッセージを保持するとこ
if(!resisterWindowClass(hInstance,WIN_CLASS_NAME))
return 0;
if((hWnd = createWindow(hInstance, WIN_CLASS_NAME)) == NULL)
return 0;
//DirectXの初期化
if(initD3D(hWnd) != D3D_OK){
MessageBox(hWnd, TEXT("DirectXの初期化に失敗しました!"), TEXT("Error"), MB_ICONINFORMATION);
return 0;
}
////////////////////////////////////////////////////////////////
//頂点バッファの作成
////////////////////////////////////////////////////////////////
HRESULT hr;
//pVertexの先に頂点バッファ操作コンポーネント生成
hr = pD3Device->CreateVertexBuffer(sizeof(D3DVERTEX)*4, //頂点バッファのサイズ
D3DUSAGE_WRITEONLY, //リソースの使用方法指定
FVF_CUSTOM, //頂点フォーマットの型指定、D3DFVF参照
D3DPOOL_MANAGED, //バッファをどこに作るか指定、MANAGEDで適切な場所に作ってくれる
&pVertex, //頂点バッファコンポーネントへのポインタのアドレス。これを使ってバッファの操作を行う
NULL); //工事中?NULLでおk
if(hr != D3D_OK){
MessageBox(hWnd, TEXT("頂点バッファの作成に失敗しました!"), TEXT("Error"), MB_ICONINFORMATION);
return 0;
}
//頂点バッファを書き込む
void *pData;
//VRAMをロックする
hr = pVertex->Lock(0, //ロックするメモリの範囲開始点
sizeof(D3DVERTEX)*4, //ロックするメモリの範囲終点
(void**)&pData, //ロックされたメモリの先頭アドレスへのポインタ
0); //オプションフラグ、D3DLOCKを参照
if(hr == D3D_OK){
//ロックしたVRAMに頂点情報を流し込む
memcpy(pData, v, sizeof(D3DVERTEX)*4);
//ロックを外す
pVertex->Unlock();
}
else{
MessageBox(hWnd, TEXT("頂点バッファのロックに失敗しました!"), TEXT("Error"), MB_ICONINFORMATION);
return 0;
}
////////////////////////////////////////////////////////////////////
while(GetMessage(&msg, NULL, 0, 0)){//MSG構造体にメッセージをゲットだぜ
TranslateMessage(&msg);
DispatchMessage(&msg); //メッセージをウィンドウプロシージャにお裾分けする
}
pVertex->Release();
pDirect3D->Release();
pD3Device->Release();
return msg.wParam;
}
////////////////////////////////////////////////////////////////////////////
//DirectXを初期化
////////////////////////////////////////////////////////////////////////////
HRESULT initD3D(HWND hWnd){
D3DDISPLAYMODE d3ddm; //ディスプレイモードを格納するとこ
//D3Dインタフェースの取得、ここから色んな準備を行う
if((pDirect3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
return FALSE;
//バッファのサーフェイスフォーマットを指定するために、ディスプレイモードを取得する。
pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); //動的確保~
d3dpp.BackBufferFormat = d3ddm.Format; //バッファのサーフェスフォーマット。D3DFORMATを参照
d3dpp.BackBufferCount = 1; //確保するバッファ数、1ならダブルバッファ
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //ダブルバッファリングのスワップ動作指定。D3DSWAPEFFECTを参照
d3dpp.Windowed = TRUE; //FALSEでフルスクリーン
//D3Dデバイスを取得する
return pDirect3D->CreateDevice( D3DADAPTER_DEFAULT, //使用するグラフィックアダプタの指定
D3DDEVTYPE_HAL, //デバイスタイプ指定、D3DDEVTYPE参照
hWnd, //アプリのウィンドウハンドラ
D3DCREATE_SOFTWARE_VERTEXPROCESSING, //デバイスの動作を指定するフラグ
&d3dpp, //先ほど初期化したD3DPRESENT_PARAMETERSを指定
&pD3Device); //デバイスインターフェースを格納するポインタを指定
}
////////////////////////////////////////////////////////////////////////////
//ウィンドウ作成
////////////////////////////////////////////////////////////////////////////
HWND createWindow(HINSTANCE hInstance, LPCTSTR className){
return CreateWindow(className,
WINDOW_NAME,
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, //初期位置x,y
640, 480, //横幅、縦幅
NULL, NULL,
hInstance,
NULL);
}
////////////////////////////////////////////////////////////////////////////
//ウィンドウクラス登録
////////////////////////////////////////////////////////////////////////////
int resisterWindowClass(HINSTANCE hInstance, LPCTSTR className){
WNDCLASS winc;
winc.style =CS_HREDRAW | CS_VREDRAW;
winc.lpfnWndProc = WndProc;
winc.cbClsExtra = winc.cbWndExtra = 0;
winc.hInstance = hInstance;
winc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winc.hCursor = LoadCursor(NULL, IDC_ARROW);
winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
winc.lpszClassName = className;
//ウィンドウクラスを登録して使えるようにします
return RegisterClass(&winc);
}
最終更新:2008年07月28日 02:16