Kolmnurksete hulknurkade kuvamine

Lehekülg uuendatud :
Lehe loomise kuupäev :

Kokkuvõte

See kuvab 3D-ruumis kolmnurksed hulknurgad.

3角形ポリゴンの表示

Töökeskkond

Eeltingimused

Toetatud XNA versioonid
  • 4.0
Toetatud platvormid
  • Windows (XP SP2 või uuem, Vista, 7)
  • Xbox 360
  • Windows Phone 7
Windowsi nõutav vertex shaderi versioon 2.0
Windowsi nõutav versioon Pixel Shader 2.0

Töökeskkond

platvorm
  • Windows 7
  • Xbox 360
  • Windows Phone 7 emulaator

aine

Mis on hulknurk?

Hulknurk on nägu, mille tekitavad mitmed tipumääratlused. Üldiselt on hulknurk kolmnurkne nägu, mis koosneb kolmest tipust. Ja trigon on hulknurga väikseim üksus. Mõni modelleerimistarkvara võib kuvada hulknurki nelinurksete või hulknurksetena, kuid need lagunevad lõpuks kolmnurkseteks hulknurkadeks.

Mängudes kuvatav mudel on moodustatud nende kolmnurksete hulknurkade mitme ühendamise teel.

最小単位のポリゴン

Hulknurgad on moodustatud tippudest. Tippudel võivad olla sellised andmed nagu asukoht ja värv. See proov on tehtud ka "positsiooni" ja "värvi" andmetest.

ポリゴンと頂点

Selles näites on näo värv kenasti interpoleeritud iga tipu jaoks seatud värvi ja kaugusega, kuid saate seda vabalt muuta oma varjutusprogrammiga (rohkem varjutusprogrammidest teine kord).

Tipuandmete määratlused

Hulknurga kuvamiseks on vaja "tipuandmeid" ja programmeerija peab otsustama, milliseid elemente sellesse tippu lisada. Hulknurga joonistamisel peate seadmele ütlema, milline on joonistusmootor, milliste tipuandmetega hulknurka joonistada. Selleks looge klass "VertexDeclaration" ja määrake "Vertex Data Definition".

Kuid alates XNA Game Studio 4.0-st on see seadistus lihtsustatud ja te ei pea selle näpunäite jaoks VertexDeclaration klassi ette valmistama. (Seda seetõttu, et definitsiooniteave on juba kaasatud raamistiku esitatud tipuandmetesse.)

Tipu andmed

Kirjutasin, et hulknurkade joonistamiseks on vaja tipuandmeid, kuid kõigepealt peame otsustama, milliseid andmeid me tahame saada. Sel juhul kasutame andmeid "positsioon" ja "värv". Kui olete otsustanud, milliseid andmeid soovite saada, peate looma struktuuri nende andmete hoidmiseks. Teil on mõningane vabadus otsustada, millised tipuandmed on, kuid tavaliselt kasutatavad tipuandmed on XNA raamistikus juba määratletud, nii et valim kasutab seda.

Tipuandmed "positsiooni" ja "värviga" on määratletud kui "VertexPositionColor" struktuur. Kuna hulknurga moodustamiseks on vaja mitut tippu, kuulutame selle massiiviks.

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

mõju

XNA-s peate hulknurga joonistamisel kirjutama eraldi varjutusprogrammi, et otsustada, kuidas seda joonistada. Selleks looge eraldi efektifail, kirjutage programm, laadige see efektiklassina ja käivitage varjutusprogramm.

Kui te aga ei pea joonistama lihtsaid kolmnurkseid hulknurki nagu see või keerulisi joonistusefekte, võib see olla väga tülikas ülesanne.

Sel põhjusel määratleb XNA laiendatud efektid, mis võimaldavad teil määrata nõutavad üksused atribuutideks, nii et te ei pea põhijoonise jaoks varjutusprogrammi kirjutama. See on klass "BasicEffect". Kuna selle artikli eesmärk on hulknurkade joonistamine, kasutame "BasicEffect", mis ei võta joonistamiseks palju vaeva.

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

Efektidest ja BasicEffectsist räägin lähemalt muul ajal.

Muide, Windows Phone 7 ei luba teil kasutada oma efekte, vaid ainult neid, mis on sisse ehitatud sellistesse raamistikesse nagu BasicEffect.

Tipuandmete määratluse loomine

Kuni XNA raamistikuni 3.1 pidite need programmiliselt selgesõnaliselt looma, kuid alates 4.0-st on raamistiku sisseehitatud tiputeave juba tiputeabes "IVertexType.VertexDeclaration", nii et me kasutame seda.

Efektide loomine

Looge klass BasicEffect. Seadke atribuudi BasicEffect.VertexColorEnabled väärtuseks tõene, et tipuvärvid säiliksid.

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

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

BasicEffect ehitaja

Looge efektiklassi "BasicEffect" eksemplar, mis täidab tipuvärvi, tekstuuri ja valgustust, kasutades Shader Model 2.0.

