Я кодирую небольшой движок рендеринга с шейдерами GLSL:
Каждая Mesh (ну, submesh) имеет несколько вершинных потоков (например, положение, нормаль, текстура, тангенс и т.д.) в один большой VBO и MaterialID.
Каждый материал имеет набор текстур и свойств (например, зеркальный цвет, диффузный цвет, цветная текстура, нормальная карта и т.д.).
Затем у меня есть шейдер GLSL, с его формами и атрибутами. Пусть говорят:
uniform vec3 DiffuseColor;
uniform sampler2D NormalMapTexture;
attribute vec3 Position;
attribute vec2 TexCoord;
Я немного застрял в попытке разработать способ шейдера GLSL для определения сопоставлений потоков (семантики) для атрибутов и униформ, а затем привязать вершинные потоки к соответствующим атрибутам.
Что-то в строках выражения сетке: "Поместите свой позиционный поток в атрибут" Позиция "и ваши текс-координаты в" TexCoord ". Также поместите свой материал в диффузный цвет в" DiffuseColor "и ваш материал второй текстуры в" NormalMapTexture ""
В настоящее время я использую жестко закодированные имена для атрибутов (т.е. vertex pos всегда "Position" и т.д.) и проверяя каждое унифицированное имя и имя атрибута, чтобы понять, для чего используется шейдер.
Я предполагаю, что я ищу способ создания "объявления вершин", но включая униформы и текстуры.
Поэтому мне просто интересно, как это делают люди в широкомасштабных механизмах рендеринга.
Edit:
Рекомендации предлагаемых методов:
1. Атрибут/Равномерная семантика задается именем переменной (что я делаю сейчас) Использование предопределенных имен для каждого возможного атрибута. Связывание GLSL запрашивает имя для каждого атрибута и связывает массив вершин на основе имени переменной:
//global static variable
semantics (name,normalize,offset) = {"Position",false,0} {"Normal",true,1},{"TextureUV,false,2}
...when linking
for (int index=0;index<allAttribs;index++)
{
glGetActiveAttrib(program,index,bufSize,length,size[index],type[index],name);
semantics[index]= GetSemanticsFromGlobalHardCodedList(name);
}
... when binding vertex arrays for render
for (int index=0;index<allAttribs;index++)
{
glVertexAttribPointer(index,size[index],type[index],semantics[index]->normalized,bufferStride,semantics[index]->offset);
}
2. Предопределенные местоположения для каждого семантического
Связующее GLSL всегда связывает массивы вершин с теми же местами. Это зависит от того, будет ли шейдер использовать соответствующие имена для соответствия. (Это кажется ужасно похожим на метод 1, но если я не понял, это подразумевает привязку ВСЕХ доступных вершинных данных, даже если шейдер не потребляет их)
.. when linking the program...
glBindAttribLocation(prog, 0, "mg_Position");
glBindAttribLocation(prog, 1, "mg_Color");
glBindAttribLocation(prog, 2, "mg_Normal");
3. Словарь доступных атрибутов из Material, Engine globals, Renderer и Mesh
Поддерживать список доступных атрибутов, опубликованных активным Материалом, глобальными двигателями, текущим рендерером и текущей сценой Node.
например:
Material has (uniformName,value) = {"ambientColor", (1.0,1.0,1.0)}, {"diffuseColor",(0.2,0.2,0.2)}
Mesh has (attributeName,offset) = {"Position",0,},{"Normals",1},{"BumpBlendUV",2}
затем в шейдере:
uniform vec3 ambientColor,diffuseColo;
attribute vec3 Position;
При привязке данных вершин к шейдеру связующее GLSL будет перебирать атрибуты и связываться с найденным (или нет?) в словаре:
for (int index=0;index<allAttribs;index++)
{
glGetActiveAttrib(program,index,bufSize,length,size[index],type[index],name);
semantics[index] = Mesh->GetAttributeSemantics(name);
}
и то же самое с униформами, только запрос активен и материал и глобалы.