開発環境 |
Microsoft Visual C# 2010 Express (SP1) |
実行環境 |
Microsoft Windows XP Home Edition (SP3) |
プロジェクトの種類 |
Windows Game (4.0) |
プロジェクト名 |
XnaHwiModel |
CustomVertex.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace CustomVertex
{
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; } }
}
}
Game1.cs
/*
* プロジェクト/プロパティ
* [XNA Game Studio]タブ
* Use HiDef to access the complete API
*/
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using CustomVertex;
namespace XnaHwiModel
{
class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch sprite;
SpriteFont font;
Model model;
Effect effect;
VertexBuffer instanceDataStream;
// fps
int sec;
int draw = 0;
int fps = 0;
// カメラ
Vector3 camPos = new Vector3(-10, 0, -10);
float camLat = 30;
float camLon = 45;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void LoadContent()
{
sprite = new SpriteBatch(GraphicsDevice);
font = Content.Load<SpriteFont>("SpriteFont1");
//model = Content.Load<Model>("aircraft");
model = Content.Load<Model>("dice6");
effect = Content.Load<Effect>("Effect1");
effect.Parameters["World"].SetValue(Matrix.Identity);
effect.Parameters["Projection"].SetValue(Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45), GraphicsDevice.Viewport.AspectRatio, 0.1f, 1000));
int n = 20;
VertexPosition[] vp = new VertexPosition[n * n * n];
int i = 0;
for (int y = 0; y < n; y++)
{
for (int x = 0; x < n; x++)
{
for (int z = 0; z < n; z++)
{
vp[i++] = new VertexPosition(new Vector3(x * 15, y * 5, z * 15));
}
}
}
instanceDataStream = new VertexBuffer(GraphicsDevice,
typeof(VertexPosition), vp.Length, BufferUsage.WriteOnly);
instanceDataStream.SetData(vp);
base.LoadContent();
}
protected override void Update(GameTime gameTime)
{
KeyboardState kState = Keyboard.GetState();
if (kState.IsKeyDown(Keys.Escape)) Exit();
if (kState.IsKeyDown(Keys.W)) Move(0, 0);
if (kState.IsKeyDown(Keys.S)) Move(180, 0);
if (kState.IsKeyDown(Keys.A)) Move(0, -90);
if (kState.IsKeyDown(Keys.D)) Move(0, 90);
if (kState.IsKeyDown(Keys.Up)) camLat = Math.Min(camLat + 1, 89);
if (kState.IsKeyDown(Keys.Down)) camLat = Math.Max(camLat - 1, -89);
if (kState.IsKeyDown(Keys.Left)) camLon = (camLon + 359) % 360;
if (kState.IsKeyDown(Keys.Right)) camLon = (camLon + 1) % 360;
if (kState.IsKeyDown(Keys.PageUp)) Move(90, 0);
if (kState.IsKeyDown(Keys.PageDown)) Move(-90, 0);
base.Update(gameTime);
}
private void Move(int lat, int lon)
{
float rad = MathHelper.ToRadians(camLat + lat);
float y = (float)Math.Sin(rad) * 0.2f;
float r = (float)Math.Cos(rad) * 0.2f;
if (lon == 0) camPos.Y += y;
rad = MathHelper.ToRadians(camLon + lon);
camPos.X += (float)Math.Cos(rad) * r;
camPos.Z += (float)Math.Sin(rad) * r;
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.BlendState = BlendState.AlphaBlend;
//GraphicsDevice.RasterizerState = new RasterizerState { FillMode = FillMode.WireFrame};
// カメラ位置
float rad = MathHelper.ToRadians(camLat);
float y = (float)Math.Sin(rad);
float r = (float)Math.Cos(rad);
rad = MathHelper.ToRadians(camLon);
float x = (float)Math.Cos(rad) * r;
float z = (float)Math.Sin(rad) * r;
Matrix view = Matrix.CreateLookAt(camPos, camPos + new Vector3(x, y, z), Vector3.Up);
effect.Parameters["View"].SetValue(view);
foreach (ModelMesh mesh in model.Meshes)
{
MeshDraw(mesh);
}
// fps
draw++;
if (gameTime.TotalGameTime.Seconds != sec)
{
fps = draw;
draw = 0;
sec = gameTime.TotalGameTime.Seconds;
}
// 2D描画
sprite.Begin();
string text = String.Format("fps={0} lat={1:f0} long={2:f0}", fps, camLat, camLon);
sprite.DrawString(font, text, new Vector2(0, 0), Color.White);
text = String.Format("x={0:f0} y={1:f0} z={2:f0}", camPos.X, camPos.Y, camPos.Z);
sprite.DrawString(font, text, new Vector2(0, 20), Color.White);
sprite.End();
base.Draw(gameTime);
}
private void MeshDraw(ModelMesh mesh)
{
foreach (ModelMeshPart mpart in mesh.MeshParts)
{
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;
BasicEffect be = (BasicEffect)mpart.Effect;
if (be.TextureEnabled)
{
effect.CurrentTechnique = effect.Techniques["TechTexture"];
effect.Parameters["Texture"].SetValue(be.Texture);
}
else
{
effect.CurrentTechnique = effect.Techniques["TechColor"];
effect.Parameters["Color"].SetValue(be.DiffuseColor);
}
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList,
mpart.VertexOffset, 0, mpart.NumVertices, mpart.StartIndex,
mpart.PrimitiveCount, instanceDataStream.VertexCount);
}
}
}
}
}
Effect1.fx
float4x4 World;
float4x4 View;
float4x4 Projection;
float3 Color : COLOR0;
texture Texture;
sampler TextureSampler = sampler_state
{
texture = <Texture>;
mipfilter = linear;
minfilter = linear;
magfilter = linear;
};
struct VS_Input
{
float4 Position : POSITION0;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
struct VS_ColorOutput
{
float4 Position : POSITION0;
float4 Color : COLOR0;
};
struct VS_TextureOutput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
};
VS_ColorOutput VS_Color(VS_Input input, float3 transform : POSITION1)
{
VS_ColorOutput output;
float4 worldPosition = mul(input.Position + float4(transform, 0), World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.Color = float4(Color, 1.0f);
return output;
}
VS_TextureOutput VS_Texture(VS_Input input, float3 transform : POSITION1)
{
VS_TextureOutput output;
float4 worldPosition = mul(input.Position + float4(transform, 0), World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.TexCoord = input.TexCoord;
return output;
}
float4 PS_Color(float4 color : COLOR0) : COLOR0
{
return color;
}
float4 PS_Texture(float2 texCoord : TEXCOORD0) : COLOR0
{
return tex2D(TextureSampler, texCoord);
}
technique TechColor
{
pass Pass1
{
VertexShader = compile vs_3_0 VS_Color();
PixelShader = compile ps_3_0 PS_Color();
}
}
technique TechTexture
{
pass Pass1
{
VertexShader = compile vs_3_0 VS_Texture();
PixelShader = compile ps_3_0 PS_Texture();
}
}
最終更新:2012年12月28日 20:49