Я пишу уровень абстракции поверх некоторого графического API (DirectX9 и DirectX11), и мне бы хотелось, чтобы вы мнение.
Традиционно я создавал базовый класс для каждой концепции, которую хочу абстрагировать.
В типичном объектно-ориентированном стиле у меня был бы, например, класс Shader и 2 подкласса DX9Shader и DX11Shader.
Я бы повторил процесс для текстур и т. Д. ... и когда мне нужно было их создать, у меня есть абстрактная фабрика, которая вернет соответствующий подкласс в зависимости от текущего графического API.
После RAII возвращаемый указатель будет инкапсулирован в std :: shared_ptr.
Пока все хорошо, но в моем случае есть несколько проблем с этим подходом:
Это побудило меня изменить свой подход к работе: Я думал, что могу просто вернуть необработанные указатели на ресурсы и очистить графический API после себя, но все еще существует проблема с висячими указателями на сторона клиента и проблема интерфейса. Я даже рассматривал ручной подсчет ссылок, как в COM, но я подумал, что это будет шагом назад (поправьте меня, если я ошибаюсь, из мира shared_ptr ручной подсчет ссылок кажется примитивным) .
Затем я увидел работу Хумуса, в которой все его графические классы представлены целочисленными идентификаторами (очень похоже на то, что делает OpenGL).
Создание нового объекта возвращает только его целочисленный идентификатор и сохраняет указатель внутри; все это совершенно непрозрачно!
Классы, представляющие абстракцию (такие как DX9Shader и т. Д.), Все скрыты за API устройства, который является единственным интерфейсом.
Если кто-то хочет установить текстуру, достаточно вызвать device-> SetTexture (ID), а все остальное происходит за кулисами.
Крахом является то, что скрытая часть API раздута, для его работы требуется много стандартного кода, и я не поклонник универсального класса.
Есть идеи / мысли?