探索 OpenGL 音视频渲染技术(1):简介

这个系列文章我们来介绍一位海外工程师如何探索 OpenGL 音视频渲染技术,对于想要开始学习音视频技术的朋友,这些文章是份不错的入门资料,这是第 1 篇:OpenGL 简介。

—— 来自公众号关键帧Keyframe的分享

在开始我们的旅程之前,我们首先应该定义 OpenGL 究竟是什么。OpenGL 主要被认为是一个 API(应用程序编程接口),它为我们提供了一组可以用来操作图形和图像的函数。然而,严格来说,OpenGL 并不是一个 API,而只是一个规范,由 Khronos Group 开发和维护。

探索 OpenGL 音视频渲染技术(1):简介
openGL

OpenGL 规范详细规定了每个函数的输出结果和行为方式,但具体的实现细节则由开发人员自行决定。由于 OpenGL 规范并不提供实现细节,因此只要结果符合规范,不同的实现版本是可以接受的。

开发实际 OpenGL 库的通常是显卡制造商。你购买的每张显卡都支持特定版本的 OpenGL,这些版本是专门为该显卡(系列)开发的。在使用 Apple 系统时,OpenGL 库由 Apple 自行维护;而在 Linux 系统下,则存在显卡供应商版本和爱好者改编版本的组合。这也意味着,如果 OpenGL 表现异常,很可能是显卡制造商(或开发/维护库的人员)的责任。

由于大多数实现版本由显卡制造商开发,因此如果实现中存在漏洞,通常可以通过更新显卡驱动程序来解决。这些驱动程序包含了你的显卡支持的最新版本的 OpenGL。这也是为什么建议偶尔更新显卡驱动程序的原因之一。

Khronos 公开了所有 OpenGL 版本的规范文档。感兴趣的读者可以在这里找到我们使用的 OpenGL 3.3 版本的规范文档(它详细描述了函数的结果,而不是实现细节)。规范文档还提供了查找 OpenGL 函数确切工作原理的绝佳参考。

1、核心模式与立即模式

在早期,使用 OpenGL 意味着在立即模式(通常称为固定函数管线)下开发,这是一种易于使用的绘图方法。OpenGL 的大部分功能都隐藏在库中,开发人员对 OpenGL 的计算方式没有太多控制权。随着时间的推移,开发人员对灵活性的需求越来越高,规范也因此变得更加灵活;开发人员获得了更多的图形控制权。立即模式非常容易使用和理解,但它也非常低效。因此,从 3.2 版本开始,规范开始废弃立即模式功能,并开始鼓励开发人员使用 OpenGL 的核心模式,这是一种移除了所有旧版废弃功能的规范分支。

在使用 OpenGL 的核心模式时,OpenGL 强制我们使用现代实践。如果我们尝试使用 OpenGL 的废弃函数,OpenGL 会抛出错误并停止绘制。学习现代方法的优势在于它非常灵活和高效。然而,它也更难学习。立即模式抽象了 OpenGL 执行的实际操作,虽然容易学习,但很难理解 OpenGL 的实际工作原理。现代方法要求开发人员真正理解 OpenGL 和图形编程,虽然有点难,但它允许更大的灵活性、更高的效率,最重要的是:对图形编程的更好理解。

这也是为什么本书专注于 OpenGL 3.3 的核心模式。虽然它更难,但绝对值得努力。

截至今天,已经可以使用更高版本的 OpenGL(撰写本文时为 4.6),你可能会问:既然 OpenGL 4.6 已经发布,为什么还要学习 OpenGL 3.3?这个问题的答案相对简单。从 3.3 版本开始的所有后续版本都在 OpenGL 中添加了额外的有用功能,而没有改变 OpenGL 的核心机制;新版本只是引入了稍微更高效或更有用的方式来完成相同任务。结果是,所有概念和技术在现代 OpenGL 版本中保持不变,因此学习 OpenGL 3.3 是完全有效的。当你准备好并且/或更有经验时,你可以轻松地使用更近版本的特定功能。

当你使用最新版本的 OpenGL 功能时,只有最新的显卡才能运行你的应用程序。这就是为什么大多数开发人员通常以较低版本的 OpenGL 为目标,并可选地启用更高版本的功能。

在某些章节中,你会发现更现代的功能,这些功能会特别标注出来。

2、扩展

OpenGL 的一个伟大特性是它对扩展的支持。每当一家图形公司开发出一种新技术或一个大型渲染优化时,这通常会以扩展的形式出现在驱动程序中。如果应用程序运行的硬件支持这种扩展,开发人员可以使用扩展提供的功能来实现更高级或更高效的图形。这样,图形开发人员仍然可以使用这些新的渲染技术,而无需等待 OpenGL 在未来版本中包含这些功能,只需检查显卡是否支持该扩展即可。通常,当一个扩展流行或非常有用时,它最终会成为未来 OpenGL 版本的一部分。

