认识OpenGL

在使用OpenGL编程之前,我们先来简单认识一下OpenGL,然后介绍如何使用VS Code 进行OpenGL工作区的配置。

两种观点

API观点

OpenGL是图形硬件的软件接口 ,是一套图形API。借助OpenGL,我们可以编写出对图形硬件具有访问能力的程序。OpenGL的实现如下图所示:

从图中可以看出,OpenGL的下层实现和硬件紧密相关 ;上层软件层使用C语言 进行编写,最后为用户提供了一系列的函数接口。用户可以使用这些接口编写自己的图形应用程序。

正是由于OpenGL非常接近硬件底层,所以和一般的纯软件实现的图形程序不同,它可以充分发挥硬件的加速功能,使得OpenGL编写的图形程序非常高效。

此外,OpenGL的可移植性非常强,一套代码拿到另一个操作系统中,只需要重新编译链接,即可在新的操作系统下运行。

状态机观点

我们可以把OpenGL看成一个具有输入,输出的状态机

  • 输入 是指我们可以通过OpenGL提供的API来指定或修改参数,这些参数共同描述了一个状态。
  • 输出 一般是由一系列图元组成的图形。

从输入到输出的转化,就是OpenGL作为状态机发挥的作用。


使用的库

OpenGL的函数包含在两个库中:GL库(核心库)GLU库(实用库) 。后者可以看成为了方便某些功能的实现而对前者进行的封装——换言之,如果程序员足够优秀的话,只需要GL库就可以实现相同的功能。

但是,由于OpenGL为了保证代码的可移植性,所以摒弃了所有平台相关的功能,如窗口显示功能等。所以只用上面两个库,我们还无法做到在窗口中显示绘制的图形等操作。这时,我们还需要一个库——GLUT库(OpenGL实用工具集) 来辅助我们实现这些功能。

OpenGL命名规则

由于OpenGL出现的时期比较早,当时的编辑器并没有自动补全之类的功能。所以为了方便程序员记忆OpenGL的函数等,对OpenGL的命名规则进行了一系列约定。

函数命名

函数的命名采用的规则:

库(小写)+功能(开头大写)+参数描述(个数+类型+是否为向量)

glVertex3f表示gl库中使用float描述三维顶点位置的函数,里面的参数就是三个浮点数;而 glVertex3fv函数内的参数则是一个float型数组(向量)。

为什么不用重载?因为C语言不支持重载!

数据类型命名

为了保证可移植性,OpenGL也给C语言中的数据类型进行了 typedef,规则如下:

GL+名称

OpenGL数据类型汇总如下:

常用的有 GLenumGLintGLfloatGLclampf。需要注意 GLclampf的大小限制在[0,1]!

值得一提的是,OpenGL将数据类型和功能联系起来。在C语言中即使是一种数据类型,在OpenGL中数据类型也可能不同。

常量命名

OpenGL中的常量采用<mark>全大写</mark>,并且用下划线分隔每一个单词

如:表示颜色缓存的常量 GL_COLOR_BUFFER_BIT


工作区配置

Windows下配置OpenGL环境,主流的都是使用Visual Studio。但说实话,我不是很喜欢用IDE(主要是不会用),所以就直接用VS Code了——当时配VS Code的开发环境也折腾了一番(比如问助教、问b站的大佬等),算是有了一些经验吧。下面介绍如何操作。

首先展示一下我的工作区:

目录层级如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
├──.vscode
│ └──settings.json
├──bin
│ └──main.exe
├──build
├──include
│ ├──GL.H
│ ├──GLU.H
│ └──glut.h
├──lib
│ ├──libGLU32.a
│ ├──libglut32.a
│ └──libOPENGL32.a
├──src
│ └──01.animation
│ └──main.cpp
└──makefile

这样的代码组织方式借鉴于UNIX系统中编写一个工程的良好组织结构

  1. 将外部的头文件放在include目录下;
  2. 库文件放在lib目录下,并且根据静态库的标准命名方式重命名为 lib*.a的格式;
  3. 源代码放在src目录下;
  4. 输出的可执行文件放在bin目录下;
  5. build用于放置编译过程中生成的 .o文件;
  6. 最后使用一个makefile指定g++的编译规则。(图上我还创建了一个run命令并使用了一个dir变量指定要编译的源文件所在目录)
1
2
3
4
5
6
SRC		:= src/$(dir)
main:src/$(dir)/main.cpp
g++ -o bin/main src/$(dir)/main.cpp -lglut32 -lGLU32 -lOPENGL32 -lm -lwin32k -Iinclude
run: main
bin/main.exe
@echo Executing 'run' complete!

为了保证编译器能够找到头文件、链接需要的静态库,就需要配置g++的编译参数-l指定库名,-I指定头文件的搜索目录。

最后,要运行src里面某个文件夹下的源文件,只需要指定dir的值即可,再使用run命令可即时运行生成于bin目录下的可执行文件:

还有一个问题就是如何配置调试文件。图形学我现在真的不知道该怎么调试,所以没有配。

b站上用VS Code配置OpenGL开发环境的参考教程(up和我使用库的不太一样,不过方法很值得参考:

关于makefile命令的创建、变量的使用等,可以参考Dongdong大佬写的makefile教程: