Считаете ли вы, что стоит избегать абсолютной абстракции и писать ее непосредственно в 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), вы можете столкнуться с похожими проблемами «не совсем подмножества», такими как упомянутые выше.