Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualHelixirr

Posted 27 January 2013 - 04:46 AM

Hi, folks!

I have tried to create a 3D model class called Model3, which will inherit from my base class Model. This Model3-class supports only Wavefront OBJ files at the moment and I'm having trouble setting up correct data for OpenGL to process. I try to get rid of the deprecated OpenGL functions and use vertex array objects and vertex buffers objects instead to accomplish my goal to display a 3D model on screen.

The problem is rather simple to describe: polygons are formed incorrectly.

This is how I see the model in Blender (in which I also did the model):
http://imageshack.us/photo/my-images/838/timg.png/

And this is what ends up looking in my program:
http://imageshack.us/photo/my-images/546/tim2i.png/

 

Here's Model3 class definition:

/// ----------------------------------
    /// @class  	Model3
    /// @brief  	Represents a 3D model.
	/// @typedef	Model3D
    /// ----------------------------------
    typedef class Model3 : public Model{
    public:

		/// Enumerations:
		enum class FormatFile : unsigned int{
			FORMATFILE_3DS,
			FORMATFILE_OBJ
		};

        /// Constructors & destructors:
        Model3(void);
        Model3(Model3 const& model) = default;
        Model3(Model3&& model) = default;
		~Model3(void);

		/// Member functions:
		Model3& set_data(Model3::FormatFile const& format_file, std::string const& name_file);
		Model3& set_data(Model3::FormatFile const& format_file, std::string const&& name_file);
		Model3& set_data(Model3::FormatFile&& format_file, std::string const& name_file);
		Model3& set_data(Model3::FormatFile&& format_file, std::string const&& name_file);
		void show(void) const;

		/// Member functions (overloaded operators):
		Model3& operator=(Model3 const& model);
		Model3& operator=(Model3&& model);

    private:
        /// Member data:
		std::vector<Helixirr::Vector3<float>> _m_voDataFace[3]; // Element 0 contains vertex coordinates, element 1 contains texture coordinates, element 2 contains vertex normals.
		std::vector<Helixirr::Vector3<float>> _m_voDataVertex[3]; // Element 0 contains vertex coordinates, element 1 contains texture coordinates, element 2 contains vertex normals.
		unsigned int _m_uiIdArrayVertex, _m_uiBufferVertex;
	}Model3D;

 

Here are implementations of functions set_data and show:

