65.9K
CodeProject 正在变化。 阅读更多。
Home

一个多线程、支持OpenGL的应用程序。

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (49投票s)

2006年8月26日

Apache

8分钟阅读

viewsIcon

264968

downloadIcon

6829

提供了一个基础,用于编写实际的OpenGL应用程序,而不是简单的“Hello World”程序。

Skeleton Application Screenshot

序言

正如大多数学习OpenGL的人所发现的,它为开发人员直接访问计算机的底层图形硬件和/或GPU提供了一种绝佳的方式。然而,它不提供任何与主机操作系统环境协同工作的机制。

这包括系统IO、窗口化、计时等,仅举几例。填补这一空白的传统方法是使用另一个库来处理具体细节。这种方法的好处是抽象可以实现平台无关的GUI等操作。但是,与大多数抽象一样,底层的操作系统功能(随时可以选取和调整)被隐藏起来。

第二种方法是直接与平台特定功能接口,以实现所需的额外功能。这种方法不允许平台无关的代码,但它允许您精细控制应用程序的工作方式,并且没有额外的开销。作为一名长期从事Windows开发的开发人员,我选择了这条路,因为对我来说,速度很重要,并且能够从Windows中精确地获得我想要的东西也很重要。

因此,我提出了一个基于Windows的骨架应用程序,它承载了一个OpenGL渲染环境。与大多数其他基于OpenGL的骨架或向导不同,这个应用程序的功能更完善,足以创建真实世界的应用程序,而不是“Hello World”场景,并且实际上使用多线程在较新的系统上实现性能提升。

目标

这个应用程序的目标是提供启动和运行OpenGL渲染环境所需的繁琐工作,除了Windows默认提供的库之外,不使用任何外部库。这还允许我们使用一套经过良好测试和调试的通用集。

设计遵循KISS原则。它没有包含所有与OpenGL命令不直接相关的世界功能,而是包含了您所制作的几乎每个应用程序中都会存在的功能。然而,它确实包含足够的结构,以便您可以根据需要插入额外功能。

