TexturedQuadGame.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. using System;
  2. using Microsoft.Xna.Framework;
  3. using Microsoft.Xna.Framework.Graphics;
  4. using Microsoft.Xna.Framework.Input;
  5. using Microsoft.Xna.Framework.Audio;
  6. using Microsoft.Xna.Framework.Content;
  7. using Microsoft.Xna.Framework.Input.Touch;
  8. using Microsoft.Xna.Framework.Media;
  9. namespace TexturedQuad
  10. {
  11. /// <summary>
  12. /// This is the main type for your game
  13. /// </summary>
  14. public class TexturedQuadGame : Game
  15. {
  16. GraphicsDeviceManager graphics;
  17. SpriteBatch spriteBatch;
  18. private SpriteFont font;
  19. VertexPositionNormalTexture[] cubeVertices;
  20. short[] cubeIndices;
  21. VertexBuffer vertexBuffer;
  22. IndexBuffer indexBuffer;
  23. int[] faceTextureIndices = new int[6];
  24. VertexDeclaration vertexDeclaration;
  25. Matrix View, Projection;
  26. Texture2D[] textures;
  27. BasicEffect cubeEffect;
  28. float rotation = 0f;
  29. KeyboardState previousKeyboardState;
  30. /// <summary>
  31. /// Initializes a new instance of the <see cref="TexturedQuadGame"/> class and sets up the graphics device manager and content root.
  32. /// </summary>
  33. public TexturedQuadGame()
  34. {
  35. graphics = new GraphicsDeviceManager(this);
  36. Content.RootDirectory = "Content";
  37. }
  38. /// <summary>
  39. /// Initializes the game, sets up the cube geometry, view, and projection matrices.
  40. /// </summary>
  41. protected override void Initialize()
  42. {
  43. // Set up cube geometry (24 vertices, 36 indices)
  44. cubeVertices = new VertexPositionNormalTexture[24];
  45. cubeIndices = new short[36];
  46. CreateCubeGeometry();
  47. vertexBuffer = new VertexBuffer(GraphicsDevice, VertexPositionNormalTexture.VertexDeclaration, 24, BufferUsage.WriteOnly);
  48. vertexBuffer.SetData(cubeVertices);
  49. indexBuffer = new IndexBuffer(GraphicsDevice, IndexElementSize.SixteenBits, 36, BufferUsage.WriteOnly);
  50. indexBuffer.SetData(cubeIndices);
  51. for (int i = 0; i < 6; i++) faceTextureIndices[i] = i % 4;
  52. View = Matrix.CreateLookAt(new Vector3(0, 0, 3), Vector3.Zero, Vector3.Up);
  53. Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 4.0f / 3.0f, 1, 500);
  54. base.Initialize();
  55. }
  56. /// <summary>
  57. /// Loads all game content, including the four textures and sets up the effect and vertex declaration.
  58. /// </summary>
  59. protected override void LoadContent()
  60. {
  61. spriteBatch = new SpriteBatch(GraphicsDevice);
  62. font = Content.Load<SpriteFont>("font");
  63. textures = new Texture2D[4];
  64. textures[0] = Content.Load<Texture2D>("Glass");
  65. textures[1] = Content.Load<Texture2D>("GlassPane");
  66. textures[2] = Content.Load<Texture2D>("GlassPane1");
  67. textures[3] = Content.Load<Texture2D>("GlassPane2");
  68. cubeEffect = new BasicEffect(graphics.GraphicsDevice);
  69. cubeEffect.World = Matrix.Identity;
  70. cubeEffect.View = View;
  71. cubeEffect.Projection = Projection;
  72. cubeEffect.TextureEnabled = true;
  73. vertexDeclaration = new VertexDeclaration(new VertexElement[]
  74. {
  75. new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
  76. new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
  77. new VertexElement(24, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
  78. }
  79. );
  80. }
  81. /// <summary>
  82. /// Updates the game logic, handles input for exiting, switching textures, and rotates the cube.
  83. /// </summary>
  84. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  85. protected override void Update(GameTime gameTime)
  86. {
  87. #if !__IOS__
  88. if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  89. this.Exit();
  90. if (Keyboard.GetState().IsKeyDown(Keys.Escape))
  91. this.Exit();
  92. #endif
  93. // Change texture on Space key release
  94. KeyboardState state = Keyboard.GetState();
  95. if ((state.IsKeyUp(Keys.Space) && previousKeyboardState.IsKeyDown(Keys.Space))
  96. || (GamePad.GetState(PlayerIndex.One).Buttons.A == ButtonState.Pressed))
  97. {
  98. // Advance the current texture index for all faces
  99. int next = (faceTextureIndices[0] + 1) % textures.Length;
  100. for (int i = 0; i < faceTextureIndices.Length; i++)
  101. faceTextureIndices[i] = next;
  102. }
  103. previousKeyboardState = state;
  104. // Rotate the cube
  105. rotation += (float)gameTime.ElapsedGameTime.TotalSeconds;
  106. base.Update(gameTime);
  107. }
  108. /// <summary>
  109. /// Draws the current frame, rendering the rotating cube with the selected texture on all faces.
  110. /// </summary>
  111. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  112. protected override void Draw(GameTime gameTime)
  113. {
  114. GraphicsDevice.Clear(Color.MonoGameOrange);
  115. Matrix world = Matrix.CreateRotationY(rotation) * Matrix.CreateRotationX(rotation * 0.7f);
  116. cubeEffect.View = View;
  117. cubeEffect.Projection = Projection;
  118. // All faces use the same texture (current index)
  119. int currentTexture = faceTextureIndices[0];
  120. cubeEffect.World = world;
  121. cubeEffect.Texture = textures[currentTexture];
  122. GraphicsDevice.SetVertexBuffer(vertexBuffer);
  123. GraphicsDevice.Indices = indexBuffer;
  124. foreach (EffectPass pass in cubeEffect.CurrentTechnique.Passes)
  125. {
  126. pass.Apply();
  127. GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 12);
  128. }
  129. spriteBatch.Begin();
  130. spriteBatch.DrawString(font, "Press Space to change texture", new Vector2(20, 20), Color.Black);
  131. spriteBatch.End();
  132. base.Draw(gameTime);
  133. }
  134. /// <summary>
  135. /// Creates the geometry for a unit cube centered at the origin.
  136. /// </summary>
  137. private void CreateCubeGeometry()
  138. {
  139. // 24 vertices (4 per face) so each face can have its own texture coordinates
  140. Vector3[] faceNormals = new Vector3[] {
  141. Vector3.Forward, Vector3.Backward, Vector3.Left, Vector3.Right, Vector3.Up, Vector3.Down
  142. };
  143. Vector3[][] faceVerts = new Vector3[][] {
  144. // Front
  145. new Vector3[] { new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(0.5f, 0.5f, 0.5f), new Vector3(0.5f, -0.5f, 0.5f), new Vector3(-0.5f, -0.5f, 0.5f) },
  146. // Back
  147. new Vector3[] { new Vector3(0.5f, 0.5f, -0.5f), new Vector3(-0.5f, 0.5f, -0.5f), new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(0.5f, -0.5f, -0.5f) },
  148. // Left
  149. new Vector3[] { new Vector3(-0.5f, 0.5f, -0.5f), new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(-0.5f, -0.5f, -0.5f) },
  150. // Right
  151. new Vector3[] { new Vector3(0.5f, 0.5f, 0.5f), new Vector3(0.5f, 0.5f, -0.5f), new Vector3(0.5f, -0.5f, -0.5f), new Vector3(0.5f, -0.5f, 0.5f) },
  152. // Top
  153. new Vector3[] { new Vector3(-0.5f, 0.5f, -0.5f), new Vector3(0.5f, 0.5f, -0.5f), new Vector3(0.5f, 0.5f, 0.5f), new Vector3(-0.5f, 0.5f, 0.5f) },
  154. // Bottom
  155. new Vector3[] { new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, -0.5f), new Vector3(-0.5f, -0.5f, -0.5f) }
  156. };
  157. Vector2[] texCoords = new Vector2[] {
  158. new Vector2(0,0), new Vector2(1,0), new Vector2(1,1), new Vector2(0,1)
  159. };
  160. for (int face = 0; face < 6; face++)
  161. {
  162. for (int v = 0; v < 4; v++)
  163. {
  164. cubeVertices[face * 4 + v] = new VertexPositionNormalTexture(
  165. faceVerts[face][v], faceNormals[face], texCoords[v]);
  166. }
  167. }
  168. // Indices for 12 triangles (2 per face)
  169. short[] inds = new short[] {
  170. 0,1,2, 0,2,3, // Front
  171. 4,5,6, 4,6,7, // Back
  172. 8,9,10, 8,10,11, // Left
  173. 12,13,14, 12,14,15,// Right
  174. 16,17,18, 16,18,19,// Top
  175. 20,21,22, 20,22,23 // Bottom
  176. };
  177. for (int i = 0; i < 36; i++) cubeIndices[i] = inds[i];
  178. }
  179. }
  180. }