/// Member functions:
Model3& Model3::set_data(Model3::FormatFile const& format_file, std::string const& name_file){ /* UNFINISHED! */
	std::ifstream __file(name_file);

	// 3D model loading lambdas:
	auto const __load_3ds = [&](void){
		/* UNFINISHED! */
	};
	auto const __load_obj = [&](void){ /* WORKS HALF RIGHT AND MORE FUNCTIONALITY IS REQUIRED! */
		auto const __read_data_vertices = [](std::string const& string, float coordinates[], unsigned int const&& amount_elements, unsigned int&& index_begin){
			// Variables used in the following for loop:
			// index_begin = end index for string substraction operation
			// __i = index of the temporary float array
			// __j = start index for string substraction operation
			for(unsigned int __i = 0, __j = index_begin; __i != amount_elements; ++__j){
				if(string[__j] == ' '){ // If the "end character" for floating number is detected:
					coordinates[__i++] = atof(string.substr(index_begin, ++__j).c_str());
					index_begin = __j;
				}
			}
		};

		std::string __line;
		clock_t init = clock();
		while(std::getline(__file, __line)){ // For each line in the requested file:
			switch(__line[0]){ // Check out the first letter of a line:
				case 'f':{
					// Read through the whole line ignoring all the insignificant characters (like '\n'):
					for(unsigned int __i = 2, __j = 2, __k = 0; __j != __line.size() - 1; ++__j){
						if(__line[__j] == '/'){
							_m_voDataFace[__k].push_back(_m_voDataVertex[__k][atoi(__line.substr(__i, ++__j).c_str())]);
							__i = __j;
							++__k;
						}
						else if(__line[__j] == ' '){
							++__j;
							__i = __j;
							__k = 0;
						}
					}
					continue;
				}
				case 'v': // If a requested line contains some sort of vertex data:
					if(__line[1] == ' '){ // If the requested line contains vertex coordinates:
						float __coordinates[3] = {0.0f}; // A temporary float array to store vertex coordinates.
						__read_data_vertices(__line, __coordinates, 3, 2);
						_m_voDataVertex[0].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), std::move(__coordinates[2])));
					}
					else if(__line[1] == 'n'){ // If the requested line contains vertex normals:
						float __coordinates[3] = {0.0f}; // A temporary float array to store vertex normals.
						__read_data_vertices(__line, __coordinates, 3, 3);
						_m_voDataVertex[2].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), std::move(__coordinates[2])));
					}
					else if(__line[1] == 't'){ // If the requested line contains UV coordinates:
						float __coordinates[2] = {0.0f}; // A temporary float array to store UV coordinates.
						__read_data_vertices(__line, __coordinates, 2, 3);
						_m_voDataVertex[1].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), 0.0f));
					}
					continue;
				default:
					continue;
			}
		}
		printf("OBJ file loading - elapsed time: %f\n", static_cast<double>(clock() - init) / static_cast<double>(CLOCKS_PER_SEC));
	};

	// Detect requested file format:
	switch(format_file){
		case Model3::FormatFile::FORMATFILE_3DS:
			__load_3ds();
			break;
		case Model3::FormatFile::FORMATFILE_OBJ:
			__load_obj();
			break;
		default:
			break;
	}

	// Create and bind a vertex array:
	if(_m_uiIdArrayVertex == 0)
		glGenVertexArrays(1, &_m_uiIdArrayVertex);
	glBindVertexArray(_m_uiIdArrayVertex);

	// Create and bind a vertex buffer object:
	if(_m_uiBufferVertex == 0)
		glGenBuffers(1, &_m_uiBufferVertex);
	glBindBuffer(GL_ARRAY_BUFFER, _m_uiBufferVertex);

	// Insert vertex data:
	glBufferData(GL_ARRAY_BUFFER, sizeof(_m_voDataFace[0][0]) * _m_voDataFace[0].size(), &_m_voDataFace[0][0], GL_STATIC_DRAW);

	return *this;
}
Model3& Model3::set_data(Model3::FormatFile const& format_file, std::string const&& name_file){
	return this->set_data(format_file, name_file);
}
Model3& Model3::set_data(Model3::FormatFile&& format_file, std::string const& name_file){
	return this->set_data(format_file, name_file);
}
Model3& Model3::set_data(Model3::FormatFile&& format_file, std::string const&& name_file){
	return this->set_data(format_file, name_file);
}
void Model3::show(void) const{
	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, _m_uiBufferVertex);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

	glEnable(GL_POINT_SMOOTH);
	glPointSize(2.0f);

	glDrawArrays(GL_TRIANGLES, 0, _m_voDataFace[0].size() + 1);
	glDisableVertexAttribArray(0);
}


I don't understand what have I done wrong. Can anybody help me?


#6Helixirr

Posted 27 January 2013 - 04:43 AM

Hi, folks!

I have tried to create a 3D model class called Model3, which will inherit from my base class Model. This Model3-class supports only Wavefront OBJ files at the moment and I'm having trouble setting up correct data for OpenGL to process. I try to get rid of the deprecated OpenGL functions and use vertex array objects and vertex buffers objects instead to accomplish my goal to display a 3D model on screen.

The problem is rather simple to describe: polygons are formed incorrectly.

This is how I see the model in Blender (in which I also did the model):
http://imageshack.us/photo/my-images/838/timg.png/

And this is what ends up looking in my program:
http://imageshack.us/photo/my-images/546/tim2i.png/

Here is Model3 class definition:

