• Advertisement

Archived

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

More Vertex Arrays Woes (will this never stop!!)

This topic is 5098 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

Wow, am I tired of trying to get this working... Maybe I''m mixing stuff, I don''t know. Here are 2 pics, the 1st one shows my renderer with a typical display list, the 2nd using Vertex Arrays. Code follows. Sorry for the high compression, I just wanted to show that there seems to be something wrong with how texturing is being done, here is the rendering code:
glBindTexture(GL_TEXTURE_2D, TextureID);

glVertexPointer   ( 3, GL_DOUBLE, 0, VertexBuffer);
glTexCoordPointer ( 2, GL_DOUBLE, 0, TexBuffer);
glNormalPointer   ( GL_DOUBLE,    0, NormalBuffer);
	
size = NumFaces*3; // 3 Vertices per Face

glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, FaceList);
You guys see anything wrong? Normals also seem to be failing, shadow doesnt fall on the model correctly... Jester Says: Visit Positronic Dreams!
[Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It''s the only way to be sure."

Share this post


Link to post
Share on other sites
Advertisement
Not a lot of code to go on, but here are a few ideas. You are enabling all the correct arrays with glEnableClientState() and when you setup the texcoord array you are using glClientActiveTexture() to specify the texture unit the coords should be used for client side, rather than server side with glActiveTexture for actual texture binding?


glActiveTexture( GL_TEXTURE0 );
glBindTexture(GL_TEXTURE_2D, TextureID);

glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_NORMAL_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );

glVertexPointer ( 3, GL_DOUBLE, 0, VertexBuffer);

glClientActiveTexture( GL_TEXTURE0 );
glTexCoordPointer ( 2, GL_DOUBLE, 0, TexBuffer);

glNormalPointer ( GL_DOUBLE, 0, NormalBuffer);



size = NumFaces*3; // 3 Vertices per Face


glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, FaceList);

// and disable all the arrays as appropriate with glDisableClientState




[edited by - paulc on March 4, 2004 12:24:05 PM]

Share this post


Link to post
Share on other sites
the way i did it was to have a VERTEX struct and use an array of those to hold the data

struct VERTEX
{
flaot x, y, z; // The untransformed position for the vertex.

float nx,ny,nz;
DWORD color; // The vertex color.

float tu,tv;
};

glNormalPointer(GL_FLOAT,sizeof(VERTEX),&verts[0].nx);
glTexCoordPointer(2,GL_FLOAT,sizeof(VERTEX),&verts[0].tu);
glVertexPointer(3,GL_FLOAT,sizeof(VERTEX),verts);
glColorPointer(3,GL_UNSIGNED_BYTE,sizeof(VERTEX),&vert[0].color);
glDrawElements(GL_TRIANGLES,m_noTris*3,GL_UNSIGNED_INT,tris);


where tris is a DWORD array of size m_noTris*3

Share this post


Link to post
Share on other sites
Thanks guys, dumb question, in which header can I find glClientActiveTexture? And how does it work, does it limit my texture options?

Thanks for any tips on this...

Jester Says: Visit Positronic Dreams!
[Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It''s the only way to be sure."

Share this post


Link to post
Share on other sites
glClientActiveTexture should be in an uptodate version of gl.h. It functions just the same as glActiveTexture, but on the client side, e.g. it does the same thing but for gl commands that are not executed immediately (I think this just applies to glTexCoordPointer calls, can''t think of anything else that uses it) - they are batched up and executed when the DrawElements or similar function is called. Okay, so it may be a bit misleading, in that the TexCoordPointer call is executed; the pointer is setup, but the data is just copied to where gl can access and use it rather than actually being drawn immediately.

Share this post


Link to post
Share on other sites
Ok, I have those 2 functions (glActiveTextureARB & glClientActiveTextureARB) in my GLCaps class that detects and assigns opengl extensions. My revised code looks like this now, but the results i get are still equal to pic 2...


glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

GLCaps.glActiveTextureARB( GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, TextureID);

glTexCoordPointer ( 2, GL_DOUBLE, 0, TexBuffer);
glVertexPointer ( 3, GL_DOUBLE, 0, VertexBuffer);
GLCaps.glClientActiveTextureARB( GL_TEXTURE0 );

size = NumFaces*3; // 3 vertices per Face

glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, FaceList);

glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);


Jester Says: Visit Positronic Dreams!
[Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It''s the only way to be sure."

Share this post


Link to post
Share on other sites
Another question,
When we define normals and texture coords, we define them allways by vertex, never by face, right?

I don''t think we can define texture coordinates UV for a face, but we can define the normals of a face with XYZ, or per vertex...

So our normals, texture coordinates are allways defined by vertex, right?

Jester Says: Visit Positronic Dreams!
[Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It''s the only way to be sure."

Share this post


Link to post
Share on other sites
The ClientActiveTexture call should go just before the TexCoordPointer call, its performing the same operation as ActiveTexture before a BindTexture call.

Share this post


Link to post
Share on other sites
quote:
Original post by pentium3id
Another question,
When we define normals and texture coords, we define them allways by vertex, never by face, right?

I don''t think we can define texture coordinates UV for a face, but we can define the normals of a face with XYZ, or per vertex...

So our normals, texture coordinates are allways defined by vertex, right?



By convention, all data is stored in the vertices and the face description then becomes a list of vertices in that face.
So yes, all normals and texture coords should be stored in the verts. As you correctly pointed out, there is no logical representation to map textures to a face.


Share this post


Link to post
Share on other sites
Thanks paulc, still unsuccessful, current code:


GLCaps.glActiveTextureARB( GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, TextureID);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glVertexPointer ( 3, GL_DOUBLE, 0, VertexBuffer);
GLCaps.glClientActiveTextureARB( GL_TEXTURE0 );

glTexCoordPointer ( 2, GL_DOUBLE, 0, TexBuffer);
size= FaceNum*3;

glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, FaceList);

glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);


