ไฟ BasicEffect
สรุป
จัดการพารามิเตอร์ที่เกี่ยวข้องกับส่วนแสงของ BasicEffect เพื่อดูว่าโมเดลแสดงอย่างไร
สภาพแวดล้อมในการทํางาน
เบื้องต้น
เวอร์ชัน XNA ที่รองรับ |
|
แพลตฟอร์มที่รองรับ |
|
Windows เวอร์ชัน Vertex Shader ที่จําเป็น | 2.0 |
Windows เวอร์ชัน Pixel Shader ที่จําเป็น | 2.0 |
สภาพแวดล้อมในการทํางาน
แท่น |
|
วิธีการทํางานกับตัวอย่าง
ตัวควบคุม Xbox เมาส์แป้นพิมพ์ที่ใช้งานได้ | 360 | สัมผัส | ||
---|---|---|---|---|
เลือกพารามิเตอร์ที่คุณต้องการเปลี่ยน | ↑、↓ | แท่งซ้าย↑↓ | ปุ่มซ้าย | - |
การเปลี่ยนพารามิเตอร์ | ←、→ | ←สติ๊กซ้าย → | ←→ลาก | - |
สาร
แสง
แสงถูกใช้เพื่อแสดงเงาของสาร ใน XNA ไฟไม่ได้ถูกตั้งค่าเป็นหนึ่งในการตั้งค่าสภาพแวดล้อม แต่ถูกตั้งค่าเป็นเอฟเฟกต์แต่ละรายการ
มีแหล่งกําเนิดแสงแบบขนานสามแหล่งใน BasicEffect และแสงแต่ละดวงมีพารามิเตอร์ต่อไปนี้:
เปิด | ตั้งค่าว่าจะมีแสงหรือไม่ |
กระจายสี | สีของแสง สีสุดท้ายจะถูกส่งออกโดยการรวมเข้ากับสีของสาร |
สเปกลูลาร์คัลเลอร์ | สีของแสงสะท้อน มีผลต่อสีสะท้อนแสงของสาร |
ทิศทาง | ทิศทางของแสง |
นอกจากนี้ยังมีคุณสมบัติที่พบได้ทั่วไปสําหรับไฟแต่ละดวง
แอมเบียนท์ไลท์คัลเลอร์ | ตั้งค่าความสว่างให้กับสารโดยไม่ขึ้นกับแหล่งกําเนิดแสง |
PreferPerPixel แสงสว่าง | คุณสามารถระบุได้ว่าจะคํานวณแสงเป็นพิกเซลหรือไม่ |
ภาพการเปลี่ยนแปลงของแสง
ภาพด้านล่างแสดงค่าต่างๆ ของไฟ ในตัวอย่าง ไฟทั้งสามดวงถูกเปิดใช้งาน แต่ในภาพด้านล่าง จะใช้ไฟเพียงดวงเดียวในการแสดง
สถานะเริ่มต้น
นี่คือสถานะทันทีหลังจากโหลดข้อมูลโมเดลตัวอย่าง
กระจาย (สีแดง) | 1 |
กระจาย (สีเขียว) | 0.96 |
กระจาย (สีน้ําเงิน) | 0.80 |
Specular (สีแดง) | 1 |
Specular (สีเขียว) | 0.96 |
Specular (สีน้ําเงิน) | 0.80 |
ทิศทาง X | -0.52 |
ทิศทาง Y | -0.57 |
ทิศทาง Z | -0.62 |
AmbientLightColor (สีแดง) | 0.05 |
AmbientLightColor (สีเขียว) | 0.09 |
AmbientLightColor (สีน้ําเงิน) | 0.18 |
PreferPerPixel แสงสว่าง | ปลอม |
การปรับเปลี่ยนสีแบบกระจาย
การเปลี่ยน DiffuseColor ของแสง เนื่องจากสีแดงและสีน้ําเงินถูกตั้งค่าเป็น 0 และสีเขียวถูกตั้งค่าเป็น 1 จึงเน้นเฉพาะส่วนสีเขียวของโมเดลเท่านั้น (สีแดงและสีน้ําเงินยังมองเห็นได้จาง ๆ แต่นี่เป็นเพราะแสงโดยรอบ)
กระจาย (สีแดง) | 0 |
กระจาย (สีเขียว) | 1 |
กระจาย (สีน้ําเงิน) | 0 |
Specular (สีแดง) | 1 |
Specular (สีเขียว) | 0.96 |
Specular (สีน้ําเงิน) | 0.80 |
ทิศทาง X | -0.52 |
ทิศทาง Y | -0.57 |
ทิศทาง Z | -0.62 |
AmbientLightColor (สีแดง) | 0.05 |
AmbientLightColor (สีเขียว) | 0.09 |
AmbientLightColor (สีน้ําเงิน) | 0.18 |
PreferPerPixel แสงสว่าง | ปลอม |
Specular เปลี่ยนสี
การเปลี่ยนสีของแสงสะท้อน เนื่องจากตั้งค่าเฉพาะสีเขียวสีของส่วนสะท้อนแสงจึงเป็นเพียงองค์ประกอบสีเขียวเท่านั้น
กระจาย (สีแดง) | 1 |
กระจาย (สีเขียว) | 0.96 |
กระจาย (สีน้ําเงิน) | 0.80 |
Specular (สีแดง) | 0 |
Specular (สีเขียว) | 1 |
Specular (สีน้ําเงิน) | 0 |
ทิศทาง X | -0.52 |
ทิศทาง Y | -0.57 |
ทิศทาง Z | -0.62 |
AmbientLightColor (สีแดง) | 0.05 |
AmbientLightColor (สีเขียว) | 0.09 |
AmbientLightColor (สีน้ําเงิน) | 0.18 |
PreferPerPixel แสงสว่าง | ปลอม |
เปลี่ยนทิศทาง
คุณสามารถเปลี่ยนทิศทางของแสงได้โดยเปลี่ยนทิศทาง โดยปกติจะใช้การวางแนวเท่านั้นดังนั้นเวกเตอร์จึงถูกทําให้เป็นมาตรฐาน
กระจาย (สีแดง) | 1 |
กระจาย (สีเขียว) | 0.96 |
กระจาย (สีน้ําเงิน) | 0.80 |
Specular (สีแดง) | 1 |
Specular (สีเขียว) | 0.96 |
Specular (สีน้ําเงิน) | 0.80 |
ทิศทาง X | 0.67 |
ทิศทาง Y | 0.54 |
ทิศทาง Z | -0.34 |
AmbientLightColor (สีแดง) | 0.05 |
AmbientLightColor (สีเขียว) | 0.09 |
AmbientLightColor (สีน้ําเงิน) | 0.18 |
PreferPerPixel แสงสว่าง | ปลอม |
AmbientLight เปลี่ยนสี
ไฟโดยรอบสีแดงและสีน้ําเงินจะขยายใหญ่สุด และสีเขียวถูกตั้งค่าเป็น 0 หากคุณดูบริเวณที่แสงไม่ส่องคุณจะเห็นความแตกต่างระหว่างเฉดสีเขียวแดงและน้ําเงินได้อย่างชัดเจน
กระจาย (สีแดง) | 1 |
กระจาย (สีเขียว) | 0.96 |
กระจาย (สีน้ําเงิน) | 0.80 |
Specular (สีแดง) | 1 |
Specular (สีเขียว) | 0.96 |
Specular (สีน้ําเงิน) | 0.80 |
ทิศทาง X | -0.52 |
ทิศทาง Y | -0.57 |
ทิศทาง Z | -0.62 |
AmbientLightColor (สีแดง) | 1 |
AmbientLightColor (สีเขียว) | 0 |
AmbientLightColor (สีน้ําเงิน) | 1 |
PreferPerPixel แสงสว่าง | ปลอม |
PreferPerPixel การปรับเปลี่ยนแสง
ตั้งค่า PreferPerPixelLighting เป็น True เพื่อให้สามารถคํานวณแสงแบบพิกเซลต่อพิกเซลได้ เป็นการยากที่จะมองเห็นในแผนภาพ แต่ในกรณีของแสงระดับจุดยอดขอบเขตของรูปหลายเหลี่ยมจะมองเห็นได้ แต่ในกรณีของแสงแบบพิกเซลต่อพิกเซลสามารถแสดงเงาที่ราบรื่นมากได้
อย่างไรก็ตาม คุณไม่สามารถใช้คุณสมบัติ PreferPerPixelLighting ได้หากคุณไม่รองรับ pixel shader 2.0 นอกจากนี้ หากคุณใช้ไฟหลายดวง อาจดูแปลกๆ
กระจาย (สีแดง) | 1 |
กระจาย (สีเขียว) | 0.96 |
กระจาย (สีน้ําเงิน) | 0.80 |
Specular (สีแดง) | 1 |
Specular (สีเขียว) | 0.96 |
Specular (สีน้ําเงิน) | 0.80 |
ทิศทาง X | -0.52 |
ทิศทาง Y | -0.57 |
ทิศทาง Z | -0.62 |
AmbientLightColor (สีแดง) | 0.05 |
AmbientLightColor (สีเขียว) | 0.09 |
AmbientLightColor (สีน้ําเงิน) | 0.18 |
PreferPerPixel แสงสว่าง | จริง |
แสงต่อจุดยอดแสงต่อพิกเซล | |
---|---|
คําจํากัดความของคลาสพารามิเตอร์สําหรับไฟ
เนื่องจาก BasicEffect สามารถมีไฟได้หลายดวง เราจึงได้สร้างคลาสสําหรับตั้งค่าพารามิเตอร์แสง พารามิเตอร์จะเหมือนกับพารามิเตอร์ที่สามารถตั้งค่าสําหรับไฟ BasicEffect (BasicDirectionalLight)
<summary>
ライトパラメータ
</summary>
public class LightParameter
{
<summary>
ライト有効フラグ
</summary>
public bool Enabled;
<summary>
ディフューズカラー
</summary>
public Vector3 DiffuseColor;
<summary>
スペキュラーカラー
</summary>
public Vector3 SpecularColor;
<summary>
ライトの方向
</summary>
public Vector3 Direction;
}
สนาม
กําหนดพารามิเตอร์ที่จําเป็นในการตั้งค่าแสง เนื่องจากคุณสามารถตั้งค่าไฟได้สามดวงจํานวนองค์ประกอบในอาร์เรย์จึงเป็นสามดวง ฟิลด์อื่นๆ ใช้สําหรับการทํางานของเมนู การแสดงอักขระ ฯลฯ ดังนั้นโปรดดูโค้ดแบบเต็ม
<summary>
選択しているライトのインデックス
</summary>
private int selectedLightIndex = 0;
<summary>
ライトのパラメータ
</summary>
private LightParameter[] lightParameters = new LightParameter[]
{
new LightParameter(),
new LightParameter(),
new LightParameter()
};
<summary>
アンビエントカラー
</summary>
private Vector3 ambientLightColor = Vector3.Zero;
<summary>
ピクセル単位のライティング
</summary>
private bool isPreferPerPixelLighting = false;
การได้มาซึ่งการเขียนเริ่มต้น
เมธอด BasicEffect.EnableDefaultLighting ตั้งค่าพารามิเตอร์ของแสงที่ระบุโดย XNA Framework เป็นเอฟเฟกต์ เราได้รับค่านี้เพื่อเก็บไว้ในสนามครั้งเดียว (ในตัวอย่าง มันอยู่ในรูปแบบของการได้มาหลายครั้ง แต่จะง่ายขึ้นเพราะจะยาวถ้าคุณเขียนโค้ดเพื่อรับแยกต่างหาก)
// ライトとビュー、プロジェクションはあらかじめ設定しておく
foreach (ModelMesh mesh in this.model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
// デフォルトのライト適用
effect.EnableDefaultLighting();
// ビューマトリックスをあらかじめ設定 ((0, 0, 8) から原点を見る)
effect.View = Matrix.CreateLookAt(
new Vector3(0.0f, 0.0f, 8.0f),
Vector3.Zero,
Vector3.Up
);
// プロジェクションマトリックスをあらかじめ設定
effect.Projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f),
(float)this.GraphicsDevice.Viewport.Width /
(float)this.GraphicsDevice.Viewport.Height,
1.0f,
100.0f
);
// デフォルトのパラメータを受け取る
this.lightParameters[0].Enabled = effect.DirectionalLight0.Enabled;
this.lightParameters[0].DiffuseColor = effect.DirectionalLight0.DiffuseColor;
this.lightParameters[0].SpecularColor = effect.DirectionalLight0.SpecularColor;
this.lightParameters[0].Direction = effect.DirectionalLight0.Direction;
this.lightParameters[1].Enabled = effect.DirectionalLight1.Enabled;
this.lightParameters[1].DiffuseColor = effect.DirectionalLight1.DiffuseColor;
this.lightParameters[1].SpecularColor = effect.DirectionalLight1.SpecularColor;
this.lightParameters[1].Direction = effect.DirectionalLight1.Direction;
this.lightParameters[2].Enabled = effect.DirectionalLight2.Enabled;
this.lightParameters[2].DiffuseColor = effect.DirectionalLight2.DiffuseColor;
this.lightParameters[2].SpecularColor = effect.DirectionalLight2.SpecularColor;
this.lightParameters[2].Direction = effect.DirectionalLight2.Direction;
// アンビエントカラー
this.ambientLightColor = effect.AmbientLightColor;
// ピクセル単位のライティング
this.isPreferPerPixelLighting = effect.PreferPerPixelLighting;
}
}
การตั้งค่าไฟ
ฉันกําลังตั้งค่าแสงไปที่ BasicEffect ของโมเดล ค่าถูกตั้งค่าเป็นพารามิเตอร์แสงของ BasicEffect สําหรับรหัสของการดําเนินการเปลี่ยนพารามิเตอร์แสง โปรดดูรหัสแบบเต็มแยกต่างหาก
foreach (ModelMesh mesh in this.model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
for (int i = 0; i < this.lightParameters.Length; i++)
{
// ライトを取得
BasicDirectionalLight light = null;
switch (i)
{
case 0:
light = effect.DirectionalLight0;
break;
case 1:
light = effect.DirectionalLight1;
break;
case 2:
light = effect.DirectionalLight2;
break;
}
// ライト有効フラグ
light.Enabled = this.lightParameters[i].Enabled;
// ライトのディフーズカラー
light.DiffuseColor = this.lightParameters[i].DiffuseColor;
// ライトのスペキュラーカラー
light.SpecularColor = this.lightParameters[i].SpecularColor;
// ライトの方向
light.Direction = this.lightParameters[i].Direction;
}
// アンビエントカラー
effect.AmbientLightColor = this.ambientLightColor;
// ピクセル単位のライティング
effect.PreferPerPixelLighting = this.isPreferPerPixelLighting;
}
}
BasicEffect.DirectionalLight0
ทรัพย์สิน
รับพารามิเตอร์แหล่งกําเนิดแสงแบบขนานตัวแรก | พื้นฐาน DirectionalLight | รับ |
BasicEffect.DirectionalLight1
ทรัพย์สิน
รับพารามิเตอร์แหล่งกําเนิดแสงแบบขนานที่สอง | พื้นฐาน DirectionalLight | รับ |
BasicEffect.DirectionalLight2
ทรัพย์สิน
รับพารามิเตอร์แหล่งกําเนิดแสงแบบขนานที่สาม | พื้นฐาน DirectionalLight | รับ |
BasicEffect.AmbientLightColor
ทรัพย์สิน
รับและตั้งค่าสีของแสงโดยรอบ X เป็นสีแดง Y เป็นสีเขียว Z เป็นสีน้ําเงิน และแต่ละค่าอยู่ในช่วง 0.0~1.0 | เวกเตอร์ 3 | รับ ตั้งค่า |
BasicEffect.PreferPerPixelLighting
ทรัพย์สิน
หากตั้งค่าเป็น true การคํานวณแสงสามารถทําได้ตามแต่ละพิกเซล อย่างไรก็ตาม เพื่อให้คุณสมบัตินี้เป็นจริง จะต้องรองรับ pixel shader 2.0 หรือสูงกว่า หากตั้งค่าเป็นเท็จการคํานวณแสงจะดําเนินการตามจุดยอด | บูล | รับ ตั้งค่า |
BasicDirectionalLight.Enabled
ทรัพย์สิน
ตั้งค่าและปิดไฟ | บูล | รับ ตั้งค่า |
BasicDirectionalLight.DiffuseColor
ทรัพย์สิน
รับและตั้งค่าสีกระจายของแสง X เป็นสีแดง Y เป็นสีเขียว Z เป็นสีน้ําเงิน และแต่ละค่าอยู่ในช่วง 0.0~1.0 | เวกเตอร์ 3 | รับ ตั้งค่า |
BasicDirectionalLight.SpecularColor
ทรัพย์สิน
รับและตั้งค่าสีสะท้อนแสงของแสง X เป็นสีแดง Y เป็นสีเขียว Z เป็นสีน้ําเงิน และแต่ละค่าอยู่ในช่วง 0.0~1.0 | เวกเตอร์ 3 | รับ ตั้งค่า |
BasicDirectionalLight.Direction
ทรัพย์สิน
รับและกําหนดทิศทางของแสง | เวกเตอร์ 3 | รับ ตั้งค่า |
รหัสทั้งหมด
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 BasicEffectLight
{
<summary>
ゲームメインクラス
</summary>
public class GameMain : Microsoft.Xna.Framework.Game
{
<summary>
ライトパラメータ
</summary>
public class LightParameter
{
<summary>
ライト有効フラグ
</summary>
public bool Enabled;
<summary>
ディフューズカラー
</summary>
public Vector3 DiffuseColor;
<summary>
スペキュラーカラー
</summary>
public Vector3 SpecularColor;
<summary>
ライトの方向
</summary>
public Vector3 Direction;
}
<summary>
グラフィックデバイス管理クラス
</summary>
private GraphicsDeviceManager graphics = null;
<summary>
スプライトのバッチ化クラス
</summary>
private SpriteBatch spriteBatch = null;
<summary>
スプライトでテキストを描画するためのフォント
</summary>
private SpriteFont font = null;
<summary>
直前のキーボード入力の状態
</summary>
private KeyboardState oldKeyboardState = new KeyboardState();
<summary>
直前のマウスの状態
</summary>
private MouseState oldMouseState = new MouseState();
<summary>
直前のゲームパッド入力の状態
</summary>
private GamePadState oldGamePadState = new GamePadState();
<summary>
モデル
</summary>
private Model model = null;
<summary>
選択しているメニューのインデックス
</summary>
private int selectedMenuIndex = 0;
<summary>
選択しているライトのインデックス
</summary>
private int selectedLightIndex = 0;
<summary>
ライトのパラメータ
</summary>
private LightParameter[] lightParameters = new LightParameter[]
{
new LightParameter(),
new LightParameter(),
new LightParameter()
};
<summary>
アンビエントカラー
</summary>
private Vector3 ambientLightColor = Vector3.Zero;
<summary>
ピクセル単位のライティング
</summary>
private bool isPreferPerPixelLighting = false;
<summary>
パラメータの最大数
</summary>
private static int MaxParameterCount = 15;
<summary>
メニューリスト
</summary>
private static string[] MenuNameList = new string[]
{
"LightIndex",
"Light Enable",
"DiffuseColor (Red)",
"DiffuseColor (Green)",
"DiffuseColor (Blue)",
"SpecularColor (Red)",
"SpecularColor (Green)",
"SpecularColor (Blue)",
"Direction X",
"Direction Y",
"Direction Z",
"AmbientLightColor (Red)",
"AmbientLightColor (Green)",
"AmbientLightColor (Blue)",
"PreferPerPixelLighting",
};
<summary>
パラメータテキストリスト
</summary>
private string[] parameters = new string[MaxParameterCount];
<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
// ウインドウ上でマウスのポインタを表示するようにする
this.IsMouseVisible = true;
}
<summary>
ゲームが始まる前の初期化処理を行うメソッド
グラフィック以外のデータの読み込み、コンポーネントの初期化を行う
</summary>
protected override void Initialize()
{
// TODO: ここに初期化ロジックを書いてください
// コンポーネントの初期化などを行います
base.Initialize();
}
<summary>
ゲームが始まるときに一回だけ呼ばれ
すべてのゲームコンテンツを読み込みます
</summary>
protected override void LoadContent()
{
// テクスチャーを描画するためのスプライトバッチクラスを作成します
this.spriteBatch = new SpriteBatch(this.GraphicsDevice);
// フォントをコンテンツパイプラインから読み込む
this.font = this.Content.Load<SpriteFont>("Font");
// モデルを作成
this.model = this.Content.Load<Model>("Model");
// ライトとビュー、プロジェクションはあらかじめ設定しておく
foreach (ModelMesh mesh in this.model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
// デフォルトのライト適用
effect.EnableDefaultLighting();
// ビューマトリックスをあらかじめ設定 ((0, 0, 8) から原点を見る)
effect.View = Matrix.CreateLookAt(
new Vector3(0.0f, 0.0f, 8.0f),
Vector3.Zero,
Vector3.Up
);
// プロジェクションマトリックスをあらかじめ設定
effect.Projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f),
(float)this.GraphicsDevice.Viewport.Width /
(float)this.GraphicsDevice.Viewport.Height,
1.0f,
100.0f
);
// デフォルトのパラメータを受け取る
this.lightParameters[0].Enabled = effect.DirectionalLight0.Enabled;
this.lightParameters[0].DiffuseColor = effect.DirectionalLight0.DiffuseColor;
this.lightParameters[0].SpecularColor = effect.DirectionalLight0.SpecularColor;
this.lightParameters[0].Direction = effect.DirectionalLight0.Direction;
this.lightParameters[1].Enabled = effect.DirectionalLight1.Enabled;
this.lightParameters[1].DiffuseColor = effect.DirectionalLight1.DiffuseColor;
this.lightParameters[1].SpecularColor = effect.DirectionalLight1.SpecularColor;
this.lightParameters[1].Direction = effect.DirectionalLight1.Direction;
this.lightParameters[2].Enabled = effect.DirectionalLight2.Enabled;
this.lightParameters[2].DiffuseColor = effect.DirectionalLight2.DiffuseColor;
this.lightParameters[2].SpecularColor = effect.DirectionalLight2.SpecularColor;
this.lightParameters[2].Direction = effect.DirectionalLight2.Direction;
// アンビエントカラー
this.ambientLightColor = effect.AmbientLightColor;
// ピクセル単位のライティング
this.isPreferPerPixelLighting = effect.PreferPerPixelLighting;
}
}
}
<summary>
ゲームが終了するときに一回だけ呼ばれ
すべてのゲームコンテンツをアンロードします
</summary>
protected override void UnloadContent()
{
// TODO: ContentManager で管理されていないコンテンツを
// ここでアンロードしてください
}
<summary>
描画以外のデータ更新等の処理を行うメソッド
主に入力処理、衝突判定などの物理計算、オーディオの再生など
</summary>
<param name="gameTime">このメソッドが呼ばれたときのゲーム時間</param>
protected override void Update(GameTime gameTime)
{
// 入力デバイスの状態取得
KeyboardState keyboardState = Keyboard.GetState();
MouseState mouseState = Mouse.GetState();
GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
// Xbox 360 コントローラ、Windows Phone の BACK ボタンを押したときに
// ゲームを終了させます
if (gamePadState.Buttons.Back == ButtonState.Pressed)
{
this.Exit();
}
// メニューの選択
if ((keyboardState.IsKeyDown(Keys.Up) && this.oldKeyboardState.IsKeyUp(Keys.Up)) ||
(gamePadState.ThumbSticks.Left.Y >= 0.5f &&
this.oldGamePadState.ThumbSticks.Left.Y < 0.5f))
{
// 選択メニューをひとつ上に移動
this.selectedMenuIndex =
(this.selectedMenuIndex + this.parameters.Length - 1) % this.parameters.Length;
}
if ((keyboardState.IsKeyDown(Keys.Down) && this.oldKeyboardState.IsKeyUp(Keys.Down)) ||
(gamePadState.ThumbSticks.Left.Y <= -0.5f &&
this.oldGamePadState.ThumbSticks.Left.Y > -0.5f) ||
(this.oldMouseState.LeftButton == ButtonState.Pressed &&
mouseState.LeftButton == ButtonState.Released))
{
// 選択メニューをひとつ下に移動
this.selectedMenuIndex =
(this.selectedMenuIndex + this.parameters.Length + 1) % this.parameters.Length;
}
// 各マテリアルの値を操作
float moveValue = 0.0f;
if (keyboardState.IsKeyDown(Keys.Left))
{
moveValue -= (float)gameTime.ElapsedGameTime.TotalSeconds;
}
if (keyboardState.IsKeyDown(Keys.Right))
{
moveValue += (float)gameTime.ElapsedGameTime.TotalSeconds;
}
if (mouseState.LeftButton == ButtonState.Pressed)
{
moveValue += (mouseState.X - this.oldMouseState.X) * 0.005f;
}
if (gamePadState.IsConnected)
{
moveValue += gamePadState.ThumbSticks.Left.X *
(float)gameTime.ElapsedGameTime.TotalSeconds;
}
if (moveValue != 0.0f)
{
LightParameter selectedLight = this.lightParameters[this.selectedLightIndex];
switch (this.selectedMenuIndex)
{
case 0:
// ライトのインデックス
if ((keyboardState.IsKeyDown(Keys.Left) &&
this.oldKeyboardState.IsKeyUp(Keys.Left)) ||
(mouseState.LeftButton == ButtonState.Pressed &&
(mouseState.X - this.oldMouseState.X) >= 5) ||
(gamePadState.ThumbSticks.Left.X >= 0.5f &&
this.oldGamePadState.ThumbSticks.Left.X < 0.5f))
{
// ライトのインデックスをひとつ減らす
this.selectedLightIndex =
(this.selectedLightIndex + this.lightParameters.Length - 1) %
this.lightParameters.Length;
}
if ((keyboardState.IsKeyDown(Keys.Right) &&
this.oldKeyboardState.IsKeyUp(Keys.Right)) ||
(mouseState.LeftButton == ButtonState.Pressed &&
(mouseState.X - this.oldMouseState.X) <= -5) ||
(gamePadState.ThumbSticks.Left.X <= -0.5f &&
this.oldGamePadState.ThumbSticks.Left.X > -0.5f))
{
// ライトのインデックスをひとつ増やす
this.selectedLightIndex =
(this.selectedLightIndex + this.lightParameters.Length + 1) %
this.lightParameters.Length;
}
if (mouseState.LeftButton == ButtonState.Pressed)
{
this.selectedLightIndex = (int)(
MathHelper.Clamp((float)mouseState.X / this.GraphicsDevice.Viewport.Width * 3, 0, 2));
}
break;
case 1:
// ライト有効フラグ
selectedLight.Enabled = (moveValue > 0.0f);
break;
case 2:
// ライトのディフーズカラー(赤)
Vector3 diffuseX = selectedLight.DiffuseColor;
diffuseX.X = MathHelper.Clamp(diffuseX.X + moveValue, 0.0f, 1.0f);
selectedLight.DiffuseColor = diffuseX;
break;
case 3:
// ライトのディフーズカラー(緑)
Vector3 diffuseY = selectedLight.DiffuseColor;
diffuseY.Y = MathHelper.Clamp(diffuseY.Y + moveValue, 0.0f, 1.0f);
selectedLight.DiffuseColor = diffuseY;
break;
case 4:
// ライトのディフーズカラー(青)
Vector3 diffuseZ = selectedLight.DiffuseColor;
diffuseZ.Z = MathHelper.Clamp(diffuseZ.Z + moveValue, 0.0f, 1.0f);
selectedLight.DiffuseColor = diffuseZ;
break;
case 5:
// ライトのスペキュラーカラー(赤)
Vector3 specularX = selectedLight.SpecularColor;
specularX.X = MathHelper.Clamp(specularX.X + moveValue, 0.0f, 1.0f);
selectedLight.SpecularColor = specularX;
break;
case 6:
// ライトのスペキュラーカラー(緑)
Vector3 specularY = selectedLight.SpecularColor;
specularY.Y = MathHelper.Clamp(specularY.Y + moveValue, 0.0f, 1.0f);
selectedLight.SpecularColor = specularY;
break;
case 7:
// ライトのスペキュラーカラー(青)
Vector3 specularZ = selectedLight.SpecularColor;
specularZ.Z = MathHelper.Clamp(specularZ.Z + moveValue, 0.0f, 1.0f);
selectedLight.SpecularColor = specularZ;
break;
case 8:
// ライトの方向X
Vector3 directionX = selectedLight.Direction;
directionX.X += moveValue;
selectedLight.Direction = directionX;
break;
case 9:
// ライトの方向Y
Vector3 directionY = selectedLight.Direction;
directionY.Y += moveValue;
selectedLight.Direction = directionY;
break;
case 10:
// ライトの方向Z
Vector3 directionZ = selectedLight.Direction;
directionZ.Z += moveValue;
selectedLight.Direction = directionZ;
break;
case 11:
// アンビエントカラー(赤)
this.ambientLightColor.X =
MathHelper.Clamp(this.ambientLightColor.X + moveValue, 0.0f, 1.0f);
break;
case 12:
// アンビエントカラー(緑)
this.ambientLightColor.Y =
MathHelper.Clamp(this.ambientLightColor.Y + moveValue, 0.0f, 1.0f);
break;
case 13:
// アンビエントカラー(青)
this.ambientLightColor.Z =
MathHelper.Clamp(this.ambientLightColor.Z + moveValue, 0.0f, 1.0f);
break;
case 14:
// ピクセル単位のライティング
this.isPreferPerPixelLighting = (moveValue > 0.0f);
break;
}
}
// ライトを設定
foreach (ModelMesh mesh in this.model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
for (int i = 0; i < this.lightParameters.Length; i++)
{
// ライトを取得
DirectionalLight light = null;
switch (i)
{
case 0:
light = effect.DirectionalLight0;
break;
case 1:
light = effect.DirectionalLight1;
break;
case 2:
light = effect.DirectionalLight2;
break;
}
// ライト有効フラグ
light.Enabled = this.lightParameters[i].Enabled;
// ライトのディフーズカラー
light.DiffuseColor = this.lightParameters[i].DiffuseColor;
// ライトのスペキュラーカラー
light.SpecularColor = this.lightParameters[i].SpecularColor;
// ライトの方向
light.Direction = this.lightParameters[i].Direction;
}
// アンビエントカラー
effect.AmbientLightColor = this.ambientLightColor;
// ピクセル単位のライティング
effect.PreferPerPixelLighting = this.isPreferPerPixelLighting;
}
}
// 入力情報を記憶
this.oldKeyboardState = keyboardState;
this.oldMouseState = mouseState;
this.oldGamePadState = gamePadState;
// 登録された GameComponent を更新する
base.Update(gameTime);
}
<summary>
描画処理を行うメソッド
</summary>
<param name="gameTime">このメソッドが呼ばれたときのゲーム時間</param>
protected override void Draw(GameTime gameTime)
{
// 画面を指定した色でクリアします
this.GraphicsDevice.Clear(Color.CornflowerBlue);
// 深度バッファを有効にする
this.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
// モデルを描画
foreach (ModelMesh mesh in this.model.Meshes)
{
#if WINDOWS_PHONE
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = Matrix.CreateRotationZ(-MathHelper.PiOver2);
}
#endif
mesh.Draw();
}
// スプライトの描画準備
this.spriteBatch.Begin();
// 操作
this.spriteBatch.DrawString(this.font,
"Up, Down : Select Menu",
new Vector2(20.0f, 20.0f), Color.White);
this.spriteBatch.DrawString(this.font,
"Left, right : Change Value",
new Vector2(20.0f, 45.0f), Color.White);
this.spriteBatch.DrawString(this.font,
"MouseClick & Drag :",
new Vector2(20.0f, 70.0f), Color.White);
this.spriteBatch.DrawString(this.font,
" Select Menu & Change Value",
new Vector2(20.0f, 95.0f), Color.White);
// 各メニュー //
for (int i = 0; i < MenuNameList.Length; i++)
{
this.spriteBatch.DrawString(this.font,
MenuNameList[i],
new Vector2(40.0f, 120.0f + i * 20.0f), Color.White);
}
// 各パラメータ //
LightParameter selectedLight = this.lightParameters[this.selectedLightIndex];
// ライトのインデックス
this.parameters[0] = this.selectedLightIndex.ToString();
// ライトの有効フラグ
this.parameters[1] = selectedLight.Enabled.ToString();
// ライトのディフーズカラー(赤)
this.parameters[2] = selectedLight.DiffuseColor.X.ToString();
// ライトのディフーズカラー(緑)
this.parameters[3] = selectedLight.DiffuseColor.Y.ToString();
// ライトのディフーズカラー(青)
this.parameters[4] = selectedLight.DiffuseColor.Z.ToString();
// ライトのスペキュラーカラー(赤)
this.parameters[5] = selectedLight.SpecularColor.X.ToString();
// ライトのスペキュラーカラー(緑)
this.parameters[6] = selectedLight.SpecularColor.Y.ToString();
// ライトのスペキュラーカラー(青)
this.parameters[7] = selectedLight.SpecularColor.Z.ToString();
// ライトの方向X
this.parameters[8] = selectedLight.Direction.X.ToString();
// ライトの方向Y
this.parameters[9] = selectedLight.Direction.Y.ToString();
// ライトの方向Z
this.parameters[10] = selectedLight.Direction.Z.ToString();
// アンビエントカラー(赤)
this.parameters[11] = this.ambientLightColor.X.ToString();
// アンビエントカラー(緑)
this.parameters[12] = this.ambientLightColor.Y.ToString();
// アンビエントカラー(青)
this.parameters[13] = this.ambientLightColor.Z.ToString();
// ピクセル単位のライティング
this.parameters[14] = this.isPreferPerPixelLighting.ToString();
for (int i = 0; i < this.parameters.Length; i++)
{
this.spriteBatch.DrawString(this.font,
this.parameters[i],
new Vector2(300.0f, 120.0f + i * 20.0f), Color.White);
}
// 選択インデックス
this.spriteBatch.DrawString(this.font, "*",
new Vector2(20.0f, 124.0f + this.selectedMenuIndex * 20.0f), Color.White);
// スプライトの一括描画
this.spriteBatch.End();
// 登録された DrawableGameComponent を描画する
base.Draw(gameTime);
}
}
}