Hi everyone, when I import an .obj file I get a model looking similar to the one I want but some triangles look distorted.
this is the model
declarations:
// vertex, normal, and index related declarations
GLfloat vertices[500];
GLfloat normals[540];
int indices[1300];
int vertexIndex = 0, normalIndex = 0, elementIndex = 0;
my load function:
// extracts object's vertices, indices, and normals from given file
int LoadObject( const char* filename, GLfloat vertices[], GLfloat normals[], int elements[] )
{
// local variables
const int MAX_CHARS_PER_LINE = 64;
char lineBuffer[64];
char temp[16];
char tempFloat[16];
FILE *objFile;
int count;
GLfloat coordinate; // stored in vertices
int index;
int charCount;
int isVertex = -1; // -1 for normal, 1 for vertex
int isFirstNormal = 1; // 1 for first normal, -1 for any other normal
// open file
fopen_s( &objFile, filename, "r" );
// check for errors
if ( objFile == NULL )
{
return 0;
}
// while there are lines to read
while ( fgets( lineBuffer, MAX_CHARS_PER_LINE, objFile ) != NULL )
{
// if we are reading a vector
if ( strncmp( lineBuffer, "v ", 2 ) == 0 )
{
// initialize charCount
charCount = 0;
// loop through each char in the line
for ( count = 2; count < (int)strlen( lineBuffer ); count++ )
{
// if we are reading part of a float coordinate
if ( ( lineBuffer[count] == '-' ) || ( isdigit( lineBuffer[count] ) ) || ( lineBuffer[count] == '.') )
{
// store this char into temp
temp[charCount++] = lineBuffer[count];
}
// if we are not reading part of a float and a float exists in temp
else if ( charCount != 0 )
{
// copy the float coordinate to tempFloat
strncpy( tempFloat, temp, charCount );
//
tempFloat[ charCount ] = '\n';
// store the coordinate in our vertices array
coordinate = atof( tempFloat );
vertices[vertexIndex++] = coordinate;
// re-initialize charCount
charCount = 0;
}
}
}
// if we are reading a normal
if ( strncmp( lineBuffer, "vn ", 3 ) == 0 )
{
// initialize charCount
charCount = 0;
// loop through each char in the line
for ( count = 3; count < (int)strlen( lineBuffer ); count++ )
{
// if we are reading part of a float coordinate
if ( ( lineBuffer[count] == '-' ) || ( isdigit( lineBuffer[count] ) ) || ( lineBuffer[count] == '.') )
{
// store this char into temp
temp[charCount++] = lineBuffer[count];
}
// if we are not reading part of a float and a float exists in temp
else if ( charCount != 0 )
{
// copy the float coordinate to tempFloat
strncpy( tempFloat, temp, charCount );
//
tempFloat[ charCount ] = '\n';
// store the coordinate in our normals array
coordinate = atof( tempFloat );
normals[normalIndex++] = coordinate;
// re-initialize charCount
charCount = 0;
}
}
}
// if we are reading face info
if ( strncmp( lineBuffer, "f ", 2 ) == 0 )
{
// initialize charCount, isVertex and isFirstNormal
charCount = 0;
isVertex = 1;
isFirstNormal = 1;
// loop through each char in the line
for ( count = 2; count < (int)strlen( lineBuffer ); count++ )
{
// if we are reading part of an index
if ( isdigit( lineBuffer[count] ) )
{
// store this char into temp
temp[charCount++] = lineBuffer[count];
}
// if we are not reading part of an index and an index exists in temp
else if ( charCount != 0 )
{
// if the index is a vertex
if ( isVertex == 1 )
{
// copy the float coordinate to tempFloat
strncpy( tempFloat, temp, charCount );
//
tempFloat[ charCount ] = '\n';
// store the coordinate in our indices array
index = atof( tempFloat );
elements[elementIndex++] = (int)index;
}
// if the index is a normal
else
{
// if this is the first normal in the line
if ( isFirstNormal == 1 )
{
// copy the float coordinate to tempFloat
strncpy( tempFloat, temp, charCount );
//
tempFloat[ charCount ] = '\n';
// store the coordinate in our normals array
index = atof( tempFloat );
elements[elementIndex++] = (int)index;
// switch isFirstNormal
isFirstNormal *= -1;
}
}
// switch isVertex
isVertex *= -1;
// re-initialize charCount
charCount = 0;
}
}
}
}
// close file
fclose( objFile );
// return ok
return 1;
}
my draw routine:
// draw our model
glBegin( GL_TRIANGLES );
// go through each element
for ( i = 0; i < elementIndex; i += 4 )
{
// set offsets
normalOffset = 3;
vertexOffset = 3;
// calculate index of x coordinate of current normal
currentNormalIndex = normalOffset * ( indices[i + 1] - 1 );
// calculate index of x coordinates of the three vertices
firstVertexIndex = vertexOffset * ( indices[ i + 1 ] - 1 );
secondVertexIndex = vertexOffset * ( indices[ i + 2 ] - 1 );
thirdVertexIndex = vertexOffset * ( indices[ i + 3 ] - 1 );
// set the normal for our triangle face
glNormal3f( normals[ normalOffset ],
normals[ normalOffset + 1 ],
normals[ normalOffset + 2 ] );
// set vertex 1
glVertex3f( vertices[ firstVertexIndex ],
vertices[ firstVertexIndex + 1 ],
vertices[ firstVertexIndex + 2 ]);
// set vertex 2
glVertex3f( vertices[ secondVertexIndex ],
vertices[ secondVertexIndex + 1 ],
vertices[ secondVertexIndex + 2 ]);
// set vertex 3
glVertex3f( vertices[ thirdVertexIndex ],
vertices[ thirdVertexIndex + 1 ],
vertices[ thirdVertexIndex + 2 ]);
}
glEnd();
The object was exported from blender using:
- selection only (current model)
- include normals
- triangulate faces
- keep vertex order
I understand that there are alternative ways to import and draw an .obj file but this will help me understand OpenGL and 3D objects better since I'm new to both 3D modelling and OpenGL.
Can someone help through this?
arigatou
EDIT: the indices are stored like this: [vector], [vector normal], [vector], [vector] for each line and I use the same vector normal for the 3 vectors to save space