LINUX.ORG.RU

Техника отрисовки полигональных моделей. (Mesh - ей)

 ,


0

3

Доброе утро/день/вечер/ночь всем.Возник вопрос, как бы наиболее эффективно отрисовать 3d объект за один вызов функции OpenGL.

Вот, к примеру, возьмем формат описания 3d модели obj (от компании Wavefront). Там о каждом геометрическом объекте выписана следующая информация: 1)вершины 2)координаты текстур 3)нормали

4)каждый полигон представлен набором индексов каждого из массивов.

Вот запись простейшего куба:

# Blender v2.74 (sub 0) OBJ File: ''
# www.blender.org
mtllib Cube.mtl
o Cube
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -0.000000 -0.000000 1.000000
vn -1.000000 -0.000000 -0.000000
vn 0.000000 0.000000 -1.000000
usemtl Material
s 1
f 1//1 2//1 3//1 4//1
f 5//2 8//2 7//2 6//2
f 1//3 5//3 6//3 2//3
f 2//4 6//4 7//4 3//4
f 3//5 7//5 8//5 4//5
f 5//6 1//6 4//6 8//6

v-вершины, vn - нормали, vt - координаты текстур (этот кубик без текстур).

Запись f 1//1 2//1 3//1 4//1 обозначает полигон с индексами вершин 1,2,3,4 и индексами нормалей 1,1,1,1 для каждой вершины. Индексы координат текстур пропущены.

Суть проблемы в том, что в этом формате, каждая грань лаконично описана индексами ДЛЯ КАЖДОГО из аттрибутов вершин, в OpenGL же массив индексов для функции glDrawElements описывает ТОЛЬКО индексы вершин.И даже если засунуть все аттрибуты вершин к ним в массив, то нормаль и координата текстур будет выбираться с тем же индексом, что и сама вершина, а не с тем, с каким нужно.

Вот пример:

GLfloat VertexAttribs[]=
{
  //Координаты вершин
    -0.5f,-0.5f,0.0f,
    0.5f,-0.5f,0.0f,
    0.5f,0.5f,0.0f,
    -0.5f,0.5f,0.0f,
  //Координаты вершин

  //Нормали
    0.0 -1.0 0.0
    0.0 1.0 0.0
    1.0 0.0 0.0
    -0.0 -0.0 1.0
    -1.0 -0.0 -0.0
    0.0 0.0 -1.0
  //Нормали
}

GLushort Indices[]=
{
  0,1,2,3
}

При вызове:

     glDrawElements(GL_TRIANGLE_FAN,4,GL_UNSIGNED_SHORT,NULL);
(Индексы были забиты в GL_ELEMENT_ARRAY_BUFFER)

При таком вызове будет нарисован следующий полигон:

  f 1//1 2//2 3//3 4//4     //(в формате obj индексы начинаются с 1)

, а нужно вот такой:

  f 1//6 2//6 3//6 4//6 

Но как такое сделать? В OpenGL индексуются сразу все аттрибуты.

Хочется делать все прямо, как в формате, чтобы никаких продублированных координат вершин и текстур (ну разве что индексы для нормалей будут дублироваться).Чтобы 1 вершину использовать в двух полигонах,а не две вершины с одинаковыми координатами для каждого полигона.Для этого нужно использовать индексированную отрисовку, но там встает проблема, описанная выше. Может я чего-то не знаю, может есть какой-то красивый способ обойти проблему?

С точки зрения ГАПИ вершина это набор уникальных атрибутов, так-что если какие-то атрибуты меняются (нормаль, например) это будут разные вершины, даже если остальные атрибуты совпадают.

oh-la-la
()

Есть, по идее, вариант смастерить какой-то буфер, содержащий фактические аттрибуты вершин Mesh-а, и подключить его к шейдеру.А в качестве формальных аттрибутов через glVertexAttribPointer посылать индексы фактических аттрибутов.Но GL_UNIFORM_BUFFER и GL_SHADER_STORAGE_BUFFER внутри шейдера должны быть объявленны с конкретным размером. Можно, конечно, поставить размер с запасом....но как-то это коряво...

Nerevarino
() автор топика
Ответ на: комментарий от oh-la-la

Я может бы сильно и не загонялся на эту тему.Тогда такой вопрос: значит дублирование информации при отрисовки сеток - обычное явление и чураться не надо?

Nerevarino
() автор топика
Ответ на: комментарий от Nerevarino

Вполне обычное.

P.S. Чтобы не париться с форматами можно взять Assimp, он будет выдавать уже подготоволенные вершины.

oh-la-la
()
Ответ на: комментарий от Nerevarino

Я использовал OpenImageIO. Для начала его хватит, но по-хорошему надо хранить текстуры в каком-нибудь DDS. Когда будет много текстур генерить для них мипмапы на лету будет долго.

oh-la-la
()

Подскажите, пожалуйста, сколько сейчас полигонов в секунду способна отрабатывать среднестатистическая карточка тысяч за 15-20 рублей?

Мне чисто, чтобы понимать, какой объем информации современные карты слопают и не заметят, а чем могут поперхнуться.

Или вопрос несколько некорректен?

P.S. Знаю, что результат зависит от накрученности шейдеров, света, текстур, но хоть какая информация хоть при каких условиях.

Nerevarino
() автор топика
Ответ на: комментарий от Nerevarino

Точнее даже треугольников, а не полигонов.

Nerevarino
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.