2013-10-12 42 views
0

black screen如何刷新图形以避免黑屏?

当我最小化我的directx框架并打开任务管理然后返回到框架。它给了我黑屏。我应该如何修改我的代码来修复这个缺陷?

GraphicsClass.h

#ifndef _GRAPHICSCLASS_H_ 
#define _GRAPHICSCLASS_H_ 


////////////// 
// INCLUDES // 
////////////// 
#include <d3dx9.h> 
#include <assert.h> 
#include <string> 
using namespace std; 


///////////// 
// GLOBALS // 
///////////// 
const bool FULL_SCREEN   = false; 
const unsigned int SCREEN_WIDTH = 1280; 
const unsigned int SCREEN_HEIGHT = 720; 



//////////////////////////////////////////////////////////////////////////////// 
// Class name: GraphicsClass 
//////////////////////////////////////////////////////////////////////////////// 
class GraphicsClass 
{ 
public: 
    GraphicsClass(HWND hwnd); 
    ~GraphicsClass(); 
    void SetPath(const string& loadFolder); 

    void BeginFrame(); 
    void EndFrame(); 

    void Load(IDirect3DTexture9*& texture, string imgName, int imgWidth, int imgHeight); 
    void setFont(ID3DXFont*& font, char* fontName, int fontHeight); 

    void SourceRect(RECT& sourceRect, int left, int right, int top, int bottom); 

    void DrawText(ID3DXFont*& font, LPCSTR string, int charNum, RECT& SourceRect, DWORD format, D3DCOLOR color); 
    void Draw(IDirect3DTexture9* texture); 
    void Draw(IDirect3DTexture9* texture, float posX, float posY); 
    void Draw(IDirect3DTexture9* texture, RECT& sourceRect, float posX, float posY); 

private: 
    string    path; 
    HRESULT    result; 
    ID3DXSprite*  pSprite; 
    IDirect3D9*   pDirect3D; 
    IDirect3DDevice9* pDevice; 
}; 


#endif 

GraphicsClass.cpp

#include "GraphicsClass.h" 

GraphicsClass::GraphicsClass(HWND hwnd) 
{ 
    pDirect3D = Direct3DCreate9(D3D_SDK_VERSION); 

    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(&d3dpp, sizeof(d3dpp)); 
    d3dpp.Windowed    = TRUE; 
    d3dpp.SwapEffect   = D3DSWAPEFFECT_DISCARD; 
    d3dpp.BackBufferFormat  = D3DFMT_X8R8G8B8; 
    d3dpp.BackBufferCount  = 1; 
    d3dpp.BackBufferWidth  = SCREEN_WIDTH; 
    d3dpp.BackBufferHeight  = SCREEN_HEIGHT; 
    d3dpp.hDeviceWindow   = hwnd; 
    //d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; 

    result = pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, 
    D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice); 
    assert(!FAILED(result)); 

    result = D3DXCreateSprite(pDevice, &pSprite); 
    assert(!FAILED(result)); 
} 


GraphicsClass::~GraphicsClass() 
{ 
    // Release and clean up sprite 
    pSprite->Release(); 
    pSprite = NULL; 
} 


void GraphicsClass::SetPath(const string& path) 
{ 
    this->path = path; 
} 


void GraphicsClass::BeginFrame() 
{ 
    pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0); 
    pDevice->BeginScene(); 

    // Specify alpha blend will ensure that the sprite will render the background with alpha. 
    pSprite->Begin(D3DXSPRITE_ALPHABLEND); 
} 


void GraphicsClass::EndFrame() 
{ 
    // End sprite drawing 
    pSprite->End(); 

    pDevice->EndScene(); 
    pDevice->Present(NULL, NULL, NULL, NULL); 
} 


void GraphicsClass::Load(IDirect3DTexture9*& texture, string imgName, int imgWidth, int imgHeight) 
{ 
    string fullPath; 
    fullPath = path + imgName; 

    result = D3DXCreateTextureFromFileEx(pDevice, fullPath.c_str(), imgWidth, imgHeight, 
    D3DX_DEFAULT, NULL, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, 
    D3DX_DEFAULT, D3DX_DEFAULT, NULL, 
    NULL, NULL, &texture); 
} 


void GraphicsClass::setFont(ID3DXFont*& font, char* fontName, int fontHeight) 
{ 
    result = D3DXCreateFont(pDevice, fontHeight, 0, 0, 1, false, 
    DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, DEFAULT_QUALITY, 
    DEFAULT_PITCH | FF_DONTCARE, fontName, &font); 
} 


void GraphicsClass::SourceRect(RECT& sourceRect, int left, int right, int top, int bottom) 
{ 
    sourceRect.left  = left; 
    sourceRect.right = right; 
    sourceRect.top  = top; 
    sourceRect.bottom = bottom; 
} 


void GraphicsClass::DrawText(ID3DXFont*& font, LPCSTR string, int charNum, RECT& SourceRect, DWORD format, D3DCOLOR color) 
{ 
    font->DrawText(pSprite, string, charNum, &SourceRect, format, color); 
} 


