WinRT: bug fixes for device orientation + Direct3D 11.1 rendering
This commit is contained in:
parent
19ff37c4b3
commit
4a906d9edf
4 changed files with 115 additions and 23 deletions
|
@ -30,6 +30,8 @@ extern "C" {
|
|||
#include "SDL_system.h"
|
||||
#include "SDL_syswm.h"
|
||||
#include "../SDL_sysrender.h"
|
||||
#include "SDL_log.h"
|
||||
#include "../../video/SDL_sysvideo.h"
|
||||
//#include "stdio.h"
|
||||
}
|
||||
|
||||
|
@ -561,7 +563,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
|
|||
// landscape-oriented width and height. If the window is in a portrait
|
||||
// orientation, the dimensions must be reversed.
|
||||
data->orientation = DisplayProperties::CurrentOrientation;
|
||||
bool swapDimensions =
|
||||
const bool swapDimensions =
|
||||
data->orientation == DisplayOrientations::Portrait ||
|
||||
data->orientation == DisplayOrientations::PortraitFlipped;
|
||||
data->renderTargetSize.x = swapDimensions ? windowHeight : windowWidth;
|
||||
|
@ -930,9 +932,9 @@ D3D11_UpdateViewport(SDL_Renderer * renderer)
|
|||
break;
|
||||
|
||||
case DisplayOrientations::Portrait:
|
||||
data->vertexShaderConstantsData.projection = XMFLOAT4X4( // 270-degree Z-rotation
|
||||
0.0f, -1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
data->vertexShaderConstantsData.projection = XMFLOAT4X4( // 90-degree Z-rotation
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
);
|
||||
|
@ -948,9 +950,9 @@ D3D11_UpdateViewport(SDL_Renderer * renderer)
|
|||
break;
|
||||
|
||||
case DisplayOrientations::PortraitFlipped:
|
||||
data->vertexShaderConstantsData.projection = XMFLOAT4X4( // 90-degree Z-rotation
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f, 0.0f,
|
||||
data->vertexShaderConstantsData.projection = XMFLOAT4X4( // 270-degree Z-rotation
|
||||
0.0f, -1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
);
|
||||
|
@ -964,26 +966,58 @@ D3D11_UpdateViewport(SDL_Renderer * renderer)
|
|||
//
|
||||
// Update the view matrix
|
||||
//
|
||||
float windowWidth = (float) renderer->viewport.w;
|
||||
float windowHeight = (float) renderer->viewport.h;
|
||||
XMStoreFloat4x4(&data->vertexShaderConstantsData.view, // (4)
|
||||
float viewportWidth = (float) renderer->viewport.w;
|
||||
float viewportHeight = (float) renderer->viewport.h;
|
||||
XMStoreFloat4x4(&data->vertexShaderConstantsData.view,
|
||||
XMMatrixMultiply(
|
||||
XMMatrixScaling(2.0f / windowWidth, 2.0f / windowHeight, 1.0f),
|
||||
XMMatrixScaling(2.0f / viewportWidth, 2.0f / viewportHeight, 1.0f),
|
||||
XMMatrixMultiply(
|
||||
XMMatrixTranslation(-1, -1, 0),
|
||||
XMMatrixRotationX(XM_PI)
|
||||
)));
|
||||
|
||||
//
|
||||
// Update the Direct3D viewport, which seems to be aligned to the
|
||||
// swap buffer's coordinate space, which is always in landscape:
|
||||
//
|
||||
SDL_FRect orientationAlignedViewport;
|
||||
const bool swapDimensions =
|
||||
data->orientation == DisplayOrientations::Portrait ||
|
||||
data->orientation == DisplayOrientations::PortraitFlipped;
|
||||
if (swapDimensions) {
|
||||
orientationAlignedViewport.x = (float) renderer->viewport.y;
|
||||
orientationAlignedViewport.y = (float) renderer->viewport.x;
|
||||
orientationAlignedViewport.w = (float) renderer->viewport.h;
|
||||
orientationAlignedViewport.h = (float) renderer->viewport.w;
|
||||
} else {
|
||||
orientationAlignedViewport.x = (float) renderer->viewport.x;
|
||||
orientationAlignedViewport.y = (float) renderer->viewport.y;
|
||||
orientationAlignedViewport.w = (float) renderer->viewport.w;
|
||||
orientationAlignedViewport.h = (float) renderer->viewport.h;
|
||||
}
|
||||
// WinRT, TODO: get custom viewports working with non-Landscape modes (Portrait, PortraitFlipped, and LandscapeFlipped)
|
||||
|
||||
D3D11_VIEWPORT viewport;
|
||||
memset(&viewport, 0, sizeof(viewport));
|
||||
viewport.TopLeftX = (float) renderer->viewport.x;
|
||||
viewport.TopLeftY = (float) renderer->viewport.y;
|
||||
viewport.Width = (float) renderer->viewport.w;
|
||||
viewport.Height = (float) renderer->viewport.h;
|
||||
viewport.TopLeftX = orientationAlignedViewport.x;
|
||||
viewport.TopLeftY = orientationAlignedViewport.y;
|
||||
viewport.Width = orientationAlignedViewport.w;
|
||||
viewport.Height = orientationAlignedViewport.h;
|
||||
viewport.MinDepth = 0.0f;
|
||||
viewport.MaxDepth = 1.0f;
|
||||
data->d3dContext->RSSetViewports(1, &viewport);
|
||||
|
||||
#if 0
|
||||
SDL_Log("%s, oav={%.0f,%.0f,%.0f,%.0f}, rend={%.0f,%.0f}\n",
|
||||
__FUNCTION__,
|
||||
orientationAlignedViewport.x,
|
||||
orientationAlignedViewport.y,
|
||||
orientationAlignedViewport.w,
|
||||
orientationAlignedViewport.h,
|
||||
data->renderTargetSize.x,
|
||||
data->renderTargetSize.y);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1116,9 +1150,33 @@ D3D11_RenderFillRects(SDL_Renderer * renderer,
|
|||
b = (float)(renderer->b / 255.0f);
|
||||
a = (float)(renderer->a / 255.0f);
|
||||
|
||||
D3D11_RenderStartDrawOp(renderer);
|
||||
#if 0
|
||||
// Set up a test pattern:
|
||||
SDL_FRect rects[] = {
|
||||
{-1.1f, 1.1f, 1.1f, -1.1f},
|
||||
{-1.0f, 1.0f, 1.0f, -1.0f}, // red
|
||||
{0.0f, 1.0f, 1.0f, -1.0f}, // green
|
||||
{-1.0f, 0.0f, 1.0f, -1.0f}, // blue
|
||||
{0.0f, 0.0f, 1.0f, -1.0f} // white
|
||||
};
|
||||
count = sizeof(rects) / sizeof(SDL_FRect);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
D3D11_RenderStartDrawOp(renderer);
|
||||
|
||||
#if 0
|
||||
// Set colors for the test pattern:
|
||||
a = 1.0f;
|
||||
switch (i) {
|
||||
case 0: r = 1.0f; g = 1.0f; b = 0.0f; break;
|
||||
case 1: r = 1.0f; g = 0.0f; b = 0.0f; break;
|
||||
case 2: r = 0.0f; g = 1.0f; b = 0.0f; break;
|
||||
case 3: r = 0.0f; g = 0.0f; b = 1.0f; break;
|
||||
case 4: r = 1.0f; g = 1.0f; b = 1.0f; break;
|
||||
}
|
||||
#endif
|
||||
|
||||
VertexPositionColor vertices[] = {
|
||||
{XMFLOAT3(rects[i].x, rects[i].y, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)},
|
||||
{XMFLOAT3(rects[i].x, rects[i].y + rects[i].h, 0.0f), XMFLOAT2(0.0f, 0.0f), XMFLOAT4(r, g, b, a)},
|
||||
|
|
|
@ -51,6 +51,7 @@ SDL_WinRTApp::SDL_WinRTApp() :
|
|||
m_windowClosed(false),
|
||||
m_windowVisible(true),
|
||||
m_sdlWindowData(NULL),
|
||||
m_sdlVideoDevice(NULL),
|
||||
m_useRelativeMouseMode(false)
|
||||
{
|
||||
}
|
||||
|
@ -146,11 +147,35 @@ void SDL_WinRTApp::Uninitialize()
|
|||
|
||||
void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
|
||||
{
|
||||
#if 0
|
||||
SDL_Log("%s, {%f,%f}\n", __FUNCTION__, args->Size.Width, args->Size.Height);
|
||||
#endif
|
||||
|
||||
if (m_sdlWindowData) {
|
||||
// Make the new window size be the one true fullscreen mode.
|
||||
// This change was 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.
|
||||
//
|
||||
// TODO, WinRT: consider dropping old display modes after the fullscreen window changes size (from rotations, etc.)
|
||||
m_sdlWindowData->sdlWindow->fullscreen_mode = SDL_WinRTGlobalApp->GetMainDisplayMode();
|
||||
SDL_AddDisplayMode(&m_sdlVideoDevice->displays[0], &m_sdlWindowData->sdlWindow->fullscreen_mode);
|
||||
|
||||
const int windowWidth = (int) ceil(args->Size.Width);
|
||||
const int windowHeight = (int) ceil(args->Size.Height);
|
||||
SDL_SendWindowEvent(
|
||||
m_sdlWindowData->sdlWindow,
|
||||
SDL_WINDOWEVENT_RESIZED,
|
||||
(int) ceil(args->Size.Width),
|
||||
(int) ceil(args->Size.Height));
|
||||
windowWidth,
|
||||
windowHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
|
||||
|
@ -744,6 +769,11 @@ void SDL_WinRTApp::SetSDLWindowData(const SDL_WindowData* windowData)
|
|||
m_sdlWindowData = windowData;
|
||||
}
|
||||
|
||||
void SDL_WinRTApp::SetSDLVideoDevice(const SDL_VideoDevice * videoDevice)
|
||||
{
|
||||
m_sdlVideoDevice = videoDevice;
|
||||
}
|
||||
|
||||
IFrameworkView^ Direct3DApplicationSource::CreateView()
|
||||
{
|
||||
// TODO, WinRT: see if this function (CreateView) can ever get called
|
||||
|
|
|
@ -26,6 +26,7 @@ internal:
|
|||
bool HasSDLWindowData() const;
|
||||
void SetRelativeMouseMode(bool enable);
|
||||
void SetSDLWindowData(const SDL_WindowData * windowData);
|
||||
void SetSDLVideoDevice(const SDL_VideoDevice * videoDevice);
|
||||
Windows::Foundation::Point TransformCursor(Windows::Foundation::Point rawPosition);
|
||||
|
||||
protected:
|
||||
|
@ -49,6 +50,7 @@ private:
|
|||
bool m_windowClosed;
|
||||
bool m_windowVisible;
|
||||
const SDL_WindowData* m_sdlWindowData;
|
||||
const SDL_VideoDevice* m_sdlVideoDevice;
|
||||
bool m_useRelativeMouseMode;
|
||||
};
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ WINRT_Available(void)
|
|||
static void
|
||||
WINRT_DeleteDevice(SDL_VideoDevice * device)
|
||||
{
|
||||
SDL_WinRTGlobalApp->SetSDLVideoDevice(NULL);
|
||||
SDL_free(device);
|
||||
}
|
||||
|
||||
|
@ -103,9 +104,10 @@ WINRT_CreateDevice(int devindex)
|
|||
//device->UpdateWindowFramebuffer = SDL_WINRT_UpdateWindowFramebuffer;
|
||||
//device->DestroyWindowFramebuffer = SDL_WINRT_DestroyWindowFramebuffer;
|
||||
device->GetWindowWMInfo = WINRT_GetWindowWMInfo;
|
||||
|
||||
device->free = WINRT_DeleteDevice;
|
||||
|
||||
SDL_WinRTGlobalApp->SetSDLVideoDevice(device);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue