API不可知的桥梁(即OpenGL / D3D /任何)。您是否使用它们,如何制作它们。专业人士和骗子[关闭]


12

您正在制作3D引擎。您想要最好的多平台世界。突然您意识到,如果要在Windows机器上使用Direct3D,在OSX / Linux上使用OpenGL,则必须牺牲这两个最小公分母的支持功能。

有些人可能会在三个OS上使用OpenGL,因为它本身似乎是最小公分母。一切都很好。然后,您必须将图形API后端移植到Nintendo的GX,还必须创建PS3和Xbox360路径。

你是做什么?您是否设计自己的API(本身是最不常见的),并为每个平台编写后端实现,还是为每个平台编写自己的分支?

如果您选择设计自己的API,是使用网桥模式还是自己的伏都教?疯狂在哪里停止,您意识到一切都停止了,厨房水槽方法也必须停止,并且基本上每个平台都有一个单独的引擎作为分支。或者,您坚持一切和厨房水槽,并在每个平台的后端模块专业化中保留平台特定信息。

Answers:


9

我不喜欢分母最少的方法。如果这样做,最终可能会导致功能残缺和性能不佳。

相反,我过去所做的是在库中提供更高级别的功能。该库(大多数情况下)与API无关,可以在任何地方使用,但是对于不同的平台/图形后端,该库的实现是完全不同的。因此,例如,除了具有SetStateX()函数之外,您还具有RenderMesh()或CreateRenderTarget()之类的更高功能。

每当您迁移到新平台时,这比真正的薄层工作要多得多,但这将是完全值得的,因为您将能够以该平台的最佳方式实现事物,并且能够本机独特功能的优势。

还有一件事:不要害怕稍微破坏封装。知道您所处的平台具有某些功能并且无法使用它们,这无非是令人沮丧。留下某种后门以便更高级别的代码可以利用该平台非常有用(例如,能够检索D3D设备或OpenGL上下文)。


3
我认为您说了我想说的话,只会更好。
AShelly

6

我只能说是看Ogre3D。它是用C ++,开放源代码(现已获得MIT许可)编写的,并且可以在每个主要平台上运行。它提取了渲染api,仅需几个设置就可以从使用DirectX切换到OpenGL。但是,我对DirectX和OpenGL的功能集之间的差异了解得不够多,不能说它支持或不支持特定功能。

Runic Games编写的《Torchlight》是使用Ogre编写的,我已经在Mac和PC上玩过,并且在两者上都运行得很好。


2
+1表示食人魔。我知道,已经阅读了一些代码。我对听到有关该方法以及其他人在这种情况下的所作所为的个人故事更感兴趣。
关键帧

2
谢谢!好吧,我大多数会像食人魔那样做。我在许多跨平台开发中都使用了Interface / Factory方法,但实际上我不确定该如何做。我要说的是,您绝对需要同时在多个平台上工作。不要尝试在Windows上编写所有代码,而要尝试例如移植到Mac。
Casey 2010年

是! 我开始厌倦滚动自己的跨API包装器,然后才开始使用Ogre。还没回头。:)
jacmoe 2010年

1

我尚未针对图形执行此操作,但确实创建了跨平台音频工具包(PC / XBOX / PS2)。我们采用了创建具有最小公分母功能以及可选的平台特定功能的API的途径。以下是一些经验教训:

关键是定义一个处理路径,该路径封装每个平台的核心功能并允许增长。为此,您需要真正了解每个平台的低级API,以便可以识别正确的抽象。确保链适用于功能最差的平台,同时提供对功能最强的patform的高级功能的访问。做一些正确的工作,以后您将节省很多工作。

对于音频来说,链条就像SoundSources -> [Decoders] -> Buffers -> [3D Positioner] ->[Effects] -> Players

对于图形,可能是Model -> Shapes -> Positioner -> Texturer -> [Lighting] -> [Particle Effects] -> Renderer(这可能是一个完全错误的设置,我不是图形专家)。

编写一个用于处理核心对象的前端API,以及一个将API映射到低级功能的特定于平台的后端。为每种功能尽力而为。例如,在PC和XBOX上,3D音频定位是使用声音芯片的HRTF功能完成的,而PS2使用简单的摇摄和淡入淡出功能。图形引擎可能在照明方面做类似的事情。

