Zeichnen eines trigonalen Polygons mit einem Vertex-Puffer

Diese Seite wurde aktualisiert :
Erstellungsdatum der Seite :

Zusammenfassung

Durch die Verwendung von Vertex-Puffern können Polygone schnell gezeichnet werden.

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

Betriebsumgebung

Voraussetzungen

Unterstützte XNA-Versionen
  • 4.0
Unterstützte Plattformen
  • Windows (XP SP2 oder höher, Vista, 7)
  • Xbox 360
  • Windows Phone 7
Erforderliche Vertex-Shader-Version für Windows 2.0
Erforderliche Pixel-Shader-Version für Windows 2.0

Betriebsumgebung

Bahnsteig
  • Windows 7
  • Xbox 360
  • Windows Phone 7-Emulator

Substanz

Wenn Sie ein Polygon zeichnen, können Sie es mit einem sogenannten "Vertex-Puffer" zeichnen. Der Vertex-Puffer kann mit Vertex-Daten gefüllt werden, die beim Zeichnen von Grundelementen, wie z. B. Polygonen, verwendet werden können. Der Vertexpuffer ermöglicht das Platzieren von Vertexdaten im Videospeicher, und die Zeichnungspipeline kann Daten viel schneller austauschen als aus dem normalen Hauptspeicher, sodass eine Verbesserung der Zeichnungsgeschwindigkeit erwartet werden kann.

Bei einem einzelnen Polygon wie diesem hat man nicht das Gefühl, dass man mit hoher Geschwindigkeit zeichnet, aber ich denke, dass der Effekt sichtbar ist, wenn man Tausende oder Zehntausende von Polygonen zeichnet.

Feld

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

Um einen Vertex-Puffer zu verwenden, verwenden Sie die Klasse "VertexBuffer". Wenn bei jedem Zeichnen benutzerdefinierte Scheitelpunktdaten an die Pipeline gesendet wurden, mussten die Scheitelpunktdaten immer aufbewahrt werden, aber wenn ein Scheitelpunktpuffer erstellt wurde, verwaltet der Scheitelpunktpuffer die Scheitelpunktdaten, sodass die Scheitelpunktdaten nicht aufbewahrt werden müssen.

Erstellen eines Vertex-Puffers

// 頂点の数
int vertexCount = 3;

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

In der LoadGraphicsContent-Methode erstellen wir einen VertexBuffer.

Das erste Argument ist ein GraphicsDevice.

Das zweite Argument gibt den Typ der Struktur an, die die Scheitelpunktdaten enthält, oder die Scheitelpunktdeklaration der zu verwendenden Scheitelpunktdaten. Hier wird typeof im Typ der Struktur übergeben. Da für Vertex-Daten "Vertex Position" und "Vertex Color" verwendet werden, ist die vom XNA Framework bereitgestellte "VertexPositionColor"-Struktur standardmäßig spezifiziert.

Das dritte Argument gibt die Anzahl der zu erstellenden Scheitelpunkte an.

Das vierte Argument gibt die Verwendung des Vertexpuffers an, aber wenn nichts Bestimmtes vorhanden ist, können Sie "BufferUsage.None" angeben.

VertexBuffer Konstruktor

Erstellen Sie eine Instanz der Klasse "VertexBuffer" zum Erstellen von Vertex-Daten.

Grafikgerät Grafikgerät Gibt das GraphicsDevice an, das dem Vertexpuffer zugeordnet werden soll.
vertexType Art Gibt den Typ der zu verwendenden Vertexdaten an.
vertexCount Int Gibt die Anzahl der zu erstellenden Scheitelpunkte an.
Verwendung BufferUsage Gibt die Verwendung des Vertexpuffers an. Wenn nichts Bestimmtes vorhanden ist, geben Sie "BufferUsage.None" an.
// 頂点データを作成する
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);

Nachdem Sie den Vertexpuffer erstellt haben, legen Sie den Vertexpuffer mit Vertexdaten fest. Verwenden Sie zum Festlegen von Vertexdaten die Methode "VertexBuffer.SetData".

Sobald die Vertex-Daten im Vertex-Puffer festgelegt sind, werden sie vom Vertex-Puffer verwaltet, sodass Sie sie so verwerfen können, wenn Sie sie nicht mehr verwenden.

VertexBuffer.SetData Methode

Legen Sie die Vertex-Daten im Vertex-Puffer fest.

T WertTyp Gibt die Struktur der zu verwendenden Scheitelpunktdaten an.
Daten T[] Gibt ein Array von Vertex-Daten an, die im Vertex-Puffer festgelegt werden sollen. Die im Vertexpuffer angegebene Größe muss mit der Größe der festzulegenden Vertexdaten übereinstimmen.

Zeichnung

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

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

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

Um ein Polygon zu zeichnen, legen Sie den Scheitelpunktpuffer fest, der zum Zeichnen verwendet werden soll. Das GraphicsDevice verfügt über eine "SetVertexBuffer"-Methode, die den Vertexpuffer darauf festlegt.

GraphicsDevice.SetVertexBuffer Methode

Gibt den Vertexpuffer an, der zum Zeichnen verwendet werden soll.

vertexBuffer VertexBuffer Gibt den Vertexpuffer an, der zum Zeichnen verwendet werden soll.

Verwenden Sie zum Zeichnen der eigentlichen Polygone die Methode "GraphicsDevice.DrawPrimitives". Wenn Sie einen Vertexpuffer verwenden möchten, zeichnen Sie ihn mit dieser Methode. Im Gegensatz zur DrawUserPrimitives-Methode, die die benutzerdefinierten Punktdaten so angibt, wie sie sind, wird diese Methode zum Zeichnen mithilfe eines Vertexpuffers verwendet.

Das erste Argument ist der Typ des zu zeichnenden Primitivs, das zweite Argument ist der Vertex-Index, um mit dem Zeichnen zu beginnen, und das dritte Argument ist die Anzahl der zu zeichnenden Primitive.

GraphicsDevice.DrawPrimitives Methode

Zeichnet einen Grundkörper unter Verwendung des angegebenen Vertex-Puffers.

primitiver Typ Primitiver Typ Gibt den Typ des zu zeichnenden Grundkörpers an
startVertex Int Der erste Index des zu ladenden Vertex
primitiveCount Int Anzahl der zu zeichnenden Grundkörper

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