...Also, do I really have to do glEnableClientState, or can I do it once, at program initialization? Cause I''m currently doing it once per frame...

psamty10, thanks for clearing that up.

Jester Says: Visit Positronic Dreams!
[Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It''s the only way to be sure."

Share this post


Link to post
Share on other sites
New Screenshots to go with that code:

Display Lists:

Vertex Arrays:


Notice how the legs seem to be geting textured correctly, and after a while texturing goes ay-wire....

Jester Says: Visit Positronic Dreams!
[Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It''s the only way to be sure."

Share this post


Link to post
Share on other sites
How are VertexBuffer, TexBuffer, and FaceList defined?

Michael K.,
Co-designer and Graphics Programmer of "The Keepers"



We come in peace... surrender or die!

Share this post


Link to post
Share on other sites
VertexBuffer is a variable-length Array of this structure type:
struct Mesh_Vertex_3D // 3 Doubles, 24 bytes
{
double X, Y, Z;
};

TexBuffer is a variable-length Array of this structure type:
struct Mesh_TVertex_2D
{
double U, V;
};

FaceList is a variable-length Array of this structure type:
struct Mesh_Face_3I
{
UINT V1, V2, V3;
};

Here are the two cubes, as requested:
A) Display Lists
B) Vertex Arrays


Also, would like to touch another point, here are some stats about my teapot:

# of Vertices 1598
# of TexCoordinates 2048
# of Vertex Normals 9408
# of Faces 3136
# of Texture Faces 3136
# of Face Normals 3136

Now, I sense trouble here, i have more texture coordinates than I have vertices, and I have more vertex normals than I have vertices...

Now, they are all organised into lists of 3136 faces, which works when using display lists cause you batch commands...

But when I use vertex arrays I cant define a "list" of Vertex Normals, nor can i seem to be able to define a list of texture coordinates, right?

Using VAs I can still define a list of faces, in the call:
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, FaceList);

but none of the other 2 lists....

So how do i get to eat my cake and have it too?

Do I have to "unroll" my data? Create a per-vertex list of vertex normals and per-vertex texture coordinates?

I''m still importing from ASE files (text files generated by 3D studio), and they export data in this fashion, I may need to post-process it I guess, or switch to another format...

What do you guys think?

Jester Says: Visit Positronic Dreams!
[Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It''s the only way to be sure."

Share this post


Link to post
Share on other sites
Yup, you need to process the vertex data into lists of the same size, so for each vertex there is one normal and one set of texture coords. When you call DrawElements it uses the indices in the list you pass in to index into the vertex, normal and texture coord arrays. It uses the same index in each case so the data in the arrays must line up.

Share this post


Link to post
Share on other sites
arrghhh....

ok, my fears where correct...

now, how do i "line-up" the data? is there a 3d studio exporter that exports data in a VA-friendly maner?

btw, immense thanks for the help paulc, you''re a credit to gamedev

Jester Says: Visit Positronic Dreams!
[Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It''s the only way to be sure."

Share this post


Link to post
Share on other sites
Well, having done this myself, although quite a while ago, should at least being able to give you a pointer or two - as long as the ASE format hasn''t changed too much.

I suspect the problem may be caused by texture seams, or at least the way Max handles texture mapping. While it has the same number of Faces and Texture Faces, the problem is that each face doesn''t use the same indices, e.g.

Face 0: 0 1 3
TFace 0: 0 2 1

To Max, this is perfectly normal, but because GL just uses the indices from Face to index both the vertex list and the tex coord list it will use the wrong tex coords. You will have to process the tex-coord list to produce a new list that uses the same indices as the entries in the list of Faces. ( I suspect I never actually got round to doing this myself - but hey, I need to go back and totally re-work my mesh loading code at some point...).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Any time you encounter a vertex which lies on a color, smoothing, texture or shader boundary, split it into as many copies of that vertex as there are unique combinations of these boundary parameters.

Share this post


Link to post
Share on other sites
If you export to .3ds, it will break up the vertices for you.

One thing you can do is, export your model to .3ds, then import it back into Max and your vertices will be properly split up, after that export to whatever format you need to.

This also gave me many problems in the past when i relied on ASE.

Share this post


Link to post
Share on other sites
GamerSg: I exported a teapot from 3D Studio onto a .3DS file, then imported it and re-exported it to .ASE, and it worked perfectly on the Vertex Array

Im finishing the plugin system, only thing really left to do is write some SDK documentation so other interested programmers can write file importers/ exporters to use with the engine, so ASE will do for now for testing, and either me or someone else will write a 3DS file importer.

Thanks for the tips guys. I think I should write some sort of Tutorial on this. The information is trully scatered arround the net, and full of holes, and unfortunatly, in many places, mistakes.

Thanks

Jester Says: Visit Positronic Dreams!
[Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It''s the only way to be sure."

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Anonymous Poster
Any time you encounter a vertex which lies on a color, smoothing, texture or shader boundary, split it into as many copies of that vertex as there are unique combinations of these boundary parameters.

I said unique combinations, but I really should have said distinct combinations. For example, if you have a set of 4 polygons (P1, P2, P3, P4) which share a vertex V with associated UV coordinates (1.0, 1.0, 1.0, 0.5) and smoothing groups (1, 1, 2, 3), this gives you a total of three distinct combinations (out of four) in the form (UV, smoothing): (1.0, 1) (1.0, 2) and (0.5, 3).

Share this post


Link to post
Share on other sites

  • Advertisement