前提・実現したいこと
C++でDirectX9を使ってD&Dした画像をどんどん表示していくシステムを作っています。
D3DXCreateTextureFromFile()で画像を読み込み、SetTexture()、SetFVF()、DrawPrimitiveUP()で表示する
というクラスを作り、それをstd::vectorを使ってD&Dされる度にemplace_back()で増やしています。
発生している問題・エラーメッセージ
一回目は通るのですが、二回目、三回目のD&Dでこういったエラーがでます。
プロジェクト名.exe の 0x67abcdd7 で初回の例外が発生しました: 0xC0000005: 場所 0x0000000c を読み込み中にアクセス違反が発生しました。 プロジェクト名.exe の 0x67abcdd7 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x0000000c を読み込み中にアクセス違反が発生しました。
おかしな番地を示しているのはわかりますが、なぜなのか全くわかりません。
それと0x67abcdd7が何かわかりませんが、プログラムはここで中断されているみたいです。
pDevice3D->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,vtx,sizeof(Vertex));
該当のソースコード
C++
1#include <Windows.h> 2 3#include <vector> 4 5#define D3D_DEBUG_INFO // Direct3Dデバックフラグ 6 7#pragma comment(lib, "d3d9.lib") 8#pragma comment(lib, "d3dx9.lib") 9#include <d3dx9.h> 10#include <d3dx9tex.h> 11 12 13// Direct3Dクラス 14class Direct3D 15{ 16public: 17 IDirect3D9* pD3D9; // Direct3Dデバイス生成用オブジェクト 18 IDirect3DDevice9* pDevice3D; // Direct3Dのデバイス 19 20 // コンストラクタ 21 Direct3D(); 22 // デストラクタ 23 ~Direct3D(); 24 25 // デバイス作成 26 bool Create(HWND hWnd,int Width,int Height); 27}; 28 29// テクスチャクラス 30class Image{ 31public: //変数 32 IDirect3DDevice9* pDevice3D; 33 IDirect3DTexture9* pTexture; 34 D3DXIMAGE_INFO pSrcInfo; 35 36 // 板ポリゴン頂点情報 37 struct Vertex{ 38 float x,y,z;// 3次元座標 39 float rhw; // 2D変換済みフラグ 40 float u,v; // UV座標 41 }; 42 // FVF(柔軟な頂点構造体宣言)フラグ 43 static const DWORD SPRITE_FVF = D3DFVF_XYZRHW | D3DFVF_TEX1; 44 45 // スプライト位置 46 D3DXVECTOR2 pos; 47 // スプライトサイズ 48 int width; 49 int height; 50 51public: //関数 52 // コンストラクタ 53 Image(IDirect3DDevice9*); 54 // デストラクタ 55 ~Image(); 56 // 画像データ読み込み 57 bool Load(TCHAR* FileName); 58 59 void SetPos(float x,float y); 60 void SetWidth(int Width,int Height); 61 void Draw(IDirect3DTexture9* pTexture); 62 63}; 64 65// コンストラクタ 66Direct3D::Direct3D(){ 67 pD3D9 = NULL; // Direct3Dデバイス生成用オブジェクト 68 pDevice3D = NULL; // Direct3Dのデバイス 69} 70// デストラクタ 71Direct3D::~Direct3D(){ 72 // DirectXの変数は必ず後処理をすること 73 if(pDevice3D != NULL) 74 pDevice3D->Release(); 75 if(pD3D9 != NULL) 76 pD3D9->Release(); 77} 78 79// デバイス作成 80bool Direct3D::Create(HWND hWnd,int Width,int Height){ 81 82 // Direct3D9オブジェクトの作成 83 pD3D9 = Direct3DCreate9(D3D_SDK_VERSION); 84 // ディスプレイ情報取得 85 D3DDISPLAYMODE Display; 86 pD3D9->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &Display); 87 88 D3DPRESENT_PARAMETERS D3DParam = { // スワップチェイン設定 89 Width,Height,Display.Format,1,D3DMULTISAMPLE_NONE,0, 90 D3DSWAPEFFECT_DISCARD,hWnd,TRUE,TRUE,D3DFMT_D24S8,0,0,D3DPRESENT_INTERVAL_DEFAULT 91 }; 92 93 // HALモードで3Dデバイス作成 94 if (FAILED(pD3D9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, D3DParam.hDeviceWindow, 95 D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &D3DParam, &pDevice3D))) 96 if (FAILED(pD3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DParam.hDeviceWindow, 97 D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &D3DParam, &pDevice3D))) 98 // REFモードで3Dデバイス作成 99 if (FAILED(pD3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, D3DParam.hDeviceWindow, 100 D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &D3DParam, &pDevice3D))) 101 if (FAILED(pD3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, D3DParam.hDeviceWindow, 102 D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &D3DParam, &pDevice3D))) 103 { 104 // 3Dデバイス作成失敗(このグラフィックボードではDirectXが使えない) 105 pD3D9->Release(); 106 return false; 107 } 108 109 return true; 110} 111 112Image::Image(IDirect3DDevice9* pd3d){ 113 pDevice3D = pd3d; 114 pTexture = NULL; 115 116 pos.x = pos.y = 0.0f; 117 width = height = 0; 118} 119Image::~Image() 120{ 121 // 読み込まれていたら破棄 122 if(pTexture != NULL) 123 pTexture->Release(); 124} 125bool Image::Load(TCHAR* FileName) 126{ 127 //画像サイズを取得 128 D3DXGetImageInfoFromFile(FileName,&pSrcInfo); 129 width = pSrcInfo.Width; 130 height = pSrcInfo.Height; 131 132 // 画像読み込み 133 // DirextXやWindowsAPIの関数はHRESULTを結果に返す関数が多い 134 // FAILEDマクロで関数が失敗したかわかる 135 // SUCEEDEDマクロで関数が成功したかわかる 136 if(FAILED(D3DXCreateTextureFromFile(pDevice3D,FileName,&pTexture))) 137 return false; // 画像読み込み失敗(ファイルがない可能性あり) 138 139 // 画像読み込み成功 140 return true; 141} 142 143void Image::SetPos(float x,float y) 144{ 145 pos.x = x; 146 pos.y = y; 147} 148void Image::SetWidth(int Width,int Height) 149{ 150 width = Width; 151 height = Height; 152} 153 154void Image::Draw(IDirect3DTexture9* pTexture) 155{ 156 // 頂点情報セット 157 Vertex vtx[4]={ 158 { pos.x + width/2, pos.y - height/2, 0.0f, 1.0f, 1.0f, 0.0f}, 159 { pos.x + width/2, pos.y + height/2, 0.0f, 1.0f, 1.0f, 1.0f}, 160 { pos.x - width/2, pos.y - height/2, 0.0f, 1.0f, 0.0f, 0.0f}, 161 { pos.x - width/2, pos.y + height/2, 0.0f, 1.0f, 0.0f, 1.0f} 162 }; 163 164 // テクスチャセット 165 pDevice3D->SetTexture(0,pTexture); 166 // 頂点構造体宣言セット 167 pDevice3D->SetFVF(SPRITE_FVF); 168 **// スプライト描画 169 pDevice3D->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,vtx,sizeof(Vertex));** 170} 171 172// Direct3Dの初期化 173Direct3D direct3d; 174 175//Imageオブジェクト作成 176std::vector<Image> image; 177 178// ウィンドウプロシージャ、ウィンドウに対するメッセージ処理を行う 179LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ 180 TCHAR lpszFile[MAX_PATH]; 181 HDROP hDrop = (HDROP)wParam; 182 RECT rect; 183 GetWindowRect(hwnd, (LPRECT)&rect); 184 185 switch(msg){ 186 case WM_DROPFILES: //ファイルがドロップされたとき 187 DragQueryFile(hDrop,0,lpszFile,MAX_PATH); 188 189 **image.emplace_back(direct3d.pDevice3D); 190 image.back().Load(lpszFile);** 191 image.back().SetPos((rect.right - rect.left)/2.0f,(rect.bottom - rect.top)/2.0f); 192 break; 193 case WM_DESTROY: // ウィンドウが破棄されたとき 194 PostQuitMessage(0); // WM_QUITメッセージをメッセージキューに送る 195 return 0; 196 } 197 198 // デフォルトのメッセージ処理を行う 199 return DefWindowProc(hwnd, msg, wParam, lParam); 200} 201 202// WinMain関数(アプリケーションの開始関数) 203// コンソールアプリケーションと違い、コンソールを開かない 204int _stdcall WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){ 205 const TCHAR CLASS_NAME[] = TEXT("WindowClass"); 206 207 // シンプルウィンドウクラス設定 208 WNDCLASSEX wcex ={sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,WndProc, 0,0,hInstance, 209 (HICON)LoadImage(NULL,MAKEINTRESOURCE(IDI_APPLICATION),IMAGE_ICON,0,0,LR_DEFAULTSIZE | LR_SHARED), 210 (HCURSOR)LoadImage(NULL,MAKEINTRESOURCE(IDC_ARROW),IMAGE_CURSOR,0,0,LR_DEFAULTSIZE | LR_SHARED), 211 (HBRUSH)GetStockObject(WHITE_BRUSH), NULL, CLASS_NAME , NULL}; 212 213 // シンプルウィンドウクラス作成 214 if(!RegisterClassEx(&wcex)) 215 return false; 216 217 const int WINDOW_WIDTH = 1920; 218 const int WINDOW_HEIGHT = 1080; 219 220 // ウィンドウの作成 221 HWND hwnd = CreateWindowEx(WS_EX_ACCEPTFILES,CLASS_NAME, 222 TEXT("Application"), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE | WS_MAXIMIZE, 223 CW_USEDEFAULT,CW_USEDEFAULT,WINDOW_WIDTH,WINDOW_HEIGHT,NULL,NULL,hInstance,NULL); 224 225 if(hwnd == NULL) return 0; 226 227 direct3d.Create(hwnd,WINDOW_WIDTH,WINDOW_HEIGHT); 228 229 // メッセージループ 230 MSG msg = {}; 231 while(msg.message != WM_QUIT) { 232 // アプリケーションに送られてくるメッセージをメッセージキューから取得する 233 if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){ 234 DispatchMessage(&msg); // アプリケーションの各ウィンドウプロシージャにメッセージを転送する 235 } 236 // メッセージ処理をしていないとき 237 else{ 238 // 描画開始 239 if(SUCCEEDED(direct3d.pDevice3D->BeginScene())) 240 { 241 DWORD ClearColor = 0xff808080; // 背景クリア色 242 // 背景クリア 243 direct3d.pDevice3D->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, ClearColor, 1.0f, 0 ); 244 245 **for(unsigned int i=0;i<image.size();i++) 246 image[i].Draw(image[i].pTexture);** 247 248 // 描画終了 249 direct3d.pDevice3D->EndScene(); 250 } 251 // 描画反映 252 direct3d.pDevice3D->Present( NULL, NULL, NULL, NULL ); 253 } 254 } 255 256 return 0; 257}
補足情報
Microsoft Visual C++ 2010 Express
Windows SDK v6.0A
DirectX SDK (June 2010)
あなたの回答
tips
プレビュー