OpenGL学习与探索

初探OpenGL 及相关名词解析

2020-07-02  本文已影响0人  Sheisone

一、什么是OpenGL

我们先了解一下OpenGL到底是什么?一般它被认为是一个API(Application Programming Interface, 应用程序编程接口),包含了一系列可以操作图形、图像的函数。然而,OpenGL本身并不是一个API,它仅仅是一个由Khronos组织制定并维护的规范(Specification)。

OpenGL Logo

OpenGL规范严格规定了每个函数该如何执行,以及它们的输出值。至于内部具体每个函数是如何实现(Implement)的,将由OpenGL库的开发者自行决定(译注:这里开发者是指编写OpenGL库的人)。因为OpenGL规范并没有规定实现的细节,具体的OpenGL库允许使用不同的实现,只要其功能和结果与规范相匹配(亦即,作为用户不会感受到功能上的差异)。

实际的OpenGL库的开发者通常是显卡的生产商。你购买的显卡所支持的OpenGL版本都为这个系列的显卡专门开发的。当你使用Apple系统的时候,OpenGL库是由Apple自身维护的。在Linux下,有显卡生产商提供的OpenGL库,也有一些爱好者改编的版本。这也意味着任何时候OpenGL库表现的行为与规范规定的不一致时,基本都是库的开发者留下的bug。

由于OpenGL的大多数实现都是由显卡厂商编写的,当产生一个bug时通常可以通过升级显卡驱动来解决。这些驱动会包括你的显卡能支持的最新版本的OpenGL,这也是为什么总是建议你偶尔更新一下显卡驱动。

二、OpenGL相关专用名词解析

1.OpenGL 上下文(context)

struct object_name {
    float  option1;
    int    option2;
    char[] name;
};

2.OpenGL 状态机

3.渲染

4.顶点数组(VertexArray)和顶点缓冲区(VertexBuffer)

现代建筑基本都是框架式结构,修建的时候先搭建房子的主体框架,有了框架,然后再根据设计图在对应的位置填充不同的材料(窗户玻璃、砖墙体等)就可以了。在OPenGL中类似,显示图像也是先搭建框架,再进行填充。与现实中不同的是,OpenGL中的图像都是由图元组成。在OpenGLES中,有3种类型的图元:点、线、三⻆形。所以我们只要能够知道这三种图元的定点的位置,即可确定图像的具体位置。那这些顶点数据最终是存储在哪里的呢?

5.管线

汽车生产线,是将汽车从合金框架一步步组装成为可以让我们的驾驶的汽车的必经流程。管线在OpenGL中类似,就是我们渲染图像的必经流程。管线是一个抽象的概念,之所以称之为管线是因为显卡在处理数据的时候是按照一个固定的顺序来的,而且严格按照这个顺序。就像水从一根管⼦的⼀端流到另一端,这个顺序是不能打破的。
管线也分为固定管线(存储着色器)和可编程管线:

固定管线可编程管线的区别就是,固定管线是OpenGL封装好的可以直接传入参数调用来实现渲染的.而可编程管线需要开发者完全通过自定义来实现渲染的.但可编程管线不是说管线中的每一步流程都可以自定义实现,直到OpenGLES 3.0,依然只支持顶点着色器片源着色器这两个最基础的着色器这两步的自定义。

6.着色器程序(Shader)

着色器(Shader)是运行在GPU上的小程序。这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上来说,着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序,因为它们之间不能相互通信;它们之间唯一的沟通只有通过输入和输出
有些着色器允许开发者自己配置,这就允许我们用自己写的着色器来替换默认的。这样我们就可以更细致地控制图形渲染管线中的特定部分了,而且因为它们运行在GPU上,所以它们可以给我们节约宝贵的CPU时间。

#version version_number
in type in_variable_name;
in type in_variable_name;

out type out_variable_name;

uniform type uniform_name;

int main()
{
  // 处理输入并进行一些图形操作
  ...
  // 输出处理过的结果到输出变量
  out_variable_name = weird_stuff_we_processed;
}

OpenGL着⾊语言GLSL是用来在OpenGL中着⾊编程的语言,也即开发人员写的短小的自定义程序。它们是在图形卡的GPU (Graphic Processor Unit图形处理单元)上执行的,代替了固定的渲染管线的一部分,使渲染管线中不同层次具有可编程性.⽐如:视图转换,投影转换等.GLSL的着⾊器代码分成2个部分:VertexShader(顶点着⾊色器)FragmentShader(⽚元着⾊器)

1).顶点着色器(VertexShader)

2).片源着色器(FragmentShader)

7.光栅化Rasterization

8.纹理

从前面我们已经了解到,我们可以为每个顶点添加颜色来增加图形的细节,从而创建出有趣的图像。但是,如果想让图形看起来更真实,我们就必须有足够多的顶点,从而指定足够多的颜色。这将会产生很多额外开销,因为每个模型都会需求更多的顶点,每个顶点又需求一个颜色属性。

艺术家和程序员更喜欢使用纹理(Texture)。纹理是一个2D图片(甚至也有1D和3D的纹理),它可以用来添加物体的细节;你可以想象纹理是一张绘有砖块的纸,无缝折叠贴合到你的3D的房子上,这样你的房子看起来就像有砖墙外表了。因为我们可以在一张图片上插入非常多的细节,这样就可以让物体非常精细而不用指定额外的顶点。
就像下图,在三角形上贴了一张绘有砖块的纸。

image

9.混合(Blending)

在测试阶段之后,如果像素依然没有被剔除,那么像素的颜⾊将会和帧缓冲区中附着上的颜色进⾏混合,混合的算法可以通过OpenGL的函数进行指定。但是OpenGL提供的混合算法是有限的,如果需要更加复杂的混合算法,⼀般可以通过像素着⾊器进⾏实现,当然性能会比原生的混合算法差⼀些。

物体透明分成两种透明,一种是完全透明另一种是部分透明,完全透明的话会使颜色完全穿透,而部分透明使颜色穿透的同时也显示自身颜色。为了渲染出不同的透明度级别,我们需要开启混合(glEnable(GL_BLEND))。简单理解就是两张不同颜色图片放在一起,它们重合的地方就需要运用混合来展示新的颜色。

未命名.001.jpeg

10.变换矩阵(Transformation)

我们现在已经知道了如何创建一个物体、着色、加入纹理,给它们一些细节的表现,但因为它们都还是静态的物体,仍是不够有趣。我们可以尝试着在每一帧改变物体的顶点并且重配置缓冲区从而使它们移动,但这太繁琐了,而且会消耗很多的处理时间。我们现在有一个更好的解决方案,使用(多个)矩阵(Matrix)对象可以更好的变换(Transform)一个物体。这些矩阵即为换矩阵(Transformation)

11.投影矩阵(Projection)

12.渲染上屏/交换缓冲区(SwapBuffer)

image

为了解决这个问题,GPU 通常有一个机制叫做垂直同步(简写也是 V-Sync),当开启垂直同步后,GPU 会等待显示器的 VSync 信号发出后,才进行新的一帧渲染和缓冲区更新。这样能解决画面撕裂现象,也增加了画面流畅度,但需要消费更多的计算资源,也会带来部分延迟。

参考资料:
https://learnopengl-cn.github.io/intro/
https://www.w3cschool.cn/stiahw/fb7jqozt.html

觉得不错记得点赞哦!听说看完点赞的人逢考必过,逢奖必中。ღ( ´・ᴗ・` )比心

上一篇 下一篇

猜你喜欢

热点阅读