/// ---------------------------------- /// @class Model3 /// @brief Represents a 3D model. /// @typedef Model3D /// ---------------------------------- typedef class Model3 : public Model{ public: /// Enumerations: enum class FormatFile : unsigned int{ FORMATFILE_3DS, FORMATFILE_OBJ }; /// Constructors & destructors: Model3(void); Model3(Model3 const& model) = default; Model3(Model3&& model) = default; ~Model3(void); /// Member functions: Model3& set_data(Model3::FormatFile const& format_file, std::string const& name_file); Model3& set_data(Model3::FormatFile const& format_file, std::string const&& name_file); Model3& set_data(Model3::FormatFile&& format_file, std::string const& name_file); Model3& set_data(Model3::FormatFile&& format_file, std::string const&& name_file); void show(void) const; /// Member functions (overloaded operators): Model3& operator=(Model3 const& model); Model3& operator=(Model3&& model); private: /// Member data: std::vector
Here are implementations of functions set_data and show:
/// Member functions:Model3& Model3::set_data(Model3::FormatFile const& format_file, std::string const& name_file){ /* UNFINISHED! */ std::ifstream __file(name_file); // 3D model loading lambdas: auto const __load_3ds = [&](void){ /* UNFINISHED! */ }; auto const __load_obj = [&](void){ /* WORKS HALF RIGHT AND MORE FUNCTIONALITY IS REQUIRED! */ auto const __read_data_vertices = [](std::string const& string, float coordinates[], unsigned int const&& amount_elements, unsigned int&& index_begin){ // Variables used in the following for loop: // index_begin = end index for string substraction operation // __i = index of the temporary float array // __j = start index for string substraction operation for(unsigned int __i = 0, __j = index_begin; __i != amount_elements; ++__j){ if(string[__j] == ' '){ // If the "end character" for floating number is detected: coordinates[__i++] = atof(string.substr(index_begin, ++__j).c_str()); index_begin = __j; } } }; std::string __line; clock_t init = clock(); while(std::getline(__file, __line)){ // For each line in the requested file: switch(__line[0]){ // Check out the first letter of a line: case 'f':{ // Read through the whole line ignoring all the insignificant characters (like '\n'): for(unsigned int __i = 2, __j = 2, __k = 0; __j != __line.size() - 1; ++__j){ if(__line[__j] == '/'){ _m_voDataFace[__k].push_back(_m_voDataVertex[__k][atoi(__line.substr(__i, ++__j).c_str())]); __i = __j; ++__k; } else if(__line[__j] == ' '){ ++__j; __i = __j; __k = 0; } } continue; } case 'v': // If a requested line contains some sort of vertex data: if(__line[1] == ' '){ // If the requested line contains vertex coordinates: float __coordinates[3] = {0.0f}; // A temporary float array to store vertex coordinates. __read_data_vertices(__line, __coordinates, 3, 2); _m_voDataVertex[0].push_back(Helixirr::Vector3(std::move(__coordinates[0]), std::move(__coordinates[1]), std::move(__coordinates[2]))); } else if(__line[1] == 'n'){ // If the requested line contains vertex normals: float __coordinates[3] = {0.0f}; // A temporary float array to store vertex normals. __read_data_vertices(__line, __coordinates, 3, 3); _m_voDataVertex[2].push_back(Helixirr::Vector3(std::move(__coordinates[0]), std::move(__coordinates[1]), std::move(__coordinates[2]))); } else if(__line[1] == 't'){ // If the requested line contains UV coordinates: float __coordinates[2] = {0.0f}; // A temporary float array to store UV coordinates. __read_data_vertices(__line, __coordinates, 2, 3); _m_voDataVertex[1].push_back(Helixirr::Vector3(std::move(__coordinates[0]), std::move(__coordinates[1]), 0.0f)); } continue; default: continue; } } printf("OBJ file loading - elapsed time: %f\n", static_cast(clock() - init) / static_cast(CLOCKS_PER_SEC)); }; // Detect requested file format: switch(format_file){ case Model3::FormatFile::FORMATFILE_3DS: __load_3ds(); break; case Model3::FormatFile::FORMATFILE_OBJ: __load_obj(); break; default: break; } // Create and bind a vertex array: if(_m_uiIdArrayVertex == 0) glGenVertexArrays(1, &_m_uiIdArrayVertex); glBindVertexArray(_m_uiIdArrayVertex); // Create and bind a vertex buffer object: if(_m_uiBufferVertex == 0) glGenBuffers(1, &_m_uiBufferVertex); glBindBuffer(GL_ARRAY_BUFFER, _m_uiBufferVertex); // Insert vertex data: glBufferData(GL_ARRAY_BUFFER, sizeof(_m_voDataFace[0][0]) * _m_voDataFace[0].size(), &_m_voDataFace[0][0], GL_STATIC_DRAW); return *this;}Model3& Model3::set_data(Model3::FormatFile const& format_file, std::string const&& name_file){ return this->set_data(format_file, name_file);}Model3& Model3::set_data(Model3::FormatFile&& format_file, std::string const& name_file){ return this->set_data(format_file, name_file);}Model3& Model3::set_data(Model3::FormatFile&& format_file, std::string const&& name_file){ return this->set_data(format_file, name_file);}void Model3::show(void) const{ glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, _m_uiBufferVertex); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnable(GL_POINT_SMOOTH); glPointSize(2.0f); glDrawArrays(GL_TRIANGLES, 0, _m_voDataFace[0].size() + 1); glDisableVertexAttribArray(0);}

I don't understand what have I done wrong. Can anybody help me?

#5Helixirr

Posted 27 January 2013 - 04:38 AM

Hi, folks!

