OBJ parsing and texture mapping

Started by
12 comments, last by haegarr 13 years, 3 months ago
Hi, I manage to parse a OBJ file, show the model and then I try to apply a texture to it. The model I try to render is complex, terrain model.When I draw the arrays like this:


glDrawElements(GL10.GL_TRIANGLE_STRIP, mFacesCount, GL10.GL_UNSIGNED_SHORT, mFaceBuffer);


I get the texture drawn on each triangle separately. So I get massive fractal-like object.

When I try to apply the texture on a pyramid model (4 sided), the texture applies GREAT, but for the complex model it won't.
I have the faces, vertices, normals and texture coordinates correctly.

Here is how the model is supposed to look:

JFwOs.png

And here is how it looks:

FqIN7.png

This


glDrawArrays(GL10.GL_TRIANGLES, 0, mFacesCount);


draws even worse texture over the model.
So, the model renders fine, the texture is a problem.
Advertisement
Hi!
It looks like your texture coordinates are
[0.0f,0.0f]
[1.0f,0.0f]
[1.0f,1.0f]
[0.0f,1.0f]
for each face.

Maybe you could post a snippet of your texture coordinate parsing. Also, you may want to printout the texture coordinates at runtime after the completion of the obj parsing to ensure you are not seeing the above mentioned results.

I also assume that your entire terrain texture is one image?

Hi!
It looks like your texture coordinates are
[0.0f,0.0f]
[1.0f,0.0f]
[1.0f,1.0f]
[0.0f,1.0f]
for each face.

Maybe you could post a snippet of your texture coordinate parsing. Also, you may want to printout the texture coordinates at runtime after the completion of the obj parsing to ensure you are not seeing the above mentioned results.

I also assume that your entire terrain texture is one image?


going backwards:
yes it is one image.

the texture parsing code is in Java, here is the code:


private void processVTLine(String line){
String [] tokens=line.split("[ ]+"); //split the line at the spaces
int c=tokens.length;
for(int i=1; i<c; i++){ //add the vertex to the vertex array
vt.add(Float.valueOf(tokens));
}
}


The coordinates are:


0.983644, 0.001656, 0.992169, 0.001997, 0.99218, 0.009859, 0.983658, 0.009516,
0.975123, 0.001323, 0.975142, 0.009179, 0.992199, 0.017727, 0.983679, 0.017383,
0.975166, 0.017043, 0.96661, 0.001007, 0.966635, 0.008855, 0.958109, 7.17E-4,
0.958139, 0.008554, 0.966664, 0.016713, 0.958173, 0.0164, 0.992227, 0.025603,
0.983709, 0.025261, 0.9752, 0.024921, 0.992266, 0.033489, 0.983751, 0.033155,
0.975247, 0.03282, 0.966701, 0.024586, 0.958214, 0.024263, 0.966752, 0.032484,
0.958268, 0.032152, 0.949626, 4.66E-4, 0.949661, 0.008287, 0.941164, 2.62E-4,
0.941203, 0.008065, 0.949699, 0.016117, 0.941243, 0.015874, 0.932726, 1.14E-4,
0.932765, 0.007896, 0.924312, 2.6E-5, 0.924345, 0.007784, 0.932802, 0.015681,
0.924375, 0.015542, 0.949742, 0.023961, 0.941287, 0.023694, 0.949797, 0.031832,
0.941342, 0.03154, 0.932844, 0.023474, 0.924407, 0.023306, 0.932897, 0.03129,
0.924451, 0.031089, 0.992318, 0.041386, 0.983809, 0.041068, 0.975311, 0.040746,
....

etc. (long list)

And one more thing I forgot to mention:

the binding of the texture goes like this:


glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
glEnable(GL10.GL_TEXTURE_2D);
glBindTexture(GL10.GL_TEXTURE_2D, tex);
glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);


Where textureBuffer is made of the coordinates above.

Thanks.
We should probably take a look at where your code converts the vt collection to a floatBuffer, textureBuffer.



.
private void processVTLine(String line){
String [] tokens=line.split("[ ]+"); //split the line at the spaces
int c=tokens.length;
for(int i=1; i<c; i++){ //add the vertex to the vertex array
vt.add(Float.valueOf(tokens));
}
}



glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
glEnable(GL10.GL_TEXTURE_2D);
glBindTexture(GL10.GL_TEXTURE_2D, tex);
glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);


We should probably take a look at where your code converts the vt collection to a floatBuffer, textureBuffer.


Here it is:


public void createTextureBuffer() {
ByteBuffer bb = ByteBuffer.allocateDirect(vt.size() * 4);
bb.order(ByteOrder.nativeOrder());
textureBuffer = bb.asFloatBuffer();
textureBuffer.put(toPrimitiveArrayF(vt));
textureBuffer.position(0);
}
Hey again,
Can you confirm that
System.err.println(Arrays.toString(toPrimitiveArrayF(vt)));
gives you what you expect?


Here it is:


