הצגת מצולעים משולשים
תקציר
הוא מציג מצולעים משולשים במרחב תלת ממדי.
סביבת הפעלה
דרישות מוקדמות
גרסאות XNA נתמכות |
|
פלטפורמות נתמכות |
|
Windows נדרש Vertex Shader גירסה | 2.0 |
גירסת Pixel Shader נדרשת של Windows | 2.0 |
סביבת הפעלה
פלטפורמה |
|
חומר
מהו מצולע?
מצולע הוא פרצוף שנוצר על ידי הגדרות קודקודים מרובות. באופן כללי, מצולע הוא פרצוף משולש המורכב משלושה קודקודים. והטריגון הוא היחידה הקטנה ביותר של המצולע. תוכנות מידול מסוימות עשויות להציג מצולעים כמרובעים או מצולעים, אך אלה יפורקו בסופו של דבר למצולעים משולשים.
המודל המוצג במשחקים נוצר על ידי שילוב של מצולעים משולשים אלה.
מצולעים נוצרים על ידי קודקודים. קודקודים יכולים להכיל נתונים כגון מיקום וצבע. מדגם זה עשוי גם מנתוני "מיקום" ו"צבע".
צבע הפנים בדוגמה זו עובר אינטרפולציה מסודרת על-ידי הצבע והמרחק שהוגדרו עבור כל קודקוד, אך באפשרותך לשנות אותו באופן חופשי באמצעות תוכנית Shader משלך (עוד על תוכניות Shader בפעם אחרת).
הגדרות נתונים של Vertex
על מנת להציג מצולע, נדרשים "נתוני קודקודים", ועל המתכנת להחליט אילו אלמנטים לכלול בקודקוד זה. בעת ציור מצולע, אתה צריך להגיד למכשיר, שהוא מנוע השרטוט, עם אילו נתוני קודקוד לצייר את המצולע. לשם כך, צור מחלקה "VertexDeclaration" והגדר את "Vertex Data Definition".
עם זאת, החל מ-XNA Game Studio 4.0, הגדרה זו הפכה לפשוטה יותר, ואין צורך להכין מחלקת VertexDeclaration עבור עצה זו. (הסיבה לכך היא שמידע ההגדרה כבר מוטבע בנתוני הקודקודים שסופקו על-ידי המסגרת).
נתוני Vertex
כתבתי שנתוני קודקודים נדרשים כדי לצייר מצולעים, אבל קודם אנחנו צריכים להחליט איזה סוג של נתונים אנחנו רוצים שיהיו לנו. במקרה זה, נשתמש בנתוני "מיקום" ו"צבע". לאחר שהחלטת אילו נתונים ברצונך שיהיו לך, עליך ליצור מבנה שיחזיק נתונים אלה. יש לך חופש מסוים להחליט מהם נתוני קודקודים, אך נתוני הקודקודים הנפוצים כבר מוגדרים במסגרת XNA, כך שהמדגם משתמש בהם.
נתוני קודקוד עם "מיקום" ו"צבע" מוגדרים כמבנה "VertexPositionColor". מכיוון שיש צורך במספר קודקודים כדי ליצור מצולע, אנו מכריזים עליו כמערך.
<summary>
頂点データリスト
</summary>
private VertexPositionColor[] vertices = null;
אפקט
ב- XNA, כאשר אתה מצייר מצולע, עליך לכתוב תוכנית Shader נפרדת כדי להחליט כיצד לצייר אותו. לשם כך, צור קובץ אפקטים נפרד, כתוב תוכנית, טען אותה כמחלקת אפקטים והפעל את תוכנית Shader.
עם זאת, אם אינך צריך לצייר מצולעים משולשים פשוטים כמו זה, או אפקטים מורכבים של ציור, זו יכולה להיות משימה מסורבלת מאוד.
מסיבה זו, XNA מגדיר אפקטים מורחבים המאפשרים לך להגדיר את הפריטים הדרושים כמאפיינים כך שלא תצטרך לכתוב תוכנית Shader עבור ציור בסיסי. זוהי המחלקה "BasicEffect". מכיוון שמטרת מאמר זה היא לצייר מצולעים, נשתמש ב- "BasicEffect" שאינו דורש מאמץ רב לצייר.
<summary>
基本エフェクト
</summary>
private BasicEffect basicEffect = null;
אני אדבר יותר על אפקטים ואפקטים בסיסיים במועד אחר.
אגב, 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" המבצע צבע, מרקם ותאורה של קודקודים באמצעות Shader Model 2.0.
מכשיר | GraphicsDevice | מציין את 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 | מיקום המצלמה |
cameraTarget | וקטור3 | נקודת עניין במצלמה |
cameraUpVector | וקטור3 | כיוון כלפי מעלה של המצלמה |
כדי ליצור מטריצת הקרנה, השתמש בשיטה "Matrix.CreatePerspectiveFieldOfView".
הטיעון הראשון הוא זווית הצפייה ברדיאנים. במדגם, יחידת התואר מומרת לרדיאנים בשיטת "MathHelper.ToRadians". לקבלת מידע נוסף אודות Radian ו- Degree, ראה Radian ו- Degree.
הארגומנט השני מציין את יחס הרוחב-גובה (יחס גובה-רוחב). בדרך כלל, יש לציין ערך בתיבה 'רוחב תצוגה' ÷'גובה'. במדגם, הוא מחושב מהרוחב והגובה שנקבעו עבור האשנב של המכשיר.
הארגומנט השלישי מציין את מיקום החיתוך קדימה, והארגומנט הרביעי מציין את מיקום החיתוך לאחור.
Matrix.CreatePerspectiveFieldOfView
שיטת
יצירת מטריצת הקרנת פרספקטיבה המבוססת על הגדרות שדה התצוגה.
fieldOfView | שט | זווית צפייה. מצוין ביחידות רדיאן. |
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);
ישנם שני סוגים של אפקטים, הנקראים "טכניקות" ו"נתיבים", שבאמצעותם אתה מפעיל את תוכנית הציור בפועל. מכיוון שיכולים להיות נתיבים מרובים באפקט אחד, אני מנסה לקרוא להם שוב ושוב בהקדמה. עם זאת, ב- BasicEffect, יש טכניקה אחת ונתיב אחד, כך שתוכל לציין את האינדקס של הנתיב ישירות, אך התיאור לעיל יהיה נקי יותר מכיוון שניתן להחליף אותו באפקטים אחרים.
לפני תחילת הציור בפועל, התקשר לשיטה "EffectPass.Apply" כדי להתחיל את המעבר. על ידי קריאה לשיטה זו, הפרמטרים של האפקט שישמש הפעם מוחלים על התקן הגרפיקה.
לאחר שהתחלת את הנתיב, צייר את המצולע בשיטה "GraphicsDevice.DrawUserPrimitives".
הארגומנט הראשון מציין את סוג הפרימיטיבי שיש לצייר. במקרה זה, נצייר מצולע משולש, לכן ציין "PrimitiveType.TriangleList".
הארגומנט השני מציין את נתוני הקודקודים שנוצרו.
הארגומנט השלישי מציין את הקודקוד שממנו יש להסיק. בדרך כלל, זה 0.
הארגומנט הרביעי מציין את מספר הפרימיטיביים שיש לצייר. במקרה זה, יש רק מצולע משולש אחד, לכן ציין 1. שים לב שזה לא מספר הקודקודים.
GraphicsDevice.DrawUserPrimitives
שיטת
מצייר פרימיטיבים בהתבסס על נתוני קודקודים שסופקו על-ידי המשתמש.
T | ללא הגבלה | מבני נתונים של Vertex |
סוג פרימיטיבי | PrimitiveType | סוג הפרימיטיבי לצייר |
vertexData | T[] | מערך של נתוני קודקודים לציור |
vertexOffset | int | ציון מספר נתוני הקודקודים שישמשו לציור |
ספירה פרימיטיבית | int | מספר הפרימיטיביים לצייר. |
זהו זה עבור תוכנית הציור. אם אתה באמת מפעיל אותו ומוצג משולש, סיימת.
כל הקודים
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);
}
}
}