android - 从分屏到全屏后出现幻影

标签 android opengl-es android-ndk vulkan

我正在使用 NDK 为 Android 编写游戏。我的游戏使用 vulkan(如果可用),否则使用 OpenGL。

我遇到了一个问题,如果您将游戏置于分屏模式,同时将设备置于纵向,然后将游戏大小调整为全屏模式,旧 View 中的游戏残像仍然可见。注意:在游戏中执行此操作会触发调用 SurfaceHolder.Callback.surfaceDestroyed(在 Java 中),这反过来会关闭我在 C++ 中的渲染线程。我对 surfaceDestroyed 的回调告诉 C++ 渲染线程停止,然后加入它。

我可以通过使用任何颜色调用 glClearColor,然后在渲染线程关闭之前调用 eglSwapBuffers,在 OpenGL 中解决这个问题。

这是对 OpenGL 的有效修复吗?我还应该做些什么来清理旧表面吗?我 验证在退出渲染线程之前,在从 ANativeWindow_fromSurface 获取的窗口上调用了 ANativeWindow_release。

然后我尝试在 vulkan 中做同样的事情并再次遇到问题......我使用 vkCmdClearColorImage by do 正在执行以下操作:

(1) vkQueueWaitIdle(presentQueue)

(2) vkAquireNextImageKHR

(3) 初始化相应的命令缓冲区:

(3a) ImageMemoryBarrier VK_IMAGE_LAYOUT_UNDEFINED -> VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0 -> VK_ACCESS_TRANSFER_WRITE_BIT

(3b) vkCmdClearColor VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL

(3c) ImageMemoryBarrier VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL -> VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,VK_ACCESS_TRANSFER_WRITE_BIT -> VK_ACCESS_MEMORY_READ_BIT

(4) vkQueueSubmit(图形队列...)

(5) vkQueuePresentKHR(presentQueue...)

(6) vkQueueWaitIdle(presentQueue)

我到了 3a,然后我在验证层中收到一个错误,指出图像不是使用 VK_IMAGE_USAGE_TRANSFER_DST_BIT 使用标志创建的。如何使用此使用位创建交换链图像?

如果需要其他信息,请告诉我。谢谢!

最佳答案

Vulkan 部分不言自明;有一个 imageUsage 成员。让我给你代码:

VkSurfaceCapabilitiesKHR caps;
errco = vkGetPhysicalDeviceSurfaceCapabilitiesKHR( pdev, mySurface, &caps ); if(errco) panic();
if( !(caps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) ) panic();

VkSwapchainCreateInfoKHR sci = {VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR};
sci.surface = mySurface;
sci.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; // !
// etc

VkSwapchainKHR mySwapchain;
errco = vkCreateSwapchainKHR( dev, &sci, nullptr, &mySwapchain ); if(errco) panic();

尽管您可能无论如何都不应该这样做。没有理由执行 vkCmdClearColorImage。在您打算写入之前使用渲染 channel 清除彩色图像 (VkAttachmentDescription::loadOp)。它效率更高,作为奖励,它被视为渲染并且不需要使用 TRANSFER

好像windowBackgroundFallback假设您的应用无法及时提供新图像,这应该是解决此问题的通用解决方案。

消除幻像的最佳解决方案是告诉 android 在发生屏幕大小调整时不要关闭应用程序。这样,可以通过重新创建交换链和重新绘制游戏来处理屏幕大小调整。这article会谈设置android:configChanges在 list 文件中。当屏幕从分屏调整为全屏时,以下设置阻止 android 关闭应用程序:

android:configChanges="screenSize|orientation|screenLayout"

关于android - 从分屏到全屏后出现幻影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54974981/

相关文章:

java - Android Studio - 按钮重复辅助

java - 将现有的 Java 代码与 React Native 结合使用

ios - 使用 UINavigationController 推送 EAGL-View 时 iPhone 内存使用量增加

android - 在 opengl 中,如何获得像素与 gl.gltranslatef(floatx,y,z) 之间的关系?

java - Android 读取文件和偶尔不正确的值

ffmpeg - 使用 Android NDK 从 OGG 音乐文件中提取原始音频帧

android - 在运行时设置 Google Maps v2 API key

ios - 使用 Metal/OpenGL ES 在 iOS 中渲染视频

android - 为什么android ndk函数AAsetManager_open报错,当路径是这样的

java - 来自 Fragment 的 Android 调用 Activity 使应用程序崩溃