開発環境 Microsoft Visual C# 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Windows Game (4.0)
プロジェクト名 ShaderInstancing

[ソリューションのディレクトリを作成]にチェックを付けないと.slnファイルが指定した場所の直下に作られる。

.fxファイルの追加方法
ソリューション エクスプローラーの(Content)を右クリックして[追加]-[新しい項目]を選択する。
テンプレート:Effect File

参考

Program.cs
namespace ShaderInstancing
{
    static class Program
    {
        static void Main()
        {
            using (Game1 game = new Game1())
            {
                game.Run();
            }
        }
    }
}
 

Game1.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
 
namespace ShaderInstancing
{
    struct VertexPositionColorIndex : IVertexType
    {
        public Vector3 Position;
        public Color Color;
        public float Index;
 
        static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration(
            new VertexElement(0,
                VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
            new VertexElement(sizeof(float) * 3,
                VertexElementFormat.Color, VertexElementUsage.Color, 0),
            new VertexElement(sizeof(float) * 3 + 4,
                VertexElementFormat.Single, VertexElementUsage.TextureCoordinate, 1));
 
        VertexDeclaration IVertexType.VertexDeclaration { get { return VertexDeclaration; } }
    }
 
    class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        Effect effect;
        VertexBuffer vertexBuffer;
 
        const int instanceCount = 10;
        VertexPositionColorIndex[] vertices = new VertexPositionColorIndex[3 * instanceCount];
        Matrix[] instanceTransforms = new Matrix[instanceCount];
 
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            IsMouseVisible = true;
 
            for (int i = 0; i < instanceCount; i++)
            {
                vertices[3 * i].Color = Color.Blue;
                vertices[3 * i].Position = new Vector3(-0.1f, 0.1f, 0);
                vertices[3 * i].Index = i;
 
                vertices[3 * i + 1].Color = Color.White;
                vertices[3 * i + 1].Position = new Vector3(0.1f, 0.1f, 0);
                vertices[3 * i + 1].Index = i;
 
                vertices[3 * i + 2].Color = Color.Red;
                vertices[3 * i + 2].Position = new Vector3(0.1f, -0.1f, 0);
                vertices[3 * i + 2].Index = i;
            }
 
            for (int i = 0; i < instanceTransforms.Length; i++)
            {
                instanceTransforms[i] = Matrix.CreateTranslation(0.1f * i, 0, 0);
            }
        }
 
        protected override void LoadContent()
        {
            effect = Content.Load<Effect>("ShaderInstancing");
 
            vertexBuffer = new VertexBuffer(GraphicsDevice,
                typeof(VertexPositionColorIndex), 3 * instanceCount, BufferUsage.None);
            vertexBuffer.SetData(vertices);
            GraphicsDevice.SetVertexBuffer(vertexBuffer);
 
            base.LoadContent();
        }
 
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
 
            effect.Parameters["InstanceTransforms"].SetValue(instanceTransforms);
 
            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, vertices.Length / 3);
            }
 
            base.Draw(gameTime);
        }
    }
}
 

ShaderInstancing.fx
float4x4 InstanceTransforms[10];
 
struct VertexPositionColor
{
	float4 Position : POSITION;
	float4 Color : COLOR;
};
 
VertexPositionColor VertexShaderFunction(
	VertexPositionColor input,
	float instanceIndex : TEXCOORD1)
{
	VertexPositionColor output;
	output.Position = mul(input.Position, InstanceTransforms[instanceIndex]);
	output.Color = input.Color;
	return output;
}
 
float4 PixelShaderFunction(float4 color : COLOR) : COLOR
{
	return color;
}
 
technique ShaderInstancing
{
	pass ShaderInstancingPass
	{
		VertexShader = compile vs_2_0 VertexShaderFunction();
		PixelShader = compile ps_2_0 PixelShaderFunction();
	}
}
 
最終更新:2012年11月29日 21:56