Üçgen çokgenleri görüntüleme
özet
3B uzayda üçgen çokgenleri görüntüler.
Çalışma ortamı
Önkoşullar
Desteklenen XNA Sürümleri |
|
Desteklenen Platformlar |
|
Windows Gerekli Köşe Gölgelendiricisi Sürümü | 2.0 |
Windows Gerekli Pixel Shader Sürümü | 2.0 |
Çalışma ortamı
peron |
|
madde
Çokgen nedir?
Çokgen, birden çok köşe tanımı tarafından oluşturulan bir yüzdür. Genel olarak, bir çokgen, üç köşeden oluşan üçgen bir yüzdür. Ve trigon, çokgenin en küçük birimidir. Bazı modelleme yazılımları çokgenleri dörtgen veya çokgen olarak görüntüleyebilir, ancak bunlar sonunda üçgen çokgenlere ayrıştırılacaktır.
Oyunlarda görüntülenen model, bu üçgen çokgenlerin katsayılarının birleştirilmesiyle oluşturulur.
Çokgenler köşelerden oluşur. Köşeler, konum ve renk gibi verilere sahip olabilir. Bu örnek aynı zamanda "konum" ve "renk" verilerinden de yapılmıştır.
Bu örnekteki yüzün rengi, her köşe için ayarlanan renk ve mesafe ile düzgün bir şekilde enterpolasyonlanmıştır, ancak bunu kendi gölgelendirici programınızla serbestçe değiştirebilirsiniz (gölgelendirici programları hakkında başka bir zaman daha fazlası).
Köşe Veri Tanımları
Bir çokgeni görüntülemek için "köşe verileri" gereklidir ve programcının bu köşeye hangi öğeleri dahil edeceğine karar vermesi gerekir. Bir çokgen çizerken, çizim motoru olan cihaza, çokgeni hangi köşe verileriyle çizeceğini söylemeniz gerekir. Bunu yapmak için bir "VertexDeclaration" sınıfı oluşturun ve "Vertex Data Definition" ı ayarlayın.
Ancak, XNA Game Studio 4.0'dan başlayarak bu kurulum basitleştirildi ve bu ipucu için bir VertexDeclaration sınıfı hazırlamanıza gerek yok. (Bunun nedeni, tanım bilgilerinin çerçeve tarafından sağlanan köşe verilerine zaten gömülü olmasıdır.)
Köşe verileri
Çokgenleri çizmek için köşe verilerinin gerekli olduğunu yazdım, ancak önce ne tür verilere sahip olmak istediğimize karar vermemiz gerekiyor. Bu durumda, "konum" ve "renk" verilerini kullanacağız. Hangi verilere sahip olmak istediğinize karar verdikten sonra, bu verileri tutacak bir yapı oluşturmanız gerekir. Köşe verisinin ne olduğuna karar verme özgürlüğüne sahipsiniz, ancak yaygın olarak kullanılan köşe verileri XNA Çerçevesinde zaten tanımlanmıştır, bu nedenle örnek bunu kullanır.
"position" ve "color" içeren köşe verileri, "VertexPositionColor" yapısı olarak tanımlanır. Bir çokgen oluşturmak için birden fazla köşeye ihtiyaç duyulduğundan, onu bir dizi olarak bildiririz.
<summary>
頂点データリスト
</summary>
private VertexPositionColor[] vertices = null;
etki
XNA'da, bir çokgen çizdiğinizde, onu nasıl çizeceğinize karar vermek için ayrı bir gölgelendirici programı yazmanız gerekir. Bunu yapmak için ayrı bir efekt dosyası oluşturun, bir program yazın, bunu bir efekt sınıfı olarak yükleyin ve gölgelendirici programını çalıştırın.
Ancak, bunun gibi basit üçgen çokgenler veya karmaşık çizim efektleri çizmeniz gerekmiyorsa, bu çok zahmetli bir iş olabilir.
Bu nedenle, XNA, temel çizim için bir gölgelendirici programı yazmak zorunda kalmamanız için gerekli öğeleri özellik olarak ayarlamanıza olanak tanıyan genişletilmiş efektler tanımlar. Bu "BasicEffect" sınıfıdır. Bu yazının amacı çokgen çizmek olduğu için çizmek için fazla çaba gerektirmeyen "BasicEffect" kullanacağız.
<summary>
基本エフェクト
</summary>
private BasicEffect basicEffect = null;
Efektler ve Temel Efektler hakkında başka bir zaman daha fazla konuşacağım.
Bu arada, Windows Phone 7 kendi efektlerinizi kullanmanıza izin vermez, yalnızca BasicEffect gibi çerçevelerde yerleşik olanları kullanmanıza izin verir.
Köşe veri tanımı oluşturma
XNA Framework 3.1'e kadar, bunları açıkça programlı olarak oluşturmanız gerekiyordu, ancak 4.0'dan başlayarak, çerçevenin yerleşik köşe bilgileri zaten köşe bilgilerine "IVertexType.VertexDeclaration" olarak dahil edilmiştir, bu yüzden onu kullanacağız.
Efekt Oluşturma
Bir BasicEffect sınıfı oluşturun. Köşe renklerini korumak için BasicEffect.VertexColorEnabled özelliğini true olarak ayarlayın.
// エフェクトを作成
this.basicEffect = new BasicEffect(this.GraphicsDevice);
// エフェクトで頂点カラーを有効にする
this.basicEffect.VertexColorEnabled = true;
BasicEffect
Oluşturucu
Shader Model 2.0'ı kullanarak köşe rengi, dokusu ve ışıklandırması gerçekleştiren "BasicEffect" efekt sınıfının bir örneğini oluşturun.
aygıt | Ekran KartıAygıt | Efekti oluşturmak için GraphicsDevice'ı belirtir |
Matris ve Projeksiyon Matrisini Görüntüle
BasicEffect'i bir görünüm matrisi ve bir projeksiyon matrisi olarak ayarlayın. Her birinin kavramsal bir açıklaması için aşağıdaki bağlantılara bakın.
// ビューマトリックスをあらかじめ設定 ((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
);
Bir görünüm matrisi oluşturmak için "Matrix.CreateLookAt" yöntemini kullanın.
İlk bağımsız değişken kameranın konumunu, ikinci bağımsız değişken kameranın ilgi noktasını ve üçüncü bağımsız değişken kameranın yukarı yönünü belirtir.
Bu durumda, (0, 0, 15) konumundan orijine bakacak şekilde ayarlanmıştır.
Matrix.CreateLookAt
yöntem
Bir görünüm matrisi oluşturun.
kamera Konumu | Vektör3 | Kamera Konumu |
kamera hedefi | Vektör3 | Kamera İlgi Çekici Nokta |
cameraUpVector | Vektör3 | Kameranın yukarı yönü |
Bir projeksiyon matrisi oluşturmak için "Matrix.CreatePerspectiveFieldOfView" yöntemini kullanın.
İlk argüman, radyan cinsinden görüş açısıdır. Örnekte, derece birimi "MathHelper.ToRadians" yöntemi kullanılarak radyana dönüştürülür. Radyan ve Derece hakkında daha fazla bilgi için bkz: Radyan ve Derece.
İkinci bağımsız değişken en boy oranını (en boy oranı) belirtir. Genellikle, Görünüm Genişliği ÷ Yüksekliği için bir değer belirtirsiniz. Örnekte, cihazın görüntü alanı için ayarlanan genişlik ve yükseklikten hesaplanır.
Üçüncü bağımsız değişken ileri kırpma konumunu, dördüncü bağımsız değişken ise geriye doğru kırpma konumunu belirtir.
Matrix.CreatePerspectiveFieldOfView
yöntem
Görünüm alanının ayarlarına bağlı olarak bir perspektif projeksiyon matrisi oluşturur.
fieldOfView | yüzmek | Görüş açısı. Radyan birimlerinde belirtilmiştir. |
aspectRatio (En Boy Oranı) | yüzmek | En boy oranı (en boy oranı). Normalde, "Görünüm Genişliği ÷ Yüksekliği" için bir değer belirtirsiniz |
nearPlaneDistance (Uçak Mesafesi) | yüzmek | İleri klip konumu. Bu konumun önündeki nesneler çizilmez. |
farPlaneDistance (FarPlaneDistance | yüzmek | Arka klips konumu. Bu konumun ötesindeki nesneler çizilmez. |
Köşe Verileri Oluşturma
Üç köşe verisi oluşturun. İlk olarak, bir dizi oluşturacağız ve her bir köşeyi oluşturacağız.
// 頂点データを作成する
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);
Köşe verileri oluşturmak için, "VertexPositionColor" yapıcısında "köşe konumunu" ve "köşe rengini" belirtin.
VertexPositionColor
Oluşturucu
Konum ve renk köşe verileriyle "VertexPositionColor" yapısının bir örneğini oluşturun.
konum | Vektör3 | Köşe Konumu |
Renk | Renk | Köşe rengi |
Köşelerin konumunu kameradan görülebilen aralığa ayarlayın. Ayrıca, köşe düzenlemesini "saat yönünde (saat yönünde)" olarak ayarlayın. "Saat yönünün tersine" olarak ayarlarsanız, çokgen görünmeyecektir. Bunun açıklaması için, bkz: Çizilecek Çokgenin Yüzlerini Belirleme.
Çokgen çizme
// パスの数だけ繰り替えし描画 (といっても直接作成した 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);
"Teknikler" ve "yollar" adı verilen ve gerçek çizim programını çalıştırdığınız iki tür efekt vardır. Tek bir efektte birden fazla yol olabileceğinden, bunları foreach içinde tekrar tekrar çağırmaya çalışıyorum. Bununla birlikte, BasicEffect'te bir teknik ve bir yol vardır, bu nedenle yolun dizinini doğrudan belirleyebilirsiniz, ancak yukarıdaki açıklama daha temiz olacaktır çünkü onu diğer efektlerle değiştirebilirsiniz.
Gerçek çizime başlamadan önce, geçişi başlatmak için "EffectPass.Apply" yöntemini çağırın. Bu yöntemi çağırarak, bu sefer kullanılacak efektin parametreleri grafik aygıtına uygulanır.
Yolu başlattıktan sonra, çokgeni "GraphicsDevice.DrawUserPrimitives" yöntemiyle çizin.
İlk bağımsız değişken, çizilecek temel öğenin türünü belirtir. Bu durumda, üçgen bir çokgen çizeceğiz, bu nedenle "PrimitiveType.TriangleList" belirtin.
İkinci bağımsız değişken, oluşturulan köşe verilerini belirtir.
Üçüncü bağımsız değişken, çizilecek tepe noktasını belirtir. Normalde, bu 0'dır.
Dördüncü bağımsız değişken, çizilecek temel öğelerin sayısını belirtir. Bu durumda, yalnızca bir üçgen çokgen vardır, bu nedenle 1 belirtin. Bunun köşe sayısı olmadığını unutmayın.
GraphicsDevice.DrawUserPrimitives
yöntem
Kullanıcı tarafından sağlanan köşe verilerine dayalı olarak temel öğeler çizer.
T | Limit yok | Vertex Veri Yapıları |
ilkel tip | İlkel Tip | Çizilecek ilkel türü |
köşe Verileri | T[] | Çizilecek bir köşe verileri dizisi |
köşe Ofseti | Int | Çizim için kullanılacak köşe verilerinin sayısını belirtin |
ilkel Sayı | Int | Çizilecek temel öğelerin sayısı. |
Çizim programı için bu kadar. Gerçekten çalıştırdıysanız ve bir üçgen görüntüleniyorsa, işiniz bitti.
Tüm Kodlar
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);
}
}
}