Skybox on Windows Phone 7


When we have no custom shader, we need to make some sort of little magics to create usual effects like Skybox. This Small post will show a way to simulate this visual effect on Windows Phone 7.
The trick is actually very simple, we just “extract” all the textures from the cube map texture (normally we feed it to a shader that would sample it with the eye vector, but we dont have custom shaders …) and draw all of then each frame (transformed by the camera matrices).

Before showing the code, i need to make some things clear =P.
I used some render functions of PloobsEngine (to hold graphics state, create graphics resources …., tried to use it as little as possible), the functions names used says what is being done, so it is very easy to convert it to plain XNA.

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Features
{
    public class SkyBox
    {
        String textureCubeName;
        bool enable = false;        

        public void Initialize(String texCubeName)
        {
            Cube = GraphicFactory.GetTextureCube(texCubeName);
            CubeFaces = new Texture2D[6];
            PositionOffset = new Vector3(20, 20, 20);
            CreateGraphic(512);
            StripTexturesFromCube();
            InitializeData();
        }       

        #region Properties
        GraphicFactory GraphicFactory;
        public Vector3 PositionOffset { get; set; }
        public Vector3 Position { get; set; }
        public TextureCube Cube { get; set; }
        public Color[] PixelArray { get; set; }
        public Texture2D[] CubeFaces { get; set; }
        public VertexBuffer VertexBuffer { get; set; }
        public IndexBuffer IndexBuffer { get; set; }
        public BasicEffect Effect { get; set; }
        #endregion

        #region Fields

        private List _vertices = new List();
        private List _indices = new List();
        #endregion

        #region Private methods
        private void InitializeData()
        {
            VertexBuffer = GraphicFactory.CreateVertexBuffer(VertexPositionNormalTexture.VertexDeclaration, _vertices.Count, BufferUsage.None);
            VertexBuffer.SetData(_vertices.ToArray());
            IndexBuffer = GraphicFactory.CreateIndexBuffer(IndexElementSize.SixteenBits, _indices.Count, BufferUsage.None);
            IndexBuffer.SetData(_indices.ToArray());
            Effect = GraphicFactory.GetBasicEffect();
            Effect.TextureEnabled = true;
        }

        ///just a fancy quad
        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] = GraphicFactory.CreateTexture2D(Cube.Size, Cube.Size, false, SurfaceFormat.Color);
                switch (s)
                {
                    case 0:
                        Cube.GetData(CubeMapFace.PositiveX, PixelArray);
                        CubeFaces[s].SetData(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

        public void PreDraw(RenderHelper render, GameTime gt, ref Matrix activeView, ref Matrix activeProjection, Vector3 CamPos)
        {
            if (!enable || Cube == null)
                return;

            Vector3 position = camPos

            this.Position = position + PositionOffset;
            Effect.View = activeView;
            Effect.Projection = activeProjection;
            Effect.World = Matrix.CreateTranslation(this.Position);

            render.PushDepthStencilState(new DepthStencilState() { DepthBufferEnable = false });
            render.PushRasterizerState(new RasterizerState() { CullMode = CullMode.None });

            var graphics = Effect.GraphicsDevice;
            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);

            render.PopDepthStencilState();
            render.PopRasterizerState();

        }
    }
}

You need to call the draw function before all 3D drawing !!!

