How to handle single vertex with multiple uv co-ordinates?

Hi,

I’m trying to get a texture a cube, however I’ve come across an issue, and I have no idea how I go about solving it.

Here’s an image to try assist with explanation of my problem.

http://imageshack.com/a/img809/6545/z9sr.png

This is what the cube is like UV un-wraped, 14 co-ordinates to 8 vertices.
Now, as you can see there are several circle, each one represents a single vertex by color.
So you can see, some vertices appear in multiple places, each place being a unique UV co-ordinate.
With that in mind, how do I tell OpenGL that a vertex may have more than one UV co-ordinate.
I understand how to do it in the case of it being one-to-one.

I’m using LWJGL v2.9.1
The OpenGL version I’m focusing on is v4.X

If I poorly explained this, I apologize, I will try my best to answer any questions regarding it.

when drawing a cube (In Immediate Mode?) you should have 6 parts, the 6 faces you draw. The Cube has 8 different Vertices but you have to use each Vertice 3 times (Because there’s 6 faces touching it). So you use the Texture coordinate corresponding to the Face you’re drawing

What about when I’m using VBOs in a VAO?

Its the same idea. You have to pass in texture coordinates via a floatbuffer (you already use one for the vertex positions).

You don’t only have 8 vertices as you think. Instead you have 24, because a vertex is the entirety of its data not only the position.

[quote]Its the same idea. You have to pass in texture coordinates via a floatbuffer (you already use one for the vertex positions).
[/quote]
How do I then tell OpenGL what order that these occur?

Here’s the actual data:


v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 0.500000 0.500000
vt 0.250043 0.500000
vt 0.250043 0.250043
vt 0.749957 0.500000
vt 0.749957 0.250043
vt 0.999913 0.500000
vt 0.500000 0.749957
vt 0.000087 0.500000
vt 0.500000 0.000087
vt 0.749957 0.000087
vt 0.500000 0.250043
vt 0.749957 0.749957
vt 0.999913 0.250043
vt 0.000087 0.250043
f 1/1 2/2 3/3
f 5/4 8/5 6/6
f 1/1 5/4 2/7
f 2/2 6/8 3/3
f 3/9 7/10 8/5
f 5/4 1/1 8/5
f 4/11 1/1 3/3
f 5/4 6/12 2/7
f 1/1 4/11 8/5
f 8/5 7/13 6/6
f 4/11 3/9 8/5
f 6/8 7/14 3/3

(I deleted some stuff, I don’t really think it was necessary, s, usemtl. It’s a Wavefront .obj file)

Do I pass it in the same order as the vt (the UV co-ordinates) section, or do I pass the corresponding co-ordinate in the f (order of vertices to create a triangle with corresponding UV co-ordinates) section?

OpenGL does not understand the structure used in the OBJ format. You will have to create vertices (with their attributes) using the ‘f’ faces as your primairy source. With them you create your triangles one by one, by looking up the ‘v’ vertices and ‘vt’ texcoords. You send your resulting set of triangles to OpenGL using either immediate mode (to see whether the output looks correct) or VBO, to make it speedy.

I currently have 2 VBOs one for vertex, the other for UVs (v’s and vts respectively), I then I have another buffer (stores the f values - 1) to tell OpenGL what order to draw the triangles from the vertex data, I pass this buffer in the call to glDrawElements.

So how do I tell OpenGL when to use a certain vt?
Like the way I have for the vertex data.

I’m finding it difficult to describe what exactly I’m asking beyond what I have already stated.

Also, I don’t really want to use immediate mode as it’s depreciated.

Would it help if I provided my code and explained it, the way the “custom” parts work, like what data I get and from where?

You have to use faces to do this correctly as you can not use indices if one vertex has multiple attributes of the same type so you gotta cut it up by parsing the faces. Read this:www.opengl-tutorial.org/beginners-tutorials/tutorial-7-model-loading/ (on my phone in class can’t be more specific atm)

First of all, your view on what vertex data is, is wrong.

Vertex data is the entirety of all attributes of a single data point. Such data points(vertices) are than used in some way to render OpenGL primitives(triangles, quads).

You do have in most cases a position attribute (a “v” attribute in the OBJ format). The OBJ format lets you define a face (triangle) through a lookup of up to three attributes (position, uv, normal), it does this to safe space in the file.

OpenGL does expect to get all vertex attributes with one lookup(index), because of this the data-view of the OBJ format is incompatible. You have to create an independent data-point for each combination of single attributes in the OBJ file to be able to use it in OpenGL.

=>
A cube has 8 geometrical points(corners) => 8 distinctive position attributes.
Each corner belongs to 3 faces of the cube and each face has an own uv space.
=> 8 * 3 gives a total of 24 combinations => you have to create a VBO which holds 24 distinct vertices.

Ah ok, thanks guys, I think I understand, well, more than I did, I’ll get back if I have any issues.
I have some work to do :slight_smile:
Also, quick question, is what you’re on about also called “interleave”? I did read I bit about it, not much though.

Not really. but the faces can be used to facilitate interleaving. I’m out of class and on a laptop so ill write out an explanation to your problem and also explain interleaving a bit.
imagine the vertices of your points in open space without any faces.
Imagine how many random triangles you can make using these points, however if you put the triangles together using the vertices in the correct way it forms a cube.
So now imagine your cube cut up into triangles.
now imagine one of the corners. see how 3 of the triangles touch this corner.
In openGL, you have to describe each triangles points separately since openGL only thinks in terms of triangles, this is why you would need 24 vertices as mentioned before.
So you would make a buffer for the vertices then make another one that gives the program the UV coordinates in the same order as the coorspoinding verticies. A vertex shader will take the first vertex position and uv position and combine them into the final vertex. Instead of giving your graphics card two buffers to look through and keep track of you can put the data together into one buffer by interleaving them and explain this to openGL. this woud be done by first putting the vertex point (v) and then the UV coord (t) and keep alternating so your buffer looks like :
v1 t1 v2 t2 v3 t3… etc
two separate buffers would be:
buffer 1: v1 v2 v3 …
buffer 2: t1 t2 t3…

Sorry to post after so long, I just wanted to say that I managed to get it to work.
Thanks for the help guys :smiley: