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

为了邮箱5 为了邮箱5     2022-09-06     453

关键词:

  事实上,前面编写的渲染器 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渲染框架-04绘制图片

阅读文章前需要了解的知识,纹理:https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/   过程简述:利用FreeImage库加载图像数据,再创建OpenGL纹理,通过Canvas2D画布绘制,最后又Renderer渲染器渲染   本来想用soil库... 查看详情

基于opengl编写一个简易的2d渲染框架-09重构渲染器-shader

  Shader只是进行一些简单的封装,主要功能:    1、编译着色程序    2、绑定Uniform数据    3、根据着色程序的顶点属性传递顶点数据到GPU   着色程序的编译GLuintShader::createShaderProgram(constchar*vsname,constchar*p... 查看详情

基于opengl编写一个简易的2d渲染框架-05渲染文本

阅读文章前需要了解的知识:文本渲染 https://learnopengl-cn.github.io/06%20In%20Practice/02%20Text%20Rendering/ 简要步骤:获取要绘制的字符的Unicode码,使用FreeType库获取对应的位图数据,添加到字符表中(后面同样的字符可以再表中... 查看详情

基于opengl编写一个简易的2d渲染框架02——搭建opengl环境

由于没有使用GLFW库,接下来得费一番功夫。阅读这篇文章前请看一下这个网页:https://learnopengl-cn.github.io/01%20Getting%20started/02%20Creating%20a%20window/ 以下,我摘取了一点片段 Windows上的OpenGL库  如果你是Windows平台,opengl32.l... 查看详情

基于opengl编写一个简易的2d渲染框架-13使用例子

 这是重构渲染器的最后一部分了,将会给出一个demo,测试模板测试、裁剪测试、半透明排序等等: 上图是本次demo的效果图,中间的绿色图形展现的是模板测试。 模板测试voidinit(Pass*&p1,Pass*&p2){p1=newPass;p2=newPass;... 查看详情

基于opengl编写一个简易的2d渲染框架-12重构渲染器-blockallocator

 BlockAllocator的内存管理情况可以用下图表示   整体思路是,先分配一大块内存Chunk,然后将Chunk分割成小块Block。由于Block是链表的一个结点,所以可以通过链表的形式把未使用的Block连接起来,并保存到pFreeLists中。当... 查看详情

基于opengl编写一个简易的2d渲染框架-11重构渲染器-renderer

 假如要渲染一个纯色矩形在窗口上,应该怎么做?先确定顶点的格式,一个顶点应该包含位置信息vec3以及颜色信息vec4,所以顶点的结构体定义可以这样:structVertex{Vec3position;Vec4color;};然后填充矩形四个顶点是数据信息:Verte... 查看详情

基于opengl编写一个简易的2d渲染框架-07鼠标事件和键盘事件

这次为程序添加鼠标事件和键盘事件   当检测到鼠标事件和键盘事件的信息时,捕获其信息并将信息传送到需要信息的对象处理。为此,需要一个可以分派信息的对象,这个对象能够正确的把信息交到正确的对象。 实... 查看详情

基于opengles的深度学习框架编写

基于OpenGLES的深度学习框架编写背景与工程定位背景项目组基于深度学习实现了视频风格化和人像抠图的功能,但这是在PC/服务端上跑的,现在需要移植到移动端,因此需要一个移动端的深度学习的计算框架。同类型的库caffe-andr... 查看详情

在 MacOS 中模糊的 Opengl 像素完美渲染

】在MacOS中模糊的Opengl像素完美渲染【英文标题】:OpenGLpixel-perfectrenderingblurredinMacOSX【发布时间】:2014-08-2419:02:06【问题描述】:我正在编写一个跨平台应用程序,它使用OpenGL绘制从PNG文件读取的2d图像。我的程序适用于Linux、Wi... 查看详情

opengl绘制三角形(代码片段)

...对象:ElementBufferObject,EBO或IndexBufferObject,IBO渲染管线在OpenGL中,任何事物都在3D空间中,而屏幕和窗口却是2D像素数组,这导致OpenGL的大部分工作都是关于把3D坐标转变为适应你屏幕的2D像素。3D坐标转为2D坐标的处理过程是由Ope... 查看详情

OpenGL 2D像素完美渲染

】OpenGL2D像素完美渲染【英文标题】:OpenGL2Dpixelperfectrendering【发布时间】:2013-12-2115:04:10【问题描述】:我正在尝试渲染2D图像,以便它完全覆盖整个窗口。对于我的测试,我设置了一个窗口,使客户区正好是320x240,纹理也是... 查看详情

OpenGL 2d矩形没有被渲染

】OpenGL2d矩形没有被渲染【英文标题】:OpenGL2drectanglenotbeingrendered【发布时间】:2016-12-2200:07:43【问题描述】:我正在尝试在屏幕上渲染一个矩形。程序运行时,只显示清晰的颜色,没有矩形显示。代码如下:glClearColor(0.0,0.0,0.0,... 查看详情

RGBA 整数值到 OpenGL 纹理

】RGBA整数值到OpenGL纹理【英文标题】:RGBAintegervaluestoOpenGLTexture【发布时间】:2012-04-0216:08:35【问题描述】:我正在用C++编写一个光线投射器,它将其结果输出到常规图像文件。现在,我想将内部RGBA表示(4个整数)渲染到GLUT提... 查看详情

OpenGL:如何在 3d 模式下优化多层相互重叠的 2d 渲染?

】OpenGL:如何在3d模式下优化多层相互重叠的2d渲染?【英文标题】:OpenGL:Howtooptimize2drenderingwithmultiplelayersoverlappingeachotherin3dmode?【发布时间】:2011-06-0612:36:31【问题描述】:我知道如何通过简单地首先渲染最近的平面来加速3d渲... 查看详情

opengl工作流程

  在OpenGL中,一切事物都在3D空间中,但我们的屏幕坐标确实2D像素数组,OpenGL大部分工作就是把3D坐标转换成适应屏幕的2D像素。3D坐标转换成2D屏幕坐标的过程是有OpenGL的图形渲染管线管理的。图形渲染管线的工作可以被划分... 查看详情

opengl-渲染流程

参考技术A在OpenGL中,任何事物都处于3D空间中,而屏幕和窗口却都是2D像素数组,这就导致了OpenGL大部分工作都是关于把3D坐标转变为适配你屏幕的2D像素,3D坐标转为2D坐标的处理过程是由OpenGL的图形渲染管线(指的是一堆原始图... 查看详情

使用 opencl 将软件渲染到 opengl 2d 视图 [关闭]

】使用opencl将软件渲染到opengl2d视图[关闭]【英文标题】:softwarerenderingwithopenclontoopengl2dview[closed]【发布时间】:2011-07-0606:59:44【问题描述】:我想构建一个小的软件渲染库,因为我喜欢体素的想法,以及其他可能的替代渲染方... 查看详情