基于OpenGL编写一个简易的2D渲染框架-08 重构渲染器-整体架构
事实上,前面编写的渲染器 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 重构渲染器-整体架构的更多相关文章
- 基于OpenGL编写一个简易的2D渲染框架-05 渲染文本
阅读文章前需要了解的知识:文本渲染 https://learnopengl-cn.github.io/06%20In%20Practice/02%20Text%20Rendering/ 简要步骤: 获 ...
- 基于OpenGL编写一个简易的2D渲染框架-06 编写一个粒子系统
在这篇文章中,我将详细说明如何编写一个简易的粒子系统. 粒子系统可以模拟许多效果,下图便是这次的粒子系统的显示效果.为了方便演示,就弄成了一个动图. 图中,同时显示了 7 种不同粒子效果,看上去效果挺 ...
- 基于OpenGL编写一个简易的2D渲染框架-01 创建窗口
最近正在学习OpenGL,我认为学习的最快方法就是做一个小项目了. 如果对OpenGL感兴趣的话,这里推荐一个很好的学习网站 https://learnopengl-cn.github.io/ 我用的 ...
- 基于OpenGL编写一个简易的2D渲染框架-04 绘制图片
阅读文章前需要了解的知识,纹理:https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/ 过程简述:利用 FreeI ...
- 基于OpenGL编写一个简易的2D渲染框架-09 重构渲染器-Shader
Shader 只是进行一些简单的封装,主要功能: 1.编译着色程序 2.绑定 Uniform 数据 3.根据着色程序的顶点属性传递顶点数据到 GPU 着色程序的编译 GLuint Shader::cr ...
- 基于OpenGL编写一个简易的2D渲染框架-03 渲染基本几何图形
阅读文章前需要了解的知识,你好,三角形:https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/ 要 ...
- 基于OpenGL编写一个简易的2D渲染框架-02 搭建OpenGL环境
由于没有使用GLFW库,接下来得费一番功夫. 阅读这篇文章前请看一下这个网页:https://learnopengl-cn.github.io/01%20Getting%20started/02%20 ...
- 基于OpenGL编写一个简易的2D渲染框架-11 重构渲染器-Renderer
假如要渲染一个纯色矩形在窗口上,应该怎么做? 先确定顶点的格式,一个顶点应该包含位置信息 vec3 以及颜色信息 vec4,所以顶点的结构体定义可以这样: struct Vertex { Vec3 p ...
- 基于OpenGL编写一个简易的2D渲染框架-10 重构渲染器-Pass
Pass,渲染通路,一个渲染通路指的是一次像素处理和一次顶点处理,也就是指的是一次绘制.简单来说就是顶点数据在渲染管线中走一遍最后绘制. 渲染粒子系统的粒子时,需要开启 OpenGL 的混合模式,并使 ...
随机推荐
- leetcode:Reverse Integer【Python版】
1.在进入while之前,保证x是非负的: 2.符号还是专门用flag保存 =================== 3.另一思路:将integer转换成string,然后首位swap,直至中间: cl ...
- jsp servlet 进行基于js的用户验证
写这个只是完成使用js文件参数进行用户验证的处理的jsp 版,已经写过 asp.net php nodejs 以及纯js的,现在完善jsp的 使用的技术是比较简单的就是站点应用我们的js脚本,但是是带 ...
- 在CentOS和RHEL中配置SNMPv3
首先,使用yum安装必要的软件 [root@server ~]# yum install net-snmp-utils net-snmp-devel安装完成之后, 先停止snmpd,再创建具有只读属性 ...
- Linux小问题以及解决方案
1.Linux的时间有问题? ntpdate pool.ntp.org 2.要把一条命令开机执行开机 vim /etc/rc.local 添加要执行的命令 3.系统中网络进程的端口监听情况: nets ...
- FastAdmin selectPage 前端传递查询条件
★夕狱-东莞 2018/2/2 16:19:33 selectpage 怎么在前端传递查询条件,看了下源码,好像有个custom,怎么用来的,比如我要下拉的时候,只显示id=1的数据 Karson-深 ...
- oracle之 变更OS时间对数据库的影响
本文:说明提供了操作系统日期变更对数据库.应用程序数据和作业的影响. 1.它将会影响插入的任何记录,如果涉及到sysdate,则更改日期.2.它还会影响在那个日期运行的任何调度器作业. 如果将系统时间 ...
- CDN、浏览器缓存
CDN是什么? 谈到CDN的作用,可以用8年买火车票的经历来形象比喻: 8年前,还没有火车票代售点一说,12306.cn更是无从说起.那时候火车票还只能在火车站的售票大厅购买,而我所住的小县城并不通火 ...
- Excel的方向键失灵
Excel的方向键操作不再是sheet范围内转动:而是变成了整个sheet页面在跳动. 不只是Excel,viso也是如此. 这是因为你的Scroll Lock键被按下了:所致箭头被解读为页面滚轮在滑 ...
- JZ2440 裸机驱动 第14章 ADC和触摸屏接口
本章目标: 了解S3C2410/S3C2440和触摸屏的结构: 了解电阻触摸屏的工作原理和等效电路图: 了解S3C2410/S3C2440触摸屏控制器的多种工作模式: ...
- 关闭IE 对剪切板访问的提示
在internet 选项-“安全”选项卡-自定义级别. 在“脚本”下面找到“允许对剪切板进行编程访问”,选择“启用”即可. -END