Я не сделал этого для графики, но я создал кроссплатформенный аудио инструментарий (PC / XBOX / PS2). Мы пошли по пути создания нашего собственного API с возможностью наименьшего общего знаменателя, а также дополнительными возможностями для конкретной платформы. Вот некоторые извлеченные уроки:
Ключевым моментом является определение пути обработки, который включает в себя основные возможности каждой платформы и обеспечивает рост. Чтобы сделать это, вам нужно по-настоящему понять API низкого уровня каждой платформы, чтобы вы могли определить правильные абстракции. Убедитесь, что цепочка работает для наименее способной платформы, обеспечивая при этом доступ к расширенным функциям наиболее способной формы. Сделайте работу, чтобы сделать это правильно, и вы сэкономите много усилий позже.
Для аудио цепочка была чем-то вроде SoundSources -> [Decoders] -> Buffers -> [3D Positioner] ->[Effects] -> Players
.
Для графики это может быть Model -> Shapes -> Positioner -> Texturer -> [Lighting] -> [Particle Effects] -> Renderer
. (Это, вероятно, совершенно неправильный набор, я не графический парень).
Напишите интерфейсный API, который обрабатывает ваши основные объекты, и специфичный для платформы сервер, который отображает API на низкоуровневые возможности. Приложите максимум усилий для каждой возможности. Например, на ПК и XBOX позиционирование 3D-звука осуществлялось с использованием возможностей звуковых чипов HRTF, в то время как PS2 использовала простое панорамирование и фейдеры. Графический движок может сделать что-то похожее с освещением.
Реализуйте как можно больше внешнего интерфейса с помощью нейтрального кода платформы. Код для привязки объекта реверберации к звуковому объекту или актива текстуры к объекту формы должен быть совершенно обычным, как и код для итерации и обработки активных объектов. С другой стороны, объекты низкого уровня могут полностью зависеть от платформы, за исключением общего интерфейса.
Убедитесь, что API или файлы конфигурации позволяют пользователю указывать специфичные для платформы параметры. Мы старались не выдвигать специфичный для платформы код на игровой уровень, сохраняя его в файлах конфигурации: в одном файле конфигурации платформы можно указать «effect: SuperDuperParticleGenerator», а в другой - «effect: SoftGlow»
Определенно развивайте платформы параллельно. Убедитесь, что специфичные для платформы интерфейсы хорошо определены и тестируемы сами по себе. Это предотвращает много "это уровень платформы или уровень API?" проблемы при отладке.