glmark2代码分析6(scene Desktop)

类关系:

SceneDesktop 包含 struct SceneDesktopPrivate 变量,SceneDesktopPrivate 中包含 RenderScreen 和 RenderClearImage

SceneDesktop SceneDesktopPrivate *priv_ SceneDesktopPrivate RenderScreen screen RenderClearImage desktop std::vector<RenderObject *> windows RenderWindowShadow RenderObject RenderScreen RenderClearImage RenderWindowBlur struct

RenderWindowBlur 和 RenderWindowShadow 是effect的具体实现类。
上面是集成和类的组合关系,使用的关系为:

  • screen
    代表的是屏幕,即默认的窗口framebuffer
    screen在SceneDesktopPrivate的初始化的时候用的是canvas,和其他scene一样,底层用的普通的窗口系统egl/glx。这些通过fbo来进行控制:
class RenderScreen : public RenderObject
{
public:
    RenderScreen(Canvas &canvas) { fbo_ = canvas.fbo(); }
    virtual void init() {}
    virtual void release() {}
};
  • desktop
    代表的背景纹理图像
    创建一个framebuffer来实现,绘制一个全屏的正方行,将纹理贴到上面,desktop上有一层纹理,然后在纹理上再画其他小窗口。
  • windows
    是具体的小窗口
    小窗口根据 effect 参数的类型,用RenderWindowBlur 或 RenderWindowShadow
    上面这四个类的基类都是窗口绘制类 RenderObject

SceneDesktop 类

和其他的scene类的方法一样,包含:load、unload、setup、teardown、update、draw、validate。重点介绍setup、构造函数

构造函数

创建 SceneDesktopPrivate 对象,设置输入参数默认值。

setup

  1. 获取输入参数值
  2. 查找纹理,放到textureMap中
  3. 初始化clearcolor等
  4. 调用screen.init初始化canvas
  5. 调用desktop.init到RenderObject的init中,初始化FBO、texture对象、program对象
  6. 设置screen和desktop的size
  7. 计算子窗口的大小和位置,根据effect参数创建子窗口,然后初始化,并绘制到背景大窗口中,其实是绘制到fbo上。
for (unsigned int i = 0; i < windows; i++) {
    RenderObject* win;
    if (options_["effect"].value == "shadow")
        win = new RenderWindowShadow(shadow_size);
    else
        win = new RenderWindowBlur(passes, blur_radius, separable);

    win->init();
    win->render_to(priv_->desktop);
    priv_->windows.push_back(win);
}
  1. 再将fbo切换回来,计算帧率和时间参数

teardown

中件的关系:
screen是最大的
desktop.render_to(priv_->screen)
四个win->render_to(priv_->desktop);

  1. 修改去掉背景:让四个win直接render到screen上,去掉desktop,将fbo改成0,去掉fbo的创建
  2. 减少CPU的运算量,让四个win的位置固定----------update中的内容注释掉
  3. 在effect2d中添加四个窗口

update

计算新的win->position,计算方法:在分别x、y两个方向上,在旧的位置上加上偏移量(偏移量=speed*delta_time),计算的结果如果小于0,或加上边框超出canvas的范围,给速度取个反向。

draw

进行绘制,如上面的关系,先clear desktop,然后将四个window渲染到desktop上,然后将desktop渲染到screen上。

validate

和其他的scene相同,读一个点的像素进行比较

RenderClearImage 类

构造函数用RenderObject的构造函数,制定一个纹理名,作为背景照片。

init

  1. 调用 RenderObject::init();
  2. 用 Texture::load 加载创建背景的纹理对象 background_texture_

release

  1. 删除纹理对象 background_texture_
  2. 释放 RenderObject 中申请的纹理对象和fbo

clear

用纹理进行清屏绘制,绘制一个全屏的正方形贴上 background_texture_

RenderWindowBlur 类

init

调用的是 RenderObject 的 init
这里会有一个静态的变量成员 use_count ,记录new的个数。init中++,对应在release中–。window_contents_ 是一个 RenderClearImage 的对象,
draw_contents_ 控制是否绘制内容,设置位false后四个小窗口不渲染。

size

设置window的size

render_to

将rendertarget渲染到window_contents_(RenderClearImage类型,用来指向窗口界面)上,draw_contents_这个参数可以控制是否直接绘制屏幕上。好处在于统一了render的关系。
用的shader是通过create_blur_shader创建出来的,通过kernel来控制blur,提取texture中的像素,根据kernel来取偏移。
separable_ 参数是用来控制H和V两个方向的,主要实现方式是通过取kernel的参数的方法。

RenderWindowShadow 类

阴影是由5部分组成,拼接到一起的,这里shadow分成几个方向的:
shadow_h_ :下边的阴影竖条
shadow_v_ : 右边的阴影竖条
shadow_corner_ : 三个角的阴影
阴影的绘制也是用RenderObject类的render_to方法,program用的是普通的纹理贴图,没有拼接。

RenderScreen类

将fbo设置成canvas的fbo,其他的继承RenderObject类

RenderObject类

做真正的绘制

init

创建texture和fbo对象,把texture绑定到fbo的GL_COLOR_ATTACHMENT0上。
创建main_program

make_current

把fbo切换成当前的fbo

size

重新设置纹理的大小,并告诉fbo

render_to

通过中心点计算方向,计算四个角度的旋转,加上便宜,就是四个点的位置坐标,然受根据位置计算normalized,设置纹理坐标,绑定纹理,绘制正方形。

render_from

position位置固定,texcoord的位置通过ll和ur计算出来,然后绑定纹理绘制。

draw_quad_with_program

OpenGL用VertextAttribPointer绘制四边形。

算法点

  1. 顶点计算方式
  2. seperate中h和v的shader计算方式
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值