Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

daimj69

Quick Vertex Array Question

This topic is 5158 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi. I''ve created a room with a number of objects, which are made up of Quads. I''ve heard that Vertex Arrays can be used as a more efficient way to draw shapes, objects etc. The following code creates a simple table with two legs:
//WORK TABLE.

	//TOP.

	glBegin(GL_QUADS);
		//Front.

		glNormal3f(0.0,0.0,1.0);
		glTexCoord2f(0.5,0.5);glVertex3f(0.0,1.0,-2.11);
		glTexCoord2f(0.0,0.5);glVertex3f(-2.1,1.0,-2.11);
		glTexCoord2f(0.0,0.0);glVertex3f(-2.1,0.8,-2.11);
		glTexCoord2f(0.5,0.0);glVertex3f(0.0,0.8,-2.11);
		//Left.

		glNormal3f(-1.0,0.0,0.0);
		glTexCoord2f(0.5,0.5);glVertex3f(-2.1,1.0,-2.11);
		glTexCoord2f(0.0,0.5);glVertex3f(-2.1,1.0,-3.0);
		glTexCoord2f(0.0,0.0);glVertex3f(-2.1,0.8,-3.0);
		glTexCoord2f(0.5,0.0);glVertex3f(-2.1,0.8,-2.11);
		//Right.

		glNormal3f(1.0,0.0,0.0);
		glTexCoord2f(0.5,0.5);glVertex3f(0.0,1.0,-3.0);
		glTexCoord2f(0.0,0.5);glVertex3f(0.0,1.0,-2.11);
		glTexCoord2f(0.0,0.0);glVertex3f(0.0,0.8,-2.11);
		glTexCoord2f(0.5,0.0);glVertex3f(0.0,0.8,-3.0);
		//Bottom.

		glNormal3f(0.0,-1.0,0.0);
		glTexCoord2f(1.0,1.0);glVertex3f(0.0,0.8,-2.11);
		glTexCoord2f(0.0,1.0);glVertex3f(-2.1,0.8,-2.11);
		glTexCoord2f(0.0,0.0);glVertex3f(-2.1,0.8,-3.0);
		glTexCoord2f(1.0,0.0);glVertex3f(0.0,0.8,-3.0);
		//Top.

		glNormal3f(0.0,1.0,0.0);
		glTexCoord2f(1.0,1.0);glVertex3f(0.0,1.0,-3.0);
		glTexCoord2f(0.0,1.0);glVertex3f(-2.1,1.0,-3.0);
		glTexCoord2f(0.0,0.0);glVertex3f(-2.1,1.0,-2.11);
		glTexCoord2f(1.0,0.0);glVertex3f(0.0,1.0,-2.11);
	glEnd();
	//LEFT LEG.

	glBegin(GL_QUADS);
		//Front.

		glNormal3f(0.0,0.0,1.0);
		glTexCoord2f(0.5,0.5);glVertex3f(-0.1,0.8,-2.21);
		glTexCoord2f(0.0,0.5);glVertex3f(-0.3,0.8,-2.21);
		glTexCoord2f(0.0,0.0);glVertex3f(-0.3,0.0,-2.21);
		glTexCoord2f(0.5,0.0);glVertex3f(-0.1,0.0,-2.21);
		//Left.

		glNormal3f(-1.0,0.0,0.0);
		glTexCoord2f(1.0,1.0);glVertex3f(-0.3,0.8,-2.21);
		glTexCoord2f(0.0,1.0);glVertex3f(-0.3,0.8,-2.9);
		glTexCoord2f(0.0,0.0);glVertex3f(-0.3,0.0,-2.9);
		glTexCoord2f(1.0,0.0);glVertex3f(-0.3,0.0,-2.21);
		//Right.

		glNormal3f(1.0,0.0,0.0);
		glTexCoord2f(1.0,1.0);glVertex3f(-0.1,0.8,-2.9);
		glTexCoord2f(0.0,1.0);glVertex3f(-0.1,0.8,-2.21);
		glTexCoord2f(0.0,0.0);glVertex3f(-0.1,0.0,-2.21);
		glTexCoord2f(1.0,0.0);glVertex3f(-0.1,0.0,-2.9);
		//Back.

		glNormal3f(0.0,0.0,-1.0);
		glTexCoord2f(0.5,0.5);glVertex3f(-0.3,0.8,-2.9);
		glTexCoord2f(0.0,0.5);glVertex3f(-0.1,0.8,-2.9);
		glTexCoord2f(0.0,0.0);glVertex3f(-0.1,0.0,-2.9);
		glTexCoord2f(0.5,0.0);glVertex3f(-0.3,0.0,-2.9);
	glEnd();
	//RIGHT LEG.

	glBegin(GL_QUADS);
		//Front.

		glNormal3f(0.0,0.0,1.0);
		glTexCoord2f(0.5,0.5);glVertex3f(-1.8,0.8,-2.21);
		glTexCoord2f(0.0,0.5);glVertex3f(-2.0,0.8,-2.21);
		glTexCoord2f(0.0,0.0);glVertex3f(-2.0,0.0,-2.21);
		glTexCoord2f(0.5,0.0);glVertex3f(-1.8,0.0,-2.21);
		//Left.

		glNormal3f(-1.0,0.0,0.0);
		glTexCoord2f(1.0,1.0);glVertex3f(-2.0,0.8,-2.21);
		glTexCoord2f(0.0,1.0);glVertex3f(-2.0,0.8,-2.9);
		glTexCoord2f(0.0,0.0);glVertex3f(-2.0,0.0,-2.9);
		glTexCoord2f(1.0,0.0);glVertex3f(-2.0,0.0,-2.21);
		//Right.

		glNormal3f(1.0,0.0,0.0);
		glTexCoord2f(1.0,1.0);glVertex3f(-1.8,0.8,-2.9);
		glTexCoord2f(0.0,1.0);glVertex3f(-1.8,0.8,-2.21);
		glTexCoord2f(0.0,0.0);glVertex3f(-1.8,0.0,-2.21);
		glTexCoord2f(1.0,0.0);glVertex3f(-1.8,0.0,-2.9);
		//Back.

		glNormal3f(0.0,0.0,-1.0);
		glTexCoord2f(0.5,0.5);glVertex3f(-2.0,0.8,-2.9);
		glTexCoord2f(0.0,0.5);glVertex3f(-1.8,0.8,-2.9);
		glTexCoord2f(0.0,0.0);glVertex3f(-1.8,0.0,-2.9);
		glTexCoord2f(0.5,0.0);glVertex3f(-2.0,0.0,-2.9);
	glEnd();
