VertexArray glBindTexture not working.

Hi guys, I asked this question in the beginner forum some days ago, but I did’nt get any answer, and I’m a bit puzzled. Hope you can help me.

I’m trying to learn how to use vertex arrays, but I must have some error, or there must be something I’m not understanding, because for some reason my little test app is not working as expected.
Just trying to draw one textured triangle using vertex arrays. If I call glBindTexture() before calling glDrawArrays() or glDrawElements() no texture is shown, but if I omit the texture binding everything works ‘right’. Tell me if you see the problem in this implementation:

float vertices = { -10.0f, -10.0f, 0.0f, -10.0f, 10.0f, 0.0f, 10.0f, 10.0f, 0.0f };

float colors = { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };

float texcoords = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f };

int indices = { 0, 1, 2 };

in my init function:

textureID = LoadJPG( “cool.JPG” );
glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
glColorPointer(3, GL_FLOAT, 0, colors);
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );

then in my Draw function:

//glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);
glBindTexture(GL_TEXTURE_2D, textureID);
glDrawArrays (GL_TRIANGLES, 0, 3);

…and the polygon renders non textured. I’ve tried alternative methods with Vertex arrays but they always fail, so I think I’m not understanding how this really works.

Thank you.

[This message has been edited by Anonymous Coward (edited 05-06-2003).]

[This message has been edited by Anonymous Coward (edited 05-06-2003).]

You have no glTexImage2D call (OK that looks like you load it in the LoadJPG function), and you have no glEnable call for texture, so that may be the issue.

[This message has been edited by dorbie (edited 05-06-2003).]

No, if I just remove the glBindTexture function IT SHOWS the texture…just that.

For some reason if I simply create the texture and then create the vertex arrays, it works fine. If I call glBindTexture it shows no texture

Your loadJPG function should return a texture object id obtained with glGenTextures. I’m sure it already does.
Additionally you must bind this texture inside your loadJPG function before setting up the texture (ie before glTexImage2d, before glTexParameteri etc).

Otherwise, you’re modifying the default texture object NULL, which is a valid texture object, so this would explain why your code works if you omit glBindTexture in the rendering code.

If that wasn’t it, I’d like to see your loadJPG code

It’s something like this, but the texture loading code its already tested because its the saem function I use in other projects…
Thank you

	

m_Id = GenTextureId();			// generate Id

	// an Id == 0 is an error
	if (m_Id == 0) {
	
		return 0;
	}

	// create texture

	glBindTexture( GL_TEXTURE_2D,  m_Id);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, 
					 GL_UNSIGNED_BYTE, bits );

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

Last straw:
Your function does return m_Id if it succeeds, right?
You’ve omitted that part.

Yep, that’s right. Anyway, the first code I posted, with the coords, indices and all the Vertex Array stuff is supposed to be right?
Thats what I have understand from the Red Book, but it doesn’t include an example that uses vertex array + texturing.
Thanks!

If removing the bind operation works then is may indicate a problem with the binding of your texture in the image load function but it doesn’t seem like it from your code.

You don’t need to obtain the handle any specific way, you can use any number, just pick a positive integer. Wrapping your own gen function just confuses the issue further(why people write obfuscating code like this I don’t know), just pick a number for the test. You are allowed to do this in OpenGL, the utilities to generate handles are just to help code play together. Pick any number and use it.

There just isn’t enough OpenGL in your posted example to show a consistent working code path. Important stuff is hidden so we’re left guessing.

I still don’t see a glEnable call for texture, perhaps you have a heuristic somewhere that is switching it off based on rendering path and we can’t see it. Go find the glEnable(GL_TEXTURE_2D) call in your code & make sure it’s in the right place.

[This message has been edited by dorbie (edited 05-07-2003).]

As errors are not apparent in the code you posted and it is difficult to debug without the complete src. , I will just post the way I do it and hope it helps:

