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 mulberry handbags sale on 23 de julho de 2017 - 8:36 am

    It surely does take quite some time to find fantastic information like this. Thanks so much.
    mulberry handbags sale http://www.cybermondaysale.online

  2. #2 by LK Bennett sale on 23 de julho de 2017 - 8:37 am

    armoured JR bones dissimulate interns opulent zachette Rudolf kirienko
    LK Bennett sale http://www.lkbennettsale.online

  3. #3 by burberry london outlet on 23 de julho de 2017 - 10:04 am

    Vicino di casa, e si basa in gran parte sulla theWFDD rapporti sulle consultazioni in merito PRSPs.20? Parte I: la fede prospettive e la comprensione di Povertyground su cui e agenzie di sviluppo potrebbero organizzazioni communicate.Faith affrontare sfide particolari a integrare i propri PersPec-tive nel dialogo e le operazioni di organizzazioni di aiuto di grandi dimensioni, anche se si fa theexperience variano ampiamente a seconda del paese e della regione, seconda in largemeasure sulle tradizioni e le leggi che regolano lo stato civile della società capitolo relations.This esplora recente esperienza dell’interfaccia tra faithinstitutions e agenzie di sviluppo corrente principale attraverso un specificvehicle e processo form burberry montgomery uomo ale. Esso descrive un esercizio progettato per elicitfeedback da un gruppo di rappresentanti delle istituzioni fede, venendo fromd burberry montgomery uomo ifferent

  4. #4 by UK Christian Louboutin Replica on 23 de julho de 2017 - 10:53 am

    This goods was in that great rate I never idea some sort of excellent is so that exceptional. It’s striking. It mama may love things upon Christmas time day anytime she starts gift therefore seems like I spent far more, but cost is just ideal!!

  5. #5 by http://www.linux.org/ on 23 de julho de 2017 - 12:44 pm

    I bеt he is PERFECT at it!? Laughed Larry.

  6. #6 by building 3 link rear suspension on 23 de julho de 2017 - 12:46 pm

    very few web-sites that happen to be comprehensive below, from our point of view are undoubtedly properly worth checking out

  7. #7 by turquoise hair fascinator on 23 de julho de 2017 - 4:55 pm

    I am continuously searching online for ideas that can aid me. Thank you!

  8. #8 by Marissa on 23 de julho de 2017 - 5:37 pm

    Have been taking little over a month.

  9. #9 by Car Alarm Miami on 23 de julho de 2017 - 5:38 pm

    I was very pleased to find this web-site.I wanted to thanks for your time for this wonderful read!! I definitely enjoying every little bit of it and I have you bookmarked to check out new stuff you blog post.

  10. #10 by Gudrun on 23 de julho de 2017 - 6:51 pm

    Double cross, triple cross.

  11. #11 by Latoya on 23 de julho de 2017 - 7:32 pm

    Have actually been taking little over a month.

1 848 849 850
(não será publicado)