PDA

View Full Version : TexCoords gone mad with the help of VBO's



rsp91
07-14-2008, 11:12 PM
Hello I have a problem with VBO's. Everything is working great except texture coordinates, they are nowhere near where they should be.

This image might help you understand my problem:
http://img32.picoodle.com/img/img32/4/7/14/f_vboissuem_7ca8ff6.png


I use 4 separate VBO's, I have heard using two is better but I have also heard nVidia recommending not to. Anyhow I don't think that is my problem here, but you tell me...

The following is the code I use to render my models

void Model::Render() {
if(Materials.at(0).TexMat.texture)
glBindTexture(GL_TEXTURE_2D,Materials.at(0).TexMat .texture); //Don't ask

glBindBufferARB(GL_ARRAY_BUFFER_ARB,vBuffer[3]);
glNormalPointer(GL_FLOAT,0,0);

glBindBufferARB(GL_ARRAY_BUFFER_ARB,vBuffer[2]);
glTexCoordPointer(2,GL_FLOAT,0,0);

glBindBufferARB(GL_ARRAY_BUFFER_ARB,vBuffer[0]);
glVertexPointer(3,GL_FLOAT,0,0);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,vBuffe r[1]);
glDrawRangeElements(GL_TRIANGLES,0,0,Stats.nTriang les,GL_UNSIGNED_SHORT,0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

For the record here is my OBJ loader

void Model::Load(string tmp) {
vector<unsigned short> Triangles;
vector<GLfloat> Vertices;
vector<GLfloat> Coords;
vector<GLfloat> Normals;

ifstream f(tmp.c_str());

if(!f) {
cerr<<"ERROR: Model \""<<tmp<<"\" was not found"<<endl;
exit(1);
}

tmp.erase(tmp.size()-4,0); //Remove file extension
Stats.Name=tmp; //Save the name to model stats

while(f>>tmp) {
if(tmp=="mtllib") {
f>>tmp;
ifstream matfile((TexDir+tmp).c_str());

while(matfile>>tmp) {
if(tmp=="newmtl") {
matfile>>tmp;
mat tmp_mat;
tmp_mat.Name=tmp;
Materials.push_back(tmp_mat);
}

else if(tmp=="Ns") {
matfile>>tmp;
Materials.back().Specular2=atof(tmp.c_str());
}

else if(tmp=="Ka") {
for(int i=0; i<3; i++) {
matfile>>tmp;
Materials.back().Ambient[i]=atof(tmp.c_str());
}
}

else if(tmp=="Kd") {
for(int i=0; i<3; i++) {
matfile>>tmp;
Materials.back().Diffuse[i]=atof(tmp.c_str());
}
}

else if(tmp=="Ks") {
for(int i=0; i<3; i++) {
matfile>>tmp;
Materials.back().Specular[i]=atof(tmp.c_str());
}
}

else if(tmp=="map_Kd") {
matfile>>tmp;
Materials.back().TexMat.Load(TexDir+tmp);
}
}
}

else if(tmp=="v") {
for(int i=0; i<3; i++) {
f>>tmp;
Vertices.push_back(atof(tmp.c_str()));
}
}

else if(tmp=="vn") {
for(int i=0; i<3; i++) {
f>>tmp;
Normals.push_back(atof(tmp.c_str()));
}
}

else if(tmp=="vt") {
for(int i=0; i<2; i++) {
f>>tmp;
Coords.push_back(atof(tmp.c_str()));
}
f>>tmp; //No Z
}

else if(tmp=="f") {
int vertices[4];
int texcoords[4];
int normals[4];

for(int i=0; i<3; i++) {
f>>tmp;
GetFaces(tmp,vertices[i],texcoords[i],normals[i]);
}

if(f.peek()==' ') {
f>>tmp;
//Convert quad to triangles
}
else {
for(int i=0; i<3; Triangles.push_back(vertices[i++]-1));
}
}
}

glGenBuffersARB(4,vBuffer);

//Vertices
glBindBufferARB(GL_ARRAY_BUFFER_ARB,vBuffer[0]);
glBufferDataARB(GL_ARRAY_BUFFER_ARB,Vertices.size( )*sizeof(GLfloat),&amp;Vertices[0],GL_STATIC_DRAW_ARB);

//Vertex Indices
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,vBuffe r[1]);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,Triang les.size()*sizeof(unsigned short),&amp;Triangles[0],GL_STATIC_DRAW_ARB);

//Tex Coords
glBindBufferARB(GL_ARRAY_BUFFER_ARB,vBuffer[2]);
glBufferDataARB(GL_ARRAY_BUFFER_ARB,Coords.size()* sizeof(GLfloat),&amp;Coords[0],GL_STATIC_DRAW_ARB);

//Vertex Normals
glBindBufferARB(GL_ARRAY_BUFFER_ARB,vBuffer[3]);
glBufferDataARB(GL_ARRAY_BUFFER_ARB,Normals.size() *sizeof(GLfloat),&amp;Normals[0],GL_STATIC_DRAW_ARB);

//Remember the properties
Stats.nVertices=Vertices.size();
Stats.nTriangles=Triangles.size();
Stats.nCoords=Coords.size();
Stats.nNormals=Normals.size();
}

I know that I have gotten the data from my vectors to work with immediate mode, even textures if that's any help.

Hoping for answers, I have been struggling with this for a long time!

Komat
07-15-2008, 12:24 AM
The OBJ file has separate indices for vertex positions, normals and texture coordinates. The OpenGL supports only one index stream used by all of them. You need to create vertex for each combination of position&normal&coordinate indices used by face inside the OBJ file.

rsp91
07-15-2008, 05:24 AM
I heard that from another person, just wanted to make sure. Is there any tutorial about this? I find it hard to imagine the solution.

dletozeun
07-15-2008, 05:35 AM
I don't think there are any tutorial about this.
What you have to do is index one characteristic of your geometry and then duplicate the rest of the data relating to these indices.

I mean, usually your indices are vertex indices. Then you have to generate normals and texture coordinates arrays thinking that vertex indices are the ones that will be used to index these arrays.
Practically you loop on each triangle vertices, you read texture coordinates and normals at each vertex and build the new texture coordinates and normals arrays at the same time.
So you will end with a lot of duplicated data, but you don't have the choice for now.

I hope I am clear. Don't hesitate to ask more questions. :)

rsp91
07-15-2008, 05:37 AM
Some pseudocode would not be bad, really :)

update
I now have a vector of sorted vertices

struct sorted_vertex {
GLfloat x, y, z;
GLfloat s, t;
GLfloat nx, ny, nz;
};

they are matching the vertices used in OBJ files

rsp91
07-15-2008, 07:30 AM
http://img28.picoodle.com/img/img28/4/7/15/f_Skrmbildgltm_6ee7271.png


Thanks for explaining more in depth dletozeun

4600 FPS... :)

Now, what would be the next step in my render?

CatDog
07-15-2008, 07:42 AM
It's a shield. Now you should add a sword.

CatDog

dletozeun
07-15-2008, 07:58 AM
And a knight to carry this stuff. :)

rsp91
07-15-2008, 08:01 AM
:)
Guess I'll be looking into GLSL next.

dletozeun
07-15-2008, 08:05 AM
you will put some metal reflection? That would be nice

satan
07-15-2008, 10:00 AM
It's a shield. Now you should add a sword.

It's not just a shield, it's the master shield (http://www.nwiizone.com/wp-content/uploads/2006/11/The_Legend_of_Zelda_Twilight_Princess_wii_wallpape r.jpg).