As always code is not optimized and some stuffs are hardcoded.

  1. #1 by Isin4d on 22 de junho de 2017 - 1:32 pm

    Thanks to my father who stated to me concerning this web site,
    this web site is truly remarkable.

  2. #2 by Strategies_To_Come_Across_The_Perfect_Option_Regarding_Seeing_Movies_Online_Very_Fast on 22 de junho de 2017 - 1:33 pm

    Hello mates, how is everything, and what you wish for to say about this
    post, in my view its really amazing designed for
    me.

  3. #3 by 123movies on 22 de junho de 2017 - 1:45 pm

    It’s genuinely very complex in this full of activity life
    to listen news on TV, therefore I only use
    the web for that purpose, and take the latest information.

  4. #4 by katies on 22 de junho de 2017 - 2:03 pm

    synedrex diet pills where to buy in tulsa ok where can u buy

  5. #5 by Home Product and Service on 22 de junho de 2017 - 2:11 pm

    Hello, you used to write magnificent, but the last several posts have been kinda boring¡K I miss your tremendous writings. Past few posts are just a bit out of track! come on!

  6. #6 by empfehlen sie gelesen on 22 de junho de 2017 - 2:20 pm

    Also werden wir sofortwichsen.

  7. #7 by katies on 22 de junho de 2017 - 3:17 pm

    fibre trim diet pills 1988 olympics gymnastics results

  8. #8 by 123movies on 22 de junho de 2017 - 3:28 pm

    Very soon this site will be famous amid all blogging users, due to it’s good articles

  9. #9 by 123 movies on 22 de junho de 2017 - 3:41 pm

    Wow, fantastic weblog structure! How lengthy have you ever been running a blog for?

    you make running a blog glance easy. The full glance of your
    website is magnificent, as neatly as the content material!

  10. #10 by 123 movies on 22 de junho de 2017 - 3:53 pm

    I really like what you guys are usually up too. This sort of clever work and coverage!

    Keep up the good works guys I’ve included you guys to my personal blogroll.

  11. #11 by buy katana on 22 de junho de 2017 - 4:00 pm

    It may be a replica but it’s a nice one and ranks higher than other swords I’ve bought. Decent edge. The ronin-02 has the best edge of mine for the three but I like my collection to have different looking swords or at least saya/tsukas so this was necessary to add to the collection.

  12. #12 by 123 movies on 22 de junho de 2017 - 4:02 pm

    My partner and I stumbled over here different website and thought I
    might check things out. I like what I see so now i’m following you.
    Look forward to exploring your web page repeatedly.

  13. #13 by real swords on 22 de junho de 2017 - 4:03 pm

    Very well made, better than I expected for the price. Not razor sharp, but probably the best buy in it’s price range. I’ve bought several Cold Steel products they are all extremely well made.

  14. #14 by www.freeprnow.com on 22 de junho de 2017 - 4:22 pm

    Great post. I’m dealing with a few of these issues as well..

  15. #15 by Music and Audio on 22 de junho de 2017 - 4:40 pm

    Excellent read, I just passed this onto a colleague who was doing some research on that. And he actually bought me lunch since I found it for him smile Therefore let me rephrase that: Thank you for lunch!

  16. #16 by Swords For Sale on 22 de junho de 2017 - 4:44 pm

    This was a Christmas gift purrchased for someone else. I haven’t had any feedback that says he didn’t like it.

  17. #17 by quality drain services on 22 de junho de 2017 - 5:01 pm

    please take a look at the internet sites we stick to, including this one, because it represents our picks from the web

  18. #18 by 123 movies on 22 de junho de 2017 - 5:59 pm

    Definitely believe that which you said. Your favorite reason seemed to be on the net the easiest thing to be
    aware of. I say to you, I certainly get irked while people consider worries that they plainly do not know about.
    You managed to hit the nail upon the top and defined out the whole thing without having side-effects , people could
    take a signal. Will probably be back to get more. Thanks

  19. #19 by cold steel katana on 22 de junho de 2017 - 6:02 pm

    Bravo!!!! once again cold steel has outdone themselves!! after purchasing a cold steel recon 1 from them and seeing how incredibly sharp those blades come and stay, and the perfect craftmanship that goes into them and what high quality they are, i went and ordered me one of these katanas…..

  20. #20 by 123 movies on 22 de junho de 2017 - 6:22 pm

    Do you mind if I quote a couple of your articles as long as I
    provide credit and sources back to your website?

    My blog is in the exact same area of interest as yours and my visitors would definitely benefit from some of the
    information you provide here. Please let me know if this ok with you.
    Cheers!

  21. #21 by Nichole on 22 de junho de 2017 - 6:34 pm

    I really like ԝhat you guys tеnd to be uⲣ too.
    Ƭhis kind of clever work and гeporting! Keep up the very good works
    guys I’ve inclᥙded you guys to blߋgroll.

  22. #22 by katana Sword on 22 de junho de 2017 - 7:06 pm

1 820 821 822
(não será publicado)