内容简介:文档列表见:可见,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 下的坐标系和着色器渲染流程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C++程序设计语言
Bjarne Stroustrup / 裘宗燕 / 机械工业出版社 / 2010-3-1 / 99.00元
本书是在C++语言和程序设计领域具有深远影响、畅销不衰的著作,由C++语言的设计者编写,对C++语言进行了最全面、最权威的论述,覆盖标准C++以及由C++所支持的关键性编程技术和设计技术。本书英文原版一经面世,即引起业内人士的高度评价和热烈欢迎,先后被翻译成德、希、匈、西、荷、法、日、俄、中、韩等近20种语言,数以百万计的程序员从中获益,是无可取代的C++经典力作。 在本书英文原版面世10年......一起来看看 《C++程序设计语言》 这本书的介绍吧!