Teken een driehoekige veelhoek met behulp van een hoekpuntbuffer

Pagina bijgewerkt :
Aanmaakdatum van pagina :

samenvatting

Door gebruik te maken van hoekpuntbuffers kunnen polygonen snel worden getekend.

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

Werkomgeving

Voorwaarden

Ondersteunde XNA-versies
  • 4.0
Ondersteunde platforms
  • Windows (XP SP2 of hoger, Vista, 7)
  • Xbox 360
  • Windows Phone 7
Windows vereist Vertex Shader-versie 2.0
Windows Vereiste Pixel Shader-versie 2.0

Werkomgeving

perron
  • Vensters 7
  • Xbox 360
  • Windows Phone 7-emulator

stof

Wanneer u een veelhoek tekent, kunt u deze tekenen met behulp van iets dat een "hoekpuntbuffer" wordt genoemd. De hoekpuntbuffer kan worden gevuld met hoekpuntgegevens die kunnen worden gebruikt bij het tekenen van primitieven zoals veelhoeken. Met de vertexbuffer kunnen vertex-gegevens op het videogeheugen worden geplaatst en de tekenpijplijn kan veel sneller gegevens uitwisselen dan uit het normale hoofdgeheugen, dus er kan worden verwacht dat de tekensnelheid wordt verbeterd.

In het geval van een enkele veelhoek zoals deze heb je niet het gevoel dat je met hoge snelheid tekent, maar ik denk dat het effect zichtbaar is bij het tekenen van duizenden of tienduizenden veelhoeken.

veld

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

Als u een hoekpuntbuffer wilt gebruiken, gebruikt u de klasse "VertexBuffer". Als door de gebruiker gedefinieerde hoekpuntgegevens elke keer dat deze werd getekend naar de pijplijn werden verzonden, moesten de hoekpuntgegevens te allen tijde worden bewaard, maar als er een hoekpuntbuffer werd gemaakt, beheert de hoekpuntbuffer de hoekpuntgegevens, dus het is niet nodig om de hoekpuntgegevens te bewaren.

Een hoekpuntbuffer maken

// 頂点の数
int vertexCount = 3;

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

In de LoadGraphicsContent-methode maken we een VertexBuffer.

Het eerste argument is een GraphicsDevice.

Het tweede argument geeft het type structuur op dat de hoekpuntgegevens bevat, of de hoekpuntverklaring van de hoekpuntgegevens die moeten worden gebruikt. Hier wordt het type doorgegeven in het type van de structuur. Aangezien "vertex position" en "vertex color" worden gebruikt voor vertex-gegevens, wordt de "VertexPositionColor"-structuur die door het XNA Framework wordt geleverd, als standaard gespecificeerd.

Het derde argument geeft het aantal hoekpunten aan dat moet worden gemaakt.

Het vierde argument specificeert het gebruik van de hoekpuntbuffer, maar als er niets bijzonders is, kunt u "BufferUsage.None" opgeven.

VertexBuffer bouwer

Maak een exemplaar van de klasse "VertexBuffer" voor het maken van hoekpuntgegevens.

grafischApparaat Grafisch apparaat Hiermee geeft u het grafische apparaat op dat moet worden gekoppeld aan de hoekpuntbuffer.
hoekpuntType Type Hiermee geeft u het type hoekpuntgegevens op dat moet worden gebruikt.
hoekpuntCount Int Hiermee geeft u het aantal punten op dat moet worden gemaakt.
gebruik Buffer Gebruik Hiermee geeft u het gebruik van de hoekpuntbuffer op. Als er niets bijzonders is, geef dan "BufferUsage.None" op.
// 頂点データを作成する
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);

Nadat u de hoekpuntbuffer hebt gemaakt, stelt u de hoekpuntbuffer in met hoekpuntgegevens. Als u hoekpuntgegevens wilt instellen, gebruikt u de methode "VertexBuffer.SetData".

Zodra de hoekpuntgegevens zijn ingesteld in de hoekpuntbuffer, worden deze beheerd door de hoekpuntbuffer, dus als u deze niet meer gebruikt, kunt u deze weggooien zoals ze zijn.

VertexBuffer.SetData methode

Stel de hoekpuntgegevens in de hoekpuntbuffer in.

T WaardeType Hiermee geeft u de structuur op van de hoekpuntgegevens die moeten worden gebruikt.
gegevens T[] Hiermee geeft u een matrix met hoekpuntgegevens op die in de hoekpuntbuffer moeten worden ingesteld. De grootte die in de hoekpuntbuffer is opgegeven, moet overeenkomen met de grootte van de hoekpuntgegevens die moeten worden ingesteld.

tekening

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

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

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

Als u een veelhoek wilt tekenen, stelt u de hoekpuntbuffer in die voor het tekenen moet worden gebruikt. Het grafische apparaat heeft een "SetVertexBuffer"-methode die de hoekpuntbuffer erop instelt.

GraphicsDevice.SetVertexBuffer methode

Hiermee geeft u de hoekpuntbuffer op die moet worden gebruikt voor het tekenen.

hoekpuntBuffer HoekpuntBuffer Hiermee geeft u de hoekpuntbuffer op die moet worden gebruikt voor het tekenen.

Om de werkelijke polygonen te tekenen, gebruikt u de methode "GraphicsDevice.DrawPrimitives". Als u een hoekpuntbuffer wilt gebruiken, tekent u deze met deze methode. In tegenstelling tot de DrawUserPrimitives-methode, die de door de gebruiker gedefinieerde puntgegevens specificeert zoals ze zijn, wordt deze methode gebruikt om te tekenen met behulp van een hoekpuntbuffer.

Het eerste argument is het type primitief om te tekenen, het tweede argument is de hoekpuntindex om te beginnen met tekenen, en het derde argument is het aantal primitieven om te tekenen.

GraphicsDevice.DrawPrimitives methode

Tekent een primitief met behulp van de opgegeven hoekpuntbuffer.

primitief type Primitief type Specificeert het type primitief dat moet worden getekend
startHoekpunt Int De eerste index van het hoekpunt om te laden
primitiveCount Int Aantal primitieven om te tekenen

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