Кроссплатформенный рендерер в OpenGL ES

Пишу кроссплатформенный рендерер. Я хочу использовать его на Windows, Linux, Android, iOS.

Считаете ли вы хорошей идеей избегать абсолютной абстракции и писать ее непосредственно в OpenGL ES 2.0?

Насколько я знаю, я должен быть в состоянии скомпилировать его на ПК со стандартным OpenGL, лишь с небольшими изменениями в коде, который обрабатывает контекст и подключение к оконной системе.


person runnydead    schedule 19.01.2012    source источник
comment
Вы слышали Киви? Это кроссплатформенный язык программирования с открытым исходным кодом для Linux, Windows, MacOSX, Android и IOS, который отображает все свои представления в OpenGL (kivy. орг). Язык также включает в себя собственный набор инструментов для виджетов. Я просто решил выбросить это, поскольку есть вероятность, что вы, возможно, не захотите изобретать велосипед, если решение уже существует, и вы, возможно, просто еще не обнаружили его.   -  person trusktr    schedule 09.09.2012
comment
Если у вас Android или iOS, попробуйте поискать Kivy в Play Store или App Store, чтобы увидеть примеры его использования.   -  person trusktr    schedule 09.09.2012


Ответы (2)


Считаете ли вы хорошей идеей избегать абсолютной абстракции и писать ее непосредственно в OpenGL ES 2.0?

Ваши основные трудности с этим будут связаны с теми частями спецификации ES 2.0, которые на самом деле не совпадают с OpenGL 2.1.

Например, вы просто не сможете пропихнуть шейдеры ES 2.0 через десктопный компилятор GLSL 1.20. В ES 2.0 вы используете такие вещи, как указание точности; это недопустимые конструкции в GLSL 1.20.

Однако вы можете #define обойти их, но для этого потребуется небольшое ручное вмешательство. Вам нужно будет вставить #ifdef в исходный файл шейдера. Есть трюки с компиляцией шейдеров, которые вы можете сделать, чтобы сделать это немного проще.

Действительно, поскольку GL ES использует совершенно другой набор расширений (хотя некоторые из них являются зеркалами и подмножествами расширений GL для настольных компьютеров), вы можете захотеть сделать это.

Каждый шейдер GLSL (настольный или ES) должен иметь «преамбулу». Первой вещью без комментариев в шейдере должно быть объявление #version. К счастью для вас, версия GL 2.1 для настольных ПК и GL ES 2.0 одинакова: #version 1.20. Проблема в том, что будет дальше: список #extension (если есть). Это включает расширения, необходимые шейдеру.

Поскольку GL ES использует расширения, отличные от настольных GL, вам потребуется изменить этот список расширений. А поскольку велика вероятность, что вам потребуется больше расширений GLSL ES, чем расширений GL 2.1 для настольных компьютеров, эти списки будут не просто сопоставлением 1:1, а совершенно другими списками.

Я предлагаю использовать возможность задавать шейдерам GLSL несколько строк. То есть в ваших реальных файлах шейдеров нет каких-либо преамбул. Они только имеют фактические определения и функции. Основная часть шейдера.

При работе на GL ES у вас есть глобальная преамбула, которую вы прикрепите к началу шейдера. У вас будет другая глобальная преамбула в настольной GL. Код будет выглядеть так:

GLuint shader = glCreateShader(/*shader type*/);
const char *shaderList[2];
shaderList[0] = GetGlobalPreambleString(); //Gets preamble for the right platform
shaderList[1] = LoadShaderFile(); //Get the actual shader file
glShaderSource(shader, 2, shaderList, NULL);

Преамбула может также включать #define для конкретной платформы. Определяется пользователем, конечно. Таким образом, вы можете #ifdef кодировать для разных платформ.

Есть и другие различия между ними. Например, хотя действительные вызовы функций загрузки текстур ES 2.0 будут нормально работать в настольной версии GL 2.1, они не обязательно будут оптимальными. Вещи, которые будут нормально загружаться на машинах с обратным порядком байтов, таких как все мобильные системы, потребуют некоторой настройки драйвера на настольных машинах с прямым порядком байтов. Таким образом, вы можете захотеть указать разные параметры передачи пикселей в GL ES и настольной GL.

Кроме того, в ES 2.0 и настольной версии GL 2.1 есть разные наборы расширений, которыми вы захотите воспользоваться. Хотя многие из них пытаются зеркально отразить друг друга (OES_framebuffer_object является подмножеством EXT_framebuffer_object), вы можете столкнуться с похожими проблемами «не совсем подмножества», подобными упомянутым выше.

person Nicol Bolas    schedule 19.01.2012
comment
Спасибо за исчерпывающий ответ. Итак, вы думаете, что будет лучше создать какую-то абстракцию рендерера OpenGL? Например, у меня может быть текстура, представленная классом Texture2D. Этот класс будет содержать вещи, общие для обеих спецификаций, но реализация некоторых вещей будет отличаться. - person runnydead; 19.01.2012
comment
@hubrobin: это не должно быть таким абстрактным. Вам просто нужен код для конкретной платформы в определенных местах. Теперь, если вы ориентируетесь на GL 3.3 вместо 2.1, вам потребуется гораздо больше абстракции. - person Nicol Bolas; 19.01.2012
comment
Я не хочу поддерживать больше функций на ПК. Так вы в основном говорите, что это выполнимо? - person runnydead; 19.01.2012
comment
Интересный момент: современные устройства ARM имеют обратный порядок байтов, например x86. - person karunski; 20.01.2012

По моему скромному опыту, лучший подход для таких требований — разработать ваш движок на чистом языке C, без каких-либо дополнительных слоев.

Я являюсь главным разработчиком движка PATRIA 3D, основанного на только что упомянутом вами основном принципе переносимости, и мы достигли этого, просто разработав инструмент на базовых стандартных библиотеках.

Усилия по компиляции вашего кода на разных платформах очень минимальны.

Фактические усилия по переносу всего решения можно рассчитать в зависимости от компонентов, которые вы хотите внедрить в свой движок.

Например:


Стандарт С:

Двигатель 3D

Логика игры

Игровой ИИ

Физика


+


Оконный интерфейс (GLUT, EGL и т. д.) — зависит от платформы, в любом случае может быть GLUT для рабочего стола и EGL для мобильных устройств.

Человеческий интерфейс - зависит от портирования, Java для Android, OC для IOS, любая версия рабочего стола

Звуковой менеджер - зависит от портирования

Маркет сервисов - зависит от портирования


Таким образом, вы можете беспрепятственно повторно использовать 95% своих усилий.

мы приняли это решение для нашего двигателя, и на данный момент оно действительно стоит первоначальных инвестиций.

person Maurizio Benedetti    schedule 19.01.2012