Fixed: #980 Create a setScreenMode method in OpenGL driver

This commit is contained in:
kervala 2010-06-12 17:38:03 +02:00
parent a6ddd4152f
commit 9f13de0d2a
2 changed files with 110 additions and 91 deletions

View file

@ -846,6 +846,7 @@ private:
bool restoreScreenMode(); bool restoreScreenMode();
bool saveScreenMode(); bool saveScreenMode();
bool setScreenMode(const GfxMode &mode);
// Get the proj matrix setupped in GL // Get the proj matrix setupped in GL
void refreshProjMatrixFromGL(); void refreshProjMatrixFromGL();

View file

@ -209,6 +209,9 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
uint width = mode.Width; uint width = mode.Width;
uint height = mode.Height; uint height = mode.Height;
if (!setScreenMode(mode))
return false;
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
// Driver caps. // Driver caps.
@ -541,32 +544,6 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
WndFlags=WS_POPUP; WndFlags=WS_POPUP;
_FullScreen= true; _FullScreen= true;
DEVMODE devMode;
_OldScreenMode.dmSize= sizeof(DEVMODE);
_OldScreenMode.dmDriverExtra= 0;
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &_OldScreenMode);
_OldScreenMode.dmFields= DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY ;
devMode.dmSize= sizeof(DEVMODE);
devMode.dmDriverExtra= 0;
devMode.dmFields= DM_PELSWIDTH | DM_PELSHEIGHT;
devMode.dmPelsWidth= width;
devMode.dmPelsHeight= height;
if(mode.Depth > 0)
{
devMode.dmBitsPerPel= mode.Depth;
devMode.dmFields |= DM_BITSPERPEL;
}
if(mode.Frequency > 0)
{
devMode.dmDisplayFrequency= mode.Frequency;
devMode.dmFields |= DM_DISPLAYFREQUENCY;
}
if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
return false;
} }
WndRect.left=0; WndRect.left=0;
WndRect.top=0; WndRect.top=0;
@ -877,51 +854,122 @@ bool CDriverGL::restoreScreenMode()
} }
// -------------------------------------------------- // --------------------------------------------------
bool CDriverGL::setMode(const GfxMode& mode) bool CDriverGL::setScreenMode(const GfxMode &mode)
{ {
H_AUTO_OGL(CDriverGL_setMode) H_AUTO_OGL(CDriverGL_setScreenMode)
#ifdef NL_OS_WINDOWS
if (mode.Windowed) if (mode.Windowed)
{ {
// if fullscreen, switch back to desktop screen mode
if (_FullScreen) if (_FullScreen)
{
restoreScreenMode(); restoreScreenMode();
modifyStyle(_hWnd, GWL_STYLE, WS_POPUP, WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS);
}
_WindowWidth = mode.Width;
_WindowHeight = mode.Height;
return true;
} }
else
{ // save previous screen mode only if switching from windowed to fullscreen
// get old mode.
if (!_FullScreen) if (!_FullScreen)
saveScreenMode(); saveScreenMode();
// setup new mode // if switching exactly to the same screen mode, doesn't change it
DEVMODE newDevMode; GfxMode previousMode;
newDevMode.dmSize= sizeof(DEVMODE); if (getCurrentScreenMode(previousMode)
newDevMode.dmDriverExtra= 0; && mode.Width == previousMode.Width
newDevMode.dmFields= DM_PELSWIDTH | DM_PELSHEIGHT; && mode.Height == previousMode.Height
newDevMode.dmPelsWidth= mode.Width; && mode.Depth == previousMode.Depth
newDevMode.dmPelsHeight= mode.Height; && mode.Frequency == previousMode.Frequency)
return true;
#if defined(NL_OS_WINDOWS)
DEVMODE devMode;
memset(&devMode, 0, sizeof(DEVMODE));
devMode.dmSize = sizeof(DEVMODE);
devMode.dmDriverExtra = 0;
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
devMode.dmPelsWidth = mode.Width;
devMode.dmPelsHeight = mode.Height;
if(mode.Depth > 0) if(mode.Depth > 0)
{ {
newDevMode.dmBitsPerPel= mode.Depth; devMode.dmBitsPerPel = mode.Depth;
newDevMode.dmFields |= DM_BITSPERPEL; devMode.dmFields |= DM_BITSPERPEL;
} }
if(mode.Frequency > 0) if(mode.Frequency > 0)
{ {
newDevMode.dmDisplayFrequency= mode.Frequency; devMode.dmDisplayFrequency = mode.Frequency;
newDevMode.dmFields |= DM_DISPLAYFREQUENCY; devMode.dmFields |= DM_DISPLAYFREQUENCY;
} }
// try to really change the display mode if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
if (ChangeDisplaySettings(&newDevMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
nlwarning("Fullscreen mode switch failed");
return false;
}
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
// TODO
#elif defined(NL_OS_UNIX)
#if defined(XF86VIDMODE)
bool found = false;
// Find the requested mode and use it
XF86VidModeModeInfo **modes;
int nmodes;
if (XF86VidModeGetAllModeLines(_dpy, DefaultScreen(_dpy), &nmodes, &modes))
{
for (int i = 0; i < nmodes; i++)
{
nldebug("3D: Available mode - %dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
if (modes[i]->hdisplay == width && modes[i]->vdisplay == height)
{
if (XF86VidModeSwitchToMode(_dpy, DefaultScreen(_dpy), modes[i]))
{
nlinfo("3D: Switching to mode %dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
XF86VidModeSetViewPort(_dpy, DefaultScreen(_dpy), 0, 0);
found = true;
}
break;
}
}
XFree(modes);
}
if (!found)
return false; return false;
#endif // XF86VIDMODE
#endif // NL_OS_WINDOWS
return true;
}
// --------------------------------------------------
bool CDriverGL::setMode(const GfxMode& mode)
{
H_AUTO_OGL(CDriverGL_setMode)
if (!setScreenMode(mode))
return false;
#ifdef NL_OS_WINDOWS
if (mode.Windowed)
{
if (_FullScreen)
modifyStyle(_hWnd, GWL_STYLE, WS_POPUP, WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS);
_WindowWidth = mode.Width;
_WindowHeight = mode.Height;
}
else
{
// mode ok => copy changes // mode ok => copy changes
_WindowWidth = mode.Width; _WindowWidth = mode.Width;
_WindowHeight = mode.Height; _WindowHeight = mode.Height;
@ -961,42 +1009,11 @@ bool CDriverGL::setMode(const GfxMode& mode)
_FullScreen = !mode.Windowed; _FullScreen = !mode.Windowed;
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE) #elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
NL3D::MAC::setMode(mode); NL3D::MAC::setMode(mode);
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)
#ifdef XF86VIDMODE
if (!mode.Windowed)
{
int screen = DefaultScreen(_dpy);
// Store old mdoe in order to restore it when leaving fullscreen
if (mode.Windowed == _FullScreen)
saveScreenMode();
// Find the requested mode and use it
XF86VidModeModeInfo **modes;
int nmodes;
if (XF86VidModeGetAllModeLines(_dpy, screen, &nmodes, &modes))
{
for (int i = 0; i < nmodes; i++)
{
nldebug("3D: Available mode - %dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
if(modes[i]->hdisplay == mode.Width && modes[i]->vdisplay == mode.Height)
{
if(XF86VidModeSwitchToMode(_dpy, screen, modes[i]))
{
nlinfo("3D: Switching to mode %dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
XF86VidModeSetViewPort(_dpy, screen, 0, 0);
}
break;
}
}
}
}
else if (mode.Windowed == _FullScreen)
restoreScreenMode();
#endif // XF86VIDMODE
// Update WM hints (update size and disallow resizing) // Update WM hints (update size and disallow resizing)
XSizeHints size_hints; XSizeHints size_hints;
size_hints.x = 0; size_hints.x = 0;
@ -1048,6 +1065,7 @@ bool CDriverGL::setMode(const GfxMode& mode)
XMapWindow(_dpy, _win); XMapWindow(_dpy, _win);
#endif // NL_OS_UNIX #endif // NL_OS_UNIX
return true; return true;
} }