BasicEffectShape.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // BasicEffectShape.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 System;
  11. using System.Collections.Generic;
  12. using System.Text;
  13. using Microsoft.Xna.Framework.Graphics;
  14. using Microsoft.Xna.Framework;
  15. using System.Diagnostics;
  16. #endregion
  17. namespace Spacewar
  18. {
  19. /// <summary>
  20. /// The shapes that this class can draw
  21. /// </summary>
  22. public enum BasicEffectShapes
  23. {
  24. /// <summary>
  25. /// Ship models used ingame and in selection screen
  26. /// </summary>
  27. Ship,
  28. /// <summary>
  29. /// Asteroid models
  30. /// </summary>
  31. Asteroid,
  32. /// <summary>
  33. /// Projectile models
  34. /// </summary>
  35. Projectile,
  36. /// <summary>
  37. /// Weapon models for the selection screen
  38. /// </summary>
  39. Weapon,
  40. }
  41. /// <summary>
  42. /// BasicEffect shapes represent the 3d models used by the evolved variation of the game. These shapes come through the Content Pipeline.
  43. /// They are all lit using the BasicEffect Shader and have similar input and construction methods
  44. /// </summary>
  45. class BasicEffectShape : Shape
  46. {
  47. //Materials
  48. private static Color white = Color.White;
  49. private static Color body = white; //body has texture so don't need material
  50. private static Color pipes = white; //pipes has texture so don't need material
  51. private static Color cockpit1 = new Color((byte)(.529f * 255), 255, 255, 0);
  52. private static Color cockpit2 = new Color(255, 255, (byte)(.373f * 255), 0);
  53. private static Color engines = new Color((byte)(.925f * 255), (byte)(.529f * 255), 255, 0);
  54. private Texture2D texture;
  55. private int skinNumber;
  56. private int shapeNumber;
  57. private BasicEffectShapes shape = BasicEffectShapes.Projectile;
  58. private PlayerIndex player;
  59. private Model model; //New content Pipeline Mesh
  60. private bool deviceCreated;
  61. string[] modelNames = null;
  62. string[] textureNames = null;
  63. private int scene; //0 is in game 1 is selection screens
  64. private Color[] material;
  65. private static Vector3 SunPosition = new Vector3(-0.5f, -0.5f, 100.0f);
  66. #region filenames
  67. private static string[,] shipMesh = new string[,]
  68. {
  69. {
  70. @"models\pencil_player1",
  71. @"models\saucer_player1",
  72. @"models\wedge_player1",
  73. },
  74. {
  75. @"models\pencil_player2",
  76. @"models\saucer_player2",
  77. @"models\wedge_player2",
  78. }
  79. };
  80. private static string[,] shipDiffuse = new string[,]
  81. {
  82. {
  83. @"textures\pencil_p1_diff_v{0}",
  84. @"textures\saucer_p1_diff_v{0}",
  85. @"textures\wedge_p1_diff_v{0}",
  86. },
  87. {
  88. @"textures\pencil_p2_diff_v{0}",
  89. @"textures\saucer_p2_diff_v{0}",
  90. @"textures\wedge_p2_diff_v{0}",
  91. }
  92. };
  93. private static string[,] shipNormal = new String[,]
  94. {
  95. {
  96. @"textures\pencil_p1_norm_1",
  97. @"textures\saucer_p1_norm_1",
  98. @"textures\wedge_p1_norm_1",
  99. },
  100. {
  101. @"textures\pencil_p2_norm_1",
  102. @"textures\saucer_p2_norm_1",
  103. @"textures\wedge_p2_norm_1",
  104. }
  105. };
  106. private static string[,] shipReflection = new String[,]
  107. {
  108. {
  109. @"textures\p1_reflection_cubemap",
  110. "",
  111. },
  112. {
  113. @"textures\p2_reflection_cubemap1",
  114. @"textures\p2_reflection_cubemap2",
  115. }
  116. };
  117. private static string[] projectileMeshes = new String[]
  118. {
  119. @"models\pea_proj",
  120. @"models\mgun_proj",
  121. @"models\mgun_proj",
  122. @"models\p1_rocket_proj",
  123. @"models\bfg_proj",
  124. };
  125. private static string[] projectileDiffuse = new String[]
  126. {
  127. @"textures\pea_proj",
  128. @"textures\pea_proj",
  129. @"textures\mgun_proj",
  130. @"textures\rocket_proj",
  131. @"textures\bfg_proj",
  132. };
  133. private static string[] asteroidMeshes = new String[]
  134. {
  135. @"models\asteroid1",
  136. @"models\asteroid2",
  137. };
  138. private static string[] asteroidDiffuse = new String[]
  139. {
  140. @"textures\asteroid1",
  141. @"textures\asteroid2",
  142. };
  143. private static string[][] weaponMeshes = new String[][]
  144. {
  145. new string[]
  146. {
  147. @"models\p1_pea",
  148. @"models\p1_mgun",
  149. @"models\p1_dual",
  150. @"models\p1_rocket",
  151. @"models\p1_bfg",
  152. },
  153. new string[]
  154. {
  155. @"models\p2_pea",
  156. @"models\p2_mgun",
  157. @"models\p2_dual",
  158. @"models\p2_rocket",
  159. @"models\p2_bfg",
  160. }
  161. };
  162. private static string[,][] weaponDiffuse = new String[,][]
  163. {
  164. {
  165. new string[]
  166. {
  167. @"textures\p1_back" // Used by p1_pea
  168. },
  169. new string[]
  170. {
  171. @"textures\p1_back", @"textures\p1_dual" //Used by p1_mgun
  172. },
  173. new string[]
  174. {
  175. @"textures\p1_dual", @"textures\p1_back" //Used by p1_dual
  176. },
  177. new string[]
  178. {
  179. @"textures\p1_back", @"textures\p1_rocket" //Used by p1_rocket
  180. },
  181. new string[]
  182. {
  183. @"textures\p1_bfg", "", @"textures\p1_back" //Used by the p1_bfg
  184. }
  185. },
  186. {
  187. new string[]
  188. {
  189. @"textures\p2_back", @"textures\p2_back" // Used by p2_pea
  190. },
  191. new string[]
  192. {
  193. @"textures\p2_back", @"textures\p2_back", @"textures\p2_dual" // Used by p2_mgun
  194. },
  195. new string[]
  196. {
  197. @"textures\p2_back", @"textures\p2_back", @"textures\p2_dual" // Used by p2_dual
  198. },
  199. new string[]
  200. {
  201. @"textures\p2_rocket", @"textures\p2_back", @"textures\p2_back" // Used by p2_rocket
  202. },
  203. new string[]
  204. {
  205. @"textures\p2_back", @"textures\p2_back", @"textures\p2_bfg", @"textures\p2_back" // Used by p2_bfg
  206. }
  207. }
  208. };
  209. private Color[,][] shipMaterials = new Color[,][]
  210. {
  211. { //player 1 ships
  212. new Color[] {body, engines, cockpit1, cockpit1},
  213. new Color[] {body, cockpit1, engines},
  214. new Color[] {body, cockpit1, engines},
  215. },
  216. { //player 2 ships
  217. new Color[] {cockpit2, pipes, body},
  218. new Color[] {pipes, body, cockpit2},
  219. new Color[] {pipes, cockpit2, body},
  220. }
  221. };
  222. private bool[,][] shipUsesReflection2 = new bool[,][]
  223. {
  224. { //player 1 ships - always use 1st reflection map
  225. new bool[] {false, false, false, false},
  226. new bool[] {false, false, false},
  227. new bool[] {false, false, false},
  228. },
  229. { //player 2 ships
  230. new bool[] {true, true, false},
  231. new bool[] {true, false, true},
  232. new bool[] {true, true, false},
  233. }
  234. };
  235. #endregion
  236. public BasicEffectShape(Game game, BasicEffectShapes shape, PlayerIndex player, int shipNumber, int skinNumber, LightingType scene)
  237. : base(game)
  238. {
  239. Debug.Assert(shape == BasicEffectShapes.Ship, "Constructor should only be called with Ship");
  240. this.shape = shape;
  241. this.shapeNumber = shipNumber;
  242. this.skinNumber = skinNumber;
  243. this.player = player;
  244. this.scene = (int)scene;
  245. CreateShip();
  246. }
  247. public BasicEffectShape(Game game, BasicEffectShapes shape, PlayerIndex player, int shapeNumber, LightingType scene)
  248. : base(game)
  249. {
  250. Debug.Assert(shape == BasicEffectShapes.Weapon, "Constructor should only be called with Weapon");
  251. this.player = player;
  252. this.shape = shape;
  253. this.shapeNumber = shapeNumber;
  254. this.scene = (int)scene;
  255. CreateShape();
  256. }
  257. public BasicEffectShape(Game game, BasicEffectShapes shape, int shapeNumber, LightingType scene)
  258. : base(game)
  259. {
  260. this.shape = shape;
  261. this.shapeNumber = shapeNumber;
  262. this.scene = (int)scene;
  263. CreateShape();
  264. }
  265. public override void Create()
  266. {
  267. //Load the correct shader and set up the parameters
  268. OnCreateDevice();
  269. }
  270. public override void OnCreateDevice()
  271. {
  272. deviceCreated = true;
  273. }
  274. public void CreateShip()
  275. {
  276. //Model
  277. model = SpacewarGame.ContentManager.Load<Model>(SpacewarGame.Settings.MediaPath + shipMesh[(int)player, shapeNumber]);
  278. //Matching Textures
  279. texture = SpacewarGame.ContentManager.Load<Texture2D>(SpacewarGame.Settings.MediaPath + String.Format(shipDiffuse[(int)player, shapeNumber], (skinNumber + 1)));
  280. //Point to the right material array for this ship
  281. material = shipMaterials[(int)player, shapeNumber];
  282. SetupEffect();
  283. }
  284. public void CreateShape()
  285. {
  286. switch (shape)
  287. {
  288. case BasicEffectShapes.Projectile:
  289. modelNames = projectileMeshes;
  290. textureNames = projectileDiffuse;
  291. break;
  292. case BasicEffectShapes.Asteroid:
  293. modelNames = asteroidMeshes;
  294. textureNames = asteroidDiffuse;
  295. break;
  296. case BasicEffectShapes.Weapon:
  297. modelNames = weaponMeshes[(int)player];
  298. textureNames = weaponDiffuse[(int)player, shapeNumber];
  299. break;
  300. default:
  301. //Should never get here
  302. Debug.Assert(true, "EvolvedShape:CreateShape - bad EvolvedShape passed in");
  303. break;
  304. }
  305. //Model
  306. model = SpacewarGame.ContentManager.Load<Model>(SpacewarGame.Settings.MediaPath + modelNames[shapeNumber]);
  307. //Matching Textures
  308. if (shape == BasicEffectShapes.Asteroid || shape == BasicEffectShapes.Projectile)
  309. texture = SpacewarGame.ContentManager.Load<Texture2D>(SpacewarGame.Settings.MediaPath + textureNames[shapeNumber]);
  310. SetupEffect();
  311. }
  312. private void SetupEffect()
  313. {
  314. int i = 0;
  315. foreach (ModelMesh modelMesh in model.Meshes)
  316. {
  317. foreach (BasicEffect effect in modelMesh.Effects)
  318. {
  319. //State
  320. effect.Alpha = 1.0f;
  321. effect.SpecularPower = 200.0f;
  322. effect.AmbientLightColor = new Vector3(0.15f, 0.15f, 0.15f);
  323. //Lighting
  324. effect.LightingEnabled = true;
  325. effect.DirectionalLight0.Enabled = true;
  326. effect.DirectionalLight0.DiffuseColor = new Vector3(SpacewarGame.Settings.ShipLights[scene].DirectionalColor.X,
  327. SpacewarGame.Settings.ShipLights[scene].DirectionalColor.Y,
  328. SpacewarGame.Settings.ShipLights[scene].DirectionalColor.Z);
  329. effect.DirectionalLight0.SpecularColor = new Vector3(0.1f, 0.1f, 0.1f);
  330. effect.DirectionalLight0.Direction = Vector3.Normalize(new Vector3(SpacewarGame.Settings.ShipLights[scene].DirectionalDirection.X,
  331. SpacewarGame.Settings.ShipLights[scene].DirectionalDirection.Y,
  332. SpacewarGame.Settings.ShipLights[scene].DirectionalDirection.Z));
  333. effect.DirectionalLight1.Enabled = true;
  334. effect.DirectionalLight1.DiffuseColor = new Vector3(SpacewarGame.Settings.ShipLights[scene].PointColor.X,
  335. SpacewarGame.Settings.ShipLights[scene].PointColor.Y,
  336. SpacewarGame.Settings.ShipLights[scene].PointColor.Z);
  337. effect.DirectionalLight1.SpecularColor = new Vector3(0.1f, 0.1f, 0.1f);
  338. if (shape == BasicEffectShapes.Weapon)
  339. {
  340. if (string.IsNullOrEmpty(textureNames[i]))
  341. {
  342. texture = null;
  343. }
  344. else
  345. {
  346. texture = SpacewarGame.ContentManager.Load<Texture2D>(SpacewarGame.Settings.MediaPath + textureNames[i]);
  347. }
  348. }
  349. effect.Texture = texture;
  350. if (shape == BasicEffectShapes.Ship)
  351. {
  352. //Ships have materials and reflection maps
  353. effect.SpecularColor =
  354. effect.DiffuseColor = new Vector3(material[i].R / 255.0f, material[i].G / 255.0f, material[i].B / 255.0f);
  355. if (material[i] == Color.White)
  356. {
  357. effect.TextureEnabled = true;
  358. }
  359. else
  360. {
  361. effect.TextureEnabled = false;
  362. }
  363. }
  364. else
  365. {
  366. //Material is white
  367. effect.SpecularColor =
  368. effect.DiffuseColor = Vector3.One;
  369. effect.TextureEnabled = true;
  370. }
  371. }
  372. }
  373. }
  374. public override void Render()
  375. {
  376. base.Render();
  377. IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)GameInstance.Services.GetService(typeof(IGraphicsDeviceService));
  378. graphicsService.GraphicsDevice.BlendState = BlendState.Opaque;
  379. graphicsService.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
  380. if (shape == BasicEffectShapes.Ship)
  381. {
  382. //Model
  383. model = SpacewarGame.ContentManager.Load<Model>(SpacewarGame.Settings.MediaPath + shipMesh[(int)player, shapeNumber]);
  384. //Matching Textures
  385. texture = SpacewarGame.ContentManager.Load<Texture2D>(SpacewarGame.Settings.MediaPath + String.Format(shipDiffuse[(int)player, shapeNumber], (skinNumber + 1)));
  386. }
  387. else
  388. {
  389. //Model
  390. model = SpacewarGame.ContentManager.Load<Model>(SpacewarGame.Settings.MediaPath + modelNames[shapeNumber]);
  391. //Matching Textures
  392. if (shape == BasicEffectShapes.Asteroid || shape == BasicEffectShapes.Projectile)
  393. texture = SpacewarGame.ContentManager.Load<Texture2D>(SpacewarGame.Settings.MediaPath + textureNames[shapeNumber]);
  394. }
  395. if (deviceCreated)
  396. {
  397. SetupEffect();
  398. deviceCreated = false;
  399. }
  400. foreach (ModelMesh modelMesh in model.Meshes)
  401. {
  402. foreach (BasicEffect effect in modelMesh.Effects)
  403. {
  404. //Transform
  405. effect.View = SpacewarGame.Camera.View;
  406. effect.Projection = SpacewarGame.Camera.Projection;
  407. effect.World = World;
  408. effect.Texture = texture;
  409. // "fake" a point light by shining the directional light from the sun on the shape.
  410. Vector3 direction = Position - SunPosition;
  411. direction.Normalize();
  412. effect.DirectionalLight1.Direction = direction;
  413. }
  414. modelMesh.Draw();
  415. }
  416. }
  417. /// <summary>
  418. /// Preloads all the in game meshes and textures
  419. /// </summary>
  420. public static void Preload()
  421. {
  422. }
  423. }
  424. }