diff --git a/src/render/direct3d11/SDL_render_d3d11.cpp b/src/render/direct3d11/SDL_render_d3d11.cpp index 8cffaa237..e742eed0b 100644 --- a/src/render/direct3d11/SDL_render_d3d11.cpp +++ b/src/render/direct3d11/SDL_render_d3d11.cpp @@ -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)}, diff --git a/src/video/windowsrt/SDL_WinRTApp.cpp b/src/video/windowsrt/SDL_WinRTApp.cpp index f5fd02fa4..478297d9c 100644 --- a/src/video/windowsrt/SDL_WinRTApp.cpp +++ b/src/video/windowsrt/SDL_WinRTApp.cpp @@ -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) { - 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) @@ -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 diff --git a/src/video/windowsrt/SDL_WinRTApp.h b/src/video/windowsrt/SDL_WinRTApp.h index d43f42b12..0a12e327e 100644 --- a/src/video/windowsrt/SDL_WinRTApp.h +++ b/src/video/windowsrt/SDL_WinRTApp.h @@ -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; }; diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 1d56e0c72..0e640a4ba 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -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; }