OpenGL初识

OpenGL初识

图形API简介

  • OpenGL(Open Graphics Library):一个跨编程语言、跨平台的图形程序接口,它将计算机的资源抽象称为一个个OpenGL的对象,对这些资源的操作抽象为⼀个个的OpenGL指令。
  • OpenGL ES (OpenGL for Embedded Systems):是OpenGL 三维图形API的子集,针对⼿手机、PDA和游戏主机等嵌⼊式设备而设计,OpenGL ES为了支持新改进的方法抛弃了对于旧式的低效的内存复制操作的支持。
  • DirectX:是由很多API组成的,DirectX并不是一个单纯的图形API。最重要的是DirectX是属于Windows上⼀个多媒体处理API。并不支持Windows以外的平台,所以不是跨平台框架。按照性质分类,可以分为四⼤大部分,显示部分、声⾳部分、输入部分和网络部分。
  • Metal:Apple为游戏开发者推出了了新的平台技术Metal,该技术能够为3D图像提高10倍的渲染性能。Metal是Apple为了解决3D渲染⽽而推出的框架。

图形API的功能:实现图形的底层渲染

  • 在游戏开发中,对于游戏场景/游戏⼈物的渲染
  • 在⾳音视频开发中,对于视频解码后的数据渲染
  • 在地图引擎,对于地图上的数据渲染
  • 在动画中,实现动画的绘制
  • 在视频处理理中,对于视频加上滤镜效果

OpenGL名词注解

  • GPU:图形处理单元,图形卡上的可编程芯片,它是高度并行的,并且具有非常快的速度。能够结合几何、颜色、灯光和其他数据而产生一个屏幕图像的硬件组件。

  • 渲染:屏幕只有2维,因此显示3D数据的技巧就在于产生能够迷惑眼睛使其看到丢失的第3维的一个图像。将数学和图形数据转换成3D空间图像的操作叫做渲染

  • 像素:在计算机上显示的图片是由矩形的颜色点组成的,这些矩形的颜色点叫做像素。单独的像素,如果通过放大镜仔细观察显示器,你会看到每个像素都是由3个颜色元素组成的,即一个红点、一个绿点和一个蓝点。

  • 缓存OpenGL ES为两个内存区域间的数据交换定义了缓存(buffers)的概念。缓存是指 图形处理器能够控制和管理的连续RAM。

