PDA

View Full Version : Weird fullscreen/acclerated problem



Pirateman
02-22-2001, 05:40 PM
My engine allows the user to choose between software and hardware acclereated modes, and windowed and fullscreen modes. Both software and hardware use OpenGL, and as it is they use the same code, too. Software mode works just fine, fullscreen and windowed. Hardware mode works fine windowed, but it does all kinds of goofy things in fullscreen. I'm pretty new to OGL and can't find any reason for what's happening. Here's the initialization code (simplified a bit):

//Things already initialized elsewhere
HWND window;
bool windowed;
int bpp, width, height, refresh;
int mode; //HARDWARE or SOFTWARE

//Other members
HGLRC OpenGL;
HWND deviceWindow;
DEVMODE displaymode;
PIXELFORMATDESCRIPTOR pixelFormat, current;
int i;
HDC deviceContext;

if(!windowed) //Fullscreen
{
//Set new resolution
displaymode.dmSize = sizeof(DEVMODE);
displaymode.dmBitsPerPel = bpp;
displaymode.dmPelsWidth = width;
displaymode.dmPelsHeight = height;
displaymode.dmDisplayFrequency = refresh;
displaymode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

if(refresh)
displaymode.dmFields |= DM_DISPLAYFREQUENCY;

if(DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettings(&displaymode, CDS_FULLSCREEN))
return false;
}

//NULL means the whole screen
deviceWnd = windowed ? window : NULL;
deviceContext = GetDC(deviceWnd);
if(!deviceContext)
return false;

//Set the pixel format
numPFormats = DescribePixelFormat(deviceContext, 1, 0, NULL);

//Initialize
current.nSize = sizeof(PIXELFORMATDESCRIPTOR);
current.nVersion = 1;
ZeroMemory(&pixelFormat, sizeof(PIXELFORMATDESCRIPTOR));

//Iterate through pixel formats
for(i = 1;i <= numPFormats;i++)
{
DescribePixelFormat(deviceContext, i, current.nSize, &current);

if((current.dwFlags & PFD_DOUBLEBUFFER) &&
(current.dwFlags & PFD_SUPPORT_OPENGL) &&
(current.dwFlags & PFD_DRAW_TO_WINDOW) &&
(current.iPixelType == PFD_TYPE_RGBA) &&
(current.cColorBits >= 16) &&
current.cDepthBits)
{
switch(mode)
{
case HARDWARE:
if(current.dwFlags & PFD_GENERIC_FORMAT)
continue;
break;
case SOFTWARE:
if(!current.dwFlags & PFD_GENERIC_FORMAT)
continue;
break;
}

if(current.cColorBits > pixelFormat.cColorBits)
{
memcpy(&pixelFormat, &current, sizeof(PIXELFORMATDESCRIPTOR));
selected = i;
}
else if(current.cDepthBits > pixelFormat.cDepthBits)
{
memcpy(&pixelFormat, &current, sizeof(PIXELFORMATDESCRIPTOR));
selected = i;
}
}
}

//This checks if a good format was found
if(pixelFormat.nSize == 0)
return false;

if(!SetPixelFormat(deviceContext, selected, &pixelFormat))
return false;
OpenGL = wglCreateContext(deviceContext);
if(!OpenGL)
return false;
if(!wglMakeCurrent(deviceContext, OpenGL))
return false;

return true;


And my cleanup code looks like this:

glFlush();
wglMakeCurrent(NULL, NULL);
wglDeleteContext(OpenGL);
ReleaseDC(deviceWindow, deviceContext);
ChangeDisplaySettings(NULL, 0);


The problem heppsn with or without any actual rendering, so it must be caused somewhere in the above code. If anyone sees a problem, please tell me! Oh, and if you need more info, just ask. Thanks a lot!

-Evan

mango
02-22-2001, 06:02 PM
What kind of goofy things?
How do you go to and leave fullscreen mode? ( how is the window created/destroyed)

Pirateman
02-22-2001, 08:44 PM
Originally posted by mango:
What kind of goofy things?
How do you go to and leave fullscreen mode? ( how is the window created/destroyed)

Well, The window itself is only created once at the beginning of the program and destroyed at the end. The way I switch to fullscreen is by running the cleanup code mentioned in my other message, changing some variables and then running the init code again. Here's the specifics of how the window is created:

wc.style = CS_BYTEALIGNWINDOW | CS_BYTEALIGNCLIENT | CS_CLASSDC | CS_SAVEBITS;
wc.lpfnWndProc = DealWithMessages;
wc.cbClsExtra = wc.cbWndExtra = 0;
wc.hInstance = AfxGetInstanceHandle();
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = name;

if (!RegisterClass(&wc))
TRACE("Failure to register the window class\n");

handle = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_CLIENTEDGE, "Window", _T("Window"), WS_SIZEBOX | WS_CAPTION | WS_VISIBLE | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, x, y, width, height, NULL, NULL, AfxGetInstanceHandle(), NULL);

Could the problem lie in the message handler? Are there any special messages OGL send I should consider?

Thanks for helping!

Bob
02-23-2001, 04:06 AM
That windowcreation code, is that for creating a fullscreen windows aswell? If it is, it should give you some problems. A fullscreen window should have the WS_POPUP flag set, and should be placed at (0,0), with width and height the same as the fullscreen enviroment.

Take a look at NeHe's site (http://nehe.gamedev.net) for window/fullscreen code in Win32.

Pirateman
02-23-2001, 01:57 PM
Originally posted by Bob:
That windowcreation code, is that for creating a fullscreen windows aswell? If it is, it should give you some problems. A fullscreen window should have the WS_POPUP flag set, and should be placed at (0,0), with width and height the same as the fullscreen enviroment.

Take a look at NeHe's site (http://nehe.gamedev.net) for window/fullscreen code in Win32.

Actually, no, the same window isn't used. What I do, if you infer from the init code I gave, is get the DC of the screen by effectively doing GetDC(NULL) if in fullscreen mode.

However, you have given me a couple ideas that I'd like to try. Perhaps if I maximized my window and gave it the DC of the whole thing (including the frame)... yes I believe that might work. I'll just have my message handler ignore WM_NCPAINT messages in those cases, just for completeness.

Well, I'll tell you how it goes! And thanks for the help (however inadvertent =P )!!

-Evan

Pirateman
02-24-2001, 02:34 PM
Nope. Didn't work. But I'll continue to try other things...

mango
02-25-2001, 01:00 AM
Why not create the window with the same setting as NeHe?
As mentioned earlier can you not create a fullscreen window with your settings.

Bob
02-25-2001, 02:38 AM
Well, as mango said. Using that code for fullscreen environments won't work. I didn't asked if you used the same window, I asked if you used the same code to create the window, wether it was a fullscreen window or not.

When creating a fullscreen window, you can use these flags: WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS. Works great for me. And don't forget to place the window at (0,0).

Pirateman
02-25-2001, 06:41 PM
Worked! Thanks guys!