我试图在XNA中制作一个3D WP7游戏,通过绘制由线组成的模型,使用DrawUserIndexedPrimitives --这一切都很好,但是现在我想让每个模型都有自己的旋转。目前,我正在使用BasicEffect绘制所有的模型。我可以设置它的旋转,但是所有的对象都会有相同的旋转。有没有办法为每个对象设置不同的旋转方式?我目前已经想出了几种解决方案,我可以使用,但我对这两种解决方案都不满意:
这里有建议的路线吗?
我不知道DrawUserIndexedPrimitives是否是最好的使用方法,我只想画出线,并给他们一个旋转。如果有更好的方法,请告诉我:)
我目前的解决方案:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
foreach (var model in _models)
{
foreach (var pass in model.Effect.CurrentTechnique.Passes)
{
pass.Apply();
model.Effect.World = _model.GetWorld();
var points = model.GetPoints();
GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.LineList, points, 0, points.Length, model.Lines, 0, model.Lines.Length / 2);
_models[0].Draw(GraphicsDevice);
}
}
base.Draw(gameTime);
}model.GetWorld()返回具有对象的旋转、平移和缩放的矩阵,model.GetPoints()返回带点的列表,model.Lines是具有连通点索引的列表
发布于 2012-05-13 04:24:04
您通常只需要任何类型的效果(如BasicEffect)中的一种。原因是因为效果包括两个主要内容:为GPU (照明等)编写的代码和它公开的参数(如Effect.World,世界矩阵)。不需要多次编译GPU代码,因为每次编译都是一样的,所以我们需要考虑的是参数。
注意对pass.Apply()的调用。这实际上是上传所有的参数,你已经设置的效果,每一次之前,你的GPU。希望能告诉你的是,在每次抽签和调用应用之前,你应该能够将旋转设定在一个单一的效果上,而不是用单独设置的旋转来创建一系列的效果。此外,设置Effect.World实际上应该放在pass.Apply()之前。
回答第二个要点,你是完全正确的。GPU是用来对具有大规模并行性的点进行转换的,所以最好不要自己尝试,因为它会很慢。
至于DrawUserIndexedPrimitives,我不是图形迷,但通常情况下,这种调用只适用于顶点不断变化的情况(比如软体斑点或布),基本上没有办法通过翻译、旋转和缩放来描述网格。GPU公开了名为VertexBuffer的特殊原语,其整个目标是在GPU内存中存储一组点(这使它们能够快速访问)。从那里开始,如果您想要移动它,GPU将转换每个点(但是请注意,您需要传递它的所有东西是平移、旋转和缩放,以及它的优点)。使用DrawUserIndexedPrimitives实际上必须将所有的点发送到GPU的每一个帧,这是比较慢的(有多少,谁知道现在没有测试)。
幸运的是,显卡实际上实现了一种特殊的绘图模式,称为“线框”,它不是画三角形,而是将三角形的边缘画成直线。若要设置线框模式,请在调用“绘制”之前执行以下操作:
this.GraphicsDevice.RasterizerState.FillMode = FillMode.WireFrame;现在,就应用您自己的旋转而言,您真正需要做的就是将世界矩阵乘以一个旋转矩阵(使用类似于Matrix.CreateRotationX(YourAngle)的方法)。
发布于 2012-05-13 04:26:36
您的当前解决方案很好,尽管我会在pass.Apply()之前进行世界分配。
如果您有几个模型,您可以传递到着色器和数组与转换,并添加到您的顶点结构一个索引到这个数组。
这样你就可以一次画出你所有的模型。
https://stackoverflow.com/questions/10567052
复制相似问题