C++,DirextXで、バグの原因がわからない(><)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
食虫飲食物
記事: 1
登録日時: 10年前

C++,DirextXで、バグの原因がわからない(><)

#1

投稿記事 by 食虫飲食物 » 10年前

現在、C++とDirectXを使ってゲームを作っているのですが、一週間ほど前に発生したバグの原因が未だに分からず大変苦戦しております。
原因を見つけていただけるとありがたいです。

バグの内容は次のようなものです。
①画像の描画が正しく行われない。
②描画する関数の直前にOutputDebugStringA( );などを入れるだけで正しく描画される。
③直接描画に関係ないはずのコードを書き換えるだけでも、なぜか描画が行われる。
④バグ発生時の挙動は様々で、マウスの位置によって描画が行われたり行われなかったりする、何をしても描画されないなど様々です。

おそらくポインタ系のバグであるとは思うのですが、どうにも原因を見つけることができません。以下が問題のコード(原因がどこにあるか予想もつかないので全体を貼ります。できるだけ縮めてあります)ですので、どうかよろしくお願いいたします。

コード:

//////////////////////////////////////////////////
//Game.h
/////////////////////////////////////////////////
#pragma once

class Game
{
public:
Game(void);
~Game(void);
};

コード:

//////////////////////////////////////////////////
//Game.cpp
/////////////////////////////////////////////////
#include "Game.h"
#include <tchar.h>
#include "RootMain.h"

#define _CRTDBG_MAP_ALLOC


// プロトタイプ宣言
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);
RootMain *rootMain;



int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int showCmd)
{
WNDCLASSEX wc;
HWND hWnd;
MSG msg;

// ウィンドウクラスの情報を設定
wc.cbSize = sizeof(wc); // 構造体サイズ
wc.style = CS_HREDRAW | CS_VREDRAW; // スタイル
wc.lpfnWndProc = WndProc; // ウィンドウプロシージャ
wc.cbClsExtra = 0; // 拡張情報1
wc.cbWndExtra = 0; // 拡張情報2
wc.hInstance = hInst; // インスタンスハンドル
wc.hIcon = (HICON)LoadImage( // アイコン
NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON,
0, 0, LR_DEFAULTSIZE | LR_SHARED
);
wc.hIconSm = wc.hIcon; // 子アイコン
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 = _T("Default Class Name");// ウィンドウクラス名


// ウィンドウクラスを登録する
if( RegisterClassEx( &wc ) == 0 ){ return 1; }

// ウィンドウを作成する
hWnd = CreateWindow(
wc.lpszClassName, // ウィンドウクラス名
_T("Game"), // タイトルバーに表示する文字列
WS_OVERLAPPEDWINDOW, // ウィンドウの種類
CW_USEDEFAULT, // ウィンドウを表示する位置(X座標)
CW_USEDEFAULT, // ウィンドウを表示する位置(Y座標)
1000, // ウィンドウの幅
1000, // ウィンドウの高さ
NULL, // 親ウィンドウのウィンドウハンドル
NULL, // メニューハンドル
hInst, // インスタンスハンドル
NULL // その他の作成データ
);
if( hWnd == NULL ){ return 1; }

// ウィンドウを表示する
ShowWindow( hWnd, SW_SHOW );
UpdateWindow( hWnd );



//ルートメインを生成
rootMain=new RootMain(hInst,hWnd);
// メッセージループ
while( 1 )
{


BOOL ret =PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
if (msg.message==VK_ESCAPE)
{
break;
}
if( msg.message==WM_QUIT||ret == -1 )
{
// アプリケーションを終了させるメッセージが来ていたら、
// あるいは GetMessage() が失敗したら( -1 が返されたら )、ループを抜ける
break;
}
else
{


// メッセージを処理する
TranslateMessage( &msg );
DispatchMessage( &msg );
}

// アプリケーションの終了操作


//ここはウィンドウが表示されている間ループし続ける
rootMain->rootMainProcess();
//ここはウィンドウが表示されている間ループし続ける


}
//おそらくhWndがウィンドウを表している。
//_CrtDumpMemoryLeaks();
return 0;
}

// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{

switch( msg )
{
case WM_DESTROY: // ウィンドウを破棄するとき
PostQuitMessage( 0 );
return 0;


}

if(wp==VK_ESCAPE){
PostQuitMessage( 0 );
return 0;
}

// 他のメッセージは、デフォルトの処理を行う
return DefWindowProc( hWnd, msg, wp, lp );
}

コード:

//////////////////////////////////////////////////
//RootMain.h
/////////////////////////////////////////////////
#pragma once
#include < d3d9.h >
#include "NBCommon.h"
#include "PanelCreatePanel.h"
#include "MovePanel.h"
class RootMain
{


public:
RootMain(HINSTANCE,HWND);
~RootMain(void);
void rootMainProcess();

private:
PanelCreatePanel* pcp;
MovePanel* mp;
};

