Question

black screen

When I minimized my directx framework and open up the task manage then go back to the framework. It gives me the black screen. How should I modify my code to fix this flaw?

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);
}
Was it helpful?

Solution

You're not handling situation when device is lost, which is (possibly) what happens in this case.

Basically, BEFORE rendering anything you should test cooperative level, if it returns D3DERR_DEVICELOST, do not do not draw anything. If it returns D3DERR_DEVICENOTRESET, you should reset the device, if it returns 0 (D3DERR_OK or use SUCCEEDED macro), then proceed to draw the frame.

When device is reset, it loses all resources that are not in D3DPOOL_MANAGED, and you'll need to recreate them, or reload them. You can release all shaders and id3dx objects (like ID3DXFont) before calling IDirect3DDevice9::Reset, then recreate them after succesfull reset call.

Failure to handle "lost devices" will mean that you won't be able to alt-tab your game when running in fullscreen, and switching display mode might "break it". IN your situation black screen most likely happens for the same reason.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top