Как правильно отрисовать лица из файла 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 каждый раз, позволяя мне пропустить данные лица.

На всякий случай кому-то было любопытно.

Другие вопросы по тегам