Üçgen çokgenleri görüntüleme

Sayfa güncel :
Sayfa oluşturma tarihi :

özet

3B uzayda üçgen çokgenleri görüntüler.

3角形ポリゴンの表示

Çalışma ortamı

Önkoşullar

Desteklenen XNA Sürümleri
  • 4.0
Desteklenen Platformlar
  • Windows (XP SP2 veya üstü, Vista, 7)
  • Xbox 360 için Oyunlar
  • Windows Phone 7
Windows Gerekli Köşe Gölgelendiricisi Sürümü 2.0
Windows Gerekli Pixel Shader Sürümü 2.0

Çalışma ortamı

peron
  • Windows 7
  • Xbox 360 için Oyunlar
  • Windows Phone 7 Emülatörü

madde

Çokgen nedir?

Çokgen, birden çok köşe tanımı tarafından oluşturulan bir yüzdür. Genel olarak, bir çokgen, üç köşeden oluşan üçgen bir yüzdür. Ve trigon, çokgenin en küçük birimidir. Bazı modelleme yazılımları çokgenleri dörtgen veya çokgen olarak görüntüleyebilir, ancak bunlar sonunda üçgen çokgenlere ayrıştırılacaktır.

Oyunlarda görüntülenen model, bu üçgen çokgenlerin katsayılarının birleştirilmesiyle oluşturulur.

最小単位のポリゴン

Çokgenler köşelerden oluşur. Köşeler, konum ve renk gibi verilere sahip olabilir. Bu örnek aynı zamanda "konum" ve "renk" verilerinden de yapılmıştır.

ポリゴンと頂点

Bu örnekteki yüzün rengi, her köşe için ayarlanan renk ve mesafe ile düzgün bir şekilde enterpolasyonlanmıştır, ancak bunu kendi gölgelendirici programınızla serbestçe değiştirebilirsiniz (gölgelendirici programları hakkında başka bir zaman daha fazlası).

Köşe Veri Tanımları

Bir çokgeni görüntülemek için "köşe verileri" gereklidir ve programcının bu köşeye hangi öğeleri dahil edeceğine karar vermesi gerekir. Bir çokgen çizerken, çizim motoru olan cihaza, çokgeni hangi köşe verileriyle çizeceğini söylemeniz gerekir. Bunu yapmak için bir "VertexDeclaration" sınıfı oluşturun ve "Vertex Data Definition" ı ayarlayın.

Ancak, XNA Game Studio 4.0'dan başlayarak bu kurulum basitleştirildi ve bu ipucu için bir VertexDeclaration sınıfı hazırlamanıza gerek yok. (Bunun nedeni, tanım bilgilerinin çerçeve tarafından sağlanan köşe verilerine zaten gömülü olmasıdır.)

Köşe verileri

Çokgenleri çizmek için köşe verilerinin gerekli olduğunu yazdım, ancak önce ne tür verilere sahip olmak istediğimize karar vermemiz gerekiyor. Bu durumda, "konum" ve "renk" verilerini kullanacağız. Hangi verilere sahip olmak istediğinize karar verdikten sonra, bu verileri tutacak bir yapı oluşturmanız gerekir. Köşe verisinin ne olduğuna karar verme özgürlüğüne sahipsiniz, ancak yaygın olarak kullanılan köşe verileri XNA Çerçevesinde zaten tanımlanmıştır, bu nedenle örnek bunu kullanır.

"position" ve "color" içeren köşe verileri, "VertexPositionColor" yapısı olarak tanımlanır. Bir çokgen oluşturmak için birden fazla köşeye ihtiyaç duyulduğundan, onu bir dizi olarak bildiririz.

/// <summary>
/// 頂点データリスト
/// </summary>
private VertexPositionColor[] vertices = null;

etki

XNA'da, bir çokgen çizdiğinizde, onu nasıl çizeceğinize karar vermek için ayrı bir gölgelendirici programı yazmanız gerekir. Bunu yapmak için ayrı bir efekt dosyası oluşturun, bir program yazın, bunu bir efekt sınıfı olarak yükleyin ve gölgelendirici programını çalıştırın.

Ancak, bunun gibi basit üçgen çokgenler veya karmaşık çizim efektleri çizmeniz gerekmiyorsa, bu çok zahmetli bir iş olabilir.

Bu nedenle, XNA, temel çizim için bir gölgelendirici programı yazmak zorunda kalmamanız için gerekli öğeleri özellik olarak ayarlamanıza olanak tanıyan genişletilmiş efektler tanımlar. Bu "BasicEffect" sınıfıdır. Bu yazının amacı çokgen çizmek olduğu için çizmek için fazla çaba gerektirmeyen "BasicEffect" kullanacağız.

/// <summary>
/// 基本エフェクト
/// </summary>
private BasicEffect basicEffect = null;

Efektler ve Temel Efektler hakkında başka bir zaman daha fazla konuşacağım.

