内容简介:文档列表见:可见,OpenGL / ES的接口屏蔽了绝大部分细节,
文档列表见: Rust 移动端跨平台复杂图形渲染项目开发系列总结(目录)
gfx-hal 接口以1:1模仿Vulkan,下面改用Vulkan接口作说明。由于Vulkan接口粒度过细,比OpenGL / ES难学数倍。根据个人经验,对于移动端图形开发者,照着OpenGL ES的接口讲解Vulkan可降低学习难度。
OpenGL / ES 逐帧渲染流程示例
// 准备渲染目标环境 glBindFramebuffer(); glFramebufferTexture2D(); glCheckFramebufferStatus(); // 假如渲染到纹理 glViewport(x, y, width, height); // 准备渲染目标环境 glUseProgram(x); glBindBuffer(i) loop i in 0..VertexVarCount { glEnableVertexAttribArray(i); glVertexAttribPointer(i, ...); } loop i in 0..UniformVarCount { switch UniformType { case NoTexture: glUniformX(i, data); break; case Texture: { glActiveTexture(j); glBindTexture(type, texture_name); glUniform1i(location, j); break; } default:ERROR(); } } // 配置其他Fragment操作,比如glBlend, glStencil glDrawArrays/Elements/ArraysInstanced... // 到此完成Draw Call,视情况调用EGL函数交换前后帧缓冲区,非GL函数, // 渲染到纹理则无此操作。 // 为了不干扰后续绘制,恢复刚才设置的Fragment操作为默认值。 eglSwapbuffers()/[EAGLContext presentRenderbuffer]; 复制代码
可见,OpenGL / ES的接口屏蔽了绝大部分细节, 整体代码量显得很少,但初学时也不好理解 ,用久了就成套路,觉得就该这样,以致于第一次接触Vulkan发现很多细节之前完全不了解,有点懵。
gfx-hal逐帧渲染到视图的调用流程介绍
gfx-hal(Vulkan)逐帧渲染到视图的核心调用流程如下所示:
EventSource ->[CommandPool -> ComanndBuffer -> Submit -> Submission -> QueueGroup -> CommandQueue] -> GraphicsHardware 复制代码
说明:
- EventSource:表示信号源,比如相机回调一帧图像、屏幕的vsync信号、用户输入等。
- CommandQueue:用于执行不同类型任务的队列,比如渲染任务、计算任务。
- QueueGroup:CommandQueue集合
- GraphicsHardware:图形硬件
具体流程代码:
-
重置Fence,给后面提交Submission到队列使用。
device.reset_fence(&frame_fence); 复制代码
-
重置CommandPool
command_pool.reset(); 复制代码
-
从SwapChain获取Image索引
let frame = swap_chain.acquire_image(!0, FrameSync::Semaphore(&mut frame_semaphore)); 复制代码
-
通过CommandPool创建、配置CommandBuffer,然后得到Submit对象
let mut cmd_buffer = command_pool.acquire_command_buffer(false); // 一系列类似OpenGL / ES的Fragment操作、绑定数据到Program的配置 // 两个值得注意的Pipeline操作 cmd_buffer.bind_graphics_pipeline(&pipeline); cmd_buffer.bind_graphics_descriptor_sets(&pipeline_layout, 0, Some(&desc_set), &[]); // 联合RenderPass的操作 let mut encoder = cmd_buffer.begin_render_pass_inline(&render_pass,...); let submit = cmd_buffer.finish() 复制代码
-
通过Submit创建Submission
let submission = Submission::new() .wait_on(&[(&frame_semaphore, PipelineStage::BOTTOM_OF_PIPE)]) .submit(Some(submit)); 复制代码
-
提交Submission到队列
queue.submit(submission, Some(&mut frame_fence)); 复制代码
-
等待CPU编码完成
device.wait_for_fence(&frame_fence, !0); 复制代码
-
交换前后帧缓冲区
swap_chain.present(&mut queue_group.queues[0], frame, &[]) 复制代码
配置CommandBuffer的进一步介绍
OpenGL / ES 2/3.x没 CommandPool
与 CommandBuffer
数据结构,除了最新的OpenGL小版本才加入了SPIR-V和Command,但OpenGL ES还没更新。Metal的 CommandBuffer
接口定义不同于Vulkan。Metal创建 MTLCommandBuffer
,由Buffer与 RenderPassDescriptor
一起创建出 Enconder
,然后打包本次渲染相关的资源,最后提交Buffer到队列让GPU执行。Vulkan基本把Metal的Encoder操作放到CommandBuffer,只留了很薄的Encoder操作。
总体流程:
- 由Command Pool分配可用Command Buffer
- 配置viewport等信息
- 设置输出目标
-
设置绘制方式,
draw
/draw_indexed
/draw_indirect
等等 - 结束配置
代码示例如下:
let submit = { // 从缓冲区中取出一个实际为RawCommandBuffer的实例,加上线程安全对象,组装成CommandBuffer实例,这是线程安全的 let mut cmd_buffer = command_pool.acquire_command_buffer(false); cmd_buffer.set_viewports(0, &[viewport.clone()]); cmd_buffer.set_scissors(0, &[viewport.rect]); cmd_buffer.bind_graphics_pipeline(&pipeline.as_ref().unwrap()); cmd_buffer.bind_vertex_buffers(0, pso::VertexBufferSet(vec![(&vertex_buffer, 0)])); cmd_buffer.bind_graphics_descriptor_sets(&pipeline_layout, 0, Some(&desc_set)); //TODO { let mut encoder = cmd_buffer.begin_render_pass_inline( &render_pass, &framebuffers[frame.id()], viewport.rect, &[command::ClearValue::Color(command::ClearColor::Float([0.8, 0.8, 0.8, 1.0]))], ); encoder.draw(0..6, 0..1); } cmd_buffer.finish() }; 复制代码
前面代码显示了CommandBuffer两个很关键的操作: bind_graphics_pipeline(GraphicsPipeline)
和 bind_graphics_descriptor_sets(PipelineLayout, DescriptorSet)
。GraphicsPipeline相当于OpenGL / ES的Program, PipelineLayout
和 DescriptorSet
描述了Shader的Uniform变量如何读取Buffer的数据。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- iOS界面渲染流程分析
- iOS OpenGL开发(二) - 着色器渲染流程
- OpenGL/OpenGL ES 渲染流程以及固定存储着色器
- Cocos2dx v3.x渲染管线流程
- Cocos2dx v3.x渲染管线流程
- OpenGL ES 入门之旅--OpenGL 下的坐标系和着色器渲染流程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
计算机网络(第6版)
[美] James F.Kurose、[美] Keith W.Ross / 陈鸣 / 机械工业出版社 / 2014-10 / 79.00元
《计算机网络:自顶向下方法(原书第6版)》第1版于12年前出版,首创采用自顶向下的方法讲解计算机网络的原理和协议,出版以来已被几百所大学和学院选用,是业界最经典的计算机网络教材之一。 《计算机网络:自顶向下方法(原书第6版)》第6版继续保持了以前版本的特色,为计算机网络教学提供了一种新颖和与时俱进的方法,同时也进行了相当多的修订和更新:第1章更多地关注时下,更新了接入网的论述;第2章用pyt......一起来看看 《计算机网络(第6版)》 这本书的介绍吧!