忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

かんたんXNA その11 VertexBuffer

このページは古いです
最新版はこちら

ここまで三角形や四角形を描くのに
GraphicsDevice.DrawUserPrimitivesジェネリックメソッドを使ってきました。
これはシンプルではあるのですがパフォーマンスがあまりよくありません。

良いパフォーマンスを持っているのは
GraphicsDevice.DrawPrimitivesメソッドです。
ただし、これは頂点データの配列そのものは直接使えません。
配列からVertexBufferを作り、それを使わねばならないのです。
(複雑で、はっきり言ってサンプル向きではありません。
しかし全く扱わないわけにも行かないでしょう)

 



using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

 


public class MyGame : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    BasicEffect effect;

    VertexPositionColor[] vertices = new VertexPositionColor[3];
    VertexBuffer vertexBuffer;

    public MyGame()
    {
        graphics = new GraphicsDeviceManager(this);

        vertices[0] = new VertexPositionColor(new Vector3(1, 0, 0), Color.White);
        vertices[1] = new VertexPositionColor(new Vector3(-1, 0, 0), Color.Red);
        vertices[2] = new VertexPositionColor(new Vector3(0, 1, 0), Color.Navy);
    }

    protected override void LoadGraphicsContent(bool loadAllContent)
    {
        if (loadAllContent)
        {
            effect = new BasicEffect(graphics.GraphicsDevice, null);
            effect.VertexColorEnabled = true;
            effect.Projection = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.ToRadians(45),
                Window.ClientBounds.Width / (float)Window.ClientBounds.Height,
                1,
                100
                );
            effect.View = Matrix.CreateLookAt(
                new Vector3(0, 0, 3),
                new Vector3(0, 0, 0),
                new Vector3(0, 1, 0)
            );

            vertexBuffer = new VertexBuffer(
                graphics.GraphicsDevice,
                VertexPositionColor.SizeInBytes * vertices.Length,
                ResourceUsage.None
                );
            vertexBuffer.SetData<VertexPositionColor>(vertices);
        }
    }

    protected override void Draw(GameTime gameTime)
    {
        graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

        graphics.GraphicsDevice.VertexDeclaration = new VertexDeclaration(
            graphics.GraphicsDevice,
            VertexPositionColor.VertexElements
            );

        effect.Begin();

        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
        {
            pass.Begin();

            graphics.GraphicsDevice.Vertices[0].SetSource(
                vertexBuffer,
                0,  //The starting offset.
                VertexPositionColor.SizeInBytes
                );
            graphics.GraphicsDevice.DrawPrimitives(
                PrimitiveType.TriangleList,
                0,  //startVertex
                1   //primitiveCount
                );

            pass.End();
        }

        effect.End();
    }
}


 

xnaVertexBuffer.JPG

このサンプルではGraphicsDevice.DrawUserPrimitivesのかわりに
GraphicsDevice.DrawPrimitivesメソッドを
使って三角形を描画しています。
見た目は変わりません。
ただ、ほんの少しパフォーマンスはよくなっているはずです。
(サンプルではありがたみは全く感じられませんが)

このメソッドを呼ぶ前にはSetSourceでvertexBufferを
セットしてやらなければなりません。
DrawPrimitivesはVertexBufferが引数に無いのです。


さて、ここで注意しておきたいことはこのSetSourceとDrawPrimitivesの
ペアは一回のDrawメソッドの中で何度呼んでもいいということです。
(そうでなければ物体を2つ以上描画できなくなってしまいます。)

物体を2つ以上描画するときはこんな感じでいいでしょう。

 

        effect.Begin();

        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
        {
            pass.Begin();
   
            //1回目
     graphics.GraphicsDevice.Vertices[0].SetSource(
              vertexBuffer1,
              0, 
              VertexPositionColor.SizeInBytes
            );

            graphics.GraphicsDevice.DrawPrimitives(
                PrimitiveType.TriangleList,
                0,
               
                );

           //2回目
    graphics.GraphicsDevice.Vertices[0].SetSource(
              vertexBuffer2,
              0, 
              VertexPositionColor.SizeInBytes
            );

            graphics.GraphicsDevice.DrawPrimitives(
                PrimitiveType.TriangleList,
                0, 
               
                );

            pass.End();
        }

        effect.End();



 

拍手[0回]

PR