Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在不同的游戏引擎实现组件中填充SharpDX和OpenTK?_C#_.net Assembly_Extensibility - Fatal编程技术网

C# 在不同的游戏引擎实现组件中填充SharpDX和OpenTK?

C# 在不同的游戏引擎实现组件中填充SharpDX和OpenTK?,c#,.net-assembly,extensibility,C#,.net Assembly,Extensibility,我希望我的C#引擎能够让用户在使用Direct3D或OpenGL之间进行选择。 我的引擎的内部设计与着色器类的抽象示例类似: internal class Shader { private IShaderImplementation _implementation; internal Shader(ShaderType type, string code) { switch (Engine.GraphicsInterface) {

我希望我的C#引擎能够让用户在使用Direct3D或OpenGL之间进行选择。 我的引擎的内部设计与着色器类的抽象示例类似:

internal class Shader
{
    private IShaderImplementation _implementation;

    internal Shader(ShaderType type, string code)
    {
        switch (Engine.GraphicsInterface)
        {
            case GraphicsInterface.Direct3D:
                _implementation = new Direct3DShader(type, code);
                break;
            case GraphicsInterface.OpenGL:
                _implementation = new OpenGLShader(type, code);
                break;
            default:
                throw new UnsupportedInterfaceException("Shader");
                break;
        }
    }

    internal void Compile()
    {
        _implementation.Compile();
    }
}
我认为这是一个很好的设计模式。(正如您可能已经注意到的,我也更喜欢调用构造函数而不是工厂方法,但这只是一件次要的事情)

然而:

  • 我不想将OpenTK(用于OpenGL)程序集引用与SharpDX(用于Direct3D)程序集引用一起填充到一个类库中。我甚至不知道这是不是个好主意。从当前设计来看,这是必需的,因为Direct3DShader和OpenGLShader类直接引用D3D或OGL方法。即使用户只希望使用OpenGL,我是否需要同时发布OpenTK/SharpDX程序集
  • 我希望有一个主程序集只包含上面提到的通用接口内容(比如“可怕的.Engine.dll”,另一个只包含OpenGL内容(“可怕的.Engine.OpenGL.dll”),另一个用于Direct3D内容(“可怕的.Engine.Direct3D”)。但是如何在主程序集中引用它?正如您所看到的,我有一个接口枚举,这将不再有效
以更一般的形式询问,我的主程序集接口和类如何在子程序集中实现和扩展


PS:我听说过关于反射的事,我只知道一两分钱,然后是托管扩展性框架,但我还没有弄清楚它如何适合我的设计。

将它设计为3个类库,用于图形层和声音层

类库1:接口层

  • 包含包装器将实现的所有包装器和接口
  • 设计接口,使其在自己的应用程序域中工作,并为所有内容分发接口
类库2(OpenTK):

  • 引用类库1和OpenTK
  • 添加一个像OpenAL这样的声音API
  • 实现封装对OpenTK的调用并播放声音的接口
类库3(SharpDX):

  • 参考类库1和Sharp DX
  • 实现封装对SharpDX的调用并通过SharpDX播放声音的接口
游戏代码

  • 向类库1添加一个硬引用,这样您就拥有了所有接口类型、枚举等
  • 使用反射动态加载类库2或类库3
  • 为硬件层创建新的应用程序域
  • 使用
    AppDomain.Load
    加载类库2或类库3
  • 加载硬件程序集并拥有
    assembly
    对象后,使用反射获取对接口的引用,可能类似以下内容:

    // Making up this pseudo code
    GameApi gameApi = (GameApi)hardwareAsm.GetType(GameApi).GetMethod("Initialize").Invoke();
    
    TheGame gameWorld = gameApi.CreateGame(...);
    gameWorld.ResolutionChanged += Resolution_Changed(...);
    gameWorld.Terminated += Terminated(...);
    gameWorld.KeyDown += Key_Down(...);
    // etc....
    gameWorld.Start();
    
让整个层在其自己的应用程序域中运行的好处有很多:

  • 可以卸载应用程序域,从而也可以卸载它们加载的任何程序集。(如果用户可以在运行时从DirectX切换到OpenGL,这将是必需的,这将是整洁和可能的,我以前从未见过有人这样做)
  • 应用程序域可以使用自己的安全描述符、ACE等进行保护。例如,您可以阻止应用程序域中运行的代码访问创建文件、发出internet请求等(如果您正在为游戏加载项设计插件层,则非常有用)
  • 可以编写应用程序域,使其能够正常崩溃、记录崩溃并在不影响根进程的情况下重新启动

您想在编译时还是运行时切换它?@thumbmunkeys:在编译时就足够了。用户实现了一个属性“GraphicsInterface”,在该属性中他返回所需的枚举值。如果可能的话。这听起来很好,但是,您能想到隐藏反射“stuff”的可能性吗从编写游戏代码的用户那里?我需要让它对用户来说尽可能简单。我想这样做是无法避免的,那也不是问题。是的,简单。在接口DLL中(这是您的最终用户的参考)只要有一个指向所有内容的主入口点,例如1个静态类。下面是一个伪示例GameSettings settings=GameApi.CreateSettings();settings.GFXBacker=GFXBacker.OpenGL3;GameApi.CreateGame(设置);CreateGame将使用设置来确定要使用的硬件层。它执行所有动态加载、应用程序域创建、反射以加载Game类挂钩的所有接口等。此外,在您使用时,我建议与mono兼容,以便用户可以移植到linux、osx等。基本上,只需抽象relflection层即可使用类似GameApi静态类的想法进行操作。此外,请记住,如果操作正确,反射代码只是初始化代码,这意味着它只能运行一次。一旦获得所有接口,游戏类(或您最终构建的w/e)就会运行一次无需继续使用反射就可以直接引用它们。反射很昂贵,你不想经常使用它,尤其是在绘制循环中,它会破坏循环的性能。我也很好奇你的建筑到底是什么。不确定你是否知道,但Mono Project选择了XNA Game Studio,它不是我们称之为MonoGame,它允许你用c#构建游戏,就像XNA一样,而且它们是可移植的,MonoGame使用OpenTK,它们也有一个使用SharpDX的构建。不久前我开始进行游戏开发,但当我遇到一个恼人的问题时就停止了。所以现在我正在开发一个自定义字体光栅化器,它可以使用真正的字体。我的current SharpDX only engine允许使用自己的窗口创建多个游戏类实例,就像引擎的两个实例一样