베이직 이펙트 라이트
요약
BasicEffect의 조명 부분과 관련된 파라미터를 조작하여 모델이 표시되는 방식을 확인합니다.
운영 환경
필수 구성 요소
지원되는 XNA 버전 |
|
지원되는 플랫폼 |
|
Windows 필수 버텍스 셰이더 버전 | 2.0 |
Windows 필수 픽셀 셰이더 버전 | 2.0 |
운영 환경
플랫폼 |
|
샘플로 작업하는 방법
작동 키보드Xbox | 360 컨트롤러마우스 | 터치 | ||
---|---|---|---|---|
변경할 매개 변수를 선택합니다 | ↑、↓ | 왼쪽 스틱 ↑, ↓ | 왼쪽 버튼 | - |
파라미터 변경 | ←、→ | 왼쪽 스틱 ←, → | ←→ 드래그 | - |
물질
광
조명은 물질의 그림자를 나타내는 데 사용됩니다. XNA에서 조명은 환경 설정 중 하나로 설정되지 않고 개별 효과로 설정됩니다.
BasicEffect에서 사용할 수 있는 세 개의 평행 광원이 있으며 각 광원에는 다음과 같은 매개변수가 있습니다.
사용 | 라이트를 사용할 수 있는지 여부를 설정합니다. |
디퓨즈 컬러(DiffuseColor) | 조명의 색상입니다. 최종 색상은 물질의 색상과 결합하여 출력됩니다. |
스페큘러 컬러(SpecularColor) | 반사된 빛의 색상입니다. 그것은 물질의 반사 색상에 영향을 미칩니다. |
방향 | 라이트의 방향입니다. |
개별 라이트에 공통적인 속성도 있습니다.
AmbientLightColor (앰비언트 라이트 컬러) | 광원과 독립적으로 물질의 밝기를 설정합니다. |
픽셀 라이팅 선호(PreferPerPixelLighting) | 조명을 픽셀 단위로 계산할지 여부를 지정할 수 있습니다. |
빛의 변화 이미지
아래 이미지는 조명의 다양한 값을 보여줍니다. 샘플에서는 세 개의 조명을 모두 사용할 수 있지만 아래 이미지에서는 하나의 조명만 사용하여 표시합니다.
초기 상태
샘플 모델 데이터를 로드한 직후의 상태입니다.
확산(빨간색) | 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 |
픽셀 라이팅 선호(PreferPerPixelLighting) | 거짓 |
DiffuseColor 수정
라이트의 DiffuseColor 를 변경합니다. 빨간색과 파란색은 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 |
픽셀 라이팅 선호(PreferPerPixelLighting) | 거짓 |
SpecularColor 변경
반사된 빛의 색상 변경. 초록색만 설정되어 있기 때문에 반사부의 색은 초록색 요소뿐입니다.
확산(빨간색) | 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 |
픽셀 라이팅 선호(PreferPerPixelLighting) | 거짓 |
방향 변경
방향을 변경하여 조명의 방향을 변경할 수 있습니다. 일반적으로 방향만 사용되므로 벡터가 정규화됩니다.
확산(빨간색) | 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 |
픽셀 라이팅 선호(PreferPerPixelLighting) | 거짓 |
AmbientLightColor 변경
빨간색과 파란색 주변 조명이 최대화되고 녹색이 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) | 거짓 |
PreferPerPixelLighting 수정
픽셀 단위 조명 계산을 허용하려면 PreferPerPixelLighting을 True로 설정합니다. 그림에서는 잘 보이지 않지만, 꼭짓점 조명의 경우 다각형의 경계가 어떻게든 보이지만, 픽셀 단위 조명의 경우 매우 부드러운 그림자를 표현할 수 있습니다.
그런데 픽셀 셰이더 2.0을 지원하지 않는 경우 PreferPerPixelLighting 속성을 사용할 수 없습니다. 또한 여러 개의 조명을 사용하면 이상하게 보일 수 있습니다.
확산(빨간색) | 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 |
픽셀 라이팅 선호(PreferPerPixelLighting) | 참 |
Per-vertex lighting픽셀당 | 조명 |
---|---|
조명에 대한 파라미터 클래스 정의(Parameter Class Definitions for Lights)
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;
}
밭
라이트를 설정하는 데 필요한 매개변수를 정의합니다. 조명에 대해 3개의 조명을 설정할 수 있으므로 배열의 요소 수도 3개입니다. 다른 필드는 메뉴 조작, 문자 표시 등에 사용되므로 전체 코드를 참조하십시오.
<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의 light 매개 변수로 설정하기만 하면 됩니다. 라이트 파라미터 변경 작업의 코드는 전체 코드를 별도로 참조하십시오.
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 범위입니다. | 벡터3 | get, set |
BasicEffect.PreferPerPixelLighting
재산
true로 설정하면 픽셀 단위로 조명 계산을 수행할 수 있습니다. 그러나 이 속성이 true가 되려면 픽셀 셰이더 2.0 이상을 지원해야 합니다. false로 설정하면 조명 계산이 꼭짓점별로 수행됩니다. | 부울 | get, set |
BasicDirectionalLight.Enabled
재산
라이트를 설정하고 비활성화합니다. | 부울 | get, set |
BasicDirectionalLight.DiffuseColor
재산
조명의 확산 색을 가져오고 설정합니다. X는 빨간색, Y는 녹색, Z는 파란색이며 각 값은 0.0~1.0 범위입니다. | 벡터3 | get, set |
BasicDirectionalLight.SpecularColor
재산
조명의 반사색을 가져오고 설정합니다. X는 빨간색, Y는 녹색, Z는 파란색이며 각 값은 0.0~1.0 범위입니다. | 벡터3 | get, set |
BasicDirectionalLight.Direction
재산
조명의 방향을 가져오고 설정합니다. | 벡터3 | get, set |
모든 코드
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);
}
}
}