NormalMappingEffect.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // NormalMappingEffect.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using Microsoft.Xna.Framework;
  11. using Microsoft.Xna.Framework.Content;
  12. using Microsoft.Xna.Framework.Graphics;
  13. using Microsoft.Xna.Framework.Input;
  14. #endregion
  15. namespace NormalMappingEffect
  16. {
  17. /// <summary>
  18. /// Sample shows how to render a model using a custom effect.
  19. /// </summary>
  20. public class NormalMappingEffectGame : Microsoft.Xna.Framework.Game
  21. {
  22. #region Fields
  23. GraphicsDeviceManager graphics;
  24. KeyboardState lastKeyboardState = new KeyboardState();
  25. GamePadState lastGamePadState = new GamePadState();
  26. KeyboardState currentKeyboardState = new KeyboardState();
  27. GamePadState currentGamePadState = new GamePadState();
  28. Model model;
  29. // the next 4 fields are inputs to the normal mapping effect, and will be set
  30. // at load time. change these to change the light properties to modify
  31. // the appearance of the model.
  32. Vector4 lightColor = new Vector4(1, 1, 1, 1);
  33. Vector4 ambientLightColor = new Vector4(.2f, .2f, .2f, 1);
  34. float shininess = .3f;
  35. float specularPower = 4.0f;
  36. // the sample arc ball camera values
  37. float cameraArc = 0;
  38. float cameraRotation = 45;
  39. float cameraDistance = 1500;
  40. // the light rotates around the origin using these 3 constants. the light
  41. // position is set in the draw function.
  42. const float LightHeight = 600;
  43. const float LightRotationRadius = 800;
  44. const float LightRotationSpeed = .5f;
  45. bool rotateLight = true;
  46. float lightRotation;
  47. #endregion
  48. #region Initialization
  49. public NormalMappingEffectGame()
  50. {
  51. Content.RootDirectory = "Content";
  52. graphics = new GraphicsDeviceManager(this);
  53. }
  54. /// <summary>
  55. /// Load your graphics content.
  56. /// </summary>
  57. protected override void LoadContent()
  58. {
  59. model = Content.Load<Model>("lizard");
  60. foreach (ModelMesh mesh in model.Meshes)
  61. {
  62. foreach (Effect effect in mesh.Effects)
  63. {
  64. effect.Parameters["LightColor"].SetValue(lightColor);
  65. effect.Parameters["AmbientLightColor"].SetValue
  66. (ambientLightColor);
  67. effect.Parameters["Shininess"].SetValue(shininess);
  68. effect.Parameters["SpecularPower"].SetValue(specularPower);
  69. }
  70. }
  71. }
  72. #endregion
  73. #region Update and Draw
  74. /// <summary>
  75. /// Allows the game to run logic.
  76. /// </summary>
  77. protected override void Update(GameTime gameTime)
  78. {
  79. HandleInput();
  80. UpdateCamera(gameTime);
  81. // Turn on the rotating light
  82. if ((currentGamePadState.Buttons.A == ButtonState.Pressed &&
  83. lastGamePadState.Buttons.A != ButtonState.Pressed) ||
  84. (currentKeyboardState.IsKeyUp(Keys.Space) &&
  85. lastKeyboardState.IsKeyDown(Keys.Space)))
  86. {
  87. rotateLight = !rotateLight;
  88. }
  89. base.Update(gameTime);
  90. }
  91. /// <summary>
  92. /// This is called when the game should draw itself.
  93. /// </summary>
  94. protected override void Draw(GameTime gameTime)
  95. {
  96. GraphicsDevice device = graphics.GraphicsDevice;
  97. device.Clear(Color.CornflowerBlue);
  98. // Compute camera matrices.
  99. Matrix unrotatedView = Matrix.CreateLookAt(
  100. new Vector3(0, 0, -cameraDistance), Vector3.Zero, Vector3.Up);
  101. Matrix view = Matrix.CreateRotationY(MathHelper.ToRadians(cameraRotation)) *
  102. Matrix.CreateRotationX(MathHelper.ToRadians(cameraArc)) *
  103. unrotatedView;
  104. Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
  105. device.Viewport.AspectRatio,
  106. 1,
  107. 10000);
  108. if (rotateLight)
  109. {
  110. lightRotation +=
  111. (float)gameTime.ElapsedGameTime.TotalSeconds * LightRotationSpeed;
  112. }
  113. Matrix lightRotationMatrix = Matrix.CreateRotationY(lightRotation);
  114. Vector3 lightPosition = new Vector3(LightRotationRadius, LightHeight, 0);
  115. lightPosition = Vector3.Transform(lightPosition, lightRotationMatrix);
  116. // Draw the model.
  117. Matrix[] transforms = new Matrix[model.Bones.Count];
  118. model.CopyAbsoluteBoneTransformsTo(transforms);
  119. foreach (ModelMesh mesh in model.Meshes)
  120. {
  121. foreach (Effect effect in mesh.Effects)
  122. {
  123. Matrix world = transforms[mesh.ParentBone.Index];
  124. effect.Parameters["World"].SetValue(world);
  125. effect.Parameters["View"].SetValue(view);
  126. effect.Parameters["Projection"].SetValue(projection);
  127. effect.Parameters["LightPosition"].SetValue(lightPosition);
  128. }
  129. mesh.Draw();
  130. }
  131. base.Draw(gameTime);
  132. }
  133. #endregion
  134. #region Handle Input
  135. /// <summary>
  136. /// Handles input for quitting the game.
  137. /// </summary>
  138. private void HandleInput()
  139. {
  140. lastKeyboardState = currentKeyboardState;
  141. lastGamePadState = currentGamePadState;
  142. currentKeyboardState = Keyboard.GetState();
  143. currentGamePadState = GamePad.GetState(PlayerIndex.One);
  144. // Check for exit.
  145. if (currentKeyboardState.IsKeyDown(Keys.Escape) ||
  146. currentGamePadState.Buttons.Back == ButtonState.Pressed)
  147. {
  148. Exit();
  149. }
  150. }
  151. /// <summary>
  152. /// Handles camera input.
  153. /// </summary>
  154. private void UpdateCamera(GameTime gameTime)
  155. {
  156. float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
  157. // Check for input to rotate the camera up and down around the model.
  158. if (currentKeyboardState.IsKeyDown(Keys.Up) ||
  159. currentKeyboardState.IsKeyDown(Keys.W))
  160. {
  161. cameraArc += time * 0.1f;
  162. }
  163. if (currentKeyboardState.IsKeyDown(Keys.Down) ||
  164. currentKeyboardState.IsKeyDown(Keys.S))
  165. {
  166. cameraArc -= time * 0.1f;
  167. }
  168. cameraArc += currentGamePadState.ThumbSticks.Right.Y * time * 0.25f;
  169. // Limit the arc movement.
  170. if (cameraArc > 90.0f)
  171. cameraArc = 90.0f;
  172. else if (cameraArc < -90.0f)
  173. cameraArc = -90.0f;
  174. // Check for input to rotate the camera around the model.
  175. if (currentKeyboardState.IsKeyDown(Keys.Right) ||
  176. currentKeyboardState.IsKeyDown(Keys.D))
  177. {
  178. cameraRotation += time * 0.1f;
  179. }
  180. if (currentKeyboardState.IsKeyDown(Keys.Left) ||
  181. currentKeyboardState.IsKeyDown(Keys.A))
  182. {
  183. cameraRotation -= time * 0.1f;
  184. }
  185. cameraRotation += currentGamePadState.ThumbSticks.Right.X * time * 0.25f;
  186. // Check for input to zoom camera in and out.
  187. if (currentKeyboardState.IsKeyDown(Keys.Z))
  188. cameraDistance += time * 0.5f;
  189. if (currentKeyboardState.IsKeyDown(Keys.X))
  190. cameraDistance -= time * 0.5f;
  191. cameraDistance += currentGamePadState.Triggers.Left * time;
  192. cameraDistance -= currentGamePadState.Triggers.Right * time;
  193. // Limit the camera distance.
  194. if (cameraDistance > 5000.0f)
  195. cameraDistance = 5000.0f;
  196. else if (cameraDistance < 350.0f)
  197. cameraDistance = 350.0f;
  198. if (currentGamePadState.Buttons.RightStick == ButtonState.Pressed ||
  199. currentKeyboardState.IsKeyDown(Keys.R))
  200. {
  201. cameraArc = 0;
  202. cameraRotation = 45;
  203. cameraDistance = 1500;
  204. }
  205. }
  206. #endregion
  207. }
  208. #region Entry Point
  209. /// <summary>
  210. /// The main entry point for the application.
  211. /// </summary>
  212. static class Program
  213. {
  214. static void Main()
  215. {
  216. using (NormalMappingEffectGame game = new NormalMappingEffectGame())
  217. {
  218. game.Run();
  219. }
  220. }
  221. }
  222. #endregion
  223. }