【ステップ1−1 フォント生成】 | 解説 |
![]() |
ワークスペース(左図の部分)から、 d3dmain.cpp をダブルクリックして開きます。 すると画面は、図2の様になったはずです。 |
図1 ワークスペース |
![]() |
図2 d3dmain.cpp |
![]() |
次に、図3のようにして編集メニューから検索コマンドを選びます。 すると、図4のようなダイアログウィンドウが出てきます、 ここでは、RestoreDeviceObjects というキーワードで検索を実行。 すると、リスト1aのプログラムが出てくるはずです。 違うようなら、「次を検索」で検索を繰り返してみて下さい。 | |
![]() | ||
図4 検索ウィンドウ
| 図3 検索コマンド |
改造前 |
---|
HRESULT RestoreDeviceObjects() { LPDIRECT3DSURFACE8 pBackBuffer; g_lpD3DDEV->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer ); pBackBuffer->GetDesc( &g_d3dsdBackBuffer ); pBackBuffer->Release(); D3DXCreateTextureFromResourceEx(g_lpD3DDEV, GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_BITMAP1), 0,0,1,0, D3DFMT_A1R5G5B5,D3DPOOL_MANAGED, D3DX_FILTER_LINEAR,D3DX_FILTER_LINEAR, D3DCOLOR_XRGB(0,255,255), // Color key. NULL,NULL,&g_pTexture); g_fTexImageWidth = 1.0f; g_fTexImageHeight = 1.0f; return S_OK; } |
リスト1a |
改造後 | |
---|---|
HRESULT RestoreDeviceObjects() { LPDIRECT3DSURFACE8 pBackBuffer; g_lpD3DDEV->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer ); pBackBuffer->GetDesc( &g_d3dsdBackBuffer ); pBackBuffer->Release(); D3DXCreateTextureFromResourceEx(g_lpD3DDEV, GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_BITMAP1), 0,0,1,0, D3DFMT_A1R5G5B5,D3DPOOL_MANAGED, D3DX_FILTER_LINEAR,D3DX_FILTER_LINEAR, D3DCOLOR_XRGB(0,255,255), // Color key. NULL,NULL,&g_pTexture); |
|
HFONT hf; hf = CreateFont(16,0,0,0,0,false,false,false,ANSI_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE,""); if (hf != NULL){ D3DXCreateFont(g_lpD3DDEV,hf,&g_pFont); DeleteObject(hf); } | |
g_fTexImageWidth = 1.0f; g_fTexImageHeight = 1.0f; return S_OK; } |
|
リスト1b |
解説 |
リスト1bの明るい部分の内容を追加記入してください。
ここではデバイス依存オブジェクトとして、ID3DXFont型のインスタンスを 生成しています。詳しくは Microsoft のドキュメントを参照の事。 |
【ステップ1−2 フォント破棄】 | 解説 | |
![]() |
再度、図5のようにして編集メニューから検索コマンドを選びます。 すると、図6のようなダイアログウィンドウが出てきます、 こんどは、InvalidateDeviceObjects というキーワードで検索を実行。 | |
![]() | ||
図6 検索ウィンドウ
| 図5 検索コマンド |
改造前 |
---|
HRESULT InvalidateDeviceObjects() { if (g_pTexture != NULL){ g_pTexture->Release(); g_pTexture = NULL; } return S_OK; } |
リスト2a |
改造後 | |
---|---|
HRESULT InvalidateDeviceObjects() { |
|
if (g_pFont != NULL){ g_pFont->Release(); g_pFont = NULL; } |
|
if (g_pTexture != NULL){ g_pTexture->Release(); g_pTexture = NULL; } return S_OK; } |
|
リスト2b |
解説 |
リスト2bの明るい部分の内容を追加記入してください。
ここでは、ステップ1−1で生成したID3DXFontオブジェクトを 破棄しています。 |
【ステップ1−3 表示】 | 解説 | |
![]() |
次に、図7のようにして編集メニューから検索コマンドを選びます。 すると、図8のようなダイアログウィンドウが出てきます、 ここでは、UpdateScreen というキーワードで検索を実行。 | |
![]() | ||
図8 検索ウィンドウ
| 図7 検索コマンド |
改造前 |
---|
void UpdateScreen() { float timeElapsed; HRESULT hr; if (g_pHighResTimer == NULL) return; if (0.5 > g_pHighResTimer->GetElapsedTime()) return; timeElapsed=g_pHighResTimer->GetElapsedTimeAndReset(); // Test the cooperative level to see if it's okay to render if( FAILED( hr = g_lpD3DDEV->TestCooperativeLevel() ) ) { // If the device was lost, do not render until we get it back if( D3DERR_DEVICELOST == hr ) return; // Check if the device needs to be resized. if( D3DERR_DEVICENOTRESET == hr ) { // If we are windowed, read the desktop mode and use the same format for // the back buffer if( g_bWindowed ) { D3DAdapterInfo* pAdapterInfo = &g_Adapters[g_dwAdapter]; g_lpD3D->GetAdapterDisplayMode( g_dwAdapter, &pAdapterInfo->d3ddmDesktop ); g_d3dprm.BackBufferFormat = pAdapterInfo->d3ddmDesktop.Format; } if( FAILED( hr = Resize3DEnvironment() ) ) return; } return; } if (g_bUseDepthBuffer) g_lpD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,g_bgColor,1.0f,0); else g_lpD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET,g_bgColor,1.0f,0); g_lpD3DDEV->BeginScene(); SetDefaultRenderState(g_lpD3DDEV); // 描画方法の設定 g_lpD3DDEV->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); g_lpD3DDEV->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); g_lpD3DDEV->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); if (g_bCanGreaterEqual){ g_lpD3DDEV->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE ); g_lpD3DDEV->SetRenderState( D3DRS_ALPHAREF, 0x08 ); g_lpD3DDEV->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL ); } // アニメーションの為の座標計算 int x,y; static double d1=0,d2=0; d1 += 0.07*timeElapsed; d2 += 0.05*timeElapsed; if (d1 > (D3DX_PI*2)) d1 -= D3DX_PI*2; if (d2 > (D3DX_PI*2)) d2 -= D3DX_PI*2; y = (int)(100*sin(d1)); y += 240; x = (int)(200*sin(d2)); x += 320; // 四角形の頂点の設定 TLVERTEX2D pV[4]; pV[0].x = (float)x;pV[0].y=(float)y;pV[0].z=0.0f;pV[0].rhw=1.0f; pV[0].tu = 0.0f;pV[0].tv=0.0f;pV[0].color=D3DCOLOR_XRGB(255,255,255); pV[1].x = (float)(x + 64);pV[1].y=(float)y;pV[1].z=0.0f;pV[1].rhw=1.0f; pV[1].tu = 1.0f;pV[1].tv=0.0f;pV[1].color=D3DCOLOR_XRGB(255,255,255); pV[2].x = (float)(x + 64);pV[2].y=(float)(y + 64);pV[2].z=0.0f;pV[2].rhw=1.0f; pV[2].tu = 1.0f;pV[2].tv=1.0f;pV[2].color=D3DCOLOR_XRGB(255,255,255); pV[3].x = (float)x;pV[3].y=(float)(y + 64);pV[3].z=0.0f;pV[3].rhw=1.0f; pV[3].tu = 0.0f;pV[3].tv=1.0f;pV[3].color=D3DCOLOR_XRGB(255,255,255); // 描画の実行 g_lpD3DDEV->SetTexture(0,g_pTexture); g_lpD3DDEV->SetVertexShader(FVF_TLVERTEX2D); g_lpD3DDEV->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,2,pV,sizeof(TLVERTEX2D)); // ※ここを改造 g_lpD3DDEV->EndScene(); if (FAILED(g_lpD3DDEV->Present(NULL,NULL,NULL,NULL))){ Resize3DEnvironment(); } } |
リスト3a |
解説 |
関数 UpdateScreen は、OnIdle 関数から呼び出している関数で、
I/O入力、座標計算などのアニメーション、あたり判定、画面表示 など(初期化と終了処理を除く)ゲームのメインとなるプログラムを 想定しています。 その為、ゲームのキャラクタの表示ルーチンなどはここに記入すれば 良い事になります。 |
改造後 | |
---|---|
void UpdateScreen() { float timeElapsed; HRESULT hr; if (g_pHighResTimer == NULL) return; if (0.5 > g_pHighResTimer->GetElapsedTime()) return; timeElapsed=g_pHighResTimer->GetElapsedTimeAndReset(); // Test the cooperative level to see if it's okay to render if( FAILED( hr = g_lpD3DDEV->TestCooperativeLevel() ) ) { // If the device was lost, do not render until we get it back if( D3DERR_DEVICELOST == hr ) return; // Check if the device needs to be resized. if( D3DERR_DEVICENOTRESET == hr ) { // If we are windowed, read the desktop mode and use the same format for // the back buffer if( g_bWindowed ) { D3DAdapterInfo* pAdapterInfo = &g_Adapters[g_dwAdapter]; g_lpD3D->GetAdapterDisplayMode( g_dwAdapter, &pAdapterInfo->d3ddmDesktop ); g_d3dprm.BackBufferFormat = pAdapterInfo->d3ddmDesktop.Format; } if( FAILED( hr = Resize3DEnvironment() ) ) return; } return; } if (g_bUseDepthBuffer) g_lpD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,g_bgColor,1.0f,0); else g_lpD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET,g_bgColor,1.0f,0); g_lpD3DDEV->BeginScene(); SetDefaultRenderState(g_lpD3DDEV); // 描画方法の設定(描画エンジンの設定) g_lpD3DDEV->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); g_lpD3DDEV->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); g_lpD3DDEV->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); if (g_bCanGreaterEqual){ g_lpD3DDEV->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE ); g_lpD3DDEV->SetRenderState( D3DRS_ALPHAREF, 0x08 ); g_lpD3DDEV->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL ); } // アニメーションの為の座標計算 int x,y; static double d1=0,d2=0; d1 += 0.07*timeElapsed; d2 += 0.05*timeElapsed; if (d1 > (D3DX_PI*2)) d1 -= D3DX_PI*2; if (d2 > (D3DX_PI*2)) d2 -= D3DX_PI*2; y = (int)(100*sin(d1)); y += 240; x = (int)(200*sin(d2)); x += 320; // 四角形の頂点の設定 TLVERTEX2D pV[4]; pV[0].x = (float)x;pV[0].y=(float)y;pV[0].z=0.0f;pV[0].rhw=1.0f; pV[0].tu = 0.0f;pV[0].tv=0.0f;pV[0].color=D3DCOLOR_XRGB(255,255,255); pV[1].x = (float)(x + 64);pV[1].y=(float)y;pV[1].z=0.0f;pV[1].rhw=1.0f; pV[1].tu = 1.0f;pV[1].tv=0.0f;pV[1].color=D3DCOLOR_XRGB(255,255,255); pV[2].x = (float)(x + 64);pV[2].y=(float)(y + 64);pV[2].z=0.0f;pV[2].rhw=1.0f; pV[2].tu = 1.0f;pV[2].tv=1.0f;pV[2].color=D3DCOLOR_XRGB(255,255,255); pV[3].x = (float)x;pV[3].y=(float)(y + 64);pV[3].z=0.0f;pV[3].rhw=1.0f; pV[3].tu = 0.0f;pV[3].tv=1.0f;pV[3].color=D3DCOLOR_XRGB(255,255,255); // 描画の実行 g_lpD3DDEV->SetTexture(0,g_pTexture); g_lpD3DDEV->SetVertexShader(FVF_TLVERTEX2D); g_lpD3DDEV->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,2,pV,sizeof(TLVERTEX2D)); |
|
// 文字描画 char str[64]; static int count = 0; RECT r; sprintf(str,"%08d",count++); r.left = 10; r.top = 10; r.right = r.left + 150; r.bottom = r.top + 16; g_pFont->DrawText(str,-1,&r,DT_BOTTOM | DT_LEFT,D3DCOLOR_XRGB(255,255,255)); // 線の描画方法の設定 g_lpD3DDEV->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); // 線を描画する座標の計算 x = (int)(250 * sin(d1)); x += 270; y = 240; // 線の描画 LVERTEX2D pV2[4]; pV2[0].x = (float)x;pV2[0].y=(float)y;pV2[0].z=0.0f;pV2[0].rhw=1.0f; pV2[0].color=D3DCOLOR_XRGB(255,0,0); pV2[1].x = (float)(x + 100);pV2[1].y=(float)y;pV2[1].z=0.0f;pV2[1].rhw=1.0f; pV2[1].color=D3DCOLOR_XRGB(255,255,255); g_lpD3DDEV->SetTexture(0,NULL); g_lpD3DDEV->SetVertexShader(FVF_LVERTEX2D); g_lpD3DDEV->DrawPrimitiveUP(D3DPT_LINELIST,1,pV2,sizeof(LVERTEX2D)); // 点の描画方法の設定 g_lpD3DDEV->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); // 点を描画する座標の計算 y = (int)(240 * sin(d1)); y += 240; x = 128; // 点の描画 pV2[0].x = (float)x;pV2[0].y=(float)y;pV2[0].z=0.0f;pV2[0].rhw=1.0f; pV2[0].color=D3DCOLOR_XRGB(255,127,255); pV2[1].x = (float)(x + 128);pV2[1].y=(float)y;pV2[1].z=0.0f;pV2[1].rhw=1.0f; pV2[1].color=D3DCOLOR_XRGB(255,255,255); pV2[2].x = (float)(x + 256);pV2[2].y=(float)y;pV2[2].z=0.0f;pV2[2].rhw=1.0f; pV2[2].color=D3DCOLOR_XRGB(255,255,255); pV2[3].x = (float)(x + 384);pV2[3].y=(float)y;pV2[3].z=0.0f;pV2[3].rhw=1.0f; pV2[3].color=D3DCOLOR_XRGB(255,255,255); g_lpD3DDEV->SetTexture(0,NULL); g_lpD3DDEV->SetVertexShader(FVF_LVERTEX2D); g_lpD3DDEV->DrawPrimitiveUP(D3DPT_POINTLIST,4,pV2,sizeof(LVERTEX2D)); |
|
g_lpD3DDEV->EndScene(); if (FAILED(g_lpD3DDEV->Present(NULL,NULL,NULL,NULL))){ Resize3DEnvironment(); } } |
|
リスト3b |
解説 |
リスト3bの明るい部分の内容を追加記入してください。
ここでは、D3DXライブラリを使用して文字描画を行った後、 3Dのレンダリングエンジンを設定し、 続いて、アニメーションの為の座標計算を行っています。 最後に、実際のレンダリング(描画)を行っています。 構造体 LVERTEX2D および、マクロ定数 FVF_LVERTEX2D は d3dmain.h の中で宣言されています。 |
![]() |