Similar code is used to generate all objects in my scene, a picture of which can be seen at http://www.btinternet.com/~daimj69/images/3droom.jpg. I was wondering if someone could be kind enough to quickly explain how I would, for example, draw the top of the table, applying the normal and the texture co-ords using the Vertex Array method. Once I get an idea, i''m sure I can convert my entire program to use this method. Thanks in advance, appreciate it. Dai.

Share this post


Link to post
Share on other sites
Advertisement
When using vertex arrays, all of your geometry is managed as arrays of data, rather than separate glVertex()-type immediate-mode calls. You can specify vertex data as either aggregate (all vertex elements contained in a structure), or as separate arrays for each component (an array of float for normal, an array of float for vertex, an array of float for texture, etc...).

OpenGL provides functions for specifying the data sources: glTexCoordPointer(), glVertexPointer(), glColorPointer(), glNormalPointer(), etc... Each of these functions accepts data describing the size of each element (for instance, 3 for a vertex that has x,y,z components), a constant describing the data format of each element (GL_SHORT, GL_FLOAT, etc...), and a pointer to the array holding the component data. They also accept a parameter called stride, which tells OpenGL the offset between consecutive elements. This stride is used for incrementing from one element to the next, to the next, etc... and is useful for when the vertex data is packed into a struct, rather than in separate arrays. In an implementation where the data is in a struct, the stride is the size in bytes of the struct. In an implementation where the components are in separate arrays, the stride is usually 0.

You can also use glInterleavedArrays() to forego having to set sources for each element. glInterleavedArrays() will take a pointer to vertex data in struct form, and an identifier telling OpenGL what format the vertex data is in, using common formats. For instance, GL_V2F would indicate vertex data in the form of 2 floats. GL_T2F_N3F_V3F would indicate an array of vertex structures where each vertex has 2 floats for texture coords, 3 floats for the normal, and 3 floats for the vertex.

To use vertex arrays, you need to setup your array(s) of vertex data components. As an example, you might setup your table like this:

struct VertexStruct
{
float u,v; // Tex coords

float nx,ny,nz; // Normal

float x,y,z; // Vertex

};

VertexStruct Table[NUM_VERTS_IN_TABLE]=
{
{ 0.5,0.5, 0.0,0.0,1.0, 0.0,1.0,-2.11 },
{ 0.0,0.5, 0.0,0.0,1.0, -2.1,1.0,-2.11 },
{ 0.0,0.0, 0.0,0.0,1.0, -2.1,0.8,-2.11 },
.
.
.
};

Each vertex in the mesh has it''s own entry in the Table[] array, with texcoord, normal and vertex information. Then, you set your sources:

glInterleavedArrays(GL_T2F_N3F_V3F, 0, Table);

Now, you can draw the mesh with a single call:

glDrawArrays(GL_QUADS, 0, NUM_VERTS_IN_TABLE-1);

This call will use the vertex data specified by glInterleavedArrays() (or by glVertexPointer() and friends, if you use them instead) and loop through it starting at index 0, drawing quads. Mesh data can be drawn in a number of ways, really. glDrawArrays() specifies an index into the arrays, and draws a number of vertices starting from the offset. glDrawElements() will accept a separate array of indices into the vertex arrays, and iterate through that separate array. For each element, the vertex index is taken from the array, and that vertex is drawn from the vertex arrays. This allows you to build complex meshes, where a certain vertex can be shared by multiple faces. The vertex is included once in the component arrays, but in the index array it is specified multiple times, whenever it needs to be used.

The beauty of using arrays rather than lists of separate glVertex() type calls as you are presently doing is that it allows you to load vertex data, for instance from a file, and feed it to OpenGL in big chunks. Just rapidly fill an array with loaded from file, then use glInterleavedArrays() to set the source and draw. Mesh data isn''t hard-coded into the program, and can be drawn very rapidly in chunks by OpenGL.

I hope I didn''t confuse you too badly...


Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!