【问题标题】:Proper way of transforming 3D primitives in C#/XNA?在 C#/XNA 中转换 3D 图元的正确方法?
【发布时间】:2012-06-04 13:43:24
【问题描述】:

我有一个 Block 类,它基本上包含一个 36 个顶点的数组,一个围绕原点 (0, 0, 0) 构建块的构造函数,以及一个更新方法。

我正在使用物理库来操作块。我为块分配了一个身体和碰撞皮肤,并在每次更新时更新物理步骤。每次更新后,我都会返回一个矩阵,其中包含块的新位置、方向等。

现在,我无法理解的是,将矩阵应用于块并有效地每帧更新顶点缓冲区的最佳方法。

这基本上是我目前所拥有的,我几乎肯定有更好的方法......

class Block
{
    const float FullBlockSize = 20f;
    const float HalfBlockSize = FullBlockSize / 2;

    public VertexPositionNormalTexture [] vertices = new VertexPositionNormalTexture[36];
    public VertexPositionNormalTexture [] currentVertices = new VertexPositionNormalTexture[36];
    public DynamicVertexBuffer vBuffer;

    Vector3 position;

    public Block(Vector3 blockPosition)
    {
        position = blockPosition * FullBlockSize;

        /*
         * Build the 6 faces of the block here.
         * The block is built around the origin,
         * (0, 0, 0) being the center of the block.
        */

        vBuffer = new DynamicVertexBuffer(Game.Device, VertexPositionNormalTexture.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly);
        vBuffer.SetData(vertices);
    }
    public Matrix WorldMatrix
    {
        get
        {
            return Matrix.CreateTranslation(position);
        }
    }
    public void Update()
    {
        currentVertices = (VertexPositionNormalTexture[])vertices.Clone();
        Matrix currentWorld = WorldMatrix;
        for(int i = 0; i < currentVertices.Length; ++i)
        {
            currentVertices[i].Position = Vector3.Transform(currentVertices[i].Position, currentWorld);
        }
        vBuffer.SetData(currentVertices);
    }
}

【问题讨论】:

  • 为什么要修改顶点数据?这将变得非常缓慢。存储原始顶点和变换矩阵就完全足够了。
  • @NicoSchertler 这就是我的想法,但将变换矩阵传递给 GPU 并绘制三角形似乎并不奏效。他们都只是停留在原点。

标签: c# 3d matrix xna


【解决方案1】:

让着色器来做...着色器的参数之一通常是 WorldMatrix...

画出来:

effect.Parameters["WorldMatrix"].SetValue(World);
effect.Apply(0);

如果你在绘制方块时遇到问题...尝试自己创建一个世界变换矩阵并进行测试...

effect.Parameters["WorldMatrix"].SetValue(Matrix.CreateRotationZ(angle));
effect.Apply(0);

如果您有多个块实例,则可以使用实例化将 vertexBuffer 中的 trasnform 矩阵传递给着色器...

您可以在此处找到有关实例化的信息:http://blogs.msdn.com/b/shawnhar/archive/2010/06/17/drawinstancedprimitives-in-xna-game-studio-4-0.aspx

【讨论】:

  • 在您的第一个语句中,您的意思是将着色器的世界矩阵设置为立方体的变换,绘制它,重复直到绘制所有立方体?实例化听起来不错,但听起来更像是性能问题(如果我错了,请纠正我)。现在我只想专注于了解在屏幕上实际显示多个立方体的基础知识。我现在有一个 Draw() 方法,它将着色器的世界矩阵设置为立方体的变换,然后绘制它。这似乎没有任何影响(所有立方体都绘制在原点上)。
  • 那么你要么传递了错误的世界矩阵,要么着色器不正确......弄清楚或发布一个新问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-04
相关资源
最近更新 更多