How to load .obj files with textures into JOGL/LWJGL program

Hello,
So I posted a topic before on how to load an .obj file into a JOGL program and I successfully did that using this loader, but now I’m having a problem with loading the textures, I tried binding the textures with the object but that seemed impossible since I can’t use the glTexCoord2f with a 3D object (or can I?) so my question now is how to load an object with the textures that it already has for example I want to load this car from here which comes with the textures as JPG files?

Thanks,
Lawa

How are you feeding the model data to OpenGL?

The .obj file will contain vertex positions, texture coordinates, possibly normals. These are all “vertex attributes.” It seems you’re familiar with the immediate mode functions used to set the values of these attributes: glVertex3f for position, glColor3f for colour, and so on. What you need to do is find exactly where and how you’re taking vertex positions from the .obj loader, and using them to specify vertex positions in OpenGL. Then you should add the texture coordinate attribute in the same way. Depending on how you’re drawing your model, this might (roughly speaking) mean adding a call to glTexCoord2f next to glVertex3f, or a call to glTexCoordPointer next to glVertexPointer, or an additional call to glVertexAttribPointer.

You should also find the documentation for these functions and read it carefully. For instance, when you use glVertexAttribPointer to define an array of vertex attributes, you also need to enable that array using glEnableVertexAttribArray before actually making the draw call (e.g. with glDrawArrays or glDrawElements). Again, the specifics vary depending on the API subset you’re using.

I can point you to more specific information once you describe how exactly you’re rendering the model right now.

I’m not sure I understand your question very because as I said above I use that loader to load the .obj (not even changed anything because this is my first time dealing with .obj files)
and here is how it goes on (loading the files into the world)

First of all I create an object from SimpleArrayObjFile (Yes the same exact SimpleArrayObjFile as in the link I posted above)

SimpleArrayObjFile obj

Second I initialize the object in run() method such as this

obj = new SimpleArrayObjFile();
obj.load("res/L200/L200-OBJ.obj");
obj.dump();

Third and last step is where I place the final part of the code to actually make the shape appear and thats in render() method :

glPushMatrix();
glRotatef(rotation.x,1f,0f,0f);
glRotatef(rotation.y, 0f, 1f, 0f);
glRotatef(rotation.z, 0f, 0f, 1f);
glTranslatef(location.x, location.y, location.z);		
GL11.glPointSize(3.0f);
GL11.glLineWidth(2.0f);
GL11.glColor4f(0.5f,0.5f,0.5f,0.25f);
SimpleObjFileTools.drawFaces(obj1);
SimpleObjFileTools.drawQuads(obj1);
GL11.glColor4f(0.1f,0.1f,0.1f,1.0f);
SimpleObjFileTools.drawPoints(obj1);
glPopMatrix();

And thats how I draw the shapes into my world, and again the SimpleObjFileTools, SimpleOBJFile, SimpleOBJFileAdapter, SimpleArrayObjFile that I use are the same exact as the ones in this post.

Thanks for the help!

Which version of OpenGL do you target?

currently I’m using lwjgl-2.9.3 , does that answer the question ?

OpenGL profile such as 2.1, 3.3, 4.5…

Or which graphic card are you using?

Not quite sure about the OpenGL as I don’t know how to check that , but my graphic card is AMD Radeon 8730M

Well, then you can and should avoid deprecated OpenGL… no more glRotatef or glVertex3f

it will be a little harder at the begin, but then you will truly know how OpenGL works

Alright sorry about that last reply , apperantly I haven’t installed my AMD drivers so my Intel HD 4000 is working atm

Which shows that I have OpenGL 4.0

and the main reason that I’m still using glRotate and glVertex is because I want this for a university project, but in future development I’ll most probably not go with these setting that I have now

So any suggestions on how to load the textures on these settings here?

In the drawFaces method, you’ll find this:


