「VCS/XnaShader」の編集履歴(バックアップ)一覧に戻る

VCS/XnaShader - (2012/11/29 (木) 10:12:14) のソース

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

.fxファイルの追加方法
ソリューション エクスプローラーのContentに新しい項目を追加。
テンプレート:Effect File

ビルド時に以下のエラーが発生した場合
XNA Framework Reach profile does not support vertex shader model 3.0.

プロジェクトのプロパティを開く。
XNA Game Studioタブを選択する。
Game profileに[Use HiDef to access the complete API]を選択する。

参考
-[[プログラマブル・シェーダによる積極的なGPUの活用 - @IT>http://www.atmarkit.co.jp/fdotnet/directxworld/directxworld07/directxworld07_01.html]]

Program.cs
#highlight(c#){{
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

class Game1 : Game
{
	GraphicsDeviceManager graphics;
	VertexBuffer vb;
	Effect effect;

	// 頂点構造体
	struct MyVertex : IVertexType
	{
		Vector2 Position;
		Vector2 UV;
		public MyVertex(Vector2 position, Vector2 uv)
		{
			Position = position;
			UV = uv;
		}
		public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration(
			new VertexElement[] {
				new VertexElement(0, VertexElementFormat.Vector2,
					VertexElementUsage.Position, 0),
				new VertexElement(8, VertexElementFormat.Vector2,
					VertexElementUsage.TextureCoordinate, 0),
			});
		VertexDeclaration IVertexType.VertexDeclaration { get { return VertexDeclaration;} }
	}

	public Game1()
	{
		graphics = new GraphicsDeviceManager(this);
		Content.RootDirectory = "Content";
		Window.AllowUserResizing = true;
	}

	protected override void LoadContent()
	{
		const int numVertices = 4;
		vb = new VertexBuffer(GraphicsDevice, typeof(MyVertex), numVertices,
			BufferUsage.None);
		MyVertex[] vertices = new MyVertex[numVertices] {
			new MyVertex(new Vector2(-1.0f,  1.0f), new Vector2(0.0f, 1.0f)), // LU
			new MyVertex(new Vector2( 1.0f,  1.0f), new Vector2(1.0f, 1.0f)), // RU
			new MyVertex(new Vector2(-1.0f, -1.0f), new Vector2(0.0f, 0.0f)), // LD
			new MyVertex(new Vector2( 1.0f, -1.0f), new Vector2(1.0f, 0.0f)), // RD
		};
		vb.SetData(vertices);

		// ContentにSimple.fxを追加しておく
		effect = Content.Load<Effect>("Simple");

		base.LoadContent();
	}

	protected override void Draw(GameTime gameTime)
	{
		GraphicsDevice.Clear(Color.CornflowerBlue);

		GraphicsDevice.SetVertexBuffer(vb);
		foreach(EffectPass pass in effect.CurrentTechnique.Passes) {
			pass.Apply();
			GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
		}

		base.Draw(gameTime);
	}
}

class Program
{
	static void Main()
	{
		using (Game1 game = new Game1()) {
			game.IsMouseVisible = true;
			game.Run();
		}
	}
}
}}

Simple.fx
#highlight(c#){{
// 頂点シェーダ
struct VertexIn
{
	float2 Pos : POSITION;
	float2 UV : TEXCOORD0;
};

struct VertexOut
{
	float4 ScreenPos : POSITION;
	float2 UV : TEXCOORD0;
};

VertexOut MyVertexShader(VertexIn input)
{
	VertexOut output;
	output.ScreenPos = float4(input.Pos, 0.0f, 1.0f);
	output.UV = input.UV;
	return output;
}

// ピクセルシェーダ
struct PixelIn
{
	float2 UV : TEXCOORD0;
};

struct PixelOut
{
	float4 Color : COLOR0;
};

PixelOut MyPixelShader(PixelIn input)
{
	PixelOut output;
	output.Color = float4(input.UV, 0.0f, 1.0f);
	return output;
}

// レンダー
technique Render
{
	pass Pass0
	{
		VertexShader = compile vs_3_0 MyVertexShader();
		PixelShader = compile ps_3_0 MyPixelShader();
	}
}
}}