C++ DirectX - 对 2D 网格进行纹理化
Posted
技术标签:
【中文标题】C++ DirectX - 对 2D 网格进行纹理化【英文标题】:C++ DirectX - texturing a 2D mesh 【发布时间】:2013-05-09 18:47:43 【问题描述】:在 DirectX 中,我一直在使用以下结构处理带纹理的四边形:
struct TLVERTEX
float x;
float y;
float z;
D3DCOLOR colour;
float u;
float v;
;
但是,我想制作更复杂的 2D 网格并对它们进行纹理处理,但我不知道如何在其上对齐纹理。在纹理四边形中,结构体的 u 和 v 属性决定了纹理的方向。
理想情况下,我最终想要做的是要么拥有一个带有纹理的 2D 网格,要么我需要什么新的结构属性,纹理拉伸/操纵以完全适合网格,无论它多么扭曲可能最终看起来。
我想做的另一件事是说有一个带有纹理的 2D 网格,没有拉伸纹理等。我只想对齐它,所以如果纹理不适合网格的形状,位会丢失等。
我尝试过 Google 搜索,但只能找到与 3D 图形相关的内容。虽然我意识到我在技术上是在 3D 空间中工作,但我最终想要做的是创建 2D 图形。如果可能的话,我会很感激从哪里寻找/开始实现这一目标的建议到完成示例的任何答案。
【问题讨论】:
老实说,您的问题有点含糊。如果您有一个顶点,您可以在网格中拥有任意数量的顶点/三角形。通常,模型/地图/对象导出器会以您读取的文件格式列出 uv 的位置。 是的,但我有一个只有四个顶点的纹理四边形。问题是有四个以上。 u 和 v 属性决定了四边形上纹理的方向,但是当有超过 4 个顶点时如何实现呢?或者你是说 u 和 v 属性可以应用于纹理四边形以外的东西?如果是这样,我将如何在这种情况下使用它们? 【参考方案1】:您应该真正了解纹理坐标的工作原理。
让我们考虑以下网格。我们想应用一个不失真的纹理(虚线矩形):
然后为每个顶点指定纹理坐标就很简单了:
u = (x - minX) / (maxX - minX)
v = (y - minY) / (maxY - minY)
如果要旋转纹理,则必须将顶点投影到相应的轴上。
如果要扭曲纹理,则必须在纹理边缘指定纹理坐标。一个可以使用的简单算法如下:
Choose an arbitrary point in the polygon -> o
For each vertex v
Shoot a ray from o through v
Find the intersection of this ray with minX / maxX / minY / maxY
Calculate the texture coordinates at the intersection points as above
Next
但是,该算法不能保证每个纹理元素都映射到网格。例如。上面示例的右上角未使用上述算法映射到任何内容。此外,它只保证凸多边形的一致映射。
这是凹多边形的算法。它应该产生一致的坐标。但是,我不知道结果会是什么样子。该算法也可以跳过角落。可以包括检查以将角的坐标应用于特定顶点(例如,当边改变时):
Calculate the polygon's perimeter -> p
//The texture coodinate space has a perimeter of 4
currentPos := 0
for each vertex
if(4 * currentPos < 1)
uv = (4 * currentPos / p, 0) // top edge
else if(4 * currentPos < 2)
uv = (1, 4 * currentPos / p - 1); //right edge
else if(4 * currentPos < 3)
uv = (1 - 4 * currentPos / p - 2, 1); //bottomedge
else
uv = (0, 1 - 4 * currentPos / p - 3); //leftedge
currentPos += distance to next vertex
next
【讨论】:
这很有趣也很有帮助,谢谢!我一直在做一些搜索,试图找到关于这方面的好的阅读材料,但没有太大的成功。你有什么建议吗?还有你是如何处理凹凸问题的?您是否必须根据对凹顶点的检查来分解它,以便最终得到一堆凸形状?还是我想错了? MSDN (msdn.microsoft.com/en-us/library/windows/desktop/…) 是一个好的开始。要处理凹多边形,需要采用不同的方法。我为此添加了一个示例算法。 将此标记为答案,因为您似乎让我走上了正确的轨道。谢谢!以上是关于C++ DirectX - 对 2D 网格进行纹理化的主要内容,如果未能解决你的问题,请参考以下文章
使用 Direct2D 和 DirectWrite(C++、DirectX)制作按钮