# vertex arrays texturing problem, solved ?

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

## Recommended Posts

!NOTE I may have found the solution but is it correct one ? Here is the code I am using right now for drawing. I increased vboar and tboar arrays to the size equal faces number * 3. It seems to be working , but is it the right way to draw ?


for(int i = 0; i < header.num_face; i++)
{

//now uv
au = (float)uvlist[ faceuvlist.auv ].u / header.skinwidth;
av = 1 - (float)uvlist[ faceuvlist.auv ].v / header.skinheight;

bu = (float)uvlist[ faceuvlist.buv ].u  / header.skinwidth;
bv = 1 - (float)uvlist[ faceuvlist.buv ].v / header.skinheight;

cu = (float)uvlist[ faceuvlist.cuv ].u  / header.skinwidth;
cv = 1 - (float)uvlist[ faceuvlist.cuv ].v / header.skinheight;

vboar[ cnt ].x = ax;
vboar[ cnt ].y = ay;
vboar[ cnt ].z = az;

tboar[ cnt ].u = au;
tboar[ cnt++ ].v = av;

vboar[ cnt ].x = bx;
vboar[ cnt ].y = by;
vboar[ cnt ].z = bz;

tboar[ cnt ].u = bu;
tboar[ cnt++ ].v = bv;

vboar[ cnt ].x = cx;
vboar[ cnt ].y = cy;
vboar[ cnt ].z = cz;

tboar[ cnt ].u = cu;
tboar[ cnt++ ].v = cv;

}
//Drawing

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState( GL_TEXTURE_COORD_ARRAY );

glTexCoordPointer( 2,GL_FLOAT,0, tboar );
glVertexPointer(3,  GL_FLOAT, 0,vboar);

//now let's draw it
//I am using glDrawArrays Right now !
//glDrawElements(GL_TRIANGLES, header.num_face * 3, GL_UNSIGNED_SHORT, facelist);

glDrawArrays( GL_TRIANGLES, 0, header.num_face * 3);

glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState(GL_VERTEX_ARRAY);


---------- previous post: Hi I am now working with vertex array, and encountered the following problem: The md2 model that I am rendering seems to have all it's uv coordinates distorted. Here are the structures I am using:
Quote:
 //compressed uv coordinate typedef struct { short u; short v; } uv; //the id of the uv typedef struct { short auv; short buv; short cuv; }faceuvlist; typedef struct { GLushort a; GLushort b; GLushort c; }facelist;
Here is how I obtain coordinates for intermidate mode( Works OK)
		//now uv
au = (float)uvlist[ faceuvlist.auv ].u / header.skinwidth;
av = 1 - (float)uvlist[ faceuvlist.auv ].v / header.skinheight;

bu = (float)uvlist[ faceuvlist.buv ].u  / header.skinwidth;
bv = 1 - (float)uvlist[ faceuvlist.buv ].v / header.skinheight;

cu = (float)uvlist[ faceuvlist.cuv ].u  / header.skinwidth;
cv = 1 - (float)uvlist[ faceuvlist.cuv ].v / header.skinheight;

glTexCoord2f( au,av);
glVertex3f( ax , ay , az);

glTexCoord2f( bu,bv);
glVertex3f( bx , by , bz);

glTexCoord2f( cu,cv);
glVertex3f( cx , cy , cz);


//here is how I am trying to render with vertex arrays (Here is the problem) - I store these coordinates in a separate array : typedef struct { GLfloat u; GLfloat v; }tboar; typedef struct { GLfloat x; GLfloat y; GLfloat z; }vboar;
		//now uv
au = (float)uvlist[ faceuvlist.auv ].u / header.skinwidth;
av = 1 - (float)uvlist[ faceuvlist.auv ].v / header.skinheight;

bu = (float)uvlist[ faceuvlist.buv ].u  / header.skinwidth;
bv = 1 - (float)uvlist[ faceuvlist.buv ].v / header.skinheight;

