2012-08-09 146 views
2

我正在尝试在OpenGL中创建一个简单的GUI。我创建了一个画面,所以我可以参考,并做出解释简单:纹理映射 - 拉伸

texture map http://img407.imageshack.us/img407/9016/textureg.png

当我申请一个按钮(32×32)的纹理到四多边形的120x20(即不是大小矩形作为纹理),MLMR被拉伸成非常粗的线条,并使按钮看起来难看。我知道通过为每个片段创建一个新的四边形多边形(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 
             }; 

回答

2

我知道通过为每个区段(TL,TM,TR等)创建一个新的四多边形和施加纹理它们中的每一个部分,我能避免失真,如图图片

而这正是你应该的。

问题2:如果这是不可能的,我将如何去减少所需的顶点数量?

当然,您可以共享边缘相交的顶点,因为您的纹理映射在那里是连续的,只有一阶导数完全按顺序变化。

+0

我该如何分享顶点?是否有可以提供的代码片段或者可能是关键字,以便我可以自行搜索? – 2012-08-09 13:47:42

+0

使用指定顶点/纹理坐标的顶点数组并使用glDrawElemets绘制它,其中索引数组引用顶点数组索引。 – datenwolf 2012-08-09 14:37:41

1

我还没有听到任何关于拉伸纹理的部分。在您的情况下,不仅MLMR正在拉伸,MM也拉伸。它只是不可见,因为MM是一种颜色。

关于你的问题......你可以将按钮的多边形划分为9个四边形,就像你发布的图片一样?然后,您可以切割纹理并将其不同部分应用于不同的四边形。这是我现在所能想到的。

关于问题#2 - 我相信你应该看看顶点和索引缓冲区。基本上,顶点缓冲区是所有唯一顶点的缓冲区,索引缓冲区按顺序保存来自顶点缓冲区的顶点索引,当您从它们组装三角形时,它们会出现在其中。在索引缓冲区中,索引可以多次出现(这是此缓冲区的用途 - 因此,您不会有多于一次的顶点)。

+0

我有点明白你的意思与指数,我会尽力找到更多的信息 – 2012-08-09 13:48:42

0

而是每个纹理四点绘制的OpenGL多边形的坐标

请尝试使用更多的点来使,所以你可以控制纹理的一部分将被拉长。提到你的图像,你可以在OpenGL中制作9个矩形,以避免边缘的伸展。