#region File Description //----------------------------------------------------------------------------- // GameQuad.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; using Microsoft.Xna.Framework.Graphics; using RobotGameData; using RobotGameData.Render; #endregion namespace RobotGameData.GameObject { /// /// Since this sprite contains its own up vector and normal vector, /// it does not get affected by view matrix. /// public class GameQuad : GameSceneNode { #region Fields Vector3 upperLeft; Vector3 lowerLeft; Vector3 upperRight; Vector3 lowerRight; Vector3 normal; Vector3 planeUp; Vector3 left; VertexPositionNormalTexture[] vertices; int[] indices; VertexDeclaration vertexDecl; BasicEffect effect; IGraphicsDeviceService graphics; bool alphaTestEnable = false; bool alphaBlendEnable = false; CompareFunction alphaFunction = CompareFunction.Always; Blend sourceBlend = Blend.One; Blend destinationBlend = Blend.Zero; BlendFunction blendFunction = BlendFunction.Add; int referenceAlpha = 0; bool depthBufferEnable = true; bool depthBufferWriteEnable = true; CompareFunction depthBufferFunction = CompareFunction.LessEqual; CullMode cullMode = CullMode.CullCounterClockwiseFace; #endregion #region Properties /// /// Gets or sets the world matrix. /// public Matrix World { get { return effect.World; } set { effect.World = value; } } /// /// Gets or sets the view matrix. /// public Matrix View { get { return effect.View; } set { effect.View = value; } } /// /// Gets or sets the projection matrix. /// public Matrix Projection { get { return effect.Projection; } set { effect.Projection = value; } } /// /// Gets or sets the texture. /// public Texture2D Texture { get { return effect.Texture; } set { effect.Texture = value; if (effect.Texture == null) effect.TextureEnabled = false; else effect.TextureEnabled = true; } } /// /// Gets or sets the lighting enable. /// public bool LightingEnabled { get { return effect.LightingEnabled; } set { effect.LightingEnabled = value; } } /// /// Gets or sets the vertex color enable. /// public bool VertexColorEnabled { get { return effect.VertexColorEnabled; } set { effect.VertexColorEnabled = value; } } /// /// Gets or sets the alpha of the mesh. /// public float Alpha { get { return effect.Alpha; } set { effect.Alpha = value; } } public bool AlphaTestEnable { get { return alphaTestEnable; } set { alphaTestEnable = value; } } public bool AlphaBlendEnable { get { return alphaBlendEnable; } set { alphaBlendEnable = value; } } public int ReferenceAlpha { get { return referenceAlpha; } set { referenceAlpha = value; } } public CompareFunction AlphaFunction { get { return alphaFunction; } set { alphaFunction = value; } } public bool DepthBufferEnable { get { return depthBufferEnable; } set { depthBufferEnable = value; } } public bool DepthBufferWriteEnable { get { return depthBufferWriteEnable; } set { depthBufferWriteEnable = value; } } public CompareFunction DepthBufferFunction { get { return depthBufferFunction; } set { depthBufferFunction = value; } } public Blend SourceBlend { get { return sourceBlend; } set { sourceBlend = value; } } public Blend DestinationBlend { get { return destinationBlend; } set { destinationBlend = value; } } public BlendFunction BlendFunction { get { return blendFunction; } set { blendFunction = value; } } public CullMode CullMode { get { return cullMode; } set { cullMode = value; } } #endregion /// /// Constructor. /// /// origin position /// normal vector /// up vector /// width size /// height size public GameQuad(Vector3 origin, Vector3 normal, Vector3 up, float width, float height) { this.graphics = (IGraphicsDeviceService)FrameworkCore.Game.Services.GetService( typeof(IGraphicsDeviceService)); this.effect = new BasicEffect(graphics.GraphicsDevice, null); this.vertices = new VertexPositionNormalTexture[4]; this.indices = new int[6]; this.normal = normal; this.planeUp = up; // Calculate the quad corners this.left = Vector3.Cross(normal, this.planeUp); Vector3 uppercenter = (this.planeUp * height / 2) + origin; this.upperLeft = uppercenter + (this.left * width / 2); this.upperRight = uppercenter - (this.left * width / 2); this.lowerLeft = this.upperLeft - (this.planeUp * height); this.lowerRight = this.upperRight - (this.planeUp * height); vertexDecl = new VertexDeclaration(graphics.GraphicsDevice, VertexPositionNormalTexture.VertexElements); FillVertices(); } /// /// fills vertex data using members. /// private void FillVertices() { // Fill in texture coordinates to display full texture // on quad Vector2 textureUpperLeft = new Vector2( 0.0f, 0.0f ); Vector2 textureUpperRight = new Vector2( 1.0f, 0.0f ); Vector2 textureLowerLeft = new Vector2( 0.0f, 1.0f ); Vector2 textureLowerRight = new Vector2( 1.0f, 1.0f ); // Provide a normal for each vertex for (int i = 0; i < this.vertices.Length; i++) { this.vertices[i].Normal = this.normal; } // Set the position and texture coordinate for each // vertex this.vertices[0].Position = this.lowerLeft; this.vertices[0].TextureCoordinate = textureLowerLeft; this.vertices[1].Position = this.upperLeft; this.vertices[1].TextureCoordinate = textureUpperLeft; this.vertices[2].Position = this.lowerRight; this.vertices[2].TextureCoordinate = textureLowerRight; this.vertices[3].Position = this.upperRight; this.vertices[3].TextureCoordinate = textureUpperRight; // Set the index buffer for each vertex, using // clockwise winding this.indices[0] = 0; this.indices[1] = 1; this.indices[2] = 2; this.indices[3] = 2; this.indices[4] = 1; this.indices[5] = 3; } protected override void Dispose(bool disposing) { if (vertexDecl != null) { vertexDecl.Dispose(); vertexDecl = null; } if (effect != null) { effect.Dispose(); effect = null; } base.Dispose(disposing); } /// /// draws a 3D quad. /// /// protected override void OnDraw(RenderTracer renderTracer) { World = this.TransformedMatrix; View = renderTracer.View; Projection = renderTracer.Projection; renderTracer.Device.VertexDeclaration = vertexDecl; renderTracer.Device.RenderState.AlphaTestEnable = alphaTestEnable; renderTracer.Device.RenderState.AlphaBlendEnable = alphaBlendEnable; renderTracer.Device.RenderState.AlphaFunction = alphaFunction; renderTracer.Device.RenderState.SourceBlend = sourceBlend; renderTracer.Device.RenderState.DestinationBlend = destinationBlend; renderTracer.Device.RenderState.BlendFunction = blendFunction; renderTracer.Device.RenderState.ReferenceAlpha = referenceAlpha; renderTracer.Device.RenderState.DepthBufferEnable = depthBufferEnable; renderTracer.Device.RenderState.DepthBufferWriteEnable = depthBufferWriteEnable; renderTracer.Device.RenderState.DepthBufferFunction = depthBufferFunction; renderTracer.Device.RenderState.CullMode = cullMode; GraphicsDevice device = renderTracer.Device; effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); device.DrawUserIndexedPrimitives( PrimitiveType.TriangleList, this.vertices, 0, 4, this.indices, 0, 2); pass.End(); } effect.End(); } } }