mirror of https://github.com/encounter/SDL.git
WinRT: made rendering work with orientation changes on Windows Phone
Pointer event geometry still needs to be adjusted on Windows Phone, to note.
This commit is contained in:
parent
91b039027f
commit
31235b4b99
|
@ -145,6 +145,77 @@ static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *n
|
||||||
DisplayProperties::AutoRotationPreferences = (DisplayOrientations) orientationFlags;
|
DisplayProperties::AutoRotationPreferences = (DisplayOrientations) orientationFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
WINRT_ProcessWindowSizeChange()
|
||||||
|
{
|
||||||
|
// Make the new window size be the one true fullscreen mode.
|
||||||
|
// This change was initially done, in part, to allow the Direct3D 11.1
|
||||||
|
// renderer to receive window-resize events as a device rotates.
|
||||||
|
// Before, rotating a device from landscape, to portrait, and then
|
||||||
|
// back to landscape would cause the Direct3D 11.1 swap buffer to
|
||||||
|
// not get resized appropriately. SDL would, on the rotation from
|
||||||
|
// landscape to portrait, re-resize the SDL window to it's initial
|
||||||
|
// size (landscape). On the subsequent rotation, SDL would drop the
|
||||||
|
// window-resize event as it appeared the SDL window didn't change
|
||||||
|
// size, and the Direct3D 11.1 renderer wouldn't resize its swap
|
||||||
|
// chain.
|
||||||
|
SDL_DisplayMode resizedDisplayMode = WINRT_CalcDisplayModeUsingNativeWindow();
|
||||||
|
if (resizedDisplayMode.w == 0 || resizedDisplayMode.h == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_DisplayMode oldDisplayMode;
|
||||||
|
SDL_zero(oldDisplayMode);
|
||||||
|
if (WINRT_GlobalSDLVideoDevice) {
|
||||||
|
oldDisplayMode = WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode;
|
||||||
|
WINRT_GlobalSDLVideoDevice->displays[0].current_mode = resizedDisplayMode;
|
||||||
|
WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = resizedDisplayMode;
|
||||||
|
WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0] = resizedDisplayMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WINRT_GlobalSDLWindow) {
|
||||||
|
// Send a window-resize event to the rest of SDL, and to apps:
|
||||||
|
SDL_SendWindowEvent(
|
||||||
|
WINRT_GlobalSDLWindow,
|
||||||
|
SDL_WINDOWEVENT_RESIZED,
|
||||||
|
resizedDisplayMode.w,
|
||||||
|
resizedDisplayMode.h);
|
||||||
|
|
||||||
|
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||||
|
// HACK: On Windows Phone, make sure that orientation changes from
|
||||||
|
// Landscape to LandscapeFlipped, Portrait to PortraitFlipped,
|
||||||
|
// or vice-versa on either of those two, lead to the Direct3D renderer
|
||||||
|
// getting updated.
|
||||||
|
const DisplayOrientations oldOrientation = (DisplayOrientations) (unsigned int) oldDisplayMode.driverdata;
|
||||||
|
const DisplayOrientations newOrientation = (DisplayOrientations) (unsigned int) resizedDisplayMode.driverdata;
|
||||||
|
|
||||||
|
if ((oldOrientation == DisplayOrientations::Landscape && newOrientation == DisplayOrientations::LandscapeFlipped) ||
|
||||||
|
(oldOrientation == DisplayOrientations::LandscapeFlipped && newOrientation == DisplayOrientations::Landscape) ||
|
||||||
|
(oldOrientation == DisplayOrientations::Portrait && newOrientation == DisplayOrientations::PortraitFlipped) ||
|
||||||
|
(oldOrientation == DisplayOrientations::PortraitFlipped && newOrientation == DisplayOrientations::Portrait))
|
||||||
|
{
|
||||||
|
// One of the reasons this event is getting sent out is because SDL
|
||||||
|
// will ignore requests to send out SDL_WINDOWEVENT_RESIZED events
|
||||||
|
// if and when the event size doesn't change (and the Direct3D 11.1
|
||||||
|
// renderer doesn't get the memo).
|
||||||
|
//
|
||||||
|
// Make sure that the display/window size really didn't change. If
|
||||||
|
// it did, then a SDL_WINDOWEVENT_SIZE_CHANGED event got sent, and
|
||||||
|
// the Direct3D 11.1 renderer picked it up, presumably.
|
||||||
|
if (oldDisplayMode.w == resizedDisplayMode.w &&
|
||||||
|
oldDisplayMode.h == resizedDisplayMode.h)
|
||||||
|
{
|
||||||
|
SDL_SendWindowEvent(
|
||||||
|
WINRT_GlobalSDLWindow,
|
||||||
|
SDL_WINDOWEVENT_SIZE_CHANGED,
|
||||||
|
resizedDisplayMode.w,
|
||||||
|
resizedDisplayMode.h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDL_WinRTApp::SDL_WinRTApp() :
|
SDL_WinRTApp::SDL_WinRTApp() :
|
||||||
m_windowClosed(false),
|
m_windowClosed(false),
|
||||||
m_windowVisible(true)
|
m_windowVisible(true)
|
||||||
|
@ -194,6 +265,13 @@ void SDL_WinRTApp::OnOrientationChanged(Object^ sender)
|
||||||
(int)DisplayProperties::AutoRotationPreferences);
|
(int)DisplayProperties::AutoRotationPreferences);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||||
|
// On Windows Phone, treat an orientation change as a change in window size.
|
||||||
|
// The native window's size doesn't seem to change, however SDL will simulate
|
||||||
|
// a window size change.
|
||||||
|
WINRT_ProcessWindowSizeChange();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_WinRTApp::SetWindow(CoreWindow^ window)
|
void SDL_WinRTApp::SetWindow(CoreWindow^ window)
|
||||||
|
@ -294,32 +372,7 @@ void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEven
|
||||||
(WINRT_GlobalSDLWindow ? "yes" : "no"));
|
(WINRT_GlobalSDLWindow ? "yes" : "no"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (WINRT_GlobalSDLWindow) {
|
WINRT_ProcessWindowSizeChange();
|
||||||
// Make the new window size be the one true fullscreen mode.
|
|
||||||
// This change was initially done, in part, to allow the Direct3D 11.1
|
|
||||||
// renderer to receive window-resize events as a device rotates.
|
|
||||||
// Before, rotating a device from landscape, to portrait, and then
|
|
||||||
// back to landscape would cause the Direct3D 11.1 swap buffer to
|
|
||||||
// not get resized appropriately. SDL would, on the rotation from
|
|
||||||
// landscape to portrait, re-resize the SDL window to it's initial
|
|
||||||
// size (landscape). On the subsequent rotation, SDL would drop the
|
|
||||||
// window-resize event as it appeared the SDL window didn't change
|
|
||||||
// size, and the Direct3D 11.1 renderer wouldn't resize its swap
|
|
||||||
// chain.
|
|
||||||
SDL_DisplayMode resizedDisplayMode = WINRT_CalcDisplayModeUsingNativeWindow();
|
|
||||||
WINRT_GlobalSDLVideoDevice->displays[0].current_mode = resizedDisplayMode;
|
|
||||||
WINRT_GlobalSDLVideoDevice->displays[0].desktop_mode = resizedDisplayMode;
|
|
||||||
WINRT_GlobalSDLVideoDevice->displays[0].display_modes[0] = resizedDisplayMode;
|
|
||||||
|
|
||||||
// Send the window-resize event to the rest of SDL, and to apps:
|
|
||||||
const int windowWidth = (int) ceil(args->Size.Width);
|
|
||||||
const int windowHeight = (int) ceil(args->Size.Height);
|
|
||||||
SDL_SendWindowEvent(
|
|
||||||
WINRT_GlobalSDLWindow,
|
|
||||||
SDL_WINDOWEVENT_RESIZED,
|
|
||||||
windowWidth,
|
|
||||||
windowHeight);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
|
void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
|
||||||
|
|
|
@ -920,7 +920,7 @@ D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
||||||
{
|
{
|
||||||
//D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
|
//D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
|
||||||
|
|
||||||
if (event->event == SDL_WINDOWEVENT_RESIZED) {
|
if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||||
D3D11_UpdateForWindowSizeChange(renderer);
|
D3D11_UpdateForWindowSizeChange(renderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1215,16 +1215,16 @@ D3D11_UpdateViewport(SDL_Renderer * renderer)
|
||||||
// Windows Phone rotations
|
// Windows Phone rotations
|
||||||
//
|
//
|
||||||
case DisplayOrientations::Landscape:
|
case DisplayOrientations::Landscape:
|
||||||
// 90-degree Z-rotation
|
// 270-degree (-90 degree) Z-rotation
|
||||||
XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PIDIV2));
|
XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(-XM_PIDIV2));
|
||||||
break;
|
break;
|
||||||
case DisplayOrientations::Portrait:
|
case DisplayOrientations::Portrait:
|
||||||
// 0-degree Z-rotation
|
// 0-degree Z-rotation
|
||||||
XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixIdentity());
|
XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixIdentity());
|
||||||
break;
|
break;
|
||||||
case DisplayOrientations::LandscapeFlipped:
|
case DisplayOrientations::LandscapeFlipped:
|
||||||
// 270-degree (-90 degree) Z-rotation
|
// 90-degree Z-rotation
|
||||||
XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(-XM_PIDIV2));
|
XMStoreFloat4x4(&data->vertexShaderConstantsData.projection, XMMatrixRotationZ(XM_PIDIV2));
|
||||||
break;
|
break;
|
||||||
case DisplayOrientations::PortraitFlipped:
|
case DisplayOrientations::PortraitFlipped:
|
||||||
// 180-degree Z-rotation
|
// 180-degree Z-rotation
|
||||||
|
@ -1280,11 +1280,15 @@ D3D11_UpdateViewport(SDL_Renderer * renderer)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Update the Direct3D viewport, which seems to be aligned to the
|
// Update the Direct3D viewport, which seems to be aligned to the
|
||||||
// swap buffer's coordinate space, which is always in landscape:
|
// swap buffer's coordinate space, which is always in either
|
||||||
|
// a landscape mode, for all Windows 8/RT devices, or a portrait mode,
|
||||||
|
// for Windows Phone devices.
|
||||||
//
|
//
|
||||||
SDL_FRect orientationAlignedViewport;
|
SDL_FRect orientationAlignedViewport;
|
||||||
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||||
const bool swapDimensions = false;
|
const bool swapDimensions =
|
||||||
|
data->orientation == DisplayOrientations::Landscape ||
|
||||||
|
data->orientation == DisplayOrientations::LandscapeFlipped;
|
||||||
#else
|
#else
|
||||||
const bool swapDimensions =
|
const bool swapDimensions =
|
||||||
data->orientation == DisplayOrientations::Portrait ||
|
data->orientation == DisplayOrientations::Portrait ||
|
||||||
|
|
|
@ -154,6 +154,8 @@ WINRT_VideoInit(_THIS)
|
||||||
SDL_DisplayMode
|
SDL_DisplayMode
|
||||||
WINRT_CalcDisplayModeUsingNativeWindow()
|
WINRT_CalcDisplayModeUsingNativeWindow()
|
||||||
{
|
{
|
||||||
|
using namespace Windows::Graphics::Display;
|
||||||
|
|
||||||
// Create an empty, zeroed-out display mode:
|
// Create an empty, zeroed-out display mode:
|
||||||
SDL_DisplayMode mode;
|
SDL_DisplayMode mode;
|
||||||
SDL_zero(mode);
|
SDL_zero(mode);
|
||||||
|
@ -168,7 +170,7 @@ WINRT_CalcDisplayModeUsingNativeWindow()
|
||||||
// Fill in most fields:
|
// Fill in most fields:
|
||||||
mode.format = SDL_PIXELFORMAT_RGB888;
|
mode.format = SDL_PIXELFORMAT_RGB888;
|
||||||
mode.refresh_rate = 0; // TODO, WinRT: see if refresh rate data is available, or relevant (for WinRT apps)
|
mode.refresh_rate = 0; // TODO, WinRT: see if refresh rate data is available, or relevant (for WinRT apps)
|
||||||
mode.driverdata = NULL;
|
mode.driverdata = (void *) DisplayProperties::CurrentOrientation;
|
||||||
|
|
||||||
// Calculate the display size given the window size, taking into account
|
// Calculate the display size given the window size, taking into account
|
||||||
// the current display's DPI:
|
// the current display's DPI:
|
||||||
|
@ -177,6 +179,30 @@ WINRT_CalcDisplayModeUsingNativeWindow()
|
||||||
mode.w = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Width * currentDPI) / dipsPerInch);
|
mode.w = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Width * currentDPI) / dipsPerInch);
|
||||||
mode.h = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Height * currentDPI) / dipsPerInch);
|
mode.h = (int) ((CoreWindow::GetForCurrentThread()->Bounds.Height * currentDPI) / dipsPerInch);
|
||||||
|
|
||||||
|
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||||
|
// On Windows Phone, the native window's size is always in portrait,
|
||||||
|
// regardless of the device's orientation. This is in contrast to
|
||||||
|
// Windows 8/RT, which will resize the native window as the device's
|
||||||
|
// orientation changes. In order to compensate for this behavior,
|
||||||
|
// on Windows Phone, the mode's width and height will be swapped when
|
||||||
|
// the device is in a landscape (non-portrait) mode.
|
||||||
|
switch (DisplayProperties::CurrentOrientation) {
|
||||||
|
case DisplayOrientations::Landscape:
|
||||||
|
case DisplayOrientations::LandscapeFlipped:
|
||||||
|
{
|
||||||
|
const int tmp = mode.h;
|
||||||
|
mode.h = mode.w;
|
||||||
|
mode.w = tmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach the mode to te
|
||||||
|
#endif
|
||||||
|
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue