【问题标题】:Texture mapping - Stretching纹理映射 - 拉伸
【发布时间】:2019-08-23 13:31:46
【问题描述】:

我正在尝试在 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
                                      };

【问题讨论】:

    标签: c# c++ opengl


    【解决方案1】:

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

    这正是你应该做的。

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

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

    【讨论】:

    • 如何共享顶点?是否有您可以提供的 sn-p 代码或关键字,以便我可以自己搜索?
    • 使用指定顶点/纹理坐标的顶点数组并使用 glDrawElemets 绘制它,其中索引数组引用顶点数组索引。
    【解决方案2】:

    我还没有听说过关于拉伸纹理部分的消息。在您的情况下,不仅 MLMR 被拉伸,MM 也被拉伸。它只是不那么明显,因为 MM 是一种颜色。

    关于您的问题...您可以将按钮的多边形划分为 9 个四边形,就像您发布的图片中一样?然后,您可以对纹理进行切片并将其不同部分应用到不同的四边形上。目前我能想到的就这些了。

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

    【讨论】:

    • 我有点理解您对索引的意思,我会尝试查找更多信息
    【解决方案3】:

    而不是用四个点绘制 OpenGL 多边形,每个点都有纹理坐标

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      • 2011-03-16
      相关资源
      最近更新 更多