【问题标题】:Question about building a program from scratch关于从头开始构建程序的问题
【发布时间】:2020-01-21 02:07:21
【问题描述】:

我一生都在预建软件、Unity、Unreal、Python 等基础上构建游戏和程序,但我从未真正了解它是如何在行业中以标准方式完成的,你的引擎很酷,但它们也导致问题,例如您可以做的事情受到限制,以及必须解决错误等。但是让我们看看其他软件:MS Office、7Zip、Evernote、Firefox、Youtube、Amazon Alexa 应用程序、Inkscape、Autodesk cad、Photoshop等等。这些只是一些随机的例子,但它们不是内置在引擎中的,而是设法跨平台的。需要什么技能/语言才能做到这一点?需要明确的是,我并不是要一个奇迹般的答案来告诉我我需要知道的一切,但我正在寻找有关用于构建此类事物的工具的指南。是 C++ 吗?是 OpenGL 吗?我还是想得太高了吗?我对此了解不多,但这是正确的方向吗?我听说过电子之类的东西,但我认为您可以将其视为更多引擎。我无法想象这些公司在二进制级别上这样做,我认为在这样的时代对每个程序都这样做是荒谬的,对于像 Mozilla 和 Evernote 这样的初创公司来说,如果没有大型金额(如果有的话)收入。最后,我想我要问的是,构建跨平台程序时的行业标准是什么?他们倾向于使用哪些工具?我可以从哪些资源中学习来了解这方面的矿石?


附:需要明确的是,我理解 Evernote、Youtube、Alexa App 等背后都有后端,但我不是在谈论那些,我主要指的是前端,尽管我认为无论标准是什么都能做到处理后端。

【问题讨论】:

    标签: android c windows macos frontend


    【解决方案1】:

    此处为前中间件游戏开发人员。要在任何给定平台上进行任何操作,在最低级别,您必须开始访问操作系统或特定于硬件的 API(例如,在 Windows 上,使用 CreateFile 打开文件或 open()在 Linux 上)。 C/C++ 标准库建立在这些 API 之上,以提供一个通用的平台来构建跨平台应用程序。

    实际上,C++ 标准库在这方面并没有太大帮助,主要是因为图形、窗口 API 等。它们都在标准库的职权范围之外。对于我们游戏开发者来说,在控制台上使用 C++ 标准库的另一个大问题是,他们的行为往往针对“一般情况”,而不是特定平台。以 cmath 函数为例。在任何情况下,我都不会调用效率极低的 std::sin() 实现。 std::sin 在一个方面很棒——它处理非正规数,正确识别 NAN/INF,并且有一个很好的报告错误的方法。

    在游戏引擎世界中,我们倾向于花费大量时间预先烘焙资产,以使这些 INF/NAN 永远无法进入游戏计算。所以在运行时处理这些东西是浪费时间,所以我们通常编写自己的数学近似值(我们不是在月球上着陆,我们只是在屏幕上扔一些多边形,所以我们通常不需要标准库提供的准确性)。

    那么如何组织一个典型的跨平台游戏呢?您可能会看到一个类似于此的目录结构:

    game/
      platform/          //< contains all OS specific code (timers, mutexs, etc)
      vpu/               //< wrappers over the SIMD instructions on the platform
      maths/             //< fast versions of cmath + Vectors/Quats/Matrices/etc
      graphics/          //< wrappers over the core graphics APIs
      sound/             //< wrappers over the platform specific audio stuff
    

    这几乎是编写所有其他代码所针对的“平台”(换句话说,我们基本上最终会为每个新平台编写自己的 C++ 标准库版本)。虽然上述工作涉及大量工作,但当出现新的硬件平台(例如 Playstation 6、XBox 99 等)时,通常合理直接重写整个代码库。当然,这比重写整个游戏要少。

    在某些情况下,有些工作不会改变(例如,iOS 和 Android 都使用 ARM CPU,因此针对 ARM NEON 优化的数学例程将由两者共享,OpenGLES 图形例程也是如此)。

    如果运气好的话,99.99% 的游戏代码都不需要修改。运气好的话——在很多情况下我们没那么幸运:([虽然现在比十年前更容易了!]

    通常情况下(尤其是在控制台上),在游戏开发开始时,您会以可爱的抽象核心库为目标,一切都会好起来的。当您接近项目结束时,您可能最终会收到大量#ifdef XBOX 定义,这些定义利用特定硬件的特定性能增益(我们需要达到 60fps 的目标,我们并不真正关心 tbh )。在极端情况下,您可能会发现给定平台需要如此多的特定于平台的优化(例如渲染器),以至于它已经有效地分化为仅适用于该平台的全新库。

    无论如何。这种情况在 PC 和 android 上略有不同——仅仅是因为硬件的多样性很重要(不像 XBOX,它们都是相同的!)。在这些情况下,我们将针对已经抽象的 API(例如 OpenGL、OpenAL、D3D 等)编写代码,并且我们将不得不插入比在控制台上更多的运行时错误检查(例如,在控制台上,我们可能知道我们有 256Mb 的内存。在 Android 上可能是 32Mb,也可能是 2Gb,谁知道呢!没关系,我们需要优雅地处理故障)。

    对于桌面应用程序,对于窗口 API,绝大多数理智的人现在只使用 QT(如果他们需要 3D 渲染,可能会使用 OpenGL)。

    【讨论】:

    • 好的,很抱歉对你这样做,但作为一个还不明白下面发生了什么的高级用户,你能帮我把它说得更简单一点吗?我知道你可以对 C++ 做一些对跨平台的东西来说通常更通用的东西,就是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    相关资源
    最近更新 更多