繁体   English   中英

纹理映射 - 拉伸

[英]Texture mapping - Stretching

我试图在OpenGL中创建一个简单的GUI。 我创建了一张图片,所以我可以参考它并使解释更简单:

纹理贴图

当我将按钮(32x32)的纹理应用到尺寸为120x20的四边形(即不是矩形作为纹理)时, MLMR会拉伸成非常粗的线条,这会使按钮看起来不美观。 我知道通过为每个段( TLTMTR等)创建一个新的四边形多边形并将纹理的一部分应用到每个段,我可以避免失真,如图所示:

扭曲的纹理

问题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
                                      };

我知道通过为每个段(TL,TM,TR等)创建一个新的四边形多边形并将纹理的一部分应用到每个段,我可以避免失真,如图所示

这正是你应该做的。

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

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

我没有听说过任何关于拉伸纹理部分的信息。 在你的情况下,不仅MLMR被拉伸, MM也被拉伸。 它只是不可见,因为MM是一种颜色。

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

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

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

请尝试使用更多的点,以便您可以控制纹理的哪个部分将被拉伸。 参考你的图像,你可以在OpenGL中制作9个矩形,以避免边缘的拉伸。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM