Zobrazenie trojuholníkových mnohouholníkov

Stránka aktualizovaná :
Dátum vytvorenia strany :

súhrn

Zobrazuje trojuholníkové mnohouholníky v 3D priestore.

3角形ポリゴンの表示

Prevádzkové prostredie

Predpoklady

Podporované verzie XNA
  • 4.0
Podporované platformy
  • Windows (XP SP2 alebo novší, Vista, 7)
  • Konzola Xbox 360
  • Windows Phone 7
Windows vyžaduje verziu tieňovača vrcholov 2.0
Windows vyžaduje verziu Pixel Shader 2.0

Prevádzkové prostredie

nástupište
  • Windows 7
  • Konzola Xbox 360
  • Emulátor Windows Phone 7

látka

Čo je to mnohouholník?

Mnohouholník je plôška, ktorá je generovaná viacerými definíciami vrcholov. Vo všeobecnosti je mnohouholník trojuholníková plocha pozostávajúca z troch vrcholov. A trigón je najmenšia jednotka mnohouholníka. Niektoré modelovacie softvéry môžu zobrazovať mnohouholníky ako štvoruholníkové alebo mnohouholníkové, ale nakoniec sa rozložia na trojuholníkové mnohouholníky.

Model zobrazený v hrách je vytvorený kombináciou viacerých týchto trojuholníkových mnohouholníkov.

最小単位のポリゴン

Mnohouholníky sú tvorené vrcholmi. Vrcholy môžu obsahovať údaje, ako je poloha a farba. Táto vzorka je tiež vytvorená z údajov o "polohe" a "farbe".

ポリゴンと頂点

Farba tváre v tomto príklade je úhľadne interpolovaná farbou a vzdialenosťou nastavenou pre každý vrchol, ale môžete ju ľubovoľne meniť pomocou vlastného programu shadera (viac o programoch shaderov inokedy).

Definície údajov vrcholov

Na zobrazenie mnohouholníka sú potrebné "údaje vrcholov" a programátor sa musí rozhodnúť, ktoré prvky zahrnie do tohto vrcholu. Pri kreslení mnohouholníka musíte zariadeniu, ktoré je kresliacim strojom, povedať, s akými dátami vrcholov má mnohouholník nakresliť. Ak to chcete urobiť, vytvorte triedu "VertexDeclaration" a nastavte "Vertex Data Definition".

Počnúc XNA Game Studio 4.0 sa však toto nastavenie zjednodušilo a na tento tip nemusíte pripravovať triedu VertexDeclaration. (Je to preto, že informácie o definícii sú už vložené do údajov vrcholov poskytovaných rámcom.)

Údaje vrcholov

Napísal som, že na kreslenie mnohouholníkov sú potrebné údaje vrcholov, ale najprv sa musíme rozhodnúť, aký druh údajov chceme mať. V tomto prípade použijeme údaje o "polohe" a "farbe". Keď sa rozhodnete, aké údaje chcete mať, musíte vytvoriť štruktúru na uchovávanie týchto údajov. Máte určitú slobodu rozhodnúť sa, čo sú údaje vrcholov, ale bežne používané údaje vrcholov sú už definované v rámci XNA, takže ich ukážka používa.

Údaje vrcholov s "position" a "color" sú definované ako štruktúra "VertexPositionColor". Keďže na vytvorenie mnohouholníka je potrebných viacero vrcholov, deklarujeme ho ako pole.

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

účinok

V XNA, keď kreslíte mnohouholník, musíte napísať samostatný program shaderu, aby ste sa rozhodli, ako ho nakresliť. Ak to chcete urobiť, vytvorte samostatný súbor efektov, napíšte program, načítajte ho ako triedu efektov a spustite program shader.

Ak však nepotrebujete kresliť jednoduché trojuholníkové mnohouholníky, ako je tento, alebo zložité efekty kreslenia, môže to byť veľmi ťažkopádna úloha.

Z tohto dôvodu XNA definuje rozšírené efekty, ktoré vám umožňujú nastaviť požadované položky ako vlastnosti, aby ste nemuseli písať program shadera pre základné kreslenie. To je trieda "BasicEffect". Keďže účelom tohto článku je kresliť mnohouholníky, použijeme "BasicEffect", ktorého kreslenie nevyžaduje veľa úsilia.

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

O efektoch a BasicEffects budem hovoriť inokedy.

Mimochodom, Windows Phone 7 vám neumožňuje používať vlastné efekty, iba tie, ktoré sú zabudované do rámcov, ako je BasicEffect.

Vytvorenie definície údajov vrcholov

Až do XNA Framework 3.1 ste ich museli explicitne vytvárať programovo, ale počnúc verziou 4.0 sú vstavané informácie o vrcholoch frameworku už zahrnuté v informáciách o vrcholoch ako "IVertexType.VertexDeclaration", takže ich použijeme.

Vytváranie efektov

Vytvorte triedu BasicEffect. Nastavte vlastnosť BasicEffect.VertexColorEnabled na hodnotu true, aby sa zachovali farby vrcholov.

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

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

BasicEffect staviteľ

Vytvorte inštanciu triedy efektov "BasicEffect", ktorá vykonáva farbu vrcholov, textúru a osvetlenie pomocou modelu tieňovača 2.0.

zariadenie Grafické zariadenie Určuje grafické zariadenie na vytvorenie efektu

