「VCS/XnaSphere5」の編集履歴(バックアップ)一覧はこちら

VCS/XnaSphere5」(2012/12/15 (土) 10:37:08) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

|開発環境|Microsoft Visual C# 2010 Express (SP1)| |実行環境|Microsoft Windows XP Home Edition (SP3)| |プロジェクトの種類|Windows Game (4.0)| |プロジェクト名|XnaSphere| Game1.cs #highlight(c#){{ // XnaSphere5 - 再帰分割slerp+index using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; namespace XnaSphere { class Game1 : Game { GraphicsDeviceManager graphics; SpriteBatch sprite; SpriteFont font; BasicEffect effect; VertexBuffer vertexBuffer; IndexBuffer indexBuffer; List<VertexPositionColor> vtxList = new List<VertexPositionColor>(); List<short> idxList = new List<short>(); const int level = 4; // fps int sec; int draw = 0; int fps = 0; // カメラ int camLat = 0; int camLong = 90; float camDist = 5; public Game1() { graphics = new GraphicsDeviceManager(this); graphics.PreferredBackBufferWidth = 1280; graphics.PreferredBackBufferHeight = 720; Content.RootDirectory = "Content"; IsMouseVisible = true; } protected override void LoadContent() { font = Content.Load<SpriteFont>("SpriteFont1"); sprite = new SpriteBatch(GraphicsDevice); effect = new BasicEffect(GraphicsDevice); //effect.EnableDefaultLighting(); effect.Projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians(45), GraphicsDevice.Viewport.AspectRatio, 1, 100); // 頂点バッファ Vector3[] pos = { Vector3.Up, Vector3.Right, Vector3.Backward, Vector3.Left, Vector3.Forward, Vector3.Down }; int[] idx = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 1, 5, 2, 1, 5, 3, 2, 5, 4, 3, 5, 1, 4 }; for (int n = 0; n < idx.Length; n += 3) { GenerateTriangle(level, pos[idx[n]], pos[idx[n + 1]], pos[idx[n + 2]]); } vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor), vtxList.Count, BufferUsage.WriteOnly); vertexBuffer.SetData(vtxList.ToArray()); indexBuffer = new IndexBuffer(GraphicsDevice, typeof(short), idxList.Count, BufferUsage.WriteOnly); indexBuffer.SetData(idxList.ToArray()); base.LoadContent(); } void GenerateTriangle(int lv, Vector3 p1, Vector3 p2, Vector3 p3) { if (lv-- <= 0) { AddVertex(p1); AddVertex(p2); AddVertex(p3); return; } Vector3 p4 = QV(Quaternion.Slerp(new Quaternion(p1, 0), new Quaternion(p2, 0), 0.5f)); Vector3 p5 = QV(Quaternion.Slerp(new Quaternion(p2, 0), new Quaternion(p3, 0), 0.5f)); Vector3 p6 = QV(Quaternion.Slerp(new Quaternion(p3, 0), new Quaternion(p1, 0), 0.5f)); GenerateTriangle(lv, p1, p4, p6); GenerateTriangle(lv, p2, p5, p4); GenerateTriangle(lv, p3, p6, p5); GenerateTriangle(lv, p4, p5, p6); } void AddVertex(Vector3 pos) { for (int n = 0; n < vtxList.Count; n++) { if ((pos - vtxList[n].Position).Length() < 0.00001f) { idxList.Add((short)n); return; } } vtxList.Add(new VertexPositionColor(pos, (vtxList.Count & 1) == 0 ? Color.Red : Color.Yellow)); idxList.Add((short)(vtxList.Count - 1)); } Vector3 QV(Quaternion q) { return new Vector3(q.X, q.Y, q.Z); } protected override void Update(GameTime gameTime) { KeyboardState kState = Keyboard.GetState(); if (kState.IsKeyDown(Keys.Escape)) Exit(); 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)) camLong = (camLong + 1) % 360; if (kState.IsKeyDown(Keys.Right)) camLong = (camLong + 359) % 360; if (kState.IsKeyDown(Keys.PageUp)) camDist -= 0.1f; if (kState.IsKeyDown(Keys.PageDown)) camDist += 0.1f; base.Update(gameTime); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); GraphicsDevice.DepthStencilState = DepthStencilState.Default; // カメラ位置 float rad = MathHelper.ToRadians(camLat); float y = (float)Math.Sin(rad) * camDist; float r = (float)Math.Cos(rad) * camDist; rad = MathHelper.ToRadians(camLong); float x = (float)Math.Cos(rad) * r; float z = (float)Math.Sin(rad) * r; effect.View = Matrix.CreateLookAt(new Vector3(x, y, z), Vector3.Zero, Vector3.Up); GraphicsDevice.SetVertexBuffer(vertexBuffer); GraphicsDevice.Indices = indexBuffer; foreach (EffectPass pass in effect.CurrentTechnique.Passes) { GraphicsDevice.RasterizerState = new RasterizerState { FillMode = FillMode.WireFrame }; effect.World = Matrix.CreateTranslation(-1, 0, 0); effect.VertexColorEnabled = false; pass.Apply(); GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertexBuffer.VertexCount, 0, indexBuffer.IndexCount / 3); GraphicsDevice.RasterizerState = new RasterizerState { FillMode = FillMode.Solid }; effect.World = Matrix.CreateTranslation(1, 0, 0); effect.VertexColorEnabled = true; pass.Apply(); GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertexBuffer.VertexCount, 0, indexBuffer.IndexCount / 3); } // fps draw++; if (gameTime.TotalGameTime.Seconds != sec) { fps = draw; draw = 0; sec = gameTime.TotalGameTime.Seconds; } sprite.Begin(); string text = String.Format( "fps={0} lat={1} long={2} dist={3:f1}", fps, camLat, camLong, camDist); sprite.DrawString(font, text, new Vector2(0, 0), Color.White); text = String.Format("lv={0} vtx={1} idx={2}", level, vertexBuffer.VertexCount, indexBuffer.IndexCount); sprite.DrawString(font, text, new Vector2(0, 20), Color.White); sprite.End(); base.Draw(gameTime); } } } }}

表示オプション

横に並べて表示:
変化行の前後のみ表示: