Disegna un poligono trigonale usando un buffer di vertici

Pagina aggiornata :
Data di creazione della pagina :

sommario

Utilizzando i buffer dei vertici, i poligoni possono essere disegnati rapidamente.

頂点バッファを使用した3角形ポリゴンの描画

Ambiente operativo

Prerequisiti

Versioni XNA supportate
  • 4.0
Piattaforme supportate
  • Windows (XP SP2 o successivo, Vista, 7)
  • Xbox 360
  • Windows Phone 7
Versione Vertex Shader richiesta da Windows 2.0
Versione Pixel Shader richiesta da Windows 2.0

Ambiente operativo

piattaforma
  • finestre 7
  • Xbox 360
  • Emulatore di Windows Phone 7

sostanza

Quando si disegna un poligono, è possibile disegnarlo utilizzando qualcosa chiamato "buffer dei vertici". Il buffer dei vertici può essere riempito con i dati dei vertici da utilizzare quando si disegnano primitive come i poligoni. Il buffer dei vertici consente di inserire i dati dei vertici nella memoria video e la pipeline di disegno può scambiare dati molto più velocemente rispetto alla normale memoria principale, quindi ci si può aspettare che migliori la velocità di disegno.

Nel caso di un singolo poligono come questo, non si ha la sensazione di disegnare ad alta velocità, ma penso che l'effetto sia visibile quando si disegnano migliaia o decine di migliaia di poligoni.

campo

/// <summary>
/// 頂点バッファ
/// </summary>
private VertexBuffer vertexBuffer = null;

Per utilizzare un buffer dei vertici, utilizzare la classe "VertexBuffer". Se i dati dei vertici definiti dall'utente venivano inviati alla pipeline ogni volta che venivano disegnati, i dati dei vertici dovevano essere mantenuti sempre, ma se veniva creato un buffer dei vertici, il buffer dei vertici gestiva i dati dei vertici, quindi non è necessario mantenere i dati dei vertici.

Creazione di un buffer dei vertici

// 頂点の数
int vertexCount = 3;

// 頂点バッファ作成
this.vertexBuffer = new VertexBuffer(this.GraphicsDevice,
    typeof(VertexPositionColor), vertexCount, BufferUsage.None);

Nel metodo LoadGraphicsContent viene creato un VertexBuffer.

Il primo argomento è un GraphicsDevice.

Il secondo argomento specifica il tipo di struttura che contiene i dati del vertice o la dichiarazione del vertice dei dati del vertice da utilizzare. In questo caso, typeof viene passato nel tipo della struttura. Poiché per i dati dei vertici vengono utilizzati "posizione dei vertici" e "colore dei vertici", la struttura "VertexPositionColor" fornita da XNA Framework viene specificata come standard.

Il terzo argomento specifica il numero di vertici da creare.

Il quarto argomento specifica l'utilizzo del buffer dei vertici, ma se non è presente nulla in particolare, è possibile specificare "BufferUsage.None".

VertexBuffer costruttore

Creare un'istanza della classe "VertexBuffer" per la creazione di dati dei vertici.

graficaDispositivo Dispositivo grafico Specifica l'oggetto GraphicsDevice da associare al buffer dei vertici.
Tipo di vertice Digitare Specifica il tipo di dati dei vertici da utilizzare.
vertexCount Int Specifica il numero di vertici da creare.
uso BufferUsage Specifica l'utilizzo del buffer dei vertici. Se non è presente nulla in particolare, specificare "BufferUsage.None".
// 頂点データを作成する
VertexPositionColor[] pointList = new VertexPositionColor[vertexCount];

pointList[0] = new VertexPositionColor(new Vector3(0.0f3.0f0.0f), Color.Red);
pointList[1] = new VertexPositionColor(new Vector3(3.0f-2.0f0.0f), Color.Blue);
pointList[2] = new VertexPositionColor(new Vector3(-3.0f-2.0f0.0f), Color.Green);

// 頂点データを頂点バッファに書き込む
this.vertexBuffer.SetData(pointList);

