Page Flip

I always assumed that if I created a window with WM_POPUP at (0,0) and made it the size of the screen that the driver would understand that it’s a fullscreen mode and would just switch the buffers instead of copying the backbuffer into the framebuffer.
I was obviously wrong …

I’m working a little on a small benchmarking utility and when I had done the test for pixel fillrate I was surpriced by the low number I got. After a few tests I found that it spent almost half the time in SwapBuffers(). I tried changing the OGLEnableHWPageFlip key (this is on a Radeon card btw) and saw a clear difference in Quake3 but not in my app. I’ve tried changing the way I create my window, but the only time I get a real fullscreen mode is if I remove the WS_VISIBLE flag and don’t call ShowWindow() … but then my window of course isn’t recieving and input messages

I guess it’s something with how I create my window, this is how I do it right now:
CreateWindowEx(WS_EX_APPWINDOW, “GLwin”,“GLbench”, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, Width, Height, NULL, NULL, hInstance, NULL);

So, what am I doing wrong?
Exactly what do I need to do to make the driver understand that I’m using fullscreen mode?

I always add WS_EX_TOPMOST in the extended
style, try it and see if that helps…
-bart

This MAY help

WindowRect.left=(long)0;			// Set Left Value To 0
WindowRect.right=(long)width;		// Set Right Value To Requested Width
WindowRect.top=(long)0;				// Set Top Value To 0
WindowRect.bottom=(long)height;		// Set Bottom Value To Requested Height

hInstance = GetModuleHandle(NULL);
wc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc   = (WNDPROC)WindowProc;
wc.cbClsExtra    = 0;
wc.cbWndExtra    = 0;
wc.hInstance     = hInstance;
wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName  = NULL;
wc.lpszClassName = "Arioch";


if (flags&GL_WIN_FULLSCREEN)
{
	DEVMODE dmScreenSettings;								// Device Mode
	memset(&dmScreenSettings,0,sizeof(dmScreenSettings));	// Makes Sure Memory's Cleared
	dmScreenSettings.dmSize=sizeof(dmScreenSettings);		// Size Of The Devmode Structure
	dmScreenSettings.dmPelsWidth	= width;					// Selected Screen Width
	dmScreenSettings.dmPelsHeight	= height;				// Selected Screen Height
	dmScreenSettings.dmBitsPerPel	= depth;						// Selected Bits Per Pixel
	dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

		// Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
	if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)==DISP_CHANGE_SUCCESSFUL)
	{
		fullscreen=TRUE;
	}
}
if (fullscreen)												// Are We In Fullscreen Mode?
{
	dwExStyle=WS_EX_APPWINDOW;								// Window Extended Style
	dwStyle=WS_POPUP;										// Windows Style
	ShowCursor(FALSE);										// Hide Mouse Pointer
}
else
{
	dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			// Window Extended Style
	dwStyle=WS_OVERLAPPEDWINDOW;							// Windows Style
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);		// Adjust Window To True Requested Size

if (!RegisterClass(&wc)) {
    MessageBox(NULL, "RegisterClass() failed:  "
	       "Cannot register window class.", "Error", MB_OK);
	 return;
}

hWnd=CreateWindowEx(	dwExStyle,							// Extended Style For The Window
							(char*)"Arioch",					// Class Name
							(char*)p_name,						// Window Title
							dwStyle |							// Defined Window Style
							WS_CLIPSIBLINGS |					// Required Window Style
							WS_CLIPCHILDREN,					// Required Window Style
							0, 0,									// Window Position
							WindowRect.right-WindowRect.left,
							WindowRect.bottom-WindowRect.top,
							NULL,									// No Parent Window
							NULL,									// No Menu
							hInstance,							// Instance
							NULL);								// Dont Pass Anything To WM_CREATE

if (hWnd == NULL) {
	MessageBox(NULL, "CreateWindow() failed:  Cannot create a window.",
	   	"Error", MB_OK);
	return;
}

Thanks for the help guys!
Got it working. I found that I had to call ShowWindow before I create the GL context … not sure why, but now it work at least.

btw Paddy, do most of that code originally come from a nehe tutorial?

In fact is comes from SGI …
Nehe also has his sources

Aha … I see

While trying to solve the prob I just picked a random nehe tutorial and checked how he did it. I just saw that your code was very very similar … could not be coincidental …

I’m not destroying the main window when I switch to windowed/fullscreen (Nehe do that)… I just use this code to adjust the window properties:

********** constants.h ***************

define OGLWMISC (WS_CLIPSIBLINGS | WS_CLIPCHILDREN)

define OGLW_EXSTYLE_F (WS_EX_APPWINDOW)

define OGLW_STYLE_F (WS_POPUP | OGLWMISC)

define OGLW_EXSTYLE_W (WS_EX_APPWINDOW | WS_EX_WINDOWEDGE)

define OGLW_STYLE_W (WS_OVERLAPPEDWINDOW | OGLWMISC)


Style = (VPFullScreen)? OGLW_STYLE_F : OGLW_STYLE_W;
ExStyle = (VPFullScreen)? OGLW_EXSTYLE_F : OGLW_EXSTYLE_W;

SetWindowLong (SysHwnd, GWL_STYLE, Style);
SetWindowLong (SysHwnd, GWL_EXSTYLE, ExStyle);
SetWindowPos (SysHwnd, NULL, 0, 0,
(renderSpace.right - renderSpace.left),
(renderSpace.bottom - renderSpace.top), SWP_NOOWNERZORDER);

That is wrong? well, actually I’m getting exacly the same performance in windowed and fullscreen… so I think it’s a bad signal…

Should I register the class with fullscreen properties so that the driver chooses pageFlipping istead of a back to frontbuffer copy?

But if I destroy the window, I must re-initialize directsound,directinput, and evertying that depends on the main HWND… this just seems very inefficient…

  • Royconejo.