シーン遷移をタイトル、ゲーム、リザルトとし、game.cpp内の関数でゲーム処理を一括管理しています。(InitGame内でInitObjectなどをしています)
そんな中ゲーム画面において、プレイヤー、オブジェクトなど色々な処理が多くなり、だんだんと処理が重くなってきました。
ここでお聞きしたいのですが、描画処理など少しでも軽くさせるようなことはできないでしょうか?(SetTextureの位置や頂点バッファなどが不適切?)
main.cpp以外にobject.cppだけ載せますが、他のプロジェクトも書き方はほとんど同じです。
どなたかよろしくお願いします。
<main.h>
#ifndef _MAIN_H_
#define _MAIN_H_
/*==============================*/
/* インクルードファイル */
/*==============================*/
#include <stdio.h>
#include <Windows.h>
#include <d3dx9.h>
#define DIRECTINPUT_VERSION ( 0x0800 )
#include <dinput.h>
#include <XAudio2.h>
#pragma comment ( lib , "d3d9.lib" )
#pragma comment ( lib , "d3dx9.lib" )
#pragma comment ( lib , "dxguid.lib" )
#pragma comment ( lib , "dinput8.lib" )
#pragma comment ( lib , "winmm.lib" )
/*====================*/
/* マクロ定義 */
/*====================*/
#define CLASS_NAME "サンプル"
#define WINDOW_NAME "Direct3D"
#define NUM_VERTEX ( 4 )
#define SCREEN_WIDTH ( 800 )
#define SCREEN_HEIGHT ( 600 )
#define FVF_VERTEX_2D ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 )
/*====================*/
/* 頂点構造体 */
/*====================*/
typedef struct
{
D3DXVECTOR3 pos;
float rhw;
D3DCOLOR color;
D3DXVECTOR2 tex;
}VERTEX_2D;
/*========================*/
/* 画面遷移構造体 */
/*========================*/
typedef enum
{
MODE_TITLE = 0 ,
MODE_GAME ,
MODE_RESULT ,
MODE_MAX
}MODE;
/*==========================*/
/* プロトタイプ宣言 */
/*==========================*/
LRESULT CALLBACK WndProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam );
HRESULT Init ( HINSTANCE hInstance , HWND hWnd , BOOL bWindow ); // 初期化処理
void Uninit ( void ); // 終了処理
void Update ( void ); // 更新処理
void Draw ( void ); // 描画処理
#ifdef _DEBUG
void DrawFPS ( void ); // デバック表示用関数
#endif
LPDIRECT3DDEVICE9 GetDevice ( void ); // デバイス状態取得
void SetMode ( MODE ); // 画面モードセット
MODE GetMode ( void ); // 画面モード取得
#endif // _MAIN_H_
//============================== EOF ==============================//
/*==============================*/
/* インクルードファイル */
/*==============================*/
#include "main.h"
#include "input.h"
#include "sound.h"
#include "result.h"
#include "title.h"
#include "game.h"
#include "player.h"
/*========================*/
/* グローバル変数 */
/*========================*/
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
int g_nCountFPS = 0;
MODE g_mode = MODE_TITLE;
MODE mode;
#ifdef _DEBUG
LPD3DXFONT g_pFont = NULL;
#endif
int APIENTRY WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpCmdLine , int nCmdShow )
{
UNREFERENCED_PARAMETER ( hPrevInstance );
UNREFERENCED_PARAMETER ( lpCmdLine );
WNDCLASSEX wcex =
{
sizeof ( WNDCLASSEX ) ,
CS_CLASSDC ,
WndProc ,
0 ,
0 ,
hInstance ,
NULL ,
LoadCursor ( NULL , IDC_ARROW ) ,
( HBRUSH ) ( COLOR_WINDOW + 1 ) ,
NULL ,
CLASS_NAME ,
NULL
};
RegisterClassEx ( &wcex );
static HWND hWnd;
static MSG msg;
// ウィンドウスタイル定義
const int wstyle = WS_OVERLAPPEDWINDOW &~ WS_MINIMIZEBOX &~ WS_MAXIMIZEBOX &~ WS_THICKFRAME;
RECT cr = { 0 , 0 , SCREEN_WIDTH , SCREEN_HEIGHT };
AdjustWindowRect ( &cr , wstyle , FALSE );
int ww = cr.right - cr.left; // 画面(ウィンドウ表示)幅
int wh = cr.bottom - cr.top; // 画面(ウィンドウ表示)高
// 初期ウィンドウ位置を真ん中に設定
RECT dr;
GetWindowRect ( GetDesktopWindow() , &dr );
int dw = dr.right - dr.right;
int dh = dr.bottom - dr.top;
int wx = ww > dw ? 0: ( dw - ww ) / 2;
int wy = wh > dh ? 0: ( dh - wh ) / 2;
// ウィンドウを作成
hWnd = CreateWindowEx ( 0 ,
CLASS_NAME ,
WINDOW_NAME ,
wstyle ,
wx,
wy,
ww ,
wh ,
NULL ,
NULL ,
hInstance ,
NULL
);
// ウィンドウの表示
ShowWindow ( hWnd , nCmdShow );
UpdateWindow ( hWnd );
Init ( hInstance , hWnd , TRUE ); // 初期化
// 分解能の設定
timeBeginPeriod ( 1 );
// 各カウンターの初期化
DWORD dwFrameCount = 0;
DWORD dwCurrentTime = 0;
DWORD dwExecLastTime = timeGetTime ();
DWORD dwFPSLastTime = dwExecLastTime;
// ゲームループ
while ( GetMessage ( &msg , NULL , 0 , 0 ) )
{
for ( ;; )
{
if ( PeekMessage ( &msg , NULL , 0 , 0 , PM_REMOVE ) != 0 )
{
// Windowsの処理
if ( msg.message == WM_QUIT )
{
break;
}
else
{
// メッセージの翻訳と送出
TranslateMessage ( &msg );
DispatchMessage ( &msg );
break;
}
}
else
{
dwCurrentTime = timeGetTime (); // システム時間の取得
if ( ( dwCurrentTime - dwFPSLastTime ) >= 500 )
{
g_nCountFPS = ( dwFrameCount * 1000 ) / ( dwCurrentTime - dwFPSLastTime );
dwFPSLastTime = dwCurrentTime;
dwFrameCount = 0;
}
if ( ( dwCurrentTime - dwExecLastTime ) >= ( 1000 / 60 ) )
{
dwExecLastTime = dwCurrentTime; // 処理した時間を保存
// DirectXの処理
Update (); // 更新処理
Draw (); // 描画処理
dwFrameCount++;
}
}
}
}
timeEndPeriod ( 1 ); // タイマ終了
Uninit (); // 終了処理
return msg.wParam;
}
LRESULT CALLBACK WndProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
switch ( uMsg )
{
case WM_KEYDOWN:
if( wParam == VK_ESCAPE )
{
UINT nID = MessageBox ( NULL , "ウィンドウを閉じますか?" , "Message" , MB_YESNO );
if ( nID == IDYES )
{
DestroyWindow ( hWnd );
}
}
break;
case WM_DESTROY:
PostQuitMessage ( 0 );
break;
}
return DefWindowProc ( hWnd , uMsg , wParam , lParam );
}
/*====================*/
/* 初期化関数 */
/*====================*/
HRESULT Init ( HINSTANCE hInstance , HWND hWnd , BOOL bWindow )
{
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE d3ddm;
g_pD3D = Direct3DCreate9 ( D3D_SDK_VERSION );
if ( g_pD3D == NULL )
{
return E_FAIL;
}
if ( FAILED ( g_pD3D -> GetAdapterDisplayMode ( D3DADAPTER_DEFAULT , &d3ddm ) ) )
{
return E_FAIL;
}
ZeroMemory ( &d3dpp , sizeof ( d3dpp ) );
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.BackBufferCount = 1;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.Windowed = bWindow;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
// Direct3Dデバイスの作成
if ( FAILED ( g_pD3D -> CreateDevice ( D3DADAPTER_DEFAULT ,
D3DDEVTYPE_HAL ,
hWnd ,
D3DCREATE_HARDWARE_VERTEXPROCESSING ,
&d3dpp ,
&g_pD3DDevice ) ) )
{
if ( FAILED ( g_pD3D -> CreateDevice ( D3DADAPTER_DEFAULT ,
D3DDEVTYPE_HAL ,
hWnd ,
D3DCREATE_SOFTWARE_VERTEXPROCESSING ,
&d3dpp ,
&g_pD3DDevice ) ) )
{
if ( FAILED ( g_pD3D -> CreateDevice ( D3DADAPTER_DEFAULT ,
D3DDEVTYPE_REF ,
hWnd ,
D3DCREATE_SOFTWARE_VERTEXPROCESSING ,
&d3dpp ,
&g_pD3DDevice ) ) )
{
return E_FAIL;
}
}
}
#ifdef _DEBUG
D3DXCreateFont ( g_pD3DDevice ,
18 ,
0 ,
0 ,
0 ,
FALSE ,
SHIFTJIS_CHARSET ,
OUT_DEFAULT_PRECIS ,
DEFAULT_QUALITY ,
DEFAULT_PITCH ,
"Terminal" ,
&g_pFont
);
#endif // _DEBUG
//g_pD3DDevice -> SetRenderState ( D3DRS_CULLMODE , D3DCULL_CCW );
g_pD3DDevice -> SetRenderState ( D3DRS_ALPHABLENDENABLE , TRUE );
g_pD3DDevice -> SetRenderState ( D3DRS_SRCBLEND , D3DBLEND_SRCALPHA );
g_pD3DDevice -> SetRenderState ( D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA );
//g_pD3DDevice -> SetSamplerState ( 0 , D3DSAMP_MINFILTER , D3DTEXF_LINEAR );
g_pD3DDevice -> SetSamplerState ( 0 , D3DSAMP_MAGFILTER , D3DTEXF_LINEAR );
SetMode ( g_mode );
InitKeyboard ( hInstance , hWnd );
InitSound ( hWnd );
InitGame ();
return S_OK;
}
/*==================*/
/* 終了処理 */
/*==================*/
void Uninit ( void )
{
if ( g_pD3DDevice != NULL )
{
// Direct3Dデバイスの解放
g_pD3DDevice -> Release ();
g_pD3DDevice = NULL;
}
if ( g_pD3D != NULL )
{
// Direct3Dインタフェースの解放
g_pD3D -> Release ();
g_pD3D = NULL;
}
UninitKeyboard ();
UninitSound ();
UninitGame ();
#ifdef _DEBUG
if ( g_pFont != NULL )
{
// フォントの解放
g_pFont -> Release ();
g_pFont = NULL;
}
#endif
}
/*==================*/
/* 更新処理 */
/*==================*/
void Update ( void )
{
UpdateKeyboard ();
switch ( g_mode )
{
case MODE_TITLE:
UpdateTitle ();
if ( GetKeyboardPress ( DIK_RETURN ) )
{
SetMode ( MODE_GAME );
}
break;
case MODE_GAME:
UpdateGame ();
if ( GetKeyboardPress ( DIK_RETURN ) )
{
SetMode ( MODE_RESULT );
}
break;
case MODE_RESULT:
UpdateResult ();
if ( GetKeyboardPress ( DIK_RETURN ) )
{
SetMode ( MODE_TITLE );
}
break;
}
}
/*==================*/
/* 描画関数 */
/*==================*/
void Draw ( void )
{
g_pD3DDevice -> Clear ( 0 ,
NULL ,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER ,
D3DCOLOR_RGBA ( 255 , 255 , 255 , 0 ) ,
1.0f ,
0
);
// 描画の開始
if ( SUCCEEDED ( g_pD3DDevice -> BeginScene () ) )
{
switch ( g_mode )
{
case MODE_TITLE:
DrawTitle ();
break;
case MODE_GAME:
DrawGame ();
#ifdef _DEBUG
// FPS表示
DrawFPS ();
#endif
break;
case MODE_RESULT:
DrawResult ();
break;
}
if ( g_mode != mode )
{
SetMode ( g_mode );
}
// 描画終了
g_pD3DDevice -> EndScene ();
}
g_pD3DDevice -> Present ( NULL , NULL , NULL , NULL );
}
LPDIRECT3DDEVICE9 GetDevice ( void )
{
return g_pD3DDevice;
}
/*=====================*/
/* FPS表示関数 */
/*=====================*/
#ifdef _DEBUG
void DrawFPS ( void )
{
char aStr [256];
RECT rect = { 0, 0 , SCREEN_WIDTH , SCREEN_HEIGHT };
// FPS表示
sprintf ( &aStr [0] , "FPS:%d\n" , g_nCountFPS );
g_pFont -> DrawText ( NULL ,
&aStr [0] ,
-1 ,
&rect ,
DT_LEFT ,
D3DCOLOR_RGBA ( 255 , 0 , 0 , 255 ) );
}
#endif // _DEBUG
/*================================*/
/* 画面モード状態取得関数 */
/*================================*/
MODE GetMode ( void )
{
return g_mode;
}
/*==================================*/
/* 画面モード状態セット関数 */
/*==================================*/
void SetMode ( MODE mode )
{
// 終了処理
switch ( g_mode )
{
case MODE_TITLE:
UninitTitle ();
break;
case MODE_GAME:
UninitGame ();
break;
case MODE_RESULT:
UninitResult ();
break;
}
// 初期化処理
switch ( mode )
{
case MODE_TITLE:
InitTitle ();
break;
case MODE_GAME:
InitGame ();
break;
case MODE_RESULT:
InitResult ();
break;
}
g_mode = mode;
}
//============================== EOF ==============================//
//==============================//
/* インクルードファイル */
//==============================//
#include "object.h"
#include "main.h"
#include "player.h"
//====================//
/* マクロ定義 */
//====================//
#define OBJECT_TEXTURENAME "data/TEXTURE/Coin.jpg"
// ポリゴン表示位置X
#define OBJECT_POS_X ( 400 )
// ポリゴン表示位置Y
#define OBJECT_POS_Y ( 480 )
// ポリゴン幅
#define OBJECT_WIDTH ( 100 )
// ポリゴン高さ
#define OBJECT_HEIGHT ( 100 )
// プレイヤーのポリゴン数
#define NUM_OBJECT ( 2 )
//==========================//
/* プロトタイプ宣言 */
//==========================//
HRESULT MakeVertexObject ( LPDIRECT3DDEVICE9 pDevice6 ); // 頂点作成関数
//========================//
/* グローバル変数 */
//========================//
VERTEX_2D g_aVertex8 [ NUM_VERTEX ];
LPDIRECT3DTEXTURE9 g_pTextureObject = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVtxBufferObject = NULL;
float g_PosPlayer;
//====================//
/* 初期化処理 */
//====================//
void InitObject ( void )
{
LPDIRECT3DDEVICE9 pDevice = GetDevice();
MakeVertexObject ( pDevice );
// テクスチャの設定
if ( FAILED ( D3DXCreateTextureFromFile ( pDevice , OBJECT_TEXTURENAME , &g_pTextureObject ) ) )
{
MessageBox ( NULL , "テクスチャファイル(オブジェクト)読み込み失敗" , "ERROR" , MB_OK );
}
}
//==================//
/* 終了処理 */
//==================//
void UninitObject ( void )
{
if ( g_pTextureObject != NULL )
{
// テクスチャポリゴンの解放
g_pTextureObject -> Release ();
g_pTextureObject = NULL;
}
}
//==================//
/* 更新処理 */
//==================//
void UpdateObject ( void )
{
VERTEX_2D* pVtx;
g_pVtxBufferObject -> Lock(
0 ,
0 ,
( void** )&pVtx ,
0 );
g_pVtxBufferObject -> Unlock();
}
//==================//
/* 描画処理 */
//==================//
void DrawObject ( void )
{
LPDIRECT3DDEVICE9 pDevice = GetDevice();
pDevice -> SetStreamSource ( 0 ,
g_pVtxBufferObject ,
0 ,
sizeof ( VERTEX_2D )
);
// 頂点フォーマットの設定
pDevice -> SetFVF ( FVF_VERTEX_2D );
// テクスチャセット
if ( FAILED ( pDevice -> SetTexture ( 0 , g_pTextureObject ) ) )
{
MessageBox ( NULL , "ポリゴンへのテクスチャ設定失敗" , "ERROR" , MB_OK );
}
// プレイヤーの座標取得
g_PosPlayer = GetPlayer ();
if ( g_PosPlayer < OBJECT_POS_X )
{
// ポリゴン描画
pDevice -> DrawPrimitive ( D3DPT_TRIANGLESTRIP ,
0 ,
NUM_OBJECT
);
}
}
//======================//
/* 頂点作成関数 */
//======================//
HRESULT MakeVertexObject ( LPDIRECT3DDEVICE9 pDevice6 )
{
// 頂点バッファの生成
pDevice6 -> CreateVertexBuffer ( sizeof ( VERTEX_2D ) * NUM_VERTEX ,
D3DUSAGE_WRITEONLY ,
FVF_VERTEX_2D ,
D3DPOOL_MANAGED ,
&g_pVtxBufferObject ,
NULL
);
if ( FAILED ( pDevice6 -> CreateVertexBuffer ( sizeof ( VERTEX_2D ) * NUM_VERTEX , D3DUSAGE_WRITEONLY , FVF_VERTEX_2D , D3DPOOL_MANAGED , &g_pVtxBufferObject , NULL ) ) )
{
return E_FAIL;
}
VERTEX_2D* pVtx;
g_pVtxBufferObject -> Lock ( 0 ,
0 ,
( void** )&pVtx ,
0 );
// 頂点座標の設定
pVtx [ 0 ].pos = D3DXVECTOR3 ( OBJECT_POS_X , OBJECT_POS_Y , 0.0f );
pVtx [ 1 ].pos = D3DXVECTOR3 ( OBJECT_POS_X + OBJECT_WIDTH , OBJECT_POS_Y , 0.0f );
pVtx [ 2 ].pos = D3DXVECTOR3 ( OBJECT_POS_X , OBJECT_POS_Y + OBJECT_HEIGHT , 0.0f );
pVtx [ 3 ].pos = D3DXVECTOR3 ( OBJECT_POS_X + OBJECT_WIDTH , OBJECT_POS_Y + OBJECT_HEIGHT , 0.0f );
pVtx [ 0 ].rhw = 1.0f;
pVtx [ 1 ].rhw = 1.0f;
pVtx [ 2 ].rhw = 1.0f;
pVtx [ 3 ].rhw = 1.0f;
// 頂点色の設定
pVtx [ 0 ].color = D3DCOLOR_RGBA ( 255 , 255 , 255 , 255 );
pVtx [ 1 ].color = D3DCOLOR_RGBA ( 255 , 255 , 255 , 255 );
pVtx [ 2 ].color = D3DCOLOR_RGBA ( 255 , 255 , 255 , 255 );
pVtx [ 3 ].color = D3DCOLOR_RGBA ( 255 , 255 , 255 , 255 );
// テクスチャ座標の設定
pVtx [ 0 ].tex = D3DXVECTOR2 ( 0.0f , 0.0f );
pVtx [ 1 ].tex = D3DXVECTOR2 ( 1.0f , 0.0f );
pVtx [ 2 ].tex = D3DXVECTOR2 ( 0.0f , 1.0f );
pVtx [ 3 ].tex = D3DXVECTOR2 ( 1.0f , 1.0f );
g_pVtxBufferObject -> Unlock();
return S_OK;
}
//============================== EOF ==============================//