コード:

//////////////////////////////////////////////////
//RootMain.cpp
/////////////////////////////////////////////////
#include "RootMain.h"
#include <stdio.h>

RootMain::RootMain(HINSTANCE myHinst,HWND hWnd)
{
NBCommon::NBCommon(myHinst,hWnd);
pcp=new PanelCreatePanel();
mp=new MovePanel();
}

RootMain::~RootMain(void)
{
}

void RootMain::rootMainProcess(){
NBCommon::device->BeginScene();
NBCommon::device->Clear(0, NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_ARGB(200,200,200,200), 1.0f, 0);
//ここからメイン処理
pcp->PanelAction();
mp->PanelAction();
//ここまでメイン処理
NBCommon::device->EndScene();
NBCommon::device->Present(NULL, NULL,NULL, NULL);
}

コード:

//////////////////////////////////////////////////
//XBase.h
/////////////////////////////////////////////////
#pragma once
#include < d3d9.h >

class XBase
{
public:
HWND hWnd;
XBase(HWND);
~XBase(void);
LPDIRECT3D9 pD3d;
LPDIRECT3DDEVICE9 pDevice;
LPDIRECT3DDEVICE9 getDevice();
};

コード:

//////////////////////////////////////////////////
//XBase.cpp
/////////////////////////////////////////////////
#include "XBase.h"

XBase::XBase(HWND myHWnd)
{
hWnd=myHWnd;
}

XBase::~XBase(void)
{
}

LPDIRECT3DDEVICE9 XBase::getDevice(){
///////////////////////////////////
// Direct3Dの初期化
////////////////////////////////////
IDirect3D9* pD3D9 = NULL; // Direct3Dデバイス生成用オブジェクト
IDirect3DDevice9* pDevice3D = NULL; // Direct3Dのデバイス


// Direct3D9オブジェクトの作成
pD3D9 = Direct3DCreate9(D3D_SDK_VERSION);
// ディスプレイ情報取得
D3DDISPLAYMODE Display;
pD3D9->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &Display);

D3DPRESENT_PARAMETERS D3DParam = { // スワップチェイン設定
1000,1000,Display.Format,1,D3DMULTISAMPLE_NONE,0,
D3DSWAPEFFECT_DISCARD,hWnd,TRUE,TRUE,D3DFMT_D24S8,0,0,D3DPRESENT_INTERVAL_DEFAULT
};

// HALモードで3Dデバイス作成
if (FAILED(pD3D9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, D3DParam.hDeviceWindow,
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &D3DParam, &pDevice3D)))
if (FAILED(pD3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DParam.hDeviceWindow,
D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &D3DParam, &pDevice3D)))
// REFモードで3Dデバイス作成
if (FAILED(pD3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, D3DParam.hDeviceWindow,
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &D3DParam, &pDevice3D)))
if (FAILED(pD3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, D3DParam.hDeviceWindow,
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &D3DParam, &pDevice3D)))
{
// 3Dデバイス作成失敗(このグラフィックボードではDirectXが使えない)
pD3D9->Release();
}

return pDevice3D;
}

コード:

//////////////////////////////////////////////////
//NBCommon.h
/////////////////////////////////////////////////
#pragma once
#include < d3d9.h >
#include "XBase.h"
#include "PanelLibrary.h"


/**
複数のクラスで共通して使う変数をまとめたクラス。このクラスのメンバにはstatic参照できる。

*/
class NBCommon
{
public :
NBCommon(HINSTANCE myHinst,HWND myHWnd);
~NBCommon(void);

static HINSTANCE hinst;//WinAPIのHINSTANCE。
static HWND hWnd;//ウィンドウのハンドル。WinApiに与えられたもの。
static LPDIRECT3DDEVICE9 device;//DirectXのデバイス


};

コード:

//////////////////////////////////////////////////
//NBCommon.cpp
/////////////////////////////////////////////////
#include "NBCommon.h"

NBCommon::NBCommon(HINSTANCE myHinst,HWND myHWnd)
{
hinst=myHinst;
hWnd=myHWnd;
device=NULL;
XBase* xBase=new XBase(hWnd);
device=xBase->getDevice();
}

NBCommon::~NBCommon(void)
{
}

HINSTANCE NBCommon::hinst;//WinAPIのHINSTANCE。
HWND NBCommon::hWnd;//ウィンドウのハンドル。WinApiに与えられたもの。
LPDIRECT3DDEVICE9 NBCommon::device;//DirectXのデバイス

コード:

