Merge branch 'fullscreen-api-nonrecreate' into dev
This commit is contained in:
commit
3a7f91cb07
7 changed files with 136 additions and 20 deletions
|
|
@ -24,7 +24,19 @@ void DisplayExample::onEvent(const sp::Event& event)
|
||||||
{
|
{
|
||||||
if (event.type == sp::Event::Key && event.key.pressed == false) {
|
if (event.type == sp::Event::Key && event.key.pressed == false) {
|
||||||
|
|
||||||
if (event.key.code == sp::Keyboard::Space) {
|
if (event.key.code == sp::Keyboard::W) {
|
||||||
|
|
||||||
|
if (m_mode == sp::Display::WINDOWED) {
|
||||||
|
m_mode = sp::Display::WINDOWEDFULLSCREEN;
|
||||||
|
sp::Log::info("Windowed Fullscreen");
|
||||||
|
} else {
|
||||||
|
m_mode = sp::Display::WINDOWED;
|
||||||
|
sp::Log::info("Windowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
getGraphics()->setDisplayMode(m_mode);
|
||||||
|
|
||||||
|
} else if (event.key.code == sp::Keyboard::Space) {
|
||||||
|
|
||||||
if (m_mode == sp::Display::WINDOWED) {
|
if (m_mode == sp::Display::WINDOWED) {
|
||||||
m_mode = sp::Display::FULLSCREEN;
|
m_mode = sp::Display::FULLSCREEN;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "DisplayMode.h"
|
#include "DisplayMode.h"
|
||||||
#include "DisplayDescription.h"
|
#include "DisplayDescription.h"
|
||||||
|
#include <Spectre/Math/Vector2.h>
|
||||||
#include <Spectre/Display/GLContext.h>
|
#include <Spectre/Display/GLContext.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -71,6 +72,10 @@ protected :
|
||||||
protected :
|
protected :
|
||||||
enum Mode m_fmode;
|
enum Mode m_fmode;
|
||||||
|
|
||||||
|
// Cache window position when entering fullscreen
|
||||||
|
// So it can be restored when returning to window mode.
|
||||||
|
Vector2u m_cachePos;
|
||||||
|
|
||||||
DisplayDescription m_description;
|
DisplayDescription m_description;
|
||||||
DisplayDescription m_cacheDesc;
|
DisplayDescription m_cacheDesc;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,28 +98,39 @@ void Display::setSize(unsigned int width, unsigned int height)
|
||||||
|
|
||||||
void Display::setVideoMode(Mode mode)
|
void Display::setVideoMode(Mode mode)
|
||||||
{
|
{
|
||||||
DisplayDescription desc;
|
|
||||||
|
|
||||||
if (m_fmode == mode) {
|
if (m_fmode == mode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mode != FULLSCREEN) {
|
||||||
|
m_impl->exitFullscreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache window position when entering fullscreen.
|
||||||
if (mode == FULLSCREEN || mode == WINDOWEDFULLSCREEN) {
|
if (mode == FULLSCREEN || mode == WINDOWEDFULLSCREEN) {
|
||||||
|
m_cachePos = m_impl->getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
// True fullscreen
|
// True fullscreen
|
||||||
if (mode == FULLSCREEN) {
|
if (mode == FULLSCREEN) {
|
||||||
desc.mode = m_description.mode;
|
m_impl->enterFullscreen(m_description.mode);
|
||||||
} else {
|
|
||||||
desc.mode = DisplayMode::getDesktopMode();
|
|
||||||
m_cacheDesc = m_description;
|
|
||||||
}
|
}
|
||||||
|
// Windowed fullscreen.
|
||||||
desc.decoration = DisplayDecorate::None;
|
else if (mode == WINDOWEDFULLSCREEN) {
|
||||||
} else {
|
DisplayMode desktop = DisplayMode::getDesktopMode();
|
||||||
desc = m_cacheDesc;
|
m_impl->setDecoration(DisplayDecorate::None);
|
||||||
|
m_impl->setSize(desktop.width, desktop.height);
|
||||||
|
m_impl->setPosition(0, 0);
|
||||||
}
|
}
|
||||||
|
// Window mode.
|
||||||
|
else {
|
||||||
|
// Set stored decoration.
|
||||||
|
m_impl->setDecoration(m_description.decoration);
|
||||||
|
|
||||||
create(desc);
|
// Restore size and position.
|
||||||
|
m_impl->setSize(m_description.mode.width, m_description.mode.height);
|
||||||
|
m_impl->setPosition(m_cachePos.x, m_cachePos.y);
|
||||||
|
}
|
||||||
|
|
||||||
m_fmode = mode;
|
m_fmode = mode;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ bool Graphics::init()
|
||||||
DisplayMode mode(m_width, m_height);
|
DisplayMode mode(m_width, m_height);
|
||||||
DisplayDescription desc(mode);
|
DisplayDescription desc(mode);
|
||||||
|
|
||||||
desc.decoration = DisplayDecorate::Menu | DisplayDecorate::Close | DisplayDecorate::Resize;
|
|
||||||
|
|
||||||
if (!m_display->create(desc)) {
|
if (!m_display->create(desc)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <Spectre/Math/Vector2.h>
|
#include <Spectre/Math/Vector2.h>
|
||||||
#include <Spectre/Display/DisplayDescription.h>
|
#include <Spectre/Display/DisplayDescription.h>
|
||||||
|
#include <Spectre/Display/DisplayMode.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
@ -39,10 +40,16 @@ public :
|
||||||
|
|
||||||
virtual void setVisible(bool visible) = 0;
|
virtual void setVisible(bool visible) = 0;
|
||||||
|
|
||||||
|
virtual void setDecoration(unsigned decoration) = 0;
|
||||||
|
|
||||||
virtual void minimize() = 0;
|
virtual void minimize() = 0;
|
||||||
|
|
||||||
virtual void maximize() = 0;
|
virtual void maximize() = 0;
|
||||||
|
|
||||||
|
virtual void enterFullscreen(DisplayMode mode) = 0;
|
||||||
|
|
||||||
|
virtual void exitFullscreen() = 0;
|
||||||
|
|
||||||
virtual void setCaption(const std::string& caption) = 0;
|
virtual void setCaption(const std::string& caption) = 0;
|
||||||
|
|
||||||
virtual void setIcon(unsigned int width, unsigned int height, const uint8_t *pixels) = 0;
|
virtual void setIcon(unsigned int width, unsigned int height, const uint8_t *pixels) = 0;
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ Win32Display::~Win32Display()
|
||||||
|
|
||||||
bool Win32Display::create(DisplayDescription description)
|
bool Win32Display::create(DisplayDescription description)
|
||||||
{
|
{
|
||||||
DWORD flags = getWin32Flags(description.decoration);
|
DWORD flags;
|
||||||
Vector2i pos;
|
Vector2i pos;
|
||||||
|
|
||||||
if (firstTime) {
|
if (firstTime) {
|
||||||
|
|
@ -49,7 +49,9 @@ bool Win32Display::create(DisplayDescription description)
|
||||||
firstTime = false;
|
firstTime = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set window to center and set decoration flags.
|
||||||
pos = centerWindow(description.mode.width, description.mode.height);
|
pos = centerWindow(description.mode.width, description.mode.height);
|
||||||
|
flags = getWin32Flags(description.decoration);
|
||||||
|
|
||||||
// Create window.
|
// Create window.
|
||||||
m_handle = CreateWindowExA(0, WND_CLASSNAME, "", flags,
|
m_handle = CreateWindowExA(0, WND_CLASSNAME, "", flags,
|
||||||
|
|
@ -128,6 +130,11 @@ void Win32Display::setVisible(bool visible)
|
||||||
::ShowWindow(m_handle, visible ? SW_SHOW : SW_HIDE);
|
::ShowWindow(m_handle, visible ? SW_SHOW : SW_HIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Win32Display::setDecoration(unsigned decoration)
|
||||||
|
{
|
||||||
|
::SetWindowLong(m_handle, GWL_STYLE, getWin32Flags(decoration));
|
||||||
|
}
|
||||||
|
|
||||||
void Win32Display::minimize()
|
void Win32Display::minimize()
|
||||||
{
|
{
|
||||||
::ShowWindow(m_handle, SW_MINIMIZE);
|
::ShowWindow(m_handle, SW_MINIMIZE);
|
||||||
|
|
@ -277,6 +284,60 @@ Vector2i Win32Display::centerWindow(int width, int height)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Win32Display::enterFullscreen(DisplayMode mode)
|
||||||
|
{
|
||||||
|
LONG rc;
|
||||||
|
::DEVMODEW dev;
|
||||||
|
dev.dmSize = sizeof(dev);
|
||||||
|
dev.dmPelsWidth = mode.width;
|
||||||
|
dev.dmPelsHeight = mode.height;
|
||||||
|
dev.dmBitsPerPel = mode.bpp;
|
||||||
|
dev.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
|
||||||
|
|
||||||
|
rc = ::ChangeDisplaySettingsW(&dev, CDS_FULLSCREEN);
|
||||||
|
if (rc != DISP_CHANGE_SUCCESSFUL) {
|
||||||
|
const char *msg;
|
||||||
|
|
||||||
|
switch(rc) {
|
||||||
|
case DISP_CHANGE_BADDUALVIEW :
|
||||||
|
msg = "The system is DualView capable"; break;
|
||||||
|
case DISP_CHANGE_BADFLAGS :
|
||||||
|
msg = "Invalid flags given"; break;
|
||||||
|
case DISP_CHANGE_BADPARAM :
|
||||||
|
msg = "Invalid parameter"; break;
|
||||||
|
case DISP_CHANGE_BADMODE :
|
||||||
|
msg = "Resolution not supported"; break;
|
||||||
|
case DISP_CHANGE_FAILED :
|
||||||
|
msg = "Display driver failed to set mode"; break;
|
||||||
|
case DISP_CHANGE_NOTUPDATED :
|
||||||
|
msg = "Unable to write settings to the registry"; break;
|
||||||
|
case DISP_CHANGE_RESTART :
|
||||||
|
msg = "System restart required"; break;
|
||||||
|
default :
|
||||||
|
msg = "Unkown error";
|
||||||
|
}
|
||||||
|
|
||||||
|
sp::Log::error("Win32: Failed to switch to fullscreen mode: %s.", msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
::SetWindowLong(m_handle, GWL_STYLE, WS_VISIBLE | WS_POPUP);
|
||||||
|
::SetWindowPos(m_handle, HWND_TOP, 0, 0, mode.width, mode.height, SWP_FRAMECHANGED | SWP_SHOWWINDOW);
|
||||||
|
|
||||||
|
grabCursor(true);
|
||||||
|
|
||||||
|
m_fs_mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32Display::exitFullscreen()
|
||||||
|
{
|
||||||
|
if (!m_fs_mode.empty()) {
|
||||||
|
// Restore to previous mode.
|
||||||
|
::ChangeDisplaySettingsW(NULL, 0);
|
||||||
|
m_fs_mode = DisplayMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Win32Display::processResizeMessage(const Vector2u& new_size)
|
void Win32Display::processResizeMessage(const Vector2u& new_size)
|
||||||
{
|
{
|
||||||
// Check if the size has actually changed.
|
// Check if the size has actually changed.
|
||||||
|
|
@ -301,9 +362,22 @@ void Win32Display::processMessage(UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
break;
|
break;
|
||||||
case WM_SETFOCUS :
|
case WM_SETFOCUS :
|
||||||
Log::debug("WM_SETFOCUS");
|
Log::debug("WM_SETFOCUS");
|
||||||
|
if (m_fs_mode.empty() == false) {
|
||||||
|
enterFullscreen(m_fs_mode);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WM_KILLFOCUS :
|
case WM_KILLFOCUS :
|
||||||
Log::debug("WM_KILLFOCUS");
|
Log::debug("WM_KILLFOCUS");
|
||||||
|
// If in fullscreen mode.
|
||||||
|
if (m_fs_mode.empty() == false) {
|
||||||
|
// Switch to window mode.
|
||||||
|
::ChangeDisplaySettingsW(NULL, 0);
|
||||||
|
|
||||||
|
// also minimize the window to get it out of the way.
|
||||||
|
minimize();
|
||||||
|
}
|
||||||
|
|
||||||
|
grabCursor(false);
|
||||||
break;
|
break;
|
||||||
case WM_SIZE :
|
case WM_SIZE :
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,12 @@ public :
|
||||||
|
|
||||||
virtual void setVisible(bool visible);
|
virtual void setVisible(bool visible);
|
||||||
|
|
||||||
|
virtual void setDecoration(unsigned decoration);
|
||||||
|
|
||||||
|
virtual void enterFullscreen(DisplayMode mode);
|
||||||
|
|
||||||
|
virtual void exitFullscreen();
|
||||||
|
|
||||||
virtual void minimize();
|
virtual void minimize();
|
||||||
|
|
||||||
virtual void maximize();
|
virtual void maximize();
|
||||||
|
|
@ -74,6 +80,9 @@ protected :
|
||||||
Vector2u m_size;
|
Vector2u m_size;
|
||||||
|
|
||||||
Vector2u m_minSize;
|
Vector2u m_minSize;
|
||||||
|
|
||||||
|
// Fullscreen mode.
|
||||||
|
DisplayMode m_fs_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sp
|
} // namespace sp
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue