|開発環境|Microsoft Visual C# 2010 Express (SP1)| |実行環境|Microsoft Windows XP Home Edition (SP3)| |プロジェクトの種類|Windows Game (4.0)| |プロジェクト名|XnaTexture2D| +スクロール +半球 参考 -[[Planet Earth Texture Maps>http://planetpixelemporium.com/earth.html]] Game1.cs #highlight(c#){{ // XnaTexture2D3 緯経修正 using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; namespace XnaTexture2D { class Game1 : Game { GraphicsDeviceManager graphics; SpriteBatch sprite; SpriteFont font; VertexBuffer vertexBuffer; Effect effect; BasicEffect basicEffect; Texture2D texture; VertexPositionColor[] cross; EffectParameter fxLat; EffectParameter fxLon; EffectParameter fxScale; float lat = 0; float lon = 135; float scale = 1; // fps int fpsSec; int fpsDraw = 0; int fpsCount = 0; 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"); texture = Content.Load<Texture2D>("earthmap1k"); effect = Content.Load<Effect>("Effect1"); effect.Parameters["WorldMap"].SetValue(texture); effect.Parameters["aspect"].SetValue(GraphicsDevice.Viewport.AspectRatio); fxLat = effect.Parameters["lat"]; fxLon = effect.Parameters["lon"]; fxScale = effect.Parameters["scale"]; fxLat.SetValue(lat / 180); fxLon.SetValue(lon / 360); fxScale.SetValue(scale); basicEffect = new BasicEffect(GraphicsDevice); // 地図 VertexPositionTexture[] vertices = new VertexPositionTexture[4]; vertices[0] = new VertexPositionTexture(new Vector3(-1, 1, 0), new Vector2(0, 0)); vertices[1] = new VertexPositionTexture(new Vector3(1, 1, 0), new Vector2(1, 0)); vertices[2] = new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0, 1)); vertices[3] = new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1, 1)); vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionTexture), 4, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); // 照準 cross = new VertexPositionColor[4]; cross[0] = new VertexPositionColor(new Vector3(-0.05f, 0, 0), Color.White); cross[1] = new VertexPositionColor(new Vector3(0.05f, 0, 0), Color.White); cross[2] = new VertexPositionColor(new Vector3(0, -0.1f, 0), Color.White); cross[3] = new VertexPositionColor(new Vector3(0, 0.1f, 0), Color.White); base.LoadContent(); } protected override void Update(GameTime gameTime) { float deltaLat = 0; float deltaLon = 0; float deltaScale = 0; KeyboardState kState = Keyboard.GetState(); if (kState.IsKeyDown(Keys.Escape)) Exit(); if (kState.IsKeyDown(Keys.Up)) deltaLat = 1; if (kState.IsKeyDown(Keys.Down)) deltaLat = -1; if (kState.IsKeyDown(Keys.Left)) deltaLon = -1; if (kState.IsKeyDown(Keys.Right)) deltaLon = 1; if (kState.IsKeyDown(Keys.PageUp)) deltaScale = 0.1f; if (kState.IsKeyDown(Keys.PageDown)) deltaScale -= 0.1f; if (deltaLat != 0) { lat = MathHelper.Clamp(lat + deltaLat / scale, -89.9f, 89.9f); fxLat.SetValue(lat / 180); // -0.5 - 0.5 } if (deltaLon != 0) { lon += deltaLon / scale; if (lon <= -180) lon += 360; if (180 < lon) lon -= 360; fxLon.SetValue(lon / 360); // -0.5 - 0.5 } if (deltaScale != 0) { scale = MathHelper.Clamp(scale + deltaScale, 1, 5); fxScale.SetValue(scale); } base.Update(gameTime); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); GraphicsDevice.SamplerStates[0] = SamplerState.LinearClamp; GraphicsDevice.SetVertexBuffer(vertexBuffer); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); } foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) { pass.Apply(); GraphicsDevice.DrawUserPrimitives(PrimitiveType.LineList, cross, 0, 2); } // fps fpsDraw++; if (gameTime.TotalGameTime.Seconds != fpsSec) { fpsCount = fpsDraw; fpsDraw = 0; fpsSec = gameTime.TotalGameTime.Seconds; } sprite.Begin(); string text = string.Format("fps={0} lat={1:f1} lon={2:f1} scale={3:f1}", fpsCount, lat, lon, scale); sprite.DrawString(font, text, new Vector2(0, 0), Color.Red); sprite.End(); base.Draw(gameTime); } } } }} Effect1.fx #highlight(){{ // XnaTexture2D3 スクロール texture WorldMap; float lat; float lon; float aspect; // 未使用 float scale; sampler TextureSampler = sampler_state { texture = <WorldMap>; minfilter = linear; magfilter = linear; }; struct VertexShaderInput { float4 Position : POSITION0; float2 TexCoord : TEXCOORD0; }; struct VertexShaderOutput { float4 Position : POSITION0; float2 TexCoord : TEXCOORD0; }; VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; output.Position = input.Position; output.TexCoord = input.TexCoord; return output; } float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { float x = input.TexCoord.x * 2.0f - 1.0f; // -1 - 1 float y = input.TexCoord.y * 2.0f - 1.0f; // -1 - 1 float2 t; t.x = frac((x / scale + 1.0f) * 0.5f + lon); t.y = abs((y / scale + 1.0f) * 0.5f - lat); if (1.0f < t.y) { t.y = 2.0f - t.y; } return tex2D(TextureSampler, t); } technique Technique1 { pass Pass1 { VertexShader = compile vs_2_0 VertexShaderFunction(); PixelShader = compile ps_2_0 PixelShaderFunction(); } } }} Effect1.fx #highlight(){{ // XnaTexture2D3 半球 texture WorldMap; float lat; // 未使用 float lon; float aspect; float scale; // 未使用 sampler TextureSampler = sampler_state { texture = <WorldMap>; minfilter = linear; magfilter = linear; }; struct VertexShaderInput { float4 Position : POSITION0; float2 TexCoord : TEXCOORD0; }; struct VertexShaderOutput { float4 Position : POSITION0; float2 TexCoord : TEXCOORD0; }; VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; output.Position = input.Position; output.TexCoord = input.TexCoord; return output; } float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { float x = input.TexCoord.x * 2.0f - 1.0f; // -1 - 1 float y = input.TexCoord.y * 2.0f - 1.0f; // -1 - 1 float width = sqrt(1.0f - y * y); x *= aspect; if (width < abs(x) || width <= 0.0f) { discard; } float2 t; t.x = frac((0.5f * x / width + 1.0f) * 0.5f + lon); t.y = input.TexCoord.y; return tex2D(TextureSampler, t); } technique Technique1 { pass Pass1 { VertexShader = compile vs_2_0 VertexShaderFunction(); PixelShader = compile ps_2_0 PixelShaderFunction(); } } }}