//////////////////////////////////////////////////
//XDraw.h
/////////////////////////////////////////////////
#pragma once
#include < d3d9.h >
#include "NBCommon.h"
#include < d3dx9.h >
class XDraw
{
public:

XDraw();
~XDraw(void);
LPDIRECT3DTEXTURE9 LoadTexture(char* Adress);
void drawTexture(LPDIRECT3DTEXTURE9 texture,float x,float y,float width,float height,float alpha);
LPD3DXSPRITE sprite;
HRESULT hr;
};

コード:

//////////////////////////////////////////////////
//XDraw.cpp
/////////////////////////////////////////////////
#include "XDraw.h"
#include <stdio.h>

XDraw::XDraw()
{
sprite=NULL;//スプライト。スプライトとは画面上に張り付く透明な板のこと。これにテクスチャを貼り付けて描画する。
D3DXCreateSprite(NBCommon::device,&sprite);
}

XDraw::~XDraw(void)
{
}

/**
実行ファイルのあるフォルダからの相対パスを指定して画像をロード。テクスチャ型の戻り値を返す。
*/
LPDIRECT3DTEXTURE9 XDraw::LoadTexture(char* Adress){
LPDIRECT3DTEXTURE9 texture=NULL;
D3DXCreateTextureFromFile( NBCommon::device , Adress , &texture );
return texture;
}

void XDraw::drawTexture(LPDIRECT3DTEXTURE9 texture,float x,float y,float width,float height,float alpha){
D3DXMATRIX Mat;
	
	//テクスチャの幅と高さを取得
	UINT texWidth=0;
	UINT texHeight=0;
	texture->GetLevelDesc(0,&desc);
	texWidth=desc.Width;
	texHeight=desc.Height;
	//テクスチャの幅と高さを取得	
	///////////////////テクスチャを描画
	sprite->Begin( NULL);
	D3DXVECTOR3 center , position;

	D3DXVECTOR2 pos2D; // 拡大
	D3DXVECTOR2 scale; // 拡大

	scale.x=width/texWidth;
	scale.y=height/texHeight;
	position.x = x;
	position.y = y;
	pos2D.x=position.x;
	pos2D.y=position.y;
	D3DXMatrixTransformation2D(&Mat,&pos2D , 0, &scale, NULL, 0, NULL);//第二項は拡大の基準。NULLだと、0,0になってしまうので、画像の左上座標を入れている。
	sprite->SetTransform(&Mat);

	D3DCOLOR color=D3DCOLOR_RGBA(0xff,0xff,0xff,(int)(alpha*255));
	sprite->Draw( texture , NULL ,NULL , &position ,color );
	sprite->End();		
}

コード:

//////////////////////////////////////////////////
//PanelCreatePanel.h
/////////////////////////////////////////////////
#pragma once
#include "Panel.h"
#include <d3d9.h>
#include "XDraw.h"
class PanelCreatePanel:public Panel
{
public:
PanelCreatePanel();
~PanelCreatePanel(void);
void PanelAction();

private:
XDraw* xDraw;
LPDIRECT3DTEXTURE9 textrue;
};

コード:

//////////////////////////////////////////////////
//PanelCreatePanel.cpp
/////////////////////////////////////////////////
#include "PanelCreatePanel.h"
#include <stdio.h>

PanelCreatePanel::PanelCreatePanel()
{
xDraw=new XDraw();
textrue=xDraw->LoadTexture("xFiles/緑のテクスチャー.png");
}


PanelCreatePanel::~PanelCreatePanel(void)
{
}

void PanelCreatePanel::PanelAction(void)
{
/*ここのコメントアウトを外すと正常に画像が表示される。
char str[500];
sprintf(str,"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas");
OutputDebugStringA( str );
*/
//ここから描画
xDraw->drawTexture(textrue,300,100,200,200,0.3f);
//ここまで描画

}

コード:

//////////////////////////////////////////////////
//MovePanel.h
/////////////////////////////////////////////////
#pragma once
#include "Panel.h"
#include <d3d9.h>
#include "XDraw.h"
class MovePanel:public Panel
{
public:
MovePanel();
~MovePanel(void);

void PanelAction();

private:
XDraw* xDraw;
LPDIRECT3DTEXTURE9 textrue;
};

コード:

//////////////////////////////////////////////////
//MovePanel.cpp
/////////////////////////////////////////////////
#include "MovePanel.h"
#include <stdio.h>

MovePanel::MovePanel()
{
xDraw=new XDraw();
textrue=xDraw->LoadTexture("xFiles/移動パネル.png");
}


MovePanel::~MovePanel(void)
{
}

void MovePanel::PanelAction(void)
{
/*ここのコメントアウトを外すと正常に画像が表示される。
char str[500];
sprintf(str,"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas");
OutputDebugStringA( str );
*/

xDraw->drawTexture(textrue,100,100,200,200,0.3f);
}

“C言語何でも質問掲示板” へ戻る