Skip to main content
gamedev.net
🔒 Locked

Vertex Array Texture Binding Problem

Started by Butterman 7 replies 1.5k views
Original Post
Butterman
Butterman
Hey guys. I'm trying to bind textures to models I'm loading to my custom format. It all worked perfectly fine when I was using (glBegin(), glEnd(), glVertex3f(), glTexCoord2d(), etc). But I'm moving over to Vertex Arrays because that's all my target platform supports. Here is a video from when it was working.
I just modified my code, using the same variable format. Now I get this. Here is my current drawing code.


static void DrawJModel(JModel *model, int frame = 0)
	{
		glTranslatef(model->X,model->Y,model->Z);
		glRotatef(model->angleY + 180,0,1,0);
		glScalef(0.7,0.7,0.7);

		glEnableClientState(GL_VERTEX_ARRAY);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);

		glVertexPointer(3, GL_FLOAT, 0, model->frames[frame].verticies);

		for(int b = 0; b < model->tFaces; b++)
		{
			glTexCoordPointer(2,GL_FLOAT,0, &model->faces.UV[0]);

			std::cout << model->faces.UV[4] << " " << model->faces.UV[5] << std::endl;

			if(model->faces.num == 3)
			{
				glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, model->faces.indicies);
			}
			else
			{
				glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, model->faces.indicies);
			}
		}

		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
		glDisableClientState(GL_VERTEX_ARRAY);
	}


I know the UVs are getting loaded fine, they worked fine before and as you can see I'm even outputting the UVs as they're drawn to make sure they're intact. Even still, here is a snippet from my loading code.

//For each face in the model
		for(int i = 0; i < temp.tFaces; i++)
		{
			//Read in the number of indicies in the face
			fscanf(pFile,"\n %i ",&temp.faces.num);

			//Create room for the uv depending on the number of indicies, we need a U and a V per index
			//temp.faces->UV = new GLfloat[temp.faces.num * 2 + 2];

			//For each of the indicies in the face
			for(int c = 0; c < temp.faces.num; c++)
			{
				//Load up their index and UV co-ordinates
				fscanf(pFile,"%i %f %f ", &temp.faces.indicies[c], 
					&temp.faces.UV[(c * 2)], 
					&temp.faces.UV[((c * 2) + 1)]);
			}

		}

I've been working at this problem most of last week, any help is great :D Cheers!
Game Development Tutorials, a few good game development tutorials located on my site.
Great_White
Great_White
not sure about this but may be you should not set the stride parameter correctly when calling gl*Pointer().Are you using interleave format for vertex data ? Also instead of calling glDrawElements() for every faces you can call it once with all the faces.
"A human being is a part of a whole, called by us,universe, a part limited in time and space. He experiences himself, his thoughts and feelings as something separated from the rest... a kind of optical delusion of his consciousness. This delusion is a kind of prison for us, restricting us to our personal desires and to affection for a few persons nearest to us. Our task must be to free ourselves from this prison by widening our circle of compassion to embrace all living creatures and the whole o
Butterman
Butterman
There is no stride. Each UV array is a fixed 10 float array. That goes, U,V,U,V,U,V for each of the indicies in its face. (One UV array per face). So, it's just size two. I'm not interweaving any data.

I can't just call DrawElements, because I have to provide GL_QUADS or GL_TRIANGLES, my model format supports faces with 3 or 4 verticies.

As you can see the model is drawing fine, it's just the texture.
Game Development Tutorials, a few good game development tutorials located on my site.
scratt
scratt
Your GL code looks ok.

How is your structure arranged for your faces / UV coords.

What I am driving at here is.. If you were sending them up before with individual commands for each vertex and now you are sending them in small batches with DrawArrays and pointers.. Are the UV coords all sequential in memory?
Feel free to 'rate me down', especially when I prove you wrong, because it will make you feel better for a second....
Butterman
Butterman
Urm. I don't know what I can show you about UV arrangement apart from what was in my loading code above.



struct face{	int num;	GLubyte indicies[5];	GLfloat UV[20];};struct frame{	float *verticies;};struct JModel{	int tVerticies;	int tFrames;	int tFaces;	face *faces;	frame *frames;	float angleY;	float X,Y,Z;};


