OBJ, буферные объекты и индексы граней

Совсем недавно я добился больших успехов в работе с объектами буфера вершин. Итак, я перешел к массивам элементов и подумал, что с такой реализацией я могу затем загружать данные вершин и граней из объекта.

Я не слишком хорошо разбираюсь в чтении файлов на С++, поэтому я написал документ на Python, чтобы проанализировать объект и написать 2 отдельных txts, чтобы получить массив вершин и индексы граней, и вставить их прямо в мой код. Это похоже на 6000 строк, но работает (без ошибок компиляции). И вот как это выглядит

.

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

Вот код рендеринга

void Mesh_handle::DrawTri(){
    glBindBuffer(GL_ARRAY_BUFFER,vertexbufferid);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,elementbufferid);
    int index1=glGetAttribLocation(bound_program,"inputvertex");
    int index2=glGetAttribLocation(bound_program,"inputcolor");
    int index3=glGetAttribLocation(bound_program,"inputtexcoord");

    glEnableVertexAttribArray(index1);
    glVertexAttribPointer(index1,3,GL_FLOAT,GL_FALSE,9*sizeof(float),0);

    glEnableVertexAttribArray(index2);
    glVertexAttribPointer(index2,4,GL_FLOAT,GL_FALSE,9*sizeof(float),(void*)(3*sizeof(float)));

    glEnableVertexAttribArray(index3);
    glVertexAttribPointer(index3,2,GL_FLOAT,GL_FALSE,9*sizeof(float),(void*)(7*sizeof(float)));

    glDrawArrays(GL_TRIANGLE_STRIP,0,elementcount);
    //glDrawElements(GL_TRIANGLE_STRIP,elementcount,GL_UNSIGNED_INT,0);
}

Мой синтаксический анализатор Python, который просто записывает информацию в файл: источник

Объект — Эзреаль из League of Legends.

Я не уверен, то ли я неправильно читаю лица, то ли они даже не такие, какими я их представлял. Я предполагаю использовать GL_TRIANGLE_STRIP или что-то еще. Любые подсказки или запросить дополнительную информацию.


person Kaliber64    schedule 28.08.2012    source источник
comment
+1 за современное искусство. Верхняя часть этой... штуки... на самом деле похожа на прическу Эзраила, если вы включите свое воображение xD   -  person SingerOfTheFall    schedule 28.08.2012
comment
Поскольку ваша проблема почти наверняка связана с вашим кодом .obj, а не с вашим кодом рендеринга, почему бы вам не показать нам, в чем ваша реальная проблема?   -  person Nicol Bolas    schedule 28.08.2012


Ответы (3)


Во-первых, как заявил Андреас, файлы .obj используют индексы, начинающиеся с 1, поэтому вам необходимо преобразовать их в индексы, начинающиеся с 0.

Второй:

glDrawArrays(GL_TRIANGLE_STRIP,0,elementcount);
//glDrawElements(GL_TRIANGLE_STRIP,elementcount,GL_UNSIGNED_INT,0);

Если вы не проделали какую-то специальную работу, чтобы превратить список лиц, который вы получили в файле .obj, в треугольную полосу, у вас нет треугольных полос. Вы должны рендерить GL_TRIANGLES, а не полоски.

person Nicol Bolas    schedule 28.08.2012
comment
Хорошо, так что объекты работают в треугольниках, я не был уверен. Большое спасибо. Я забыл, что после того, как я изменил лица, мне нужно было рисовать элементы. Я не знаю, о чем я думал с помощью drawarrays, он даже не использует индексы XD. минус один из граней, используйте треугольники и рисуйте элементы. УРА! это такой калейдоскоп ОО - person Kaliber64; 28.08.2012
comment
@Kaliber64: на самом деле у objs могут быть любые полигоны, обычно сначала нужно триангулировать данные. - person KillianDS; 28.08.2012
comment
Я понял кучу сейчас. Я нашел один для квадов, но что это, если на грань всего 2 номера? линии? - person Kaliber64; 28.08.2012
comment
Я визуализировал это как линии, и это сработало. Оказывается, я не могу заставить блендер выводить объекты с треугольниками или квадратами. Просто каркасы. Max и Maya не загрузят объект. ничего не говорит для загрузки: S. - person Kaliber64; 28.08.2012
comment
Только что сравнил экспортированный .obj с включенными индексами Blender, и он не совпадает - person June Wang; 05.09.2019
comment
@JuneWang: Чему они не соответствуют? - person Nicol Bolas; 05.09.2019
comment
@NicolBolas, то есть лицо в .obj равно «f 2//1 4//1 1//1», вычтите 1, вы получите [1 3 0] в виде треугольника. Но в Блендере [1 3 0] не является треугольником. - person June Wang; 05.09.2019
comment
@JuneWang: Откуда ты это знаешь? Как вы изучаете индексы в Blender, чтобы узнать, на какие вершины они сопоставляются? Я не знал, что вершины имеют индексы даже в самом Blender; они получают индексы только тогда, когда вы экспортируете их в какой-либо формат. - person Nicol Bolas; 05.09.2019
comment
В Blender 2.8 вы можете включить индексы, нажав стрелку вниз «Наложение окна просмотра» -> «Разработчик» и отметив опцию «индексы», она будет визуализировать индексы вершин. @NicolBolas - person June Wang; 05.09.2019
comment
@JuneWang: Хорошо, а где в экспортере OBJ Blender есть утверждение, что индексы в Blender будут соответствовать индексам, выводимым экспортером? Потому что я не вижу причин, по которым должна быть такая корреляция. - person Nicol Bolas; 05.09.2019
comment
@NicolBolas Должна быть какая-то корреляция, иначе как Blender узнает, какая вершина к какой соединяется. - person June Wang; 05.09.2019
comment
@JuneWang: Должна быть какая-то корреляция, иначе как Blender узнает, какая вершина с какой соединяется. Грани треугольника определяются набором из 3 позиций. Индексы действуют как посредники между гранью треугольника и позициями, на которые она ссылается. Но какой именно индекс используется для обеспечения связи между положением и лицами, является произвольным и не обязательно должен быть последовательным или сохраненным. Вы можете обеспечить любой порядок позиций с любой их индексацией, при этом представляя один и тот же набор лиц. - person Nicol Bolas; 05.09.2019
comment
@NicolBolas Да, но мне нужно было, чтобы индексы Blender/obj точно совпадали (после вычитания 1). Найденное решение состоит в том, чтобы вручную проверить «сохранять вертикальный порядок» в импортере/экспортере .obj, чтобы сохранить то же сопоставление. Спасибо. - person June Wang; 05.09.2019

Индексы в obj-файлах основаны на 1, поэтому вам нужно вычесть 1 из всех индексов, чтобы использовать их с OpenGL.

person Andreas Brinck    schedule 28.08.2012
comment
Нет, если вы не хотите новый выбор, он выглядит почти так же. Я использую правильный примитив? - person Kaliber64; 28.08.2012
comment
Я взял один из всех. Я пошел искать и нашел 1, но я не могу найти 0. Я не знаю. - person Kaliber64; 28.08.2012

Судя по изображению, ваши вершины испорчены. Похоже, вы указали шаг 9 * sizeof (float) в glGetAttribLocation, но из того, что я могу сказать из вашего кода, ваш массив плотно упакован.

glEnableVertexAttribArray(index1);
glVertexAttribPointer(index1,3,GL_FLOAT,GL_FALSE,0,0);

Также удалите шаг из координат цвета/текстуры.

person vasmos    schedule 29.07.2019