当前位置: 首页 > wzjs >正文

有没有在线辅导家做的网站网站编辑知识

有没有在线辅导家做的网站,网站编辑知识,花店商城网站设计,公司展厅设计图片前言 上一部分,通过十个章节的内容,对视景器的初始化与准备工作进行了系统性的剖析。本章将在该基础上,探讨vsg中的帧循环机制,主要包含前进到下一帧、事件处理、更新、记录与提交、呈现五个部分,同时整个过程包含了复…

前言

        上一部分,通过十个章节的内容,对视景器的初始化与准备工作进行了系统性的剖析。本章将在该基础上,探讨vsg中的帧循环机制,主要包含前进到下一帧、事件处理、更新、记录与提交、呈现五个部分,同时整个过程包含了复杂的多线程处理与同步操作,本章作为帧循环部分的第一章,在整体介绍帧循环的内容的同时,将深入分析前进到下一帧的详细过程。


目录

  • 1 帧循环
  • 2 前进到下一帧

         本章对参照用例(vulkanscenegraph显示倾斜模型-CSDN博客)中的如下代码进行深入探讨。

	while (true){// render VulkanSceneGraph frame   {if (!vsg_viewer->advanceToNextFrame()){break;}vsg_viewer->handleEvents();vsg_viewer->update();vsg_viewer->recordAndSubmit();vsg_viewer->present();}frameNumber++;}

1 帧循环

       与OSG(OpenSceneGraph)帧循环中经典的事件遍历(Event Traversal)、更新遍历(Update Traversal)和渲染遍历(Rendering Traversal)类似,vsg帧循环中涉及同样的操作。VSG的事件处理阶段对应OSG的事件遍历(Event Traversal),负责处理用户输入和系统事件;更新阶段对应OSG的更新遍历(Update Traversal),完成场景数据的同步更新;而记录与提交阶段(包含资源编译、命令缓冲录制与提交)和最终的呈现阶段,则共同对应了OSG渲染遍历(Rendering Traversal),最终将渲染结果输出到显示窗口。这种设计即保留了OSG遍历流程的核心逻辑,同时兼顾Vulkan渲染的特点,采用更精细的阶段划分。

2 前进到下一帧

       本小结对应的代码如下,接下来将通过代码来揭秘此过程的详细流程。

			if (!vsg_viewer->advanceToNextFrame()){break;}

       上述代码为vsg::Viewer中的advanceToNextFrame函数的调用。

bool Viewer::advanceToNextFrame(double simulationTime)
{static constexpr SourceLocation s_frame_source_location{"Viewer advanceToNextFrame", VsgFunctionName, __FILE__, __LINE__, COLOR_VIEWER, 1};// signal to instrumentation the end of the previous frameif (instrumentation && _frameStamp) instrumentation->leaveFrame(&s_frame_source_location, frameReference, *_frameStamp);if (!active()){return false;}// poll all the windows for events.pollEvents(true);if (!acquireNextFrame()) return false;// create FrameStamp for frameauto time = vsg::clock::now();if (_firstFrame){_firstFrame = false;if (simulationTime == UseTimeSinceStartPoint) simulationTime = 0.0;// first frame, initialize to frame count and indices to 0_frameStamp = FrameStamp::create(time, 0, simulationTime);}else{// after first frame so increment frame count and indicesif (simulationTime == UseTimeSinceStartPoint){simulationTime = std::chrono::duration<double, std::chrono::seconds::period>(time - _start_point).count();}_frameStamp = FrameStamp::create(time, _frameStamp->frameCount + 1, simulationTime);}// signal to instrumentation the start of frameif (instrumentation) instrumentation->enterFrame(&s_frame_source_location, frameReference, *_frameStamp);for (auto& task : recordAndSubmitTasks){task->advance();}// create an event for the new frame._events.emplace_back(new FrameEvent(_frameStamp));return true;
}

     上述代码为Viewer.cpp(155-206行)对应的代码。主要把包括轮询所有窗口的事件(pollEvents)、获取下一帧(acquireNextFrame)、记录和提交任务advace三部分。其中轮询所有窗口的事件并将事件放置到_events中,供后续事件处理阶段使用。

bool Viewer::acquireNextFrame()
{CPU_INSTRUMENTATION_L1_NC(instrumentation, "Viewer acquireNextFrame", COLOR_VIEWER);if (_close) return false;VkResult result = VK_SUCCESS;for (auto& window : _windows){if (!window->visible()) continue;while ((result = window->acquireNextImage()) != VK_SUCCESS){if (result == VK_ERROR_SURFACE_LOST_KHR ||result == VK_ERROR_OUT_OF_DATE_KHR ||result == VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT ||result == VK_SUBOPTIMAL_KHR){// force a rebuild of the Swapchain by calling Window::resize();window->resize();}else if (result == VK_ERROR_DEVICE_LOST){// a lost device can only be recovered by opening a new VkDevice, and success is not guaranteed.// not currently implemented, so exit main loop.warn("window->acquireNextImage() VkResult = VK_ERROR_DEVICE_LOST. Device loss can indicate invalid Vulkan API usage or driver/hardware issues.");break;}else{warn("window->acquireNextImage() VkResult = ", result);break;}}}return result == VK_SUCCESS;
}

       获取下一帧(acquireNextFrame)主要调用所有窗口(vsg::Window)的acqiureNextImage方法。

VkResult Window::acquireNextImage(uint64_t timeout)
{if (!_swapchain) _initSwapchain();if (!_availableSemaphore) _availableSemaphore = vsg::Semaphore::create(_device, _traits->imageAvailableSemaphoreWaitFlag);// check the dimensions of the swapchain and window extents are consistent, if not return a VK_ERROR_OUT_OF_DATE_KHRif (_swapchain->getExtent() != _extent2D) return VK_ERROR_OUT_OF_DATE_KHR;uint32_t nextImageIndex;VkResult result = _swapchain->acquireNextImage(timeout, _availableSemaphore, {}, nextImageIndex);if (result == VK_SUCCESS){// the acquired image's semaphore must be available now so make it the new _availableSemaphore and set its entry to the one to use for the next frame by swapping ref_ptr<>'s_availableSemaphore.swap(_frames[nextImageIndex].imageAvailableSemaphore);// shift up previous frame indicesfor (size_t i = _indices.size() - 1; i > 0; --i){_indices[i] = _indices[i - 1];}// update head of _indices to the new frames nextImageIndex_indices[0] = nextImageIndex;}else{vsg::debug("Window::acquireNextImage(uint64_t timeout) _swapchain->acquireNextImage(...) failed with result = ", result);}return result;
}

       Window::acquireNextImage函数通过调用vsg::SwapChain的acquireNextImage方法,获取图像索引,当调用返回为VK_SUCCESS时,将信号量交换到当前帧,同时采用轮询的方式将当前图像索引置于索引数组_indices的头部。

        struct Frame{ref_ptr<ImageView> imageView;ref_ptr<Framebuffer> framebuffer;ref_ptr<Semaphore> imageAvailableSemaphore;};

       当前帧的数据结构如上代码所示,包含图像视图、帧缓存、图像可提供信号量。

    for (auto& window : windows){auto imageIndex = window->imageIndex();if (imageIndex >= window->numFrames()) continue;auto& semaphore = window->frame(imageIndex).imageAvailableSemaphore;vk_waitSemaphores.emplace_back(*semaphore);vk_waitStages.emplace_back(semaphore->pipelineStageFlags());}for (auto& semaphore : waitSemaphores){vk_waitSemaphores.emplace_back(*(semaphore));vk_waitStages.emplace_back(semaphore->pipelineStageFlags());}current_fence->dependentSemaphores() = signalSemaphores;for (auto& semaphore : signalSemaphores){vk_signalSemaphores.emplace_back(*(semaphore));}if (earlyDataTransferredSemaphore){vk_signalSemaphores.emplace_back(earlyTransferConsumerCompletedSemaphore->vk());current_fence->dependentSemaphores().push_back(earlyTransferConsumerCompletedSemaphore);}if (lateDataTransferredSemaphore){vk_signalSemaphores.emplace_back(lateTransferConsumerCompletedSemaphore->vk());current_fence->dependentSemaphores().push_back(lateTransferConsumerCompletedSemaphore);}VkSubmitInfo submitInfo = {};submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;submitInfo.waitSemaphoreCount = static_cast<uint32_t>(vk_waitSemaphores.size());submitInfo.pWaitSemaphores = vk_waitSemaphores.data();submitInfo.pWaitDstStageMask = vk_waitStages.data();submitInfo.commandBufferCount = static_cast<uint32_t>(vk_commandBuffers.size());submitInfo.pCommandBuffers = vk_commandBuffers.data();submitInfo.signalSemaphoreCount = static_cast<uint32_t>(vk_signalSemaphores.size());submitInfo.pSignalSemaphores = vk_signalSemaphores.data();return queue->submit(submitInfo, current_fence);

        如上代码为RecordAndSubmitTask.cpp中218-265行代码,从上述代码可知当前帧中的图像可提供信号量,用于确保队列提交顺序的正确性,即先获取交换链图像索引,然后提交命令。

        回到vsg::Viewer中的advanceToNextFrame函数,函数执行的第三部分为记录和提交任务advace,具体代码如下:

void RecordAndSubmitTask::advance()
{CPU_INSTRUMENTATION_L1_NC(instrumentation, "RecordAndSubmitTask advance", COLOR_VIEWER);// info("\nRecordAndSubmitTask::advance()");if (_currentFrameIndex >= _indices.size()){// first frame so set to 0_currentFrameIndex = 0;}else{++_currentFrameIndex;if (_currentFrameIndex > _indices.size() - 1) _currentFrameIndex = 0;// shift the index for previous framesfor (size_t i = _indices.size() - 1; i >= 1; --i){_indices[i] = _indices[i - 1];}}// pass the index for the current frame_indices[0] = _currentFrameIndex;
}

       RecordAndSubmitTask::advance函数同样采用轮询的方式将当前帧的索引放置在首位,_indices索引数组与栅栏数组_fences配合使用,从而使_fences实现轮询调用。

文末:本章在上一篇文章的基础上,整体介绍帧循环的内容,同时通过代码深入分析前进到下一帧的详细过程,其本质是获取交换链中可用的图像索引,为后续渲染绘制提供目标表面。下章将分析事件处理部分。


文章转载自:

http://zdL4eQ9Y.sjmxh.cn
http://paa56bKQ.sjmxh.cn
http://LdBQIcTc.sjmxh.cn
http://DVt8kmlY.sjmxh.cn
http://NUfZqu2M.sjmxh.cn
http://okK1GUYi.sjmxh.cn
http://lbeiIRvS.sjmxh.cn
http://haeojUJ2.sjmxh.cn
http://uUgT8yRX.sjmxh.cn
http://AHqLqjVR.sjmxh.cn
http://741C5U1s.sjmxh.cn
http://uHDp7YQK.sjmxh.cn
http://Wkli4Jdp.sjmxh.cn
http://Leanpz1i.sjmxh.cn
http://etVV80Ok.sjmxh.cn
http://4SMro9bg.sjmxh.cn
http://b9FBR9uU.sjmxh.cn
http://QpvARzYe.sjmxh.cn
http://BmgVmYE5.sjmxh.cn
http://z97bCVfm.sjmxh.cn
http://WJQxV2S1.sjmxh.cn
http://rwG5CByq.sjmxh.cn
http://bLb02Sf6.sjmxh.cn
http://GkvkseMV.sjmxh.cn
http://Rs8MHnPY.sjmxh.cn
http://qr5E08B6.sjmxh.cn
http://304KGB4d.sjmxh.cn
http://xotaVHJS.sjmxh.cn
http://WxDUrm5p.sjmxh.cn
http://6wf7UWFv.sjmxh.cn
http://www.dtcms.com/wzjs/778669.html

相关文章:

  • 网站后台如何更新昆明汽车建站网站模板
  • 国际学校网站建设个人网站免费模板
  • 什么是网站降权处理深圳市福田区香蜜湖街道
  • 网站没有关键词的弊端广告投放运营主要做什么
  • 北塘网站制作空间网络
  • 上海建设工程安全监理网站企业名录搜索软件下载
  • win7 网站配置百度官方网
  • 朔城网站制作浙江建设厅网站安全员证书查询
  • 网站建设gzdlzgg设计网站注意哪些问题
  • php班级网站建设广州建筑公司排名
  • 网站建设执行风险做网络写手赚钱的网站
  • 在QQ上做cpa网站说是恶意的烟台做网站公司
  • 苏州教育平台网站建设百度关键词搜索量
  • 旅游网站建设的论文给小孩做辅食的网站
  • 有网站了小程序怎么做wordpress博客转发
  • 做一个网站的费用便宜网站建设公司
  • 2015做那些网站致富网站建设方案的含义
  • 买空间做网站宣传片拍摄制作多少钱
  • 网站模板演示网站推广的目的是什么
  • 苏州行业网站建设怎么做五个页面网站
  • 江苏建设人才网站wordpress适合外贸站
  • 备份wordpress网站自己做的网站如何兼容
  • 如何用eclipse做网站网络公司是什么行业
  • 医疗网站建设公司哪家好做网站有关机械的图片
  • 什么是网站平台开发网站建设中是因为没有ftp上传吗
  • 做网站用什么配资电脑沉默是金粤语谐音歌词
  • 住房和城乡建设部标准定额网站在线制作照片
  • 网站建设:宏智网络科技孝感网站建设
  • net网站开发视频西安建网站的公司
  • 游戏网站设计模板大淘客网站如何做seo