游戏引擎Flax Engine分析(六)渲染

2021SC@SDUSC


一、简述

        这篇博客继续上一篇未分析完的部分继续分析,分析2D渲染服务。

二、分析

        我们先看一下我们曾在Render2D.h这个头文件中介绍过的开始渲染函数,其有多个重载:

API_FUNCTION() static void Begin(GPUContext* context, GPUTexture* output, GPUTexture* depthBuffer = nullptr);
API_FUNCTION() static void Begin(GPUContext* context, GPUTexture* output, GPUTexture* depthBuffer, API_PARAM(Ref) const Matrix& viewProjection);
API_FUNCTION() static void Begin(GPUContext* context, GPUTextureView* output, GPUTextureView* depthBuffer, API_PARAM(Ref) const Viewport& viewport);
API_FUNCTION() static void Begin(GPUContext* context, GPUTextureView* output, GPUTextureView* depthBuffer, API_PARAM(Ref) const Viewport& viewport, API_PARAM(Ref) const Matrix& viewProjection);

        (1)从最简单的,含有三个参数包括要使用的 GPU 命令上下文、输出目标和深度缓冲区:

ASSERT(output != nullptr);
    Begin(context, output->View(), depthBuffer ? depthBuffer->View() : nullptr, Viewport(output->Size()));

        对输出目标进行了判断,关于ASSERT这个预定义宏,目的是执行表达式的硬断言, 使引擎崩溃并在表达式失败时插入调试器中断。

        调用Begin()的重载, Viewpoint为输出视点,关于这个重载函数的实现我们在下面分析,在此之前我们先看第二个函数。

        (2)增加的一个参数viewProjection:视图*投影矩阵。,允许以 3D 或自定义转换呈现 GUI。

ASSERT(output != nullptr);
    Begin(context, output->View(), depthBuffer ? depthBuffer->View() : nullptr, Viewport(output->Size()), viewProjection);

        这里调用的是另一个Begin()的重载。

        (3)这里我们看关于(1)中所调用的Begin()的重载函数的实现(这里仅截取部分代码用于分析):


    Matrix::OrthoOffCenter(-halfWidth, halfWidth, halfHeight, -halfHeight, zNear, zFar, projection);
    Matrix::Translation(-halfWidth, -halfHeight, 0, view);
    Matrix::Multiply(view, projection, viewProjection);

    Begin(context, output, depthBuffer, viewport, viewProjection);

   

        halfWith,halfHeight为视点宽度和高度的一半,zNear和zFar分别为浮点数的0和1。view, projection, viewProjection为Matrix类型,表示一个 4x4 的数学矩阵。

        OrthoOffCenter创建一个左手的、自定义的正交投影矩阵。参数含义依次为观测量的最小 x 值、观测量的最大 x 值、观测量的最小 y 值、观测量的最大 y 值、观测量的最小 z 值、观测量的最大 z 值、当方法完成时,包含创建的投影矩阵。

        Translation使用指定的偏移量创建平移矩阵。参数依次为X 坐标偏移、Y 坐标偏移、Z 坐标偏移、当方法完成时,包含创建的投影矩阵。

        Multiply计算两个矩阵的乘积。参数依次为矩阵1(左)、矩阵2(右)、结果。

        然后再调用最后一个重载函数。

        (4)这里我们介绍最后一个重载的Begin(),也就是上述几个Begin()函数调用的最底层:

ASSERT(Context == nullptr && Output == nullptr);
ASSERT(context != nullptr && output != nullptr);

        先对 命名空间内预先声明的GPUContext*(代码中的Context)和GPUTextureView*(Output)是否为空进行判断;同时判断形参是否有内容。

        设置:

    Context = context;
    Output = output;
    DepthBuffer = depthBuffer;
    View = viewport;
    ViewProjection = viewProjection;
    DrawCalls.Clear();

         初始化默认转换,清空转换层堆栈,再将默认转换压入栈中:

    const Matrix3x3 defaultTransform = Matrix3x3::Identity;
    TransformLayersStack.Clear();
    TransformLayersStack.Push(defaultTransform);
    TransformCached = defaultTransform;

        初始化默认剪辑蒙版: 

    const Rectangle defaultBounds(viewport.Location, viewport.Size);
    const RotatedRectangle defaultMask(defaultBounds);
    ClipLayersStack.Clear();
    ClipLayersStack.Add({ defaultMask, defaultBounds });

        初始化默认色调堆栈 :

    TintLayersStack.Clear();
    TintLayersStack.Add({ 1, 1, 1, 1 });

        只能为 2D 正投影启用剪刀,因此此处设置为false: 

IsScissorsRectEnabled = false;

        重置几何缓冲区: 

    VB.Clear();
    IB.Clear();
    VBIndex = 0;
    IBIndex = 0;

         到这里,开始渲染的整个流程已经分析结束,下一篇博客将关注结束时所作的工作以及其他2D渲染操作。

 

 

 

 

  

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值