美文网首页
OpenGL-渲染架构

OpenGL-渲染架构

作者: 卖馍工程师 | 来源:发表于2020-07-03 22:49 被阅读0次

    OpenGL设计模式

    OpenGL是按照客户机-服务器模式设计的。需要注意的是并非指我们平常所理解的移动端与后端。

    客户端:

    • 负责发送OpenGL指令
    • CPU上面存储的代码,比如OpenGLApi,C和C++代码

    服务端:

    • 负责接收OpenGL命令并执行相应的操作
    • 调用的是GPU芯片
    客户端-服务器

    进一步阐述

    • 客户端 是存储在CPU储存器中的,并且在应用程序中执行或者在主系统内存中驱动程序中执行。驱动程序会将渲染命令数组组合起来,发送给 服务器 执行!
    • 服务器客户端功能上也是异步的。客户端不断的把数据块和命令块组合在⼀起输送到缓冲区,然后缓冲区就会发送到服务器执行

    如果服务端停止工作等待客户端,或者客户端停止工作来等待服务端做好接受更多的命令和准备,我们把这种情况成为 管线停滞

    OpenGL渲染架构

    OpenGL渲染架构

    首先理解下绘图过程

    无非是把数据从系统内存中复制到图形卡,然后绘制出图形

    绘图流程

    中间涉及到 着色器 的流程。顶点着色器 处理从客户端输入的数据,用数学运算来计算光照效果、位移、颜色值等。有几个顶点,顶点着色器就要执行几次。

    通过图元装配,将顶点组成在一起,变成 图元

    进而通过裁剪、转换窗口坐标、光栅化,输入到 片元着色器片元着色器,将对应的栅格(像素)填充为具体的颜色。

    在这里,顶点着色(包括细分和几何着色)决定了一个图元应该位于屏幕的什么位置,呈现什么形状;而 片元着色 使用这些信息来决定某个片元的颜色应该是什么。

    对于渲染流程详细流程,有兴趣可以移步OpenGL渲染流程

    这其中,渲染数据是如何在着色器中传递的?我们继续看上面的OpenGL渲染架构图。

    客户端向服务端传递数据的方式

    • Attributes

    就是对每⼀个顶点都要作出改变的数据元素。实际上,顶点位置本身就是一个属性.。属性可以是浮点类型,整型,布尔类型等。

    • 常用属性传递的数据 顶点数据(x,y,z,w),颜色值,光照计算法线,投影矩阵、模型矩阵,纹理坐标(图片映射坐标)
    • 属性总是以四维向量的形式进行内部存储
    • 属性会从本地客户端内存中复制存储在图像硬件中的一个缓冲区中
    • 属性只供顶点着色器使用,对片段着色器没有意义

    Attributes 只能输入到顶点着色器,无法“直接”输入到片元着色器

    • Texture Data

    对纹理进行采样和筛选。纹理数据的作用不仅仅是表现图形。很多图形文件格式都是以无符号字节形式对颜色分量进行存储的,但我们仍然可以设置浮点纹理。这就是说,任何大型浮点数据块(例如消耗资源很大的函数的大型查询表)都可以通过这种方式传递给着色器。

    纹理数据 可以直接输入到顶点着色器, 也可以直接输入到片元着色器

    • Uniforms

    通过设置 Uniform 变量就紧接着发送一个图元批次处理命令。Uniform 变量实际上可以无限次的使⽤。 设置一个应用于整个表⾯面的单个颜色值,还可也是一个时间值。

    uniform变量最常见的应用是在顶点渲染中设置变换矩阵

    Uniforms 可以直接输入到顶点着色器,也可以直接输入到片元着色器

    • Ins and Outs

    着色器之间可以按照固定流程 in 和 out,相应地,数据也可以逐层传递

    在OpenGL中通过GLBatch(是GLTools中包含的简单容器类)批次类来设置图元连接方式和组装顶点数据:

    GLBatch可以作为7种图元的简单批次容器使用。而且它知道在使用GL_ShaderManager支持的任意存储着色器时如何对图元进行渲染。
    使用 GLBatch 类非常简单。首先对批次进行初始化,告诉这个类它代表哪种图元,其中包括的顶点数,以及(可选)一组或两组纹理坐标。

    参数1:图元
    参数2:顶点数 
    参数3:一组或者2组纹理坐标(可选)
    void GLBatch::Begin(GLeunm primitive,GLuint nVerts,GLuint nTexttureUnints = 0);
    
    //绘制图形
    void GLBatch::Draw(void);
    

    然后,至少要复制一个由3分量(x, y, z)顶点组成的数组。

    //复制顶点数据(⼀一个由3分量量x,y,z顶点组成的数组)
    void GLBatch::CopyVerterxData3f(GLfloat *vVerts);
    

    还可以选择复制表面发现、颜色和纹理坐标。

    //复制表⾯法线数据
    void GLBatch::CopyNormalDataf(GLfloat *vNorms);
    //复制颜色数据
    void GLBatch::CopyColorData4f(GLfloat *vColors);
    //复制纹理坐标数据
    void GLBatch::CopyTexCoordData2f(GLFloat *vTextCoords, GLuint uiTextureLayer);
    

    完成上述工作以后,可调用End来表明已经完成了数据复制工作,并且将设置内部标记,以通知这个类包含哪些属性。

    //结束数据复制
    void GLBatch::End(void);
    

    基本图元连接方式

    基本图元
    图元 描述
    GL_POINTS 每个顶点在屏幕上都是单独点
    GL_LINES 每⼀对顶点定义⼀个线段
    GL_LINE_STRIP 一个从第⼀个顶点依次经过每⼀个后续顶点而绘制的线条
    GL_LINE_LOOP 和GL_LINE_STRIP相同,但是最后⼀个顶点和第⼀个顶点连接起来了
    GL_POLYGON 每4个顶点定义一个新的四边形
    GL_QUADS 每4个顶点连接并内部填充
    GL_QUAD_STRIP 形成四边形后2个顶点复用
    GL_TRIANGLES 每3个顶点定义⼀个新的三角形
    GL_TRIANGLE_STRIP 共⽤一个条带(strip)上的顶点的一组三⻆形
    GL_TRIANGLE_FAN 以⼀个圆点为中⼼呈扇形排列,共⽤相邻顶点的⼀组三⻆形
    • 三角形带

    对于很多表面或者形状⽽⾔,我们会需要绘制⼏个相连的三角形. 这时我们可以使用GL_TRIANGLE_STRIP 图元绘制一串相连三角形,从而节省大量的时间。

    三角形带
    • 三角形扇

    对于很多表面或者形状⽽⾔言,我们会需要绘制⼏个相连的三角形. 这时我们可以使用GL_TRIANGLE_FAN 图元绘制一组围绕一个中心点相连的三⻆形。

    三角形扇

    运用三角形带和三角形扇优点:

    • 复用:⽤前3个顶点指定第1个三角形之后,对于接下来的每一个三⻆形,只需要再指定1个顶点。需要绘制⼤量的三角形时,采用这种⽅法可以节省⼤量的程序代码和数据存储空间
    • 效率:提供运算性能和节省带宽。更少的顶点意味着数据从内存传输到图形卡的速度更快,并且顶点着色器需要处理的次数也更少了了。

    几种固定管线下的着色器

    单元着⾊器

    参数1: 单元着⾊器-GLT_SHADER_IDENTITY
    参数2: 颜⾊值
    GLShaderManager::UserStockShader(GLT_SHADER_IDENTITY, 
                                     GLfloat vColor[4]);
    

    使⽤场景:只是简单地使用默认的笛卡尔坐标系(坐标范围-1.0~1.0)。 图形所有片段都会以⼀种颜⾊填充,无法做变化,属于最基本的单元着色器。

    平⾯着⾊器

    参数1: 平⾯着⾊器-GLT_SHADER_FLAT
    参数2: 允许变化的4*4矩阵
    参数3: 颜⾊色值
    GLShaderManager::UserStockShader(GLT_SHADER_FLAT,
                                     GLfloat mvp[16],
                                     GLfloat vColor[4]);
    

    使⽤场景:将单位着色器进行了扩展,允许为集合图形变换指定一个 4 x 4 的变换矩阵

    上⾊着⾊器

    参数1: 上⾊着⾊器-GLT_SHADER_SHADED
    参数2: 允许变化的4*4矩阵
    GLShaderManager::UserStockShader(GLT_SHADER_SHADED,
                                     GLfloat mvp[16]);
    

    使⽤场景:唯一的 Uniform 值就是在几何图形中应用的变换矩阵。GLT_ATTRIBUTE_VERTEX 和 GLT_ATTRIBUTE_COLOR 在这种着色器中都会使用。颜色值将被平滑地插入顶点之间(称为平滑着色)。

    默认光源着⾊器

    参数1: 默认光源着⾊器-GLT_SHADER_DEFAULT_LIGHT
    参数2: 模型4*4矩阵
    参数3: 投影4*4矩阵
    参数4: 颜⾊值
    GLShaderManager::UserStockShader(GLT_SHADER_DEFAULT_LIGHT,
                                     GLfloat mvMatrix[16],
                                     GLfloat pMatrix[16],
                                     GLfloat vColor[4]);
    

    使⽤场景:这种着色器使对象产生阴影和光照的效果。需要模型视图矩阵、投影矩阵和作为基本色的颜色值等 Uniform 值。所需的属性有 GLT_ATTRIBUTE_VERTEX(顶点分量)和 GLT_ATTRIBUTE_NORMAL(表面法线)。

    点光源着⾊器

    参数1: 点光源着⾊器-GLT_SHADER_POINT_LIGHT_DIEF
    参数2: 模型4*4矩阵
    参数3: 投影4*4矩阵
    参数4: 点光源的位置
    参数5: 漫反射颜⾊值
    GLShaderManager::UserStockShader(GLT_SHADER_POINT_LIGHT_DIEF,
                                     GLfloat mvMatrix[16],
                                     GLfloat pMatrix[16],
                                     GLfloat vLightPos[3],
                                     GLfloat vColor[4]);
    

    使⽤场景:和默认光源着色器很相似,但光源位置可能是待定的。接受 4 个 Uniform 值,即模型视图矩阵、投影矩阵、视点坐标系中的光源位置和对象的基本漫反射颜色。同样所需的属性有 GLT_ATTRIBUTE_VERTEX(顶点分量)和 GLT_ATTRIBUTE_NORMAL(表面法线)。

    纹理替换矩阵着⾊器

    参数1: 纹理替换矩阵着⾊器-GLT_SHADER_TEXTURE_REPLACE
    参数2: 模型4*4矩阵
    参数3: 纹理单元
    GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_REPLACE,
                                     GLfloat mvMatrix[16],
                                     GLint nTextureUnit);
    

    使⽤场景:着色器通过给定的模型视图投影矩阵,使用绑定到 nTextureUnit(纹理单元) 指定的纹理单元的纹理对几何图形进行变换。片段颜色是从纹理样本中直接获取的。所需的属性有 GLT_ATTRIBUTE_VERTEX(顶点分量)和 GLT_ATTRIBUTE_NORMAL(表面法线)。

    纹理调整着⾊器

    参数1: 纹理调整着⾊器-GLT_SHADER_TEXTURE_MODULATE
    参数2: 模型4*4矩阵
    参数3: 颜⾊值
    参数4: 纹理单元
    GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_MODULATE,
                                     GLfloat mvMatrix[16],
                                     GLfloat vColor[4],
                                     GLint nTextureUnit);
    

    使⽤场景:这种着色器将一个基本色乘以一个取自纹理单元 nTextureUnit 的纹理。所需的属性有 GLT_ATTRIBUTE_VERTEX(顶点分量)和 GLT_ATTRIBUTE_TEXTURE0(纹理坐标)。

    纹理光源着⾊器

    参数1:纹理光源着⾊器-GLT_SHADER_TEXTURE_POINT_LIGHT_DIEF
    参数2: 模型4*4矩阵
    参数3: 投影4*4矩阵
    参数4: 点光源位置
    参数5: 颜⾊值
    参数6: 纹理单元
    GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIEF,
                                     GLfloat mvMatrix[16],
                                     GLfloat pMatrix[16],
                                     GLfloat vLightPos[3],
                                     GLfloat vBaseColor[4],
                                     GLint nTextureUnit);
    

    使⽤用场景:这种着色器将一个纹理通过漫反射照明计算进行调整(相乘),光线在视觉空间中的位置是给定的。这种着色器接受 5 个 Uniform 值,即模型视图矩阵、投影矩阵、视觉空间中的光源位置、几何图形的基本色和将要使用的纹理单元。所需的属性有 GLT_ATTRIBUTE_VERTEX(顶点分量)、GLT_ATTRIBUTE_NORMAL(表面法线)和 GLT_ATTRIBUTE_TEXTURE0(纹理坐标)。

    相关文章

      网友评论

          本文标题:OpenGL-渲染架构

          本文链接:https://www.haomeiwen.com/subject/rhasqktx.html