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.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Brauchen Sie nicht, um die Freigabe von Ressourcen in D3DPOOL_MANAGED. Sie brauchen zum freigeben von Ressourcen in D3DPOOL_DEFAULT.
Wenn Sie mit D3DX-Objekte (ID3DXFont, ID3DXMesh, ID3DXSprite), Sie haben in der Regel "OnLostDevice" und "OnResetDevice" Methoden. Rufen Sie diese Methoden in geeigneten Situationen.
Wenn ein Objekt keine Methoden für den Umgang mit "DeviceLost" - Zustand, und Sie freigegeben werden soll, einfach das Objekt löschen, bevor Sie das Gerät zurückzusetzen, und laden Sie es anschließend wieder ein.
Bitte beachten Sie, dass D3DPOOL_MANAGED Objekte neu geladen werden, automatisch durch den Treiber, und brauchen keine "Hilfe" aus, dass Sie sich mit reset/devicelost. Sie benötigen zu kümmern über, alle anderen Objekte.
Zusätzlich zu dem, was ich sagte/schrieb, solltest du natürlich Lesen DirectX-SDK-Dokumentation. Decken Sie verlorene Geräte in Ihrer Dokumentation, und DirectX Beispiele normalerweise überleben zurücksetzen des Geräts in Ordnung.