ترسیم یک چند ضلعی مثلثی با استفاده از بافر راس

صفحه به روز شده :
تاریخ ایجاد صفحه :

خلاصه

با استفاده از بافرهای راس، چند ضلعی ها را می توان به سرعت ترسیم کرد.

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

محیط عملیاتی

پیش نیازها

نسخه های XNA پشتیبانی شده
  • 4.0
پلتفرم های پشتیبانی شده
  • ویندوز (XP SP2 یا بالاتر، ویستا، 7)
  • ایکس باکس 360
  • ویندوز فون 7
نسخه Vertex Shader مورد نیاز ویندوز 2.0
ویندوز نسخه Pixel Shader مورد نیاز است 2.0

محیط عملیاتی

بستر
  • ویندوز 7
  • ایکس باکس 360
  • شبیه ساز ویندوز فون 7

ماده

هنگامی که یک چند ضلعی می کشید، می توانید آن را با استفاده از چیزی به نام "بافر راس" ترسیم کنید. بافر راس را می توان با داده های راس پر کرد تا هنگام ترسیم مواد اولیه مانند چند ضلعی ها استفاده شود. بافر راس اجازه می دهد تا داده های راس در حافظه ویدیویی قرار گیرد و خط لوله ترسیم می تواند داده ها را بسیار سریعتر از حافظه اصلی معمولی مبادله کند، بنابراین می توان انتظار داشت که سرعت ترسیم را بهبود بخشد.

در مورد یک چند ضلعی مانند این، نمی توانید احساس کنید که با سرعت بالا نقاشی می کنید، اما من فکر می کنم که این اثر هنگام ترسیم هزاران یا ده ها هزار چند ضلعی قابل مشاهده است.

زمینه

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

برای استفاده از بافر راس، از کلاس "VertexBuffer" استفاده کنید. اگر داده های راس تعریف شده توسط کاربر هر بار که ترسیم می شدند به خط لوله ارسال می شد، داده های راس باید همیشه نگهداری می شدند، اما اگر یک بافر راس ایجاد می شد، بافر راس داده های راس را مدیریت می کند، بنابراین نیازی به نگهداری داده های راس نیست.

ایجاد یک بافر Vertex

// 頂点の数
int vertexCount = 3;

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

در متد LoadGraphicsContent، ما در حال ایجاد یک VertexBuffer هستیم.

اولین آرگومان یک GraphicsDevice است.

آرگومان دوم نوع ساختاری را مشخص می کند که حاوی داده های راس یا اعلان راس داده های راس مورد استفاده است. در اینجا، typeof در نوع سازه منتقل می شود. از آنجایی که "موقعیت راس" و "رنگ راس" برای داده های راس استفاده می شود، ساختار "VertexPositionColor" ارائه شده توسط چارچوب XNA به عنوان استاندارد مشخص می شود.

آرگومان سوم تعداد رئوس ایجاد را مشخص می کند.

آرگومان چهارم کاربرد بافر راس را مشخص می کند، اما اگر چیز خاصی وجود نداشته باشد، می توانید "BufferUsage.None" را مشخص کنید.

VertexBuffer سازنده

یک نمونه از کلاس "VertexBuffer" برای ایجاد داده راس ایجاد کنید.

گرافیکدستگاه دستگاه گرافیکی GraphicsDevice را مشخص می کند تا با بافر راس مرتبط شود.
راس تایپ نوع نوع داده های راس مورد استفاده را مشخص می کند.
راس شمارش هوشمند تعداد رئوس برای ایجاد را مشخص می کند.
استفاده استفاده از بافر استفاده از بافر راس را مشخص می کند. اگر چیز خاصی وجود ندارد، "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 نوع ارزش ساختار داده های راس مورد استفاده را مشخص می کند.
داده 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 روش

با استفاده از بافر راس مشخص شده یک ابتدایی ترسیم می کند.

نوع ابتدایی نوع اولیه نوع ابتدایی برای ترسیم را مشخص می کند
startVertex هوشمند اولین شاخص راس برای بارگیری
شمارش ابتدایی هوشمند تعداد ابتدایی ها برای ترسیم

همه کدها

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