三维渲染引擎渲染层设计(3D Engine Design for Vritual Globes -翻译未完)

来源:互联网 发布:凡科绑定域名 编辑:程序博客网 时间:2024/04/27 21:38

英语水平有限,凑合看,备忘用的。

1: 第一节: 渲染层抽象的优点不翻译了。 

2:第二节: 渲染层鸟瞰:

         渲染层用来封装GPU中的相关资源和调用渲染命令, 如图图3.1显示了渲染层的主要部分; 由于一少部分渲染状态配置在固定管线中(针对OpenGL_ES),鉴于此渲染层基于着色器设计, 这里面封装大部分渲染状态, 比如深度测试,模板测试。 渲染状态不包传统固定管线中的状态,因为这些状态可能已经实现在着色器中,像光照,纹理等。


 

         我们的着色器程序包含顶点着色器,几何着色器,片段着色器, 以用来执行渲染调用。我们的渲染层当然也包含了用于着色器之间通信的attributes 和 uniforms 变量。     顶点数组是一个保存顶点属性的轻量级的容器,它接受数据通过一个或多个的vertexbuffer(顶点缓冲区),或者IndexBuffer(顶点索引缓冲区)。 

         二维纹理代表一个在驱动内存中的图片, 当合并(猜想应该是贴图)时会用一个采样器来指定纹理过滤和纹理环绕的方式,  纹理的数据传输通过将纹理读入到pixel buffers(像素缓冲区)中,像素缓冲区是传输数据的通道,最终,纹理图片数据存储在纹理对象中。 

  

       最后,  帧缓冲区是一个包含纹理的轻量级容器,它能把纹理渲染到texture techniques,帧缓冲区可以包含多重纹理。


       如图3.2 一个叫做“Device”的静态类用来创建各种渲染对象, 可以把它想象乘一个创建对象的工厂。 但是不调用渲染命令。图中:GraphiWindow 用来创建和本地窗口相关的Context(渲染上下文), 而Device创建的其他对象共享这个上下文。


     


      如图3.3, 一个叫“Contex”类是用来调用渲染命令的。Context 是 GraphicsWindow 一部分, 它在Device.CreateWindow创建, 一个图形窗口,包含了设备上下文和绘图命令以及窗口事件。 Device 创建的对象能在多个Context中共享, 例如, 客户端代码创建两个不同的窗口,但是他们可以用相同的shaders, vertexbuffer, indexbuffer,texttures 等, 本章描述这些类型细节。

      Contex用来创建渲染对象和包含一些渲染状态, 例如 视口转换矩阵, 帧缓冲区, 纹理, 采样器, 等。 

     

      Device 接口代码:

     

      Context 代码:

    


3: 第三节:渲染状态管理: 

        渲染状态配置在固定管线中,用于呈现和影响绘制调用,比如模板测试, 深度测试, 裁剪测试,透明。 在原始的GL 中, 渲染状态是全局变量,可以在任意时刻被设置,前提是一个有效上下文属于当前线程。 一种方法是管理全局状态变量产生一个状态集合在函数调用之前, 并且要调用函数存储状态改变。 但这个方法有一个缺点,就是如果重复调用一个函数时,将导致状态反复改变,由此带来效率问题,

       即使GL API 使用全局渲染状态,但是渲染层不必暴露全局渲染状态,全局渲染状态是实现细节, 有一种方法是隐藏全局状态,排序渲染状态并分组放到一个单独的对象中去并传递到渲染方法中,然后在实际的渲染方法调用之前设置渲染状态对象。 用这种设计的好处是,不要在疑问当前渲染状态是什么,因为没有所谓的当前状态, 每一个渲染函数调用都有子渲染状态, 这样就不会产生状态切换从一个渲染调用到另外一个函数调用。

       RenderState 类接口设计:

      


         到目前为止, 我们定义了RenderState  作为一个渲染状态容器对象, 为了应用渲染状态并被传递到渲染调用中,我们要做渲染状态的同步处理。 当然 一个渲染状态对象不需要每次初始化在每次渲染调用中。 一个对象可以实例化一次或者在多次并设置属性。


4:  Shader 封装:

        在我们的渲染层中,相比其他模块而言,着色器支持更多的接口和代码,恰当的说,着色器是现代渲染引擎的核心,甚至移动平台普遍支持的OpenGL ES 2.0具有顶点着色器和片段着色器功能,今天桌面平台具有更高可编程性的管线, 包括可编程顶点, 几何着色器,片段着色器等。 本节主要关注顶点着色器,片段着色器。

       最开始让我们看下编译链接着色器例子:

      

      两个字符串,vs 和 fs 包含顶点和片段着色器代码, 几何着色器不在这里显示。 源码字符串可能是硬编码或者生成的代码片段或者磁盘上的一个文件, 大多数情况下,我们的着色器代码都是存储在.glsl的文件里。 根据作者经验,作者认为着色器源码缓存起来比较好,使用方便。 在程序运行时刻像这样载入源码:

    

    把着色器代码传进 Device.CreateShaderProgram中,这样可以创建一个着色器对象, 构造完成之后准备渲染用, 在上一节中说过,着色器也当作渲染状态的一部分,因此可以不必和当前渲染上下文绑定在一起。 作为渲染状态的一部分,着色器在每次渲染命令调用中都会被指定。

     我们用ShaderProgramGL3x 实现 着色器,它代表一个可编程管线并封装渲染细节, ShaderProgramGL3x 构造函数调用 glCreateShader, glShaderSource, glCompileShader, glGetShader 来创建并编译着色器对象。 如果创建失败会抛出异常, 创建完对象后通过调用 glLinkProgram 链接, 链接出错会抛出异常。

    


         

     

     

       

0 0