//Step 1: Allocate Memory
int sizei;
if(m_bTextured)
sizei = 8m_NumVerticessizeof(float); //2(tex) + 3(normals) + 3(verts) = 8
else
sizei = 6m_NumVerticessizeof(float); //3(normals) + 3(verts) = 6
//try to put it un the video memory, : static geometry
NVRangeEXTbuffer = (float *)(g_pWndMainGL->wglAllocateMemoryNV(sizei,0,0,1));
if(!NVRangeEXTbuffer) //if Video Memory is not available, put it in AGP
NVRangeEXTbuffer = (float *)(g_pWndMainGL->wglAllocateMemoryNV(sizei,0,0,0.5));

	//Step 2: Set up Fences (Optional, some GEForces don't support it : e.g. Mine!)
//	glGenFencesNV(1,&fence);

	//Step 3: Enable Memory
	g_pWndMainGL->glVertexArrayRangeNV(sizei,NVRangeEXTbuffer);
	glEnableClientState(GL_VERTEX_ARRAY_RANGE_NV); //Enable the extension

	//Step 4: Define Vertex Arrays
	if(m_bTextured)
		glInterleavedArrays(GL_T2F_N3F_V3F,0,NVRangeEXTbuffer);
	else
		glInterleavedArrays(GL_N3F_V3F,0,NVRangeEXTbuffer);

	//Step 5: Recycle AGP Memory, use the fences instead of flushing. Fences had a finer
	//control last time I checked !(Beware!, some GEForces don't support it.)
//	glFinishFenceNV(fence);
	g_pWndMainGL->glFlushVertexArrayRangeNV();

	//Step 6: Copy data into Arrays
	//Synchronize Memory , the memory is interleaved. the structure is :
	// normal(x-y-z)-Vertex(x-y-z)-normal(x-y-z)...... , all floats
	//if texture is present, then tex(x-y)-nor,al(x-y-z)-Vertex(x-y-z)-tex(x-y)...
	if(NVRangeEXTbuffer)
	{
		j=0;
		for(i=0;i<m_NumVertices;i++)
		{
			if(m_bTextured)
			{
				//Texture Coordinates
				NVRangeEXTbuffer[j++] = m_pTexCoords[i].GetPointX();
				NVRangeEXTbuffer[j++] = m_pTexCoords[i].GetPointY();
			}

			//Normals
			NVRangeEXTbuffer[j++] = m_pNormals[i].GetPointX();
			NVRangeEXTbuffer[j++] = m_pNormals[i].GetPointY();
			NVRangeEXTbuffer[j++] = m_pNormals[i].GetPointZ();
			
			//Vertices
			NVRangeEXTbuffer[j++] = m_pVertices[i].GetPointX();
			NVRangeEXTbuffer[j++] = m_pVertices[i].GetPointY();
			NVRangeEXTbuffer[j++] = m_pVertices[i].GetPointZ();
		}

		j=0;
		for(i=0;i<m_NumTriangles;i++)
		{
			pVertexIndices[j] = (unsigned int)(m_pTriangles[i].GetVertexMap(0));
			pVertexIndices[j+1] = (unsigned int)(m_pTriangles[i].GetVertexMap(1));
			pVertexIndices[j+2] = (unsigned int)(m_pTriangles[i].GetVertexMap(2));
			j = j+3;
		}
	}

And then a snippet from the draw function
glEnable(GL_TEXTURE_2D);
m_vpLightMapLib[lightMapIdx]->BindTexture();
glDrawElements(GL_TRIANGLES,3*m_NumTriangles,GL_UNSIGNED_INT,pVertexIndices);
// glSetFenceNV(fence,GL_ALL_COMPLETED_NV);

The trick is to group all the triangles according to the texture they are bound to.
And use the vertex array for each group.
hope this helps.

Bivas

[This message has been edited by bivasb (edited 05-07-2003).]

[This message has been edited by bivasb (edited 05-07-2003).]