#region File Description
//-----------------------------------------------------------------------------
// GameMesh.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using RobotGameData.Render;
using RobotGameData.Resource;
using RobotGameData.Helper;
#endregion
namespace RobotGameData.GameObject
{
public enum RenderingSpace
{
///
/// 3D world space
///
World = 0,
///
/// 2D screen space
///
Screen,
}
///
/// This mesh is drawn on the 3D world.
/// It contains a vertex buffer and an index buffer.
///
public class GameMesh : GameSceneNode
{
#region Fields
// If it's true, will be disabled VertexBuffer and IndexBuffer
public bool userPrimitive = true;
public VertexPositionColorTexture[] vertexData = null;
public short[] indexData = null;
public VertexBuffer vertexBuffer = null;
public IndexBuffer indexBuffer = null;
Texture2D textureResource = null;
int updateVertexCount = 0;
int primitiveCount = 0;
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;
static VertexDeclaration vertexDeclaration = null;
static BasicEffect basicEffect = null;
#endregion
#region Properties
public int UpdateVertexCount
{
get { return updateVertexCount; }
set { updateVertexCount = value; }
}
public int PrimitiveCount
{
get { return this.primitiveCount; }
set { this.primitiveCount = 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
protected override void Dispose(bool disposing)
{
if (this.vertexBuffer != null)
{
this.vertexBuffer.Dispose();
this.vertexBuffer = null;
}
if (this.indexBuffer != null)
{
this.indexBuffer.Dispose();
this.indexBuffer = null;
}
if (vertexDeclaration != null)
{
vertexDeclaration.Dispose();
vertexDeclaration = null;
}
if (basicEffect != null)
{
basicEffect.Dispose();
basicEffect = null;
}
base.Dispose(disposing);
}
protected override void UnloadContent()
{
base.UnloadContent();
}
///
/// the mesh is drawn by using the vertexData.
/// When the userPrimitive member is set to true,
/// it is drawn without using the vertex buffer and the index buffer.
///
///
protected override void OnDraw(RenderTracer renderTracer)
{
GraphicsDevice device = renderTracer.Device;
RenderState renderState = device.RenderState;
basicEffect.Texture = this.textureResource;
basicEffect.World = this.TransformedMatrix;
basicEffect.View = renderTracer.View;
basicEffect.Projection = renderTracer.Projection;
basicEffect.LightingEnabled = false;
device.VertexDeclaration = vertexDeclaration;
device.SamplerStates[0].AddressU = TextureAddressMode.Wrap;
device.SamplerStates[0].AddressV = TextureAddressMode.Wrap;
device.SamplerStates[0].MinFilter = TextureFilter.Linear;
device.SamplerStates[0].MagFilter = TextureFilter.Linear;
device.SamplerStates[0].MipFilter = TextureFilter.Point;
renderState.AlphaTestEnable = alphaTestEnable;
renderState.AlphaBlendEnable = alphaBlendEnable;
renderState.AlphaFunction = alphaFunction;
renderState.SourceBlend = sourceBlend;
renderState.DestinationBlend = destinationBlend;
renderState.BlendFunction = blendFunction;
renderState.ReferenceAlpha = referenceAlpha;
renderState.DepthBufferEnable = depthBufferEnable;
renderState.DepthBufferWriteEnable = depthBufferWriteEnable;
renderState.DepthBufferFunction = depthBufferFunction;
renderState.CullMode = cullMode;
basicEffect.Begin();
for (int i = 0; i < basicEffect.CurrentTechnique.Passes.Count; i++)
{
EffectPass pass = basicEffect.CurrentTechnique.Passes[i];
pass.Begin();
if (userPrimitive )
{
// Use index?
if (indexData != null)
{
// only use vertex and index data
device.DrawUserIndexedPrimitives(
PrimitiveType.TriangleList,
vertexData,
0,
vertexData.Length,
indexData,
0,
this.primitiveCount);
}
else
{
device.DrawUserPrimitives(
PrimitiveType.TriangleList,
vertexData,
0,
this.primitiveCount);
}
}
else
{
// Use vertex buffer
device.Vertices[0].SetSource(vertexBuffer,
0,
VertexPositionColorTexture.SizeInBytes);
// Use index?
if (indexBuffer != null)
{
// Use index buffer
device.Indices = indexBuffer;
device.DrawIndexedPrimitives(PrimitiveType.TriangleList,
0,
0,
updateVertexCount,
0,
this.primitiveCount);
}
else
{
device.DrawPrimitives(PrimitiveType.TriangleList,
0,
this.primitiveCount);
}
}
pass.End();
}
basicEffect.End();
device.RenderState.DepthBufferWriteEnable = true;
}
///
/// create members for creating mesh data.
///
/// vertex count
/// index count
/// texture file name
public void Create(int vertexCount, int indexCount, string fileName)
{
// Load texture
GameResourceTexture2D resource =
FrameworkCore.ResourceManager.LoadTexture(fileName);
Create(vertexCount, indexCount, resource.Texture2D);
}
///
/// create members for creating mesh data.
///
/// vertex count
/// index count
/// texture resource
public void Create(int vertexCount, int indexCount, Texture2D texture)
{
GraphicsDevice device = FrameworkCore.Game.GraphicsDevice;
this.updateVertexCount = vertexCount;
if( indexCount > 0)
this.primitiveCount = vertexCount / 2;
else
this.primitiveCount = vertexCount / 3;
this.textureResource = texture;
if (basicEffect == null)
{
basicEffect = new BasicEffect(device, null);
basicEffect.LightingEnabled = false;
basicEffect.VertexColorEnabled = true;
basicEffect.TextureEnabled = true;
}
if (vertexDeclaration == null)
{
vertexDeclaration = new VertexDeclaration(device,
VertexPositionColorTexture.VertexElements);
}
// Create vertexBuffer
if( vertexCount > 0)
{
vertexData = new VertexPositionColorTexture[vertexCount];
for (int i = 0; i < vertexCount; i++)
{
vertexData[i].Color.PackedValue = 0xFFFFFFFF;
}
if (userPrimitive == false)
{
vertexBuffer = new DynamicVertexBuffer(device,
VertexPositionColorTexture.SizeInBytes * vertexCount,
BufferUsage.WriteOnly);
vertexBuffer.SetData(vertexData);
}
}
// Create indexBuffer
if( indexCount > 0)
{
indexData = new short[indexCount];
if (userPrimitive == false)
{
indexBuffer = new DynamicIndexBuffer(device,
sizeof(short) * indexCount,
BufferUsage.WriteOnly,
IndexElementSize.SixteenBits);
indexBuffer.SetData(indexData);
}
}
}
///
/// configures a position to the vertex component data.
///
/// an index of the vertex component data
/// a position vector
public void SetPositionData(int index, Vector3 position)
{
vertexData[index].Position = position;
}
///
/// configure positions to the vertex component data.
///
/// array of position vector
public void SetPositionData(Vector3[] position)
{
for(int i = 0; i < position.Length; i++)
{
SetPositionData(i, position[i]);
}
}
///
/// configures color to the vertex component data.
///
/// an index of the vertex component data
/// packed color value
public void SetColorData(int index, uint color)
{
vertexData[index].Color.PackedValue = color;
}
///
/// configures color to the vertex component data.
///
/// an index of the vertex component data
/// color
public void SetColorData(int index, Color color)
{
vertexData[index].Color = color;
}
///
/// configure colors to the vertex component data.
///
/// array of packed color value
public void SetColorData(uint[] color)
{
for (int i = 0; i < color.Length; i++)
{
SetColorData(i, color[i]);
}
}
///
/// configure colors to the vertex component data.
///
/// array of color
public void SetColorData(Color[] color)
{
for (int i = 0; i < color.Length; i++)
{
SetColorData(i, color[i]);
}
}
///
/// configures texture coordinates to the vertex component data.
///
/// an index of the vertex component data
/// texture coordinates
public void SetTextureCoordData(int index, Vector2 texturecoord)
{
vertexData[index].TextureCoordinate = texturecoord;
}
///
/// configures texture coordinates to the vertex component data.
///
/// array of texture coordinates
public void SetTextureCoordData(Vector2[] texturecoord)
{
for (int i = 0; i < texturecoord.Length; i++)
{
SetTextureCoordData(i, texturecoord[i]);
}
}
///
/// configures vertex index to the vertex component data.
///
/// an index of the vertex component data
/// index value
public void SetIndexData(int index, short val)
{
indexData[index] = val;
}
///
/// configures vertex indicies to the vertex component data.
///
/// array of value
public void SetIndexData(short[] val)
{
for (int i = 0; i < val.Length; i++)
{
SetIndexData(i, val[i]);
}
}
///
/// binds the vertex component data to the vertex buffer.
///
public void BindVertexBuffer()
{
// Set vertex buffer
vertexBuffer.SetData(vertexData);
}
///
/// binds the index values to the index buffer.
///
public void BindIndexBuffer()
{
// Set index buffer
indexBuffer.SetData(indexData);
}
}
}