程序从 CPU 的内存复制数据到 OpenGL ES 的缓存。在 GPU 取得一个缓存的所有权以后,运行在 CPU 中的程序理想情况下将不 再接触这个缓存。通过控制独占的缓存,GPU 就能够尽可能以最有效的方式读写内存。 图形处理器把它处理大量数据的能力异步同时地应用到缓存上,这意味着在 GPU 使用 缓存中的数据工作的同时,运行在 CPU 中的程序可以继续执行。

  • OpenGL上下文(context):用于配置OpenGL的保存在特定平台的软件数据结构中的信息会被封装到一个OpenGL上下文(context)中。OpenGL是一个状态机器,这意味着在一个程序中设置了一个配置值后,这个值会一直保持,直到程序修改了这个值。切换上下文往往会产生较大的开销,但是不同的绘制模块,可能需要使用完全独立的状态管理。因此,可以在应用程序中分别创建多个不同的上下⽂,在不同线程中使用不同的上下文,上下文之间共享纹理、缓冲区等资源。这样的方案,会⽐反复切换上下文,或者大量修改渲染状态,更加合理高效的。

  • OpenGL状态机

    1. 状态机是一个抽象的模型,表示一组状态变量的集合。每个状态变量可以有各种不同的值,或者只能可以打开或关闭等。当我们在OpenGL中进行绘图时,如果每次都要指定所有这些变量显然有点不切实际。反之,OpenGL使用了一种状态模型(或称状态机)来追踪所有的OpenGL状态变量。当一个状态值被设置之后,它就一直保持这个状态,直到其他函数对它进行修改为止。许多状态只能简单地打开或关闭。例如,深度测试就是要么打开、要么关闭。
    2. OpenGL可以记录自己的状态(比如:当前所使用的颜色、是否开启了混合功能,等等,这些都是要记录的)
    3. OpenGL可以接收输入(当我们调用OpenGL函数的时候,实际上可以看成OpenGL在接收我们的输入),根据输入的内容和自己的状态,修改自己的状态,并且可以得到输出(比如我们调用glColor3f,则OpenGL接收到这个输入后会修改自己的“当前颜色”这个状态;我们调用glRectf,则OpenGL会输出一个矩形)
    4. OpenGL可以进入停止状态,不再接收输入。这个可能在我们的程序中表现得不太明显,不过在程序退出前,OpenGL总会先停止工作的。
  • 顶点(空间中的一个位置):在2D和3D中,当我们绘制一个物体时,实际上是用一些更小的称为图元(Primitives)的形状来组成这个物体。图元是一维或者二维的实体或表面,如点、直线和多边形(平面多边的形状)。在3D空间中,我们把图元组合在一起创建3D物体。例如一个三维立方体是由6个正方形组成,每个正方形代表一个独立的面。正方形(其他任何图元)的每个角称为顶点(Vertex)。这些顶点就在3D空间中指定了一个特定的坐标。顶点其实就是2D或3D空间中的一个坐标。

  • 顶点数组:一个顶点(vertex)就是一个坐标空间的点。顶点数组就是存储这一个图形的所有顶点数据的一段缓存。

  • 管线

    • OpenGL的模型就好比一条生产线或者管线。数据流在这个模型中通常是单一路经的,数据通过我们的程式调用的命令进入管线的开端,然后流过一个一个阶段直到管线的末端。
    • OpenGL通过连接多个叫做着色器的小程序并佐以固定功能函数作为"胶水"来工作。当我们绘图时,图形处理器执行我们的着色器并将它们的输入输出在管线中串联起来,直到像素完成于管线末端。
  • 固定管线/存储着色器

    • 在早期的OpenGL版本,它封装了很多种着色器程序块内置的一段包含了光照、坐标变换、裁剪等等诸多功能的固定shader程序来完成,来帮助开发者来完成图形的渲染而开发者只需要传入相应的参数,就能快速完成图形的渲染。
    • 但是由于OpenGL的使用场景非常丰富,固定管线或存储着色器无法完成每一个业务。这时将相关部分开放成可编程。
  • 着色器程序shader

    • 就全面的将固定渲染管线架构变为了可编程渲染管线。因此,OpenGL在实际调用绘制函数之前,还需要指定一个由shader编译成的着色器程序。常见的着色器主要有顶点着色器(VertexShader),片段着色器(FragmentShader)/像素着色器(PixelShader) ,几何着色器(GeometryShader)曲面细分着色器(TessellationShader)。片段着色器和像素着色器只是在OpenGL和DX中的不同叫法而已。可惜的是,直到OpenGL ES 3.0,依然只支持了顶点着色器和片段着色器这两个最基础的着色器。
    • OpenGl在处理Shader时,和其他编译器一样。通过编译、链接等步骤,生成了着色器程序(glProgram),着色器程序同时包含了顶点着色器和片段着色器的运算逻辑。在0penGL进行绘制的时候,首先由顶点着色器对传入的顶点数据进行运算。再通过图元装配,将顶点转换为图元。然后进行光栅化,将图元这种矢量图形,转换为栅格化数据。最后,将栅格化数据传入片段着色器中进行运算。片段着色器会对栅格化数据中的每一个像素进行运算,并决定像素的颜色。
  • 顶点着色器VertexShader

    • 用来处理图形每个顶点变换(旋转/平移/投影等)。
    • 顶点着色器是逐顶点运算的程序,也就是说每个顶点数据都会执行一次顶点着色器,当然这是并行的,并且顶点着色器运算过程中无法访问其他顶点的数据。
    • 典型的需要计算的顶点属性主要包括顶点坐标变换、逐顶点光照运算等等。顶点坐标由自身坐标系转换到归一化坐标系的运算,就是在这里发生的。
  • 片元着色器程序FragmentShader

    • 用来处理图形中每个像素点颜色的计算和填充的程序。
    • 它是逐像素运算的程序,也就是说每个像素都会执行一次片段着色器,当然也是并行的。
  • GLSL(OpenGL Shadding Language):OpenGL着色器使用一种叫做OpenGL着色语言(OpenGL Shading Language)的语言进行编写,或者叫做GLSL。这个语言的编译器内置在OpenGl中。

  • 光栅化Rasterization:实际绘制或填充每个顶点之间的像素形成线段就叫做光栅化。

  • 纹理:一个用来保存图像的颜色元素值的 OpenGL ES 缓存。

  • 混合Blending:像素的颜色将会和帧缓冲区中颜色附着上的颜色进行混合,混合的算法可以通过0penGL的函数进
    行指定。

  • 变幻矩阵:计算图形发生变化的矩阵。

  • 投影矩阵:用于将3D坐标转换为2D坐标,并在2D下绘制。

  • 渲染上屏/交换缓冲区

    • 一般窗口上显示的是某个渲染缓冲区的资源,如果直接在这个缓冲区中进行渲染,在渲染过程中,窗口会显示不完整的图像。
    • 所以OpenGL程序都至少使用两个缓冲区,在窗口中看到的是屏幕缓冲区,还有一个不显示的离屏幕缓冲区。在离屏缓冲区渲染完成后,通过离屏缓冲区和屏幕缓冲区进行数据交换实现屏幕显示。
    • 屏幕的刷新一般是逐行进行的。如果一次刷新未结束时进行了两个缓冲区交换,图像就会错乱,一部分是旧图的内容,一部分是新图的内容。因此,交换需要等到屏幕发出刷新完成的信号,这个信号叫垂直同步信号,这个技术就是垂直同步技术。
    • 在使用双缓冲区和垂直同步技术的情况下,离屏渲染完成后收到垂直同步信号并交换缓冲区后才能进行下一帧的渲染。这样无法达到最高的帧率,硬件性能产生了浪费。因此,引入了三缓冲区技术。等待垂直同步信号时,交替渲染两个离屏缓冲区,屏幕刷新完成后,屏幕渲染区和最近完成渲染的离屏缓冲区交换。

