Vẽ đa giác tam giác bằng cách sử dụng bộ đệm đỉnh

Trang Cập Nhật :
Ngày tạo trang :

tóm tắt

Bằng cách sử dụng bộ đệm đỉnh, đa giác có thể được vẽ nhanh chóng.

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

Môi trường hoạt động

Điều kiện tiên quyết

Các phiên bản XNA được hỗ trợ
  • 4.0
Nền tảng được hỗ trợ
  • Windows (XP SP2 trở lên, Vista, 7)
  • Xbox 360
  • Windows Phone 7
Phiên bản Vertex Shader bắt buộc của Windows 2.0
Phiên bản Pixel Shader bắt buộc của Windows 2.0

Môi trường hoạt động

nền tảng
  • cửa sổ 7
  • Xbox 360
  • Trình giả lập Windows Phone 7

chất

Khi bạn vẽ một đa giác, bạn có thể vẽ nó bằng cách sử dụng một thứ gọi là "bộ đệm đỉnh". Bộ đệm đỉnh có thể được lấp đầy với dữ liệu đỉnh được sử dụng khi vẽ các nguyên thủy như đa giác. Bộ đệm đỉnh cho phép dữ liệu đỉnh được đặt trên bộ nhớ video và đường ống vẽ có thể trao đổi dữ liệu nhanh hơn nhiều so với bộ nhớ chính thông thường, do đó có thể cải thiện tốc độ vẽ.

Trong trường hợp một đa giác đơn lẻ như thế này, bạn không thể cảm thấy rằng bạn đang vẽ ở tốc độ cao, nhưng tôi nghĩ rằng hiệu ứng có thể nhìn thấy khi vẽ hàng ngàn hoặc hàng chục nghìn đa giác.

trường

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

Để sử dụng bộ đệm đỉnh, hãy sử dụng lớp "VertexBuffer". Nếu dữ liệu đỉnh do người dùng xác định được gửi đến đường ống mỗi khi nó được vẽ, dữ liệu đỉnh phải được lưu giữ mọi lúc, nhưng nếu bộ đệm đỉnh được tạo, bộ đệm đỉnh sẽ quản lý dữ liệu đỉnh, do đó không cần giữ dữ liệu đỉnh.

Tạo bộ đệm đỉnh

// 頂点の数
int vertexCount = 3;

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

Trong phương thức LoadGraphicsContent, chúng ta đang tạo một VertexBuffer.

Đối số đầu tiên là một GraphicsDevice.

Đối số thứ hai chỉ định kiểu cấu trúc chứa dữ liệu đỉnh hoặc khai báo đỉnh của dữ liệu đỉnh sẽ được sử dụng. Ở đây, typeof được thông qua trong loại cấu trúc. Vì "vị trí đỉnh" và "màu đỉnh" được sử dụng cho dữ liệu đỉnh, cấu trúc "VertexPositionColor" do XNA Framework cung cấp được chỉ định làm tiêu chuẩn.

Đối số thứ ba chỉ định số đỉnh để tạo.

Đối số thứ tư chỉ định cách sử dụng bộ đệm đỉnh, nhưng nếu không có gì cụ thể, bạn có thể chỉ định "BufferUsage.None".

VertexBuffer Constructor

Tạo một thể hiện của lớp "VertexBuffer" để tạo dữ liệu đỉnh.

đồ họaThiết bị Đồ họaThiết bị Chỉ định GraphicsDevice để liên kết với bộ đệm đỉnh.
đỉnhLoại Kiểu Chỉ định loại dữ liệu đỉnh sẽ sử dụng.
vertexCount Int Chỉ định số đỉnh cần tạo.
Sử dụng Bộ đệmSử dụng Chỉ định cách sử dụng bộ đệm đỉnh. Nếu không có gì đặc biệt, hãy chỉ định "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);

Sau khi tạo bộ đệm đỉnh, đặt bộ đệm đỉnh với dữ liệu đỉnh. Để đặt dữ liệu đỉnh, hãy sử dụng phương thức "VertexBuffer.SetData".

Khi dữ liệu đỉnh được đặt trong bộ đệm đỉnh, nó được quản lý bởi bộ đệm đỉnh, vì vậy nếu bạn không sử dụng nó nữa, bạn có thể loại bỏ nó như hiện tại.

VertexBuffer.SetData phương pháp

Đặt dữ liệu đỉnh trong bộ đệm đỉnh.

T Loại giá trị Chỉ định cấu trúc của dữ liệu đỉnh để sử dụng.
dữ liệu T[] Chỉ định một mảng dữ liệu đỉnh được đặt trong bộ đệm đỉnh. Kích thước được chỉ định trong bộ đệm đỉnh phải khớp với kích thước của dữ liệu đỉnh được đặt.

Vẽ

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

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

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

Để vẽ đa giác, hãy đặt bộ đệm đỉnh được sử dụng để vẽ. GraphicsDevice có phương thức "SetVertexBuffer" đặt bộ đệm đỉnh cho nó.

GraphicsDevice.SetVertexBuffer phương pháp

Chỉ định bộ đệm đỉnh để sử dụng để vẽ.

vertexBuffer VertexBuffer Chỉ định bộ đệm đỉnh để sử dụng để vẽ.

Để vẽ các đa giác thực tế, hãy sử dụng phương thức "GraphicsDevice.DrawPrimitives". Nếu bạn muốn sử dụng bộ đệm đỉnh, bạn sẽ vẽ nó bằng phương pháp này. Không giống như phương thức DrawUserPrimitives, chỉ định dữ liệu điểm do người dùng xác định, phương thức này được sử dụng để vẽ bằng bộ đệm đỉnh.

Đối số thứ nhất là kiểu nguyên thủy để vẽ, đối số thứ hai là chỉ số đỉnh để bắt đầu vẽ và đối số thứ ba là số nguyên thủy cần vẽ.

GraphicsDevice.DrawPrimitives phương pháp

Vẽ một nguyên thủy bằng cách sử dụng bộ đệm đỉnh được chỉ định.

nguyên thủyLoại PrimitiveType Chỉ định loại nguyên thủy để vẽ
startVertex Int Chỉ số đầu tiên của đỉnh tải
nguyên thủyBá tước Int Số lượng nguyên thủy để vẽ

Tất cả các mã

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