#1
by うまお » 5年前
[1] 質問文
[1.1] 自分が今行いたい事は何か
2Dゲームを作りたいがために板ポリゴンを用意して移動処理等を書いてみたが、拡大縮小・回転の処理が想定していた処理と違う(拡大縮小についてはポリゴンが移動しながら行われてしまい、回転に関してもポリゴンの位置も移動している)。その為拡大縮小と回転を板ポリゴンの中心を軸に行いたいがやり方がわからない。
[1.2] どのように取り組んだか(プログラムコードがある場合記載)
Main.cpp
コード:
//=============================================================================
//【Main.cpp】
//メインとなるクラス
//=============================================================================
//*****************************************************************************
//インクルード・ヘッダーファイル
//*****************************************************************************
#include "Main.h" //メインとなるヘッダー
#include "Player.h" //Playerポリゴンのヘッダー
//*****************************************************************************
//ライブラリのリンク
//*****************************************************************************
//*****************************************************************************
//マクロ定義
//*****************************************************************************
#define CLASS_NAME "ウィンドウのクラス名" //ウィンドウのクラス名
#define WINDOW_NAME "Windowsテンプレート" //ウィンドウのキャプション名
//*****************************************************************************
//イーナム定義
//*****************************************************************************
//*****************************************************************************
//構造体定義
//*****************************************************************************
//*****************************************************************************
//プロトタイプ宣言
//*****************************************************************************
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //ウィンドウプロシジャ関数
HRESULT Init3D3(HWND, BOOL); //Direct3D初期化関数
void Uninit3D3(void); //Direct3D終了処理関数
void Update(void); //更新処理関数
void Draw(void); //画面描写処理関数
//*****************************************************************************
//グローバル変数:
//*****************************************************************************
LPDIRECT3D9 g_pD3D = NULL; //Direct3Dへアクセスするためのポインタ
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL; //ビデオカードへアクセスするためのポインタ
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【メイン関数】
//WinMain()からプログラムが開始される
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int APIENTRY WinMain(
HINSTANCE hInstance, //インスタンスハンドル
HINSTANCE hPrevInstance, //未使用(常にNULL)
LPSTR lpCmdLine, //コマンドライン引数
int nCmdShow) //ウィンドウの表示方法
{
//ウィンドウクラスを登録
WNDCLASSEX wcex; //WNDCLASSEX構造体の変数
wcex.cbSize = sizeof(WNDCLASSEX); //WNDCLASSEX構造体のサイズ
wcex.style = CS_CLASSDC; //ウインドウスタイル
wcex.lpfnWndProc = WndProc; //ウィンドウプロシージャのアドレス
wcex.cbClsExtra = 0; //補助メモリを追加するためのサイズ
wcex.cbWndExtra = 0; //ウインドウを表す内部データ構造体に追加するメモリ
wcex.hInstance = hInstance; //WinMain()のインスタンスハンドル
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); //タスクバーやタイトルバーに表示されるアイコン
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //hCursor:ウィンドウのクライアントエリア上のマウスカーソル
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); //ウインドウのクライアント領域の背景色
wcex.lpszMenuName = NULL; //メニュー
wcex.lpszClassName = TEXT(CLASS_NAME); //Windowクラスの名前
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); //使用する小さいアイコン
if (RegisterClassEx(&wcex) == 0) return 0; //RegisterClass関数を使用してNDCLASSEX構造体の登録を行い失敗したら終了する
//ウィンドウ生成を行う
HWND hWnd; //ウィンドウハンドルの変数
hWnd = CreateWindowEx( //CreateWindowEx関数を使用してウインドウを生成する。
0, //拡張ウィンドウスタイル
TEXT(CLASS_NAME), //登録されているクラス名
TEXT(WINDOW_NAME), //タイトルバーに表示する文字列
WS_OVERLAPPEDWINDOW, //ウィンドウスタイル
CW_USEDEFAULT, //ウインドウ左上のX座標
CW_USEDEFAULT, //ウインドウ左上のY座標
(SCREEN_WIDTH + GetSystemMetrics(SM_CXDLGFRAME) * 2), //ウィンドウの幅
(SCREEN_HEIGHT + GetSystemMetrics(SM_CYDLGFRAME) * 2) //ウィンドウの高さ
+ GetSystemMetrics(SM_CYCAPTION),
NULL, //オーナー(親)ウィンドウのハンドル
NULL, //メニューハンドルまたは子のID(識別子)
hInstance, //アプリケーションインスタンスのハンドル
NULL); //ウィンドウ作成データ
if (!hWnd) return 0; //失敗した場合終了する
//Direct3Dの初期化を行う
if (FAILED(Init3D3(hWnd, WINMODE))) return 0; //失敗した場合終了する
ShowWindow(hWnd, nCmdShow); //ShowWindow関数を使用してウィンドウを表示する
UpdateWindow(hWnd); //UpdateWindow関数を使用してウィンドウを更新する
//FPS制御の準備を行う
DWORD dwBeforeTime; //時間更新前格納用変数
DWORD dwAfterTime; //時間更新後格納用変数
timeBeginPeriod(1); //ミリ単位で最小タイマ分解能を指定
dwBeforeTime = timeGetTime(); //timeGetTime関数でソフト起動時のシステム時間をミリ単位で取得し格納する
//メインメッセージループを行う
MSG msg = { 0 }; //MSG構造体の変数
while (WM_QUIT != msg.message)
{
//メッセージ処理
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) { //PeekMessage関数を使用してキューにメッセージがポストされてるかを確認する
TranslateMessage(&msg); //TranslateMessage関数を使用して押されているキーボードの情報をアプリケーションが取得できる形に変換してくれている
DispatchMessage(&msg); //DispatchMessage関数を使用して取得したメッセージをウインドウプロシージャに送る処理をする
}
//DirectX処理
else {
dwAfterTime = timeGetTime(); //timeGetTime関数で現在のシステム時間をミリ単位で取得し格納する
if (FRAME_DIRAY <= dwAfterTime - dwBeforeTime) { //フレーム周期 <= 現在のシステム時間-更新前のシステム時間の場合処理を行う
dwBeforeTime = dwAfterTime; //更新を行ったため現在のシステム時間を時間更新前格納用変数に格納
Update(); //更新処理を行う
Draw(); //描写処理を行う
}
}
}
//ウィンドウクラスを削除しメモリを解放する
UnregisterClass(TEXT(CLASS_NAME), wcex.hInstance);
//Direct3Dの終了処理を行う
Uninit3D3();
//WM_QUITメッセージを受け取って正常に終了する場合はmsg.wParamを返さないといけない
//メッセージループに入る前の場合は0を返す
return (int)msg.wParam;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【ウィンドウプロシージャ関数】
//メッセージループで取得したメッセージを処理する関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
LRESULT CALLBACK WndProc(
HWND hWnd, //メッセージが発生したウィンドウのハンドル
UINT message, //メッセージコード
WPARAM wParam, //メッセージの付加情報(メッセージコードにより異なる)
LPARAM lParam) //メッセージの付加情報(メッセージコードにより異なる)
{
//messageによってメッセージを判断する。
switch (message)
{
case WM_DESTROY: //ウィンドウ右上の閉じるボタンを押した際
PostQuitMessage(0); //PostQuitMessage関数を使用してWM_QUITメッセージを発生させる
DestroyWindow(hWnd);
break;
default: //ウィンドウプロシージャが処理しない部分
return DefWindowProc(hWnd, message, wParam, lParam); //DefWindowProc関数を使用してWindows側で勝手に処理をさせる
//この関数を実行しないと基本的なウィンドウの動作ができなくなる
}
return 0;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Direct3D初期化関数】
//Direct3Dの初期化処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HRESULT Init3D3(
HWND hWnd, //ウィンドウハンドル
BOOL bWindow) //ウィンドウモード
{
D3DPRESENT_PARAMETERS d3dpp; //D3DPRESENT_PARAMETERS構造体の変数
D3DDISPLAYMODE d3ddm; //D3DDISPLAYMODE構造体の変数
//IDIRECT3D9コンポーネントの取得を行い、失敗したらE_FAILを返す
if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) return E_FAIL;
//GetAdapterDisplayMode関数を使用して現在のディスプレイモードの取得を行い、失敗したらE_FAILを返す
if (FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) return E_FAIL;
ZeroMemory(&d3dpp, sizeof(d3dpp)); //ZeroMemoryを使用してd3dppを初期化している?
d3dpp.BackBufferWidth = SCREEN_WIDTH; //画面の幅
d3dpp.BackBufferHeight = SCREEN_HEIGHT; //画面の高さ
d3dpp.BackBufferFormat = d3ddm.Format; //バックバッファのフォーマット
d3dpp.BackBufferCount = 1; //バックバッファの数
d3dpp.MultiSampleType; //マルチサンプルの数
d3dpp.MultiSampleQuality; //マルチサンプルの品質レベル
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //フロントバッファとバックバッファの切り替え方法
d3dpp.hDeviceWindow; //画面を描画するウィンドウハンドル
d3dpp.Windowed = bWindow; //スクリーンモード
d3dpp.EnableAutoDepthStencil = TRUE; //深度ステンシルバッファの有無
d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8; //ステンシルバッファのフォーマット
d3dpp.Flags; //バックバッファからフロントバッファへ転送する時の機能のオプション
//ウィンドウモードごとの設定部分
if (bWindow) { //ウィンドウモード
d3dpp.FullScreen_RefreshRateInHz = 0; //フルスクリーンでのリフレッシュレート
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //スワップの書き換えタイミング
}
else { //フルスクリーンモード
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
}
//IDirect3DDevice9コンポーネントの取得を行い、失敗したらE_FAILを返す
if (FAILED(g_pD3D->CreateDevice( //最初に描画と頂点処理をハードウェアで行うようにする
D3DADAPTER_DEFAULT, //ディスプレイアダプタの番号
D3DDEVTYPE_HAL, //D3DDEVTYPE列挙型のメンバ
//D3DDEVTYPE_HALでハードウェアで描画実行をするように指定
hWnd, //描画を行うウィンドウハンドル
D3DCREATE_HARDWARE_VERTEXPROCESSING, //デバイスの作成を制御するオプションフラグ
//D3DCREATE_HARDWARE_VERTEXPROCESSINGでハードウェアを使用して頂点処理を行うようにする
&d3dpp, //D3DPRESENT_PARAMETERS構造体へのポインタ
&g_pD3DDevice))) //IDirect3DDevice9コンポーネントへのポインタ
if (FAILED(g_pD3D->CreateDevice( //上記で失敗したため描画をハードウェアで行い頂点処理をCPUで行うようにする
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, //D3DCREATE_SOFTWARE_VERTEXPROCESSINGでCPUを使用して頂点処理を行うようにする
&d3dpp,
&g_pD3DDevice)))
if (FAILED(g_pD3D->CreateDevice( //上記で失敗したため描画をCPUで行い頂点処理をハードウェアで行うようにする
D3DADAPTER_DEFAULT,
D3DDEVTYPE_REF, //D3DDEVTYPE_REFでCPUで描画実行をするように指定
hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp,
&g_pD3DDevice)))
if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, //上記で失敗したため描画と頂点処理をCPUで行うようにする
D3DDEVTYPE_REF,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&g_pD3DDevice)))
{
g_pD3D->Release(); //Release関数でメモリを開放する
return E_FAIL;
}
//ポリゴンとテクスチャの色の乗算処理
g_pD3DDevice->SetTextureStageState( //ここでテクスチャの色を1番目の対象にする
0, //対象となるテクスチャステージ
D3DTSS_COLORARG1, //D3DTEXTURESTAGESTATETYPE列挙型で合成対象や合成演算を決める
//D3DTSS_COLORARG1 :1番目に対象となる色の引数
D3DTA_TEXTURE); //上記の処理によって入るものが異なる
//D3DTA_TEXTURE :テクスチャを対象
g_pD3DDevice->SetTextureStageState( //ここで色に対する処理を指定
0,
D3DTSS_COLOROP, //D3DTSS_COLOROP :色の演算子
D3DTOP_MODULATE); //D3DTOP_MODULATE :乗算
g_pD3DDevice->SetTextureStageState( //ここでポリゴンの色を2番目の対象にする
0,
D3DTSS_COLORARG2, //D3DTSS_COLORARG2 :2番目に対象となる色の引数
D3DTA_DIFFUSE); //D3DTA_DIFFUSE :ポリゴンを対象
//αブレンディング処理を行う
g_pD3DDevice->SetTextureStageState( //テクスチャの色を1番目の対象にする
0,
D3DTSS_COLORARG1,
D3DTA_TEXTURE);
g_pD3DDevice->SetTextureStageState( //色に対する処理を指定
0,
D3DTSS_COLOROP,
D3DTOP_BLENDTEXTUREALPHA); //D3DTOP_BLENDTEXTUREALPHA :あらかじめ乗算されたアルファを使用するテクスチャステージの線形ブレンディングを実行する
g_pD3DDevice->SetTextureStageState( //ポリゴンの色を2番目の対象にする
0,
D3DTSS_COLORARG2,
D3DTA_DIFFUSE);
g_pD3DDevice->SetTextureStageState( //ここでα値に対する処理を指定
0,
D3DTSS_ALPHAOP,
D3DTOP_SELECTARG2); //2番目の色はアルファ引数を変更せずに使用する
g_pD3DDevice->SetTextureStageState( //ポリゴンのα値を対象にする
0,
D3DTSS_ALPHAARG2, //2番目のα値を対象
D3DTA_DIFFUSE);
//ポリゴンとテクスチャの透明度の乗算処理
g_pD3DDevice->SetTextureStageState( //ここでテクスチャのα値を対象にする
0,
D3DTSS_ALPHAARG1, //D3DTSS_ALPHAARG1 :1番目に対象となるα値
D3DTA_TEXTURE);
g_pD3DDevice->SetTextureStageState( //ここでα値に対する処理を指定
0,
D3DTSS_ALPHAOP, //アルファブレンディング処理
D3DTOP_MODULATE);
g_pD3DDevice->SetTextureStageState( //ここでポリゴンのα値を対象にする
0,
D3DTSS_ALPHAARG1, //D3DTSS_ALPHAARG2 :2番目に対象となるα値
D3DTA_TEXTURE);
if (FAILED(InitPlayer(g_pD3D, g_pD3DDevice))) return E_FAIL; //Playerポリゴン初期化処理
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Direct3D終了処理関数】
//Direct3Dの終了処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void Uninit3D3(void)
{
if (g_pD3DDevice != NULL) {
g_pD3DDevice->Release();
g_pD3DDevice = NULL;
}
if (g_pD3D != NULL) {
g_pD3D->Release();
g_pD3D = NULL;
}
UninitPlayer(); //Playerポリゴン終了処理
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【更新処理関数】
//更新に関する処理を扱う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void Update(void)
{
UpdataPlayer(g_pD3DDevice); //Playerポリゴン更新処理
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【画面描写処理関数】
//ウィンドウの描写処理を扱う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void Draw(void)
{
//Clear関数で指定した色でクリアし、深度バッファをクリアする。更にステンシルバッファを削除する
g_pD3DDevice->Clear(
0, //クリアする矩形領域の数
NULL, //矩形領域
(D3DCLEAR_TARGET //レンタリングターゲットをクリアしてClearパラメータの色にする
| D3DCLEAR_ZBUFFER), //深海バッファをクリアしてZパラメータの値にする
D3DCOLOR_RGBA(0, 0, 0, 0), //透明度100%で指定した色にクリア
1.0f, //Zバッファのクリア値
0); //ステンシルバッファのクリア値
if (SUCCEEDED(g_pD3DDevice->BeginScene())) //バックバッファに描画開始
{
DrawPlayer(g_pD3DDevice); //Playerポリゴン描画処理
g_pD3DDevice->EndScene(); //バックバッファの描画終了
}
g_pD3DDevice->Present(NULL, NULL, NULL, NULL); //Present関数で画面に表示
}
Main.h
コード:
//=============================================================================
//【Main.h】
//メインとなるヘッダー
//=============================================================================
#ifndef _MAIN_H_ //二重定義防止の為に行う
#define _MAIN_H_
//*****************************************************************************
//インクルード・ヘッダーファイル
//*****************************************************************************
#include <windows.h> //Windows標準関数実装
#include <d3d9.h> //Direct3D関連実装
#include <d3dx9.h> //Direct3D関連関数実装
//*****************************************************************************
//ライブラリのリンク
//*****************************************************************************
#pragma comment (lib, "dxguid.lib") //グローバルユニークIDに関わるライブラリ
#pragma comment (lib, "d3d9.lib") //Direct3Dコアライブラリ
#pragma comment (lib, "d3dx9.lib") //Direct3D拡張ライブラリ
#pragma comment (lib,"winmm.lib") //Windowsライブラリ
//*****************************************************************************
//マクロ定義
//*****************************************************************************
#define WINMODE TRUE //ウィンドウモードの指定
#define SCREEN_WIDTH (800) //ウィンドウの幅
#define SCREEN_HEIGHT (600) //ウインドウの高さ
#define SCREEN_CENTER_X (SCREEN_WIDTH/2) //ウィンドウの中心座標X
#define SCREEN_CENTER_Y (SCREEN_HEIGHT/2) //ウィンドウの中心座標Y
#define FPS (60) //1秒間に画面を更新する回数(フレーム/秒)
#define FRAME_DIRAY ((DWORD)(1000 / FPS)) //フレーム周期(1フレームあたりの最大処理時間)
#define NUM_VERTEX (4) //頂点の数
#define NUM_POLYGON (2) //ポリゴンの数
#define FVF_CUSTOM (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1) //頂点情報フラグ
//D3DFVF_XYZRHW :トランスフォームされた頂点の位置座標を含む頂点フォーマット
//D3DFVF_DIFFUSE:ディフューズ色成分を含む頂点フォーマット
//D3DFVF_TEX1 :テクスチャ座標の頂点フォーマット
//*****************************************************************************
//イーナム定義
//*****************************************************************************
//*****************************************************************************
//構造体定義
//*****************************************************************************
typedef struct CUSTOMVERTEX //2Dに必須なフォーマットをまとめた構造体の定義
{
D3DXVECTOR3 pos; //頂点座標
float rhw; //除算数
D3DCOLOR col; //頂点カラー
D3DXVECTOR2 tex; //テクスチャ座標
};
//*****************************************************************************
//プロトタイプ宣言
//*****************************************************************************
#endif
Player.cpp(今回の質問の箇所)
コード:
//=============================================================================
//【Player.cpp】
//Playerポリゴンを管理する関数を扱うクラス
//=============================================================================
//*****************************************************************************
//インクルード・ヘッダーファイル
//*****************************************************************************
#include "Player.h"
//*****************************************************************************
//ライブラリのリンク
//*****************************************************************************
//*****************************************************************************
//マクロ定義
//*****************************************************************************
//#define PLAYER_TEXTURENAME "DATA/TEXTURE/Player.png" //テクスチャファイル名
#define PLAYER_INITPOS_X (SCREEN_CENTER_X) //初期位置X
#define PLAYER_INITPOS_Y (SCREEN_CENTER_Y) //初期位置Y
#define PLAYER_SIZE_X (50) //横幅
#define PLAYER_SIZE_Y (50) //横幅
//*****************************************************************************
//イーナム定義
//*****************************************************************************
//*****************************************************************************
//構造体定義
//*****************************************************************************
//*****************************************************************************
//プロトタイプ宣言
//*****************************************************************************
void MakeFormatPlayer(LPDIRECT3DDEVICE9 pDevice); //Playerポリゴンフォーマット情報作成関数
void MovePlayer(float, float, float); //Playerポリゴン移動関数
void ZoomPlayer(float, float, float); //Playerポリゴン拡大縮小関数
void RotationPlayer(float); //Playerポリゴン回転関数
//*****************************************************************************
//グローバル変数:
//*****************************************************************************
CUSTOMVERTEX g_pFormatPlayer[NUM_VERTEX]; //フォーマット情報格納用変数
LPDIRECT3DVERTEXBUFFER9 g_pVertexPlayer = NULL; //頂点バッファコンポーネントへのポインタ
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン初期化関数】
//Playerポリゴンの初期化処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HRESULT InitPlayer(
LPDIRECT3D9 pD3D, //Direct3Dへアクセスするためのポインタ
LPDIRECT3DDEVICE9 pDevice) //ビデオカードへアクセスするためのポインタ
{
//フォーマット情報を作成する
MakeFormatPlayer(pDevice);
//頂点バッファの作成をする
if (FAILED(pDevice->CreateVertexBuffer(
sizeof(CUSTOMVERTEX) * 4, //確保する頂点バッファのサイズ
D3DUSAGE_WRITEONLY, //リソースの使用法を定義するフラグ
FVF_CUSTOM, //頂点フォーマットの型の指定
D3DPOOL_MANAGED, //どの種類のメモリに頂点バッファを置くかの指定
&g_pVertexPlayer, //頂点バッファコンポーネントへのポインタのアドレス
NULL))) //特に使用されていない為NULL
{
pDevice->Release();
pD3D->Release();
return E_FAIL;
}
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン終了処理関数】
//Playerポリゴンの終了処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void UninitPlayer(void)
{
if (g_pVertexPlayer != NULL) {
g_pVertexPlayer->Release();
g_pVertexPlayer = NULL;
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン更新処理関数】
//Playeポリゴンrの更新処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void UpdataPlayer(LPDIRECT3DDEVICE9 pDevice)
{
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン描画処理関数】
//Playerポリゴンの描画処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void DrawPlayer(LPDIRECT3DDEVICE9 pDevice) //ビデオカードへアクセスするためのポインタ
{
//頂点バッファを書き込むためにメモリをロックする
void *pData;
if (SUCCEEDED(g_pVertexPlayer->Lock(
0, //全体にロックをするため0
sizeof(CUSTOMVERTEX) * 4, //ロックしたいメモリサイズ
(void**)&pData, //ロックされたメモリ範囲の先頭アドレスへのポインタ
0))) //ロック時の動作を定義するフラグ
{
memcpy(pData, g_pFormatPlayer, sizeof(CUSTOMVERTEX) * 4);
g_pVertexPlayer->Unlock();
}
//ストリームソースという頂点処理の流れに頂点バッファを実際にセットする
pDevice->SetStreamSource(
0, //ストリームの番号
g_pVertexPlayer, //頂点バッファコンポーネントへのポインタ
0, //頂点データの書き始めを示すオフセット
sizeof(CUSTOMVERTEX)); //1頂点のサイズ
//ストリームに頂点バッファの型を教える
pDevice->SetFVF(FVF_CUSTOM);
//頂点の結び方とポリゴンの描画枚数を指定
pDevice->DrawPrimitive(
D3DPT_TRIANGLESTRIP, //頂点をどう結びポリゴンにするかのフラグ
0, //描画を開始する最初の頂点番号
2); //描画するポリゴンの数
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴンフォーマット情報作成関数】
//Playerポリゴンのフォーマット情報作成処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void MakeFormatPlayer(LPDIRECT3DDEVICE9 pDevice) //ビデオカードへアクセスするためのポインタ
{
//頂点座標設定
g_pFormatPlayer[0].pos = //左上
D3DXVECTOR3(PLAYER_INITPOS_X - PLAYER_SIZE_X / 2, PLAYER_INITPOS_Y - PLAYER_SIZE_Y / 2, 0.0f);
g_pFormatPlayer[1].pos = //右上
D3DXVECTOR3(PLAYER_INITPOS_X + PLAYER_SIZE_X / 2, PLAYER_INITPOS_Y - PLAYER_SIZE_Y / 2, 0.0f);
g_pFormatPlayer[2].pos = //左下
D3DXVECTOR3(PLAYER_INITPOS_X - PLAYER_SIZE_X / 2, PLAYER_INITPOS_Y + PLAYER_SIZE_Y / 2, 0.0f);
g_pFormatPlayer[3].pos = //右下
D3DXVECTOR3(PLAYER_INITPOS_X + PLAYER_SIZE_X / 2, PLAYER_INITPOS_Y + PLAYER_SIZE_Y / 2, 0.0f);
//除算数設定
g_pFormatPlayer[0].rhw = 1.0f;
g_pFormatPlayer[1].rhw = 1.0f;
g_pFormatPlayer[2].rhw = 1.0f;
g_pFormatPlayer[3].rhw = 1.0f;
//頂点カラー設定
g_pFormatPlayer[0].col =
D3DCOLOR_RGBA(255, 255, 255, 255);
g_pFormatPlayer[1].col =
D3DCOLOR_RGBA(255, 255, 255, 255);
g_pFormatPlayer[2].col =
D3DCOLOR_RGBA(255, 255, 255, 255);
g_pFormatPlayer[3].col =
D3DCOLOR_RGBA(255, 255, 255, 255);
//テクスチャ座標設定
g_pFormatPlayer[0].tex =
D3DXVECTOR2(0.0f, 0.0f); //左上
g_pFormatPlayer[1].tex =
D3DXVECTOR2(1.0f, 0.0f); //右上
g_pFormatPlayer[2].tex =
D3DXVECTOR2(0.0f, 1.0f); //左下
g_pFormatPlayer[3].tex =
D3DXVECTOR2(1.0f, 1.0f); //右下
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン移動関数】
//Playerポリゴンの移動処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void MovePlayer(
float x, //移動距離X
float y, //移動距離Y
float z) //移動距離Z
{
D3DXMATRIX PosMatrix; //Playerポリゴンの現在位置格納用単位行列
D3DXMATRIX MoveMatrix; //Playerポリゴンの移動量格納用単位行列
//行列初期化
D3DXMatrixIdentity(&PosMatrix);
D3DXMatrixIdentity(&MoveMatrix);
//移動処理
D3DXMatrixTranslation( //D3DXMatrixTranslation関数を使用してMoveMatrixに移動量を格納する
&MoveMatrix,
x,
y,
z);
for (int i = 0; i < NUM_VERTEX; i++) {
D3DXMatrixTranslation( //D3DXMatrixTranslation関数を使用してPosMatrixに現在地を格納する
&PosMatrix,
g_pFormatPlayer[i].pos.x,
g_pFormatPlayer[i].pos.y,
g_pFormatPlayer[i].pos.z);
PosMatrix *= MoveMatrix; //現在地の行列に移動量行列を加算する
g_pFormatPlayer[i].pos.x = PosMatrix._41; //演算結果をポリゴンのX座標に格納する
g_pFormatPlayer[i].pos.y = PosMatrix._42; //演算結果をポリゴンのY座標に格納する
g_pFormatPlayer[i].pos.z = PosMatrix._43; //演算結果をポリゴンのZ座標に格納する
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン拡大縮小関数】
//Playerポリゴンの拡大処理と縮小処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void ZoomPlayer(float x, float y, float z)
{
D3DXMATRIX PosMatrix; //Playerポリゴンの現在位置格納用単位行列
D3DXMATRIX ZoomMatrix; //Playerポリゴンの拡張量格納用単位行列
//行列初期化
D3DXMatrixIdentity(&PosMatrix);
D3DXMatrixIdentity(&ZoomMatrix);
//拡大縮小処理
D3DXMatrixScaling( //D3DXMatrixScaling関数を使用してZoomMatrixに拡張量を格納する
&ZoomMatrix,
x,
y,
z);
for (int i = 0; i < NUM_VERTEX; i++) {
D3DXMatrixTranslation( //D3DXMatrixTranslation関数を使用してPosMatrixに現在地を格納する
&PosMatrix,
g_pFormatPlayer[i].pos.x,
g_pFormatPlayer[i].pos.y,
g_pFormatPlayer[i].pos.z);
PosMatrix *= ZoomMatrix; //現在地の行列に拡張量行列を加算する
g_pFormatPlayer[i].pos.x = PosMatrix._41; //演算結果をポリゴンのX座標に格納する
g_pFormatPlayer[i].pos.y = PosMatrix._42; //演算結果をポリゴンのY座標に格納する
g_pFormatPlayer[i].pos.z = PosMatrix._43; //演算結果をポリゴンのZ座標に格納する
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン回転関数】
//Playerポリゴンの回転処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void RotationPlayer(float angle)
{
D3DXMATRIX PosMatrix; //Playerポリゴンの現在位置格納用単位行列
D3DXMATRIX RotationMatrix; //Playerポリゴンの回転量格納用単位行列
//行列初期化
D3DXMatrixIdentity(&PosMatrix);
D3DXMatrixIdentity(&RotationMatrix);
//拡大縮小処理
D3DXMatrixRotationZ( //D3DXMatrixRotationZ関数を使用してRotationMatrixに回転量を格納する
&RotationMatrix,
D3DXToRadian(angle));
for (int i = 0; i < NUM_VERTEX; i++) {
D3DXMatrixTranslation( //D3DXMatrixTranslation関数を使用してPosMatrixに現在地を格納する
&PosMatrix,
g_pFormatPlayer[i].pos.x,
g_pFormatPlayer[i].pos.y,
g_pFormatPlayer[i].pos.z);
PosMatrix *= RotationMatrix; //現在地の行列に回転量行列を加算する
g_pFormatPlayer[i].pos.x = PosMatrix._41; //演算結果をポリゴンのX座標に格納する
g_pFormatPlayer[i].pos.y = PosMatrix._42; //演算結果をポリゴンのY座標に格納する
g_pFormatPlayer[i].pos.z = PosMatrix._43; //演算結果をポリゴンのZ座標に格納する
}
}
Player.h
コード:
//=============================================================================
//【Player.h】
//Playerポリゴン用ヘッダー
//=============================================================================
#ifndef _Player_H_ //二重定義防止の為に行う
#define _Player_H_
//*****************************************************************************
//インクルード・ヘッダーファイル
//*****************************************************************************
#include "Main.h"
//*****************************************************************************
//ライブラリのリンク
//*****************************************************************************
//*****************************************************************************
//マクロ定義
//*****************************************************************************
//*****************************************************************************
//イーナム定義
//*****************************************************************************
//*****************************************************************************
//構造体定義
//*****************************************************************************
//*****************************************************************************
//プロトタイプ宣言
//*****************************************************************************
HRESULT InitPlayer(LPDIRECT3D9, LPDIRECT3DDEVICE9); //Playerポリゴン初期化処理関数
void UninitPlayer(void); //Playerポリゴン終了処理関数
void UpdataPlayer(LPDIRECT3DDEVICE9 pDevic); //Playerポリゴン更新処理関数
void DrawPlayer(LPDIRECT3DDEVICE9 pDevice); //Player描画処理関数
#endif
[1.3] どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)
実行できている為割愛。
[1.4] 今何がわからないのか、知りたいのか
板ポリゴンの中心を軸に位置が変わらなず回転・拡大縮小を行いたい。
[2] 環境
[2.1] OS:Windows10
[2.2] コンパイラ名: Visual C++ 2017
[3] その他
・C、DirectX共に半年触ったか触っていないか程度。現在きちんと講習を受けている最中。
正し軽い基礎はjavaを1年独学でやっていた。
[1] 質問文
[1.1] 自分が今行いたい事は何か
[align=center]2Dゲームを作りたいがために板ポリゴンを用意して移動処理等を書いてみたが、拡大縮小・回転の処理が想定していた処理と違う(拡大縮小についてはポリゴンが移動しながら行われてしまい、回転に関してもポリゴンの位置も移動している)。その為拡大縮小と回転を板ポリゴンの中心を軸に行いたいがやり方がわからない。[/align]
[1.2] どのように取り組んだか(プログラムコードがある場合記載)
Main.cpp
[code]//=============================================================================
//【Main.cpp】
//メインとなるクラス
//=============================================================================
//*****************************************************************************
//インクルード・ヘッダーファイル
//*****************************************************************************
#include "Main.h" //メインとなるヘッダー
#include "Player.h" //Playerポリゴンのヘッダー
//*****************************************************************************
//ライブラリのリンク
//*****************************************************************************
//*****************************************************************************
//マクロ定義
//*****************************************************************************
#define CLASS_NAME "ウィンドウのクラス名" //ウィンドウのクラス名
#define WINDOW_NAME "Windowsテンプレート" //ウィンドウのキャプション名
//*****************************************************************************
//イーナム定義
//*****************************************************************************
//*****************************************************************************
//構造体定義
//*****************************************************************************
//*****************************************************************************
//プロトタイプ宣言
//*****************************************************************************
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //ウィンドウプロシジャ関数
HRESULT Init3D3(HWND, BOOL); //Direct3D初期化関数
void Uninit3D3(void); //Direct3D終了処理関数
void Update(void); //更新処理関数
void Draw(void); //画面描写処理関数
//*****************************************************************************
//グローバル変数:
//*****************************************************************************
LPDIRECT3D9 g_pD3D = NULL; //Direct3Dへアクセスするためのポインタ
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL; //ビデオカードへアクセスするためのポインタ
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【メイン関数】
//WinMain()からプログラムが開始される
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int APIENTRY WinMain(
HINSTANCE hInstance, //インスタンスハンドル
HINSTANCE hPrevInstance, //未使用(常にNULL)
LPSTR lpCmdLine, //コマンドライン引数
int nCmdShow) //ウィンドウの表示方法
{
//ウィンドウクラスを登録
WNDCLASSEX wcex; //WNDCLASSEX構造体の変数
wcex.cbSize = sizeof(WNDCLASSEX); //WNDCLASSEX構造体のサイズ
wcex.style = CS_CLASSDC; //ウインドウスタイル
wcex.lpfnWndProc = WndProc; //ウィンドウプロシージャのアドレス
wcex.cbClsExtra = 0; //補助メモリを追加するためのサイズ
wcex.cbWndExtra = 0; //ウインドウを表す内部データ構造体に追加するメモリ
wcex.hInstance = hInstance; //WinMain()のインスタンスハンドル
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); //タスクバーやタイトルバーに表示されるアイコン
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //hCursor:ウィンドウのクライアントエリア上のマウスカーソル
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); //ウインドウのクライアント領域の背景色
wcex.lpszMenuName = NULL; //メニュー
wcex.lpszClassName = TEXT(CLASS_NAME); //Windowクラスの名前
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); //使用する小さいアイコン
if (RegisterClassEx(&wcex) == 0) return 0; //RegisterClass関数を使用してNDCLASSEX構造体の登録を行い失敗したら終了する
//ウィンドウ生成を行う
HWND hWnd; //ウィンドウハンドルの変数
hWnd = CreateWindowEx( //CreateWindowEx関数を使用してウインドウを生成する。
0, //拡張ウィンドウスタイル
TEXT(CLASS_NAME), //登録されているクラス名
TEXT(WINDOW_NAME), //タイトルバーに表示する文字列
WS_OVERLAPPEDWINDOW, //ウィンドウスタイル
CW_USEDEFAULT, //ウインドウ左上のX座標
CW_USEDEFAULT, //ウインドウ左上のY座標
(SCREEN_WIDTH + GetSystemMetrics(SM_CXDLGFRAME) * 2), //ウィンドウの幅
(SCREEN_HEIGHT + GetSystemMetrics(SM_CYDLGFRAME) * 2) //ウィンドウの高さ
+ GetSystemMetrics(SM_CYCAPTION),
NULL, //オーナー(親)ウィンドウのハンドル
NULL, //メニューハンドルまたは子のID(識別子)
hInstance, //アプリケーションインスタンスのハンドル
NULL); //ウィンドウ作成データ
if (!hWnd) return 0; //失敗した場合終了する
//Direct3Dの初期化を行う
if (FAILED(Init3D3(hWnd, WINMODE))) return 0; //失敗した場合終了する
ShowWindow(hWnd, nCmdShow); //ShowWindow関数を使用してウィンドウを表示する
UpdateWindow(hWnd); //UpdateWindow関数を使用してウィンドウを更新する
//FPS制御の準備を行う
DWORD dwBeforeTime; //時間更新前格納用変数
DWORD dwAfterTime; //時間更新後格納用変数
timeBeginPeriod(1); //ミリ単位で最小タイマ分解能を指定
dwBeforeTime = timeGetTime(); //timeGetTime関数でソフト起動時のシステム時間をミリ単位で取得し格納する
//メインメッセージループを行う
MSG msg = { 0 }; //MSG構造体の変数
while (WM_QUIT != msg.message)
{
//メッセージ処理
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) { //PeekMessage関数を使用してキューにメッセージがポストされてるかを確認する
TranslateMessage(&msg); //TranslateMessage関数を使用して押されているキーボードの情報をアプリケーションが取得できる形に変換してくれている
DispatchMessage(&msg); //DispatchMessage関数を使用して取得したメッセージをウインドウプロシージャに送る処理をする
}
//DirectX処理
else {
dwAfterTime = timeGetTime(); //timeGetTime関数で現在のシステム時間をミリ単位で取得し格納する
if (FRAME_DIRAY <= dwAfterTime - dwBeforeTime) { //フレーム周期 <= 現在のシステム時間-更新前のシステム時間の場合処理を行う
dwBeforeTime = dwAfterTime; //更新を行ったため現在のシステム時間を時間更新前格納用変数に格納
Update(); //更新処理を行う
Draw(); //描写処理を行う
}
}
}
//ウィンドウクラスを削除しメモリを解放する
UnregisterClass(TEXT(CLASS_NAME), wcex.hInstance);
//Direct3Dの終了処理を行う
Uninit3D3();
//WM_QUITメッセージを受け取って正常に終了する場合はmsg.wParamを返さないといけない
//メッセージループに入る前の場合は0を返す
return (int)msg.wParam;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【ウィンドウプロシージャ関数】
//メッセージループで取得したメッセージを処理する関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
LRESULT CALLBACK WndProc(
HWND hWnd, //メッセージが発生したウィンドウのハンドル
UINT message, //メッセージコード
WPARAM wParam, //メッセージの付加情報(メッセージコードにより異なる)
LPARAM lParam) //メッセージの付加情報(メッセージコードにより異なる)
{
//messageによってメッセージを判断する。
switch (message)
{
case WM_DESTROY: //ウィンドウ右上の閉じるボタンを押した際
PostQuitMessage(0); //PostQuitMessage関数を使用してWM_QUITメッセージを発生させる
DestroyWindow(hWnd);
break;
default: //ウィンドウプロシージャが処理しない部分
return DefWindowProc(hWnd, message, wParam, lParam); //DefWindowProc関数を使用してWindows側で勝手に処理をさせる
//この関数を実行しないと基本的なウィンドウの動作ができなくなる
}
return 0;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Direct3D初期化関数】
//Direct3Dの初期化処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HRESULT Init3D3(
HWND hWnd, //ウィンドウハンドル
BOOL bWindow) //ウィンドウモード
{
D3DPRESENT_PARAMETERS d3dpp; //D3DPRESENT_PARAMETERS構造体の変数
D3DDISPLAYMODE d3ddm; //D3DDISPLAYMODE構造体の変数
//IDIRECT3D9コンポーネントの取得を行い、失敗したらE_FAILを返す
if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) return E_FAIL;
//GetAdapterDisplayMode関数を使用して現在のディスプレイモードの取得を行い、失敗したらE_FAILを返す
if (FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) return E_FAIL;
ZeroMemory(&d3dpp, sizeof(d3dpp)); //ZeroMemoryを使用してd3dppを初期化している?
d3dpp.BackBufferWidth = SCREEN_WIDTH; //画面の幅
d3dpp.BackBufferHeight = SCREEN_HEIGHT; //画面の高さ
d3dpp.BackBufferFormat = d3ddm.Format; //バックバッファのフォーマット
d3dpp.BackBufferCount = 1; //バックバッファの数
d3dpp.MultiSampleType; //マルチサンプルの数
d3dpp.MultiSampleQuality; //マルチサンプルの品質レベル
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //フロントバッファとバックバッファの切り替え方法
d3dpp.hDeviceWindow; //画面を描画するウィンドウハンドル
d3dpp.Windowed = bWindow; //スクリーンモード
d3dpp.EnableAutoDepthStencil = TRUE; //深度ステンシルバッファの有無
d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8; //ステンシルバッファのフォーマット
d3dpp.Flags; //バックバッファからフロントバッファへ転送する時の機能のオプション
//ウィンドウモードごとの設定部分
if (bWindow) { //ウィンドウモード
d3dpp.FullScreen_RefreshRateInHz = 0; //フルスクリーンでのリフレッシュレート
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //スワップの書き換えタイミング
}
else { //フルスクリーンモード
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
}
//IDirect3DDevice9コンポーネントの取得を行い、失敗したらE_FAILを返す
if (FAILED(g_pD3D->CreateDevice( //最初に描画と頂点処理をハードウェアで行うようにする
D3DADAPTER_DEFAULT, //ディスプレイアダプタの番号
D3DDEVTYPE_HAL, //D3DDEVTYPE列挙型のメンバ
//D3DDEVTYPE_HALでハードウェアで描画実行をするように指定
hWnd, //描画を行うウィンドウハンドル
D3DCREATE_HARDWARE_VERTEXPROCESSING, //デバイスの作成を制御するオプションフラグ
//D3DCREATE_HARDWARE_VERTEXPROCESSINGでハードウェアを使用して頂点処理を行うようにする
&d3dpp, //D3DPRESENT_PARAMETERS構造体へのポインタ
&g_pD3DDevice))) //IDirect3DDevice9コンポーネントへのポインタ
if (FAILED(g_pD3D->CreateDevice( //上記で失敗したため描画をハードウェアで行い頂点処理をCPUで行うようにする
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, //D3DCREATE_SOFTWARE_VERTEXPROCESSINGでCPUを使用して頂点処理を行うようにする
&d3dpp,
&g_pD3DDevice)))
if (FAILED(g_pD3D->CreateDevice( //上記で失敗したため描画をCPUで行い頂点処理をハードウェアで行うようにする
D3DADAPTER_DEFAULT,
D3DDEVTYPE_REF, //D3DDEVTYPE_REFでCPUで描画実行をするように指定
hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp,
&g_pD3DDevice)))
if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, //上記で失敗したため描画と頂点処理をCPUで行うようにする
D3DDEVTYPE_REF,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&g_pD3DDevice)))
{
g_pD3D->Release(); //Release関数でメモリを開放する
return E_FAIL;
}
//ポリゴンとテクスチャの色の乗算処理
g_pD3DDevice->SetTextureStageState( //ここでテクスチャの色を1番目の対象にする
0, //対象となるテクスチャステージ
D3DTSS_COLORARG1, //D3DTEXTURESTAGESTATETYPE列挙型で合成対象や合成演算を決める
//D3DTSS_COLORARG1 :1番目に対象となる色の引数
D3DTA_TEXTURE); //上記の処理によって入るものが異なる
//D3DTA_TEXTURE :テクスチャを対象
g_pD3DDevice->SetTextureStageState( //ここで色に対する処理を指定
0,
D3DTSS_COLOROP, //D3DTSS_COLOROP :色の演算子
D3DTOP_MODULATE); //D3DTOP_MODULATE :乗算
g_pD3DDevice->SetTextureStageState( //ここでポリゴンの色を2番目の対象にする
0,
D3DTSS_COLORARG2, //D3DTSS_COLORARG2 :2番目に対象となる色の引数
D3DTA_DIFFUSE); //D3DTA_DIFFUSE :ポリゴンを対象
//αブレンディング処理を行う
g_pD3DDevice->SetTextureStageState( //テクスチャの色を1番目の対象にする
0,
D3DTSS_COLORARG1,
D3DTA_TEXTURE);
g_pD3DDevice->SetTextureStageState( //色に対する処理を指定
0,
D3DTSS_COLOROP,
D3DTOP_BLENDTEXTUREALPHA); //D3DTOP_BLENDTEXTUREALPHA :あらかじめ乗算されたアルファを使用するテクスチャステージの線形ブレンディングを実行する
g_pD3DDevice->SetTextureStageState( //ポリゴンの色を2番目の対象にする
0,
D3DTSS_COLORARG2,
D3DTA_DIFFUSE);
g_pD3DDevice->SetTextureStageState( //ここでα値に対する処理を指定
0,
D3DTSS_ALPHAOP,
D3DTOP_SELECTARG2); //2番目の色はアルファ引数を変更せずに使用する
g_pD3DDevice->SetTextureStageState( //ポリゴンのα値を対象にする
0,
D3DTSS_ALPHAARG2, //2番目のα値を対象
D3DTA_DIFFUSE);
//ポリゴンとテクスチャの透明度の乗算処理
g_pD3DDevice->SetTextureStageState( //ここでテクスチャのα値を対象にする
0,
D3DTSS_ALPHAARG1, //D3DTSS_ALPHAARG1 :1番目に対象となるα値
D3DTA_TEXTURE);
g_pD3DDevice->SetTextureStageState( //ここでα値に対する処理を指定
0,
D3DTSS_ALPHAOP, //アルファブレンディング処理
D3DTOP_MODULATE);
g_pD3DDevice->SetTextureStageState( //ここでポリゴンのα値を対象にする
0,
D3DTSS_ALPHAARG1, //D3DTSS_ALPHAARG2 :2番目に対象となるα値
D3DTA_TEXTURE);
if (FAILED(InitPlayer(g_pD3D, g_pD3DDevice))) return E_FAIL; //Playerポリゴン初期化処理
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Direct3D終了処理関数】
//Direct3Dの終了処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void Uninit3D3(void)
{
if (g_pD3DDevice != NULL) {
g_pD3DDevice->Release();
g_pD3DDevice = NULL;
}
if (g_pD3D != NULL) {
g_pD3D->Release();
g_pD3D = NULL;
}
UninitPlayer(); //Playerポリゴン終了処理
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【更新処理関数】
//更新に関する処理を扱う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void Update(void)
{
UpdataPlayer(g_pD3DDevice); //Playerポリゴン更新処理
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【画面描写処理関数】
//ウィンドウの描写処理を扱う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void Draw(void)
{
//Clear関数で指定した色でクリアし、深度バッファをクリアする。更にステンシルバッファを削除する
g_pD3DDevice->Clear(
0, //クリアする矩形領域の数
NULL, //矩形領域
(D3DCLEAR_TARGET //レンタリングターゲットをクリアしてClearパラメータの色にする
| D3DCLEAR_ZBUFFER), //深海バッファをクリアしてZパラメータの値にする
D3DCOLOR_RGBA(0, 0, 0, 0), //透明度100%で指定した色にクリア
1.0f, //Zバッファのクリア値
0); //ステンシルバッファのクリア値
if (SUCCEEDED(g_pD3DDevice->BeginScene())) //バックバッファに描画開始
{
DrawPlayer(g_pD3DDevice); //Playerポリゴン描画処理
g_pD3DDevice->EndScene(); //バックバッファの描画終了
}
g_pD3DDevice->Present(NULL, NULL, NULL, NULL); //Present関数で画面に表示
}[/code]
Main.h
[code]//=============================================================================
//【Main.h】
//メインとなるヘッダー
//=============================================================================
#ifndef _MAIN_H_ //二重定義防止の為に行う
#define _MAIN_H_
//*****************************************************************************
//インクルード・ヘッダーファイル
//*****************************************************************************
#include <windows.h> //Windows標準関数実装
#include <d3d9.h> //Direct3D関連実装
#include <d3dx9.h> //Direct3D関連関数実装
//*****************************************************************************
//ライブラリのリンク
//*****************************************************************************
#pragma comment (lib, "dxguid.lib") //グローバルユニークIDに関わるライブラリ
#pragma comment (lib, "d3d9.lib") //Direct3Dコアライブラリ
#pragma comment (lib, "d3dx9.lib") //Direct3D拡張ライブラリ
#pragma comment (lib,"winmm.lib") //Windowsライブラリ
//*****************************************************************************
//マクロ定義
//*****************************************************************************
#define WINMODE TRUE //ウィンドウモードの指定
#define SCREEN_WIDTH (800) //ウィンドウの幅
#define SCREEN_HEIGHT (600) //ウインドウの高さ
#define SCREEN_CENTER_X (SCREEN_WIDTH/2) //ウィンドウの中心座標X
#define SCREEN_CENTER_Y (SCREEN_HEIGHT/2) //ウィンドウの中心座標Y
#define FPS (60) //1秒間に画面を更新する回数(フレーム/秒)
#define FRAME_DIRAY ((DWORD)(1000 / FPS)) //フレーム周期(1フレームあたりの最大処理時間)
#define NUM_VERTEX (4) //頂点の数
#define NUM_POLYGON (2) //ポリゴンの数
#define FVF_CUSTOM (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1) //頂点情報フラグ
//D3DFVF_XYZRHW :トランスフォームされた頂点の位置座標を含む頂点フォーマット
//D3DFVF_DIFFUSE:ディフューズ色成分を含む頂点フォーマット
//D3DFVF_TEX1 :テクスチャ座標の頂点フォーマット
//*****************************************************************************
//イーナム定義
//*****************************************************************************
//*****************************************************************************
//構造体定義
//*****************************************************************************
typedef struct CUSTOMVERTEX //2Dに必須なフォーマットをまとめた構造体の定義
{
D3DXVECTOR3 pos; //頂点座標
float rhw; //除算数
D3DCOLOR col; //頂点カラー
D3DXVECTOR2 tex; //テクスチャ座標
};
//*****************************************************************************
//プロトタイプ宣言
//*****************************************************************************
#endif[/code]
Player.cpp(今回の質問の箇所)
[code]//=============================================================================
//【Player.cpp】
//Playerポリゴンを管理する関数を扱うクラス
//=============================================================================
//*****************************************************************************
//インクルード・ヘッダーファイル
//*****************************************************************************
#include "Player.h"
//*****************************************************************************
//ライブラリのリンク
//*****************************************************************************
//*****************************************************************************
//マクロ定義
//*****************************************************************************
//#define PLAYER_TEXTURENAME "DATA/TEXTURE/Player.png" //テクスチャファイル名
#define PLAYER_INITPOS_X (SCREEN_CENTER_X) //初期位置X
#define PLAYER_INITPOS_Y (SCREEN_CENTER_Y) //初期位置Y
#define PLAYER_SIZE_X (50) //横幅
#define PLAYER_SIZE_Y (50) //横幅
//*****************************************************************************
//イーナム定義
//*****************************************************************************
//*****************************************************************************
//構造体定義
//*****************************************************************************
//*****************************************************************************
//プロトタイプ宣言
//*****************************************************************************
void MakeFormatPlayer(LPDIRECT3DDEVICE9 pDevice); //Playerポリゴンフォーマット情報作成関数
void MovePlayer(float, float, float); //Playerポリゴン移動関数
void ZoomPlayer(float, float, float); //Playerポリゴン拡大縮小関数
void RotationPlayer(float); //Playerポリゴン回転関数
//*****************************************************************************
//グローバル変数:
//*****************************************************************************
CUSTOMVERTEX g_pFormatPlayer[NUM_VERTEX]; //フォーマット情報格納用変数
LPDIRECT3DVERTEXBUFFER9 g_pVertexPlayer = NULL; //頂点バッファコンポーネントへのポインタ
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン初期化関数】
//Playerポリゴンの初期化処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HRESULT InitPlayer(
LPDIRECT3D9 pD3D, //Direct3Dへアクセスするためのポインタ
LPDIRECT3DDEVICE9 pDevice) //ビデオカードへアクセスするためのポインタ
{
//フォーマット情報を作成する
MakeFormatPlayer(pDevice);
//頂点バッファの作成をする
if (FAILED(pDevice->CreateVertexBuffer(
sizeof(CUSTOMVERTEX) * 4, //確保する頂点バッファのサイズ
D3DUSAGE_WRITEONLY, //リソースの使用法を定義するフラグ
FVF_CUSTOM, //頂点フォーマットの型の指定
D3DPOOL_MANAGED, //どの種類のメモリに頂点バッファを置くかの指定
&g_pVertexPlayer, //頂点バッファコンポーネントへのポインタのアドレス
NULL))) //特に使用されていない為NULL
{
pDevice->Release();
pD3D->Release();
return E_FAIL;
}
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン終了処理関数】
//Playerポリゴンの終了処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void UninitPlayer(void)
{
if (g_pVertexPlayer != NULL) {
g_pVertexPlayer->Release();
g_pVertexPlayer = NULL;
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン更新処理関数】
//Playeポリゴンrの更新処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void UpdataPlayer(LPDIRECT3DDEVICE9 pDevice)
{
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン描画処理関数】
//Playerポリゴンの描画処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void DrawPlayer(LPDIRECT3DDEVICE9 pDevice) //ビデオカードへアクセスするためのポインタ
{
//頂点バッファを書き込むためにメモリをロックする
void *pData;
if (SUCCEEDED(g_pVertexPlayer->Lock(
0, //全体にロックをするため0
sizeof(CUSTOMVERTEX) * 4, //ロックしたいメモリサイズ
(void**)&pData, //ロックされたメモリ範囲の先頭アドレスへのポインタ
0))) //ロック時の動作を定義するフラグ
{
memcpy(pData, g_pFormatPlayer, sizeof(CUSTOMVERTEX) * 4);
g_pVertexPlayer->Unlock();
}
//ストリームソースという頂点処理の流れに頂点バッファを実際にセットする
pDevice->SetStreamSource(
0, //ストリームの番号
g_pVertexPlayer, //頂点バッファコンポーネントへのポインタ
0, //頂点データの書き始めを示すオフセット
sizeof(CUSTOMVERTEX)); //1頂点のサイズ
//ストリームに頂点バッファの型を教える
pDevice->SetFVF(FVF_CUSTOM);
//頂点の結び方とポリゴンの描画枚数を指定
pDevice->DrawPrimitive(
D3DPT_TRIANGLESTRIP, //頂点をどう結びポリゴンにするかのフラグ
0, //描画を開始する最初の頂点番号
2); //描画するポリゴンの数
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴンフォーマット情報作成関数】
//Playerポリゴンのフォーマット情報作成処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void MakeFormatPlayer(LPDIRECT3DDEVICE9 pDevice) //ビデオカードへアクセスするためのポインタ
{
//頂点座標設定
g_pFormatPlayer[0].pos = //左上
D3DXVECTOR3(PLAYER_INITPOS_X - PLAYER_SIZE_X / 2, PLAYER_INITPOS_Y - PLAYER_SIZE_Y / 2, 0.0f);
g_pFormatPlayer[1].pos = //右上
D3DXVECTOR3(PLAYER_INITPOS_X + PLAYER_SIZE_X / 2, PLAYER_INITPOS_Y - PLAYER_SIZE_Y / 2, 0.0f);
g_pFormatPlayer[2].pos = //左下
D3DXVECTOR3(PLAYER_INITPOS_X - PLAYER_SIZE_X / 2, PLAYER_INITPOS_Y + PLAYER_SIZE_Y / 2, 0.0f);
g_pFormatPlayer[3].pos = //右下
D3DXVECTOR3(PLAYER_INITPOS_X + PLAYER_SIZE_X / 2, PLAYER_INITPOS_Y + PLAYER_SIZE_Y / 2, 0.0f);
//除算数設定
g_pFormatPlayer[0].rhw = 1.0f;
g_pFormatPlayer[1].rhw = 1.0f;
g_pFormatPlayer[2].rhw = 1.0f;
g_pFormatPlayer[3].rhw = 1.0f;
//頂点カラー設定
g_pFormatPlayer[0].col =
D3DCOLOR_RGBA(255, 255, 255, 255);
g_pFormatPlayer[1].col =
D3DCOLOR_RGBA(255, 255, 255, 255);
g_pFormatPlayer[2].col =
D3DCOLOR_RGBA(255, 255, 255, 255);
g_pFormatPlayer[3].col =
D3DCOLOR_RGBA(255, 255, 255, 255);
//テクスチャ座標設定
g_pFormatPlayer[0].tex =
D3DXVECTOR2(0.0f, 0.0f); //左上
g_pFormatPlayer[1].tex =
D3DXVECTOR2(1.0f, 0.0f); //右上
g_pFormatPlayer[2].tex =
D3DXVECTOR2(0.0f, 1.0f); //左下
g_pFormatPlayer[3].tex =
D3DXVECTOR2(1.0f, 1.0f); //右下
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン移動関数】
//Playerポリゴンの移動処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void MovePlayer(
float x, //移動距離X
float y, //移動距離Y
float z) //移動距離Z
{
D3DXMATRIX PosMatrix; //Playerポリゴンの現在位置格納用単位行列
D3DXMATRIX MoveMatrix; //Playerポリゴンの移動量格納用単位行列
//行列初期化
D3DXMatrixIdentity(&PosMatrix);
D3DXMatrixIdentity(&MoveMatrix);
//移動処理
D3DXMatrixTranslation( //D3DXMatrixTranslation関数を使用してMoveMatrixに移動量を格納する
&MoveMatrix,
x,
y,
z);
for (int i = 0; i < NUM_VERTEX; i++) {
D3DXMatrixTranslation( //D3DXMatrixTranslation関数を使用してPosMatrixに現在地を格納する
&PosMatrix,
g_pFormatPlayer[i].pos.x,
g_pFormatPlayer[i].pos.y,
g_pFormatPlayer[i].pos.z);
PosMatrix *= MoveMatrix; //現在地の行列に移動量行列を加算する
g_pFormatPlayer[i].pos.x = PosMatrix._41; //演算結果をポリゴンのX座標に格納する
g_pFormatPlayer[i].pos.y = PosMatrix._42; //演算結果をポリゴンのY座標に格納する
g_pFormatPlayer[i].pos.z = PosMatrix._43; //演算結果をポリゴンのZ座標に格納する
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン拡大縮小関数】
//Playerポリゴンの拡大処理と縮小処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void ZoomPlayer(float x, float y, float z)
{
D3DXMATRIX PosMatrix; //Playerポリゴンの現在位置格納用単位行列
D3DXMATRIX ZoomMatrix; //Playerポリゴンの拡張量格納用単位行列
//行列初期化
D3DXMatrixIdentity(&PosMatrix);
D3DXMatrixIdentity(&ZoomMatrix);
//拡大縮小処理
D3DXMatrixScaling( //D3DXMatrixScaling関数を使用してZoomMatrixに拡張量を格納する
&ZoomMatrix,
x,
y,
z);
for (int i = 0; i < NUM_VERTEX; i++) {
D3DXMatrixTranslation( //D3DXMatrixTranslation関数を使用してPosMatrixに現在地を格納する
&PosMatrix,
g_pFormatPlayer[i].pos.x,
g_pFormatPlayer[i].pos.y,
g_pFormatPlayer[i].pos.z);
PosMatrix *= ZoomMatrix; //現在地の行列に拡張量行列を加算する
g_pFormatPlayer[i].pos.x = PosMatrix._41; //演算結果をポリゴンのX座標に格納する
g_pFormatPlayer[i].pos.y = PosMatrix._42; //演算結果をポリゴンのY座標に格納する
g_pFormatPlayer[i].pos.z = PosMatrix._43; //演算結果をポリゴンのZ座標に格納する
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン回転関数】
//Playerポリゴンの回転処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void RotationPlayer(float angle)
{
D3DXMATRIX PosMatrix; //Playerポリゴンの現在位置格納用単位行列
D3DXMATRIX RotationMatrix; //Playerポリゴンの回転量格納用単位行列
//行列初期化
D3DXMatrixIdentity(&PosMatrix);
D3DXMatrixIdentity(&RotationMatrix);
//拡大縮小処理
D3DXMatrixRotationZ( //D3DXMatrixRotationZ関数を使用してRotationMatrixに回転量を格納する
&RotationMatrix,
D3DXToRadian(angle));
for (int i = 0; i < NUM_VERTEX; i++) {
D3DXMatrixTranslation( //D3DXMatrixTranslation関数を使用してPosMatrixに現在地を格納する
&PosMatrix,
g_pFormatPlayer[i].pos.x,
g_pFormatPlayer[i].pos.y,
g_pFormatPlayer[i].pos.z);
PosMatrix *= RotationMatrix; //現在地の行列に回転量行列を加算する
g_pFormatPlayer[i].pos.x = PosMatrix._41; //演算結果をポリゴンのX座標に格納する
g_pFormatPlayer[i].pos.y = PosMatrix._42; //演算結果をポリゴンのY座標に格納する
g_pFormatPlayer[i].pos.z = PosMatrix._43; //演算結果をポリゴンのZ座標に格納する
}
}
[/code]
Player.h
[code]//=============================================================================
//【Player.h】
//Playerポリゴン用ヘッダー
//=============================================================================
#ifndef _Player_H_ //二重定義防止の為に行う
#define _Player_H_
//*****************************************************************************
//インクルード・ヘッダーファイル
//*****************************************************************************
#include "Main.h"
//*****************************************************************************
//ライブラリのリンク
//*****************************************************************************
//*****************************************************************************
//マクロ定義
//*****************************************************************************
//*****************************************************************************
//イーナム定義
//*****************************************************************************
//*****************************************************************************
//構造体定義
//*****************************************************************************
//*****************************************************************************
//プロトタイプ宣言
//*****************************************************************************
HRESULT InitPlayer(LPDIRECT3D9, LPDIRECT3DDEVICE9); //Playerポリゴン初期化処理関数
void UninitPlayer(void); //Playerポリゴン終了処理関数
void UpdataPlayer(LPDIRECT3DDEVICE9 pDevic); //Playerポリゴン更新処理関数
void DrawPlayer(LPDIRECT3DDEVICE9 pDevice); //Player描画処理関数
#endif[/code]
[1.3] どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)
[align=center]実行できている為割愛。[/align]
[1.4] 今何がわからないのか、知りたいのか
[align=center]板ポリゴンの中心を軸に位置が変わらなず回転・拡大縮小を行いたい。[/align]
[2] 環境
[2.1] OS:Windows10
[2.2] コンパイラ名: Visual C++ 2017
[3] その他
・C、DirectX共に半年触ったか触っていないか程度。現在きちんと講習を受けている最中。
正し軽い基礎はjavaを1年独学でやっていた。