開発環境 |
Microsoft Visual C# 2010 Express (SP1) |
実行環境 |
Microsoft Windows XP Home Edition (SP3) |
プロジェクトの種類 |
Windows Game (4.0) |
プロジェクト名 |
XnaHwiMesh |
参考
Game1.cs
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace XnaHwiMesh
{
struct VertexPosition : IVertexType
{
public Vector3 Position;
public VertexPosition(Vector3 position)
{
Position = position;
}
static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration(
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0)
);
VertexDeclaration IVertexType.VertexDeclaration { get { return VertexDeclaration; } }
}
class Game1 : Game
{
GraphicsDeviceManager graphics;
Effect effect;
Model model;
VertexBuffer instanceDataStream;
Vector3 CameraPos;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void LoadContent()
{
effect = Content.Load<Effect>("CustomEffect");
model = Content.Load<Model>("Box");
CameraPos = new Vector3(10, 10, 10);
effect.Parameters["World"].SetValue(Matrix.Identity);
effect.Parameters["View"].SetValue(Matrix.CreateLookAt(
CameraPos, Vector3.Zero, Vector3.Up));
effect.Parameters["Projection"].SetValue(Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45), GraphicsDevice.Viewport.AspectRatio, 1, 100));
effect.Parameters["LightPos"].SetValue(Vector3.Up);
effect.Parameters["ambient"].SetValue(new Vector3(0, 0.0543f, 0.526f));
effect.Parameters["diffuselight"].SetValue(new Vector3(1, 1, 1));
foreach (var mesh in model.Meshes)
{
foreach (var mpart in mesh.MeshParts)
{
mpart.Effect = effect;
}
}
VertexPosition[] vp = new VertexPosition[2];
vp[0] = new VertexPosition(Vector3.Zero);
vp[1] = new VertexPosition(new Vector3(0, 2, 0));
instanceDataStream = new VertexBuffer(GraphicsDevice,
typeof(VertexPosition), 2, BufferUsage.WriteOnly);
instanceDataStream.SetData(vp);
base.LoadContent();
}
protected override void Update(GameTime gameTime)
{
KeyboardState state = Keyboard.GetState();
if (state[Keys.Escape] == KeyState.Down) Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
foreach (var mesh in model.Meshes)
{
MeshDraw(mesh);
}
base.Draw(gameTime);
}
VertexDeclaration CreateVertexDeclaration(VertexElement[] MeshPartElements)
{
List<VertexElement> elements = new List<VertexElement>();
foreach (VertexElement vElement in MeshPartElements)
{
elements.Add(vElement);
}
elements.Add(new VertexElement(
1, VertexElementFormat.Vector3, VertexElementUsage.Position, 1));
return new VertexDeclaration(elements.ToArray());
}
void MeshDraw(ModelMesh mesh)
{
foreach (ModelMeshPart mpart in mesh.MeshParts)
{
Effect effect = mpart.Effect;
foreach (var pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
if (0 < mpart.NumVertices)
{
VertexBufferBinding[] bindings;
bindings = new VertexBufferBinding[2];
bindings[0] = new VertexBufferBinding(mpart.VertexBuffer, 0);
bindings[1] = new VertexBufferBinding(instanceDataStream, 0, 1);
GraphicsDevice.SetVertexBuffers(bindings);
GraphicsDevice.Indices = mpart.IndexBuffer;
GraphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0,
mpart.NumVertices, mpart.StartIndex, mpart.PrimitiveCount, 2);
}
}
}
}
}
}
CustomEffect.fx
float4x4 World;
float4x4 View;
float4x4 Projection;
float3 LightPos;
float3 ambient : AMBIENT;
float3 diffuselight : DIFFUSE;
struct VertexShaderInput
{
float4 Position : POSITION0;
float3 Normal : Normal0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float3 Normal : Normal0;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input, float3 transform : POSITION1)
{
VertexShaderOutput output;
float4 worldPosition = mul(input.Position + float4(transform, 0), World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.Normal = mul(float4(input.Normal, 1), World);
output.Normal = normalize(output.Normal);
return output;
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
return float4(ambient + diffuselight * saturate(dot(input.Normal, normalize(LightPos))), 1);
}
technique Technique1
{
pass Pass0
{
VertexShader = compile vs_3_0 VertexShaderFunction();
PixelShader = compile ps_3_0 PixelShaderFunction();
}
}
最終更新:2012年12月08日 20:38