使用平台无关的代码来实现尽可能多的前端。将混响对象附加到声音对象或将纹理资产附加到形状对象的代码应该是完全通用的,迭代和处理活动对象的代码也应该完全相同。另一方面,除公共接口外,低级对象可以完全是平台特定的。

确保API或配置文件允许用户指定平台特定的选项。我们尝试通过将平台特定的代码保存在配置文件中来避免将平台特定的代码推送到游戏级别:一个平台的配置文件可以指定“效果:SuperDuperParticleGenerator”,而另一个则显示“效果:SoftGlow”

绝对要并行开发平台。确保平台特定的接口定义良好且可单独测试。这避免了很多“是平台级别还是API级别?” 调试时出现问题。


0

我正在为移动平台(Windows Mobile,Android)编写一个名为YoghurtGum的开源游戏引擎。这是我的大问题之一。首先,我像这样解决它:

class RenderMethod
{

public:

  virtual bool Init();
  virtual bool Tick();
  virtual bool Render();

  virtual void* GetSomeData(); 

}

你发现了void*吗?那是因为RenderMethodDirectDraw返回DirectDraw曲面而RenderMethodDirect3D返回顶点池。其他所有内容也被拆分。我有一个Sprite具有SpriteDirectDraw指针或SpriteDirect3D指针的类。有点烂

所以最近,我一直在重写很多东西。我现在所拥有的是a RenderMethodDirectDraw.dll和a RenderMethodDirect3D.dll。实际上,您可以尝试使用Direct3D,失败并改为使用DirectDraw。那是因为API保持不变。

如果要创建一个精灵,则不要直接创建它,而是要通过工厂来创建。然后,工厂将在DLL中调用正确的函数,并将其转换为父函数。

因此,这在RenderMethodAPI中:

virtual Sprite* CreateSprite(const char* a_Name) = 0;

这是中的定义RenderMethodDirectDraw

Sprite* RenderMethodDirectDraw::CreateSprite(const char* a_Name)
{
    bool found = false;
    uint32 i;
    for (i = 0; i < m_SpriteDataFilled; i++)
    {
        if (!strcmp(m_SpriteData[i].name, a_Name))
        {
            found = true;
            break;
        }
    }

    if (!found) 
    {
        ERROR_EXPLAIN("Could not find sprite named '%s'", a_Name);
        return NULL; 
    }

    if (m_SpriteList[m_SpriteTotal]) { delete m_SpriteList[m_SpriteTotal]; }
    m_SpriteList[m_SpriteTotal] = new SpriteDirectDraw();

    ((SpriteDirectDraw*)m_SpriteList[m_SpriteTotal])->SetData(&m_SpriteData[i]);

    return (m_SpriteList[m_SpriteTotal++]);
}

我希望这是有道理的。:)

PS我很想为此使用STL,但Android上不支持。:(

基本上:

  • 将每个渲染保持在自己的上下文中。DLL,静态库或只是一堆头文件。只要您拥有RenderMethodX,SpriteX和StuffX,您就可以大放异彩。
  • 从Ogre来源中尽可能多地窃取信息。

编辑:是的,拥有这样的虚拟接口确实有意义。如果第一次尝试失败,则可以尝试其他渲染方法。这样,您可以使所有代码呈现方法均不可知。


1
如果您永远不会同时激活一个以上的实现,那么拥有一个虚拟接口真的有意义吗?
NocturnDragon 2010年

0

我喜欢为此使用SDL。它具有适用于D3D,OpenGl,OpenGL ES的渲染器后端,以及少数其他特定于平台的后端,并且可用于各种不同的平台,并且目前正在积极开发中,并绑定了许多不同的语言。

它抽象出了不同的渲染器概念,并通过简单的跨平台API提供了创建视频(以及处理声音和输入等功能)的功能。它是由Blizzard的主要开发人员之一Sam Lantinga设计的,专门用于使移植游戏和创建跨平台游戏更加容易,因此您知道自己正在使用一个高质量的库。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.