cu = (float)uvlist[ faceuvlist.cuv ].u  / header.skinwidth;
cv = 1 - (float)uvlist[ faceuvlist.cuv ].v / header.skinheight;

tboar[ facelist.a ].u = au;
tboar[ facelist.a ].v = av;

tboar[ facelist.b ].u = bu;
tboar[ facelist.b ].v = bv;

tboar[ facelist.c ].u = cu;
tboar[ facelist.c ].v = cv;

//after I put the data to the array I render it

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState( GL_TEXTURE_COORD_ARRAY );

glTexCoordPointer( 2,GL_FLOAT,0, tboar );
glVertexPointer(3,  GL_FLOAT, 0,vboar);

//now let's draw it
glDrawElements(GL_TRIANGLES, header.num_face * 3, GL_UNSIGNED_SHORT, facelist);

glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState(GL_VERTEX_ARRAY);


Please help me out. I cannot continue with this problem remaining. Thank you for any help. [Edited by - DMINATOR on June 13, 2005 5:36:06 AM]

##### Share on other sites
ah why are you using a short for UV coordinates??? texture coordinates are floating point or how else do you plan on tiling or stretching the texture across the mesh? I might be wrong on this...

##### Share on other sites
Quote:
 Original post by MARS_999ah why are you using a short for UV coordinates??? texture coordinates are floating point or how else do you plan on tiling or stretching the texture across the mesh? I might be wrong on this...

He's storing compressed UV coordinates in short numbers, but for the final rendering they're decompressed into array of floats, from what i can see.

edit: as for rendering problem, hard to tell, but... one thing to check could be if the order of uv's in the uv array (tboar) is fully matching the order of vertex coordinates in the coordinates array (vboar) ... otherwise you're going to see mess when the routine tries to draw point X at coordinates vboar[X] and with uv's defined at tboar[X] ... and when the uv coordinates at tboar[X] actually belong to completely different vertex. o.O;

##### Share on other sites
Quote:
Original post by tolaris
Quote:
 Original post by MARS_999ah why are you using a short for UV coordinates??? texture coordinates are floating point or how else do you plan on tiling or stretching the texture across the mesh? I might be wrong on this...

He's storing compressed UV coordinates in short numbers, but for the final rendering they're decompressed into array of floats, from what i can see.

edit: as for rendering problem, hard to tell, but... one thing to check could be if the order of uv's in the uv array (tboar) is fully matching the order of vertex coordinates in the coordinates array (vboar) ... otherwise you're going to see mess when the routine tries to draw point X at coordinates vboar[X] and with uv's defined at tboar[X] ... and when the uv coordinates at tboar[X] actually belong to completely different vertex. o.O;

Thanks , Well here is how I fill the vboar array:
	      vboar[ facelist.a ].x = ax;		vboar[ facelist.a ].y = ay;		vboar[ facelist.a ].z = az;	      vboar[ facelist.b ].x = bx;		vboar[ facelist.b ].y = by;		vboar[ facelist.b ].z = bz;		vboar[ facelist.c ].x = cx;		vboar[ facelist.c ].y = cy;		vboar[ facelist.c ].z = cz;

I also have changed the tboar to

	      tboar[ facelist.a ].u = au;		tboar[ facelist.a ].v = av;		tboar[ facelist.b ].u = bu;		tboar[ facelist.b ].v = bv;		tboar[ facelist.c ].u = cu;		tboar[ facelist.c ].v = cv;

It looks a little better but is still distorted.

##### Share on other sites
Quote:
 Original post by DMINATORHere is the code I am using right now for drawing. I increased vboar and tboar arrays to the size equal faces number * 3.It seems to be working , but is it the right way to draw ?

For glDrawArrays() yes; the function simply expects straight sequence of vertex data, much like drawing your geometry 'by hand' with the glVertex/glTex/etc calls for each vertex you create.

