From 5f2fdc0dd0d66a2da20028c1d1b7a2f531186894 Mon Sep 17 00:00:00 2001 From: niki Date: Sat, 20 Aug 2022 21:03:49 +0200 Subject: [PATCH] vulkan: android: fix display orientation --- src/modules/graphics/vulkan/Graphics.cpp | 30 ++++++++++++++++++++++++ src/modules/graphics/vulkan/Graphics.h | 6 ++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index c8e0fff91..472f9b73f 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -566,6 +566,7 @@ graphics::Shader::BuiltinUniformData Graphics::getCurrentBuiltinUniformData() { data.transformMatrix = getTransform(); data.projectionMatrix = getDeviceProjection(); + data.projectionMatrix = displayRotation * data.projectionMatrix ; // The normal matrix is the transpose of the inverse of the rotation portion // (top-left 3x3) of the transform matrix. @@ -951,6 +952,35 @@ void Graphics::createSwapChain() { VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes); VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities); + if (swapChainSupport.capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR || + swapChainSupport.capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) { + uint32_t width, height; + width = extent.width; + height = extent.height; + extent.width = height; + extent.height = width; + } + + auto currentTransform = swapChainSupport.capabilities.currentTransform; + constexpr float PI = 3.14159265358979323846f; + float angle = 0.0f; + if (currentTransform & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { + angle = 0.0f; + } else if (currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) { + angle = -PI / 2.0f; + } else if (currentTransform & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) { + angle = -PI; + } else if (currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) { + angle = -3.0f * PI / 2.0f; + } + float data[] = { + cosf(angle), -sinf(angle), 0.0f, 0.0f, + sinf(angle), cosf(angle), 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + displayRotation = Matrix4(data); + uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1; if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) { imageCount = swapChainSupport.capabilities.maxImageCount; diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index 82d4be472..bbffae8e7 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -19,7 +19,6 @@ #include #include #include -#include namespace love { @@ -244,7 +243,8 @@ private: VkQueue graphicsQueue = VK_NULL_HANDLE; VkQueue presentQueue = VK_NULL_HANDLE; VkSurfaceKHR surface = VK_NULL_HANDLE; - VkSwapchainKHR swapChain = VK_NULL_HANDLE; + VkSwapchainKHR swapChain = VK_NULL_HANDLE; + Matrix4 displayRotation; std::vector swapChainImages; VkFormat swapChainImageFormat = VK_FORMAT_UNDEFINED; VkExtent2D swapChainExtent = VkExtent2D(); @@ -274,9 +274,9 @@ private: // functions that need to be called to cleanup objects that were needed for rendering a frame. // just like batchedDrawBuffers we need a vector for each frame in flight. std::vector>> cleanUpFunctions; - graphics::Texture* currentTexture = nullptr; // render pass variables. + graphics::Texture* currentTexture = nullptr; Texture* renderTargetTexture = nullptr; float currentViewportWidth = 0; float currentViewportHeight = 0;