I am attempting to create a simple GUI in OpenGL. I have created a picture so I can refer to it and make the explanation simpler:
When I apply a texture of a button (32x32) onto a quad polygon with the size of 120x20 (i.e. not a rectangle as the texture), ML and MR get stretched into very thick lines and it makes the button look unsightly. I know that by creating a new quad polygon for each of the segments (TL, TM, TR, etc.) and applying a part of the texture to each of them, I can avoid the distortion as shown in the picture:
Question #1: Can I somehow apply parts of a source texture on exact position of a quad polygon? Could I take the TL/ML/BL part of the texture and apply it with vertical stretching on the left-most side of the quad polygon, then take TM/MM/BM and apply them with horizontal stretching right next to the previous part, etc.? Is it even possible and would it be faster, since I'd only need 4 vertices?
- To rephrase, could I stretch only parts of a texture? Stretch some parts vertically and some parts horizontally and then apply this multi-stretched texture to a polygon?
Question #2: If it's not possible, how would I go about reducing the number of vertices needed? Creating 9x4vert quads needs 36 vertices, but if I made them share all the vertices that can be shared, I could reduce this number to 16?
The answer:
I have been working very long, drawing all the indices and coordinates by hand and putting it together on paper, so I hope this will be useful to someone. I hope it is correct, although it works fine for me. It is in C#, but translating it to C++ is trivial.
Edit: I've been working on it a whole lot longer and this is the final vertex/index array for a 3x3 plane.
public Vector3[] VertexData = new[]
{
new Vector3(-1.0f, -1.0f, 0.0f),
new Vector3(-0.33f, -1.0f, 0.0f),
new Vector3(0.33f, -1.0f, 0.0f),
new Vector3(1.0f, -1.0f, 0.0f),
new Vector3(-1.0f, -0.33f, 0.0f),
new Vector3(-0.33f, -0.33f, 0.0f),
new Vector3(0.33f, -0.33f, 0.0f),
new Vector3(1.0f, -0.33f, 0.0f),
new Vector3(-1.0f, 0.33f, 0.0f),
new Vector3(-0.33f, 0.33f, 0.0f),
new Vector3(0.33f, 0.33f, 0.0f),
new Vector3(1.0f, 0.33f, 0.0f),
new Vector3(-1.0f, 1.0f, 0.0f),
new Vector3(-0.33f, 1.0f, 0.0f),
new Vector3(0.33f, 1.0f, 0.0f),
new Vector3(1.0f, 1.0f, 0.0f)
};
public Vector3[] NormalData = new[]
{
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f),
new Vector3(0f, 0f, 1f)
};
public Vector2[] TextureData = new[]
{
new Vector2(0.0f, 1.0f),
new Vector2(0.33f, 1.0f),
new Vector2(0.66f, 1.0f),
new Vector2(1.0f, 1.0f),
new Vector2(0.0f, 0.66f),
new Vector2(0.33f, 0.66f),
new Vector2(0.66f, 0.66f),
new Vector2(1.0f, 0.66f),
new Vector2(0.0f, 0.33f),
new Vector2(0.33f, 0.33f),
new Vector2(0.66f, 0.33f),
new Vector2(1.0f, 0.33f),
new Vector2(0.0f, 0.0f),
new Vector2(0.33f, 0.0f),
new Vector2(0.66f, 0.0f),
new Vector2(1.0f, 0.0f)
};
public UInt32[] IndicesData = new UInt32[54]
{
0, 1, 5,
0, 4, 5,
1, 2, 6,
1, 5, 6,
2, 3, 7,
2, 6, 7,
4, 5, 9,
4, 8, 9,
5, 6, 10,
5, 9, 10,
6, 7, 11,
6, 10, 11,
8, 9, 13,
8, 12, 13,
9, 10, 14,
9, 13, 14,
10, 11, 15,
10, 14, 15
};