Dopo aver creato il buffer dei vertici, impostare il buffer dei vertici con i dati dei vertici. Per impostare i dati dei vertici, utilizzare il metodo "VertexBuffer.SetData".

Una volta che i dati dei vertici sono impostati nel buffer dei vertici, vengono gestiti dal buffer dei vertici, quindi se non li usi più, puoi scartarli così com'è.

VertexBuffer.SetData metodo

Impostare i dati dei vertici nel buffer dei vertici.

T ValoreTipo Specifica la struttura dei dati dei vertici da utilizzare.
dati T[] Specifica una matrice di dati dei vertici da impostare nel buffer dei vertici. Le dimensioni specificate nel buffer dei vertici devono corrispondere alle dimensioni dei dati dei vertici da impostare.

disegno

// 描画に使用する頂点バッファをセットします
this.GraphicsDevice.SetVertexBuffer(this.vertexBuffer);

// パスの数だけ繰り返し描画
foreach (EffectPass pass in this.basicEffect.CurrentTechnique.Passes)
{
    // パスの開始
    pass.Apply();

    // 三角形を描画する
    this.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
}

Per disegnare un poligono, impostare il buffer dei vertici da utilizzare per il disegno. GraphicsDevice dispone di un metodo "SetVertexBuffer" che imposta il buffer dei vertici su di esso.

GraphicsDevice.SetVertexBuffer metodo

Specifica il buffer dei vertici da utilizzare per il disegno.

Buffer vertice VertexBuffer Specifica il buffer dei vertici da utilizzare per il disegno.

Per disegnare i poligoni effettivi, utilizzare il metodo "GraphicsDevice.DrawPrimitives". Se si desidera utilizzare un buffer dei vertici, lo si disegnerà con questo metodo. A differenza del metodo DrawUserPrimitives, che specifica i dati dei punti definiti dall'utente così come sono, questo metodo viene utilizzato per disegnare utilizzando un buffer dei vertici.

Il primo argomento è il tipo di primitiva da disegnare, il secondo argomento è l'indice dei vertici per iniziare a disegnare e il terzo argomento è il numero di primitive da disegnare.

GraphicsDevice.DrawPrimitives metodo

Disegna una primitiva utilizzando il buffer dei vertici specificato.

primitiveType Tipo primitivo Specifica il tipo di primitiva da disegnare
startVertex Int Il primo indice del vertice da caricare
primitiveCount Int Numero di primitive da disegnare

Tutti i codici

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
#if WINDOWS_PHONE
using Microsoft.Xna.Framework.Input.Touch;
#endif

namespace VertexBufferTriangle
{
    /// <summary>
    /// ゲームメインクラス
    /// </summary>
    public class GameMain : Microsoft.Xna.Framework.Game
    {
        /// <summary>
        /// グラフィックデバイス管理クラス
        /// </summary>
        private GraphicsDeviceManager graphics = null;

        /// <summary>
        /// スプライトのバッチ化クラス
        /// </summary>
        private SpriteBatch spriteBatch = null;

        /// <summary>
        /// 頂点バッファ
        /// </summary>
        private VertexBuffer vertexBuffer = null;

        /// <summary>
        /// 基本エフェクト
        /// </summary>
        private BasicEffect basicEffect = null;


        /// <summary>
        /// GameMain コンストラクタ
        /// </summary>
        public GameMain()
        {
            // グラフィックデバイス管理クラスの作成
            this.graphics = new GraphicsDeviceManager(this);

            // ゲームコンテンツのルートディレクトリを設定
            this.Content.RootDirectory = "Content";

#if WINDOWS_PHONE
            // Windows Phone のデフォルトのフレームレートは 30 FPS
            this.TargetElapsedTime = TimeSpan.FromTicks(333333);

            // バックバッファサイズの設定
            this.graphics.PreferredBackBufferWidth = 480;
            this.graphics.PreferredBackBufferHeight = 800;

            // フルスクリーン表示
            this.graphics.IsFullScreen = true;
#endif
        }

