Как правильно отрисовать лица из файла 3ds
Я реализовал возможность загрузки файлов 3DS в мою программу OpenGL и столкнулся с небольшой проблемой. Все вершины расположены правильно, а грани нарисованы, но проблема в том, что большинство (или все) вершин, похоже, сохраняют связь с одной или двумя вершинами, создавая большое количество дополнительных ребер. Кто-нибудь сталкивался с этой проблемой раньше или есть предложение, как я могу это исправить?
Следующий блок кода - это цикл, который я использую для рисования граней. Он проходит по одной вершине за раз, пропуская каждое четвертое значение (теоретически), поскольку они являются неиспользованными модификаторами лица.
glBegin(GL_TRIANGLES);
for(int x = 1; x < 4*numberOfTriangles+1; x++)
{
//Face bit modifiers not needed, skip em.
if(tLoop == 4)
{
tLoop = 0;
continue;
}
else
{
glVertex3f(Vertices[Triangles[x]*3],Vertices[(Triangles[x]*3)+1],Vertices[(Triangles[x]*3)+2]);
tLoop++;
}
}
glEnd();
Следующее - изображение, представляющее проблему, с которой я столкнулся. http://img.photobucket.com/albums/v298/Reaperc89/Pistol.jpg
2 ответа
Дело в том, что glBegin
а также glEnd
Вне цикла это абсолютно не проблема. Рисование треугольников с использованием каждой вершины одна за другой - правильный путь. Он будет строить треугольную форму каждые 3 последовательных вершины, что вам и нужно.
Ваша проблема заключалась в том, что вы увеличили tLoop
внутри блока else, и, следовательно, фактически пропускает каждый пятый индекс, а не каждый четвертый. Так что разворачивание помешало этому, но это не имеет ничего общего с glBegin/glEnd
не работает за пределами цикла. Но, как сказано в комментарии, вам не нужно tLoop
во всяком случае, так как вы можете просто использовать x
вместо:
glBegin(GL_TRIANGLES);
for(int x = 1; x < 4*numberOfTriangles+1; x++)
if(x % 4) //works if x starts at 1, though I don't know why x has to start at 1
glVertex3f(Vertices[Triangles[x]*3],Vertices[(Triangles[x]*3)+1],Vertices[(Triangles[x]*3)+2]);
glEnd();
или даже лучше разверните цикл:
glBegin(GL_TRIANGLES);
for(int x = 1; x < 4*numberOfTriangles+1; x+=4) {
glVertex3f(Vertices[Triangles[x]*3],Vertices[(Triangles[x]*3)+1],Vertices[(Triangles[x]*3)+2]);
glVertex3f(Vertices[Triangles[x+1]*3],Vertices[(Triangles[x+1]*3)+1],Vertices[(Triangles[x+1]*3)+2]);
glVertex3f(Vertices[Triangles[x+2]*3],Vertices[(Triangles[x+2]*3)+1],Vertices[(Triangles[x+2]*3)+2]);
}
glEnd();
Но размещение glBegin/glEnd
внутри петли самая глупая вещь, которую вы можете сделать. Фактически, если вы уже используете представление на основе массива вершин / индексов, должно быть довольно просто перенести код рендеринга на массивы вершин, которые работают намного быстрее, чем в непосредственном режиме, особенно в случае работы на VBO.
Разобрался с собственной проблемой. Обратите внимание, как начальный и конечный блоки появляются за пределами цикла. Программа пыталась нарисовать треугольники, используя каждую вершину в сетке, одну за другой. Таким образом это создало один гигантский беспорядок. Я переключился на размещение трех вершин за раз (одну грань) и поместил начальный / конечный блоки внутри цикла и изменил цикл на приращение на 4 каждый раз, позволяя мне пропустить данные лица.
На всякий случай кому-то было любопытно.