-2

DIrectX9を使用して小さなゲームをプログラミングしているときに、いくつか問題が発生しました。未処理の例外が発生し、多くの試行で修正できないようです。この問題についての洞察をいただければ幸いです。デバッガーを使用しましたが、例外を修正する方法がわかりません。

出力:AACF.exeの0x00061afdで未処理の例外:0xC0000005:アクセス違反の読み取り場所0x00000000。

「データ」構造のデータはすべて0x00000000に等しいようです。これをどのように修正しますか?

例外はSystem.cppにコメントされています。

例外ロケーションファイル:

// System.cpp //

#include "Core.h"

struct {
    LPDIRECT3D9 D3D;
    LPDIRECT3DDEVICE9 D3DDEV;
    LPD3DXSPRITE D3DSPT;
    LPD3DXFONT DXFONT;
    LPDIRECT3DTEXTURE9 DisplayTexture;
} Data;

void System::InitD3D(bool Windowed, int ScreenW, int ScreenH) {
    Data.D3D = Direct3DCreate9(D3D_SDK_VERSION);
    D3DPRESENT_PARAMETERS D3DPP;

    ZeroMemory(&D3DPP, sizeof(D3DPP));
    D3DPP.Windowed = Windowed;
    D3DPP.SwapEffect = D3DSWAPEFFECT_DISCARD;
    D3DPP.hDeviceWindow = hWnd;
    D3DPP.BackBufferFormat = D3DFMT_X8R8G8B8;
    D3DPP.BackBufferWidth = ScreenW;
    D3DPP.BackBufferHeight = ScreenH;
    D3DPP.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    Data.D3D->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hWnd,
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &D3DPP,
                      &Data.D3DDEV);
    D3DXCreateSprite(Data.D3DDEV, &Data.D3DSPT);

    Load_Display();

    return;
}

void System::Render_Frame(void) {
    // EXCEPTIONS START HERE
    // Data.D3DDEV->Clear gives an exception
    Data.D3DDEV->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0F, 0); // Exception line
    Data.D3DDEV->BeginScene();
    Data.D3DSPT->Begin(D3DXSPRITE_ALPHABLEND);

    Draw_Display();

    Data.D3DSPT->End();
    Data.D3DDEV->EndScene();
    Data.D3DDEV->Present(NULL, NULL, NULL, NULL);
    return;
}

void System::CleanD3D() {
    Data.DisplayTexture->Release();
    Data.D3DDEV->Release();
    Data.D3D->Release();
    return;
}

void System::Load_Display() {
    LoadTexture(&Data.DisplayTexture, L"DisplaySprites.png");
    D3DXCreateFont(Data.D3DDEV, 20, 0, FW_BOLD, 1, false, DEFAULT_CHARSET,
                   OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
                   L"Arial", &Data.DXFONT);
    return;
}

void System::Draw_Display() {
    return;
}

void System::LoadTexture(LPDIRECT3DTEXTURE9* Texture, LPCTSTR FileName) {
    D3DXCreateTextureFromFileEx(Data.D3DDEV, FileName, D3DX_DEFAULT, D3DX_DEFAULT,
                                D3DX_DEFAULT, NULL, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT,
                                D3DX_DEFAULT, D3DCOLOR_XRGB(255, 0, 255), NULL, NULL, Texture);
    return;
}

void System::DrawTexture(LPDIRECT3DTEXTURE9 Texture, RECT TexCoords, float X, float Y, int A) {
    D3DXVECTOR3 Center(0.0F, 0.0F, 0.0F), Position(X, Y, 0.0F);
    Data.D3DSPT->Draw(Texture, &TexCoords, &Center, &Position, D3DCOLOR_ARGB(A,255,255,255));
    return;
}

void System::DrawString(const char* Text, int Count, RECT Rect, float X, float Y, int A, int R, int G, int B) {
    SetRect(&Rect, 0, 0, (int)X, (int)Y);
    Data.DXFONT->DrawTextA(NULL,
                      Text,
                      Count,
                      &Rect,
                      DT_BOTTOM | DT_RIGHT,
                      D3DCOLOR_ARGB(A, R, G, B));
}

void System::DrawNumber(int SetValue, RECT Rect, float X, float Y, int A, int R, int G, int B) {
    SetRect(&Rect, 0, 0, (int)X, (int)Y);
    static char Number[10];
    _itoa_s(SetValue, Number, 10);
    Data.DXFONT->DrawTextA(NULL,
                       (LPCSTR)&Number,
                       strlen((LPCSTR)&Number),
                       &Rect,
                       DT_BOTTOM | DT_RIGHT,
                       D3DCOLOR_ARGB(A, R, G, B));
}

System.cppヘッダー:

// System.h //

// Include Guard //
#ifndef _SYSTEM_H
#define _SYSTEM_H

#include "Core.h"

