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;
}
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;
}