Я планировал написать слой абстракции API для моего движка рендеринга. Два API, которые я хочу включить, это D3D11 и D3D12.
Итак, я начал с написания некоторых интерфейсов и их соответствующей реализации для каждого API.
Следующий фрагмент кода демонстрирует это:
class IDevice
{
//... (pure) virtual methods
};
class CD3D11Device : public IDevice
{
//... virtual method implementations
};
class CD3D12Device : public IDevice
{
//... virtual method implementations
};
Все идет нормально. Теперь к актуальной проблеме:
Если у меня есть другой интерфейс с методом, который требует IDevice*
Как параметр, как я могу убедиться, что «правильное» устройство передается?
class ISomeClass
{
public:
virtual void foo(IDevice* pDev) = 0;
};
class CD3D11SomeClass : public ISomeClass
{
public:
virtual void foo(IDevice* pDev) override
{
// should only be passed CD3D11Device
}
};
class CD3D12SomeClass : public ISomeClass
{
public:
virtual void foo(IDevice* pDev) override
{
// should only be passed CD3D12Device
}
};
Я знаю, что могу позвонить dynamic_cast
на IDevice*
указатели каждый раз и проверьте nullptr
но это утомительно и дорого с точки зрения производительности.
Есть ли какое-то элегантное решение этой проблемы? Кто-нибудь из вас знает, как профессиональные / коммерческие игровые движки справляются с этим?
Вы не сможете абстрагироваться D3D11
а также D3D12
вместе, если вы не идете намного дальше в абстракции, чем просто обертывание их интерфейса. Их конструкция слишком симметрична. Что вам нужно, так это спроектировать единый сильно абстрактный интерфейс движка рендеринга. Вещи как Material
, Image
или же Model
должно быть строгое дно вдоль боковых вещей, таких как Scene
или же RenderList
,
Что касается поддержки нескольких графических API в одном приложении, то вы ошибаетесь, в этом нет смысла D3D11
Путь к коду, если у вас есть D3D12
выбор должен быть D3D11/GL
против D3D12/Vulkan
, И это не из-за сходства API, а из-за набора функций, которые вам нужны в вашем приложении.
Потому что быть совет, D3D12
не предназначен для замены D3D11
первые существуют для 1% приложений, таких как игры AAA или тяжелый GPGPU, для большого набора данных. Если вы не являетесь экспертом в D3D11
уже и не знаю, почему именно вы должны использовать D3D12
не используйте его!
Других решений пока нет …