Bu arada, Windows Phone 7 kendi efektlerinizi kullanmanıza izin vermez, yalnızca BasicEffect gibi çerçevelerde yerleşik olanları kullanmanıza izin verir.

Köşe veri tanımı oluşturma

XNA Framework 3.1'e kadar, bunları açıkça programlı olarak oluşturmanız gerekiyordu, ancak 4.0'dan başlayarak, çerçevenin yerleşik köşe bilgileri zaten köşe bilgilerine "IVertexType.VertexDeclaration" olarak dahil edilmiştir, bu yüzden onu kullanacağız.

Efekt Oluşturma

Bir BasicEffect sınıfı oluşturun. Köşe renklerini korumak için BasicEffect.VertexColorEnabled özelliğini true olarak ayarlayın.

// エフェクトを作成
this.basicEffect = new BasicEffect(this.GraphicsDevice);

// エフェクトで頂点カラーを有効にする
this.basicEffect.VertexColorEnabled = true;

BasicEffect Oluşturucu

Shader Model 2.0'ı kullanarak köşe rengi, dokusu ve ışıklandırması gerçekleştiren "BasicEffect" efekt sınıfının bir örneğini oluşturun.

aygıt Ekran KartıAygıt Efekti oluşturmak için GraphicsDevice'ı belirtir

Matris ve Projeksiyon Matrisini Görüntüle

BasicEffect'i bir görünüm matrisi ve bir projeksiyon matrisi olarak ayarlayın. Her birinin kavramsal bir açıklaması için aşağıdaki bağlantılara bakın.

// ビューマトリックスをあらかじめ設定 ((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
    );

Bir görünüm matrisi oluşturmak için "Matrix.CreateLookAt" yöntemini kullanın.

İlk bağımsız değişken kameranın konumunu, ikinci bağımsız değişken kameranın ilgi noktasını ve üçüncü bağımsız değişken kameranın yukarı yönünü belirtir.

Bu durumda, (0, 0, 15) konumundan orijine bakacak şekilde ayarlanmıştır.

Matrix.CreateLookAt yöntem

Bir görünüm matrisi oluşturun.

kamera Konumu Vektör3 Kamera Konumu
kamera hedefi Vektör3 Kamera İlgi Çekici Nokta
cameraUpVector Vektör3 Kameranın yukarı yönü

Bir projeksiyon matrisi oluşturmak için "Matrix.CreatePerspectiveFieldOfView" yöntemini kullanın.

İlk argüman, radyan cinsinden görüş açısıdır. Örnekte, derece birimi "MathHelper.ToRadians" yöntemi kullanılarak radyana dönüştürülür. Radyan ve Derece hakkında daha fazla bilgi için bkz: Radyan ve Derece.

İkinci bağımsız değişken en boy oranını (en boy oranı) belirtir. Genellikle, Görünüm Genişliği ÷ Yüksekliği için bir değer belirtirsiniz. Örnekte, cihazın görüntü alanı için ayarlanan genişlik ve yükseklikten hesaplanır.

Üçüncü bağımsız değişken ileri kırpma konumunu, dördüncü bağımsız değişken ise geriye doğru kırpma konumunu belirtir.

Matrix.CreatePerspectiveFieldOfView yöntem

Görünüm alanının ayarlarına bağlı olarak bir perspektif projeksiyon matrisi oluşturur.