glDrawElements() is a bit different, in the sense that instead of going through the data array in fixed begin->end sequence it uses additional array that stores sequence which should be followed to draw the geometry chunk. This allows you to eliminate duplicate vertices from the vertex arrays, and only that additional indices array should have "matching" length, like face_count * 3 in case of triangles.

For the problems you're still having in the glDrawElements() ... dunno, but i looked up md2 specs at wotsit.org and they appear quite annoying to work with in anything but direct drawing mode. Because the number of vertex coordinates is separate from number of texture coordinates, the 'final' points of the model can mix-and-match these values... so when you try to 'bake' the vertices into array for DrawElements() it's possible for single vertex to have assigned multiple, different sets of UVs... and the latest set of UVs will overwrite the UVs already assigned to that vertex, leading to 'distorted' look you're experiencing.

One way to deal with it would be "unwelding" the sets of coordinates and UVs into array of completely separate points and use glDrawArray() just like you're doing it now. glDrawElements() would require extra processing steps done to this "unwelded" array, that is: to scan it for duplicate points, to remove these duplicates, to recode the vertex indices of polygons to use only the remaining vertices, to compact the unwelded array into new array with only the remaining different points... and then finally to generate the index for glDrawElements() from remapped vertex indices held by the polygon array. (fortunately, it's one of the rare cases when it's easier done than said ;s

##### Share on other sites
Quote:
Original post by tolaris
Quote:
 Original post by DMINATORHere is the code I am using right now for drawing. I increased vboar and tboar arrays to the size equal faces number * 3.It seems to be working , but is it the right way to draw ?

For glDrawArrays() yes; the function simply expects straight sequence of vertex data, much like drawing your geometry 'by hand' with the glVertex/glTex/etc calls for each vertex you create.

glDrawElements() is a bit different, in the sense that instead of going through the data array in fixed begin->end sequence it uses additional array that stores sequence which should be followed to draw the geometry chunk. This allows you to eliminate duplicate vertices from the vertex arrays, and only that additional indices array should have "matching" length, like face_count * 3 in case of triangles.

For the problems you're still having in the glDrawElements() ... dunno, but i looked up md2 specs at wotsit.org and they appear quite annoying to work with in anything but direct drawing mode. Because the number of vertex coordinates is separate from number of texture coordinates, the 'final' points of the model can mix-and-match these values... so when you try to 'bake' the vertices into array for DrawElements() it's possible for single vertex to have assigned multiple, different sets of UVs... and the latest set of UVs will overwrite the UVs already assigned to that vertex, leading to 'distorted' look you're experiencing.

One way to deal with it would be "unwelding" the sets of coordinates and UVs into array of completely separate points and use glDrawArray() just like you're doing it now. glDrawElements() would require extra processing steps done to this "unwelded" array, that is: to scan it for duplicate points, to remove these duplicates, to recode the vertex indices of polygons to use only the remaining vertices, to compact the unwelded array into new array with only the remaining different points... and then finally to generate the index for glDrawElements() from remapped vertex indices held by the polygon array. (fortunately, it's one of the rare cases when it's easier done than said ;s

Ok thanks for your explanation. But what is the best way to do ? Stick with glDrawArray or try to render with glDrawElements ? What is faster ?

##### Share on other sites
Quote:
 Original post by DMINATOROk thanks for your explanation. But what is the best way to do ? Stick with glDrawArray or try to render with glDrawElements ? What is faster ?

Dunno, tbh (think it can depend on quite a few factors) ... the easiest way to see would be simple test of what performance fps-wise you are getting with a handful of different characters on screen, drawn one way and the other? ^^

1. 1
2. 2
3. 3
Rutin
15
4. 4
khawk
13
5. 5
frob
12

• 9
• 11
• 11
• 23
• 12
• ### Forum Statistics

• Total Topics
633662
• Total Posts
3013231
×