我正在尝试在OpenGL中创建一个简单的GUI。我创建了一张图片,所以我可以参考它并使解释更简单:
texture map http://img407.imageshack.us/img407/9016/textureg.png
当我将按钮纹理(32x32)应用到尺寸为120x20的四边形(即不是矩形作为纹理)时, ML 和 MR 拉伸成很粗的线条,使按钮看起来不美观。我知道通过为每个段创建一个新的四边形( TL , TM , TR 等)并应用部分对每个人的纹理,我可以避免失真,如图所示:
Distorted texture http://img84.imageshack.us/img84/8863/buttonlpf.png
问题#1:我可以以某种方式将源纹理的一部分应用于四边形的精确位置吗?我可以采用纹理的 TL / ML / BL 部分并在四边形的最左侧进行垂直拉伸,然后采用 TM / MM / BM 并使用前一部分旁边的水平拉伸等应用它们?它是否可能并且会更快,因为我只需要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
};
答案 0 :(得分:2)
我知道通过为每个片段(TL,TM,TR等)创建一个新的四边形多边形并将纹理的一部分应用到每个片段,我可以避免如图所示的失真< / p>
这正是你应该做的。
问题2:如果不可能,我将如何减少所需的顶点数?
当然,您可以共享边缘相交的顶点,因为纹理贴图在那里是连续的,只有一阶导数发生变化,这完全是有序的。
答案 1 :(得分:1)
我没有听说过任何有关拉伸纹理部分的信息。在您的情况下,不仅 ML 和 MR 被拉伸, MM 也会被拉伸。它只是不可见,因为 MM 是一种颜色。
关于您的问题...您可以将按钮的多边形划分为9个四边形,就像您发布的图片一样吗?然后,您可以切片纹理并将其不同部分应用于不同的四边形。这就是我现在所能想到的。
关于问题#2 - 我相信你应该看看顶点和索引缓冲区。基本上,顶点缓冲区是所有唯一顶点的缓冲区,索引缓冲区按顺序保存顶点缓冲区顶点的索引,当您从它们组装三角形时,它们会出现在顶点缓冲区中。在索引缓冲区中,索引可以出现多次(这是此缓冲区的目的 - 因此您不会多次使用相同的顶点)。
答案 2 :(得分:0)
而不是使用纹理坐标
的四个点绘制OpenGL多边形请尝试使用更多点来制作它,以便您可以控制纹理的哪个部分将被拉伸。参考你的图像,你可以在OpenGL中制作9个矩形,以避免边缘的拉伸。