Εμφάνιση τριγωνικών πολυγώνων

Σελίδα ενημέρωση :
Ημερομηνία δημιουργίας σελίδας :

περίληψη

Εμφανίζει τριγωνικά πολύγωνα σε χώρο 3D.

3角形ポリゴンの表示

Περιβάλλον λειτουργίας

Προϋποθέσεις

Υποστηριζόμενες εκδόσεις XNA
  • 4.0
Υποστηριζόμενες πλατφόρμες
  • Windows (XP SP2 ή νεότερη έκδοση, Vista, 7)
  • Κονσόλα Xbox 360
  • Windows Phone 7
Windows Απαιτούμενη έκδοση σκίασης Vertex 2.0
Απαιτούμενη έκδοση Pixel Shader των Windows 2.0

Περιβάλλον λειτουργίας

πλατφόρμα
  • Τα Windows 7
  • Κονσόλα Xbox 360
  • Εξομοιωτής Windows Phone 7

ουσία

Τι είναι ένα πολύγωνο;

Ένα πολύγωνο είναι ένα πρόσωπο που δημιουργείται από πολλαπλούς ορισμούς κορυφής. Γενικά, ένα πολύγωνο είναι ένα τριγωνικό πρόσωπο που αποτελείται από τρεις κορυφές. Και το τρίγωνο είναι η μικρότερη μονάδα του πολυγώνου. Ορισμένα λογισμικά μοντελοποίησης μπορεί να εμφανίζουν πολύγωνα ως τετράπλευρα ή πολυγωνικά, αλλά αυτά τελικά θα αποσυντεθούν σε τριγωνικά πολύγωνα.

Το μοντέλο που εμφανίζεται στα παιχνίδια σχηματίζεται συνδυάζοντας πολλαπλά από αυτά τα τριγωνικά πολύγωνα.

最小単位のポリゴン

Τα πολύγωνα σχηματίζονται από κορυφές. Οι κορυφές μπορούν να έχουν δεδομένα όπως η θέση και το χρώμα. Αυτό το δείγμα γίνεται επίσης από δεδομένα "θέσης" και "χρώματος".

ポリゴンと頂点

Το χρώμα του προσώπου σε αυτό το παράδειγμα παρεμβάλλεται τακτοποιημένα από το χρώμα και την απόσταση που έχει οριστεί για κάθε κορυφή, αλλά μπορείτε να το αλλάξετε ελεύθερα με το δικό σας πρόγραμμα σκίασης (περισσότερα για τα προγράμματα σκίασης άλλη φορά).

Ορισμοί δεδομένων Vertex

Για να εμφανιστεί ένα πολύγωνο, απαιτούνται "δεδομένα κορυφής" και ο προγραμματιστής πρέπει να αποφασίσει ποια στοιχεία θα συμπεριλάβει σε αυτήν την κορυφή. Όταν σχεδιάζετε ένα πολύγωνο, πρέπει να πείτε στη συσκευή, ποια είναι η μηχανή σχεδίασης, με ποια δεδομένα κορυφής θα σχεδιάσετε το πολύγωνο. Για να το κάνετε αυτό, δημιουργήστε μια κλάση "VertexDeclaration" και ορίστε τον "Ορισμό δεδομένων Vertex".

Ωστόσο, ξεκινώντας με το XNA Game Studio 4.0, αυτή η ρύθμιση έχει απλοποιηθεί και δεν χρειάζεται να προετοιμάσετε μια κλάση VertexDeclaration για αυτήν τη συμβουλή. (Αυτό συμβαίνει επειδή οι πληροφορίες ορισμού είναι ήδη ενσωματωμένες στα δεδομένα κορυφής που παρέχονται από το πλαίσιο.)

Δεδομένα κορυφής

