Trīsstūrveida daudzstūru parādīšana

Lapa atjaunota :
Lapas izveides datums :

Kopsavilkuma

Tas parāda trīsstūrveida daudzstūrus 3D telpā.

3角形ポリゴンの表示

Darbības vide

Priekšnoteikumi

Atbalstītās XNA versijas
  • 4.0
Atbalstītās platformas
  • Windows (XP SP2 vai jaunāka versija, Vista, 7)
  • Xbox 360
  • Windows tālrunis 7
Windows nepieciešamā Vertex Shader versija 2.0
Windows nepieciešamā Pixel Shader versija 2.0

Darbības vide

platforma
  • Operētājsistēmā Windows 7
  • Xbox 360
  • Windows Phone 7 emulators

viela

Kas ir daudzstūris?

Daudzstūris ir seja, ko ģenerē vairākas virsotņu definīcijas. Kopumā daudzstūris ir trīsstūrveida seja, kas sastāv no trim virsotnēm. Un trigons ir mazākā daudzstūra vienība. Dažas modelēšanas programmatūras var parādīt daudzstūrus kā četrstūrus vai daudzstūrus, bet tie galu galā tiks sadalīti trīsstūrveida daudzstūros.

Spēlēs parādītais modelis veidojas, apvienojot vairākus no šiem trīsstūrveida daudzstūriem.

最小単位のポリゴン

Daudzstūrus veido virsotnes. Virsotnēm var būt tādi dati kā atrašanās vieta un krāsa. Šis paraugs ir izgatavots arī no "pozīcijas" un "krāsas" datiem.

ポリゴンと頂点

Sejas krāsa šajā piemērā ir kārtīgi interpolēta ar krāsu un attālumu, kas iestatīts katrai virsotnei, bet jūs varat to brīvi mainīt ar savu ēnotāju programmu (vairāk par ēnotāju programmām citu reizi).

Virsotņu datu definīcijas

Lai parādītu daudzstūri, ir nepieciešami "virsotņu dati", un programmētājam ir jāizlemj, kādus elementus iekļaut šajā virsotnē. Zīmējot daudzstūri, jums ir jāpasaka ierīcei, kas ir zīmēšanas dzinējs, ar kādiem virsotņu datiem zīmēt daudzstūri. Lai to izdarītu, izveidojiet klasi "VertexDeclaration" un iestatiet "Vertex Data Definition".

Tomēr, sākot ar XNA Game Studio 4.0, šī iestatīšana ir vienkāršota, un šim padomam nav jāsagatavo VertexDeclaration klase. (Tas ir tāpēc, ka definīcijas informācija jau ir iestrādāta sistēmas sniegtajos virsotņu datos.)

Virsotņu dati

Es rakstīju, ka virsotņu dati ir nepieciešami, lai zīmētu daudzstūrus, bet vispirms mums ir jāizlemj, kāda veida datus mēs vēlamies iegūt. Šajā gadījumā mēs izmantosim "pozīcijas" un "krāsu" datus. Kad esat izlēmis, kādus datus vēlaties iegūt, ir jāizveido struktūra šo datu glabāšanai. Jums ir zināma brīvība izlemt, kas ir virsotņu dati, bet parasti izmantotie virsotņu dati jau ir definēti XNA ietvarā, tāpēc paraugs tos izmanto.

Virsotņu dati ar "pozīciju" un "krāsu" tiek definēti kā "VertexPositionColor" struktūra. Tā kā, lai izveidotu daudzstūri, ir nepieciešamas vairākas virsotnes, mēs to pasludinām par masīvu.

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

efekts

XNA, zīmējot daudzstūri, jums ir jāraksta atsevišķa ēnotāju programma, lai izlemtu, kā to izdarīt. Lai to izdarītu, izveidojiet atsevišķu efektu failu, uzrakstiet programmu, ielādējiet to kā efektu klasi un palaidiet ēnotāju programmu.

Tomēr, ja jums nav nepieciešams zīmēt vienkāršus trīsstūrveida daudzstūrus, piemēram, šo, vai sarežģītus zīmēšanas efektus, tas var būt ļoti apgrūtinošs uzdevums.

Šī iemesla dēļ XNA definē paplašinātos efektus, kas ļauj iestatīt nepieciešamos vienumus kā rekvizītus, lai jums nebūtu jāraksta ēnotāja programma pamata zīmēšanai. Tā ir "BasicEffect" klase. Tā kā šī raksta mērķis ir zīmēt daudzstūrus, mēs izmantosim "BasicEffect", kas neprasa daudz pūļu, lai izdarītu.

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

Es runāšu vairāk par efektiem un BasicEffects citā laikā.

Starp citu, Windows Phone 7 neļauj izmantot savus efektus, tikai tos, kas iebūvēti tādos ietvaros kā BasicEffect.

Virsotņu datu definīcijas izveide

Līdz XNA Framework 3.1 jums tie bija skaidri jāizveido programmiski, bet, sākot ar 4.0, ietvara iebūvētā virsotņu informācija jau ir iekļauta virsotņu informācijā kā "IVertexType.VertexDeclaration", tāpēc mēs to izmantosim.

Efektu radīšana

Izveidojiet BasicEffect klasi. Iestatiet rekvizītu BasicEffect.VertexColorEnabled uz true, lai saglabātu virsotņu krāsas.

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

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

BasicEffect Konstruktors

Izveidojiet efektu klases "BasicEffect" gadījumu, kas veic virsotņu krāsu, faktūru un apgaismojumu, izmantojot Shader Model 2.0.

ierīce GrafikaDevice Norāda GraphicsDevice efekta izveidei

