【OpenGL】OpenGL 快速入门 概念篇

之前虽然写了一个软渲染器,不过由于没有用上GPU, 确实性能有点拉。

后来试着用了一下 OpenGL ,感觉还挺方便的。

因此写一个 OpenGL 快速入门教程。

本篇先介绍一下 OpenGL 的基本概念。

OpenGL 基本概念介绍

OpenGL (Open Graphics Library) 是一种跨平台的应用程序编程接口(API),用于渲染2D和3D矢量图形。

它是独立于操作系统和窗口系统的,并且广泛应用于游戏开发、CAD软件、科学可视化等领域。

这里简单介绍一下OpenGL中的基本概念,我们会在后面的系列文章中深入讲解。


状态机与上下文

状态机

OpenGL可以被看作是一个状态机(State Machine),这意味着OpenGL的操作取决于当前的状态。

状态机的概念意味着OpenGL在任何时候都有一组当前状态,当发出一个OpenGL命令时,它会根据当前的状态来决定行为。

状态机有以下特性:

  • 持久性:一旦设置了某种状态,它就会一直保持不变,直到明确地更改它。
  • 线程安全性:如果在一个多线程环境中使用OpenGL,那么每个线程可以持有自己的上下文,因此状态是隔离的。

上下文

OpenGL上下文(Context)是指一组当前有效的OpenGL状态设置。

例如:

  • 当前使用的着色器程序
  • 当前绑定的纹理
  • 当前启用的缓冲区

每当调用OpenGL函数时,这些函数都会根据当前上下文中定义的状态来操作。

例如,如果绑定了一个新的纹理并随后调用glTexImage2D函数,那么这个纹理就会按照当前上下文中的配置来更新。

在渲染中,上下文的作用如下:

  • 状态管理:上下文维护了一组状态,这些状态会持续存在,直到它们被显式地改变。
  • 渲染环境:每个上下文代表了一个独立的渲染环境,不同的上下文可以有不同的状态设置。

着色器与GLSL

着色器介绍

着色器是一种小的程序,主要用于控制计算机图形渲染过程中的各种效果。这些程序通常在GPU(图形处理单元)上运行,因为GPU设计了专门的硬件来高效地执行这些程序。

着色器使得开发者能够精确地控制每个顶点和像素的渲染方式,从而实现高度定制化的视觉效果。

常见的着色器如下:

  • 顶点着色器(Vertex Shader):负责处理顶点数据,比如位置变换、光照计算等。
  • 片段着色器(Fragment Shader)像素着色器(Pixel Shader):负责计算像素的最终颜色值,如纹理映射、光照计算等。
  • 几何着色器(Geometry Shader):允许在顶点着色器之后生成额外的几何体。
  • 曲面细分着色器(Tessellation Shader):用于动态增加模型的细节级别。
  • 计算着色器(Compute Shader):不直接参与渲染,而是用于执行通用计算任务。

GLSL简介

GLSL(OpenGL Shading Language)是一种专门为OpenGL API设计的着色器语言,用于编写上述提到的各种类型的着色器。 它是一种类似C语言的高级编程语言,具有丰富的数据类型和内置函数,可以方便地访问GPU的功能。

下面是一个简单的片段着色器示例,用于输出纯红色:

1
2
3
4
// 片段着色器
void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 设置颜色为红色
}
GLSL编译和链接

着色器需要被编译并链接成着色器程序才能使用。这个过程通常由应用程序完成,包括读取着色器源代码文件、编译源代码、链接着色器对象以及验证最终的着色器程序。

在OpenGL应用程序中使用GLSL涉及以下几个步骤:

  1. 创建着色器对象:为每种类型的着色器创建一个着色器对象。
  2. 加载源代码:将源代码字符串加载到着色器对象中。
  3. 编译着色器:编译着色器源代码。
  4. 创建程序对象:创建一个程序对象来容纳着色器。
  5. 链接程序:链接着色器程序。
  6. 验证程序:确保程序正确无误。
  7. 使用程序:激活程序并在渲染时使用。

这些步骤通常通过OpenGL提供的函数来完成,例如glCreateShaderglShaderSourceglCompileShaderglCreateProgramglAttachShaderglLinkProgram等。


渲染管线

OpenGL渲染管线是一个定义了从三维模型到屏幕上的二维图像这一过程中各个步骤的系统。

渲染管线中的各个阶段处理图形数据,并最终将其呈现到屏幕上。

渲染管线的主要阶段如图所示:

graph LR;
    C[顶点着色器];
    C --> D[图元装配];
    D --> E[几何着色器];
    E --> F[光栅化];
    F --> G[片段着色器];
    G --> H[混合与测试];

各阶段详细介绍如下:

  1. 顶点着色器 (Vertex Shader)
    • 顶点着色器接收原始的顶点数据,并对这些顶点应用变换,例如模型变换、视图变换和投影变换。
    • 这些变换包括但不限于平移、旋转、缩放以及从模型空间到视图空间再到裁剪空间的转换。
    • 顶点着色器还可以执行光照计算或其他顶点级别的处理。
    • 剪裁阶段会去除那些不在视口内的几何体部分。
  2. 图元装配 (Primitive Assembly)
    • 图元装配阶段将经过顶点着色器处理的顶点组装成图元,如点、线或三角形。
    • 这一阶段确定了哪些顶点组成了特定的图元,以便进行进一步的处理。
  3. 几何着色器 (Geometry Shader)
    • 几何着色器是可选的阶段,它在图元装配之后和光栅化之前运行。
    • 几何着色器可以对输入的图元进行修改,例如添加新的顶点来细化图元,或者生成新的图元。
    • 它可以用于创建复杂的几何效果,如动态地添加细节或移除不需要的图元。
  4. 光栅化 (Rasterization)
    • 光栅化阶段将几何图元转化为屏幕上的像素。
    • 这意味着将连续的几何形状转化为离散的像素,并确定每个像素的颜色。
    • 光栅化过程还包括确定哪些像素被哪些图元覆盖,以及如何进行像素颜色的插值。
  5. 片段着色器 (Fragment Shader)
    • 片段着色器(有时也称为像素着色器)处理光栅化产生的片段(即像素)。
    • 它可以为每个片段计算颜色和其他属性,例如深度值和纹理坐标。
    • 片段着色器通常执行高级着色技术,如光照、纹理映射和阴影计算。
  6. 混合与测试 (Blending and Tests)
    • 在片段着色器之后,片段还需要通过一系列测试才能最终写入帧缓冲区。
    • 这些测试包括深度测试、模板测试、alpha测试等。
    • 混合允许新片段与现有像素混合,以模拟透明度等效果。

基本概念就介绍到这里,接下来我们会深入讲解,并且提供代码示例帮助读者理解。敬请期待!