Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to Implement SkyBox in my phone game. Most of the samples in the web are for HiDef profile, and they are using custom effects (that not supported on Windows Phone). I've tried to follow this guide. But for some reason my SkyBox is not rendered.

This is my SkyBox class:

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Rocuna.Core;
using Rocuna.GameEngine.Graphics;
using Rocuna.GameEngine.Graphics.Components;

namespace Rocuna.GameEngine.Extension.WP7.Graphics
{
    /// <summary>
    /// Sky box element for phone games.
    /// </summary>
    public class SkyBox : SkyBoxBase
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="SkyBoxBase"/> class.
        /// </summary>
        /// <param name="game">The Game that the game component should be attached to.</param>
        public SkyBox(TextureCube cube, Game game)
            : base(game)
        {
            Cube = cube;
            CubeFaces = new Texture2D[6];
            PositionOffset = new Vector3(20, 20, 20);
            CreateGraphic(512);
            StripTexturesFromCube();
            InitializeData(Game.GraphicsDevice);
        }

        #region Properties

        /// <summary>
        /// Gets or sets the position offset.
        /// </summary>
        /// <value>
        /// The position offset.
        /// </value>
        public Vector3 PositionOffset { get; set; }

        /// <summary>
        /// Gets or sets the position.
        /// </summary>
        /// <value>
        /// The position.
        /// </value>
        public Vector3 Position { get; set; }

        /// <summary>
        /// Gets or sets the cube.
        /// </summary>
        /// <value>
        /// The cube.
        /// </value>
        public TextureCube Cube { get; set; }

        /// <summary>
        /// Gets or sets the pixel array.
        /// </summary>
        /// <value>
        /// The pixel array.
        /// </value>
        public Color[] PixelArray { get; set; }

        /// <summary>
        /// Gets or sets the cube faces.
        /// </summary>
        /// <value>
        /// The cube faces.
        /// </value>
        public Texture2D[] CubeFaces { get; set; }

        /// <summary>
        /// Gets or sets the vertex buffer.
        /// </summary>
        /// <value>
        /// The vertex buffer.
        /// </value>
        public VertexBuffer VertexBuffer { get; set; }

        /// <summary>
        /// Gets or sets the index buffer.
        /// </summary>
        /// <value>
        /// The index buffer.
        /// </value>
        public IndexBuffer IndexBuffer { get; set; }

        /// <summary>
        /// Gets or sets the effect.
        /// </summary>
        /// <value>
        /// The effect.
        /// </value>
        public BasicEffect Effect { get; set; }

        #endregion

        protected override void LoadContent()
        {
        }

        public override void Update(GameTime gameTime)
        {
            var camera = Game.GetService<GraphicManager>().CurrentCamera;
            this.Position = camera.Position + PositionOffset;
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            DrawOrder = int.MaxValue;
            var graphics = Effect.GraphicsDevice;
            graphics.DepthStencilState = new DepthStencilState() { DepthBufferEnable = false };
            graphics.RasterizerState = new RasterizerState() { CullMode = CullMode.None };
            graphics.BlendState = new BlendState();
            graphics.SamplerStates[0] = SamplerState.AnisotropicClamp;

            graphics.SetVertexBuffer(VertexBuffer);
            graphics.Indices = IndexBuffer;

            Effect.Texture = CubeFaces[0];
            Effect.CurrentTechnique.Passes[0].Apply();
            graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _vertices.Count, 0, 2);

