视频特效学习02- OpenGL渲染基础

学习目标:
  • 1.OpenGL渲染架构(掌握)
    1. OpenGL数据传递的3种方式(理解)
    1. OpenGL提供的着色器(掌握)
    1. 正投影/透视投影API的使用(掌握)
    1. OpenGL上常见图元(会用)
    1. 在存储着色器的情况下渲染图形并能通过键盘控制Demo(实践)

1.OpenGL渲染架构

  • 渲染架构图


    OpenGL渲染架构.png
      1. Client(客户端):Application中的代码和OpenGL API存储在CPU中,由应用程序执行,主系统内存中的驱动程序将数据不断的传递给Serve。
      1. Serve(服务端):操作GPU绘制图形的部分。在Serve端,顶点着色器处理client传递过来的数据,然后将图形进行光栅化,再由片元着色器填充颜色,完成图形的渲染。client与serve是独立异步执行的,它们分属于不同的硬件或者软件块。
      1. GPU渲染流程名词解释:
      • Vertex Shader(顶点着色器):client从Attribibutes、Uniforms、Texture Data3个通道将数据传递给顶点着色器。顶点着色器只处理Attribibutes、Uniforms数据,不处理Texture Data数据。顶点着色器处理传入顶点的数据,包括顶点位置、顶点颜色、光照等,每个顶点都会执行一次。
      • Fragment Shader(片元着色器):Attribibutes无法直接传递给片元着色器,是从顶点着色器传递过来的,Uniforms、Texture Data可以直接传递给片元着色器,片元着色器计算每一个像素点的颜色并填充。
      • Primitive Assembly(基元装配):将图形光栅化处理,将顶点链接起来组成点、线、三角形三种不同的图元,然后对超出屏幕的部分进行裁剪,这是对图形进行裁剪、透视分隔、视口变换、光栅化等操作。
      • Position Vertex:顶点位置
      • ins(输入):将数据拷贝到着色器中。
      • outs(输出):将数据由一个阶段传递到另一个阶段,开发者无法干预其过程。
      • Render渲染:渲染图形

2.OpenGL数据传递的3种方式

通道:Attributes、Uniforms、Texture Data
OpenGL API向GPU传递数据有三个通道,分别是Attributes属性、Uniforms和Texture Data纹理数据,根据场景合理的使用对应的管道

  • Attribibutes(属性):属性传递的是不断发生改变的数据,传入的数据包括顶点坐标、颜色值、纹理坐标、位移、光照法线等,属性可以是整型、浮点型、布尔、4维向量等。Attribibuty只能传递到顶点着色器,不能直接传递到片元着色器,可通过GLSL代码间接传递。
    属性总是以4维向量的形式进行内部存储,顶点坐标是(x,y,z),占3个分量;属性会从本地client内存中复制存储在图形硬件中的一个缓冲区上,这些属性只能提供给顶点着色器使用。

  • Uniforms:传递的是统一数据,如旋转矩阵、变换矩阵等。图形旋转实现是每一个顶点乘以旋转矩阵,确定旋转角度后旋转矩阵不在发生变化,这个旋转矩阵就可以通过Uniform传递,传递的数据类型有整型、浮点型、布尔、4维向量等。最常见的应用是在顶点渲染中设置变换矩阵。uniform值可以直接传递到顶点着色器和片元着色器。uniform变量还可以是标量类型、矢量类型、uniform矩阵。

  • Texture Data(纹理数据):传递图片,渲染图形时的线框填充、颜色填充、纹理填充、像素填充等对图片的处理,在顶点着色器、片元着色器中都可以对纹理数据进行采样和筛选。
    滤镜的实现就是在读取颜色的时候对像素点颜色的处理,可以读取多张纹理使用颜色混合对像素进行填充
    典型的应用场景:片段着色器对一个纹理值进行采样,然后在一个三角形表面应用渲染纹理数据。

tips:不能为了达到目的而使用Uniform值传递颜色值到片元着色器,颜色值只能从Attributes值间接传递到片元着色器。
视频解码渲染使用到的颜色空间是YUV颜色值,需要将YUV乘以转换矩阵转换成RGBA来填充颜色以正确地渲染到屏幕上,这时的旋转矩阵可以通过Uniform传递到片元着色器。

3.OpenGL提供的着色器

