Ich habe hier an der Uni einen Windows 7 RC Rechner stehen und wollte mal ein bischen mit DirectX 10 (Direct3D10) rumspielen und habe mich mal durch die Samples im SDK geschlagen. Ich wollte es einfach angehen und erstellte ein Fenster das man mittels alt+enter zwischen Vollbild- und Fenstermodus umschalten konnte. DXGI sollte das ja übernehmen. Ich habe die WM_SIZE Nachricht abgefangen und ResizeBuffers aufgerufen. Doch immer wenn ich aus dem Vollbild- in den Fenstermodus
zurückgewechselt bin, ist die Anwendung so nach c.a. 10 Sekunden mit folgender Fehlermeldung abgestürzt: DXGI_ERROR_DEVICE_REMOVED! Tja, früher unter Direct3D 9 musste ich ja noch vor einem Reset alle Default Ressourcen freigeben doch das müsste unter D3D10 ja nicht mehr notwendig sein. Jetzt bin ich mir nicht sicher ob ich ein Fehler in meinem Programm habe oder aber ob es einfach noch an dem RC Status von Windows 7 liegt. Ich hoffe ihr könnt mir weiterhelfen.
Vielen Dank schon mal im Voraus
Code: Alles auswählen
//-----------------------------------------------------------------------------
// D3D10Tutorial.cpp
//
// Erstellt ein einfaches Fenster das mittels alt+enter zwischen Vollbild-
// und Fenstermodus umgeschaltet werden kann.
//-----------------------------------------------------------------------------
#include <windows.h>
#include <strsafe.h>
#include <dxerr.h>
#include <d3d10.h>
#include <d3dx10.h>
#pragma comment(lib, "dxerr.lib")
#pragma comment(lib, "d3d10.lib")
#pragma comment(lib, "d3dx10.lib")
//-----------------------------------------------------------------------------
// Makros und Konstanten.
//-----------------------------------------------------------------------------
#define SAVERELEASE(p) if (p) {p->Release(); p = NULL;}
#define MSG_SIZE 512
//-----------------------------------------------------------------------------
// Globale Variablen.
//-----------------------------------------------------------------------------
wchar_t g_errorMsg[MSG_SIZE];
bool g_bFailed = false;
HWND g_hWnd = NULL;
UINT g_width = 800;
UINT g_height = 600;
ID3D10Device* g_pD3DDevice = NULL;
IDXGISwapChain* g_pDXGISwapChain = NULL;
ID3D10RenderTargetView* g_pD3DRenderTV = NULL;
ID3DX10Font* g_pD3DFont = NULL;
//-----------------------------------------------------------------------------
// Forwärtsdeklarationen.
//-----------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void Error(const wchar_t *pMsg, HRESULT hr, bool bWin32Error);
bool InitWindow(HINSTANCE hInstance);
bool InitD3D10();
bool InitResources();
bool AdjustSwapChain();
bool CreateRenderTargetView();
bool Render();
void Cleanup();
//-----------------------------------------------------------------------------
// Der Haupteinsteigspunkt initialisiert und startet die Anwendung.
//-----------------------------------------------------------------------------
int WINAPI wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nShowCmd)
{
if (InitWindow(hInstance) && InitD3D10() && InitResources())
{
ShowWindow(g_hWnd, nShowCmd);
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if (!Render())
DestroyWindow(g_hWnd);
}
}
}
Cleanup();
if (g_bFailed)
MessageBox(NULL, g_errorMsg, L"Failed", MB_ICONERROR);
return 0;
}
//-----------------------------------------------------------------------------
// Verarbeitet Windows Nachrichten.
//-----------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (WM_DESTROY == msg)
PostQuitMessage(0);
else if (WM_KEYDOWN == msg && VK_ESCAPE == wParam)
SendMessage(g_hWnd, WM_CLOSE, 0, 0);
else if (WM_SIZE == msg)
{
if (!AdjustSwapChain())
DestroyWindow(g_hWnd);
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
//-----------------------------------------------------------------------------
// Formatiert eine Fehlermeldung und zeigt eine genaue Beschreibung des
// aufgetretenen Fehlers.
//
// Parameter pMsg
// Die Fehlermeldung (Normalerweise der Name der aufgerufenen Funktion).
//
// Parameter hr
// Der Fehlercode.
//
// bWin32Error
// Wenn gesetzt, wird der HRESULT Parameter ignoriert und mittels GetLastError
// die letzte Fehlermeldung von Windows verwendet.
//-----------------------------------------------------------------------------
void Error(const wchar_t *pMsg, HRESULT hr, bool bWin32Error = false)
{
if (bWin32Error)
{
DWORD dwError = GetLastError();
hr = HRESULT_FROM_WIN32(static_cast<unsigned long>(dwError));
}
g_bFailed = true;
StringCbPrintf(
g_errorMsg,
MSG_SIZE,
L"%s\n\nHRESULT = %s\n\n%s",
pMsg,
DXGetErrorString(hr),
DXGetErrorDescription(hr));
}
//-----------------------------------------------------------------------------
// Initialisiert und erstellt ein Fenster.
//-----------------------------------------------------------------------------
bool InitWindow(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbClsExtra = 0;
wcex.cbSize = sizeof(wcex);
wcex.cbWndExtra = 0;
wcex.hbrBackground = static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hIcon = NULL;
wcex.hIconSm = NULL;
wcex.hInstance = hInstance;
wcex.lpfnWndProc = WndProc;
wcex.lpszClassName = L"D3D10Tutorial";
wcex.lpszMenuName = NULL;
wcex.style = CS_VREDRAW | CS_HREDRAW;
if (!RegisterClassEx(&wcex))
{
Error(L"RegisterClassEx", NULL, true);
return false;
}
RECT rect = { 0, 0, g_width, g_height };
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
g_hWnd = CreateWindow(
L"D3D10Tutorial",
L"D3D10 Tutorial",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
rect.right - rect.left,
rect.bottom - rect.top,
NULL, NULL,
hInstance,
NULL);
if (NULL == g_hWnd)
{
Error(L"CreateWindow", NULL, true);
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Erstellt das Device und ein SwapChain.
//-----------------------------------------------------------------------------
bool InitD3D10()
{
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = g_width;
sd.BufferDesc.Height = g_height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
HRESULT hr = D3D10CreateDeviceAndSwapChain(
NULL,
D3D10_DRIVER_TYPE_HARDWARE,
NULL,
NULL,
D3D10_SDK_VERSION,
&sd,
&g_pDXGISwapChain,
&g_pD3DDevice);
if (FAILED(hr))
{
Error(L"D3D10CreateDeviceAndSwapChain", hr);
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Erstellt ein Font Objekt.
//-----------------------------------------------------------------------------
bool InitResources()
{
HRESULT hr = D3DX10CreateFont(
g_pD3DDevice,
16,
0,
FW_NORMAL,
1,
FALSE,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH |
FF_DONTCARE,
L"Arial",
&g_pD3DFont);
if (FAILED(hr))
{
Error(L"D3DX10CreateFont", hr);
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Passt die SwapChain Buffer der neuen Fenstergrösse an.
//-----------------------------------------------------------------------------
bool AdjustSwapChain()
{
RECT rect;
GetClientRect(g_hWnd, &rect);
g_width = static_cast<UINT>(rect.right);
g_height = static_cast<UINT>(rect.bottom);
SAVERELEASE(g_pD3DRenderTV);
DXGI_SWAP_CHAIN_DESC sd;
g_pDXGISwapChain->GetDesc(&sd);
HRESULT hr = g_pDXGISwapChain->ResizeBuffers(
sd.BufferCount,
g_width,
g_height,
sd.BufferDesc.Format,
NULL);
if (FAILED(hr))
{
Error(L"IDXGISwapChain::ResizeBuffers", hr);
return false;
}
if (!CreateRenderTargetView())
return false;
g_pD3DDevice->OMSetRenderTargets(1, &g_pD3DRenderTV, NULL);
D3D10_VIEWPORT vp;
vp.Width = g_width;
vp.Height = g_height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pD3DDevice->RSSetViewports(1, &vp);
return true;
}
//-----------------------------------------------------------------------------
// Erstellt einen BackBuffer.
//-----------------------------------------------------------------------------
bool CreateRenderTargetView()
{
ID3D10Texture2D* pBackBuffer = NULL;
HRESULT hr = g_pDXGISwapChain->GetBuffer(
0,
__uuidof(ID3D10Texture2D),
reinterpret_cast<void**>(&pBackBuffer));
if (FAILED(hr))
{
Error(L"IDXGISwapChain::GetBuffer", hr);
return false;
}
hr = g_pD3DDevice->CreateRenderTargetView(
pBackBuffer,
NULL,
&g_pD3DRenderTV);
SAVERELEASE(pBackBuffer);
if (FAILED(hr))
{
Error(L"ID3D10Device::CreateRenderTargetView", hr);
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Rendert die Szene.
//-----------------------------------------------------------------------------
bool Render()
{
float clearColor[4] = {0.0f, 0.0f, 1.0f, 1.0f};
D3DXCOLOR fontColor(1.0f, 1.0f, 0.0f, 1.0f);
RECT rect = {12, 10, g_width - 12, g_height - 10};
wchar_t text[40];
StringCbPrintf(text, 40, L"%d x %d", g_width, g_height);
g_pD3DDevice->ClearRenderTargetView(g_pD3DRenderTV, clearColor);
g_pD3DFont->DrawText(NULL, text, -1, &rect, 0, fontColor);
HRESULT hr = g_pDXGISwapChain->Present(0, 0);
if (FAILED(hr))
{
Error(L"IDXGISwapChain::Present", hr);
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Räumt alles auf.
//-----------------------------------------------------------------------------
void Cleanup()
{
if (g_pDXGISwapChain)
g_pDXGISwapChain->SetFullscreenState(FALSE, 0);
SAVERELEASE(g_pD3DFont);
SAVERELEASE(g_pD3DRenderTV);
SAVERELEASE(g_pDXGISwapChain);
SAVERELEASE(g_pD3DDevice);
}