Háromszög alakú sokszögek megjelenítése
összefoglalás
Háromszög alakú sokszögeket jelenít meg 3D térben.
Működési környezet
Előfeltételek
Támogatott XNA verziók |
|
Támogatott platformok |
|
Windows Szükséges Vertex Shader verzió | 2.0 |
Windows Szükséges Pixel Shader verzió | 2.0 |
Működési környezet
peron |
|
lényeg
Mi az a sokszög?
A sokszög olyan lap, amelyet több csúcspontdefiníció hoz létre. Általában a sokszög egy háromszög alakú felület, amely három csúcsból áll. És a trigon a sokszög legkisebb egysége. Egyes modellező szoftverek a poligonokat négyszögként vagy sokszögként jeleníthetik meg, de ezek végül háromszög alakú sokszögekké bomlanak.
A játékokban megjelenített modell több ilyen háromszög alakú sokszög kombinálásával jön létre.
A sokszögeket csúcsok alkotják. A csúcsok tartalmazhatnak olyan adatokat, mint a pozíció és a szín. Ez a minta "pozíció" és "szín" adatokból is készül.
Ebben a példában az arc színét szépen interpolálja az egyes csúcsokhoz beállított szín és távolság, de szabadon megváltoztathatja azt saját árnyékoló programjával (többet az árnyékoló programokról máskor).
Csúcspontadat-definíciók
A sokszög megjelenítéséhez "csúcspontadatokra" van szükség, és a programozónak el kell döntenie, hogy mely elemeket foglalja bele a csúcspontba. Sokszög rajzolásakor meg kell mondania az eszköznek, amely a rajzmotor, hogy milyen csúcsadatokkal rajzolja meg a sokszöget. Ehhez hozzon létre egy "VertexDeclaration" osztályt, és állítsa be a "Vertex Data Definition" értéket.
Az XNA Game Studio 4.0-s verziójától kezdve azonban ez a beállítás egyszerűsödött, és ehhez a tipphez nem kell VertexDeclaration osztályt készítenie. (Ennek az az oka, hogy a definíciós információ már be van ágyazva a keretrendszer által biztosított csúcspontadatokba.)
Csúcspont adatok
Azt írtam, hogy a sokszögek rajzolásához csúcsadatok szükségesek, de először el kell döntenünk, hogy milyen adatokat akarunk. Ebben az esetben "pozíció" és "szín" adatokat fogunk használni. Miután eldöntötte, hogy milyen adatokat szeretne, létre kell hoznia egy struktúrát az adatok tárolására. Bizonyos szabadsággal döntheti el, hogy mi a csúcspontadat, de az általánosan használt csúcspontadatok már definiálva vannak az XNA keretrendszerben, így a minta ezeket használja.
A "pozíció" és "szín" csúcspontadatok "VertexPositionColor" struktúraként vannak definiálva. Mivel egy sokszög kialakításához több csúcs szükséges, tömbként deklaráljuk.
<summary>
頂点データリスト
</summary>
private VertexPositionColor[] vertices = null;
hatás
Az XNA-ban, amikor sokszöget rajzol, külön árnyékoló programot kell írnia, hogy eldöntse, hogyan kell rajzolni. Ehhez hozzon létre egy külön effektusfájlt, írjon egy programot, töltse be effektusosztályként, és futtassa az árnyékoló programot.
Ha azonban nem kell ilyen egyszerű háromszög alakú sokszögeket vagy összetett rajzhatásokat rajzolnia, ez nagyon nehézkes feladat lehet.
Ezért az XNA olyan kiterjesztett effektusokat definiál, amelyek lehetővé teszik a szükséges elemek tulajdonságként való beállítását, így nem kell árnyékoló programot írnia az alapvető rajzoláshoz. Ez a "BasicEffect" osztály. Mivel ennek a cikknek a célja sokszögek rajzolása, a "BasicEffect" -et fogjuk használni, amely nem igényel sok erőfeszítést a rajzoláshoz.
<summary>
基本エフェクト
</summary>
private BasicEffect basicEffect = null;
Az effektusokról és a BasicEffectsről egy másik időpontban fogok többet beszélni.
Egyébként a Windows Phone 7 nem teszi lehetővé a saját effektusok használatát, csak azokat, amelyek olyan keretrendszerekbe vannak beépítve, mint a BasicEffect.
Csúcspontadat-definíció létrehozása
Az XNA Framework 3.1-ig explicit módon kellett létrehozni őket, de a 4.0-tól kezdve a keretrendszer beépített csúcsinformációi már szerepelnek a csúcspont-információkban "IVertexType.VertexDeclaration" néven, ezért használni fogjuk.
Effektusok létrehozása
Hozzon létre egy BasicEffect osztályt. Állítsa a BasicEffect.VertexColorEnabled tulajdonságot true értékre a csúcspont színének megtartásához.
// エフェクトを作成
this.basicEffect = new BasicEffect(this.GraphicsDevice);
// エフェクトで頂点カラーを有効にする
this.basicEffect.VertexColorEnabled = true;
BasicEffect
Konstruktor
Hozzon létre egy példányt a "BasicEffect" effektusosztályból, amely csúcspontszínt, textúrát és megvilágítást végez a Shader Model 2.0 használatával.
eszköz | GrafikaEszköz | Megadja a hatás létrehozásához használt grafikus eszközt |
Mátrix és vetítési mátrix megtekintése
Állítsa a BasicEffect értékét nézetmátrixra és vetítési mátrixra. Mindegyik fogalmi magyarázatát lásd az alábbi linkeken.
- Információk a 3D modellek koordinátatranszformációjáról
- Koordináta-rendszer megtekintése
- Projektív koordináta-rendszer
// ビューマトリックスをあらかじめ設定 ((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
);
Nézetmátrix létrehozásához használja a "Matrix.CreateLookAt" metódust.
Az első argumentum a fényképezőgép pozícióját, a második argumentum a fényképezőgép érdekes pontját, a harmadik argumentum pedig a kamera felfelé irányuló irányát adja meg.
Ebben az esetben úgy van beállítva, hogy az origót a pozícióból (0, 0, 15) nézze.
Matrix.CreateLookAt
módszer
Hozzon létre egy nézetmátrixot.
cameraPosition | Vektor3 | Kamera pozíciója |
cameraTarget | Vektor3 | Kamera érdekes hely |
cameraUpVector | Vektor3 | A kamera felfelé irányuló iránya |
Vetítési mátrix létrehozásához használja a "Matrix.CreatePerspectiveFieldOfView" metódust.
Az első érv a látószög radiánban. A mintában a fokegységet radiánra konvertáljuk a "MathHelper.ToRadians" módszerrel. További információ a radiánról és a fokozatról: radián és fok.
A második argumentum a méretarányt (oldalarányt) adja meg. Általában a Nézet szélessége ÷ a Magasság mezőben kell megadni egy értéket. A mintában ezt az eszköz nézetablakához beállított szélességből és magasságból számítja ki a rendszer.
A harmadik argumentum az előre, a negyedik pedig a hátrafelé vágási pozíciót adja meg.
Matrix.CreatePerspectiveFieldOfView
módszer
Perspektivikus vetítési mátrixot hoz létre a nézetmező beállításai alapján.
fieldOfView | lebeg | Látószög. Radián egységekben megadva. |
aspectRatio | lebeg | Képarány (képarány). Általában meg kell adnia egy értéket a "Nézet szélessége ÷ magassága" számára |
nearPlaneDistance | lebeg | Előre klip pozíciója. Az e pozíció előtti objektumok nem rajzolódnak meg. |
farPlaneDistance | lebeg | Hátsó klip helyzete. Az ezen a pozíción túli objektumok nem rajzolódnak. |
Csúcspontadatok létrehozása
Hozzon létre három csúcspontadatot. Először létrehozunk egy tömböt, és létrehozunk minden csúcsot.
// 頂点データを作成する
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);
Csúcspontadatok létrehozásához adja meg a "csúcspont pozícióját" és a "csúcspont színét" a "VertexPositionColor" konstruktorában.
VertexPositionColor
Konstruktor
Hozzon létre egy példányt a "VertexPositionColor" struktúrából a pozíció és a szín csúcspontadataival.
pozíció | Vektor3 | Csúcspont pozíciója |
szín | Szín | Csúcspont színe |
Állítsa be a csúcsok helyzetét a kamerából látható tartományra. Ezenkívül állítsa be a csúcspont elrendezését "az óramutató járásával megegyező (óramutató járásával megegyező irányba)" értékre. Ha "az óramutató járásával ellentétes irányba" állítja, a sokszög nem lesz látható. Ennek magyarázatát lásd: Rajzolandó sokszög lapjainak megadása.
Sokszögek rajzolása
// パスの数だけ繰り替えし描画 (といっても直接作成した 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);
Kétféle effektus létezik, úgynevezett "technikák" és "görbék", amelyeken keresztül futtatja a tényleges rajzprogramot. Mivel egy hatásnak több útja is lehet, igyekszem többször is meghívni őket a foreach-ban. A BasicEffect alkalmazásban azonban van egy technika és egy elérési út, így közvetlenül megadhatja az elérési út indexét, de a fenti leírás tisztább lesz, mert helyettesítheti más hatásokkal.
A tényleges rajz megkezdése előtt hívja meg az "EffectPass.Apply" metódust a menet elindításához. Ennek a módszernek a meghívásával az ezúttal használt hatás paramétereit alkalmazzák a grafikus eszközre.
Miután elindította az útvonalat, rajzolja meg a sokszöget a "GraphicsDevice.DrawUserPrimitives" módszerrel.
Az első argumentum határozza meg a rajzolandó primitív típusát. Ebben az esetben háromszög alakú sokszöget rajzolunk, ezért adja meg a "PrimitiveType.TriangleList" értéket.
A második argumentum a létrehozott csúcspont adatait adja meg.
A harmadik argumentum határozza meg azt a csúcspontot, amelyből rajzolni szeretne. Általában ez 0.
A negyedik argumentum a rajzolandó primitívek számát adja meg. Ebben az esetben csak egy háromszög alakú sokszög van, ezért adja meg az 1-et. Ne feledje, hogy ez nem a csúcsok száma.
GraphicsDevice.DrawUserPrimitives
módszer
Primitíveket rajzol a felhasználó által megadott csúcspontadatok alapján.
T | Nincs korlátozás | Csúcspont adatstruktúrák |
primitiveType | PrimitiveType | A primitív rajzolás típusa |
csúcspontadatok | T[] | Rajzolandó csúcspontadatok tömbje |
csúcsponteltolás | Int | Adja meg a rajzoláshoz használandó töréspontadatok számát |
primitiveCount | Int | A rajzolandó primitívek száma. |
Ennyi a rajzprogram. Ha valóban futtatja, és egy háromszög jelenik meg, akkor kész.
Minden kód
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);
}
}
}