首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WP7游戏XNA : DrawUserIndexedPrimitives

WP7游戏XNA : DrawUserIndexedPrimitives
EN

Stack Overflow用户
提问于 2012-05-12 20:13:26
回答 2查看 695关注 0票数 2

我试图在XNA中制作一个3D WP7游戏,通过绘制由线组成的模型,使用DrawUserIndexedPrimitives --这一切都很好,但是现在我想让每个模型都有自己的旋转。目前,我正在使用BasicEffect绘制所有的模型。我可以设置它的旋转,但是所有的对象都会有相同的旋转。有没有办法为每个对象设置不同的旋转方式?我目前已经想出了几种解决方案,我可以使用,但我对这两种解决方案都不满意:

  • 为每个对象创建了一个新的BasicEffect,它有自己的世界,然后循环遍历所有的对象以获得它们的基本效果并绘制它--我猜所有的BasicEffects都会产生很大的开销,我想将效果从模型中分离出来。
  • 自己来计算这些点(即计算旋转,并将这些值传递给DrawUserIndexedPrimitives方法)--这是一个相当昂贵的计算,大大降低了性能。

这里有建议的路线吗?

我不知道DrawUserIndexedPrimitives是否是最好的使用方法,我只想画出线,并给他们一个旋转。如果有更好的方法,请告诉我:)

我目前的解决方案:

代码语言:javascript
复制
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是具有连通点索引的列表

EN

回答 2

Stack Overflow用户

发布于 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的每一个帧,这是比较慢的(有多少,谁知道现在没有测试)。

幸运的是,显卡实际上实现了一种特殊的绘图模式,称为“线框”,它不是画三角形,而是将三角形的边缘画成直线。若要设置线框模式,请在调用“绘制”之前执行以下操作:

代码语言:javascript
复制
this.GraphicsDevice.RasterizerState.FillMode = FillMode.WireFrame;

现在,就应用您自己的旋转而言,您真正需要做的就是将世界矩阵乘以一个旋转矩阵(使用类似于Matrix.CreateRotationX(YourAngle)的方法)。

票数 2
EN

Stack Overflow用户

发布于 2012-05-13 04:26:36

您的当前解决方案很好,尽管我会在pass.Apply()之前进行世界分配。

如果您有几个模型,您可以传递到着色器和数组与转换,并添加到您的顶点结构一个索引到这个数组。

这样你就可以一次画出你所有的模型。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10567052

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档