Trikampių daugiakampių rodymas
suvestinė
Jis rodo trikampius daugiakampius 3D erdvėje.
Darbo aplinka
Būtinosios sąlygos
Palaikomos XNA versijos |
|
Palaikomos platformos |
|
"Windows" reikalinga "Vertex Shader" versija | 2.0 |
"Windows" reikalinga "Pixel Shader" versija | 2.0 |
Darbo aplinka
platforma |
|
medžiaga
Kas yra daugiakampis?
Daugiakampis yra veidas, kurį sukuria keli viršūnių apibrėžimai. Apskritai, daugiakampis yra trikampis veidas, susidedantis iš trijų viršūnių. Ir trigonas yra mažiausias daugiakampio vienetas. Kai kuri modeliavimo programinė įranga gali rodyti daugiakampius kaip keturkampius arba daugiakampius, tačiau jie galiausiai bus suskaidyti į trikampius daugiakampius.
Žaidimuose rodomas modelis formuojamas derinant kelis iš šių trikampių daugiakampių.
Daugiakampius sudaro viršūnės. Viršūnės gali turėti tokius duomenis kaip padėtis ir spalva. Šis pavyzdys taip pat pagamintas iš "padėties" ir "spalvos" duomenų.
Veido spalva šiame pavyzdyje yra tvarkingai interpoliuota pagal kiekvienai viršūnei nustatytą spalvą ir atstumą, tačiau galite laisvai ją pakeisti naudodami savo šešėlių programą (daugiau apie šešėlių programas kitą kartą).
Vertex duomenų apibrėžimai
Norint parodyti daugiakampį, reikalingi "viršūnių duomenys", o programuotojas turi nuspręsti, kokius elementus įtraukti į tą viršūnę. Piešdami daugiakampį, turite pasakyti įrenginiui, kuris yra piešimo variklis, su kokiais viršūnės duomenimis piešti daugiakampį. Norėdami tai padaryti, sukurkite klasę "VertexDeclaration" ir nustatykite "Vertex Data Definition".
Tačiau, pradedant nuo "XNA Game Studio 4.0", ši sąranka buvo supaprastinta ir jums nereikia paruošti "VertexDeclaration" klasės šiam patarimui. (Taip yra todėl, kad apibrėžimo informacija jau yra įterpta į sistemos pateiktus viršūnių duomenis.)
Vertex duomenys
Rašiau, kad viršūnių duomenys reikalingi daugiakampiams piešti, bet pirmiausia turime nuspręsti, kokius duomenis norime turėti. Tokiu atveju naudosime "padėties" ir "spalvos" duomenis. Nusprendę, kokius duomenis norite turėti, turite sukurti struktūrą tiems duomenims laikyti. Jūs turite tam tikrą laisvę nuspręsti, kas yra viršūnių duomenys, tačiau dažniausiai naudojami viršūnių duomenys jau yra apibrėžti XNA sistemoje, todėl pavyzdys juos naudoja.
Vertex duomenys su "padėtimi" ir "spalva" apibrėžiami kaip "VertexPositionColor" struktūra. Kadangi daugiakampiui suformuoti reikia kelių viršūnių, mes jį deklaruojame kaip masyvą.
<summary>
頂点データリスト
</summary>
private VertexPositionColor[] vertices = null;
Poveikis
XNA, kai piešiate daugiakampį, turite parašyti atskirą šešėlių programą, kad nuspręstumėte, kaip jį piešti. Norėdami tai padaryti, sukurkite atskirą efekto failą, parašykite programą, įkelkite ją kaip efektų klasę ir paleiskite šešėliavimo programą.
Tačiau jei jums nereikia piešti paprastų trikampių daugiakampių, tokių kaip šis, ar sudėtingų piešimo efektų, tai gali būti labai sudėtinga užduotis.
Dėl šios priežasties XNA apibrėžia išplėstinius efektus, kurie leidžia nustatyti reikiamus elementus kaip ypatybes, kad nereikėtų rašyti šešėlių programos pagrindiniam piešiniui. Tai "BasicEffect" klasė. Kadangi šio straipsnio tikslas yra piešti daugiakampius, naudosime "BasicEffect", kuriam piešti nereikia daug pastangų.
<summary>
基本エフェクト
</summary>
private BasicEffect basicEffect = null;
Daugiau apie efektus ir "BasicEffects" pakalbėsiu kitu metu.
Beje, "Windows Phone 7" neleidžia naudoti savo efektų, tik tuos, kurie yra integruoti į tokias sistemas kaip "BasicEffect".
Viršūnės duomenų aprašo kūrimas
Iki XNA Framework 3.1 turėjote juos aiškiai sukurti programiškai, tačiau pradedant nuo 4.0, sistemos integruota viršūnių informacija jau yra įtraukta į viršūnių informaciją kaip "IVertexType.VertexDeclaration", todėl mes ją naudosime.
Efektų kūrimas
Sukurkite "BasicEffect" klasę. Nustatykite ypatybę BasicEffect.VertexColorEnabled į true, kad išlaikytumėte viršūnių spalvas.
// エフェクトを作成
this.basicEffect = new BasicEffect(this.GraphicsDevice);
// エフェクトで頂点カラーを有効にする
this.basicEffect.VertexColorEnabled = true;
BasicEffect
Konstruktorius
Sukurkite efektų klasės "BasicEffect" egzempliorių, kuris atlieka viršūnių spalvą, tekstūrą ir apšvietimą naudodamas "Shader Model 2.0".
prietaisas | GrafikaDevice | Nurodo grafikos įrenginį efektui sukurti |
Peržiūrėti matricą ir projekcijos matricą
Nustatykite "BasicEffect" į vaizdo matricą ir projekcijos matricą. Norėdami gauti konceptualų kiekvieno paaiškinimą, žiūrėkite toliau pateiktas nuorodas.
- Apie koordinačių transformaciją 3D modeliuose
- Peržiūrėti koordinačių sistemą
- Projekcinė koordinačių sistema
// ビューマトリックスをあらかじめ設定 ((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
);
Norėdami sugeneruoti peržiūros matricą, naudokite metodą "Matrix.CreateLookAt".
Pirmasis argumentas nurodo fotoaparato padėtį, antrasis argumentas nurodo fotoaparato lankytiną vietą, o trečiasis argumentas nurodo fotoaparato kryptį aukštyn.
Tokiu atveju nustatoma pažvelgti į kilmę iš padėties (0, 0, 15).
Matrix.CreateLookAt
metodas
Sukurkite rodinio matricą.
fotoaparatasPadėtis | Vektorius3 | Kameros padėtis |
fotoaparatasTarget | Vektorius3 | Fotoaparato lankytina vieta |
fotoaparatasUpVector | Vektorius3 | Fotoaparato kryptis aukštyn |
Norėdami sugeneruoti projekcijos matricą, naudokite metodą "Matrix.CreatePerspectiveFieldOfView".
Pirmasis argumentas yra žiūrėjimo kampas radianais. Imtyje laipsnio vienetas konvertuojamas į radianą, naudojant "MathHelper.ToRadians" metodą. Norėdami gauti daugiau informacijos apie radianą ir laipsnį, žiūrėkite Radianas ir laipsnis.
Antrasis argumentas nurodo kraštinių santykį (kraštinių santykį). Paprastai nurodote rodinio pločio ÷ aukščio reikšmę. Pavyzdyje jis apskaičiuojamas pagal prietaiso peržiūros srities plotį ir aukštį.
Trečiasis argumentas nurodo iškarpos į priekį padėtį, o ketvirtasis argumentas nurodo iškarpos atgal padėtį.
Matrix.CreatePerspectiveFieldOfView
metodas
Sukuria perspektyvos projekcijos matricą pagal vaizdo lauko parametrus.
laukasOfView | plūduriuoti | Žiūrėjimo kampas. Nurodyta radianiniais vienetais. |
aspectRatio | plūduriuoti | Kraštinių santykis (kraštinių santykis). Paprastai nurodote reikšmę "Peržiūrėti plotį ÷ aukštį" |
netoliPlaneDistance | plūduriuoti | Priekinė spaustuko padėtis. Objektai priešais šią padėtį nėra nupiešti. |
farPlaneDistance | plūduriuoti | Galinio spaustuko padėtis. Objektai, esantys už šios padėties, nėra nupiešti. |
Vertex duomenų kūrimas
Sukurkite trijų viršūnių duomenis. Pirmiausia sukursime masyvą ir sukursime kiekvieną viršūnę.
// 頂点データを作成する
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);
Norėdami sukurti viršūnių duomenis, "VertexPositionColor" konstruktoriuje nurodykite "viršūnės padėtį" ir "viršūnės spalvą".
VertexPositionColor
Konstruktorius
Sukurkite struktūros "VertexPositionColor" egzempliorių su padėties ir spalvų viršūnių duomenimis.
Poziciją | Vektorius3 | Viršūnės padėtis |
spalva | Spalva | Vertex spalva |
Nustatykite viršūnių padėtį į diapazoną, kurį galima pamatyti iš fotoaparato. Taip pat nustatykite, kad viršūnių išdėstymas būtų "pagal laikrodžio rodyklę (pagal laikrodžio rodyklę)". Jei nustatysite jį "prieš laikrodžio rodyklę", daugiakampis nebus matomas. Norėdami tai paaiškinti, žiūrėkite Daugiakampio veidų, kuriuos reikia nupiešti, nurodymas.
Daugiakampių piešimas
// パスの数だけ繰り替えし描画 (といっても直接作成した 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);
Yra dviejų tipų efektai, vadinami "technika" ir "keliais", per kuriuos paleidžiate tikrąją piešimo programą. Kadangi viename efekte gali būti keli keliai, stengiuosi juos pakartotinai pavadinti foreach. Tačiau "BasicEffect" yra viena technika ir vienas kelias, todėl galite tiesiogiai nurodyti kelio indeksą, tačiau aukščiau pateiktas aprašymas bus švaresnis, nes galite jį pakeisti kitais efektais.
Prieš pradėdami tikrąjį piešinį, iškvieskite "EffectPass.Apply" metodą, kad pradėtumėte leidimą. Skambinant šiuo metodu, grafikos įrenginiui taikomi šį kartą naudojamo efekto parametrai.
Pradėję kelią, nubrėžkite daugiakampį naudodami "GraphicsDevice.DrawUserPrimitives" metodą.
Pirmasis argumentas nurodo, kokio tipo primityvą reikia piešti. Tokiu atveju nupiešime trikampį daugiakampį, todėl nurodykite "PrimitiveType.TriangleList".
Antrasis argumentas nurodo sukurtus viršūnės duomenis.
Trečiasis argumentas nurodo viršūnę, iš kurios reikia semtis. Paprastai tai yra 0.
Ketvirtasis argumentas nurodo primityvų, kuriuos reikia nupiešti, skaičių. Šiuo atveju yra tik vienas trikampis daugiakampis, todėl nurodykite 1. Atkreipkite dėmesį, kad tai nėra viršūnių skaičius.
GraphicsDevice.DrawUserPrimitives
metodas
Piešia primityvus pagal vartotojo pateiktus viršūnių duomenis.
T | Nėra jokių apribojimų | Vertex duomenų struktūros |
primityvusTipas | Primityvustipas | Primityviojo piešimo tipas |
vertexData | T[] | Viršūnių duomenų masyvas, kurį reikia nubrėžti |
vertexOffset | Int | Nurodykite brėžiniams naudotinų viršūnių duomenų skaičių |
primityvusCount | Int | Primityvių, kuriuos reikia nupiešti, skaičius. |
Viskas piešimo programai. Jei iš tikrųjų jį paleisite ir bus rodomas trikampis, viskas.
Visi kodai
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);
}
}
}