在不久的将来,我将开始开发一个游戏引擎。我想要包含的一个特性是拥有多个渲染系统,比如DirectX9/10/11和OpenGL。这样,使用这个引擎的游戏将能够支持更多的玩家,因为如果一个渲染系统不工作,它将恢复到不同的渲染系统。
所以我的问题是,我该怎么做呢?我研究了一下,发现Ogre3D使用了类似的东西,但我不知道他们是如何做到的。我基本上希望能够插入不同的渲染系统,并使用相同的代码来运行它。
发布于 2012-01-19 05:57:34
您可以创建一个接口类,使您可以进一步扩展您希望扩展到的API。
我已经在过去创建了一个DirectX911渲染器,我希望很快将其扩展到OpenGL。这项任务有很多确定性,但很容易解释它的基本工作原理。不幸的是,我的项目是闭源的,所以如果你对此有任何问题,请不要犹豫询问。
首先,您需要创建一个单独的项目作为.lib/.dll,我将其称为"RenderInterface“。这将包含用于顶点缓冲区、索引缓冲区、着色器以及最重要的IRenderInterface和IRenderUtility的基本接口,这些接口在后面的实现中可能包含诸如ID3D11DeviceContext和ID3D11Device之类的项。
我在"RenderInterface“项目中最重要的两个项目是IRenderInterface和IRenderUtility。这里的想法是让IRenderInterface来做繁重的工作,比如创建呈现目标、呈现和初始化应用程序接口。as IRenderUtility将执行更常见的操作,例如创建顶点/索引缓冲区、创建着色器和渲染。我在初始化和渲染时更频繁地传递IRenderUtility,而IRenderInterface很少传递。这是为了防止用户在不需要的时候进行意外操作。这个项目还将包括一些通用的structs\enum,它们将在整个代码库中使用。
然后,我创建了另一个项目,比如D3D11RenderInterface。此D3D11RenderInterface将包含IRenderInterface、IRenderUtlity、IVertexShader、IVertexBuffer等的实现。
一个非常简单的例子是
class IRenderUtility
{
public:
virtual void Draw(unsigned int vertexCount, unsigned int vertexStartOffset) = 0;
};
class D3D11RenderUtility : public IRenderUtility
{
protected:
ID3D11DeviceContext *mD3D11DeviceContext;
public:
void Draw(unsigned int vertexCount, unsigned int vertexStartOffset)
{
mD3D11DeviceContext->Draw(vertexCount, vertexStartOffset);
};
};这是通过在调用IRenderUtility::Draw之前调用IRenderUtility来设置VertexBuffer和IVertexBuffer的。
然后,在您的应用程序中将只需要加载RenderInterface项目和应用程序接口实现。还有其他方法可以做到这一点,比如在你的代码库中使用#定义代码,但是imo,这太混乱了。
发布于 2012-01-16 18:59:47
使用C++接口的强大功能!
创建定义呈现系统接口的抽象
class Renderer
{
//...
virtual void DrawRect(Color c, Vector2 Pos) = 0;
//...
}然后在每个渲染系统中实现它:
class D3DRenderer : Renderer
{
void DrawRect(Color c, Vector2 Pos);
}这种方法快速、简单、高效,这就是为什么它在许多游戏引擎中使用的原因。应该注意是,在构建这样的东西(甚至像行较大矩阵与列较大矩阵这样的小事情)时,确实需要了解某些API限制。
发布于 2012-01-16 16:55:35
使用预处理器
一种解决方案是使用预处理器。
#ifdef DIRECT_X
// something for DX
#else
// something for OpenGL etc.
#endif像SDL这样的库也使用这种方法。如果你想使用渲染系统,只需简单地#define它。此外,从跨平台兼容性来看,您可能需要使用特定于平台的宏。参见this。
使用单独的翻译单元
一种更好的方法是将特定于平台的方法放在单独的翻译单元中。这将使代码更整洁、更具可读性,更易于开发和维护。
例如:
class Rectangle
{
public:
void draw(int,int,int,int);
};rectangle_dx_9.cpp
#include "rectangle.hpp"
void
Rectangle ::
draw(int upper_left_corner_x, int upper_left_corner_y,
unsigned int length, unsigned int width)
{
// Direct X 9 specific code here.
}rectangle_open_gl.cpp
#include "rectangle.hpp"
void
Rectangle ::
draw(int upper_left_corner_x, int upper_left_corner_y,
unsigned int length, unsigned int width)
{
// OpenGL specific code here.
}等。
现在,对于DirectX9,您需要做的就是将构建过程配置为使用rectangle_dx_9.cpp,,而对于OpenGL,则使用rectangle_open_gl.cpp.
https://stackoverflow.com/questions/8877471
复制相似问题