PDA

View Full Version : OBJ Loader Problem


Eriond
04-20-2008, 12:02 PM
I'm having an incredibly strange problem with my wavefront OBJ loader. It loads everything fine, all the vertices are in proper order, normals are fine, but when it comes to texture coordinates, things are a little screwed up. When I make a cube in Blender, for example, with the numbers 1 through 6 on each side, and load it into my game, the cube shows up fine, it's lit properly, but the 1 through 6 are all over the place, clipped in some areas, not even there in others. I have no idea why this might happen. The UVs are there, I can import the model back into Blender, no problems, so the data is THERE, it's just not getting used properly.

I'm going to dump my code here. It's not too long, I'm only interested in getting the most basic parts working first. As I say, I have absolutely no idea as to why it's doing this, everything seems fine to me. If anyone has any ideas, please post, and help me out.

Vertices, TexCoords, and Normals are all arrays of simple structures that hold 3, 2 and 3 floats respectively. I draw them using glDrawArrays(GL_TRIANGLES,0,Triangles*3);

bool Static::Load(char* Buffer, int Size)
{
unsigned int Count = 0, VC = 0, VTC = 0, VNC = 0, FC = 0, VI[3],TI[3],NI[3];
char Line[256]; memset(Line,0,sizeof(Line));
Vertex3D* UVertices; Normal3D *UNormals; Point2D* UTexCoords;
Clear();
// First Parse : Counts Vertices, Normals, Texture Coordinates and Faces
for (Count = 0;; Count += sgets(Line,256,&Buffer[Count])+1){
if (strncmp("v ",Line,2) == 0) VC++;
if (strncmp("vn ",Line,3) == 0) VNC++;
if (strncmp("vt ",Line,3) == 0) VTC++;
if (strncmp("f ",Line,2) == 0) FC++;
if (Count >= Size) break;
}
if (VNC != 0) HasNormals = true; if (VTC != 0) HasTexture = true;
UVertices = new Vertex3D[VC]; if (HasTexture) UTexCoords = new Point2D[VTC]; if (HasNormals) UNormals = new Point3D[VNC];
Vertices = new Vertex3D[FC*3]; if (HasTexture) TexCoords = new Point2D[FC*3]; if (HasNormals) Normals = new Normal3D[FC*3];
// Second Parse : Read Vertices, Normals, Texture Coordinates and Faces into Organized Arrays
memset(Line,0,sizeof(Line));
for (Count = 0, VC = 0, VNC = 0, VTC = 0, FC = 0;; Count += sgets(Line,256,&Buffer[Count])+1){
if (strncmp("v ",Line,2) == 0){ sscanf(Line,"%*c %f %f %f",&UVertices[VC].X,&UVertices[VC].Y, &UVertices[VC].Z); VC++; }
if (strncmp("vn ",Line,3) == 0){ sscanf(Line,"%*s %f %f %f",&UNormals[VNC].X,&UNormals[VNC].Y, &UNormals[VNC].Z); VNC++; }
if (strncmp("vt ",Line,3) == 0){ sscanf(Line,"%*s %f %f",&UTexCoords[VTC].X,&UTexCoords[VTC].Y); VTC++;}
if (strncmp("f ",Line,2) == 0){
if (HasTexture && HasNormals)
sscanf(Line,"%*c %d %*c %d %*c %d %d %*c %d %*c %d %d %*c %d %*c %d",&VI[0],&TI[0],&NI[0],&VI[1],&TI[1],&NI[1],&VI[2],&TI[2],&NI[2]);
else if (HasTexture && !HasNormals)
sscanf(Line,"%*c %d %*c %d %*c %*d %d %*c %d %*c %*d %d %*c %d %*c %*d",&VI[0],&TI[0],&VI[1],&TI[1],&VI[2],&TI[2]);
else if (!HasTexture && HasNormals)
sscanf(Line,"%*c %d %*c %*c %d %d %*c %*c %d %d %*c %*c %d",&VI[0],&NI[0],&VI[1],&NI[1],&VI[2],&NI[2]);
else if (!HasTexture && !HasNormals)
sscanf(Line,"%*c %d %*c %*d %*c %*d %d %*c %*d %*c %*d %d %*c %*d %*c %*d",&VI[0],&VI[1],&VI[2]);
Vertices[FC*3+0] = UVertices[(VI[0]-1)]; Vertices[FC*3+1] = UVertices[(VI[1]-1)]; Vertices[FC*3+2] = UVertices[(VI[2]-1)];
if (HasNormals){ Normals[FC*3+0] = UNormals[NI[0]-1]; Normals[FC*3+1] = UNormals[NI[1]-1]; Normals[FC*3+2] = UNormals[NI[2]-1]; }
if (HasTexture){ TexCoords[FC*3+0] = UTexCoords[TI[0]-1]; TexCoords[FC*3+1] = UTexCoords[TI[1]-1]; TexCoords[FC*3+2] = UTexCoords[(TI[2]-1)]; }
FC++;
}
if (Count >= Size) break;
}
Triangles = FC;
delete[] UVertices; delete[] UTexCoords; delete[] UNormals;
return true;
}

roel
04-21-2008, 02:37 AM
I'm not in the mood to read code, but did you 1. output the numbers your code read and compared it to the text in the .obj file? and 2. manually inspect the meaning of the texture coordinates? and 3. export a triangulated mesh? iirc, .obj supports arbitrary polygons, so if you don't triangulate your mesh, the output consists of quads. But well, if that were the problem it would not result in a cube at all, so I doubt that that is the problem.

Eriond
04-21-2008, 02:46 PM
I did manually inspect the file, but it seemed fine... but upon closer inspection, you're right. I found the problem. Blender's exporting Y coordinates from the bottom up, whereas my engine reads them from the top down.

Thanks for the help. I appreciate it.