چراغ های اثر پایه
خلاصه
پارامترهای مربوط به بخش نور BasicEffect را دستکاری کنید تا ببینید مدل چگونه نمایش داده می شود.
محیط عملیاتی
پیش نیازها
نسخه های XNA پشتیبانی شده |
|
پلتفرم های پشتیبانی شده |
|
ویندوز مورد نیاز Vertex Shader نسخه | 2.0 |
ویندوز مورد نیاز Pixel Shader نسخه | 2.0 |
محیط عملیاتی
بستر |
|
نحوه کار با نمونه
صفحهکلید کار می کندXbox | 360 کنترلر | |||
---|---|---|---|---|
پارامترهایی را که می خواهید تغییر دهید انتخاب کنید | ↑、↓ | 2019 01:00:00:00:00:00:00:00:00:00:00: | دکمه چپ | - |
تغییر پارامترها | ←、→ | چوب چپ ←، → | ←→ کشیدن | - |
ماده
نور
چراغ ها برای نشان دادن سایه های یک ماده استفاده می شوند. در XNA، چراغ ها به عنوان یکی از تنظیمات محیط تنظیم نمی شوند، اما به اثرات فردی تنظیم می شوند.
سه منبع نور موازی موجود در BasicEffect وجود دارد و هر نور دارای پارامترهای زیر است:
فعال | تعیین می کند که ایا نور در دسترس است. |
پخشcolor | رنگ نور. رنگ نهایی با ترکیب ان با رنگ ماده خروجی است. |
اسپکلارcolor | رنگ نور منعکس شده این بر رنگ بازتابنده ماده تاثیر می گذارد. |
جهت | جهت نور. |
همچنین خواصی وجود دارد که برای چراغ های فردی مشترک است.
نور محیطColor | روشنایی را به ماده مستقل از منبع نور تنظیم می کند. |
ترجیح می دهمپرپیکسل روشنایی | شما می توانید مشخص کنید که ایا روشنایی در پیکسل محاسبه می شود. |
تصویر تغییر نور
تصویر زیر مقادیر مختلف چراغ ها را نشان می دهد. در نمونه، هر سه چراغ فعال هستند، اما در تصویر زیر، تنها یک نور برای نمایش ان استفاده می شود.
حالت اولیه
این حالت بلافاصله پس از بارگذاری داده های مدل نمونه است.
پخش (قرمز) | 1 |
منتشر (سبز) | 0.96 |
پخش (ابی) | 0.80 |
اسپکولار (قرمز) | 1 |
اسپکولار (سبز) | 0.96 |
اسپکولار (ابی) | 0.80 |
جهت X | -0.52 |
جهت Y | -0.57 |
جهت Z | -0.62 |
AmbientLightColor (قرمز) | 0.05 |
AmbientLightColor (سبز) | 0.09 |
AmbientLightColor (ابی) | 0.18 |
ترجیح می دهمپرپیکسل روشنایی | نادرست |
تغییر رنگ پراکنده
تغییر رنگ انتشار نور. از انجا که قرمز و ابی روی 0 و سبز روی 1 تنظیم شده است، تنها بخش سبز مدل برجسته شده است. (قرمز و ابی نیز کمی قابل مشاهده هستند، اما این به دلیل نور محیط است.)
پخش (قرمز) | 0 |
منتشر (سبز) | 1 |
پخش (ابی) | 0 |
اسپکولار (قرمز) | 1 |
اسپکولار (سبز) | 0.96 |
اسپکولار (ابی) | 0.80 |
جهت X | -0.52 |
جهت Y | -0.57 |
جهت Z | -0.62 |
AmbientLightColor (قرمز) | 0.05 |
AmbientLightColor (سبز) | 0.09 |
AmbientLightColor (ابی) | 0.18 |
ترجیح می دهمپرپیکسل روشنایی | نادرست |
تغییر رنگ اسپکولار
تغییر رنگ نور منعکس شده از انجا که فقط سبز تنظیم شده است، رنگ بخش بازتابنده تنها عنصر سبز است.
پخش (قرمز) | 1 |
منتشر (سبز) | 0.96 |
پخش (ابی) | 0.80 |
اسپکولار (قرمز) | 0 |
اسپکولار (سبز) | 1 |
اسپکولار (ابی) | 0 |
جهت X | -0.52 |
جهت Y | -0.57 |
جهت Z | -0.62 |
AmbientLightColor (قرمز) | 0.05 |
AmbientLightColor (سبز) | 0.09 |
AmbientLightColor (ابی) | 0.18 |
ترجیح می دهمپرپیکسل روشنایی | نادرست |
تغییر جهت
شما می توانید جهت نور را با تغییر جهت تغییر دهید. به طور معمول، فقط جهت گیری استفاده می شود، بنابراین بردار عادی می شود.
پخش (قرمز) | 1 |
منتشر (سبز) | 0.96 |
پخش (ابی) | 0.80 |
اسپکولار (قرمز) | 1 |
اسپکولار (سبز) | 0.96 |
اسپکولار (ابی) | 0.80 |
جهت X | 0.67 |
جهت Y | 0.54 |
جهت Z | -0.34 |
AmbientLightColor (قرمز) | 0.05 |
AmbientLightColor (سبز) | 0.09 |
AmbientLightColor (ابی) | 0.18 |
ترجیح می دهمپرپیکسل روشنایی | نادرست |
تغییر رنگ AmbientLight
چراغ های محیط قرمز و ابی به حداکثر می رسد و سبز به 0 تنظیم می شود. اگر به مناطقی که نور نمی درخشد نگاه کنید، می توانید به وضوح تفاوت بین سایه های سبز، قرمز و ابی را ببینید.
پخش (قرمز) | 1 |
منتشر (سبز) | 0.96 |
پخش (ابی) | 0.80 |
اسپکولار (قرمز) | 1 |
اسپکولار (سبز) | 0.96 |
اسپکولار (ابی) | 0.80 |
جهت X | -0.52 |
جهت Y | -0.57 |
جهت Z | -0.62 |
AmbientLightColor (قرمز) | 1 |
AmbientLightColor (سبز) | 0 |
AmbientLightColor (ابی) | 1 |
ترجیح می دهمپرپیکسل روشنایی | نادرست |
اصلاح روشنایی پیکسل را ترجیح می دهم
PreferPerPixelLighting to True را تنظیم کنید تا محاسبات روشنایی پیکسل به پیکسل را امکان دهد. دیدن ان در نمودار دشوار است، اما در مورد روشنایی در سطح راس، مرزهای چند ضلعی ها به نوعی قابل مشاهده است، اما در مورد نورپردازی پیکسل به پیکسل، سایه های بسیار صاف می تواند بیان شود.
به هر حال، شما نمی توانید از ویژگی PreferPerPixelLighting استفاده کنید اگر از shader pixel 2.0 پشتیبانی نکنید. همچنین، اگر از چندین چراغ استفاده کنید، ممکن است عجیب به نظر برسد.
پخش (قرمز) | 1 |
منتشر (سبز) | 0.96 |
پخش (ابی) | 0.80 |
اسپکولار (قرمز) | 1 |
اسپکولار (سبز) | 0.96 |
اسپکولار (ابی) | 0.80 |
جهت X | -0.52 |
جهت Y | -0.57 |
جهت Z | -0.62 |
AmbientLightColor (قرمز) | 0.05 |
AmbientLightColor (سبز) | 0.09 |
AmbientLightColor (ابی) | 0.18 |
ترجیح می دهمپرپیکسل روشنایی | واقعی |
روشنایی در هر راس روشناییپر پیکسل | |
---|---|
پارامتر تعاریف کلاس برای چراغ
از انجا که 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 را به یک اثر تنظیم می کند. ما این ارزش را به دست می اوریم تا ان را یک بار در زمینه نگه داریم. (در نمونه، ان را در قالب به دست اوردن چندین بار است، اما ان را ساده است چرا که ان را طولانی خواهد بود اگر شما نوشتن کد برای به دست اوردن ان به طور جداگانه.)
// ライトとビュー、プロジェクションはあらかじめ設定しておく
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 تنظیم شده است. برای کد عملیات تغییر پارامتر نور، لطفا به کد کامل به طور جداگانه مراجعه کنید.
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
اموال
اولین پارامتر منبع نور موازی را دریافت می کند. | BasicDirectionalLight (چراغ راهنمایی پایه) | گرفتن |
BasicEffect.DirectionalLight1
اموال
دومین پارامتر منبع نور موازی را بدست اورید. | BasicDirectionalLight (چراغ راهنمایی پایه) | گرفتن |
BasicEffect.DirectionalLight2
اموال
پارامتر منبع نور موازی سوم را بدست اورید. | BasicDirectionalLight (چراغ راهنمایی پایه) | گرفتن |
BasicEffect.AmbientLightColor
اموال
رنگ نور محیط را می گیرد و تنظیم می کند. X قرمز است، Y سبز است، Z ابی است و هر مقدار در محدوده 0.0 ~ 1.0 است. | وکتور ۳ | دریافت، تنظیم |
BasicEffect.PreferPerPixelLighting
اموال
اگر درست باشد، محاسبات روشنایی را می توان بر اساس هر پیکسل انجام داد. با این حال، برای اینکه این ویژگی درست باشد، باید از shader pixel 2.0 یا بالاتر پشتیبانی کند. اگر نادرست تنظیم شود، محاسبه روشنایی بر اساس هر راس انجام می شود. | بول | دریافت، تنظیم |
BasicDirectionalLight.Enabled
اموال
نور را تنظیم و غیرفعال می کند. | بول | دریافت، تنظیم |
BasicDirectionalLight.DiffuseColor
اموال
می شود و مجموعه ای از رنگ پراکنده از نور. X قرمز است، Y سبز است، Z ابی است و هر مقدار در محدوده 0.0 ~ 1.0 است. | وکتور ۳ | دریافت، تنظیم |
BasicDirectionalLight.SpecularColor
اموال
نور را می گیرد و رنگ منعکس شده را تنظیم می کند. X قرمز است، Y سبز است، Z ابی است و هر مقدار در محدوده 0.0 ~ 1.0 است. | وکتور ۳ | دریافت، تنظیم |
BasicDirectionalLight.Direction
اموال
می گیرد و جهت نور را تنظیم می کند. | وکتور ۳ | دریافت، تنظیم |
همه کدها
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);
}
}
}