Full Screen - Flickering

Started by
5 comments, last by IlyaZ 18 years ago
Hey, I'm working on a main menu in DX9 w. C++. It works very well in windowed mode. But when I'm toggling full screen mode the screen immediately starts to _flicker_. Because of this I can see right through the app. I see Visual Studio etc. But also the start bar (activity bar or what it's called, the thing down there). There no "box" appears showing that the program has started (in windowed mode it does). If I hold the mouse over the top left corner the custom cursor icon disappears, and when I press that area a window with the size of my screen appears. It's all white. It responds to all commands but doesnt show any gfx (text only). If I display a messagebox the flicker stops until I remove it. What could be wrong here? I can't alt tab (if I do device would be lost probably), and haven't got dual screens which makes it hard for me to debug.
Advertisement
What sort of Win32 initialization have you got? How are you handling the windows messages? Have you cross-referenced this against the SDK tutorials (and/or the DXUT framework)??

The only Direct3D reason I can think of is tearing due to no VSYNC, but that won't show any of the contents underneath/behind...

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

BOOL cApplication::Run(){  MSG Msg;  // Register window class  if(!RegisterClassEx(&m_wcex))    return FALSE;  // Create the Main Window  m_hWnd = CreateWindow(m_Class, m_Caption,        m_style,         m_XPos, m_YPos,        m_Width, m_Height,        NULL, NULL, m_hInst, NULL);  if(!m_hWnd)    return FALSE;  // Show and update the window  ShowWindow(m_hWnd, SW_NORMAL);  UpdateWindow(m_hWnd);  // Make sure client area is correct size  Resize(m_Width, m_Height);  // Initialize COM  CoInitialize(NULL);  if(Init() == TRUE) {     // Enter the message pump    ZeroMemory(&Msg, sizeof(MSG));    while(Msg.message != WM_QUIT) {      // Handle Windows messages (if any)      if(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {        TranslateMessage(&Msg);        DispatchMessage(&Msg);      } else {        // Do per-frame processing, break on FALSE return value        if(Frame() == FALSE)          break;      }    }  }  Shutdown();  // Shutdown COM  CoUninitialize();  // Unregister the window class  UnregisterClass(m_Class, m_hInst);  return TRUE;}


I use this code. It's from Jim Adams' RPG book for Dx8.
But I think there could be something wrong with init here:

BOOL cApp::Init(){		// Initialize the graphics device	m_Graphics.Init();	// Fullscreen:	m_Graphics.SetMode(GethWnd(), FALSE, TRUE);	// Small window:	//m_Graphics.SetMode(GethWnd(), TRUE, TRUE,640,480);	m_Graphics.Clear(0x00000000, 1.0f);	m_Graphics.Display();	// Set perspective	m_Graphics.SetPerspective(0.6f,1.33333f,1.0f,20000.0f);	m_StateManager.Push(IntroFrame, this);	return TRUE;}


SetMode:
BOOL cGraphics::SetMode(HWND hWnd, BOOL Windowed, BOOL UseZBuffer, long Width, long Height, char BPP){  D3DPRESENT_PARAMETERS d3dpp;  D3DFORMAT             Format, AltFormat;  RECT                  WndRect, ClientRect;  long                  WndWidth, WndHeight;  float                 Aspect;  // Error checking  if((m_hWnd = hWnd) == NULL)    return FALSE;  if(m_pD3D == NULL)    return FALSE;  // Get the current display format  if(FAILED(m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &m_d3ddm)))    return FALSE;  // Configure width  if(!Width) {    // Default to screen width if fullscreen    if(Windowed == FALSE) {      m_Width = m_d3ddm.Width;    } else {      // Otherwise grab from client size      GetClientRect(m_hWnd, &ClientRect);      m_Width = ClientRect.right;    }  } else {    m_Width = Width;  }   // Configure height  if(!Height) {    // Default to screen height if fullscreen    if(Windowed == FALSE) {      m_Height = m_d3ddm.Height;    } else {      // Otherwise grab from client size      GetClientRect(m_hWnd, &ClientRect);      m_Height = ClientRect.bottom;    }  } else {    m_Height = Height;  }  // Configure BPP  if(!(m_BPP = BPP) || Windowed == TRUE) {    if(!(m_BPP = GetFormatBPP(m_d3ddm.Format)))      return FALSE;  }  // Resize client window if using windowed mode  if(Windowed == TRUE) {    GetWindowRect(m_hWnd, &WndRect);    GetClientRect(m_hWnd, &ClientRect);    WndWidth  = (WndRect.right  - (ClientRect.right  - m_Width))  - WndRect.left;    WndHeight = (WndRect.bottom - (ClientRect.bottom - m_Height)) - WndRect.top;    MoveWindow(m_hWnd, WndRect.left, WndRect.top, WndWidth, WndHeight, TRUE);  }  // Clear presentation structure  ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));  // Default to no hardware acceleration detected  m_HAL = FALSE;  // Setup Windowed or fullscreen usage  if((m_Windowed = Windowed) == TRUE) {    d3dpp.Windowed         = TRUE;    d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;    d3dpp.BackBufferFormat = m_d3ddm.Format;    // See if card supports HAL    if(CheckFormat(m_d3ddm.Format, TRUE, TRUE) == TRUE) {      m_HAL = TRUE;    } else {      // Return error if not emulated      if(CheckFormat(m_d3ddm.Format, TRUE, FALSE) == FALSE)        return FALSE;    }  } else {    d3dpp.Windowed   = FALSE;    d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;      d3dpp.BackBufferWidth  = m_Width;    d3dpp.BackBufferHeight = m_Height;    d3dpp.FullScreen_RefreshRateInHz      = D3DPRESENT_RATE_DEFAULT;    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // or D3DPRESENT_INTERVAL_DEFAULT or D3DPRESENT_INTERVAL_IMMEDIATE    // Figure display format to use    if(m_BPP == 32) {      Format    = D3DFMT_X8R8G8B8;      AltFormat = D3DFMT_X8R8G8B8;    }    if(m_BPP == 24) {      Format    = D3DFMT_R8G8B8;      AltFormat = D3DFMT_R8G8B8;    }    if(m_BPP == 16) {      Format    = D3DFMT_R5G6B5;      AltFormat = D3DFMT_X1R5G5B5;    }    if(m_BPP == 8) {      Format    = D3DFMT_P8;      AltFormat = D3DFMT_P8;    }    // Check for HAL device    if(CheckFormat(Format, FALSE, TRUE) == TRUE) {      m_HAL = TRUE;    } else {      // Check for HAL device in alternate format      if(CheckFormat(AltFormat, FALSE, TRUE) == TRUE) {        m_HAL = TRUE;        Format = AltFormat;      } else {        // Check for Emulation device        if(CheckFormat(Format, FALSE, FALSE) == FALSE) {          // Check for Emulation device in alternate format          if(CheckFormat(AltFormat, FALSE, FALSE) == FALSE)            return FALSE;          else            Format = AltFormat;        }      }    }    d3dpp.BackBufferFormat = Format;  }  // Setup Zbuffer format - 16 bit  if((m_ZBuffer = UseZBuffer) == TRUE) {    d3dpp.EnableAutoDepthStencil = TRUE;    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;  } else {    d3dpp.EnableAutoDepthStencil = FALSE;  }    // Create the Direct3D Device object  if(FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,                (m_HAL == TRUE) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF,                hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,               &d3dpp, &m_pD3DDevice))) {    // Try to create Direct3D without ZBuffer support     // if selected and first call failed.    if(m_ZBuffer == TRUE) {      m_ZBuffer = FALSE;      d3dpp.EnableAutoDepthStencil = FALSE;      if(FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,                    (m_HAL == TRUE) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF,                    hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,                   &d3dpp, &m_pD3DDevice)))        return FALSE;    } else                                         return FALSE;  }  // Set default rendering states  // Enable texture rendering stages and filter types    // Calculate the aspect ratio based on window size  // Create a sprite interface  return TRUE;}



Maybe I'll rewrite the code completely but I mean that code should work.
The error could also have something to do with the statemanager I use. Got to check that too.
This might help you out.

For your window style use WS_POPUP

For your window size use these:

WindowWidth = GetSystemMetrices(SM_CXSCREEN)
WindowHeight = GetSystemMetrices(SM_CXSCREEN)

Hope that helps out. Good luck
Looks like I was lucky. It works :))
Just got to check what it does with MSDN now lol.

Thanks!
Crap lol. Still got some flickering, but it's a bit different now.

The text flickers. What I do:

1. Loaded the Main Menu (no flickering) (looks like it all works here)
2. Changed state to "GameFrame" (=started game) -> Menu is in the background (flickers)
3. Changed back to the menu (game is flickering in the background)
4. I switch between the states a few times. No flickering.
5. I switch one time more. Flickering starts all over again.

Hmm. Ill see if I can find the error.
Turns out some of the flickering stops if I clear the screen between state changes.

It has something to do with the backbuffer then?

EDIT: Looks like Adams doesn't clear the screen anywhere, apparently his program works (I cant compile it it's DX8, but how does he do??). So now I added code for clearing the screen every frame and it works.

[Edited by - IlyaZ on April 2, 2006 4:53:25 PM]

This topic is closed to new replies.

Advertisement