void GraphicsClass::Draw(IDirect3DTexture9* texture) 
{ 
    pSprite->Draw(texture, NULL, NULL, &D3DXVECTOR3(0, 0, 0), D3DCOLOR_XRGB(255, 255, 255)); 
} 


void GraphicsClass::Draw(IDirect3DTexture9* texture, float posX, float posY) 
{ 
    pSprite->Draw(texture, NULL, NULL, &D3DXVECTOR3(posX, posY, 0), D3DCOLOR_XRGB(255, 255, 255)); 
} 


void GraphicsClass::Draw(IDirect3DTexture9* texture, RECT& sourceRect, float posX, float posY) 
{ 
    pSprite->Draw(texture, &sourceRect, NULL, &D3DXVECTOR3(posX, posY, 0), D3DCOLOR_XRGB(255, 255, 255)); 
} 

SystemClass.cpp

void SystemClass::InitializeWindows() 
{ 
    WNDCLASSEX wc; 
    DEVMODE dmScreenSettings; 

    int screenWidth, screenHeight; 
    int posX, posY; 


    // Get an external pointer to this object 
    ApplicationHandle = this; 

    // Get the instance of this application 
    m_hinstance = GetModuleHandle(NULL); 

    // Give the application a name 
    m_applicationName = "Zero DirectX Framework"; 

    // Setup the windows class with default settings 
    wc.style   = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 
    wc.lpfnWndProc  = WndProc; 
    wc.cbClsExtra  = 0; 
    wc.cbWndExtra  = 0; 
    wc.hInstance  = m_hinstance; 
    wc.hIcon   = LoadIcon(NULL, IDI_WINLOGO); 
    wc.hIconSm   = wc.hIcon; 
    wc.hCursor   = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); 
    wc.lpszMenuName  = NULL; 
    wc.lpszClassName = m_applicationName; 
    wc.cbSize   = sizeof(WNDCLASSEX); 

    // Register the window class 
    RegisterClassEx(&wc); 

    // Determine the resolution of the clients desktop screen 
    screenWidth = GetSystemMetrics(SM_CXSCREEN); 
    screenHeight = GetSystemMetrics(SM_CYSCREEN); 

    // Setup the screen settings depending on whether it is running in full screen or in windowed mode 
    if (FULL_SCREEN) 
    { 
     // If full screen set the screen to maximum size of the users desktop and 32bit 
     memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); 
     dmScreenSettings.dmSize   = sizeof(dmScreenSettings); 
     dmScreenSettings.dmPelsWidth = (unsigned long)screenWidth; 
     dmScreenSettings.dmPelsHeight = (unsigned long)screenHeight; 
     dmScreenSettings.dmBitsPerPel = 32; 
     dmScreenSettings.dmFields  = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; 

     // Change the display settings to full screen 
     ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN); 

     // Set the position of the window to the top left corner 
     posX = posY = 0; 

     // Create the window with the screen settings and get the handle to it 
     m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName, 
     WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP, 
     posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL); 

     SetMenu(m_hwnd, NULL); 
    } 
    else 
    { 
     // If windowed then set it to 800x600 resolution 
     screenWidth = 1280; 
     screenHeight = 768; 

     // Place the window in the middle of the screen 
     posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth)/2; 
     posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight)/2; 

     m_hwnd = CreateWindowEx(0, m_applicationName, m_applicationName, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, 
     posX, posY, screenWidth, screenHeight, 
     NULL, NULL, m_hinstance, NULL); 
    } 

    // Bring the window up on the screen and set it as main focus 
    ShowWindow(m_hwnd, SW_SHOW); 
    SetForegroundWindow(m_hwnd); 
    SetFocus(m_hwnd); 

    // Hide the mouse cursor 
    ShowCursor(true); 
} 
+3

http://msdn.microsoft.com/en-us/library/windows/desktop/bb174714%28v=vs.85%29.aspx –

回答

2

你不处理的情况when device is lost,这是(可能)中会发生什么这个案例。

基本上,在呈现任何你应该test cooperative level之前,如果它返回D3DERR_DEVICELOST,不要画任何东西。如果它返回D3DERR_DEVICENOTRESET,则应该设备reset,如果返回0(D3DERR_OK或使用宏SUCCEEDED),则继续绘制帧。

设备重置时,会丢失所有不在D3DPOOL_MANAGED中的资源,您需要重新创建它们或重新加载它们。在调用IDirect3DDevice9 :: Reset之前,您可以释放所有着色器和id3dx对象(如ID3DXFont),然后在成功重置调用后重新创建它们。

未能处理“丢失的设备”将意味着您将无法在全屏运行时更改您的游戏,并且切换显示模式可能会“破坏它”。在你的情况黑屏最有可能发生的原因是相同的。

+0

解决。我使用pSprite - > OnLostDevice(); \t \t pDevice - > Reset(&d3dpp); \t \t pSprite - > OnResetDevice(); – user