首页
登录 | 注册

OpenGL内核模式学习笔记第0篇——写在开篇

在互联网上,虽然关于OpenGL的教程、学习笔记很多。但是大多数要么是关于OpenGL的旧版本,要么是过于晦涩难懂、资料不全。所以我希望这个学习笔记能够给学习OpenGL新版本的各位带来帮助。

关于这个学习笔记


阅读这个学习笔记,需要一定的C++基础。同时,在这个学习笔记中采用的开发环境为Visual Studio 2017。

另外,这个OpenGL学习笔记希望尽可能的通俗易懂,能够让只会标准C++的人能够比较轻松的学习。

学习OpenGL前需要的基础知识


什么是OpenGL?

OpenGL,一般可能会将其视为一套API(Application Programming Interface,应用程序编程接口),提供一系列的函数来调用来绘制图像。然而实际上OpenGL并不是一套API,而只是一个由Khronos组织制定和维护的一个工业标准。

OpenGL标准严格规定了每一个函数的输入、参数、以及输出值。至于内部如何实现,由编写OpenGL库的人自行决定。因为OpenGL标准没有规定关于实现的相应的细节,所以在不同的OpenGL实现往往会有一些细微的差别。

实际的OpenGL库的实现通常都是各大显卡商提供,所以你用的是Apple的产品那么OpenGL库的实现一般是Apple自身在维护,如果你用的是Linux,那么一般是显卡商在维护(也有爱好者改编的版本)。这也意味着任何时候OpenGL库的实现与标准不一致时,基本都是OpenGL库的编写者遗留下来的bug。

由于OpenGL库的实现大多数都是显卡商编写的,所以发生bug的时候一般都可以通过升级显卡驱动来解决。
这也就是为什么会建议你偶尔升级一下显卡驱动的原因。

OpenGL的内核模式和立即渲染模式

早期的OpenGL采用立即渲染模式(Immediate mode)(就是你传一点数据OpenGL渲染一点数据),或者说固定渲染管线(就是一个线性的流程)。立即渲染模式学习起来相对比较简单,大多数的细节都被OpenGL库隐藏起来了。因此开发者很少有能够控制OpenGL如何计算的自由,而开发者迫切需要更高的灵活性。随着OpenGL标准的发展,开发者获得了更大的灵活性。而在OpenGL3.2标准制定的时候,OpenGL标准逐渐遗弃了立即渲染模式,取而代之的是内核模式。

OpenGL的内核模式的学习具有一定的难度,但是具有更高的灵活性和效率。并且可以深入的理解和图形编程!

因此,在这个学习笔记我们会学习OpenGL3.3的内核模式。虽然学习起来可能会更困难,但是这份努力是值得的。

不过,OpenGL4.5都已经出来了,为什么我们还要学习3.3的版本呢?因为如果采用新的OpenGL版本,那么就必须是新版本的显卡才能支持。而OpenGL更高版本都没有修改核心的内容,而只是提供了更快的方式来完成同样的事情。因此有了OpenGL3.3的基础,学习更高版本的OpenGL也是很轻松的。

OpenGL扩展

OpenGL一个非常大的特色就是扩展(Extension)的支持。当显卡公司开发出了新特性或者渲染的大幅度优化,而新的OpenGL标准还没有确定时,OpenGL的扩展机制可以让开发者在OpenGL标准加入之前提前使用硬件支持的特性,使用扩展的代码会像是这样:

if(GL_ARB_extension_name)
{
    // 使用硬件支持的全新现代特性
}
else
{
    // 不支持这个扩展,使用已制定的标准中的方法。
}

不过,我们在使用OpenGL3.3的时候基本不需要用到扩展的内容。在之后只有在需要的时候,才会专门声明。

OpenGL状态机

OpenGL本身是巨大的状态机,大量的OpenGL对象指定了OpenGL如何绘制。OpenGL的状态通常被称为OpenGL上下文(Context),可以通过修改OpenGL的状态来控制OpenGL如何绘制。

OpenGL对象

OpenGL库是用C语言写的,同时也支持多种语言的派生,但其内核仍是一个C库。由于C的一些语言结构不易被翻译到其它的高级语言,因此OpenGL开发的时候引入了一些抽象层。“对象(Object)”就是其中一个。

OpenGL对象实际上就是一些选项的集合,是OpenGL上下文的子集。比方说,我们可以用一个对象来描述一个窗口的大小、绘制的内容等。可以把对象看成一个C风格的结构体:

struct object_name
{
    int option1;
    float option2;
    char* name;
}

而OpenGL对象则是以下形式用于OpenGL上下文的:

struct gl_context // 在OpenGL实现中,OpenGL上下文通常以结构体的形式存在。
{
    ...
    object_name* window_target;
    ...
}

使用一个OpenGL对象是通常会像以下这样:

unsigned int objectId; // OpenGL对象通过索引来标识
glGenObjects(1, &objectId); // 创建一个OpenGL对象
glBindObject(GL_WINDOW_TARGET, objectId); // 绑定这个对象到目标,使其生效
// 之后对GL_OBJECT_TARGET的操作都是针对objectId所引用的对象的。
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 640);
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 480);

glBindObject(GL_WINDOW_TARGET, 0); //重新绑定回OpenGL的默认对象

以上就是学习OpenGL前必备的概念了,在下一篇中我们正式的开始OpenGL的学习。



2020 jeepxie.net webmaster#jeepxie.net
10 q. 0.009 s.
京ICP备10005923号