Как разработать простую оболочку GLSL для использования шейдера

ОБНОВЛЕНИЕ: Поскольку мне что-то нужно было сразу, я создал простую оболочку шейдера, которая выполняет то, что мне нужно. Вы можете найти его здесь: ShaderManager на GitHub . Обратите внимание, что он разработан для Objective-C / iOS, поэтому может быть полезен не всем. Если у вас есть предложения по улучшению дизайна, дайте мне знать!

Исходная проблема:

Я новичок в использовании шейдеров GLSL. Я достаточно знаком с языком GLSL и интерфейсом OpenGL, но у меня возникли проблемы с проектированием простого API для использования шейдеров.

Интерфейс C OpenGL для взаимодействия с шейдерами кажется громоздким. Кажется, я не могу найти в сети каких-либо руководств по разработке API для таких вещей.

У меня такой вопрос: есть ли у кого-нибудь хороший, простой дизайн API или шаблон для обертывания шейдера OpenGL программный API?

Возьмем следующий простой пример. Скажем, у меня есть один вершинный шейдер, который просто имитирует фиксированную функциональность, и два фрагментных шейдера - один для рисования сглаженных прямоугольников и один для рисования сглаженных кругов. У меня есть следующие файлы:

Shader.vsh : Simple vertex shader, with the following inputs/outputs:
    -- Uniforms: mat4 Model, mat4 View, mat4 Projection
    -- Attributes: vec4 Vertex, vec2 TexCoord, vec4 Color
    -- Varying: vec4 vColor, vec2 vTexCoord

Square.fsh : Fragment shader for drawing squares based on tex coord / color
Circle.fsh : Fragment shader for drawing circles based on tex coord / color

Базовое связывание

Каков стандартный способ их использования? Могу ли я связать вышеперечисленные шейдеры с двумя программами шейдеров OpenGL? То есть:

Shader.vsh + Square.fsh = SquareProgram
Shader.vsh + Circle.fsh = CircleProgram

Или я вместо этого создаю одну большую программу, в которой шейдеры фрагментов проверяют некоторые условные однородные переменные и вызывают функцию шейдера для генерации их результата. Например:

Shader.vsh + Square.fsh + Circle.fsh + Main.fsh = ShaderProgram
//Main.fsh here would simply check whether to call out to square or circle

С двумя отдельными программами мне, вероятно, нужно будет вызывать

glUseProgram(CircleProgram); or glUseProgram(SquareProgram);

перед каждым типом элемента, который я хочу нарисовать. Затем мне нужно будет установить униформу (Модель / Вид / Проекция) и атрибуты каждой программы, прежде чем я буду ее использовать. Это кажется таким громоздким.

С единственной опцией ShaderProgram мне все равно нужно будет установить какой-то логический переключатель (круг или квадрат) во фрагментном шейдере, который будет проверяться перед отрисовкой каждого пикселя. Это тоже кажется сложным.

В качестве примечания, могу ли я связать два фрагментных шейдера, каждый с функцией main () в одну программу шейдера? Как OpenGL узнает, какой из них вызывать?

Установка переменных

Вызовы:

glUniform*
glVertexAttribPointer

Используются для установки униформ и местоположений указателей атрибутов в текущей программе.

Различные классы и структуры могут нуждаться в доступе и установке переменные в текущем шейдере (или изменить текущий шейдер) из разных мест кода. Я не могу придумать хороший способ сделать это, чтобы отделить код шейдера от кода, который хочет его использовать.

То есть каждая фигура, которую я хочу нарисовать, должна будет установить атрибуты координат вершины и текстуры - требуя дескрипторы этих атрибутов, сгенерированных OpenGL.

Камера должна будет установить свою матрицу проекции как униформу в вершинном шейдере, в то время как класс, управляющий стеком матриц модели, должен будет установить свою собственную униформу в вершинном шейдере.

Изменение шейдеров на полпути к рисованию сцены будет означать, что всем этим классам нужно будет снова установить свои униформы и атрибуты.

Как большинство людей строят проекты вокруг этого?

Глобальный словарь шейдеров, доступ к которому осуществляется дескриптором или имя, с геттерами и сеттерами для их параметров?

Объектно-ориентированный проект с шейдерными объектами, каждый из которых имеет параметры?

Я посмотрел на следующие оболочки:

Чайник Джона: GLSL Shader Manager - Это обертывает шейдеры в классы C ++. Похоже, что это не что иное, как оболочка, которая реализует принципы объектно-ориентированного программирования в C API, в результате чего API C ++ почти такой же.

Мне нужен какой-либо дизайн, упрощающий использование программ шейдеров, и меня это не волнует. о конкретной используемой парадигме (OO, процедурная, и так далее)

10
задан Sisyphus 29 May 2011 в 13:17
поделиться