// Globalizing Data Structure
struct Data;

// Define screen resolution and keyboard macros
#define SCREEN_WIDTH    (1000)
#define SCREEN_HEIGHT   (700)
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

// WinProc ProtoType
LRESULT CALLBACK WindowProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);

class System {
private:
    HWND hWnd;
public:
    System() {};
    void InitD3D(bool Windowed, int ScreenW, int ScreenH);
    void Render_Frame(void);
    void CleanD3D(void);
    void Load_Display();
    void Draw_Display();
    void LoadTexture(LPDIRECT3DTEXTURE9* Texture, LPCTSTR FileName);
    void DrawTexture(LPDIRECT3DTEXTURE9 Texture, RECT TexCoords, float X, float Y, int A);
    void DrawString(const char* Text, int Count, RECT Rect, float X, float Y, int A, int R, int G, int B);
    void DrawNumber(int SetValue, RECT Rect, float X, float Y, int A, int R, int G, int B);
};

#endif

その他のファイル:

// Core.h //

// Include Guard //
#ifndef _CORE_H
#define _CORE_H

// Pragma Comments
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

// External Include <> //
#include <Windows.h>
#include <WindowsX.h>
#include <d3d9.h>
#include <d3dx9.h>

#include <vector>
#include <map>
#include <iostream>
#include <tchar.h>

// Internal Incldue "" //
#include "System.h"

#endif

// Core.cpp //

#include "Core.h"


int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow) {
    System Sys;
    HWND hWnd;
    WNDCLASSEX WC;

    ZeroMemory(&WC, sizeof(WNDCLASSEX));

    WC.cbSize = sizeof(WNDCLASSEX);
    WC.style = CS_HREDRAW | CS_VREDRAW;
    WC.lpfnWndProc = (WNDPROC)WindowProc;
    WC.hInstance = hInstance;
    WC.hCursor = LoadCursor(NULL, IDC_ARROW);
    WC.lpszClassName = L"WindowClass";

    RegisterClassEx(&WC);
    hWnd = CreateWindowEx(NULL, L"WindowClass", L"Game Name",
                          WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
                          NULL, NULL, hInstance, NULL);
    ShowWindow(hWnd, nCmdShow);
    // Set up Direct3D
    Sys.InitD3D(TRUE, SCREEN_WIDTH, SCREEN_HEIGHT);
    // Enter Main Loop
    MSG Msg;
    while(TRUE) {
        DWORD Starting_Point = GetTickCount();
        if(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {
            if(Msg.message == WM_QUIT)
                break;
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
        Sys.Render_Frame();
        // Check escape key
        if(KEY_DOWN(VK_ESCAPE))
            PostMessage(hWnd, WM_DESTROY, 0, 0);
        while((GetTickCount() - Starting_Point) < 25);
    }
    Sys.CleanD3D();
    return Msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    switch(Message) {
    case WM_DESTROY:
        {
            PostQuitMessage(0);
            return 0;
        } break;
    }
    return DefWindowProc(hWnd, Message, wParam, lParam);
}

bool CheckCollision(float Ax, float Ay, float Aw, float Ah, float Bx, float By, float Bw, float Bh) {
    if(Ay+Ah < By) return false;
    else if(Ay > By+Bh) return false;
    else if(Ax+Aw < Bx) return false;
    else if(Ax > Bx+Bw) return false;

    return true;
}
4

1 に答える 1

1

私はDirectXの専門家ではありませんが、ここから始めます。まず、InitD3D()は失敗する可能性があるため、おそらくブール値を返すか、void以外の戻り型を持っている必要があります。

手始めに、Create()関数が成功したことを確認します。たとえば、私はおそらく次のようなものを追加します:

//Returns NULL pointer on failure.
Data.D3D = Direct3DCreate9(D3D_SDK_VERSION);

if(!Data.D3D)
    return false;

そして、あなたがデバイスを作成するために行くとき:

HRESULT hr = Data.D3D->CreateDevice(D3DADAPTER_DEFAULT,
                  D3DDEVTYPE_HAL,
                  hWnd,
                  D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                  &D3DPP,
                  &Data.D3DDEV);

if(hr != D3D_OK)
    return false;

私は少なくともいくつかの基本的なエラーチェックを行います。デバイスが正常に作成され、呼び出し時に値が設定されている場合は、それを除外できます。DirectXを使用してからしばらく経ちましたので、falseを返す前にRelease()/クリーンアップする必要があるかもしれませんが、それが基本的な考え方です。

通話時にデバイスが価値があるかどうかを簡単に確認できます。例外が発生する行にブレークポイントを設定します。ヒットしたら、デバッガーでData.D3DDEVの値を確認します。0x00000000それがnullであり、nullポインターを無視しようとしている値を持っている場合。

于 2012-12-16T21:53:28.357 に答える