我在C#中使用DirectX 9 我将所有顶点存储在一个列表(不是数组)中,因为我使用动态LOD算法,因此每帧都计算一切,因此我的顶点可能每帧都有所不同。
在我尝试添加法线和灯光之前,一切正常 我发现一旦将顶点添加到列表中就无法编辑法线,因为它是结构列表而不是类。所以它只是给出了一个错误,比如“不能修改blablaba的返回值,因为它不是变量” 例如,如果我尝试这样做,它将无法正常工作 -
vertices[i].Normal = new Vector3(0, 1, 0);
当顶点放在列表中时,必须添加法线,但在完全网格化之前无法计算法线。
所以我创建了一个新的自定义顶点类型,而不是使它成为一个结构我使它成为一个类。这不起作用,因为除非它是一个结构,否则directx不会接受它......
然后我尝试使用数组而不是顶点列表。这导致每秒少于一帧。我不得不使用Array.Resize每帧更改我的数组的大小几百次,我想它不喜欢这样。
您可能认为我应该将最终列表转换为数组,然后从那里计算法线。这不起作用,因为顶点没有按任何特定顺序添加,所以我不知道哪个顶点靠近给定顶点才能计算法线。
那么如何在构建网格物体后以一种可以给它们正常的方式存储我的顶点?
答案 0 :(得分:1)
C#阻止您编写vertices[i].Normal = new Vector3(0, 1, 0)
,因为该表达式无法执行您想要的操作。与数组索引器不同,List<T>
索引器返回指定元素的副本,并且因为顶点是结构,所以复制整个顶点Normal
和全部。您将更新顶点的临时副本,而不是列表中的实际顶点。
解决方法是从列表中获取(副本)顶点,更新它,然后放回(副本):
var vertex = vertices[i];
vertex.Normal = new Vector3(0, 1, 0);
vertices[i] = vertex;
不幸的是,没有简单的方法可以避免这种重复复制。