事实上,前面编写的渲染器 Renderer 非常简陋,虽然能够进行一些简单的渲染,但是它并不能满足我们的要求。

  当渲染粒子系统时,需要开启混合模式,但渲染其他顶点时却不需要开启混合模式。所以同时渲染粒子系统和其他纹理时会得不到想要的结果,渲染器还存在许多的不足:

  1、当渲染许多透明图形时,没有对其进行排序,使得本应透明的图形没有透明。

  2、不能对不同的顶点使用不同的状态进行渲染。

  渲染器要做的东西很简单,就是

    1、传递数据到 GPU

    2、设置 OpenGL 状态信息(Alpha测试、模板测试、深度测试、混合,裁剪测试等等)

    3、设置着色程序,绑定 Uniform 数据

    4、绘制顶点

  下面给出两种方式实现上面的流程。

  第一种实现方式:

  

  DrawList 根据绘制的图形填充顶点数据,VertexData 和 IndexData 分别指向一块内存,分别储存顶点数据和索引数据(传递数据到 GPU 时递交这两块内存的数据)。

  CmdList 命令列表,储存一些绘制的信息(Alpha测试、模板测试、深度测试、混合,裁剪测试等等)。值得注意的是,绘制命令有 BeginIndex 和 IndexCount 这两个属性数据,调用函数 glDrawElements 进行绘制时使用。

glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);

  即所有的绘制命令 Cmd 都对应着其唯一的顶点数据,只不过它们的数据都储存在一起。这样每次绘制只需要提交一次数据就可以了,提高的效率。

    这种渲染方式是在 ImGui 中看到的,但这次重写渲染器用的不是这种方式。

  第二种实现方式:

  这次渲染器要实现的功能:

    1、对于不同的顶点可以设置不同的 OpenGL 状态进行绘制。

    2、对半透明图形进行排序渲染。

  这次重写渲染器用的就是这种方式,渲染器构成的主要类:

  这里把着色器给做成一个单独的类,绘制顶点时 OpenGL 状态信息储存在 Pass 中,对象分配器(来自于物理引擎 Box2D 的小型对象分配器源码)分配内存空间储存顶点数据。

  当绘制图形并显示在窗口上时,需要进行的流程:

  首先设置渲染器当前 Pass,然后设置顶点数据到渲染器中。在渲染时

    1、渲染器会迭代每一个 Pass

    2、对顶点数据进行排序

    3、设置 OpenGL 状态

    4、合并顶点数据

    5、设置着色器

    6、绑定 Uniform 数据

    7、最后进行渲染。

  渲染器具体要做的就是如何管理好 Pass 和 VertexIndexData,又不失效率。下面是渲染器管理 Pass 和顶点数据的图片介绍:

  

  半透明渲染是这次写渲染器中遇到的一个难题,单两个不透明图形重叠时,进行深度测试时被遮挡部分的像素会被剔除或者先绘制被遮挡的图形,然后绘制顶层的图形。但是渲染半透明的图形时,半透明的图形能够看到被遮挡的图形,直接抛弃就露馅了,不顾深度测试也依然得不到正确的结果,因为 Alpha

混合颠倒顺序会得到不一样的结果。

  一个解决方法就是把透明的和半透明的图形分开,先渲染不透明的图形,然后对半透明的图形进行排序(被遮挡的半透明的图形先渲染),排序后进行渲染。但是这样代价较高,这次渲染器用的是这种方式。

  渲染器中有两个渲染列表,不透明的 Pass 列表和透明的 Pass 列表。Pass 和 RenderOperation 作为键值对储存在 Map 中,顶点数据储存在RenderOperation 中。VertexIndexData 数组用于对顶点数据进行排序,主要是解决半透明图形的渲染问题。

  接下来将对完成渲染器的各个部分。

  

基于OpenGL编写一个简易的2D渲染框架-08 重构渲染器-整体架构的更多相关文章

  1. 基于OpenGL编写一个简易的2D渲染框架-05 渲染文本

    阅读文章前需要了解的知识:文本渲染 https://learnopengl-cn.github.io/06%20In%20Practice/02%20Text%20Rendering/ 简要步骤: 获 ...

  2. 基于OpenGL编写一个简易的2D渲染框架-06 编写一个粒子系统

    在这篇文章中,我将详细说明如何编写一个简易的粒子系统. 粒子系统可以模拟许多效果,下图便是这次的粒子系统的显示效果.为了方便演示,就弄成了一个动图. 图中,同时显示了 7 种不同粒子效果,看上去效果挺 ...

  3. 基于OpenGL编写一个简易的2D渲染框架-01 创建窗口

    最近正在学习OpenGL,我认为学习的最快方法就是做一个小项目了. 如果对OpenGL感兴趣的话,这里推荐一个很好的学习网站 https://learnopengl-cn.github.io/ 我用的 ...

  4. 基于OpenGL编写一个简易的2D渲染框架-04 绘制图片

    阅读文章前需要了解的知识,纹理:https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/ 过程简述:利用 FreeI ...

  5. 基于OpenGL编写一个简易的2D渲染框架-09 重构渲染器-Shader

    Shader 只是进行一些简单的封装,主要功能: 1.编译着色程序 2.绑定 Uniform 数据 3.根据着色程序的顶点属性传递顶点数据到 GPU 着色程序的编译 GLuint Shader::cr ...

  6. 基于OpenGL编写一个简易的2D渲染框架-03 渲染基本几何图形

    阅读文章前需要了解的知识,你好,三角形:https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/ 要 ...

  7. 基于OpenGL编写一个简易的2D渲染框架-02 搭建OpenGL环境

    由于没有使用GLFW库,接下来得费一番功夫. 阅读这篇文章前请看一下这个网页:https://learnopengl-cn.github.io/01%20Getting%20started/02%20 ...

  8. 基于OpenGL编写一个简易的2D渲染框架-11 重构渲染器-Renderer

    假如要渲染一个纯色矩形在窗口上,应该怎么做? 先确定顶点的格式,一个顶点应该包含位置信息 vec3 以及颜色信息 vec4,所以顶点的结构体定义可以这样: struct Vertex { Vec3 p ...

  9. 基于OpenGL编写一个简易的2D渲染框架-10 重构渲染器-Pass

    Pass,渲染通路,一个渲染通路指的是一次像素处理和一次顶点处理,也就是指的是一次绘制.简单来说就是顶点数据在渲染管线中走一遍最后绘制. 渲染粒子系统的粒子时,需要开启 OpenGL 的混合模式,并使 ...

随机推荐

  1. goss docker-compose 集成使用

    原理很简单,就是使用volume 进行数据共享, 并执行服务器状态校验 docker-compose 文件 version: "3" services: goss: image: ...

  2. Jenkins系列之Jenkins配置常用工具和如何下载插件

    上一篇我们介绍了Jenkins的安装,这一篇我们介绍如何配置Jenkins的工具和如何下载插件. 首先我们先来看如何配置工具,这里的工具是指JDK.Ant.Maven.Git等. 1.点击系统管理,如 ...

  3. Keepalived+HAProxy实现RabbtiMQ高可用的负载均衡

    HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案,包括Twitter,Reddit,StackOverflow,GitHub在 ...

  4. hadoop之 参数调优

    一. hdfs-site.xml 配置文件 1. dfs.blocksize 参数:hadoop文件块大小描述:新文件的默认块大小,以字节为单位,默认 134217728 字节.可以使用以下后缀(大小 ...

  5. 处理json的常用java类库:Json-lib(org.json)、Gson、Jackson、Fastjson

    更多的处理json的java类库,有人做了性能对比,GitHub地址:https://github.com/fabienrenaud/java-json-benchmark 处理json的java类库 ...

  6. php curl文件上传兼容php5.0~5.6各版本

    PHP 5.0~5.6 各版本兼容的cURL文件上传 最近做的一个需求,使用PHP cURL上传文件.踩坑若干,整理如下. 不同版本PHP之间cURL的区别 PHP的cURL支持通过给CURL_POS ...

  7. golang kafka client

    针对golang的 kafka client 有很多开源package,例如sarama, confluent等等.在使用sarama 包时,高并发中偶尔遇到crash.于是改用confluent-k ...

  8. "二阶“条件概率

    公式: P(E|F)=P(E|GF)P(G|F)+P(E|GcF)P(Gc|F) 解释: 已知F发生,E发生的条件概率为P(E|F). 现在多考虑一个条件G,G可能发生也可能不发生. 若F已发生条件下 ...

  9. appium+python自动化38-adb shell按键操作(input keyevent)

    前言 接着上篇介绍input里面的按键操作keyevent事件,发送手机上常用的一些按键操作 keyevent 1.keyevent事件有一张对应的表,可以直接发送对应的数字,也可以方式字符串,如下两 ...

  10. 为MyEclipse配置Spring的约束

    1.Spring框架概述 Spring是一个Service层的框架,可以整合许多其它框架进行工作 Spring的主要技术是 IOC(DI) AOP IOC - 控制反转(依赖注入) AOP - 免息那 ...