Vertex Array problem

Started by
33 comments, last by azjerei 19 years, 2 months ago
basically indices are just an array of numbers which tell OpenGL which bit of vertex data to use, so if you had a triangle on screen with 3 verts the indices would be 0,1,2.

The Red Book has a good explination of how it all works infact.
Advertisement
Yes, I managed to figure that out. I do even save them in the level file format I am using, though I did not use the term "indices" for that list.

However.. I put that in, but whenever I have the indice assignment activated, I get a strange crashing error when loading textures.. with it disabled, the game runs fine, though without indices and thus no landscape... Blargh.. :)
Nevermind, found the error. Now it loads correctly. But.. I see nothing of the landscape (as compared to prior this, when I at least saw something that resembled polygons). Here follows the new code I have:

Loading of indices. I have stored the indices in the level format file, and when I read the number of faces (which is equivalent to (number of indices / 3), I assign the "indice" list of this object the correct size.
// Read face number for this object and allocate memory.} else if (!strcmp(strWord, MIS_NUM_FACES)) {	fscanf(m_FilePointer, " %d", &pObject->numOfFaces);	pObject->pFaces = new tFace [pObject->numOfFaces];	// Create the indice list.	pObject->indices = new int [pObject->numOfFaces * 3];


Next, filling in the indice list for this object. It reads the values from the file (they are stored correctly, did multiple tests) and puts them in the indice list.
// Read object faces.} else if (!strcmp(strWord, MIS_FACE)) {	fscanf(m_FilePointer, " %d", &indx);	fscanf(m_FilePointer, " %d %d %d",		&(pObject->pFaces[indx].vertIndex[0]),		&(pObject->pFaces[indx].vertIndex[1]),		&(pObject->pFaces[indx].vertIndex[2]));	// Fill in the data in the indice list.	pObject->indices[d++] = pObject->pFaces[indx].vertIndex[0];	pObject->indices[d++] = pObject->pFaces[indx].vertIndex[1];	pObject->indices[d++] = pObject->pFaces[indx].vertIndex[2];


Finally, the rendering function, which now looks like this:
void RenderLandscape(){	bool useDetailTexture = false;	// Activate the necessary Vertex Array properties.	glEnableClientState(GL_VERTEX_ARRAY);	for (int i = 0; i < g_3DModel.numOfObjects; i++)	{		// Draw only ground objects.		if (bItemList != false)			continue;		// Make sure we have valid objects just in case. (size() is in the vector class).		if(g_3DModel.pObject.size() <= 0) break;		// Get the current object that we are displaying.		t3DObject *pObject = &g_3DModel.pObject;		// Check visibility based on distance from object to player.		if (!ObjectDistanceCalc(player.vCharMove, pObject))			continue;		ActivateDetailTexturing();					// Does the material applied to this object have a detail texture?		if (g_TextureDetail[pObject->materialID] < 666) {			useDetailTexture = true;		} else {			useDetailTexture = false;		}		// Set up the detail texturing parameters.		if (useDetailTexture) {			SetupDetailTexturing(g_Texture[pObject->materialID],								 g_TextureDetail[pObject->materialID]);		} else {			SetupDetailTexturing(g_Texture[pObject->materialID], -1);		}		// Turn on backface culling.		glEnable(GL_CULL_FACE);		// Check if the object is to be rendered without culling.		if (!pObject->doCulling)			glDisable(GL_CULL_FACE);		// Set translucency and color.		if (pObject->transPercent < 1.0f) {			glColor4f(1.0f, 1.0f, 1.0f, pObject->transPercent);			glBlendFunc(GL_SRC_ALPHA, GL_ONE);			glEnable(GL_BLEND);		} else {			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);			glDisable(GL_BLEND);		}		// Shiny objects should have specular coloring applied.		if (pObject->ShinyObj) {			glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, SunAmbience);			glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &specularShine);		} else {			GLfloat noSpecular[] = {0, 0, 0, 1.0f};			float noShininess = 0.0f;			glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, noSpecular);			glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &noShininess);		}		// Set up the Vertex Array lists.		glVertexPointer(3, GL_FLOAT, 0, pObject->vertexArray);		// Draw the Vertex Array lists.		glDrawElements(GL_TRIANGLES, pObject->numOfFaces, GL_UNSIGNED_BYTE, pObject->indices);		// Disable detail texturing.		DisableDetailTexturing();		// Disable possible set blending.		if (pObject->transPercent < 1.0f)			glDisable(GL_BLEND);	}	glDisableClientState(GL_VERTEX_ARRAY);}


I am beginning to suspect that I have to send the texture coordinates as well, though should it not work without those and just draw a color I specify instead?
Shouldn't this be :- (And are you storing them as bytes or unsigned shorts/unsigned ints ?

glDrawElements(GL_TRIANGLES, pObject->numOfFaces * 3, GL_UNSIGNED_BYTE, pObject->indices);

The more applications I write, more I find out how less I know
I am storing them as unsigned ints.. made the change from GL_UNSIGNED_BYTE to GL_UNSIGNED_INT in the vertex array. I guess I could use something with less memory footprint.

I should not do ->numOfFaces * 3, that's incorrect since I only want to draw the number of faces for the object.
Heh.. you were right.. multiplying the pObject->numOfFaces by 3 did the trick, though I don't understand why.. hehe..

THANKS TO EVERYONE!! :)

Now for the texture coordinates ;)
Quote:Original post by azjerei
I am storing them as unsigned ints.. made the change from GL_UNSIGNED_BYTE to GL_UNSIGNED_INT in the vertex array. I guess I could use something with less memory footprint.

I should not do ->numOfFaces * 3, that's incorrect since I only want to draw the number of faces for the object.


http://msdn.microsoft.com/library/default.asp?url=/library/en-us/opengl/glfunc01_1kz7.asp

The count is number of elements to be rendered - not the number of faces. So in essence its the total number of indices - not the total number of faces.
The more applications I write, more I find out how less I know
Ok :)

Got texture coordinates to work as well, so the scene is textured. The FPS was increased to about double from before, which is great.

Though, now I have two small problems:

1. How to use my vertex normals here? I have no indice list for the vertex normals I use.. Is that even possible?

2. My multitexturing seems to be unfunctional now.. Any suggestions? I guess it is the coordinates for the detail texture that isn't quite working as it should now that I pass texture coordinates via the Vertex Array system.
Hi,

You will probably have to recalculate the normals and use glNormalPointer. Regarding multitexturing - you can do it using glClientActiveTextureARB which you will have to load using wglGetProcAddress if you are using windows.

http://www.hmug.org/man/3/glClientActiveTextureARB.html


The more applications I write, more I find out how less I know
Ok, thanks.

Though.. having done a few tests, I don't really see any speed-up at all.

With only the landscape rendered using vertex arrays (not regular objects like trees, fences, boxes etc.), I get an FPS of ~90-100. When rendering everything using vertex arrays, I get an FPS of ~70-80.

Prior to installing this, I got an FPS between 40 and 100 depending on the amount of objects being drawn (had 41 in the scene, which were rendered all at once at certain locations, with a total face count of about 2000).

How can faces be culled now? Someone said that it can be done, but theoretically, I cannot really see how, unless there is an extension for that.

This topic is closed to new replies.

Advertisement