特点

  • 基于时间的动画

    游戏动画中一个由来已久的问题是,当在比游戏设计时更快的CPU/GPU上运行时,游戏会因为运行过快而变得无法玩。反之亦然。如果游戏是在快速系统上设计的,但在较慢的系统上运行,动画可能会太慢。

    因此,骨架应用程序采用了一种称为基于时间的动画技术,该技术在动画时使用计算机每秒渲染一帧所需的CPU周期量作为乘法因子。使用这种方法可以实现平滑的动画,而与帧率无关。

  • 多线程
    骨架应用程序利用了多线程范式。它使用一个线程来处理Windows特定的处理,并使用一个单独的线程来处理OpenGL的特定处理。这有两个明显的优点。第一,这将在使用超线程和/或双核技术的现代CPU上实现性能提升。第二,这也确保了OpenGL渲染管道的更平滑操作,因为它不会被Windows消息处理(为了用户与应用程序交互而必需)所瓶颈。
  • 线程间通信
    在应用程序中,两个线程可以通过消息系统进行通信。主线程可以使用PostThreadMessage() API与渲染线程通信,渲染线程可以使用SendMessage() API与主线程通信。这为两个线程共享信息提供了一种可定制、可扩展的方式。
  • 序列化

    实际上,任何基于Windows的应用程序都倾向于使用某种方式来保存和恢复设置。一种非常流行的方法是利用Windows注册表。因此,应用程序支持在Users Hive下读写注册表,但可以很容易地进行修改,使其也能写入System Hive等。

    默认情况下,骨架应用程序将检查BPP数据、主窗口定位数据以及全屏模式下使用的垂直刷新率。

  • 命令行解析
    如果一个应用程序不使用命令行,那它会是什么样子呢?这个骨架应用程序允许您轻松添加对任意数量命令行选项的支持。默认情况下,它会检查一个/fullscreen选项,允许用户指定是希望以全屏模式还是窗口模式运行。
  • 调试宏和信息

    仅在调试模式下,骨架应用程序会做两件额外的事情

    首先,它会在主窗口的标题栏上为您提供状态信息,显示系统上安装的OpenGL版本和帧率 (FPS)。这些信息对于确定您的安装实现能做什么以及性能调整非常有用。

    其次,它启用了两个名为ENTER_GL和LEAVE_GL的调试宏,旨在用于包围OpenGL调用代码块。OpenGL的错误处理机制并不直接,这些宏将有助于缓解这个问题。应用程序本身演示了它们的用法。

  • 广泛的配置选项

    为了适应许多不同的场景,骨架应用程序在WinMain.h中使用了预处理器指令来启用、禁用或配置要使用的功能。下面是对一些可能引起混淆的指令的描述

    CONFIG_ALLOW_FULLSCREEN 如果您希望允许应用程序进入全屏模式,请将其设置为true;否则设置为false。注意:如果设置为false,它将覆盖所有其他与全屏相关的设置(注册表、命令行等)。
    CONFIG_ALLOW_RESIZE 如果您希望允许主应用程序窗口调整大小,请将其设置为true;否则设置为false。注意:如果设置为false,应用程序将不考虑任何有关窗口大小的信息(只考虑位置)。
    CONFIG_ALLOW_MENU 如果您希望在主应用程序窗口上允许标准Windows菜单,请将其设置为true;否则设置为false。注意:如果为true,应用程序假定菜单的资源ID是IDR_MAINFRAME。此外,默认情况下,ESC键将显示和隐藏菜单。这样做将使用户能够腾出更多屏幕空间。
    CONFIG_ALLOW_VSYNC 如果您希望允许应用程序调整显卡帧率的垂直刷新率同步 (VSync),请将其设置为true。注意:如果为true,它会根据系统和配置是否可能来尝试打开或关闭VSync。如果不可能或设置为false,无论设置如何,它都不会执行任何操作。如果允许,VSync可以通过注册表中的VSync键来打开或关闭。
    CONFIG_DEF_BPP 如果应用程序处于全屏模式,则使用的默认每像素位数 (BPP)。注意:这可以通过在注册表中设置BPP键来覆盖。
    CONFIG_DEF_FULLSCREEN 如果允许全屏模式,则如果您希望应用程序默认全屏模式,请将其设置为true,如果您希望默认窗口模式,请设置为false。注意:目前,/fullscreen开关可以覆盖此设置,因为它只是一个默认值。
    CONFIG_DEF_HEIGHT
    CONFIG_DEF_WIDTH
    主应用程序窗口的默认宽度和高度。注意:如果窗口不允许调整大小,这将始终是主窗口的大小。
    CONFIG_MAX_REFRESH
    CONFIG_MIN_REFRESH
    默认情况下,应用程序将在注册表中查找用于全屏模式的垂直刷新率,键为Refresh。这两个设置将确定允许的最大和最小刷新率,作为安全预防措施。
    CONFIG_MIN_HEIGHT
    CONFIG_MIN_WIDTH
    允许您指定主应用程序窗口的最小宽度和高度。如果设置,窗口不能调整到低于这些点。注意:将这些设置为0实际上意味着没有最小值。
    CONFIG_SINGLE_INSTANCE 如果您希望应用程序限制为单个实例(使用互斥体),请设置为true;否则,设置为false

关注点

  • C语言优于C++的使用

    骨架应用程序是用C语言而不是C++编写的。你们中的许多人可能更喜欢使用C++,这无可厚非。将应用程序的功能封装到几个类中应该足够容易。我个人对C++没有偏见,但我选择C语言更多是出于实用考虑,而非哲学理念。

    由于使用C语言,骨架应用程序定义并使用了booltribool数据类型,类似于C99布尔定义和C++ Boost库的三态布尔类型。

  • 源代码关键区域
    • Main\Application.h

      这是主要的应用程序包含文件,其中包含本文概述的配置选项。

    • 渲染委托

      虽然大部分代码都相对一目了然,但值得注意的是,传递给渲染线程的RENDERARGS结构体中的pRenderFrame委托函数将是OpenGL中要渲染的任何内容的起点。它将每帧调用一次,所有不包括预加载等的渲染操作都应从此函数派生。

示例应用程序

可下载的应用程序项目还演示了骨架的简单用法,以动画任天堂著名塞尔达系列中的 Triforce。它们是为清晰起见编写的骨架示例。此外,它们还利用了本文中提到的基于时间的动画。

需要注意的是,如果您使用的是 Visual Studio 2017,还需要安装 Windows 8.1 SDK,因为它默认不包含。这是因为 Microsoft 正在使 Visual Studio 的分发更加模块化。

鸣谢和历史

文章作者 - Jeremy Falcon
高分辨率计时器建议 - El Corazon
InitScene() 更新建议 - JWood
   
应用程序图标 - 由 iconshock.com 慷慨提供,作为其SIGMA Graphics系列的一部分。
  • 2017-11-14 - 1.3版发布。
  • 2014-11-26 - 1.2版发布。
  • 2006-08-27 - 1.1版发布。
  • 2006-08-26 - 1.0版发布。
© . All rights reserved.