even though I am working with OGRE since many years this is my first post on the forum!
I am quite sure this is not the right place to post mods and bugfixes. I am aware there is a track system but since
I am not working on the development trunk, please forgive me for this time (and please give directions for future contributions).
I am writing to post a bugfix for the Ogre::Win32Window::setFullscreen(..) method in RenderSystem\GL\src\OgreWin32Windows.cpp.
At the present the function lacks on controlling multiple screen for system with multi monitor and extended desktop (the system RenderWindow for Linux works correctly).
This version handles correctly the fullscreen in a specific display after a window reposition.
Please let me know what you think and if it would work for the community.
Thanks
Code: Select all
void Win32Window::setFullscreen(bool fullScreen, unsigned int width, unsigned int height)
{
if (mIsFullScreen != fullScreen || width != mWidth || height != mHeight)
{
mIsFullScreen = fullScreen;
// Getting current monitor and display info
HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTOPRIMARY);
MONITORINFOEX monitorInfo;
memset(&monitorInfo, 0, sizeof(MONITORINFOEX));
monitorInfo.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfo(hMonitor, &monitorInfo);
UINT flag;
if (mIsFullScreen)
{
DEVMODE displayDeviceMode;
memset(&displayDeviceMode, 0, sizeof(displayDeviceMode));
displayDeviceMode.dmSize = sizeof(DEVMODE);
displayDeviceMode.dmBitsPerPel = mColourDepth;
displayDeviceMode.dmPelsWidth = width;
displayDeviceMode.dmPelsHeight = height;
displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
if (mDisplayFrequency)
{
displayDeviceMode.dmDisplayFrequency = mDisplayFrequency;
displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY;
if (ChangeDisplaySettingsEx(monitorInfo.szDevice, &displayDeviceMode, NULL,
CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL)
{
LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed");
displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY;
}
}
else
{
// try a few
displayDeviceMode.dmDisplayFrequency = 100;
displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY;
if (ChangeDisplaySettingsEx(monitorInfo.szDevice, &displayDeviceMode, NULL,
CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL)
{
displayDeviceMode.dmDisplayFrequency = 75;
if (ChangeDisplaySettingsEx(monitorInfo.szDevice, &displayDeviceMode, NULL,
CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL)
{
displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY;
}
}
}
if (ChangeDisplaySettingsEx(monitorInfo.szDevice, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) {
LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed");
}
SetWindowLongPtr(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen));
// retrieving desktop and current display info
memset(&monitorInfo, 0, sizeof(MONITORINFO));
monitorInfo.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(hMonitor, &monitorInfo);
mWidth = width;
mHeight = height;
mTop = monitorInfo.rcMonitor.top;
mLeft = monitorInfo.rcMonitor.left;
flag = SWP_NOACTIVATE;
}
else
{
// drop out of fullscreen
ChangeDisplaySettingsEx(monitorInfo.szDevice, NULL, NULL, 0, NULL);
// calculate overall dimensions for requested client area
unsigned int winWidth, winHeight;
adjustWindow(width, height, &winWidth, &winHeight);
// deal with centering when switching down to smaller resolution
memset(&monitorInfo, 0, sizeof(MONITORINFO));
monitorInfo.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(hMonitor, &monitorInfo);
// Reset to default style
SetWindowLongPtr(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen));
LONG screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
LONG screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
mWidth = winWidth;
mHeight = winHeight;
mLeft = screenw > winWidth ? ((screenw - winWidth) / 2) : 0;
mTop = screenh > winHeight ? ((screenh - winHeight) / 2) : 0;
flag = SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE;
}
// Notify viewports of resize
ViewportList::iterator it = mViewportList.begin();
while( it != mViewportList.end() )
(*it++).second->_updateDimensions();
// Window reposition and dim
SetWindowPos(mHWnd, HWND_NOTOPMOST, mLeft, mTop, mWidth, mHeight, flag);
}
}