Намалюйте тригональний багатокутник за допомогою вершинного буфера

Сторінка оновлюється :
Дата створення сторінки :

зведення

Використовуючи буфери вершин, можна швидко малювати багатокутники.

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

Робоче середовище

Передумови

Підтримувані версії XNA
  • 4.0
Підтримувані платформи
  • Windows (XP SP2 або новішої версії, Vista, 7)
  • Xbox 360
  • Windows Phone 7
Потрібна версія Vertex Shader для Windows 2.0
Потрібна версія піксельного шейдера Windows 2.0

Робоче середовище

платформа
  • Вікна 7
  • Xbox 360
  • Емулятор Windows Phone 7

речовина

Коли ви малюєте багатокутник, ви можете намалювати його за допомогою так званого «вершинного буфера». Вершинний буфер може бути заповнений даними вершин, які будуть використовуватися при малюванні примітивів, таких як багатокутники. Вершинний буфер дозволяє розміщувати дані вершин у відеопам'яті, а конвеєр малювання може обмінюватися даними набагато швидше, ніж зі звичайної основної пам'яті, тому можна очікувати, що він покращить швидкість малювання.

У випадку з одним багатокутником, як цей, ви не можете відчути, що малюєте на високій швидкості, але я думаю, що ефект видно при малюванні тисяч або десятків тисяч полігонів.

поле

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

Щоб використовувати вершинний буфер, використовуйте клас "VertexBuffer". Якщо визначені користувачем дані про вершини надсилалися до конвеєра кожного разу, коли вони були намальовані, дані про вершини мали зберігатися постійно, але якщо був створений буфер вершин, буфер вершин керує даними вершини, тому немає необхідності зберігати дані вершини.

Створення вершинного буфера

// 頂点の数
int vertexCount = 3;

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

У методі LoadGraphicsContent ми створюємо VertexBuffer.

Першим аргументом є GraphicsDevice.

Другий аргумент визначає тип структури, яка містить дані вершини, або оголошення вершини даних вершини, які будуть використовуватися. Тут typeof передається в типі структури. Оскільки "позиція вершини" та "колір вершини" використовуються для даних вершин, структура "VertexPositionColor", надана XNA Framework, вказується як стандартна.

Третій аргумент вказує кількість вершин для створення.

Четвертий аргумент визначає використання буфера вершини, але якщо нічого конкретного немає, ви можете вказати "BufferUsage.None".

VertexBuffer будівник

Створити екземпляр класу "VertexBuffer" для створення вершинних даних.

Графічний пристрій Графічний пристрій Визначає GraphicsDevice для асоціювання з вершинним буфером.
vertex Type Тип Визначає тип даних вершин, які будуть використовуватися.
vertexCount Інт Визначає кількість вершин для створення.
використання Використання буфера Визначає використання вершинного буфера. Якщо нічого конкретного немає, вкажіть "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);

Після створення вершинного буфера, встановіть буфер вершин з даними про вершини. Для встановлення даних вершин використовується метод "VertexBuffer.SetData".

Як тільки дані вершини встановлені в буфері вершин, вони керуються вершинним буфером, тому, якщо ви більше їх не використовуєте, ви можете відкинути їх як є.

VertexBuffer.SetData метод

Встановити дані вершини в буфері вершин.

T ValueType Визначає структуру даних вершини, які будуть використовуватися.
дані T[] Вказує масив даних вершин, які мають бути встановлені у вершинному буфері. Розмір, вказаний у вершинному буфері, повинен відповідати розміру даних вершини, які потрібно встановити.

креслення

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

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

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

Щоб намалювати багатокутник, встановіть буфер вершин, який буде використовуватися для малювання. GraphicsDevice має метод "SetVertexBuffer", який встановлює йому вершинний буфер.

GraphicsDevice.SetVertexBuffer метод

Визначає буфер вершин, який буде використовуватися для малювання.

vertexBuffer VertexBuffer Визначає буфер вершин, який буде використовуватися для малювання.

Щоб намалювати реальні багатокутники, використовуйте метод "GraphicsDevice.DrawPrimitives". Якщо ви хочете використовувати вершинний буфер, ви намалюєте його за допомогою цього методу. На відміну від методу DrawUserPrimitives, який вказує дані про визначену користувачем точку як є, цей метод використовується для малювання за допомогою вершинного буфера.

Перший аргумент — це тип примітиву для малювання, другий аргумент — індекс вершини для початку малювання, а третій аргумент — кількість примітивів для малювання.

GraphicsDevice.DrawPrimitives метод

Малює примітив, використовуючи вказаний буфер вершин.

primitiveType PrimitiveType (Тип примітиву) Визначає тип примітиву для малювання
startVertex Інт Перший індекс вершини для навантаження
primitiveCount Інт Кількість примітивів для малювання

Всі коди

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