#region File Description //----------------------------------------------------------------------------- // EvolvedShape.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 EvolvedShapes { /// /// Ship models used ingame and in selection screen /// Ship, /// /// Asteroid models /// Asteroid, /// /// Projectile models /// Projectile, /// /// Weapon models for the selection screen /// Weapon, } /// /// Evolved shapes represents the 3d models used by the evolved variation of the game. They are all lit using the /// same shaders and have similar input and construction methods. /// class EvolvedShape : 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 TextureCube reflection1; private TextureCube reflection2; private int skinNumber; private int shapeNumber; private EvolvedShapes shape = EvolvedShapes.Projectile; private PlayerIndex player; private Model model; //New content Pipeline Mesh private Texture2D blackTexture; string[] modelNames = null; string[] textureNames = null; private int scene; //0 is in game 1 is selection screens private Color[] material; private bool[] useReflection2; private Effect effect; private EffectParameter worldParam; private EffectParameter inverseWorldParam; private EffectParameter worldViewProjectionParam; private EffectParameter viewPositionParam; private EffectParameter skinTextureParam; private EffectParameter normalTextureParam; private EffectParameter reflectionTextureParam; private EffectParameter ambientParam; private EffectParameter directionalDirectionParam; private EffectParameter directionalColorParam; private EffectParameter pointPositionParam; private EffectParameter pointColorParam; private EffectParameter pointFactorParam; private EffectParameter materialParam; #region filenames private static string[,] shipMesh = new string[,] { { @"models\p1_pencil", @"models\p1_saucer", @"models\p1_wedge", }, { @"models\p2_pencil", @"models\p2_saucer", @"models\p2_wedge", } }; 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 EvolvedShape(Game game, EvolvedShapes shape, PlayerIndex player, int shipNumber, int skinNumber, LightingType scene) : base(game) { Debug.Assert(shape == EvolvedShapes.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 EvolvedShape(Game game, EvolvedShapes shape, PlayerIndex player, int shapeNumber, LightingType scene) : base(game) { Debug.Assert(shape == EvolvedShapes.Weapon, "Constructor should only be called with Weapon"); this.player = player; this.shape = shape; this.shapeNumber = shapeNumber; this.scene = (int)scene; CreateShape(); } public EvolvedShape(Game game, EvolvedShapes 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() { effect = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + @"shaders\ship"); worldParam = effect.Parameters["world"]; inverseWorldParam = effect.Parameters["inverseWorld"]; worldViewProjectionParam = effect.Parameters["worldViewProjection"]; viewPositionParam = effect.Parameters["viewPosition"]; skinTextureParam = effect.Parameters["SkinTexture"]; normalTextureParam = effect.Parameters["NormalMapTexture"]; reflectionTextureParam = effect.Parameters["ReflectionTexture"]; ambientParam = effect.Parameters["Ambient"]; directionalDirectionParam = effect.Parameters["DirectionalDirection"]; directionalColorParam = effect.Parameters["DirectionalColor"]; pointPositionParam = effect.Parameters["PointPosition"]; pointColorParam = effect.Parameters["PointColor"]; pointFactorParam = effect.Parameters["PointFactor"]; materialParam = effect.Parameters["Material"]; blackTexture = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + @"Textures\Black"); SetupEffect(); } private void SetupEffect() { ambientParam.SetValue(SpacewarGame.Settings.ShipLights[scene].Ambient); directionalDirectionParam.SetValue(SpacewarGame.Settings.ShipLights[scene].DirectionalDirection); directionalColorParam.SetValue(SpacewarGame.Settings.ShipLights[scene].DirectionalColor); pointPositionParam.SetValue(SpacewarGame.Settings.ShipLights[scene].PointPosition); pointColorParam.SetValue(SpacewarGame.Settings.ShipLights[scene].PointColor); pointFactorParam.SetValue(SpacewarGame.Settings.ShipLights[scene].PointFactor); normalTextureParam.SetValue((Texture2D)null); //Normal maps not currently used } public void CreateShip() { //Point to the right material array for this ship material = shipMaterials[(int)player, shapeNumber]; //Point to the right cube map mapping useReflection2 = shipUsesReflection2[(int)player, shapeNumber]; SetupEffect(); } public void CreateShape() { switch (shape) { case EvolvedShapes.Projectile: modelNames = projectileMeshes; textureNames = projectileDiffuse; break; case EvolvedShapes.Asteroid: modelNames = asteroidMeshes; textureNames = asteroidDiffuse; break; case EvolvedShapes.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; } SetupEffect(); } public override void Render() { base.Render(); worldParam.SetValue(World); inverseWorldParam.SetValue(Matrix.Invert(World)); worldViewProjectionParam.SetValue(World * SpacewarGame.Camera.View * SpacewarGame.Camera.Projection); viewPositionParam.SetValue(new Vector4(SpacewarGame.Camera.ViewPosition, 0)); if (shape == EvolvedShapes.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))); //_normal = SpacewarGame.TextureCache[shipNormal[(int)_player, _shapeNumber]]; //Normal maps not currently used reflection1 = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + shipReflection[(int)player, 0]); if (player == PlayerIndex.Two) //player 2 ship has 2 reflection maps { reflection2 = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + shipReflection[(int)player, 1]); } } else { //Model model = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + modelNames[shapeNumber]); //Matching Textures if (shape == EvolvedShapes.Asteroid || shape == EvolvedShapes.Projectile) texture = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + textureNames[shapeNumber]); } int i = 0; foreach (ModelMesh modelMesh in model.Meshes) { foreach (ModelMeshPart meshPart in modelMesh.MeshParts) { if (shape == EvolvedShapes.Weapon) { if (string.IsNullOrEmpty(textureNames[i])) { texture = null; } else { texture = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + textureNames[i]); } } skinTextureParam.SetValue(texture); if (shape == EvolvedShapes.Ship) { //Ships have materials and reflection maps materialParam.SetValue(material[i].ToVector4()); if (material[i] != Color.White) skinTextureParam.SetValue(blackTexture); //Choose the correct reflection map for this subset reflectionTextureParam.SetValue(useReflection2[i] ? reflection2 : reflection1); } else { //Material is white materialParam.SetValue(Color.White.ToVector4()); reflectionTextureParam.SetValue((Texture2D)null); } effect.Techniques[0].Passes[0].Apply(); if (meshPart.PrimitiveCount > 0) { IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)GameInstance.Services.GetService(typeof(IGraphicsDeviceService)); GraphicsDevice gd = graphicsService.GraphicsDevice; gd.SetVertexBuffer(meshPart.VertexBuffer); gd.Indices = meshPart.IndexBuffer; gd.DrawIndexedPrimitives(PrimitiveType.TriangleList, meshPart.VertexOffset, 0, meshPart.NumVertices, meshPart.StartIndex, meshPart.PrimitiveCount); } i++; } } } /// /// Preloads all the in game meshes and textures /// public static void Preload() { } } }