Έγραψα ότι τα δεδομένα κορυφής απαιτούνται για να σχεδιάσουμε πολύγωνα, αλλά πρώτα πρέπει να αποφασίσουμε τι είδους δεδομένα θέλουμε να έχουμε. Σε αυτήν την περίπτωση, θα χρησιμοποιήσουμε δεδομένα "θέσης" και "χρώματος". Μόλις αποφασίσετε ποια δεδομένα θέλετε να έχετε, πρέπει να δημιουργήσετε μια δομή για να διατηρήσετε αυτά τα δεδομένα. Έχετε κάποια ελευθερία να αποφασίσετε ποια είναι τα δεδομένα κορυφής, αλλά τα δεδομένα κορυφής που χρησιμοποιούνται συνήθως ορίζονται ήδη στο XNA Framework, επομένως το δείγμα τα χρησιμοποιεί.

Τα δεδομένα κορυφής με "θέση" και "χρώμα" ορίζονται ως δομή "VertexPositionColor". Δεδομένου ότι απαιτούνται πολλαπλές κορυφές για να σχηματίσουν ένα πολύγωνο, το δηλώνουμε ως πίνακα.

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

επίδραση

Στο XNA, όταν σχεδιάζετε ένα πολύγωνο, πρέπει να γράψετε ένα ξεχωριστό πρόγραμμα σκίασης για να αποφασίσετε πώς να το σχεδιάσετε. Για να το κάνετε αυτό, δημιουργήστε ένα ξεχωριστό αρχείο εφέ, γράψτε ένα πρόγραμμα, φορτώστε το ως κλάση εφέ και εκτελέστε το πρόγραμμα σκίασης.

Ωστόσο, εάν δεν χρειάζεται να σχεδιάσετε απλά τριγωνικά πολύγωνα όπως αυτό ή πολύπλοκα εφέ σχεδίασης, μπορεί να είναι μια πολύ δυσκίνητη εργασία.

Για το λόγο αυτό, το XNA ορίζει εκτεταμένα εφέ που σας επιτρέπουν να ορίσετε τα απαιτούμενα στοιχεία ως ιδιότητες, ώστε να μην χρειάζεται να γράψετε ένα πρόγραμμα σκίασης για βασικό σχέδιο. Αυτή είναι η κατηγορία "BasicEffect". Δεδομένου ότι ο σκοπός αυτού του άρθρου είναι να σχεδιάσουμε πολύγωνα, θα χρησιμοποιήσουμε το "BasicEffect" που δεν χρειάζεται μεγάλη προσπάθεια για να σχεδιάσουμε.

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

Θα μιλήσω περισσότερο για εφέ και BasicEffects κάποια άλλη στιγμή.

Παρεμπιπτόντως, το Windows Phone 7 δεν σας επιτρέπει να χρησιμοποιήσετε τα δικά σας εφέ, μόνο εκείνα που είναι ενσωματωμένα σε πλαίσια όπως το BasicEffect.

Δημιουργία ορισμού δεδομένων κορυφής

Μέχρι το XNA Framework 3.1, έπρεπε να τα δημιουργήσετε ρητά μέσω προγραμματισμού, αλλά ξεκινώντας από το 4.0, οι ενσωματωμένες πληροφορίες κορυφής του πλαισίου περιλαμβάνονται ήδη στις πληροφορίες κορυφής ως "IVertexType.VertexDeclaration", επομένως θα τις χρησιμοποιήσουμε.

Δημιουργία εφέ

Δημιουργήστε μια κλάση BasicEffect. Ορίστε την ιδιότητα BasicEffect.VertexColorEnabled σε true για να διατηρήσετε τα χρώματα κορυφής.

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

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

BasicEffect κατασκευαστής

Δημιουργήστε μια παρουσία της κλάσης εφέ "BasicEffect" που εκτελεί χρώμα, υφή και φωτισμό κορυφής χρησιμοποιώντας το μοντέλο σκίασης 2.0.

συσκευή ΓραφικάΣυσκευή Καθορίζει το GraphicsDevice για τη δημιουργία του εφέ

