Solar Wind 3D Sample

This sample for Silverilght 5 uses the new 3D features to draw the Earth with day and night transitions, atmosphere layers, and population density overlays. It demonstrates advanced concepts like mipmaps, texture blending, multiple drawing passes, sampler states...

C# (10.4 MB)
 
 
 
 
 
4.4 Star
(8)
9,128 times
Add to favorites
9/12/2011
E-mail Twitter del.icio.us Digg Facebook
// ===================================================================================
//  Copyright (c) Microsoft Corporation.  All rights reserved.
//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
//  OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
//  LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
//  FITNESS FOR A PARTICULAR PURPOSE.
// ===================================================================================
using System;
using System.Windows;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using Primitives3D;

// alias
using Float4Register = Microsoft.Xna.Framework.Vector4;

namespace SolarWind
{
    class MagneticField
    {
        TorusPrimitive mesh;
        Texture2D texture;
        VertexShader vertexShader;
        PixelShader pixelShader;        

        // c0: WorldViewProjectionMatrix = Transform * camera.ViewTransform * camera.ProjectionTransform
        // c4: TotalSeconds
        struct VertexShaderConstants
        {
            public Matrix WorldViewProjectionMatrix;
            public Float4Register TotalSeconds;
        }
        VertexShaderConstants vertexConstants;

        /// <summary>
        /// Transform of the field
        /// </summary>
        public Matrix Transform { get; set; }

        public MagneticField()
        {
            Transform = Matrix.CreateWorld(new Vector3(), Vector3.Forward, Vector3.Up);
        }

        public void LoadContent()
        {
            // Load mesh
            mesh = new TorusPrimitive(10.0f, 0.1f, 50);

            // Load textures
            texture = ContentManager.LoadTexture("Textures/MagneticField/FieldLineRed.png");

            // Load shaders
            vertexShader = ContentManager.LoadVertexShader("Shaders/MagneticField_vs.vs");
            pixelShader = ContentManager.LoadPixelShader("Shaders/MagneticField_ps.ps");
        }

        public void Draw(GraphicsDevice device, SceneTime time, Camera camera)
        {
            const int lines = 10; // number of field lines

            // Configure pipeline
            device.SetVertexShader(vertexShader);
            device.SetPixelShader(pixelShader);
            device.BlendState = BlendState.AlphaBlend;
            device.Textures[0] = texture;
            device.SamplerStates[0] = SamplerState.LinearWrap;

            // Caclculate total seconds as input to the shader
            float totalSeconds = (float)time.TotalTime.Minutes * 60.0f 
                + (float)time.TotalTime.Seconds 
                + (float)time.TotalTime.Milliseconds / 1000.0f;

            for (int i = 0; i < lines; i++)
            {
                // Calculate world transform
                float yaw = MathHelper.ToRadians(36.0f * (float)i) + (float)totalSeconds * 0.04f;
                Matrix horizontalRotation = Matrix.CreateFromYawPitchRoll(yaw, 0.0f, 0.0f); // Rotate around
                Matrix translation = Matrix.CreateTranslation(-5.2f, 0.0f, 0.0f);
                Matrix verticalRotation = Matrix.CreateFromYawPitchRoll(0.0f, MathHelper.ToRadians(90.0f), 0.0f); // Rotate up
                Matrix world = verticalRotation * translation * horizontalRotation;

                // Set constants
                vertexConstants.WorldViewProjectionMatrix = world * camera.ViewTransform * camera.ProjectionTransform;
                vertexConstants.TotalSeconds.X = totalSeconds; // set first float in register
                device.SetVertexShaderConstantFloat4(0, ref vertexConstants);

                // Draw
                mesh.Draw(device);
            }
        }
    }
}