It's been something like a week and i still can't sort this out. I need something that converts a .obj file into data readable and drawable by my framework.
I have 1 main issues: indices.
I think i'm getting the vertices right (i checked in the debugger and everything was fine) but when i draw my model something always goes wrong.
I see the shape of the model but some triangles are not seen. I think this is a problem of clockwise/counterclockwise drawing. I exported a cube from blender to see how is done and i took pen and paper and draw it by hand following the indices the program created for me and i saw it uses a different indexing order that doesn't work in my program.
For i cube i create 36 vertices using the indices described by the "f" word. Every vertex has texture coordinates and normal vectors. Than from the indices i take the vertices indices and i use those to draw the cube, but it doesn't work.
I followed this tutorial to get into how i should script the converter
( http://www.opengl-tutorial.org/beginners-tutorials/tutorial-7-model-loading/ )
and i modified the code to make it work for DirectX drawing (which is similar to OpenGL i think) but it doesn't work at all.
void OBJLoader::loadOBJFromFile(char * fileName, std::vector<Vertex::Basic32> &output, std::vector<UINT> &vertexIndicesFinal)
{
UINT numberOfVertices = 0, numberOfNormals = 0, numberOfUVs = 0, numberOfFaces=0;
std::vector<Vertex::Basic32> outputDaMettere;
std::vector< UINT> vertexIndices, uvIndices, normalIndices;
std::vector< XMFLOAT3 > temp_vertices;
std::vector< XMFLOAT2 > temp_uvs;
std::vector< XMFLOAT3 > temp_normals;
std::vector<XMFLOAT3> outVertices;
std::vector<XMFLOAT3> outNormals;
std::vector<XMFLOAT2> outUvs;
FILE * file = fopen(fileName, "r");
if (file == NULL) {
MessageBox(0, L"NULL FILE", 0, 0);
}
while (1) {
char lineHeader[128];
int res = fscanf(file, "%s \n", lineHeader);
if (res == EOF)
break;
if (strcmp(lineHeader, "v") == 0) {
XMFLOAT3 vertex;
int a = fscanf(file, "%f %f %f \n", &vertex.x, &vertex.y, &vertex.z);
temp_vertices.push_back(vertex);
numberOfVertices++;
}
else if (strcmp(lineHeader, "vt") == 0) {
XMFLOAT2 uv;
fscanf(file, "%f %f\n", &uv.x, &uv.y);
temp_uvs.push_back(uv);
numberOfUVs++;
}
else if (strcmp(lineHeader, "vn") == 0) {
XMFLOAT3 normals;
fscanf(file, "%f %f %f \n", &normals.x, &normals.y, &normals.z);
temp_normals.push_back(normals);
numberOfNormals++;
}
else if (strcmp(lineHeader, "f") == 0) {
std::string vertex1, vertex2, vertex3;
UINT vertexIndex[3], uvIndex[3], normalIndex[3];
int matches = fscanf(file, "%i %i %i %i %i %i %i %i %i \n", &vertexIndex[0], &uvIndex[0], &normalIndex[0],
&vertexIndex[1], &uvIndex[1], &normalIndex[1],
&vertexIndex[2], &uvIndex[2], &normalIndex[2] );
if (matches != 9) {
MessageBox(0, L"File cant be read", 0, 0);
break;
}
vertexIndices.push_back(vertexIndex[0]);
vertexIndices.push_back(vertexIndex[1]);
vertexIndices.push_back(vertexIndex[2]);
uvIndices.push_back(uvIndex[0]);
uvIndices.push_back(uvIndex[1]);
uvIndices.push_back(uvIndex[2]);
normalIndices.push_back(normalIndex[0]);
normalIndices.push_back(normalIndex[1]);
normalIndices.push_back(normalIndex[2]);
numberOfFaces++;
}
}
numberOfFaces *= 3;
int cont = 0;
for (int i = 0; i < numberOfFaces; i++) {
UINT vertexIndex = vertexIndices[i];
UINT normalIndex = normalIndices[i];
UINT uvIndex = uvIndices[i];
Vertex::Basic32 temp;
temp.Pos = temp_vertices[vertexIndex - 1];
temp.Normal = temp_normals[normalIndex - 1];
temp.Tex = temp_uvs[uvIndex - 1];
output.push_back(temp);
cont++;
}
for (int i = 0; i < numberOfFaces; i++) {
vertexIndices[i]--; //Starts from 1, i need it to start from 0
}
int toAdd = 0;
for (int i = 0; i < numberOfFaces; i += 3) { //Needed to get the indices working for my draw function
vertexIndices[i] += toAdd;
vertexIndices[i + 1] += toAdd;
vertexIndices[i + 2] += toAdd;
toAdd += 2;
}
vertexIndicesFinal = vertexIndices;
}
I really need this to work, or some other code that does work and that is not impossible to understand. Thanks.