            Effect.Texture = CubeFaces[1];
            Effect.CurrentTechnique.Passes[0].Apply();
            graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _vertices.Count, 6, 2);

            Effect.Texture = CubeFaces[2];
            Effect.CurrentTechnique.Passes[0].Apply();
            graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _vertices.Count, 12, 2);

            Effect.Texture = CubeFaces[3];
            Effect.CurrentTechnique.Passes[0].Apply();
            graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _vertices.Count, 18, 2);

            Effect.Texture = CubeFaces[4];
            Effect.CurrentTechnique.Passes[0].Apply();
            graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _vertices.Count, 24, 2);

            Effect.Texture = CubeFaces[5];
            Effect.CurrentTechnique.Passes[0].Apply();
            graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _vertices.Count, 30, 2);
            base.Draw(gameTime);
        }

        #region Fields

        private List<VertexPositionNormalTexture> _vertices = new List<VertexPositionNormalTexture>();

        private List<ushort> _indices = new List<ushort>();

        #endregion

        #region Private methods

        private void InitializeData(GraphicsDevice graphicsDevice)
        {
            VertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionNormalTexture), _vertices.Count,
                BufferUsage.None);
            VertexBuffer.SetData<VertexPositionNormalTexture>(_vertices.ToArray());

            // Create an index buffer, and copy our index data into it.
            IndexBuffer = new IndexBuffer(graphicsDevice, typeof(ushort),
                                          _indices.Count, BufferUsage.None);

            IndexBuffer.SetData<ushort>(_indices.ToArray());

            // Create a BasicEffect, which will be used to render the primitive.
            Effect = new BasicEffect(graphicsDevice);

            Effect.TextureEnabled = true;

            Effect.EnableDefaultLighting();
        }

        private void CreateGraphic(float size)
        {
            Vector3[] normals = {
                                    Vector3.Right,
                                    Vector3.Left,
                                    Vector3.Up,
                                    Vector3.Down,
                                    Vector3.Backward,
                                    Vector3.Forward,
                                };
            Vector2[] textureCoordinates = {
                                               Vector2.One, Vector2.UnitY, Vector2.Zero, Vector2.UnitX,
                                               Vector2.Zero, Vector2.UnitX, Vector2.One, Vector2.UnitY,
                                               Vector2.Zero, Vector2.UnitX, Vector2.One, Vector2.UnitY,
                                               Vector2.Zero, Vector2.UnitX, Vector2.One, Vector2.UnitY,
                                               Vector2.UnitY, Vector2.Zero, Vector2.UnitX, Vector2.One,
                                               Vector2.UnitY, Vector2.Zero, Vector2.UnitX, Vector2.One,
                                           };
            var index = 0;
            foreach (var normal in normals)
            {
                var side1 = new Vector3(normal.Z, normal.X, normal.Y);
                var side2 = Vector3.Cross(normal, side1);

                AddIndex(CurrentVertex + 0);
                AddIndex(CurrentVertex + 1);
                AddIndex(CurrentVertex + 2);

                AddIndex(CurrentVertex + 0);
                AddIndex(CurrentVertex + 2);
                AddIndex(CurrentVertex + 3);

                AddVertex((normal - side1 - side2) * size / 2, normal, textureCoordinates[index++]);
                AddVertex((normal - side1 + side2) * size / 2, normal, textureCoordinates[index++]);
                AddVertex((normal + side1 + side2) * size / 2, normal, textureCoordinates[index++]);
                AddVertex((normal + side1 - side2) * size / 2, normal, textureCoordinates[index++]);
            }
        }

        protected void StripTexturesFromCube()
        {
            PixelArray = new Color[Cube.Size * Cube.Size];

            for (int s = 0; s < CubeFaces.Length; s++)
            {
                CubeFaces[s] = new Texture2D(Game.GraphicsDevice, Cube.Size, Cube.Size, false, SurfaceFormat.Color);
                switch (s)
                {
                    case 0:
                        Cube.GetData<Color>(CubeMapFace.PositiveX, PixelArray);
                        CubeFaces[s].SetData<Color>(PixelArray);
                        break;
                    case 1:
                        Cube.GetData(CubeMapFace.NegativeX, PixelArray);
                        CubeFaces[s].SetData(PixelArray);
                        break;
                    case 2:
                        Cube.GetData(CubeMapFace.PositiveY, PixelArray);
                        CubeFaces[s].SetData(PixelArray);
                        break;
                    case 3:
                        Cube.GetData(CubeMapFace.NegativeY, PixelArray);
                        CubeFaces[s].SetData(PixelArray);
                        break;
                    case 4:
                        Cube.GetData(CubeMapFace.PositiveZ, PixelArray);
                        CubeFaces[s].SetData(PixelArray);
                        break;
                    case 5:
                        Cube.GetData(CubeMapFace.NegativeZ, PixelArray);
                        CubeFaces[s].SetData(PixelArray);
                        break;
                }
            }
        }

        protected void AddVertex(Vector3 position, Vector3 normal, Vector2 textureCoordinates)
        {
            _vertices.Add(new VertexPositionNormalTexture(position, normal, textureCoordinates));
        }

        protected void AddIndex(int index)
        {
            if (index > ushort.MaxValue)
                throw new ArgumentOutOfRangeException("index");

            _indices.Add((ushort)index);
        }

        protected int CurrentVertex
        {
            get { return _vertices.Count; }
        }


        #endregion
    }
}
share|improve this question

migrated from stackoverflow.com Sep 21 '11 at 8:30

This question came from our site for professional and enthusiast programmers.

1  
The first thing I do when stumped on graphics not displaying right is debug with the Pix application to see if they're being drawn at all. Then you can check if the problem is related to setting the vertexbuffer data, or the skybox has been transformed in a way that it's not visible on the screen. –  ChrisC Sep 20 '11 at 19:29
    
Another issue with Reach profile, is that you can only use textures that are multiples of two for certain tranformations. Depending on the error you are getting, ensure your texture is 2^n x 2^n –  Jon Nov 23 '11 at 19:47

1 Answer 1

You don't have set View/Projection/World of the effect. Try something like this in the draw method :

        Effect.View = xxxx.m_viewMatrix;
        Effect.Projection = xxxx..m_projMatrix;
        Effect.World = Matrix.Identity;
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.