基于OpenGL编写一个简易的2D渲染框架-08 重构渲染器-整体架构

摘要:
第二种实现方式:这次渲染器要实现的功能:1、对于不同的顶点可以设置不同的OpenGL状态进行绘制。在渲染时1、渲染器会迭代每一个Pass2、对顶点数据进行排序3、设置OpenGL状态4、合并顶点数据5、设置着色器6、绑定Uniform数据7、最后进行渲染。但是这样代价较高,这次渲染器用的是这种方式。VertexIndexData数组用于对顶点数据进行排序,主要是解决半透明图形的渲染问题。接下来将对完成渲染器的各个部分。

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

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

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

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

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

1、传递数据到 GPU

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

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

4、绘制顶点

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

第一种实现方式:

  基于OpenGL编写一个简易的2D渲染框架-08 重构渲染器-整体架构第1张

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编写一个简易的2D渲染框架-08 重构渲染器-整体架构第2张

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

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

基于OpenGL编写一个简易的2D渲染框架-08 重构渲染器-整体架构第3张

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

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

2、对顶点数据进行排序

3、设置 OpenGL 状态

4、合并顶点数据

5、设置着色器

6、绑定 Uniform 数据

7、最后进行渲染。

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

基于OpenGL编写一个简易的2D渲染框架-08 重构渲染器-整体架构第4张

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

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

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

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

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

免责声明:文章转载自《基于OpenGL编写一个简易的2D渲染框架-08 重构渲染器-整体架构》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇等保2.0一级安全要求Internal error (java.lang.reflect.InaccessibleObjectException): Unable to make protected void java.util.ResourceBundle.setParent(java.util.ResourceBundle)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

《QT Creator快速入门》第十二章:3D绘图

OpenGL是一套跨平台的用来渲染3D图形的API。OpenGL自身是一个巨大的状态机:一系列的变量描述OpenGL此刻应当如何运行,OpenGL的状态通常被称为OpenGL上下文(Context)。我们通常使用如下途径去更改OpenGL状态:设置选项,操作缓冲,最后,我们使用当前OpenGL上下文来渲染。 假设当我们想告诉OpenGL去画线段而不是三角形...

【Chromium中文文档】跨进程通信 (IPC)

跨进程通信 (IPC) 转载请注明出处:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//General_Architecture/Inter-process_Communication.html 全书地址 Chromium中文文档 for https://www.chromium.org/...

深度自编码器(Deep Autoencoder)MATLAB解读

深度自编码器(Deep Autoencoder)MATLAB解读作者:凯鲁嘎吉 - 博客园http://www.cnblogs.com/kailugaji/ 这篇文章主要讲解Hinton在2006年Science上提出的一篇文章“Reducing the dimensionality of data with neural networks”的主要思想与M...

OpenGL的glOrtho平行投影函数详解[转]

glortho函数可以将当前的可视空间设置为正投影空间。基参数的意义如图,如果绘制的图空间本身就是二维的,可以使gluOrtho2D.他的使用类似于glOrtho 原型是: voidglOrtho(GLdoubleleft,                   GLdoubleright,                    GLdoublebottom...

[原] OpenGL ES 学习笔记 (一)

1.OpenGL ES 的坐标系在屏幕上的分布 OpenGL ES 的坐标系{x, y, z} 通过图片的三维坐标系可以知道: - 它是一个三维坐标系 {x, y, z} - 三维坐标中心在正方体的几何中心 {0, 0, 0} - 整个坐标系是 [0, 1] 的点,也就是说 OpenGL 中只支持 0 ~ 1 的点 (这里所讲的 0 和 1 ,最好理...

OpenGL教程一

引自:https://blog.csdn.net/u013654125/article/details/73613644 GLEW, GLFW和GLM介绍 现在你有了工程,就让我们开始介绍下工程所用到的开源库和为啥需要这些。 The OpenGL Extension Wrangler (GLEW)是用来访问OpenGL 3.2 API函数的。不幸的是你不能...