Jump to content

  • Log In with Google      Sign In   
  • Create Account


#Actualhikarihe

Posted 15 February 2013 - 01:15 AM

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

stick_figure_blender.jpg
 
and this is what i get (ignore rotation)
stick_figure.jpg

 

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


#1hikarihe

Posted 15 February 2013 - 01:11 AM

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

stick_figure_blender.jpg
 
and this is what i get (ignore rotation)
stick_figure.jpg

 

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


PARTNERS