I have tried to create a 3D model class called Model3, which will inherit from my base class Model. This Model3-class supports only Wavefront OBJ files at the moment and I'm having trouble setting up correct data for OpenGL to process. I try to get rid of the deprecated OpenGL functions and use vertex array objects and vertex buffers objects instead to accomplish my goal to display a 3D model on screen.

The problem is rather simple to describe: polygons are formed incorrectly.

This is how I see the model in Blender (in which I also did the model):
http://imageshack.us/photo/my-images/838/timg.png/

And this is what ends up looking in my program:
http://imageshack.us/photo/my-images/546/tim2i.png/

 

Here is Model3 class definition:

/// ----------------------------------
    /// @class  	Model3
    /// @brief  	Represents a 3D model.
	/// @typedef	Model3D
    /// ----------------------------------
    typedef class Model3 : public Model{
    public:

		/// Enumerations:
		enum class FormatFile : unsigned int{
			FORMATFILE_3DS,
			FORMATFILE_OBJ
		};

        /// Constructors & destructors:
        Model3(void);
        Model3(Model3 const& model) = default;
        Model3(Model3&& model) = default;
		~Model3(void);

		/// Member functions:
		Model3& set_data(Model3::FormatFile const& format_file, std::string const& name_file);
		Model3& set_data(Model3::FormatFile const& format_file, std::string const&& name_file);
		Model3& set_data(Model3::FormatFile&& format_file, std::string const& name_file);
		Model3& set_data(Model3::FormatFile&& format_file, std::string const&& name_file);
		void show(void) const;

		/// Member functions (overloaded operators):
		Model3& operator=(Model3 const& model);
		Model3& operator=(Model3&& model);

    private:
        /// Member data:
		std::vector<Helixirr::Vector3<float>> _m_voDataFace[3]; // Element 0 contains vertex coordinates, element 1 contains texture coordinates, element 2 contains vertex normals.
		std::vector<Helixirr::Vector3<float>> _m_voDataVertex[3]; // Element 0 contains vertex coordinates, element 1 contains texture coordinates, element 2 contains vertex normals.
		unsigned int _m_uiIdArrayVertex, _m_uiBufferVertex;
	}Model3D;


Here are implementations of functions show:

