Загрузка файла OBJ, как использовать нормали (#vertices & lt; #normals)

У меня есть файл obj и я успешно загрузил объект в opengl без использования указанных нормалей.
Вот как это выглядит:
дерево без нормалей
Формат файла:

v x y z
vn x y z
f x//x' y//y' z//z'

Функция отображения сетки выглядит так:

glBegin(GL_TRIANGLES);
for all faces
{
glVertex3f(.., .., ..);
glVertex3f(.., .., ..);
glVertex3f(.., .., ..);
}
glEnd();

И результат такой:
введите описание изображения здесь

Я читал, что объект может выглядеть плоским из-за стандартного вектора нормалей, который OpenGL использует для уравнений освещения.
Это можно решить с помощью нормалей. Даны нормали 780 и вершины 155.

Я пытался использовать glNorm перед каждым вызовом glVertex3f, но объект выглядит совершенно странно (строки и т. Д.).

Что я должен делать?

РЕДАКТИРОВАНИЕ № 1:
Вот как я читаю файл:

void loader(class mesh &tree)
{
int vx1, vx2, vx3, vn1, vn2, vn3;
ifstream file;
string line;
point vec, norm;
face tempface;

file.open("tree.obj");
if (file.is_open() == true)
{
while(getline(file, line) )
{
if (line.substr(0,2) == "") continue;
else if (line.substr(0, 2) == "v ")
{
istringstream numbers(line.substr(2));
numbers >> vec.x >> vec.y >> vec.z;
tree.vectors.push_back(vec);
}
else if (line.substr(0,2) == "vn")
{
istringstream numbers(line.substr(2));
numbers >> norm.x >> norm.y >> norm.z;
tree.normals.push_back(norm);
}
else if (line.substr(0,2) == "f ")
{
face f;
line = line.substr(2,line.length());
for (string::iterator it = line.begin(); it != line.end(); ++it)
{
if (*it == '/')
{
//erase both of the "//"line.erase(it);
line.erase(it);
//add a space between the numbers
line.insert(it, ' ');
}
}
istringstream inp(line);
inp >> f.vert_indices[0] >> f.norm_indices[0] >> f.vert_indices[1] >> f.norm_indices[1] >> f.vert_indices[2] >> f.norm_indices[2];
tree.faces.push_back(f);
}
else
continue;
}
file.close();
}
}

И вот как я это показываю:

    void mesh::displayMesh()
{
glPushMatrix();
glBegin(GL_TRIANGLES);
for(vector<face>::const_iterator it = faces.begin();
it != faces.end(); ++it)
{
//glVertex3f(normals[it->norm_indices[0] -1 ].x, normals[it->norm_indices[0] -1 ].y, normals[it->norm_indices[0] -1 ].z);
glVertex3f(vectors[it->vert_indices[0] -1 ].x, vectors[it->vert_indices[0] -1 ].y, vectors[it->vert_indices[0] -1 ].z);
//glVertex3f(normals[it->norm_indices[1] -1 ].x, normals[it->norm_indices[1] -1 ].y, normals[it->norm_indices[1] -1 ].z);
glVertex3f(vectors[it->vert_indices[1] -1 ].x, vectors[it->vert_indices[1] -1 ].y, vectors[it->vert_indices[1] -1 ].z);
//glVertex3f(normals[it->norm_indices[2] -1 ].x, normals[it->norm_indices[2] -1 ].y, normals[it->norm_indices[2] -1 ].z);
glVertex3f(vectors[it->vert_indices[2] -1 ].x, vectors[it->vert_indices[2] -1 ].y, vectors[it->vert_indices[2] -1 ].z);
}
glEnd();
glPopMatrix();
}

Функция displayMesh вызывается в функции Render openGL, а функция загрузчика вызывается в функции Setup OpenGL, а объект дерева ячеек является глобальной переменной.

РЕДАКТИРОВАТЬ № 2:
Вот как дерево выглядит с нормалями:
дерево с нормалями
Также это код функции настройки OpenGL.

3

Решение

Разве у вас не должно быть следующего в вашем коде рисования?

glNormal3f(normals[it->norm_indices[0] -1 ].x, normals[it->norm_indices[0] -1 ].y, normals[it->norm_indices[0] -1 ].z);
glVertex3f(vectors[it->vert_indices[0] -1 ].x, vectors[it->vert_indices[0] -1 ].y, vectors[it->vert_indices[0] -1 ].z);
glNormal3f(normals[it->norm_indices[1] -1 ].x, normals[it->norm_indices[1] -1 ].y, normals[it->norm_indices[1] -1 ].z);
glVertex3f(vectors[it->vert_indices[1] -1 ].x, vectors[it->vert_indices[1] -1 ].y, vectors[it->vert_indices[1] -1 ].z);
glNormal3f(normals[it->norm_indices[2] -1 ].x, normals[it->norm_indices[2] -1 ].y, normals[it->norm_indices[2] -1 ].z);
glVertex3f(vectors[it->vert_indices[2] -1 ].x, vectors[it->vert_indices[2] -1 ].y, vectors[it->vert_indices[2] -1 ].z);

РЕДАКТИРОВАТЬ: ой, вы поняли, что уже

Если вы хотите проверить правильность нормалей, раскрасьте каждую вершину в соответствии с ее нормой. использование glColor3f но поставьте нормальные.

0

Другие решения

когда вы используете стирание, это делает недействительным итератор

//erase both of the "//"it = line.erase(it);
it = line.erase(it);
//add a space between the numbers
it = line.insert(it, ' ');

Однако вы можете стереть один раз, а затем заменить

//erase both of the "//"it = line.erase(it);
//add a space between the numbers
*it = ' ';
0

По вопросам рекламы [email protected]