Dessiner un polygone trigonal à l’aide d’une zone tampon de sommets

Page mise à jour :
Date de création de la page :

résumé

En utilisant des tampons de sommets, les polygones peuvent être dessinés rapidement.

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

Environnement d’exploitation

Conditions préalables

Versions XNA prises en charge
  • 4.0
Plates-formes prises en charge
  • Windows (XP SP2 ou version ultérieure, Vista, 7)
  • Xbox 360
  • Windows Phone 7
Version du Vertex Shader requise par Windows 2.0
Version du Pixel Shader requise par Windows 2.0

Environnement d’exploitation

plateforme
  • Windows 7
  • Xbox 360
  • Émulateur Windows Phone 7

substance

Lorsque vous dessinez un polygone, vous pouvez le dessiner à l’aide de ce qu’on appelle un « tampon de sommets ». Le tampon de vertex peut être rempli avec des données de vertex à utiliser lors du dessin de primitives telles que des polygones. Le tampon de vertex permet de placer les données de vertex sur la mémoire vidéo, et le pipeline de dessin peut échanger des données beaucoup plus rapidement qu’à partir de la mémoire principale normale, de sorte qu’on peut s’attendre à ce qu’il améliore la vitesse de dessin.

Dans le cas d’un seul polygone comme celui-ci, vous ne pouvez pas avoir l’impression de dessiner à grande vitesse, mais je pense que l’effet est visible lorsque vous dessinez des milliers ou des dizaines de milliers de polygones.

champ

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

Pour utiliser un tampon de sommets, utilisez la classe « VertexBuffer ». Si des données de vertex définies par l’utilisateur étaient envoyées au pipeline à chaque fois qu’elles étaient dessinées, les données de vertex devaient être conservées à tout moment, mais si une mémoire tampon de vertex était créée, la mémoire tampon de vertex gère les données de sommet, il n’est donc pas nécessaire de conserver les données de sommet.

Création d’une mémoire tampon de sommets

// 頂点の数
int vertexCount = 3;

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

Dans la méthode LoadGraphicsContent, nous créons un VertexBuffer.

Le premier argument est un GraphicsDevice.

Le deuxième argument spécifie le type de structure qui contient les données de sommet ou la déclaration de sommet des données de sommet à utiliser. Ici, typeof est passé dans le type de la structure. Étant donné que les termes « vertex position » et « vertex color » sont utilisés pour les données de sommet, la structure « VertexPositionColor » fournie par XNA Framework est spécifiée en standard.

Le troisième argument spécifie le nombre de sommets à créer.

Le quatrième argument spécifie l’utilisation de la mémoire tampon de sommets, mais s’il n’y a rien de particulier, vous pouvez spécifier « BufferUsage.None ».

VertexBuffer constructeur

Créez une instance de la classe « VertexBuffer » pour créer des données de sommet.

graphiqueAppareil Appareil graphique Spécifie le GraphicsDevice à associer à la mémoire tampon de sommets.
typesommet Type Spécifie le type de données de sommet à utiliser.
vertexCount Int Spécifie le nombre de sommets à créer.
usage BufferUsage Spécifie l’utilisation de la mémoire tampon de sommets. S’il n’y a rien de particulier, spécifiez « 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);

Après avoir créé la mémoire tampon de sommets, définissez-la avec les données de sommet. Pour définir les données de sommet, utilisez la méthode « VertexBuffer.SetData ».

Une fois que les données de sommet sont définies dans la mémoire tampon de sommets, elles sont gérées par la mémoire tampon de sommets, donc si vous ne l’utilisez plus, vous pouvez la supprimer telle quelle.

VertexBuffer.SetData méthode

Définissez les données de sommet dans la mémoire tampon de sommet.

T Type de valeur Spécifie la structure des données de sommet à utiliser.
données T[] Spécifie un tableau de données de sommet à définir dans la mémoire tampon de sommets. La taille spécifiée dans la mémoire tampon de sommets doit correspondre à la taille des données de sommet à définir.

dessin

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

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

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

Pour dessiner un polygone, définissez la mémoire tampon de sommets à utiliser pour le dessin. Le GraphicsDevice dispose d’une méthode « SetVertexBuffer » qui définit la mémoire tampon de vertex sur celle-ci.

GraphicsDevice.SetVertexBuffer méthode

Spécifie la mémoire tampon de sommets à utiliser pour le dessin.

vertexBuffer VertexBuffer Spécifie la mémoire tampon de sommets à utiliser pour le dessin.

Pour dessiner les polygones réels, utilisez la méthode « GraphicsDevice.DrawPrimitives ». Si vous souhaitez utiliser un tampon de sommets, vous allez le dessiner avec cette méthode. Contrairement à la méthode DrawUserPrimitives, qui spécifie les données de point définies par l’utilisateur telles qu’elles sont, cette méthode est utilisée pour dessiner à l’aide d’une mémoire tampon de sommets.

Le premier argument est le type de primitive à dessiner, le deuxième argument est l’indice de sommet pour commencer à dessiner, et le troisième argument est le nombre de primitives à dessiner.

GraphicsDevice.DrawPrimitives méthode

Dessine une primitive à l’aide de la mémoire tampon de vertex spécifiée.

primitiveType PrimitiveType Spécifie le type de primitive à dessiner
débutVertex Int Le premier index du sommet à charger
primitiveCount Int Nombre de primitives à dessiner

Tous les codes

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);
        }
    }
}