当前位置:首页 > 安卓源码 > 技术博客 >

使用Kotlin Native的Vulkan API。绘制循环。

时间:2019-04-29 15:59 来源:互联网 作者:源码搜藏 浏览: 收藏 挑错 推荐 打印

介绍 好吧,在以前的部分我们几乎准备了所有的东西。 现在,我简要将描述最后需要的类- FrameBuffers , Sync 和 CommandBuffers 。 FrameBuffers 首先 是 类 - 用于定义我们将使用的附件的帧缓冲区列表,它们将使用哪些ImageView,以及它们的尺寸和spec。

介绍

好吧,在以前的部分我们几乎准备了所有的东西。现在,我简要将描述最后需要的类- FrameBuffersSyncCommandBuffers

FrameBuffers首先类 - 用于定义我们将使用的附件的帧缓冲区列表,它们将使用哪些ImageView,以及它们的尺寸和spec。和FrameBuffers类。它以标准方式创建,具有相应的结构和Vulkan API函数调用。

此外,还有Sync班级。它将包含一个信号量,用于检查演示文稿是否完整以及一个信号量,以检查渲染是否完成。以及命令缓冲区的围栏列表。所有都是以标准方式创建的。

最后一个是CommandBuffers类 - 每个图像视图的命令缓冲区列表。在这里,我们将定义清晰的值(颜色/深度模板),视口,剪刀等。以标准方式创建。 

主循环

最后我们可以使用Kotlin Native绘制出第一个三角形。之前我们添加了辅助函数来为其顶点和索引创建缓冲区:


triangle = VertexBuffer.Triangle(_physicalDevice!!, _logicalDevice!!)

这些步骤与我们在c ++中编码时使用的步骤相同:

  • 更新统一缓冲区
  • 使用vkAcquireNextImageKHR 功能获取下一个图像  并设置显示信号量     
  • 等到命令缓冲区使用fence完成执行
  • 重置围栏
  • 使用围栏提交到队列
  • 将当前缓冲区提供给swapchain并传递 

所以,它看起来像这样:

    fun draw() {

        _uniformBuffers!!.update()

        // wait for a success or error

        if (VK_CHECK(
                vkAcquireNextImageKHR(
                    _logicalDevice!!.device,
                    _swapchain!!.swapchain,
                    UINT64_MAX,
                    _sync!!.presentSemaphore,
                    null,
                    currentBuffer.ptr
                )
            )
        ) {

            // wait until the command buffer has finished execution 
            if (VK_CHECK(
                    vkWaitForFences(
                        _logicalDevice!!.device,
                        1u,
                        _sync!!.waitFences[currentBuffer.value.toInt()].ptr,
                        VK_TRUE.toUInt(),
                        UINT64_MAX
                    )
                )
            ) {

                if (VK_CHECK(
                        vkResetFences(
                            _logicalDevice!!.device,
                            1u,
                            _sync!!.waitFences[currentBuffer.value.toInt()].ptr
                        )
                    )
                ) {

                    memScoped {

                        // Pipeline stage for the queue to wait

                        val pipelineStageWaitFlags = alloc<VkPipelineStageFlagsVar>()
                        pipelineStageWaitFlags.value = 
                           VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

                        val submitInfo = alloc<VkSubmitInfo>().apply {
                            sType = VK_STRUCTURE_TYPE_SUBMIT_INFO
                            pWaitDstStageMask = pipelineStageWaitFlags.ptr
                            pWaitSemaphores = _sync!!.presentSemaphorePtr
                            waitSemaphoreCount = 1u
                            pSignalSemaphores = _sync!!.renderSemaphorePtr
                            signalSemaphoreCount = 1u
                            commandBufferCount = 1u
                            pCommandBuffers = 
                                 _commandBuffers!!
                                 .drawCmdBuffers[currentBuffer.value.toInt()].ptr
                        }

                        // Submit to the graphics queue 
                        if (VK_CHECK(
                                vkQueueSubmit(
                                    _logicalDevice!!.deviceQueue,
                                    1u,
                                    submitInfo.ptr,
                                    _sync!!.waitFences[currentBuffer.value.toInt()]
                                    .value
                                )
                            )
                        ) {

                            // Present the current buffer to the swap chain

                            val swapchains = allocArray<VkSwapchainKHRVar>(1.toInt()) {
                                this.value = _swapchain!!.swapchain
                            }

                            val presentInfo = alloc<VkPresentInfoKHR>().apply {
                                sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR
                                pNext = null
                                swapchainCount = 1u
                                pSwapchains = swapchains
                                waitSemaphoreCount = 1u
                                pWaitSemaphores = _sync!!.renderSemaphorePtr
                                pImageIndices = currentBuffer.ptr
                            }

                            if (!VK_CHECK(vkQueuePresentKHR(_logicalDevice!!
                               .deviceQueue, presentInfo.ptr))) {
                                logError("Failed present queue")
                            }

                        } else {
                            logError("Failed submit queue")
                        }

                    }

                } else {
                    logError("Failed fences reset")
                }

            } else {
                logError("Failed fences wait")
            }
        } else {
            logError("Failed aquire next image")
        }

    }

 

结果

这是我们的三角形:

 

使用Kotlin Native的Vulkan API。绘制循环。

所以我们用稳定的fps绘制了一些东西(现在它仅在Windows平台上运行)。当然,很难说这么简单的场景表演。但是作为POC,我们证明了可以使用Vulkan API和Kotlin Native,这很容易。作为下一步,我计划完成Linux平台,添加ImGUI并尝试一些复杂的场景。所有更改都将在主分支中提供。

使用Kotlin Native的Vulkan API。绘制循环。 转载https://www.codesocang.com/appboke/39913.html

技术博客阅读排行

最新文章