Προβολή μήτρας και μήτρας προβολής

Ορίστε το BasicEffect σε έναν πίνακα προβολής και έναν πίνακα προβολής. Για μια εννοιολογική εξήγηση του καθενός, δείτε τους παρακάτω συνδέσμους.

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

Για να δημιουργήσετε έναν πίνακα προβολής, χρησιμοποιήστε τη μέθοδο "Matrix.CreateLookAt".

Το πρώτο όρισμα καθορίζει τη θέση της κάμερας, το δεύτερο όρισμα καθορίζει το σημείο ενδιαφέροντος της κάμερας και το τρίτο όρισμα καθορίζει την ανοδική κατεύθυνση της κάμερας.

Σε αυτήν την περίπτωση, έχει ρυθμιστεί να εξετάζει την προέλευση από τη θέση (0, 0, 15).

Matrix.CreateLookAt μέθοδος

Δημιουργήστε έναν πίνακα προβολής.

κάμεραΘέση Διάνυσμα3 Θέση κάμερας
κάμεραΣτόχος Διάνυσμα3 Σημείο ενδιαφέροντος κάμερας
κάμεραUpVector Διάνυσμα3 Προς τα πάνω κατεύθυνση της κάμερας

Για να δημιουργήσετε έναν πίνακα προβολής, χρησιμοποιήστε τη μέθοδο "Matrix.CreatePerspectiveFieldOfView".

Το πρώτο επιχείρημα είναι η γωνία θέασης σε ακτίνια. Στο δείγμα, η μονάδα βαθμού μετατρέπεται σε ακτίνια χρησιμοποιώντας τη μέθοδο "MathHelper.ToRadians". Για περισσότερες πληροφορίες σχετικά με το ακτίνιο και το βαθμό, ανατρέξτε στο θέμα Ακτίνια και μοίρες.

Το δεύτερο όρισμα καθορίζει την αναλογία διαστάσεων (λόγος διαστάσεων). Συνήθως, καθορίζετε μια τιμή για την επιλογή Πλάτος προβολής ÷ Ύψος. Στο δείγμα, υπολογίζεται από το πλάτος και το ύψος που έχουν οριστεί για τη θύρα προβολής της συσκευής.

Το τρίτο όρισμα καθορίζει τη θέση αποκοπής προς τα εμπρός και το τέταρτο όρισμα καθορίζει τη θέση αποκοπής προς τα πίσω.

Matrix.CreatePerspectiveFieldOfView μέθοδος

Δημιουργεί έναν πίνακα προβολής προοπτικής με βάση τις ρυθμίσεις του πεδίου προβολής.

πεδίοOfView επιπλέω Γωνία θέασης. Καθορίζεται σε μονάδες ακτινίου.
aspectRatio επιπλέω Λόγος διαστάσεων (λόγος διαστάσεων). Κανονικά, καθορίζετε μια τιμή για "Πλάτος προβολής ÷ ύψος"
nearPlaneDistance επιπλέω Θέση κλιπ προς τα εμπρός. Τα αντικείμενα μπροστά από αυτή τη θέση δεν σχεδιάζονται.
farPlaneDistance επιπλέω Θέση πίσω κλιπ. Αντικείμενα πέρα από αυτή τη θέση δεν σχεδιάζονται.

Δημιουργία δεδομένων κορυφής

Δημιουργήστε τρία δεδομένα κορυφής. Πρώτον, θα δημιουργήσουμε έναν πίνακα και θα δημιουργήσουμε κάθε κορυφή.

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

Για να δημιουργήσετε δεδομένα κορυφής, καθορίστε τη "θέση κορυφής" και το "χρώμα κορυφής" στον κατασκευαστή του "VertexPositionColor".

VertexPositionColor κατασκευαστής

Δημιουργήστε μια παρουσία της δομής "VertexPositionColor" με τα δεδομένα κορυφής θέσης και χρώματος.

