Skip to main content
gamedev.net
🔒 Locked

doubt using glDrawElements

Started by FreJa 7 replies 850+ views
Original Post
FreJa
FreJa
Hi, This is how my model class looks:

struct vertex_s
{
	vertex_s(vector<double> position)
	: _position(position) {}
		
	vector<double> _position;
};
	
struct face_s
{
	face_s(vector<unsigned int> vertIndex)
	: _vertIndex(vertIndex) {}
		
	vector<unsigned int> _vertIndex;
};


class Model
{
       ...
       vector<face_s> _faces;
       vector<vertex_s> _verts;
       ...
};
My question is what should be the parameters for the glVertexPointer and glDrawElements functions...? Thanks!
"Through me the road to the city of desolation,Through me the road to sorrows diuturnal,Through me the road among the lost creation."
Zakwayda
Zakwayda
Your data is not currently in a form that OpenGL will able to process directly (as far as I can tell, at least), so you'll need to either modify the format, or store additional data in your model class that is in a format OpenGL can work with.

(Note: I'm not that familiar with VBOs, but I assume that they're similar to vertex arrays with respect to the data format/layout that they expect.)

OpenGL expects its vertex data in the form of a contiguous array, with, optionally, additional bytes of padding between individual entries. If you look at the parameters for glVertexPointer(), you can see how all this is specified.

Your vertex data is currently in the form of a 'vector of vectors'. This will not meet OpenGL's requirements, since the data is not contiguous, and it does not only consist of vertex data (the data that is actually part of the contiguous array is member data of the vector class, which means nothing to OpenGL).

What you'll probably want to do (for this and other reasons) is to use a representation other than a vector<double> for your individual vertices. A common solution is to create a simple struct or class with x, y, and z member variables, or perhaps an array of 3 floats or doubles. (I recommend using an array, which will guarantee that the individual elements of the vertex are contiguous.)

Putting all this together, you can submit the data to OpenGL as follows:
struct Vertex { float v[3]; }std::vector<Vertex> verts;// ...glVertexPointer(..., &verts.front().v[0]);
Or something similar.

I won't go into detail here, but you'll need to do something similar with your index data in order for OpenGL to make sense of (for more or less the same reasons discussed above).

Post back if you have further questions.
FreJa
FreJa
Thanks!
So this is how my class is looking right now:

struct vertex_s	{		vertex_s(double posX, double posY, double posZ)		{			_position[0] = posX;			_position[1] = posY;			_position[2] = posZ;		}				double _position[3];	};		struct face_s	{		face_s(unsigned int indA, unsigned int indB, unsigned int indC)		{			_vertIndex[0] = indA;			_vertIndex[1] = indB;			_vertIndex[2] = indC;		}				unsigned int _vertIndex[3];	};class Model{          ...       vector<vertex_s> _verts;       vector<face_s> _faces;    ...};



This is how I'm loading the vertex array:
glVertexPointer(3, GL_DOUBLE, 0, &_verts[0]._position);



And this is how I'm drawing:
glDrawElements(GL_TRIANGLES, _numFaces*3, GL_UNSIGNED_INT, &_faces[0]._vertIndex);



And this is the result:



Poor tux is full of holes... what could be wrong?


Thanks!
"Through me the road to the city of desolation,Through me the road to sorrows diuturnal,Through me the road among the lost creation."
Zakwayda
Zakwayda
Try disabling face culling and see if the problem goes away. If so, your face windings are probably inconsistent.
FreJa
FreJa
Quote:
Original post by jyk
Try disabling face culling and see if the problem goes away. If so, your face windings are probably inconsistent.


It improves a little bit... which means there's probably something wrong with the way I'm reading the 3d model file. The file is similar to the .obj format, but does not support normals or texcoords.
This is the code I'm using:

bool Object::processLine(istream &is){	string el;			if(!(is >> el))		return false;			if(el == "f")	{		unsigned int indices[3];		is >> indices[0] >> indices[1] >> indices[2];		_faces.push_back(face_s(indices[0], indices[1], indices[2]));		_numFaces++;	}	else if(el == "v")	{		double pos[3];		is >> pos[0] >> pos[1] >> pos[2];		_verts.push_back(vertex_s(pos[0], pos[1], pos[2]));		_numVerts++;	}}


Does anyone see anything wrong with this code?


Thanks again!
"Through me the road to the city of desolation,Through me the road to sorrows diuturnal,Through me the road among the lost creation."
swiftcoder
swiftcoder
Quote:
Original post by FreJa
	if(el == "f")	{		unsigned int indices[3];		is >> indices[0] >> indices[1] >> indices[2];		_faces.push_back(face_s(indices[0], indices[1], indices[2]));		_numFaces++;	}

Does anyone see anything wrong with this code?
Indices in OBJ start at 1, rather than 0, so make sure that when you use those indices, you subtract 1 from them - or better yet, subtract 1 from the right away, as you put them in the array.
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
Zakwayda
Zakwayda
Are you sure all faces in the model file have exactly three vertices? (I know some formats allow faces with four vertices, or with arbitrary numbers of vertices.)
FreJa
FreJa
I am subtracting one to the vertex index already.
Yes, I am sure they have exactly three vertices.
"Through me the road to the city of desolation,Through me the road to sorrows diuturnal,Through me the road among the lost creation."
FreJa
FreJa
Quote:
Original post by jyk
Are you sure all faces in the model file have exactly three vertices? (I know some formats allow faces with four vertices, or with arbitrary numbers of vertices.)


Oops, you were right after all... I glanced at the obj and I saw some faces with 3 vertices, but apparently others had 4. Turned on triangulation on my 3d modeling app and all is fine now!

Thanks for all the help!
"Through me the road to the city of desolation,Through me the road to sorrows diuturnal,Through me the road among the lost creation."

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.