开发人员必须在使用扩展之前查询这些扩展是否可用(或使用 OpenGL 扩展库)。这允许开发人员根据扩展是否可用,以更好或更高效的方式执行操作:

if(GL_ARB_extension_name)
{
    // 使用硬件支持的酷炫新现代功能
}
else
{
    // 扩展不支持:使用旧方法
}

在 OpenGL 3.3 中,我们很少需要为大多数技术使用扩展,但必要时会提供适当的说明。

3、状态机

OpenGL 本身是一个大型状态机:一组定义 OpenGL 当前操作方式的变量。OpenGL 的状态通常被称为 OpenGL 上下文。在使用 OpenGL 时,我们经常通过设置一些选项、操作一些缓冲区来更改其状态,然后使用当前上下文进行渲染。

例如,当我们告诉 OpenGL 现在要绘制线条而不是三角形时,我们通过更改某个上下文变量来更改 OpenGL 的状态,该变量设置 OpenGL 应该如何绘制。一旦我们通过告诉 OpenGL 绘制线条来更改上下文,下一个绘制命令将绘制线条而不是三角形。

在使用 OpenGL 时,我们会遇到许多更改状态的函数(更改上下文)和许多基于 OpenGL 当前状态执行操作的函数。只要你记住 OpenGL 本质上是一个大型状态机,它的大部分功能就会更容易理解。

4、对象

OpenGL 库是用 C 语言编写的,并允许在其他语言中进行许多派生,但在其核心中,它仍然是一个 C 库。由于许多 C 语言的构造在其他高级语言中并不容易转换,因此 OpenGL 是带着几个抽象概念开发的。其中一种抽象是 OpenGL 中的对象。

OpenGL 中的对象是一组选项的集合,代表 OpenGL 状态的一个子集。例如,我们可以有一个代表绘图窗口设置的对象;然后我们可以设置它的大小、支持的颜色数量等。可以将对象可视化为一个类似 C 的结构体:

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

每当我们要使用对象时,通常看起来像这样(将 OpenGL 上下文可视化为一个大型结构体):

// OpenGL 的状态
struct OpenGL_Context {
   ...
   object_name* object_Window_Target;
   ...
};

// 创建对象
unsignedint objectId = 0;
glGenObject(1, &objectId);
// 将对象绑定到上下文的目标位置
glBindObject(GL_WINDOW_TARGET, objectId);
// 设置当前绑定到 GL_WINDOW_TARGET 的对象的选项
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH,  800);
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600);
// 将上下文目标恢复为默认值
glBindObject(GL_WINDOW_TARGET, 0);

这段代码是你在使用 OpenGL 时会频繁看到的工作流程。我们首先创建一个对象,并存储一个引用作为 ID(实际对象的数据在后台存储)。然后我们将对象(使用其 ID)绑定到上下文的目标位置(示例中窗口对象目标的位置定义为 GL_WINDOW_TARGET)。接下来我们设置窗口选项,最后通过将窗口目标的当前对象 ID 设置为 0来解除绑定。我们设置的选项存储在 objectId 引用的对象中,并在我们将对象重新绑定到 GL_WINDOW_TARGET 时恢复。

本书中提供的代码示例只是 OpenGL 运行方式的近似值;在书中你会看到足够多的实际示例。

使用这些对象的一个好处是,我们可以在应用程序中定义多个对象,设置它们的选项,每当我们要执行使用 OpenGL 状态的操作时,我们只需绑定具有我们偏好的设置的对象。例如,有一些对象作为 3D 模型数据的容器对象(如房屋或角色),每当我们要绘制其中一个时,我们只需绑定包含我们要绘制的模型数据的对象(我们之前已经创建并设置了这些对象的选项)。拥有多个对象允许我们指定许多模型,每当我们要绘制一个特定的模型时,我们只需在绘制前绑定相应的对象,而无需再次设置它们的所有选项。

5、开始学习

现在你已经了解了一些关于 OpenGL 作为规范和库的知识,以及 OpenGL 在后台的大致运行方式和 OpenGL 使用的一些技巧。如果你没有完全理解所有内容,不要担心;在本书中,我们会一步步走过来,你会看到足够多的示例来真正掌握 OpenGL。

音视频方向学习、求职,欢迎加入我们的星球

丰富的音视频知识、面试题、技术方案干货分享,还可以进行面试辅导

探索 OpenGL 音视频渲染技术(1):简介

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论