我正在尝试在 OpenGL 中创建一个简单的 GUI。我创建了一张图片,因此我可以参考它并使解释更简单:
当我将按钮 (32x32) 的纹理应用到大小为 120x20 的四边形(即不是矩形作为纹理)上时,ML和MR被拉伸成非常粗的线条,这使得按钮看起来难看。我知道,通过为每个线段( TL、TM、TR等)创建一个新的四边形并将部分纹理应用到每个线段,我可以避免如图所示的失真:
问题 #1:我能否以某种方式将源纹理的一部分应用于四边形的确切位置?我可以取纹理的TL/ML/BL部分并在四边形的最左侧应用垂直拉伸,然后取TM/MM/BM并在前一部分旁边应用水平拉伸, ETC。?因为我只需要4个顶点,它甚至可能而且会更快吗?
- 换句话说,我可以只拉伸纹理的一部分吗?垂直拉伸一些部分,水平拉伸一些部分,然后将此多拉伸纹理应用于多边形?
问题#2:如果不可能,我将如何减少所需的顶点数量?创建 9x4vert 四边形需要 36 个顶点,但如果我让它们共享所有可以共享的顶点,我可以将这个数字减少到 16 个吗?
答案:
我一直在工作很长时间,手工绘制所有索引和坐标并将其放在纸上,所以我希望这对某人有用。我希望它是正确的,尽管它对我来说很好。它在 C# 中,但将其转换为 C++ 是微不足道的。
编辑:我一直在研究它,这是 3x3 平面的最终顶点/索引数组。
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
};