/// Member functions:
Model3& Model3::set_data(Model3::FormatFile const& format_file, std::string const& name_file){ /* UNFINISHED! */
	std::ifstream __file(name_file);

	// 3D model loading lambdas:
	auto const __load_3ds = [&](void){
		/* UNFINISHED! */
	};
	auto const __load_obj = [&](void){ /* WORKS HALF RIGHT AND MORE FUNCTIONALITY IS REQUIRED! */
		auto const __read_data_vertices = [](std::string const& string, float coordinates[], unsigned int const&& amount_elements, unsigned int&& index_begin){
			// Variables used in the following for loop:
			// index_begin = end index for string substraction operation
			// __i = index of the temporary float array
			// __j = start index for string substraction operation
			for(unsigned int __i = 0, __j = index_begin; __i != amount_elements; ++__j){
				if(string[__j] == ' '){ // If the "end character" for floating number is detected:
					coordinates[__i++] = atof(string.substr(index_begin, ++__j).c_str());
					index_begin = __j;
				}
			}
		};

		std::string __line;
		clock_t init = clock();
		while(std::getline(__file, __line)){ // For each line in the requested file:
			switch(__line[0]){ // Check out the first letter of a line:
				case 'f':{
					// Read through the whole line ignoring all the insignificant characters (like '\n'):
					for(unsigned int __i = 2, __j = 2, __k = 0; __j != __line.size() - 1; ++__j){
						if(__line[__j] == '/'){
							_m_voDataFace[__k].push_back(_m_voDataVertex[__k][atoi(__line.substr(__i, ++__j).c_str())]);
							__i = __j;
							++__k;
						}
						else if(__line[__j] == ' '){
							++__j;
							__i = __j;
							__k = 0;
						}
					}
					continue;
				}
				case 'v': // If a requested line contains some sort of vertex data:
					if(__line[1] == ' '){ // If the requested line contains vertex coordinates:
						float __coordinates[3] = {0.0f}; // A temporary float array to store vertex coordinates.
						__read_data_vertices(__line, __coordinates, 3, 2);
						_m_voDataVertex[0].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), std::move(__coordinates[2])));
					}
					else if(__line[1] == 'n'){ // If the requested line contains vertex normals:
						float __coordinates[3] = {0.0f}; // A temporary float array to store vertex normals.
						__read_data_vertices(__line, __coordinates, 3, 3);
						_m_voDataVertex[2].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), std::move(__coordinates[2])));
					}
					else if(__line[1] == 't'){ // If the requested line contains UV coordinates:
						float __coordinates[2] = {0.0f}; // A temporary float array to store UV coordinates.
						__read_data_vertices(__line, __coordinates, 2, 3);
						_m_voDataVertex[1].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), 0.0f));
					}
					continue;
				default:
					continue;
			}
		}
		printf("OBJ file loading - elapsed time: %f\n", static_cast<double>(clock() - init) / static_cast<double>(CLOCKS_PER_SEC));
	};

	// Detect requested file format:
	switch(format_file){
		case Model3::FormatFile::FORMATFILE_3DS:
			__load_3ds();
			break;
		case Model3::FormatFile::FORMATFILE_OBJ:
			__load_obj();
			break;
		default:
			break;
	}

	// Create and bind a vertex array:
	if(_m_uiIdArrayVertex == 0)
		glGenVertexArrays(1, &_m_uiIdArrayVertex);
	glBindVertexArray(_m_uiIdArrayVertex);

	// Create and bind a vertex buffer object:
	if(_m_uiBufferVertex == 0)
		glGenBuffers(1, &_m_uiBufferVertex);
	glBindBuffer(GL_ARRAY_BUFFER, _m_uiBufferVertex);

	// Insert vertex data:
	glBufferData(GL_ARRAY_BUFFER, sizeof(_m_voDataFace[0][0]) * _m_voDataFace[0].size(), &_m_voDataFace[0][0], GL_STATIC_DRAW);

	return *this;
}
Model3& Model3::set_data(Model3::FormatFile const& format_file, std::string const&& name_file){
	return this->set_data(format_file, name_file);
}
Model3& Model3::set_data(Model3::FormatFile&& format_file, std::string const& name_file){
	return this->set_data(format_file, name_file);
}
Model3& Model3::set_data(Model3::FormatFile&& format_file, std::string const&& name_file){
	return this->set_data(format_file, name_file);
}
void Model3::show(void) const{
	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, _m_uiBufferVertex);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

	glEnable(GL_POINT_SMOOTH);
	glPointSize(2.0f);

	glDrawArrays(GL_TRIANGLES, 0, _m_voDataFace[0].size() + 1);
	glDisableVertexAttribArray(0);
}

I don't understand what have I done wrong. Can anybody help me?

#4Helixirr

Posted 27 January 2013 - 04:36 AM

Hi, folks!

I have tried to create a 3D model class called Model3, which will inherit from my base class Model. This Model3-class supports only Wavefront OBJ files at the moment and I'm having trouble setting up correct data for OpenGL to process. I try to get rid of the deprecated OpenGL functions and use vertex array objects and vertex buffers objects instead to accomplish my goal to display a 3D model on screen.

The problem is rather simple to describe: polygons are formed incorrectly.

This is how I see the model in Blender (in which I also did the model):
http://imageshack.us/photo/my-images/838/timg.png/

And this is what ends up looking in my program:
http://imageshack.us/photo/my-images/546/tim2i.png/
 

Here are implementations of functions set_data and show:

/// Member functions:
Model3& Model3::set_data(Model3::FormatFile const& format_file, std::string const& name_file){ /* UNFINISHED! */
	std::ifstream __file(name_file);

	// 3D model loading lambdas:
	auto const __load_3ds = [&](void){
		/* UNFINISHED! */
	};
	auto const __load_obj = [&](void){ /* WORKS HALF RIGHT AND MORE FUNCTIONALITY IS REQUIRED! */
		auto const __read_data_vertices = [](std::string const& string, float coordinates[], unsigned int const&& amount_elements, unsigned int&& index_begin){
			// Variables used in the following for loop:
			// index_begin = end index for string substraction operation
			// __i = index of the temporary float array
			// __j = start index for string substraction operation
			for(unsigned int __i = 0, __j = index_begin; __i != amount_elements; ++__j){
				if(string[__j] == ' '){ // If the "end character" for floating number is detected:
					coordinates[__i++] = atof(string.substr(index_begin, ++__j).c_str());
					index_begin = __j;
				}
			}
		};

		std::string __line;
		clock_t init = clock();
		while(std::getline(__file, __line)){ // For each line in the requested file:
			switch(__line[0]){ // Check out the first letter of a line:
				case 'f':{
					// Read through the whole line ignoring all the insignificant characters (like '\n'):
					for(unsigned int __i = 2, __j = 2, __k = 0; __j != __line.size() - 1; ++__j){
						if(__line[__j] == '/'){
							_m_voDataFace[__k].push_back(_m_voDataVertex[__k][atoi(__line.substr(__i, ++__j).c_str())]);
							__i = __j;
							++__k;
						}
						else if(__line[__j] == ' '){
							++__j;
							__i = __j;
							__k = 0;
						}
					}
					continue;
				}
				case 'v': // If a requested line contains some sort of vertex data:
					if(__line[1] == ' '){ // If the requested line contains vertex coordinates:
						float __coordinates[3] = {0.0f}; // A temporary float array to store vertex coordinates.
						__read_data_vertices(__line, __coordinates, 3, 2);
						_m_voDataVertex[0].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), std::move(__coordinates[2])));
					}
					else if(__line[1] == 'n'){ // If the requested line contains vertex normals:
						float __coordinates[3] = {0.0f}; // A temporary float array to store vertex normals.
						__read_data_vertices(__line, __coordinates, 3, 3);
						_m_voDataVertex[2].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), std::move(__coordinates[2])));
					}
					else if(__line[1] == 't'){ // If the requested line contains UV coordinates:
						float __coordinates[2] = {0.0f}; // A temporary float array to store UV coordinates.
						__read_data_vertices(__line, __coordinates, 2, 3);
						_m_voDataVertex[1].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), 0.0f));
					}
					continue;
				default:
					continue;
			}
		}
		printf("OBJ file loading - elapsed time: %f\n", static_cast<double>(clock() - init) / static_cast<double>(CLOCKS_PER_SEC));
	};

	// Detect requested file format:
	switch(format_file){
		case Model3::FormatFile::FORMATFILE_3DS:
			__load_3ds();
			break;
		case Model3::FormatFile::FORMATFILE_OBJ:
			__load_obj();
			break;
		default:
			break;
	}

	// Create and bind a vertex array:
	if(_m_uiIdArrayVertex == 0)
		glGenVertexArrays(1, &_m_uiIdArrayVertex);
	glBindVertexArray(_m_uiIdArrayVertex);

	// Create and bind a vertex buffer object:
	if(_m_uiBufferVertex == 0)
		glGenBuffers(1, &_m_uiBufferVertex);
	glBindBuffer(GL_ARRAY_BUFFER, _m_uiBufferVertex);

	// Insert vertex data:
	glBufferData(GL_ARRAY_BUFFER, sizeof(_m_voDataFace[0][0]) * _m_voDataFace[0].size(), &_m_voDataFace[0][0], GL_STATIC_DRAW);

	return *this;
}
Model3& Model3::set_data(Model3::FormatFile const& format_file, std::string const&& name_file){
	return this->set_data(format_file, name_file);
}
Model3& Model3::set_data(Model3::FormatFile&& format_file, std::string const& name_file){
	return this->set_data(format_file, name_file);
}
Model3& Model3::set_data(Model3::FormatFile&& format_file, std::string const&& name_file){
	return this->set_data(format_file, name_file);
}
void Model3::show(void) const{
	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER, _m_uiBufferVertex);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

	glEnable(GL_POINT_SMOOTH);
	glPointSize(2.0f);

	glDrawArrays(GL_TRIANGLES, 0, _m_voDataFace[0].size() + 1); // Draw points/vertices only.
	glDisableVertexAttribArray(0);
}


I don't understand what have I done wrong. Can anybody help me?


#3Helixirr

Posted 27 January 2013 - 04:30 AM

Hi, folks! smile.png

I have tried to create a 3D model class called Model3, which will inherit from my base class Model. This Model3-class supports only Wavefront OBJ files at the moment and I'm having trouble setting up correct data for OpenGL to process. I try to get rid of the deprecated OpenGL functions and use vertex array objects and vertex buffers objects instead to accomplish my goal to display a 3D model on screen.

The problem is rather simple to describe: polygons are formed incorrectly.

This is how I see the model in Blender (in which I also did the model):
http://imageshack.us/photo/my-images/838/timg.png/

And this is what ends up looking in my program:
http://imageshack.us/photo/my-images/546/tim2i.png/

Here is my set_data-function:
Model3& Model3::set_data(Model3::FormatFile const& format_file, std::string const& name_file){ /* UNFINISHED! */	std::ifstream __file(name_file);	// 3D model loading lambdas:	auto const __load_3ds = [&](void){		/* UNFINISHED! */	};	auto const __load_obj = [&](void){ /* WORKS HALF RIGHT AND MORE FUNCTIONALITY IS REQUIRED! */		auto const __read_data_vertices = [](std::string const& string, float coordinates[], unsigned int const&& amount_elements, unsigned int&& index_begin){			// Variables used in the following for loop:			// index_begin = end index for string substraction operation			// __i = index of the temporary float array			// __j = start index for string substraction operation			for(unsigned int __i = 0, __j = index_begin; __i != amount_elements; ++__j){				if(string[__j] == ' '){ // If the "end character" for floating number is detected:					coordinates[__i++] = atof(string.substr(index_begin, ++__j).c_str());					index_begin = __j;				}			}		};		std::string __line;		clock_t init = clock();		while(std::getline(__file, __line)){ // For each line in the requested file:			switch(__line[0]){ // Check out the first letter of a line:				case 'f':{					// Read through the whole line ignoring all the insignificant characters (like '\n'):					for(unsigned int __i = 2, __j = 2, __k = 0; __j != __line.size() - 1; ++__j){						if(__line[__j] == '/'){							_m_voDataFace[__k].push_back(_m_voDataVertex[__k][atoi(__line.substr(__i, ++__j).c_str())]);							__i = __j;							++__k;						}						else if(__line[__j] == ' '){							++__j;							__i = __j;							__k = 0;						}					}					continue;				}				case 'v': // If a requested line contains some sort of vertex data:					if(__line[1] == ' '){ // If the requested line contains vertex coordinates:						float __coordinates[3] = {0.0f}; // A temporary float array to store vertex coordinates.						__read_data_vertices(__line, __coordinates, 3, 2);						_m_voDataVertex[0].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), std::move(__coordinates[2])));					}					else if(__line[1] == 'n'){ // If the requested line contains vertex normals:						float __coordinates[3] = {0.0f}; // A temporary float array to store vertex normals.						__read_data_vertices(__line, __coordinates, 3, 3);						_m_voDataVertex[2].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), std::move(__coordinates[2])));					}					else if(__line[1] == 't'){ // If the requested line contains UV coordinates:						float __coordinates[2] = {0.0f}; // A temporary float array to store UV coordinates.						__read_data_vertices(__line, __coordinates, 2, 3);						_m_voDataVertex[1].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), 0.0f));					}					continue;				default:					continue;			}		}		printf("OBJ file loading - elapsed time: %f\n", static_cast<double>(clock() - init) / static_cast<double>(CLOCKS_PER_SEC));	};	// Detect requested file format:	switch(format_file){		case Model3::FormatFile::FORMATFILE_3DS:			__load_3ds();			break;		case Model3::FormatFile::FORMATFILE_OBJ:			__load_obj();			break;		default:			break;	}	// Create and bind a vertex array:	if(_m_uiIdArrayVertex == 0)		glGenVertexArrays(1, &_m_uiIdArrayVertex);	glBindVertexArray(_m_uiIdArrayVertex);	// Create and bind a vertex buffer object:	if(_m_uiBufferVertex == 0)		glGenBuffers(1, &_m_uiBufferVertex);	glBindBuffer(GL_ARRAY_BUFFER, _m_uiBufferVertex);	// Insert vertex data:	glBufferData(GL_ARRAY_BUFFER, sizeof(_m_voDataFace[0][0]) * _m_voDataFace[0].size(), &_m_voDataFace[0][0], GL_STATIC_DRAW);	return *this;}

And here is my show-function:
void Model3::show(void) const{	glEnableVertexAttribArray(0);	glBindBuffer(GL_ARRAY_BUFFER, _m_uiBufferVertex);	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);	glEnable(GL_POINT_SMOOTH);	glPointSize(2.0f);	glDrawArrays(GL_TRIANGLES, 0, _m_voDataFace[0].size() + 1);	glDisableVertexAttribArray(0);}

I don't understand what have I done wrong. Can anybody help me? sad.png

#2Helixirr

Posted 27 January 2013 - 04:30 AM

Hi, folks! smile.png

I have tried to create a 3D model class called Model3, which will inherit from my base class Model. This Model3-class supports only Wavefront OBJ files at the moment and I'm having trouble setting up correct data for OpenGL to process. I try to get rid of the deprecated OpenGL functions and use vertex array objects and vertex buffers objects instead to accomplish my goal to display a 3D model on screen.

The problem is rather simple to describe: polygons are formed incorrectly.

This is how I see the model in Blender (in which I also did the model):
http://imageshack.us/photo/my-images/838/timg.png/