OpenGL坐标系解析

在一个简单的平面计算机屏幕上绘制点和线时,我们根据行和列指定位置。

在OpenGL或几乎所有的3D PAI中创建一个用于绘制的窗口时,必须指定希望使用的坐标系统以及指定的坐标如何映射到实际的屏幕像素。

2D笛卡尔坐标系

在二维绘图中,最常用的是笛卡尔坐标系统。笛卡尔坐标由一个x坐标和y坐标构成。x坐标测量水平方向的位置,y坐标测量垂直方向的位置。x轴和y轴垂直相交定义了一个平面。

2D笛卡尔坐标系

3D笛卡尔坐标系

2D笛卡尔坐标新增一个表示深度分量的z轴就是3D笛卡尔坐标。

3D笛卡尔坐标系

视口

视口就是窗口内部用于绘制裁剪区域的客户区域。视口简单的把裁剪区域映射到窗口中的一个区域。通常,视口被定义为整个窗口,但这并非严格必须的。

视口被定义为整个窗口

有时我们只想在窗口的一部分部分进行绘图。我们可以使用视口来缩小和放大窗口中的图像,也可以通过把视口设置大于窗口的用户区域,从而只显示裁剪区域的一部分。

视口被定义为窗口的一部分

投影方式

首先需要理解投影:把3D几何图形的坐标数据投影在一个2D的平面。就像用笔在玻璃上描摹出玻璃后面的物体的外形。而平面上的投影就是视景体。通过指定投影,我们可以指定在窗口中显示的视景体。

3D图像投影到2D平面

正投影

正投影又叫平行投影。使用这种投影时,需要指定一个正方形或长方形的视景体。视景体之外的任何物体都不会被绘制。而且,所有实际大小相同的物体在屏幕上都具有相同的大小,不管它们是远是近。

正投影

我们还可以在正投影中通过指定远、近、左、右、顶和底裁剪平面来指定视景体。在这个视景体中出现的物体和图形将被投影( 考虑它们的方向)到一个在屏幕上出现的2D图像。

透视投影

在透视投影中,远处的物体看上去比近处的物体更小一些。它的视景体看上去有点像一个顶部被削平的金字塔。剩下来的这个形状称为平截头体( Frustum)。靠近视景体前面的物体看上去比较接近它们的原始大小。但是,当靠近视景体后部的物体被投影到视景体的前部时,它们看上去就显得比较小。在模拟和3D动画中,这种投影能够获得最大程度的逼真感。

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