θέση Διάνυσμα3 Θέση κορυφής
χρώμα Χρώμα Χρώμα κορυφής

Ρυθμίστε τη θέση των κορυφών στο εύρος που μπορεί να δει κανείς από την κάμερα. Επίσης, ρυθμίστε τη διάταξη κορυφής ώστε να είναι "δεξιόστροφα (δεξιόστροφα)". Εάν το ρυθμίσετε σε "αριστερόστροφα", το πολύγωνο δεν θα είναι ορατό. Για μια εξήγηση αυτού, δείτε Καθορισμός των όψεων ενός πολυγώνου για σχεδίαση.

Σχεδίαση πολυγώνων

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

Υπάρχουν δύο τύποι εφέ, που ονομάζονται "τεχνικές" και "διαδρομές", μέσω των οποίων εκτελείτε το πραγματικό πρόγραμμα σχεδίασης. Δεδομένου ότι μπορεί να υπάρχουν πολλαπλές διαδρομές σε ένα μόνο αποτέλεσμα, προσπαθώ να τις αποκαλώ επανειλημμένα στο foreach. Ωστόσο, στο BasicEffect, υπάρχει μία τεχνική και μία διαδρομή, επομένως μπορείτε να καθορίσετε απευθείας το ευρετήριο της διαδρομής, αλλά η παραπάνω περιγραφή θα είναι πιο καθαρή επειδή μπορείτε να την αντικαταστήσετε με άλλα εφέ.

Πριν ξεκινήσετε το πραγματικό σχέδιο, καλέστε τη μέθοδο "EffectPass.Apply" για να ξεκινήσετε το πέρασμα. Καλώντας αυτήν τη μέθοδο, οι παράμετροι του εφέ που θα χρησιμοποιηθεί αυτή τη φορά εφαρμόζονται στη συσκευή γραφικών.

Μόλις ξεκινήσετε τη διαδρομή, σχεδιάστε το πολύγωνο με τη μέθοδο "GraphicsDevice.DrawUserPrimitives".

Το πρώτο όρισμα καθορίζει τον τύπο του πρωτόγονου που πρέπει να σχεδιαστεί. Σε αυτήν την περίπτωση, θα σχεδιάσουμε ένα τριγωνικό πολύγωνο, οπότε καθορίστε "PrimitiveType.TriangleList".

Το δεύτερο όρισμα καθορίζει τα δεδομένα κορυφής που δημιουργήθηκαν.

Το τρίτο όρισμα καθορίζει την κορυφή από την οποία θα αντληθεί. Κανονικά, αυτό είναι 0.

Το τέταρτο όρισμα καθορίζει τον αριθμό των πρωτόγονων που πρέπει να σχεδιάσουν. Σε αυτήν την περίπτωση, υπάρχει μόνο ένα τριγωνικό πολύγωνο, οπότε καθορίστε 1. Σημειώστε ότι δεν είναι ο αριθμός των κορυφών.

GraphicsDevice.DrawUserPrimitives μέθοδος

Σχεδιάζει πρωτόγονα με βάση τα δεδομένα κορυφής που παρέχονται από τον χρήστη.

T Χωρίς όριο Δομές δεδομένων κορυφής
πρωτόγονοςΤύπος Πρωτόγονος τύπος Ο τύπος του πρωτόγονου να σχεδιάσει
κορυφήΔεδομένα T[] Μια σειρά δεδομένων κορυφής για σχεδίαση
vertexΜετατόπιση ιντ Καθορίστε τον αριθμό των δεδομένων κορυφής που θα χρησιμοποιηθούν για τη σχεδίαση
πρωτόγονοςΚόμης ιντ Ο αριθμός των πρωτόγονων για να σχεδιάσετε.

Αυτό είναι για το πρόγραμμα σχεδίασης. Εάν το εκτελέσετε πραγματικά και εμφανιστεί ένα τρίγωνο, τελειώσατε.

Όλοι οι κωδικοί

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