固定存储着色器:早期的OpenGL版本封装的,帮助开发者完成图形渲染的程序块。

  • 单元着色器

    • 函数名称:GLShaderManager::UseStockShader(GLT_SHADER_IDENTITY,GLFloat vColor[4])。
    • 参数: 参数1:存储着色器种类-单元着色器;参数2:颜色。
    • 使用场景:绘制OpenGL默认坐标系(-1,1)下图形。图形所有片段会由一种颜色填充。
  • 平面着色器:

    • 函数名称: GLShaderManager::UseStockShader(GLT_SHADER_FLAT,GLFloat mvp[16],GLFloat vColor[4])。
    • 参数: 参数1:存储着色器种类-平面着色器;参数2:允许变化的4*4矩阵;参数3:颜色。
    • 使用场景:在绘制图形时, 可以应⽤变换(模型/投影变换)。
  • 上色着色器:

    • 函数名称:GLShaderManager::UseStockShader(GLT_SHADER_SHADER,mvp[16])
    • 参数: 参数1: 存储着⾊器种类-平面着⾊;参数2:允许变化的4*4矩阵。
    • 使用场景:在绘制图形时, 可以应用变换(模型/投影变换) ,颜⾊将会平滑地插入到顶点之间,称为平滑着色。
  • 默认光源着色器:

    • 函数名称: GLShaderManager::UseStockShader(GLT_SHADER_DEFAULT_LIGHT,GLFloat mvMatrix[16], GLFloat pMatrix[16], GLFloat vColor[4]) 。
    • 参数: 参数1: 存储着⾊器种类-默认光源着⾊器 ;参数2: 模型视图44矩阵;参数3: 投影44矩阵;参数4: 颜⾊值 。
    • 使用场景:在绘制图形时,可以应用变换(模型/投影变换),并且这种着⾊器会使绘制的图形产⽣阴影和光照的效果. 。
  • 点光源着色器:

    • 函数名称: GLShaderManager::UseStockShader(GLT_SHADER_POINT_LIGHT_DIEF,GLFloat mvMatrix[16], GLFloat pMatrix[16],GLFloat vLightPos[3], GLFloat vColor[4])
    • 参数: 参数1: 存储着⾊器种类-点光源着⾊器 ;参数2: 模型视图44矩阵;参数3: 投影44矩阵;参数4:点光源位置;参数5: 颜⾊值。
    • 使用场景:在绘制图形时, 可以应⽤变换(模型/投影变换) ,并且这种着⾊器会使绘制的图形产⽣阴影和光照的效果。它与默认光源着⾊器⾮常类似,区别只是光源位置可能是特定的。
  • 纹理替换矩阵着色器:

    • 函数名称:GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_REPLACE,GLFloat mvMatrix[16],GLint nTextureUnit)
    • 参数: 参数1: 存储着⾊器种类-纹理替换矩阵着色器 ;参数2: 模型视图4*4矩阵;参数3:纹理单元。
    • 使用场景:在绘制图形时,可以应用变换(模型/投影变换),这种着⾊器通过给定的模型视图投影矩阵。使用纹理单元来进⾏颜⾊填充。其中每个像素点的颜⾊都是从纹理中获取。
  • 纹理调整着色器:

    • 函数名称: GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_MODULATE,GLfloat mvMatrix[16],GLfloat vColor[4],GLint nTextureUnit);
    • 参数: 参数1: 存储着⾊器种类-纹理调整着色器;参数2: 模型视图4*4矩阵;参数3:颜色;参数4:纹理单元。
    • 使用场景: 在绘制图形时,可以应用变换(模型/投影变换),这种着⾊器通过给定的模型视图矩阵。 着⾊器将一个基本色乘以一个取自纹理单元nTextureUnit 的纹理.将颜色与纹理进行颜色混合后才填充到片段中。
  • 纹理光源着色器:

    • 函数名称:GLShaderManager::UserStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIEF,GLfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vLightPos[3],GLfloat vBaseColor[4],GLint nTextureUnit)
    • 参数: 参数1: 存储着色器种类-纹理光源着色器;参数2: 模型视图4 * 4矩阵;参数3: 投影4*4矩阵;参数4: 点光源位置;参数5: 颜⾊值(⼏何图形的基本色) ;参数6: 纹理理单元 。
    • 使用场景:在绘制图形时,可以应⽤变换(模型/投影变换)。这种着色器通过给定的模型视图投影矩阵。 着⾊器将⼀个纹理通过漫反射照明计算进⾏调整(相乘)。

4.正投影/透视投影API的使用

  • 正投影:用于平面图形的渲染。使用GLFrumstum::SetOrthgraphic(GLFloat xMin,GLFloat xMax,GLFloat yMin,GLFloat yMax,GLFloat zMin,GLFloat zMax)函数设置正投影矩阵。这些参数是用来设置投影区间大小。单纯的设置正投影没有意义,设置的目的是为了获得投影矩阵。
  • 透视投影:用于3D图形,可以控制图形趋于人的眼睛看到的一样。使用GLFrumstum::SetPerspective(float fFov,float fAspect,float fNear,float fFar)。参数:fFov:垂直方向上的视觉角度 fAspect:纵横比 fNear:近裁剪面距离 fFar:远裁剪面距离 纵横比 = 宽(w)/高(h)。