public void createTextureBuffer() {
ByteBuffer bb = ByteBuffer.allocateDirect(vt.size() * 4);
bb.order(ByteOrder.nativeOrder());
textureBuffer = bb.asFloatBuffer();
textureBuffer.put(toPrimitiveArrayF(vt));
textureBuffer.position(0);
}


going backwards:
yes it is one image.

the texture parsing code is in Java, here is the code:


private void processVTLine(String line){
String [] tokens=line.split("[ ]+"); //split the line at the spaces
int c=tokens.length;
for(int i=1; i<c; i++){ //add the vertex to the vertex array
vt.add(Float.valueOf(tokens));
}
}


The coordinates are:


0.983644, 0.001656, 0.992169, 0.001997, 0.99218, 0.009859, 0.983658, 0.009516,
0.975123, 0.001323, 0.975142, 0.009179, 0.992199, 0.017727, 0.983679, 0.017383,
0.975166, 0.017043, 0.96661, 0.001007, 0.966635, 0.008855, 0.958109, 7.17E-4,
0.958139, 0.008554, 0.966664, 0.016713, 0.958173, 0.0164, 0.992227, 0.025603,
0.983709, 0.025261, 0.9752, 0.024921, 0.992266, 0.033489, 0.983751, 0.033155,
0.975247, 0.03282, 0.966701, 0.024586, 0.958214, 0.024263, 0.966752, 0.032484,
0.958268, 0.032152, 0.949626, 4.66E-4, 0.949661, 0.008287, 0.941164, 2.62E-4,
0.941203, 0.008065, 0.949699, 0.016117, 0.941243, 0.015874, 0.932726, 1.14E-4,
0.932765, 0.007896, 0.924312, 2.6E-5, 0.924345, 0.007784, 0.932802, 0.015681,
0.924375, 0.015542, 0.949742, 0.023961, 0.941287, 0.023694, 0.949797, 0.031832,
0.941342, 0.03154, 0.932844, 0.023474, 0.924407, 0.023306, 0.932897, 0.03129,
0.924451, 0.031089, 0.992318, 0.041386, 0.983809, 0.041068, 0.975311, 0.040746,
....

etc. (long list)

And one more thing I forgot to mention:

the binding of the texture goes like this:


glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
glEnable(GL10.GL_TEXTURE_2D);
glBindTexture(GL10.GL_TEXTURE_2D, tex);
glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);


Where textureBuffer is made of the coordinates above.

Thanks.



You have more than 3 vt's per vertex. u v and w is optional. what are the other 5 coords?
I think you just need the first 2 vt's

for(int i=1; i<c; i++) // why are you starting at 1?
{
//add the vertex to the vertex array
vt.add(Float.valueOf(tokens));
}


try this:
for(int i=0; i < 2; i++)
{
vt.add(Float.valueOf(tokens));
}
I don't think that's his OBJ file output, that would be more like:

vt 0.476512 0.389626
vt 0.467080 0.662268
vt 0.485944 0.662267
vt 0.483396 0.389626
vt 0.469629 0.389626
vt 0.467080 0.389626
vt 0.485944 0.389626

I'm pretty sure that was just a raw dump of coords, maybe from sysout.


You have more than 3 vt's per vertex. u v and w is optional. what are the other 5 coords?
I think you just need the first 2 vt's

for(int i=1; i<c; i++) // why are you starting at 1?
{
//add the vertex to the vertex array
vt.add(Float.valueOf(tokens));
}


try this:
for(int i=0; i < 2; i++)
{
vt.add(Float.valueOf(tokens));
}

You have more than 3 vt's per vertex. u v and w is optional. what are the other 5 coords?
I think you just need the first 2 vt's

for(int i=1; i<c; i++) // why are you starting at 1?
{
//add the vertex to the vertex array
vt.add(Float.valueOf(tokens));
}


try this:
for(int i=0; i < 2; i++)
{
vt.add(Float.valueOf(tokens));
}


It starts from 1 because 0 is 'vt' from the OBJ file, one line of it looks like this:


vt 0.992678 0.073120


so only 1 and 2 are needed.



I don't think that's his OBJ file output, that would be more like:

vt 0.476512 0.389626
vt 0.467080 0.662268
vt 0.485944 0.662267
vt 0.483396 0.389626
vt 0.469629 0.389626
vt 0.467080 0.389626
vt 0.485944 0.389626

I'm pretty sure that was just a raw dump of coords, maybe from sysout.


The output you mentioned from System.err is the very same as the values that are in 'vt' array and in the file itself:


vt 0.983644 0.001656
vt 0.992169 0.001997
vt 0.992180 0.009859
vt 0.983658 0.009516
vt 0.975123 0.001323
vt 0.975142 0.009179
glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
glEnable(GL10.GL_TEXTURE_2D);
glBindTexture(GL10.GL_TEXTURE_2D, tex);
glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

I'm sorry I'm down to wild guesses now:
Are you sure you don't need to call

glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

before

glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

This topic is closed to new replies.

Advertisement