Wie zurücksetzen mein DirectX 9 Gerät?

Kürzlich, ich habe einen Fehler gefunden in meiner 3D-Anwendung, die mit DirectX 9. Der Fehler ist, dass jedesmal, wenn ich alt-tab oder Strg-alt-löschen, das Programm friert ein, oder scheint nichts zu tun. Ich habe sah sich um und fand heraus, dass ich brauche, um mein Gerät zurücksetzen mithilfe IDirect3DDevice9::TestCooperativeLevel und IDirect3DDevice9::Reset. Aber was ich zu kämpfen im moment ist, dass (soweit ich weiß), bevor ich Reset dem Gerät, ich brauche die Freigabe der Ressource in D3DPOOL_MANAGE bevor ich das Gerät zurücksetzen und eine Neuverteilung der Ressourcen zurück, die es nach dem Reset? Wie mache ich das? Unten ist der code, den ich habe für das zurücksetzen von meinem Gerät (in der IsDeviceLost() - Funktion).

DirectX.h

#pragma once
#pragma comment(lib, "d3d9.lib")

#include<d3d9.h>
#include<d3dx9math.h>

#include"Window.h"
#include"Vertex.h"
#include"Shader.h"

#define VERTEXFORMAT (D3DFVF_XYZ | D3DFVF_TEX1) //Flags for the Flexible Vertex Format (FVF)

class Shader;

class DirectX
{
public:
    DirectX(std::string windowTitle, int x, int y, unsigned int windowWidth, unsigned int windowHeight, bool fullscreen);
    virtual ~DirectX();

    static LPDIRECT3D9 direct3D;
    static LPDIRECT3DDEVICE9 device;
    static IDirect3DVertexDeclaration9* vertexDec;
    static ID3DXEffect* currentShaderEffect;

    void CheckShaderVersion();
    bool IsDeviceLost();

protected:
    D3DPRESENT_PARAMETERS direct3DPresPara;

    Window *window;
    unsigned int width;
    unsigned int height;
    D3DXMATRIX projMatrix;

private:
    void Initialize(bool fullscreenMode);
};

Direct.cpp

#include"DirectX.h"

LPDIRECT3D9 DirectX::direct3D = NULL;
LPDIRECT3DDEVICE9 DirectX::device = NULL;
IDirect3DVertexDeclaration9* DirectX::vertexDec = NULL;
ID3DXEffect* DirectX::currentShaderEffect = NULL;

DirectX::DirectX(std::string windowTitle, int x, int y, unsigned int windowWidth, unsigned int windowHeight, bool fullscreen)
{
    width = windowWidth;
    height = windowHeight;

    window = new Window(windowTitle.c_str(), windowWidth, windowHeight, x, y, fullscreen);

    Initialize(fullscreen);

    D3DXMatrixPerspectiveFovLH( &projMatrix,
                                D3DXToRadian(45),
                                (float)width/(float)height,
                                1.0f,
                                15000.0f);

    //device->SetTransform(D3DTS_PROJECTION, &projMatrix);
}

DirectX::~DirectX()
{
    direct3D->Release();
    device->Release();
    vertexDec->Release();

    delete vertexDec;
    delete currentShaderEffect;
    delete window;
}

void DirectX::Initialize(bool fullscreenMode)
{
    direct3D = Direct3DCreate9(D3D_SDK_VERSION);

    ZeroMemory(&direct3DPresPara, sizeof(direct3DPresPara));

    switch(fullscreenMode)
    {
        case true:
            direct3DPresPara.Windowed = false;
        break;
        case false:
            direct3DPresPara.Windowed = true;
    }

    direct3DPresPara.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //turns off VSync, comment this line of code to turn VSync back on
    direct3DPresPara.SwapEffect = D3DSWAPEFFECT_DISCARD;
    direct3DPresPara.hDeviceWindow = window->GetHandle();
    direct3DPresPara.BackBufferFormat = D3DFMT_X8R8G8B8;
    direct3DPresPara.BackBufferWidth = width;
    direct3DPresPara.BackBufferHeight = height;
    direct3DPresPara.EnableAutoDepthStencil = TRUE;
    direct3DPresPara.AutoDepthStencilFormat = D3DFMT_D16;

    direct3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window->GetHandle(), D3DCREATE_SOFTWARE_VERTEXPROCESSING, &direct3DPresPara, &device);

    D3DVERTEXELEMENT9 vertexElement[] = {   {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
                                            {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
                                            D3DDECL_END()};

    device->CreateVertexDeclaration(vertexElement, &vertexDec);

    //currentShaderEffect = 0;
}

void DirectX::CheckShaderVersion()
{
    D3DCAPS9 caps;

    device->GetDeviceCaps(&caps);

    bool stop = false;
    int i = 6;
    while(!stop)
    {
        if(caps.VertexShaderVersion < D3DVS_VERSION(i, 0))
        {
            i--;
        }
        else
        {
            std::cout << "you are using shader model " << i << std::endl;
            stop = true;
        }
    }

    //std::cout << caps.VertexShaderVersion << std::endl;
    //std::cout << D3DVS_VERSION(3, 0) << std::endl;
}

bool DirectX::IsDeviceLost()
{
    HRESULT result = device->TestCooperativeLevel();

    if(result == D3DERR_DEVICELOST)
    {
        Sleep(20); //Sleep for a little bit then try again.
        return true;
    }
    else if(result == D3DERR_DRIVERINTERNALERROR)
    {
        MessageBox(0, "Internal Driver Error. The program will now exit.", 0, 0);
        PostQuitMessage(0);
        return true;
    }
    else if(result == D3DERR_DEVICENOTRESET)
    {
        device->Reset(&direct3DPresPara);
        return false;
    }
    else
    {
        return false;
    }
}

Jede Hilfe oder Beratung wird sehr geschätzt. Dank

  • D3DPOOL_MANAGED eigentlich gar nicht erfordern viel Arbeit, um dieses Problem. Der einfachste Weg ist es, erstellen Sie einfach die Dinge, die für ungültig erklärt werden, on the fly, so dass Sie schon zerstört und neu erstellt, wenn dies geschieht.
InformationsquelleAutor Danny | 2013-11-14
Schreibe einen Kommentar