#region Copyright
/*
--------------------------------------------------------------------------------
This source file is part of Xenocide
by Project Xenocide Team
For the latest info on Xenocide, see http://www.projectxenocide.com/
This work is licensed under the Creative Commons
Attribution-NonCommercial-ShareAlike 2.5 License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/2.5/
or send a letter to Creative Commons, 543 Howard Street, 5th Floor,
San Francisco, California, 94105, USA.
--------------------------------------------------------------------------------
*/
/*
* @file EarthGlobe.cs
* @date Created: 2007/01/28
* @author File creator: dteviot
* @author Credits: none
*/
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
#endregion
namespace ProjectXenocide.UI.Scenes.Geoscape
{
///
/// This is a custom vertex to use with normal mapping on the Earth Normal Mapped Shader
///
[Serializable]
public struct GlobeVertex
{
///
/// The position of the vertex
///
private Vector3 Position;
///
/// Texture Coordinate
///
private Vector2 TexCoord;
///
/// The Normal of the vertex
///
private Vector3 Normal;
///
/// The Tangent of the vertex
///
private Vector3 Tangent;
///
/// The Binormal of the vertex
///
private Vector3 Binormal;
///
/// Definition of the vertex element to create the approapriate binding to the shaders.
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2105:ArrayFieldsShouldNotBeReadOnly")]
public static readonly VertexElement[] VertexElements =
new VertexElement[] {
new VertexElement(0,0,VertexElementFormat.Vector3,
VertexElementMethod.Default,VertexElementUsage.Position,0),
new VertexElement(0,sizeof(float)*3,VertexElementFormat.Vector2,
VertexElementMethod.Default,VertexElementUsage.TextureCoordinate,0),
new VertexElement(0,sizeof(float)*5,VertexElementFormat.Vector3,
VertexElementMethod.Default,VertexElementUsage.Normal,0),
new VertexElement(0,sizeof(float)*8,VertexElementFormat.Vector3,
VertexElementMethod.Default,VertexElementUsage.Tangent,0),
new VertexElement(0,sizeof(float)*11,VertexElementFormat.Vector3,
VertexElementMethod.Default,VertexElementUsage.Binormal,0),
};
///
/// The contructor of this Vertex.
///
/// The position of the vertex
/// The normal of the vertex
/// The tangent of the vertex
/// The binormal of the vertex
/// The UV coordinates
public GlobeVertex(Vector3 position, Vector3 normal, Vector3 tangent, Vector3 binormal, Vector2 texCoord)
{
Position = position;
TexCoord = texCoord;
Normal = normal;
Tangent = tangent;
Binormal = binormal;
}
///
/// Distinct operator
///
/// left operator parameter
/// right operator parameter
///
public static bool operator !=(GlobeVertex left, GlobeVertex right)
{
return left.GetHashCode() != right.GetHashCode();
}
///
/// Equals operator
///
/// left operator parameter
/// right operator parameter
///
public static bool operator ==(GlobeVertex left, GlobeVertex right)
{
return left.GetHashCode() == right.GetHashCode();
}
///
/// Returns if the objects are the equals
///
/// The object to compare
/// True if equals, false otherwise
public override bool Equals(object obj)
{
return this == (GlobeVertex)obj;
}
///
/// The size in bytes of this vertex
///
public static int SizeInBytes
{
get { return sizeof(float) * 14; }
}
///
/// Hashcode for the object.
///
///
public override int GetHashCode()
{
return Position.GetHashCode() | TexCoord.GetHashCode() | Normal.GetHashCode() | Tangent.GetHashCode() | Binormal.GetHashCode();
}
///
/// Simplified ToString method.
///
///
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2}", Position.X, Position.Y, Position.Z);
}
}
class EarthGlobe
{
Texture2D diffuseTexture;
Texture2D nightTexture;
Texture2D normapMapTexture;
SphereMesh sphereMesh;
VertexDeclaration basicEffectVertexDeclaration;
VertexBuffer vertexBuffer;
IndexBuffer indexBuffer;
///
/// Load/create the graphics resources the globe needs
///
/// the display
public void LoadContent(GraphicsDevice device)
{
diffuseTexture = Texture2D.FromFile(Xenocide.Instance.GraphicsDevice, @"Content\Textures\Geoscape\EarthDiffuseMap.jpg");
nightTexture = Texture2D.FromFile(Xenocide.Instance.GraphicsDevice, @"Content\Textures\Geoscape\EarthNightMap.png");
normapMapTexture = Texture2D.FromFile(Xenocide.Instance.GraphicsDevice, @"Content\Textures\Geoscape\EarthNormalMap.png");
sphereMesh = new SphereMesh(15);
vertexBuffer = sphereMesh.CreateVertexBuffer(device);
indexBuffer = sphereMesh.CreateIndexBuffer(device);
basicEffectVertexDeclaration = new VertexDeclaration(device, GlobeVertex.VertexElements);
}
///
/// Draw the world on the device
///
/// Device to render the globe to
/// effect to use to draw the globe
public void Draw(GraphicsDevice device, Effect effect)
{
device.VertexDeclaration = basicEffectVertexDeclaration;
device.Vertices[0].SetSource( vertexBuffer, 0, GlobeVertex.SizeInBytes);
device.Indices = indexBuffer;
effect.Parameters["GeoscapeTexture"].SetValue(diffuseTexture);
effect.Parameters["NightTexture"].SetValue(nightTexture);
effect.Parameters["NormalMapTexture"].SetValue(normapMapTexture);
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList,
0,
0,
sphereMesh.TotalVertexes,
0,
sphereMesh.TotalFaces
);
pass.End();
}
effect.End();
}
}
}