final SimpleArrayObjFile.ivec3 face       = obj.faces.get(i);
final SimpleArrayObjFile.ivec3 faceNormal = obj.faceNormals.get(i);
//
final SimpleArrayObjFile.vec3  v_a        = obj.vertices.get(face.x);
final SimpleArrayObjFile.vec3  v_b        = obj.vertices.get(face.y);
final SimpleArrayObjFile.vec3  v_c        = obj.vertices.get(face.z);
//
final SimpleArrayObjFile.vec3  vn_a       = obj.normals.get(faceNormal.x);
final SimpleArrayObjFile.vec3  vn_b       = obj.normals.get(faceNormal.y);
final SimpleArrayObjFile.vec3  vn_c       = obj.normals.get(faceNormal.z);

setColorFromNormal(vn_a);
GL11.glVertex3f(v_a.x,v_a.y,v_a.z);
setColorFromNormal(vn_b);
GL11.glVertex3f(v_b.x,v_b.y,v_b.z);
setColorFromNormal(vn_c);
GL11.glVertex3f(v_c.x,v_c.y,v_c.z);

SimpleArrayObjFile has the following members:


public ArrayList<vec3>  vertices          = null;
public ArrayList<vec2>  textureCoords     = null;
public ArrayList<vec3>  normals           = null;
public ArrayList<ivec3> faces             = null;
public ArrayList<ivec3> faceNormals       = null;
public ArrayList<ivec3> faceTextureCoords = null;

Given my advice above, can you see what needs to change in the drawFaces method? Once you figure that out, similar changes will have to be made in drawQuads.

so I guess I’ll have to add the glTexCoord2f before the GL11.glVertex3f ? but how could that work ? I mean the glTexCoord2f needs a 1 and a 0 parameters how would I work that out? I really don’t understand …

Re-read my first post here.

[quote=“boxsmith,post:2,topic:56443”]
You need to take the texture coordinates from the .obj file. We know they’re in there, somewhere.

Look again at the code I pasted. Do you see the lines where the drawFaces method takes vertex positions from the SimpleArrayObjFile? How about the normals? Which SimpleArrayObjFile members does the method access to get these values? Can you guess which member might store texture coordinates?

[quote=“Lawa,post:11,topic:56443”]
Correction: the parameters can be any numbers, really. But we tend to keep them within [0, 1] so as to not exceed the boundaries of the texture. If you wanted your texture to repeat across a surface, you could use coordinates outside this range.

[quote=“boxsmith,post:12,topic:56443”]
Re-read my first post here.

[quote=“boxsmith,post:2,topic:56443”]
You need to take the texture coordinates from the .obj file. We know they’re in there, somewhere.

Look again at the code I pasted. Do you see the lines where the drawFaces method takes vertex positions from the SimpleArrayObjFile? How about the normals? Which SimpleArrayObjFile members does the method access to get these values? Can you guess which member might store texture coordinates?

I’m getting confused as I never worked with an .obj file before, can you point me to a code example so I know how things work? or maybe have a conversation with you if its possible ofcourse?

Sure! If you have skype we can chat there. If that works for you, PM me your handle.

Awesome , I’m gonna PM you my skype name

Solved Thanks to boxsmith for his help.

I wrote a parser some time ago, it’s pretty full featured. It will take care of all of the parsing of the file and let you concentrate on writing the OpenGL code. (There is also some ‘old’ style OpenGL example code using LWJGL but if you’re new to OpenGL you’re much better off learning the modern approach to OpenGL instead.)

System.out.println(GL11.glGetString(GL11.GL_VERSION));

This will make a quick check to your version.

With LWJGL2.9.3, you use the Display class. You can control which version you use by using ContextAttribs.

Display.setDisplayMode(new DisplayMode(800,600));
final ContextAttribs context = new ContextAttribs(REQUIRED_MAJOR_VERSION, REQUIRED_MINOR_VERSION);
Display.create(new PixelFormat(), context);

With context attribs, you can set different things such as forward compatible and core profile. Stuff which you shouldn’t know yet, but its worth looking into.

You are learning opengl, and its a big thing to handle. I suggest watching these videos: http://www.youtube.com/thinmatrix Please note that his videos have the content, but aren’t written to optimum neatness, but structured in a way where each function, regardless if called once or not, does a specific step.

Make sure you target OpenGL version 3.2 to 4.5