fieldOfView yüzmek Görüş açısı. Radyan birimlerinde belirtilmiştir.
aspectRatio (En Boy Oranı) yüzmek En boy oranı (en boy oranı). Normalde, "Görünüm Genişliği ÷ Yüksekliği" için bir değer belirtirsiniz
nearPlaneDistance (Uçak Mesafesi) yüzmek İleri klip konumu. Bu konumun önündeki nesneler çizilmez.
farPlaneDistance (FarPlaneDistance yüzmek Arka klips konumu. Bu konumun ötesindeki nesneler çizilmez.

Köşe Verileri Oluşturma

Üç köşe verisi oluşturun. İlk olarak, bir dizi oluşturacağız ve her bir köşeyi oluşturacağız.

// 頂点データを作成する
this.vertices = new VertexPositionColor[3];

this.vertices[0] = new VertexPositionColor(new Vector3(0.0f, 3.0f, 0.0f),
                                           Color.Red);
this.vertices[1] = new VertexPositionColor(new Vector3(3.0f, -2.0f, 0.0f),
                                           Color.Blue);
this.vertices[2] = new VertexPositionColor(new Vector3(-3.0f, -2.0f, 0.0f),
                                           Color.Green);

Köşe verileri oluşturmak için, "VertexPositionColor" yapıcısında "köşe konumunu" ve "köşe rengini" belirtin.

VertexPositionColor Oluşturucu

Konum ve renk köşe verileriyle "VertexPositionColor" yapısının bir örneğini oluşturun.

konum Vektör3 Köşe Konumu
Renk Renk Köşe rengi

Köşelerin konumunu kameradan görülebilen aralığa ayarlayın. Ayrıca, köşe düzenlemesini "saat yönünde (saat yönünde)" olarak ayarlayın. "Saat yönünün tersine" olarak ayarlarsanız, çokgen görünmeyecektir. Bunun açıklaması için, bkz: Çizilecek Çokgenin Yüzlerini Belirleme.

Çokgen çizme

// パスの数だけ繰り替えし描画 (といっても直接作成した BasicEffect は通常1回)
foreach (EffectPass pass in this.basicEffect.CurrentTechnique.Passes)
{
    // パスの開始
    pass.Apply();

    // ポリゴンを描画する
    this.GraphicsDevice.DrawUserPrimitives(
        PrimitiveType.TriangleList,
        this.vertices,
        0,
        1
    );
}

// 登録された DrawableGameComponent を描画する
base.Draw(gameTime);

"Teknikler" ve "yollar" adı verilen ve gerçek çizim programını çalıştırdığınız iki tür efekt vardır. Tek bir efektte birden fazla yol olabileceğinden, bunları foreach içinde tekrar tekrar çağırmaya çalışıyorum. Bununla birlikte, BasicEffect'te bir teknik ve bir yol vardır, bu nedenle yolun dizinini doğrudan belirleyebilirsiniz, ancak yukarıdaki açıklama daha temiz olacaktır çünkü onu diğer efektlerle değiştirebilirsiniz.

Gerçek çizime başlamadan önce, geçişi başlatmak için "EffectPass.Apply" yöntemini çağırın. Bu yöntemi çağırarak, bu sefer kullanılacak efektin parametreleri grafik aygıtına uygulanır.

Yolu başlattıktan sonra, çokgeni "GraphicsDevice.DrawUserPrimitives" yöntemiyle çizin.

İlk bağımsız değişken, çizilecek temel öğenin türünü belirtir. Bu durumda, üçgen bir çokgen çizeceğiz, bu nedenle "PrimitiveType.TriangleList" belirtin.

İkinci bağımsız değişken, oluşturulan köşe verilerini belirtir.

Üçüncü bağımsız değişken, çizilecek tepe noktasını belirtir. Normalde, bu 0'dır.

Dördüncü bağımsız değişken, çizilecek temel öğelerin sayısını belirtir. Bu durumda, yalnızca bir üçgen çokgen vardır, bu nedenle 1 belirtin. Bunun köşe sayısı olmadığını unutmayın.

GraphicsDevice.DrawUserPrimitives yöntem

Kullanıcı tarafından sağlanan köşe verilerine dayalı olarak temel öğeler çizer.

T Limit yok Vertex Veri Yapıları
ilkel tip İlkel Tip Çizilecek ilkel türü
köşe Verileri T[] Çizilecek bir köşe verileri dizisi
köşe Ofseti Int Çizim için kullanılacak köşe verilerinin sayısını belirtin
ilkel Sayı Int Çizilecek temel öğelerin sayısı.

Çizim programı için bu kadar. Gerçekten çalıştırdıysanız ve bir üçgen görüntüleniyorsa, işiniz bitti.

Tüm Kodlar

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 DrawTriangle
{
    /// <summary>
    /// ゲームメインクラス
    /// </summary>
    public class GameMain : Microsoft.Xna.Framework.Game
    {
        /// <summary>
        /// グラフィックデバイス管理クラス
        /// </summary>
        private GraphicsDeviceManager graphics = null;

        /// <summary>
        /// スプライトのバッチ化クラス
        /// </summary>
        private SpriteBatch spriteBatch = null;

        /// <summary>
        /// 頂点データリスト
        /// </summary>
        private VertexPositionColor[] vertices = 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
                );

            // 頂点データを作成する
            this.vertices = new VertexPositionColor[3];

            this.vertices[0] = new VertexPositionColor(new Vector3(0.0f, 3.0f, 0.0f),
                                                       Color.Red);
            this.vertices[1] = new VertexPositionColor(new Vector3(3.0f, -2.0f, 0.0f),
                                                       Color.Blue);
            this.vertices[2] = new VertexPositionColor(new Vector3(-3.0f, -2.0f, 0.0f),
                                                       Color.Green);
        }

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

            // パスの数だけ繰り替えし描画 (といっても直接作成した BasicEffect は通常1回)
            foreach (EffectPass pass in this.basicEffect.CurrentTechnique.Passes)
            {
                // パスの開始
                pass.Apply();

                // ポリゴンを描画する
                this.GraphicsDevice.DrawUserPrimitives(
                    PrimitiveType.TriangleList,
                    this.vertices,
                    0,
                    1
                );
            }

            // 登録された DrawableGameComponent を描画する
            base.Draw(gameTime);
        }
    }
}