Seadme GraafikaSeade Määrab efekti loomiseks GraphicsDevice'i

Vaata maatriksit ja projektsioonimaatriksit

Seadke BasicEffect vaatemaatriksiks ja projektsioonimaatriksiks. Igaühe kontseptuaalse selgituse leiate allolevatelt linkidelt.

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

Vaatemaatriksi loomiseks kasutage meetodit "Matrix.CreateLookAt".

Esimene argument määrab kaamera asukoha, teine argument kaamera huvipunkti ja kolmas argument kaamera ülespoole suunatud suuna.

Sellisel juhul on seatud vaatama päritolu positsioonist (0, 0, 15).

Matrix.CreateLookAt Meetod

Vaatemaatriksi loomine.

kaameraPositsioon Vektor3 Kaamera asukoht
kaameraSihtimine Vektor3 Kaamera huvipunkt
kaameraUpVector Vektor3 Kaamera ülespoole suunatud suund

Projektsioonimaatriksi loomiseks kasutage meetodit "Matrix.CreatePerspectiveFieldOfView".

Esimene argument on vaatenurk radiaanides. Proovis teisendatakse kraadiühik radiaaniks, kasutades meetodit "MathHelper.ToRadians". Lisateavet radiaani ja kraadi kohta leiate jaotisest Radiaan ja kraad.

Teine argument määrab kuvasuhte (kuvasuhte). Tavaliselt saate määrata väärtuse vaate laius ÷ kõrgus. Proovis arvutatakse see seadme vaateavale määratud laiuse ja kõrguse põhjal.

Kolmas argument määrab ettepoole lõikamise asendi ja neljas argument tagasilõikeasendi.

Matrix.CreatePerspectiveFieldOfView Meetod

Loob vaatevälja sätete põhjal perspektiivprojektsioonimaatriksi.

fieldOfView Float Vaatenurk. Määratud radiaaniühikutes.
aspectRatio Float Kuvasuhe (kuvasuhe). Tavaliselt määrate väärtuse "Vaate laius ÷ kõrgus"
nearPlaneDistance Float Edasi klipi asend. Selle positsiooni ees olevaid objekte ei joonistata.
farPlaneDistance Float Tagumine klambri asend. Sellest asendist kaugemale jäävaid objekte ei joonistata.

Tipuandmete loomine

Looge kolm tipu andmeid. Esiteks loome massiivi ja loome iga tipu.

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

Tipuandmete loomiseks määrake "VertexPositionColor" konstruktoris "tipu asukoht" ja "tipu värv".

VertexPositionColor ehitaja

Looge struktuuri "VertexPositionColor" eksemplar asukoha ja värvi tipu andmetega.

asend Vektor3 Tipu asend
värv Värv Tipu värv

Seadke tippude asukoht kaamerast nähtavale vahemikule. Samuti seadke tipu paigutus "päripäeva (päripäeva)". Kui seate selle "vastupäeva", ei ole hulknurk nähtav. Selle selgituseks vaadake teemat Joonistatava hulknurga nägude täpsustamine.

Hulknurkade joonistamine

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

Efekte on kahte tüüpi, mida nimetatakse "tehnikateks" ja "radadeks", mille kaudu käivitate tegeliku joonistusprogrammi. Kuna ühes efektis võib olla mitu teed, püüan neid korduvalt nimetada. BasicEffectis on aga üks tehnika ja üks tee, nii et saate määrata tee indeksi otse, kuid ülaltoodud kirjeldus on puhtam, sest saate selle asendada teiste efektidega.

Enne tegeliku joonistamise alustamist helistage pääsme alustamiseks meetodile "EffectPass.Apply". Seda meetodit kutsudes rakendatakse graafikaseadmele seekord kasutatava efekti parameetreid.

Kui olete tee alustanud, joonistage hulknurk meetodiga "GraphicsDevice.DrawUserPrimitives".

Esimene argument määrab joonistatava primitiivse tüübi. Sel juhul joonistame kolmnurkse hulknurga, nii et täpsustage "PrimitiveType.TriangleList".

Teine argument määrab loodud tipuandmed.

Kolmas argument määrab tipu, millest joonistada. Tavaliselt on see 0.

Neljas argument määrab joonistatavate primitiivide arvu. Sel juhul on ainult üks kolmnurkne hulknurk, seega täpsustage 1. Pange tähele, et see ei ole tippude arv.

GraphicsDevice.DrawUserPrimitives Meetod

Joonistab primitiivid kasutaja esitatud tipuandmete põhjal.

T Piirangut pole Tipu andmestruktuurid
primitiveType PrimitiveType Joonistatava primitiivse tüüp
vertexData T[] Joonistatavate tipuandmete massiiv
vertexOffset Int Määrake joonistamiseks kasutatavate tipuandmete arv
primitiivneCount Int Joonistatavate primitiivide arv.

See ongi joonistusprogrammi jaoks. Kui käivitate selle tegelikult ja kuvatakse kolmnurk, olete valmis.

Kõik koodid

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