Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
WinRT: bug fixes for device orientation + Direct3D 11.1 rendering
  • Loading branch information
DavidLudwig committed Feb 18, 2013
1 parent 388c19a commit 776330e
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 23 deletions.
90 changes: 74 additions & 16 deletions src/render/direct3d11/SDL_render_d3d11.cpp
Expand Up @@ -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"
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
);
Expand All @@ -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
);
Expand All @@ -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;
}

Expand Down Expand Up @@ -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)},
Expand Down
42 changes: 36 additions & 6 deletions src/video/windowsrt/SDL_WinRTApp.cpp
Expand Up @@ -51,6 +51,7 @@ SDL_WinRTApp::SDL_WinRTApp() :
m_windowClosed(false),
m_windowVisible(true),
m_sdlWindowData(NULL),
m_sdlVideoDevice(NULL),
m_useRelativeMouseMode(false)
{
}
Expand Down Expand Up @@ -146,11 +147,35 @@ void SDL_WinRTApp::Uninitialize()

void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
{
SDL_SendWindowEvent(
m_sdlWindowData->sdlWindow,
SDL_WINDOWEVENT_RESIZED,
(int) ceil(args->Size.Width),
(int) ceil(args->Size.Height));
#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,
windowWidth,
windowHeight);
}
}

void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
Expand Down Expand Up @@ -739,11 +764,16 @@ void SDL_WinRTApp::SetRelativeMouseMode(bool enable)
m_useRelativeMouseMode = enable;
}

void SDL_WinRTApp::SetSDLWindowData(const SDL_WindowData* windowData)
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
Expand Down
2 changes: 2 additions & 0 deletions src/video/windowsrt/SDL_WinRTApp.h
Expand Up @@ -26,6 +26,7 @@ ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFramewo
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:
Expand All @@ -49,6 +50,7 @@ ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFramewo
bool m_windowClosed;
bool m_windowVisible;
const SDL_WindowData* m_sdlWindowData;
const SDL_VideoDevice* m_sdlVideoDevice;
bool m_useRelativeMouseMode;
};

Expand Down
4 changes: 3 additions & 1 deletion src/video/windowsrt/SDL_winrtvideo.cpp
Expand Up @@ -74,6 +74,7 @@ WINRT_Available(void)
static void
WINRT_DeleteDevice(SDL_VideoDevice * device)
{
SDL_WinRTGlobalApp->SetSDLVideoDevice(NULL);
SDL_free(device);
}

Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 776330e

Please sign in to comment.