Zobraziť maticu a projekčnú maticu

Nastavte BasicEffect na maticu zobrazenia a maticu projekcie. Koncepčné vysvetlenie každého z nich nájdete na odkazoch nižšie.

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

Ak chcete vygenerovať maticu zobrazenia, použite metódu "Matrix.CreateLookAt".

Prvý argument určuje polohu kamery, druhý argument určuje bod záujmu kamery a tretí argument určuje smer kamery nahor.

V tomto prípade je nastavený tak, aby sa pozeral na počiatok z pozície (0, 0, 15).

Matrix.CreateLookAt metóda

Vytvorte maticu zobrazenia.

cameraPosition Vektor3 Poloha fotoaparátu
Cieľ fotoaparátu Vektor3 Bod záujmu fotoaparátu
cameraUpVector Vektor3 Smer kamery nahor

Ak chcete vygenerovať projekčnú maticu, použite metódu "Matrix.CreatePerspectiveFieldOfView".

Prvým argumentom je pozorovací uhol v radiánoch. Vo vzorke sa jednotka stupňa prevedie na radián pomocou metódy "MathHelper.ToRadians". Ďalšie informácie o radiáne a stupni nájdete v časti Radián a stupeň.

Druhý argument určuje pomer strán (pomer strán). Zvyčajne zadávate hodnotu pre Šírka zobrazenia ÷ Výška. Vo vzorke sa vypočíta zo šírky a výšky nastavenej pre záber zariadenia.

Tretí argument určuje pozíciu orezania dopredu a štvrtý argument určuje pozíciu orezania dozadu.

Matrix.CreatePerspectiveFieldOfView metóda

Vytvorí maticu perspektívnej projekcie na základe nastavení poľa zobrazenia.

poleOfView plávať Pozorovací uhol. Špecifikované v radiánových jednotkách.
aspectRatio plávať Pomer strán (pomer strán). Za normálnych okolností zadáte hodnotu pre "Šírka zobrazenia ÷ výška"
nearPlaneDistance plávať Poloha klipu dopredu. Objekty pred touto pozíciou nie sú nakreslené.
farPlaneDistance plávať Poloha zadnej spony. Objekty mimo tejto polohy sa nekreslia.

Vytváranie údajov vrcholov

Vytvorte tri údaje vrcholov. Najprv vytvoríme pole a vytvoríme každý vrchol.

// 頂点データを作成する
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);

Ak chcete vytvoriť údaje vrcholov, zadajte "polohu vrcholu" a "farbu vrcholu" v konštruktore "VertexPositionColor".

VertexPositionColor staviteľ

Vytvorte inštanciu štruktúry "VertexPositionColor" s údajmi o polohe a vrchole farby.

pozícia Vektor3 Pozícia vrcholu
farba Farba Farba vrcholu

Nastavte polohu vrcholov na rozsah, ktorý je viditeľný z kamery. Tiež nastavte usporiadanie vrcholov na "v smere hodinových ručičiek (v smere hodinových ručičiek)". Ak ho nastavíte "proti smeru hodinových ručičiek", mnohouholník nebude viditeľný. Vysvetlenie nájdete v časti Určenie plôšok mnohouholníka, ktorý sa má nakresliť.

Kreslenie polygónov

// パスの数だけ繰り替えし描画 (といっても直接作成した 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);

Existujú dva typy efektov, nazývané "techniky" a "cesty", cez ktoré spúšťate skutočný program na kreslenie. Keďže v jednom efekte môže byť viacero ciest, snažím sa ich opakovane volať v predobraze. V BasicEffect však existuje jedna technika a jedna cesta, takže môžete priamo určiť index cesty, ale vyššie uvedený popis bude čistejší, pretože ním môžete nahradiť iné efekty.

Pred spustením skutočného kreslenia zavolajte metódu "EffectPass.Apply" na spustenie priechodu. Volaním tejto metódy sa na grafické zariadenie použijú parametre efektu, ktorý sa má tentokrát použiť.

Po spustení cesty nakreslite mnohouholník metódou "GraphicsDevice.DrawUserPrimitives".

Prvý argument určuje typ primitíva, ktorý sa má nakresliť. V tomto prípade nakreslíme trojuholníkový mnohouholník, preto zadajte "PrimitiveType.TriangleList".

Druhý argument určuje vytvorené údaje vrcholov.

Tretí argument určuje vrchol, z ktorého sa má čerpať. Normálne je to 0.

Štvrtý argument určuje počet primitív, ktoré sa majú nakresliť. V tomto prípade existuje iba jeden trojuholníkový mnohouholník, preto zadajte 1. Všimnite si, že to nie je počet vrcholov.

GraphicsDevice.DrawUserPrimitives metóda

Vykreslí primitívy na základe údajov vrcholov zadaných používateľom.

T Bez obmedzenia Dátové štruktúry vrcholov
primitívny typ Primitívny typ Typ primitíva na kreslenie
vertexData T[] Pole údajov vrcholov na kreslenie
vertexOffset Int Zadajte počet údajov vrcholov, ktoré sa majú použiť na kreslenie
primitiveCount Int Počet primitívov na nakreslenie.

To je všetko pre program na kreslenie. Ak ho skutočne spustíte a zobrazí sa trojuholník, máte hotovo.

Všetky kódy

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