Browse Source

vulkan: android: fix display orientation

niki 3 years ago
parent
commit
5f2fdc0dd0
2 changed files with 33 additions and 3 deletions
  1. 30 0
      src/modules/graphics/vulkan/Graphics.cpp
  2. 3 3
      src/modules/graphics/vulkan/Graphics.h

+ 30 - 0
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;

+ 3 - 3
src/modules/graphics/vulkan/Graphics.h

@@ -19,7 +19,6 @@
 #include <iostream>
 #include <memory>
 #include <functional>
-#include <dlfcn.h>
 
 
 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<VkImage> 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<std::vector<std::function<void()>>> cleanUpFunctions;
-	graphics::Texture* currentTexture = nullptr;
 
 	// render pass variables.
+	graphics::Texture* currentTexture = nullptr;
 	Texture* renderTargetTexture = nullptr;
 	float currentViewportWidth = 0;
 	float currentViewportHeight = 0;