5.OpenGL上常见图元

  • 7种基本图元


    OpenGL基本图元.png
  • 效果图


    OpenGL基本图元效果图.png
  • OpenGL 点/线 设置方式:

    • 1.最简单也是最常用的 由于OpenGL是状态机,所以使用后记得恢复为原始状态
       glPointSize(4.0f);
      
    • 2.通过使用程序大小模式来设置点大小
       GLfloat size[2] = {2.0f, 4.0f};
       GLflat step = 1.0f;
       glGetFloatv(GL_POINT_SIZE_RANGGE ,sizes);
       glGetFloatv(GL_POINT_GRAULARITY ,&step);
      
    • 3.在顶点着色器或几何着色器中设置点大小 使用GLSL写
      //gl_PointSize是着色器的内建变量可以在着色器源码直接写
       gl_PointSize = 5.0;
      
    • 4.设置线段宽度
      glLineWidth(2.5f);
      
  • OpenGL 三角形:

    • 概念:对于OpenGl光栅化最受欢迎的是三角形。3个顶点就能构成一个三角形。三角形类型来自于顶点。

    • 三角形环绕方式:按照顺序与方向结合来指定顶点的方式成为环绕。默认情况下,具有逆时针方向的多边形为正面。

      OpenGL三角形环绕.png

      \color{#4285f4}{绘制第一个三角形时,线条是按照V0-V1,再到V2,最后回到V0,绘制成一个闭合三角形。图中左侧为正面,右侧为反面。}
      \color{#4285f4}{当然也可以更改顺时针为正面,使用glFrontFace(GL\_CW),GL\_CW:顺时针为正面,GL\_CCW:逆时针为正面}

    • 三角形带:对于很多表面或者形状而言,我们需要绘制几个相连的三角形,使用GL_TRIANGLE_STRIP图元绘制一串相连三角形,提高效率。共用的是一条边。


      OpenGL三角形带画图过程.png

    优点:

    • 1.用前3个顶点指定第一个三角形之后,对于接下来的每一个三角形,只需要载指定1个顶点。绘制大量三角形时,采用这种方法可以节省大量的程序代码和数据存储空间。
    • 2.提高运算性能和节省带宽。更少的顶点意味着数据从内存传输到图形卡的速度更快,并且顶点着色器需要处理的次数也更少了。
  • 三角形扇:对于很多表面或者形状而言,我们需要绘制几个相连的三角形,使用GL_TRIANGLE_FAN图元绘制一组围绕一个中心点相连的三角形。共用的是一个点。


    OpenGL三角形扇画图过程.png

GLBatch,是GLTools中包含的一个简单容器类。

// 开始数据复制
// 参数1:图元
// 参数2:顶点数
// 参数3:一组或者两组纹理坐标(可选)
void GLBatch::Begain(GLeunm primitice, GLuint nVerts, GLuint nTexttureUnints = 0);

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

// 复制表面法线数据
void GLBatch::CopyNormalDataf(GLfloat *vNorms);

// 复制颜色数据
void GLBatch:CopyColorData4f(GLfloat *vColors);

// 复制纹理坐标数据
void GLBatch:CopyTextCoorData2f(GLFloat *vTextCoords,GLuint uiTextureLayer);

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

//绘制图形
void GLBatch::Draw(void);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 学习目标: OpenGL 渲染结构 如何使用7种OpenGL基础图元 如何使用储存着色器 如何使用Uniform属...
    velue阅读 1,854评论 0 0
  • 一、OpenGL与着色器 在OpenGL3.0之前,OpenGL包含一个固定功能的管线,它可以在不使用着色器的情况...
    MirL阅读 584评论 0 0
  • OpenGL基础渲染 一、OpenGL 与 着色器 在OpenGL 3.0之前,OpenGL包含一个固定功能的管线...
    wjl7004阅读 414评论 0 2
  • 由于OpenGL是基于C的API,因此它非常便携且受到⼴泛支持。作为C API,它与基于Objective-C的C...
    吕建雄阅读 391评论 0 0
  • 上一节为大家介绍了OpenGL的基本术语还编写了一个最基础的“HelloWorld”的Demo,相信大家肯定目标不...
    Mr姜饼阅读 861评论 0 6