And this is what ends up looking in my program:
http://imageshack.us/photo/my-images/546/tim2i.png/

Here is my set_data-function:
Model3& Model3::set_data(Model3::FormatFile const& format_file, std::string const& name_file){ /* UNFINISHED! */	std::ifstream __file(name_file);	// 3D model loading lambdas:	auto const __load_3ds = [&](void){		/* UNFINISHED! */	};	auto const __load_obj = [&](void){ /* WORKS HALF RIGHT AND MORE FUNCTIONALITY IS REQUIRED! */		auto const __read_data_vertices = [](std::string const& string, float coordinates[], unsigned int const&& amount_elements, unsigned int&& index_begin){			// Variables used in the following for loop:			// index_begin = end index for string substraction operation			// __i = index of the temporary float array			// __j = start index for string substraction operation			for(unsigned int __i = 0, __j = index_begin; __i != amount_elements; ++__j){				if(string[__j] == ' '){ // If the "end character" for floating number is detected:					coordinates[__i++] = atof(string.substr(index_begin, ++__j).c_str());					index_begin = __j;				}			}		};		std::string __line;		clock_t init = clock();		while(std::getline(__file, __line)){ // For each line in the requested file:			switch(__line[0]){ // Check out the first letter of a line:				case 'f':{					// Read through the whole line ignoring all the insignificant characters (like '\n'):					for(unsigned int __i = 2, __j = 2, __k = 0; __j != __line.size() - 1; ++__j){						if(__line[__j] == '/'){							_m_voDataFace[__k].push_back(_m_voDataVertex[__k][atoi(__line.substr(__i, ++__j).c_str())]);							__i = __j;							++__k;						}						else if(__line[__j] == ' '){							++__j;							__i = __j;							__k = 0;						}					}					continue;				}				case 'v': // If a requested line contains some sort of vertex data:					if(__line[1] == ' '){ // If the requested line contains vertex coordinates:						float __coordinates[3] = {0.0f}; // A temporary float array to store vertex coordinates.						__read_data_vertices(__line, __coordinates, 3, 2);						_m_voDataVertex[0].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), std::move(__coordinates[2])));					}					else if(__line[1] == 'n'){ // If the requested line contains vertex normals:						float __coordinates[3] = {0.0f}; // A temporary float array to store vertex normals.						__read_data_vertices(__line, __coordinates, 3, 3);						_m_voDataVertex[2].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), std::move(__coordinates[2])));					}					else if(__line[1] == 't'){ // If the requested line contains UV coordinates:						float __coordinates[2] = {0.0f}; // A temporary float array to store UV coordinates.						__read_data_vertices(__line, __coordinates, 2, 3);						_m_voDataVertex[1].push_back(Helixirr::Vector3<float>(std::move(__coordinates[0]), std::move(__coordinates[1]), 0.0f));					}					continue;				default:					continue;			}		}		printf("OBJ file loading - elapsed time: %f\n", static_cast<double>(clock() - init) / static_cast<double>(CLOCKS_PER_SEC));	};	// Detect requested file format:	switch(format_file){		case Model3::FormatFile::FORMATFILE_3DS:			__load_3ds();			break;		case Model3::FormatFile::FORMATFILE_OBJ:			__load_obj();			break;		default:			break;	}	// Create and bind a vertex array:	if(_m_uiIdArrayVertex == 0)		glGenVertexArrays(1, &_m_uiIdArrayVertex);	glBindVertexArray(_m_uiIdArrayVertex);	// Create and bind a vertex buffer object:	if(_m_uiBufferVertex == 0)		glGenBuffers(1, &_m_uiBufferVertex);	glBindBuffer(GL_ARRAY_BUFFER, _m_uiBufferVertex);	// Insert vertex data:	glBufferData(GL_ARRAY_BUFFER, sizeof(_m_voDataFace[0][0]) * _m_voDataFace[0].size(), &_m_voDataFace[0][0], GL_STATIC_DRAW);	return *this;}

And here is my show-function:
void Model3::show(void) const{	glEnableVertexAttribArray(0);	glBindBuffer(GL_ARRAY_BUFFER, _m_uiBufferVertex);	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);	glEnable(GL_POINT_SMOOTH);	glPointSize(2.0f);	glDrawArrays(GL_TRIANGLES, 0, _m_voDataFace[0].size() + 1);	glDisableVertexAttribArray(0);}

I don't understand what have I done wrong. Can anybody help me? sad.png

PARTNERS