我写了一个基本的 .obj 加载器。它适用于立方体和其他一些基本的东西。一旦我给它一个复杂的模型,它就会失败。
这是一些基本代码:
函数.h
#pragma once
#include <string>
struct face {
bool triangle;
int faceNumber;
int faces[4];
face(int faceNumber2,int f1,int f2, int f3, int f4) {
triangle = false;
faceNumber = faceNumber2;
faces[0] = f1;
faces[1] = f2;
faces[2] = f3;
faces[3] = f4;
}
face(int faceNumber2,int f1,int f2, int f3) {
triangle = true;
faceNumber = faceNumber2;
faces[0] = f1;
faces[1] = f2;
faces[2] = f3;
}
};
struct position {
float x, y, z;
position(float X,float Y, float Z) {
x = X;
y = Y;
z = Z;
}
};
class Functions
{
public:
Functions(void);
~Functions(void);
int loadObject(std::string fileName);
void drawCube(float size);
unsigned int loadTexture(const char* fileName);
};
函数.cpp
int Functions::loadObject(string fileName) {
ifstream file(fileName);
vector<string*> line;
vector<position*> normals;
vector<face*> faces;
vector<position*> vertices;
if (file.is_open()) {
char buffer[256];
while (!file.eof()) {
file.getline(buffer,256);
line.push_back(new string(buffer));
}
for (int i = 0; i<line.size(); i++) {
if ((*line[i])[0] == 'v' && (*line[i])[1] == ' ') { //Vertice
float x,y,z;
sscanf_s((*line[i]).c_str(),"v %f %f %f",&x,&y,&z);
vertices.push_back(new position(x,y,z));
}else if ((*line[i])[0] == 'v' && (*line[i])[1] == 'n') { //Normals
float x,y,z;
sscanf_s((*line[i]).c_str(),"vn %f %f %f",&x,&y,&z);
normals.push_back(new position(x,y,z));
} else if ((*line[i])[0] == 'f') {
if (count((*line[i]).begin(),(*line[i]).end(),' ') == 4) {
float a,b,c,d,e;
sscanf_s((*line[i]).c_str(),"f %f//%f %f//%f %f//%f %f//%f",&a,&e,&b,&e,&c,&e,&d,&e);
faces.push_back(new face(e,a,b,c,d));
} else {
float a,b,c,e;
sscanf_s((*line[i]).c_str(),"f %f//%f %f//%f %f//%f",&a,&e,&b,&e,&c,&e);
faces.push_back(new face(e,a,b,c));
}
}
}
file.close();
} else {
file.close();
throw exception("Fail to load file");
return -1;
}
int num;
num = glGenLists(1);
glNewList(num,GL_COMPILE);
for (int i = 0; i<faces.size(); i++) {
face tempFace = (*faces[i]);
if (tempFace.triangle) {
glBegin(GL_TRIANGLES);
glNormal3f((*normals[tempFace.faceNumber-1]).x, (*normals[tempFace.faceNumber-1]).y, (*normals[tempFace.faceNumber-1]).z);
glVertex3f((*vertices[tempFace.faces[0]-1]).x, (*vertices[tempFace.faces[0]-1]).y, (*vertices[tempFace.faces[0]-1]).z);
**//Errors below.**
glVertex3f((*vertices[tempFace.faces[1]-1]).x, (*vertices[tempFace.faces[1]-1]).y, (*vertices[tempFace.faces[1]-1]).z);
glVertex3f((*vertices[tempFace.faces[2]-1]).x, (*vertices[tempFace.faces[2]-1]).y, (*vertices[tempFace.faces[2]-1]).z);
glEnd();
} else {
//glNormal3f((*normals[tempFace.faceNumber-1]).x,(*normals[tempFace.faceNumber-1]).y,(*normals[tempFace.faceNumber-1]).z)
glBegin(GL_QUADS);
glNormal3f((*normals[tempFace.faceNumber-1]).x, (*normals[tempFace.faceNumber-1]).y, (*normals[tempFace.faceNumber-1]).z);
glVertex3f((*vertices[tempFace.faces[0]-1]).x, (*vertices[tempFace.faces[0]-1]).y, (*vertices[tempFace.faces[0]-1]).z);
glVertex3f((*vertices[tempFace.faces[1]-1]).x, (*vertices[tempFace.faces[1]-1]).y, (*vertices[tempFace.faces[1]-1]).z);
glVertex3f((*vertices[tempFace.faces[2]-1]).x, (*vertices[tempFace.faces[2]-1]).y, (*vertices[tempFace.faces[2]-1]).z);
glVertex3f((*vertices[tempFace.faces[3]-1]).x, (*vertices[tempFace.faces[3]-1]).y, (*vertices[tempFace.faces[3]-1]).z);
glEnd();
}
}
glEndList();
for (int i = 0; i<line.size(); i++) {
delete line[i];
}
for (int i = 0; i<normals.size(); i++) {
delete normals[i];
}
for (int i = 0; i<vertices.size(); i++) {
delete vertices[i];
}
for (int i = 0; i<faces.size(); i++) {
delete faces[i];
}
return 1;
}
我已经尝试了两天了。就像我说的那样,它适用于一些不复杂的模型。