#region File Description //----------------------------------------------------------------------------- // BasicEffectShape.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework; using System.Diagnostics; #endregion namespace Spacewar { /// /// The shapes that this class can draw /// public enum BasicEffectShapes { /// /// Ship models used ingame and in selection screen /// Ship, /// /// Asteroid models /// Asteroid, /// /// Projectile models /// Projectile, /// /// Weapon models for the selection screen /// Weapon, } /// /// BasicEffect shapes represent the 3d models used by the evolved variation of the game. These shapes come through the Content Pipeline. /// They are all lit using the BasicEffect Shader and have similar input and construction methods /// class BasicEffectShape : Shape { //Materials private static Color white = Color.White; private static Color body = white; //body has texture so don't need material private static Color pipes = white; //pipes has texture so don't need material private static Color cockpit1 = new Color((byte)(.529f * 255), 255, 255, 0); private static Color cockpit2 = new Color(255, 255, (byte)(.373f * 255), 0); private static Color engines = new Color((byte)(.925f * 255), (byte)(.529f * 255), 255, 0); private Texture2D texture; private int skinNumber; private int shapeNumber; private BasicEffectShapes shape = BasicEffectShapes.Projectile; private PlayerIndex player; private Model model; //New content Pipeline Mesh private bool deviceCreated; string[] modelNames = null; string[] textureNames = null; private int scene; //0 is in game 1 is selection screens private Color[] material; private static Vector3 SunPosition = new Vector3(-0.5f, -0.5f, 100.0f); #region filenames private static string[,] shipMesh = new string[,] { { @"models\pencil_player1", @"models\saucer_player1", @"models\wedge_player1", }, { @"models\pencil_player2", @"models\saucer_player2", @"models\wedge_player2", } }; private static string[,] shipDiffuse = new string[,] { { @"textures\pencil_p1_diff_v{0}", @"textures\saucer_p1_diff_v{0}", @"textures\wedge_p1_diff_v{0}", }, { @"textures\pencil_p2_diff_v{0}", @"textures\saucer_p2_diff_v{0}", @"textures\wedge_p2_diff_v{0}", } }; private static string[,] shipNormal = new String[,] { { @"textures\pencil_p1_norm_1", @"textures\saucer_p1_norm_1", @"textures\wedge_p1_norm_1", }, { @"textures\pencil_p2_norm_1", @"textures\saucer_p2_norm_1", @"textures\wedge_p2_norm_1", } }; private static string[,] shipReflection = new String[,] { { @"textures\p1_reflection_cubemap", "", }, { @"textures\p2_reflection_cubemap1", @"textures\p2_reflection_cubemap2", } }; private static string[] projectileMeshes = new String[] { @"models\pea_proj", @"models\mgun_proj", @"models\mgun_proj", @"models\p1_rocket_proj", @"models\bfg_proj", }; private static string[] projectileDiffuse = new String[] { @"textures\pea_proj", @"textures\pea_proj", @"textures\mgun_proj", @"textures\rocket_proj", @"textures\bfg_proj", }; private static string[] asteroidMeshes = new String[] { @"models\asteroid1", @"models\asteroid2", }; private static string[] asteroidDiffuse = new String[] { @"textures\asteroid1", @"textures\asteroid2", }; private static string[][] weaponMeshes = new String[][] { new string[] { @"models\p1_pea", @"models\p1_mgun", @"models\p1_dual", @"models\p1_rocket", @"models\p1_bfg", }, new string[] { @"models\p2_pea", @"models\p2_mgun", @"models\p2_dual", @"models\p2_rocket", @"models\p2_bfg", } }; private static string[,][] weaponDiffuse = new String[,][] { { new string[] { @"textures\p1_back" // Used by p1_pea }, new string[] { @"textures\p1_back", @"textures\p1_dual" //Used by p1_mgun }, new string[] { @"textures\p1_dual", @"textures\p1_back" //Used by p1_dual }, new string[] { @"textures\p1_back", @"textures\p1_rocket" //Used by p1_rocket }, new string[] { @"textures\p1_bfg", "", @"textures\p1_back" //Used by the p1_bfg } }, { new string[] { @"textures\p2_back", @"textures\p2_back" // Used by p2_pea }, new string[] { @"textures\p2_back", @"textures\p2_back", @"textures\p2_dual" // Used by p2_mgun }, new string[] { @"textures\p2_back", @"textures\p2_back", @"textures\p2_dual" // Used by p2_dual }, new string[] { @"textures\p2_rocket", @"textures\p2_back", @"textures\p2_back" // Used by p2_rocket }, new string[] { @"textures\p2_back", @"textures\p2_back", @"textures\p2_bfg", @"textures\p2_back" // Used by p2_bfg } } }; private Color[,][] shipMaterials = new Color[,][] { { //player 1 ships new Color[] {body, engines, cockpit1, cockpit1}, new Color[] {body, cockpit1, engines}, new Color[] {body, cockpit1, engines}, }, { //player 2 ships new Color[] {cockpit2, pipes, body}, new Color[] {pipes, body, cockpit2}, new Color[] {pipes, cockpit2, body}, } }; private bool[,][] shipUsesReflection2 = new bool[,][] { { //player 1 ships - always use 1st reflection map new bool[] {false, false, false, false}, new bool[] {false, false, false}, new bool[] {false, false, false}, }, { //player 2 ships new bool[] {true, true, false}, new bool[] {true, false, true}, new bool[] {true, true, false}, } }; #endregion public BasicEffectShape(Game game, BasicEffectShapes shape, PlayerIndex player, int shipNumber, int skinNumber, LightingType scene) : base(game) { Debug.Assert(shape == BasicEffectShapes.Ship, "Constructor should only be called with Ship"); this.shape = shape; this.shapeNumber = shipNumber; this.skinNumber = skinNumber; this.player = player; this.scene = (int)scene; CreateShip(); } public BasicEffectShape(Game game, BasicEffectShapes shape, PlayerIndex player, int shapeNumber, LightingType scene) : base(game) { Debug.Assert(shape == BasicEffectShapes.Weapon, "Constructor should only be called with Weapon"); this.player = player; this.shape = shape; this.shapeNumber = shapeNumber; this.scene = (int)scene; CreateShape(); } public BasicEffectShape(Game game, BasicEffectShapes shape, int shapeNumber, LightingType scene) : base(game) { this.shape = shape; this.shapeNumber = shapeNumber; this.scene = (int)scene; CreateShape(); } public override void Create() { //Load the correct shader and set up the parameters OnCreateDevice(); } public override void OnCreateDevice() { deviceCreated = true; } public void CreateShip() { //Model model = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + shipMesh[(int)player, shapeNumber]); //Matching Textures texture = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + String.Format(shipDiffuse[(int)player, shapeNumber], (skinNumber + 1))); //Point to the right material array for this ship material = shipMaterials[(int)player, shapeNumber]; SetupEffect(); } public void CreateShape() { switch (shape) { case BasicEffectShapes.Projectile: modelNames = projectileMeshes; textureNames = projectileDiffuse; break; case BasicEffectShapes.Asteroid: modelNames = asteroidMeshes; textureNames = asteroidDiffuse; break; case BasicEffectShapes.Weapon: modelNames = weaponMeshes[(int)player]; textureNames = weaponDiffuse[(int)player, shapeNumber]; break; default: //Should never get here Debug.Assert(true, "EvolvedShape:CreateShape - bad EvolvedShape passed in"); break; } //Model model = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + modelNames[shapeNumber]); //Matching Textures if (shape == BasicEffectShapes.Asteroid || shape == BasicEffectShapes.Projectile) texture = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + textureNames[shapeNumber]); SetupEffect(); } private void SetupEffect() { int i = 0; foreach (ModelMesh modelMesh in model.Meshes) { foreach (BasicEffect effect in modelMesh.Effects) { //State effect.Alpha = 1.0f; effect.SpecularPower = 200.0f; effect.AmbientLightColor = new Vector3(0.15f, 0.15f, 0.15f); //Lighting effect.LightingEnabled = true; effect.DirectionalLight0.Enabled = true; effect.DirectionalLight0.DiffuseColor = new Vector3(SpacewarGame.Settings.ShipLights[scene].DirectionalColor.X, SpacewarGame.Settings.ShipLights[scene].DirectionalColor.Y, SpacewarGame.Settings.ShipLights[scene].DirectionalColor.Z); effect.DirectionalLight0.SpecularColor = new Vector3(0.1f, 0.1f, 0.1f); effect.DirectionalLight0.Direction = Vector3.Normalize(new Vector3(SpacewarGame.Settings.ShipLights[scene].DirectionalDirection.X, SpacewarGame.Settings.ShipLights[scene].DirectionalDirection.Y, SpacewarGame.Settings.ShipLights[scene].DirectionalDirection.Z)); effect.DirectionalLight1.Enabled = true; effect.DirectionalLight1.DiffuseColor = new Vector3(SpacewarGame.Settings.ShipLights[scene].PointColor.X, SpacewarGame.Settings.ShipLights[scene].PointColor.Y, SpacewarGame.Settings.ShipLights[scene].PointColor.Z); effect.DirectionalLight1.SpecularColor = new Vector3(0.1f, 0.1f, 0.1f); if (shape == BasicEffectShapes.Weapon) { if (string.IsNullOrEmpty(textureNames[i])) { texture = null; } else { texture = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + textureNames[i]); } } effect.Texture = texture; if (shape == BasicEffectShapes.Ship) { //Ships have materials and reflection maps effect.SpecularColor = effect.DiffuseColor = new Vector3(material[i].R / 255.0f, material[i].G / 255.0f, material[i].B / 255.0f); if (material[i] == Color.White) { effect.TextureEnabled = true; } else { effect.TextureEnabled = false; } } else { //Material is white effect.SpecularColor = effect.DiffuseColor = Vector3.One; effect.TextureEnabled = true; } } } } public override void Render() { base.Render(); IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)GameInstance.Services.GetService(typeof(IGraphicsDeviceService)); graphicsService.GraphicsDevice.BlendState = BlendState.Opaque; graphicsService.GraphicsDevice.DepthStencilState = DepthStencilState.Default; if (shape == BasicEffectShapes.Ship) { //Model model = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + shipMesh[(int)player, shapeNumber]); //Matching Textures texture = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + String.Format(shipDiffuse[(int)player, shapeNumber], (skinNumber + 1))); } else { //Model model = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + modelNames[shapeNumber]); //Matching Textures if (shape == BasicEffectShapes.Asteroid || shape == BasicEffectShapes.Projectile) texture = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + textureNames[shapeNumber]); } if (deviceCreated) { SetupEffect(); deviceCreated = false; } foreach (ModelMesh modelMesh in model.Meshes) { foreach (BasicEffect effect in modelMesh.Effects) { //Transform effect.View = SpacewarGame.Camera.View; effect.Projection = SpacewarGame.Camera.Projection; effect.World = World; effect.Texture = texture; // "fake" a point light by shining the directional light from the sun on the shape. Vector3 direction = Position - SunPosition; direction.Normalize(); effect.DirectionalLight1.Direction = direction; } modelMesh.Draw(); } } /// /// Preloads all the in game meshes and textures /// public static void Preload() { } } }