        /// <summary>
        /// ゲームが始まる前の初期化処理を行うメソッド
        /// グラフィック以外のデータの読み込み、コンポーネントの初期化を行う
        /// </summary>
        protected override void Initialize()
        {
            // TODO: ここに初期化ロジックを書いてください

            // コンポーネントの初期化などを行います
            base.Initialize();
        }

        /// <summary>
        /// ゲームが始まるときに一回だけ呼ばれ
        /// すべてのゲームコンテンツを読み込みます
        /// </summary>
        protected override void LoadContent()
        {
            // テクスチャーを描画するためのスプライトバッチクラスを作成します
            this.spriteBatch = new SpriteBatch(this.GraphicsDevice);

            // エフェクトを作成
            this.basicEffect = new BasicEffect(this.GraphicsDevice);

            // エフェクトで頂点カラーを有効にする
            this.basicEffect.VertexColorEnabled = true;

            // ビューマトリックスをあらかじめ設定 ((0, 0, 15) から原点を見る)
            this.basicEffect.View = Matrix.CreateLookAt(
                    new Vector3(0.0f, 0.0f, 15.0f),
                    Vector3.Zero,
                    Vector3.Up
                );

            // プロジェクションマトリックスをあらかじめ設定
            this.basicEffect.Projection = Matrix.CreatePerspectiveFieldOfView(
                    MathHelper.ToRadians(45.0f),
                    (float)this.GraphicsDevice.Viewport.Width /
                        (float)this.GraphicsDevice.Viewport.Height,
                    1.0f,
                    100.0f
                );

            // 頂点の数
            int vertexCount = 3;

            // 頂点バッファ作成
            this.vertexBuffer = new VertexBuffer(this.GraphicsDevice,
                typeof(VertexPositionColor), vertexCount, BufferUsage.None);

            // 頂点データを作成する
            VertexPositionColor[] pointList = new VertexPositionColor[vertexCount];

            pointList[0] = new VertexPositionColor(new Vector3(0.0f, 3.0f, 0.0f), Color.Red);
            pointList[1] = new VertexPositionColor(new Vector3(3.0f, -2.0f, 0.0f), Color.Blue);
            pointList[2] = new VertexPositionColor(new Vector3(-3.0f, -2.0f, 0.0f), Color.Green);

            // 頂点データを頂点バッファに書き込む
            this.vertexBuffer.SetData(pointList);
        }

        /// <summary>
        /// ゲームが終了するときに一回だけ呼ばれ
        /// すべてのゲームコンテンツをアンロードします
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: ContentManager で管理されていないコンテンツを
            //       ここでアンロードしてください
        }

        /// <summary>
        /// 描画以外のデータ更新等の処理を行うメソッド
        /// 主に入力処理、衝突判定などの物理計算、オーディオの再生など
        /// </summary>
        /// <param name="gameTime">このメソッドが呼ばれたときのゲーム時間</param>
        protected override void Update(GameTime gameTime)
        {
            // Xbox 360 コントローラ、Windows Phone の BACK ボタンを押したときに
            // ゲームを終了させます
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.Exit();
            }

            // TODO: ここに更新処理を記述してください

            // 登録された GameComponent を更新する
            base.Update(gameTime);
        }

        /// <summary>
        /// 描画処理を行うメソッド
        /// </summary>
        /// <param name="gameTime">このメソッドが呼ばれたときのゲーム時間</param>
        protected override void Draw(GameTime gameTime)
        {
            // 画面を指定した色でクリアします
            this.GraphicsDevice.Clear(Color.CornflowerBlue);

            // 描画に使用する頂点バッファをセットします
            this.GraphicsDevice.SetVertexBuffer(this.vertexBuffer);

            // パスの数だけ繰り返し描画
            foreach (EffectPass pass in this.basicEffect.CurrentTechnique.Passes)
            {
                // パスの開始
                pass.Apply();

                // 三角形を描画する
                this.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
            }

            // 登録された DrawableGameComponent を描画する
            base.Draw(gameTime);
        }
    }
}