Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Generate UV texture coordinates?

This thread is locked; no one can reply to it. rss feed Print
Generate UV texture coordinates?
Thomas Fjellstrom
Member #476
June 2000
avatar

I'm wondering how to generate tex coords easily if all I have is a list of vertices. I've found some stuff on the web (ex: http://paulyg.f2s.com/uv.htm) but I can't seem to get it to work with my simple cube example.

Basically I have an array of floats, 3 per verticy * 36 to make up a cube. Applying the math on the above page leads to two faces being correct, but at least two being incorrect (end up being stripes).

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Arthur Kalliokoski
Second in Command
February 2005
avatar

You can unwrap the vertices with Blender and export to Wavefront OBJ. Or you just want a list of vertices for a cube here?

They all watch too much MSNBC... they get ideas.

Thomas Fjellstrom
Member #476
June 2000
avatar

I have the vertices, I would like to calculate the texture coordinates.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Arthur Kalliokoski
Second in Command
February 2005
avatar

The texture coordinates are vertices, too. (albeit they're in 2D) :P

You want a mini example program for a cube to get the numbers or you want the general case?

I don't see what's wrong with that link you posted, maybe you should try putting different colors at each corner to check your assumptions about which corner is which.

[EDIT]

It just occurs to me that the 0.0 - 1.0 thing in the link you posted works for a separate image on each face, but the video would show stuff like 0.6 etc. to map one image across all faces.

They all watch too much MSNBC... they get ideas.

Thomas Fjellstrom
Member #476
June 2000
avatar

I have no assumptions. :P That code doesn't make assumptions either.

Here is the code I'm using:

#SelectExpand
1float cube[NUM_VERTS * 5] = { 2 -1.0f,-1.0f,-1.0f, // triangle 1 : begin 3 -1.0f,-1.0f, 1.0f, 4 -1.0f, 1.0f, 1.0f, // triangle 1 : end 5 1.0f, 1.0f,-1.0f, // triangle 2 : begin 6 -1.0f,-1.0f,-1.0f, 7 -1.0f, 1.0f,-1.0f, // triangle 2 : end 8 1.0f,-1.0f, 1.0f, 9 -1.0f,-1.0f,-1.0f, 10 1.0f,-1.0f,-1.0f, 11 1.0f, 1.0f,-1.0f, 12 1.0f,-1.0f,-1.0f, 13 -1.0f,-1.0f,-1.0f, 14 -1.0f,-1.0f,-1.0f, 15 -1.0f, 1.0f, 1.0f, 16 -1.0f, 1.0f,-1.0f, 17 1.0f,-1.0f, 1.0f, 18 -1.0f,-1.0f, 1.0f, 19 -1.0f,-1.0f,-1.0f, 20 -1.0f, 1.0f, 1.0f, 21 -1.0f,-1.0f, 1.0f, 22 1.0f,-1.0f, 1.0f, 23 1.0f, 1.0f, 1.0f, 24 1.0f,-1.0f,-1.0f, 25 1.0f, 1.0f,-1.0f, 26 1.0f,-1.0f,-1.0f, 27 1.0f, 1.0f, 1.0f, 28 1.0f,-1.0f, 1.0f, 29 1.0f, 1.0f, 1.0f, 30 1.0f, 1.0f,-1.0f, 31 -1.0f, 1.0f,-1.0f, 32 1.0f, 1.0f, 1.0f, 33 -1.0f, 1.0f,-1.0f, 34 -1.0f, 1.0f, 1.0f, 35 1.0f, 1.0f, 1.0f, 36 -1.0f, 1.0f, 1.0f, 37 1.0f,-1.0f, 1.0f 38 }; 39 40 float lowest = -1; 41 float highest = 1; 42 float range = (lowest - highest) * -1.0; 43 float offset = 0.0 - lowest; 44 45 // for 1/-1 46 // range = (-1 - 1) * -1 == 2 47 // offset = 0 - -2 == 2 48 49 float *ptr = buff; 50 for(int i = 0; i < NUM_VERTS; i++) 51 { 52 int idx = i*3; 53 *ptr = cube[idx] + xoff; ptr++; 54 *ptr = cube[idx+1] + yoff; ptr++; 55 *ptr = cube[idx+2] + zoff; ptr++; 56 57 float absx = (cube[idx] + offset); 58 float absy = (cube[idx+1] + offset); 59 60 *ptr = (absx / range) * tx_fact + tx_x; ptr++; 61 *ptr = (absy / range) * tx_fact + tx_y; ptr++; 62 *ptr = tx_page; ptr++; 63 }

The second last two items are the u/v cords. ignore tx_* variables. tx_fact is 1.0, tx_x, and tx_y are both 0.0. They will be used, but im still trying to get the basics to work...

Assuming I've got the math right, it results in this:
{"name":"608942","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/d\/1d266d38100cf683540896fa2e1de3d6.png","w":1030,"h":795,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/d\/1d266d38100cf683540896fa2e1de3d6"}608942

Not quite correct :(

It just occurs to me that the 0.0 - 1.0 thing in the link you posted works for a separate image on each face, but the video would show stuff like 0.6 etc. to map one image across all faces.

The link is actually trying to map a single texture onto a mesh... So maybe it isn't the right thing to use here, but I was hoping it'd work. I'm currently just trying to use a single texture, with it being identical on all sides (not stretching over the cube, or doing a kind of wrapping of the image around the cube, later i might use cube maps or something, but not right now).

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Arthur Kalliokoski
Second in Command
February 2005
avatar

I made a little program to draw one image on each face of a cube, which wobbles around so you can see all sides. Each face is tinted differently.

I compiled it with

gcc -s -O2 -Wall t.c -o t -lallegro -lallegro_image -lGLU -lm

{"name":"608943","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/7\/17c89e4e445aa05757fa10ebd170bd77.png","w":802,"h":626,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/7\/17c89e4e445aa05757fa10ebd170bd77"}608943

[EDIT]

Hey, now I know where I'd seen your texture before! You're trying to make a Minecraft clone, aren't you?

They all watch too much MSNBC... they get ideas.

Thomas Fjellstrom
Member #476
June 2000
avatar

Hey, now I know where I'd seen your texture before! You're trying to make a Minecraft clone, aren't you?

I don't know if it'll get that far. So far its a little C++ Allegro5 MC Map Viewer. I had it actually loading and drawing a chunk, but textureless, which is rather anticlimactic.

Hm, your code doesn't actually calculate the uv coords though :( If you used the same vertex values I could temporarily thief your uv coords, but I'd like a way to generate the uv coords... Though for later things I may be using 3d models.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Arthur Kalliokoski
Second in Command
February 2005
avatar

Hm, your code doesn't actually calculate the uv coords though

If you look again, all the glTextureCoord2f() calls repeat exactly the same for each face.

			glTexCoord2f(0.0,1.0);	//upper left

			glTexCoord2f(0.0,0.0);	//lower left

			glTexCoord2f(1.0,1.0);	//upper right

			glTexCoord2f(1.0,1.0);	//upper right again

			glTexCoord2f(0.0,0.0);	//lower left

			glTexCoord2f(1.0,0.0);	//lower right

And if you used triangle strip you could eliminate the second "upper right" call.

They all watch too much MSNBC... they get ideas.

Thomas Fjellstrom
Member #476
June 2000
avatar

If you look again, all the glTextureCoord2f() calls repeat exactly the same for each face.

You're hardcoding them, not calculating them ;)

Quote:

And if you used triangle strip you could eliminate the second "upper right" call.

Sharing vertices can break some things. Especially when you get into texture atlasing. You will need completely separate uv coords per vertex especially if you want to use more than one texture per block (grass has three, dirt, grass top, and dirt+grass sides).

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Arthur Kalliokoski
Second in Command
February 2005
avatar

You're hardcoding them, not calculating them

A minor detail. Since they repeat endlessly, you could have had a loop that iterated over an array, with the array values grabbed from the example.

Quote:

Sharing vertices can break some things. Especially when you get into texture atlasing. You will need completely separate uv coords per vertex especially if you want to use more than one texture per block (grass has three, dirt, grass top, and dirt+grass sides).

So you'd need to start/stop each face, no problem. In other words, I'd have used glBegin(GL_TRIANGLE_STRIP) for each face with a glEnd() following each face instead of GL_TRIANGLES

They all watch too much MSNBC... they get ideas.

Thomas Fjellstrom
Member #476
June 2000
avatar

A minor detail. Since they repeat endlessly, you could have had a loop that iterated over an array, with the array values grabbed from the example.

You seem to be misunderstanding. By calculate or generate I mean using actual math and code, and not hardcoding them.

Quote:

So you'd need to start/stop each face, no problem. In other words, I'd have used glBegin(GL_TRIANGLE_STRIP) for each face with a glEnd() following each face instead of GL_TRIANGLES

I suppose I could. But its just as easy to use a triangle list.

Also I'm not using the gl immediate api, but OpenGL 3, so the old apis aren't available. I have to use Shaders and Vertex Buffer Objects. (but don't worry, I have all the code for it already)

append: For now I've just stolen data from an exported blender .obj after figuring out how to actually get it to export the uv coordinates properly.

I restructured things a little bit as well.

#SelectExpand
1 const int NUM_VERTS_SHARED = 8; 2 VF3 verts[NUM_VERTS_SHARED] = { 3 { 1.000000, -1.000000, -1.000000 }, 4 { 1.000000, -1.000000, 1.000000 }, 5 { -1.000000, -1.000000, 1.000000 }, 6 { -1.000000, -1.000000, -1.000000 }, 7 { 1.000000, 1.000000, -1.000000 }, 8 { 0.999999, 1.000000, 1.000000 }, 9 { -1.000000, 1.000000, 1.000000 }, 10 { -1.000000, 1.000000, -1.000000 } 11 }; 12 13 VF2 txcs[NUM_VERTS_SHARED] = { 14 { 0.000000, -1.000000 }, 15 { -1.000000, -1.000000 }, 16 { -1.000000, 0.000000 }, 17 { -1.000000, 1.000000 }, 18 { -0.000000, -0.000000 }, 19 { -0.000000, 1.000000 }, 20 { 1.000000, 1.000000 }, 21 { 1.000000, 0.000000 } 22 }; 23 24 const int NUM_FACES = 12; 25 VI3 vtxFaces[NUM_FACES] = { 26 { 2, 3, 4 }, 27 { 8, 7, 6 }, 28 { 1, 5, 6 }, 29 { 2, 6, 7 }, 30 { 7, 8, 4 }, 31 { 1, 4, 8 }, 32 { 1, 2, 4 }, 33 { 5, 8, 6 }, 34 { 2, 1, 6 }, 35 { 3, 2, 7 }, 36 { 3, 7, 4 }, 37 { 5, 1, 8 } 38 }; 39 40 41 VI3 txFaces[NUM_FACES] = { 42 { 1, 2, 3 }, 43 { 4, 3, 5 }, 44 { 5, 6, 4 }, 45 { 5, 6, 4 }, 46 { 6, 7, 8 }, 47 { 1, 2, 3 }, 48 { 5, 1, 3 }, 49 { 6, 4, 5 }, 50 { 3, 5, 4 }, 51 { 3, 5, 4 }, 52 { 5, 6, 8 }, 53 { 5, 1, 3 } 54 }; 55 56 CUSTOM_VERTEX *ptr = buff; 57 58 for(int i = 0; i < NUM_FACES; i++) 59 { 60 VI3 &vtxface = vtxFaces[i]; 61 VI3 &txface = txFaces[i]; 62 63 for(int j = 0; j < 3; j++) 64 { 65 VF3 &vert = verts[vtxface.i[j]-1]; 66 VF2 &txc = txcs[txface.i[j]-1]; 67 68 CUSTOM_VERTEX &cv = *ptr++; 69 70 cv.pos = vert; 71 cv.txcoord = txc; 72 cv.tx_page = 1.0; 73 } 74 }

So yeah, it works now. But I'd still like to see if theres a way to generate the uv coords from the vtx coords.

append:

So I finally have something that resembles something.

{"name":"EKwPne1.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/d\/0d9a54103ddc56f86db2906233403003.png","w":1030,"h":795,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/d\/0d9a54103ddc56f86db2906233403003"}EKwPne1.png

Now with hacked in leaf, grass and log textures:

{"name":"Ze4gsEU.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/9\/b99dde961377b18fa6df5f746670de35.png","w":1030,"h":795,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/b\/9\/b99dde961377b18fa6df5f746670de35"}Ze4gsEU.png

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Arthur Kalliokoski
Second in Command
February 2005
avatar

I'd still like to see if theres a way to generate the uv coords from the vtx coords.

I don't ever remember seeing such a calculation except for some gluCylinder etc. which is just a convenience, you could find the code in the Mesa source.

Googling a bit found this for Direct X and this for Open GL. Maybe the Mesa code used the latter, I don't remember.

That said, why would mapping a few square faces need such a thing?

They all watch too much MSNBC... they get ideas.

Elias
Member #358
May 2000

To use that, he'd have to define 6 planes to project his cube to each plane, to get the UV coordinates for each side. And the result would be 0/0, 0/1, 1/0, 1/1 every time :p

--
"Either help out or stop whining" - Evert

Thomas Fjellstrom
Member #476
June 2000
avatar

That said, why would mapping a few square faces need such a thing?

Learning exercises. Also I may have other shapes. but I'll probably just use models for the non cubic objects.

append:

{"name":"OtR0m0b.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/3\/a36e3fa9ad430ec858fe52ea0223922d.png","w":1030,"h":795,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/3\/a36e3fa9ad430ec858fe52ea0223922d"}OtR0m0b.png

Latest version \o/

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Thomas Fjellstrom
Member #476
June 2000
avatar

That's probably an artifact of the FOV, and the shape of the terrain. Mostly the FOV though. It's set to 90 right now :D

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

relpatseht
Member #5,034
September 2004
avatar

I meant to reply to this a while ago, but I forgot.

I've attached an excerpt from a primitive generator I made awhile ago. It should contain what you're looking for and then some.

It does vertices, texture, normals, tangents and bitangents for planes, cylinders, cubes, spheres, and cones, with configurable stacks and slices for each.

Thomas Fjellstrom
Member #476
June 2000
avatar

OOh, thanks man. I'll take a look at that while I'm in the philippines (or thailand). Assuming work isn't too hectic of course.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Go to: