Я кодирую небольшой движок рендеринга с помощью GLSL-шейдеров:
Каждая сетка (ну, подмешивание) имеет несколько потоков вершин (например, положение, нормаль, текстура, касательная и т. Д.) В один большойVBO и MaterialID.
Каждый материал имеет набор текстур и свойств (например, specular-color, diffuse-color, color-texture, normal-map и т. Д.)
Тогда у меня естьшейдер GLSL, с его униформой и атрибутами.Скажем:
uniform vec3 DiffuseColor;
uniform sampler2D NormalMapTexture;
attribute vec3 Position;
attribute vec2 TexCoord;
Я немного застрял в попытке разработать способ для шейдера GLSL определить потоковые отображения (семантику) для атрибутов и униформ, а затем связать потоки вершин ссоответствующие атрибуты.
Что-то в строках произнесения к сетке: "поместите ваш поток позиции в атрибут" Position ", а ваши координаты tex в" TexCoord ". Также поместите диффузный цвет вашего материала в" DiffuseColor "ивторая текстура вашего материала в "NormalMapTexture"
В настоящее время я использую жестко закодированные имена для атрибутов (т. е. vertex pos всегда "Position" и т. д.) и проверяю каждую униформу и имя атрибута, чтобы понять, чтошейдер использует его для.
Наверное, я ищу какой-то способ создания "объявления вершины", но также с учетом формы и текстур.
Так что мне просто интересно, каклюди делают это в крупномасштабных движках рендеринга.
Редактировать:
Резюме предлагаемых методов:
1. Attribute / Uniform семантика задается именем переменной (что я сейчас делаю). Использование предопределенных имен для каждого возможного атрибута. Связыватель 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, Globals Engine, Renderer и Mesh
Ведение списка доступных атрибутов, опубликованных активным Material, глобалами Engine, текущим Renderer и текущим узлом сцены.
например:
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);
}
и то же самое с униформой, только запрос активного материала и глобальных переменных.