Skatīt matricu un projekcijas matricu

Iestatiet BasicEffect uz skata matricu un projekcijas matricu. Lai iegūtu konceptuālu skaidrojumu par katru no tiem, skatiet tālāk norādītās saites.

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

Lai ģenerētu skata matricu, izmantojiet metodi "Matrix.CreateLookAt".

Pirmais arguments norāda kameras atrašanās vietu, otrais arguments norāda kameras interešu punktu, bet trešais arguments norāda kameras virzienu uz augšu.

Šajā gadījumā ir iestatīts, lai aplūkotu izcelsmi no pozīcijas (0, 0, 15).

Matrix.CreateLookAt metode

Izveidojiet skata matricu.

kameraspozīcija 3. vektors Kameras pozīcija
cameraTarget 3. vektors Kameras interešu punkts
cameraUpVector 3. vektors Kameras virziens uz augšu

Lai ģenerētu projekcijas matricu, izmantojiet metodi "Matrix.CreatePerspectiveFieldOfView".

Pirmais arguments ir skata leņķis radiānos. Paraugā grāda vienība tiek pārvērsta radiānā, izmantojot metodi "MathHelper.ToRadians". Papildinformāciju par radiānu un grādu skatiet sadaļā Radiāns un grāds.

Otrais arguments norāda malu attiecību (malu attiecība). Parasti norādiet vienuma Skats Platums ÷ Augstums vērtību. Paraugā to aprēķina no platuma un augstuma, kas iestatīts ierīces skata logam.

Trešais arguments norāda uz priekšu vērsto izgriešanas pozīciju, bet ceturtais arguments norāda atpakaļgaitas izgriešanas pozīciju.

Matrix.CreatePerspectiveFieldOfView metode

Izveido perspektīvas projekcijas matricu, pamatojoties uz skata lauka iestatījumiem.

fieldOfView peldēt Skata leņķis. Norādīts radiāna vienībās.
aspectRatio peldēt Malu attiecība (malu attiecība). Parasti jūs norādāt vērtību "Skatīt platumu ÷ augstumu"
nearPlaneDistance peldēt Uz priekšu vērstā klipa pozīcija. Objekti šīs pozīcijas priekšā netiek zīmēti.
farPlaneDistance peldēt Aizmugurējā klipa pozīcija. Objekti, kas atrodas ārpus šīs pozīcijas, netiek zīmēti.

Virsotņu datu izveide

Izveidojiet trīs virsotņu datus. Pirmkārt, mēs izveidosim masīvu un izveidosim katru virsotni.

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

Lai izveidotu virsotņu datus, norādiet "virsotnes pozīciju" un "virsotnes krāsu" "VertexPositionColor" konstruktorā.

VertexPositionColor Konstruktors

Izveidojiet struktūras "VertexPositionColor" instanci ar pozīcijas un krāsu virsotņu datiem.

pozīcija 3. vektors Virsotnes pozīcija
krāsa Krāsa Virsotņu krāsa

Iestatiet virsotņu stāvokli diapazonā, ko var redzēt no kameras. Iestatiet arī virsotņu izkārtojumu kā "pulksteņrādītāja virzienā (pulksteņrādītāja virzienā)". Ja iestatāt to uz "pretēji pulksteņrādītāja virzienam", daudzstūris nebūs redzams. Lai to izskaidrotu, skatiet sadaļu Daudzstūra seju norādīšana zīmēšanai.

Daudzstūru zīmēšana

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

Ir divu veidu efekti, ko sauc par "paņēmieniem" un "ceļiem", caur kuriem jūs palaižat faktisko zīmēšanas programmu. Tā kā vienā efektā var būt vairāki ceļi, es cenšos tos atkārtoti saukt priekšgalā. Tomēr BasicEffect ir viena tehnika un viens ceļš, tāpēc jūs varat tieši norādīt ceļa indeksu, bet iepriekš minētais apraksts būs tīrāks, jo jūs varat to aizstāt ar citiem efektiem.

Pirms sākat faktisko zīmējumu, izsauciet metodi "EffectPass.Apply", lai sāktu caurlaidi. Zvanot uz šo metodi, grafikas ierīcei tiek piemēroti šoreiz izmantojamā efekta parametri.

Kad esat sācis ceļu, uzzīmējiet daudzstūri ar metodi "GraphicsDevice.DrawUserPrimitives".

Pirmais arguments norāda uzzīmējamā primitīva veidu. Šajā gadījumā mēs uzzīmēsim trīsstūrveida daudzstūri, tāpēc norādiet "PrimitiveType.TriangleList".

Otrais arguments norāda izveidotos virsotņu datus.

Trešais arguments norāda virsotni, no kuras izdarīt. Parasti tas ir 0.

Ceturtais arguments norāda primitīvu skaitu, kas jāizdara. Šajā gadījumā ir tikai viens trīsstūrveida daudzstūris, tāpēc norādiet 1. Ņemiet vērā, ka tas nav virsotņu skaits.

GraphicsDevice.DrawUserPrimitives metode

Zīmē primitīvus, pamatojoties uz lietotāja sniegtajiem virsotņu datiem.

T Bez ierobežojuma Virsotņu datu struktūras
primitīvsTips Primitīvs tips Primitīvais veids, kā izdarīt
vertexData T[] Zīmējamo virsotņu datu masīvs
vertexOffset Int Norādiet zīmēšanai izmantojamo virsotņu datu skaitu
primitīvsKonts Int Primitīvu skaits, ko izdarīt.

Tas ir tas zīmēšanas programmai. Ja jūs to faktiski palaižat un tiek parādīts trīsstūris, esat pabeidzis.

Visi kodi

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