vertex buffer를 사용하여 삼각형 다각형을 그립니다.

페이지 업데이트 :
페이지 생성 날짜 :

요약

꼭짓점 버퍼를 사용하면 다각형을 빠르게 그릴 수 있습니다.

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

운영 환경

필수 구성 요소

지원되는 XNA 버전
  • 4.0
지원되는 플랫폼
  • Windows(XP SP2 이상, Vista, 7)
  • 엑스박스 360
  • 윈도우 폰 7
Windows 필수 버텍스 셰이더 버전 2.0
Windows 필수 픽셀 셰이더 버전 2.0

운영 환경

플랫폼
  • 윈도우 7
  • 엑스박스 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는 구조체의 형식으로 전달됩니다. 꼭짓점 데이터에는 "꼭짓점 위치" 및 "꼭짓점 색상"이 사용되므로 XNA Framework에서 제공하는 "VertexPositionColor" 구조가 표준으로 지정됩니다.

세 번째 인수는 만들 정점의 수를 지정합니다.

네 번째 인수는 꼭짓점 버퍼 사용량을 지정하지만 특별히 아무 것도 없는 경우 "BufferUsage.None"을 지정할 수 있습니다.

VertexBuffer 생성자

꼭짓점 데이터를 만들기 위한 "VertexBuffer" 클래스의 인스턴스를 만듭니다.

그래픽장치장치 그래픽장치 꼭짓점 버퍼와 연결할 GraphicsDevice를 지정합니다.
vertexType (버텍스 타입) 사용할 정점 데이터의 유형을 지정합니다.
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 (버텍스 버퍼) 꼭짓점 버퍼 그리기에 사용할 정점 버퍼를 지정합니다.

실제 다각형을 그리려면 "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);
        }
    }
}