//For each face in the model		for(int i = 0; i < temp.tFaces; i++)		{			//Read in the number of indicies in the face			fscanf(pFile,"\n %i ",&temp.faces.num);			//Create room for the uv depending on the number of indicies, we need a U and a V per index			//temp.faces->UV = new GLfloat[temp.faces.num * 2 + 2];			//For each of the indicies in the face			for(int c = 0; c < temp.faces.num; c++)			{				//Load up their index and UV co-ordinates				fscanf(pFile,"%i %f %f ", &temp.faces.indicies[c], 					&temp.faces.UV[(c * 2)], 					&temp.faces.UV[((c * 2) + 1)]);			}		}


The key here is this.

//Load up their index and UV co-ordinatesfscanf(pFile,"%i %f %f ", &temp.faces.indicies[c], 		&temp.faces.UV[(c * 2)], 		&temp.faces.UV[((c * 2) + 1)]);


You can see that I'm getting the index then its two UV co-ordinates. Each line in the model file holds 3 or 4 different index, UV pairs. That's what C is, I check how many indicies are in the face, then loop through them with C.

Here is a sample face from the format.
4 23 0.121100 0.332000 32 0.121100 0.363300 38 0.003900 0.363300 35 0.019500 0.332000 

As you can see, "4" faces, then "23" index, "0.12", "0.33" U and V then we have another index "32".

I'm almost 100% certain that it's going in fine. But I'm also 100% certain that this is where the problem is at.
Game Development Tutorials, a few good game development tutorials located on my site.
scratt
scratt
OK. I think I may know what it is... I am dredging my memory here but... I am pretty sure that when you use indexed arrays then the index affects all data sources... I seem to remember falling foul of this when I tried to do a cheap instanced vertex method on earlier shader models to draw QUADs super fast.

So you would need to have UV pairs in a general array that matches up to the vertex array.

i.e. Index 1 refers to both Vertex 1 and UV pair 1. Index 10 refers to Vertex 10 and UV pair 10.

Does that make sense to you?
Feel free to 'rate me down', especially when I prove you wrong, because it will make you feel better for a second....
Butterman
Butterman
Yeah. Perfect sense. That would explain every thing.

I'll sort that out when I get home tonight. Thanks a lot man.
Game Development Tutorials, a few good game development tutorials located on my site.
scratt
scratt
np :)
Feel free to 'rate me down', especially when I prove you wrong, because it will make you feel better for a second....
Butterman
Butterman
Well. It's done. Took one hell of a hack. I just can't see any other way of getting it working with my current format. I really like the fact that I don't have to store more than one of every vertex, but if my UV list has to match my Vertex list, well, that isn't going to work because the UV depends on the current face.

Here's my hack, tell me how bad it is. (If at all)

                //New		GLfloat *UV = new GLfloat[model->tVerticies *2];		glTranslatef(model->X,model->Y,model->Z);		glRotatef(model->angleY + 180,0,1,0);		glScalef(0.7,0.7,0.7);		glEnableClientState(GL_VERTEX_ARRAY);		glEnableClientState(GL_TEXTURE_COORD_ARRAY);		glVertexPointer(3, GL_FLOAT, 0, model->frames[frame].verticies);		glTexCoordPointer(2,GL_FLOAT,0, UV);		for(int b = 0; b < model->tFaces; b++)		{			if(model->faces.num == 3)			{                                //New				for(int c = 0; c < 3; c++)				{                                               //New					UV[(model->faces.indicies[c]) * 2] = model->faces.UV[(c * 2)];					UV[(model->faces.indicies[c]) * 2 + 1] = model->faces.UV[(c * 2) + 1];				}				glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, model->faces.indicies);			}			else			{				for(int c = 0; c < 4; c++)				{					UV[(model->faces.indicies[c]) * 2] = model->faces.UV[(c * 2)];					UV[(model->faces.indicies[c]) * 2 + 1] = model->faces.UV[(c * 2) + 1];				}				glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, model->faces.indicies);			}		}		glDisableClientState(GL_TEXTURE_COORD_ARRAY);		glDisableClientState(GL_VERTEX_ARRAY);		delete(UV);
Game Development Tutorials, a few good game development tutorials located on my site.

Topic Locked

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

Sign in to reply to this topic.