我正在阅读有关创建图形“抽象层”的信息,以便在图形平台之间切换。不幸的是,我无法找到关于这个主题的更多细节。这种抽象是否可以在功能级别上实现?
void pushMatrix(){
if (directx){
// do directx function
}else if (opengl){
// do opengl function
}
}
这是如何运作的?有没有更好的办法?有人能指出一些做这个或更多示例代码的事情的例子吗?
答案 0 :(得分:7)
通常做的是拥有“通用”渲染器的接口:
class RendererInterface{
virtual DrawMesh() = 0;
virtual SwapBuffers() = 0;
/// etc
}
每个lib都有一个实现:
class OpenGLRenderer : public RendererInterface{
virtual DrawMesh(){... }
....
}
但这个概念与亚历山大的答案相同。
答案 1 :(得分:4)
是的,这就是它的工作原理。通过抽象您使用的图形API,您将从程序员需要担心的内容中删除它。这类似于GDI抽象写入设备的方式,例如程序员不必担心它。
从这个意义上说,你的功能库与上面的类似,就像HDC一样。它是这种抽象的接口。
然后对API进行简单检查会更加困难,然后调用相应的函数。这两个API(DirectX和OpenGL)非常不同,将它们抽象为单个界面并不容易,特别是如果您想要覆盖大部分功能。
你需要更多的抽象,然后简单地制作通用函数。您需要创建更复杂的结构。
假设OpenGL要求你调用函数A,然后函数B才能使某些事情发生,但DX要求你调用func B,然后调用函数A.为了适应这个,你需要做类似的事情:< / p>
void functionA(...) {
if (OpenGL) {
glFuncA();
} else {
//store parameters
}
}
void functionB(...) {
if (OpenGL) {
glFuncB();
} else {
dxFuncB();
dxFuncA( saved params );
}
}
这不是一个很好的例子,但它证明了校长。为非常大的和不同的API创建抽象需要经过深思熟虑,并且需要更多的努力来包装每个函数。
答案 2 :(得分:3)
这将导致混乱和低效。我将通过场景图抽象,即具有“场景”的广义高级表示。然后,该场景将由“渲染器”实例渲染,该实例可以使用OpenGL或Direct3D实现。
我建议你看一下像Ogre3d这样的跨平台图形引擎。
答案 3 :(得分:2)
我同意mhutch 100%。通过重构你的渲染器来专注于它正在做的事情,而不是如何做到这一点,你将做出更清洁的设计。
围绕API设计太近,或者更糟糕的是,使用if (this_platform) { do_this(); } else { do_that(); }
乱丢代码会很快造成程序的大量混乱。
我的建议是通过你的应用程序并找出它做了什么的列表,尽量不要注意如何。你的项目可能要迟到了,我不知道你的具体情况,但是(恕我直言)从API调用乱码噩梦重构它到足以抽象它的东西将改善你的最终结果。
虽然最初想到,你可能会认为实现一个场景图形系统会增加一大堆开销。实际上,我通过使用场景图来管理状态更改,通过避免状态更改(更改纹理,更改着色器等)以及以更优化的顺序绘制场景,使用渲染引擎获得了大幅加速。像实例化这样的东西优雅地集成到场景图形系统中,可以为您提供主要的加速,以及清除代码中所有以API为中心的混乱,并将“它的作用”与主体中的“它如何做”分开程序逻辑。