Ejemplo n.º 1
0
        public GPURelativeToEye(Context context, Vector3D[] positions, byte[] colors)
        {
            _sp = Device.CreateShaderProgram(
                EmbeddedResources.GetText("OpenGlobe.Examples.GPURelativeToEye.Shaders.VS.glsl"),
                EmbeddedResources.GetText("OpenGlobe.Examples.Shaders.FS.glsl"));
            _cameraEyeHigh = (Uniform <Vector3F>)_sp.Uniforms["u_cameraEyeHigh"];
            _cameraEyeLow  = (Uniform <Vector3F>)_sp.Uniforms["u_cameraEyeLow"];
            _modelViewPerspectiveMatrixRelativeToEye = (Uniform <Matrix4F>)(_sp.Uniforms["u_modelViewPerspectiveMatrixRelativeToEye"]);
            _pointSize = (Uniform <float>)_sp.Uniforms["u_pointSize"];

            ///////////////////////////////////////////////////////////////////

            Mesh mesh = new Mesh();
            VertexAttributeFloatVector3 positionsHighAttribute = new VertexAttributeFloatVector3("positionHigh", positions.Length);
            VertexAttributeFloatVector3 positionsLowAttribute  = new VertexAttributeFloatVector3("positionLow", positions.Length);
            VertexAttributeRGB          colorAttribute         = new VertexAttributeRGB("color", positions.Length);

            mesh.Attributes.Add(positionsHighAttribute);
            mesh.Attributes.Add(positionsLowAttribute);
            mesh.Attributes.Add(colorAttribute);

            for (int i = 0; i < positions.Length; ++i)
            {
                Vector3F positionHigh;
                Vector3F positionLow;
                Vector3DToTwoVector3F(positions[i], out positionHigh, out positionLow);

                positionsHighAttribute.Values.Add(positionHigh);
                positionsLowAttribute.Values.Add(positionLow);
            }

            for (int i = 0; i < colors.Length; ++i)
            {
                colorAttribute.Values.Add(colors[i]);
            }

            _va = context.CreateVertexArray(mesh, _sp.VertexAttributes, BufferHint.StaticDraw);

            ///////////////////////////////////////////////////////////////////

            RenderState renderState = new RenderState();

            renderState.FacetCulling.Enabled = false;
            renderState.DepthTest.Enabled    = false;
            renderState.ProgramPointSize     = ProgramPointSize.Enabled;

            _drawState = new DrawState(renderState, _sp, _va);
        }
Ejemplo n.º 2
0
        public GPURelativeToEye(Context context, Vector3D[] positions, byte[] colors)
        {
            _sp = Device.CreateShaderProgram(
                EmbeddedResources.GetText("OpenGlobe.Examples.GPURelativeToEye.Shaders.VS.glsl"),
                EmbeddedResources.GetText("OpenGlobe.Examples.Shaders.FS.glsl"));
            _cameraEyeHigh = (Uniform<Vector3F>)_sp.Uniforms["u_cameraEyeHigh"];
            _cameraEyeLow = (Uniform<Vector3F>)_sp.Uniforms["u_cameraEyeLow"];
            _modelViewPerspectiveMatrixRelativeToEye = (Uniform<Matrix4F>)(_sp.Uniforms["u_modelViewPerspectiveMatrixRelativeToEye"]);
            _pointSize = (Uniform<float>)_sp.Uniforms["u_pointSize"];

            ///////////////////////////////////////////////////////////////////

            Mesh mesh = new Mesh();
            VertexAttributeFloatVector3 positionsHighAttribute = new VertexAttributeFloatVector3("positionHigh", positions.Length);
            VertexAttributeFloatVector3 positionsLowAttribute = new VertexAttributeFloatVector3("positionLow", positions.Length);
            VertexAttributeRGB colorAttribute = new VertexAttributeRGB("color", positions.Length);
            mesh.Attributes.Add(positionsHighAttribute);
            mesh.Attributes.Add(positionsLowAttribute);
            mesh.Attributes.Add(colorAttribute);

            for (int i = 0; i < positions.Length; ++i)
            {
                Vector3F positionHigh;
                Vector3F positionLow;
                Vector3DToTwoVector3F(positions[i], out positionHigh, out positionLow);

                positionsHighAttribute.Values.Add(positionHigh);
                positionsLowAttribute.Values.Add(positionLow);
            }

            for (int i = 0; i < colors.Length; ++i)
            {
                colorAttribute.Values.Add(colors[i]);
            }

            _va = context.CreateVertexArray(mesh, _sp.VertexAttributes, BufferHint.StaticDraw);

            ///////////////////////////////////////////////////////////////////

            RenderState renderState = new RenderState();
            renderState.FacetCulling.Enabled = false;
            renderState.DepthTest.Enabled = false;
            renderState.ProgramPointSize = ProgramPointSize.Enabled;

            _drawState = new DrawState(renderState, _sp, _va);
        }
Ejemplo n.º 3
0
        public RelativeToCenter(Context context, Vector3D[] positions, byte[] colors)
        {
            _sp = Device.CreateShaderProgram(
                EmbeddedResources.GetText("OpenGlobe.Examples.RelativeToCenter.Shaders.VS.glsl"),
                EmbeddedResources.GetText("OpenGlobe.Examples.Shaders.FS.glsl"));
            _modelViewPerspectiveMatrixRelativeToCenter = (Uniform <Matrix4F>)(_sp.Uniforms["u_modelViewPerspectiveMatrixRelativeToCenter"]);
            _pointSize = (Uniform <float>)_sp.Uniforms["u_pointSize"];

            ///////////////////////////////////////////////////////////////////

            Mesh mesh = new Mesh();
            VertexAttributeFloatVector3 positionsAttribute = new VertexAttributeFloatVector3("position", positions.Length);
            VertexAttributeRGB          colorAttribute     = new VertexAttributeRGB("color", positions.Length);

            mesh.Attributes.Add(positionsAttribute);
            mesh.Attributes.Add(colorAttribute);

            _center = new AxisAlignedBoundingBox(positions).Center;
            for (int i = 0; i < positions.Length; ++i)
            {
                positionsAttribute.Values.Add((positions[i] - _center).ToVector3F());
            }

            for (int i = 0; i < colors.Length; ++i)
            {
                colorAttribute.Values.Add(colors[i]);
            }

            _va = context.CreateVertexArray(mesh, _sp.VertexAttributes, BufferHint.StaticDraw);

            ///////////////////////////////////////////////////////////////////

            RenderState renderState = new RenderState();

            renderState.FacetCulling.Enabled = false;
            renderState.DepthTest.Enabled    = false;
            renderState.ProgramPointSize     = ProgramPointSize.Enabled;

            _drawState = new DrawState(renderState, _sp, _va);
        }
Ejemplo n.º 4
0
        public RelativeToCenter(Context context, Vector3D[] positions, byte[] colors)
        {
            _sp = Device.CreateShaderProgram(
                EmbeddedResources.GetText("OpenGlobe.Examples.RelativeToCenter.Shaders.VS.glsl"),
                EmbeddedResources.GetText("OpenGlobe.Examples.Shaders.FS.glsl"));
            _modelViewPerspectiveMatrixRelativeToCenter = (Uniform<Matrix4F>)(_sp.Uniforms["u_modelViewPerspectiveMatrixRelativeToCenter"]);
            _pointSize = (Uniform<float>)_sp.Uniforms["u_pointSize"];

            ///////////////////////////////////////////////////////////////////

            Mesh mesh = new Mesh();
            VertexAttributeFloatVector3 positionsAttribute = new VertexAttributeFloatVector3("position", positions.Length);
            VertexAttributeRGB colorAttribute = new VertexAttributeRGB("color", positions.Length);
            mesh.Attributes.Add(positionsAttribute);
            mesh.Attributes.Add(colorAttribute);

            _center = new AxisAlignedBoundingBox(positions).Center;
            for (int i = 0; i < positions.Length; ++i)
            {
                positionsAttribute.Values.Add((positions[i] - _center).ToVector3F());
            }

            for (int i = 0; i < colors.Length; ++i)
            {
                colorAttribute.Values.Add(colors[i]);
            }

            _va = context.CreateVertexArray(mesh, _sp.VertexAttributes, BufferHint.StaticDraw);

            ///////////////////////////////////////////////////////////////////

            RenderState renderState = new RenderState();
            renderState.FacetCulling.Enabled = false;
            renderState.DepthTest.Enabled = false;
            renderState.ProgramPointSize = ProgramPointSize.Enabled;

            _drawState = new DrawState(renderState, _sp, _va);
        }
Ejemplo n.º 5
0
        public void MeshVertexAttributes()
        {
            Mesh mesh = new Mesh();

            VertexAttributeHalfFloat halfFloatAttribute = new VertexAttributeHalfFloat("halfFloatAttribute");
            mesh.Attributes.Add(halfFloatAttribute);
            Assert.AreEqual("halfFloatAttribute", mesh.Attributes["halfFloatAttribute"].Name);
            Assert.AreEqual(VertexAttributeType.HalfFloat, mesh.Attributes["halfFloatAttribute"].Datatype);

            VertexAttributeHalfFloatVector2 halfFloatAttribute2 = new VertexAttributeHalfFloatVector2("halfFloatAttribute2");
            mesh.Attributes.Add(halfFloatAttribute2);
            Assert.AreEqual("halfFloatAttribute2", mesh.Attributes["halfFloatAttribute2"].Name);
            Assert.AreEqual(VertexAttributeType.HalfFloatVector2, mesh.Attributes["halfFloatAttribute2"].Datatype);

            VertexAttributeHalfFloatVector3 halfFloatAttribute3 = new VertexAttributeHalfFloatVector3("halfFloatAttribute3");
            mesh.Attributes.Add(halfFloatAttribute3);
            Assert.AreEqual("halfFloatAttribute3", mesh.Attributes["halfFloatAttribute3"].Name);
            Assert.AreEqual(VertexAttributeType.HalfFloatVector3, mesh.Attributes["halfFloatAttribute3"].Datatype);

            VertexAttributeHalfFloatVector4 halfFloatAttribute4 = new VertexAttributeHalfFloatVector4("halfFloatAttribute4");
            mesh.Attributes.Add(halfFloatAttribute4);
            Assert.AreEqual("halfFloatAttribute4", mesh.Attributes["halfFloatAttribute4"].Name);
            Assert.AreEqual(VertexAttributeType.HalfFloatVector4, mesh.Attributes["halfFloatAttribute4"].Datatype);

            ///////////////////////////////////////////////////////////////////

            VertexAttributeFloat floatAttribute = new VertexAttributeFloat("floatAttribute");
            mesh.Attributes.Add(floatAttribute);
            Assert.AreEqual("floatAttribute", mesh.Attributes["floatAttribute"].Name);
            Assert.AreEqual(VertexAttributeType.Float, mesh.Attributes["floatAttribute"].Datatype);

            VertexAttributeFloatVector2 floatAttribute2 = new VertexAttributeFloatVector2("floatAttribute2");
            mesh.Attributes.Add(floatAttribute2);
            Assert.AreEqual("floatAttribute2", mesh.Attributes["floatAttribute2"].Name);
            Assert.AreEqual(VertexAttributeType.FloatVector2, mesh.Attributes["floatAttribute2"].Datatype);

            VertexAttributeFloatVector3 floatAttribute3 = new VertexAttributeFloatVector3("floatAttribute3");
            mesh.Attributes.Add(floatAttribute3);
            Assert.AreEqual("floatAttribute3", mesh.Attributes["floatAttribute3"].Name);
            Assert.AreEqual(VertexAttributeType.FloatVector3, mesh.Attributes["floatAttribute3"].Datatype);

            VertexAttributeFloatVector4 floatAttribute4 = new VertexAttributeFloatVector4("floatAttribute4");
            mesh.Attributes.Add(floatAttribute4);
            Assert.AreEqual("floatAttribute4", mesh.Attributes["floatAttribute4"].Name);
            Assert.AreEqual(VertexAttributeType.FloatVector4, mesh.Attributes["floatAttribute4"].Datatype);

            ///////////////////////////////////////////////////////////////////

            VertexAttributeByte byteAttribute = new VertexAttributeByte("byteAttribute");
            mesh.Attributes.Add(byteAttribute);
            Assert.AreEqual("byteAttribute", mesh.Attributes["byteAttribute"].Name);
            Assert.AreEqual(VertexAttributeType.UnsignedByte, mesh.Attributes["byteAttribute"].Datatype);

            VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("colorAttribute");
            mesh.Attributes.Add(colorAttribute);
            Assert.AreEqual("colorAttribute", mesh.Attributes["colorAttribute"].Name);
            Assert.AreEqual(VertexAttributeType.UnsignedByte, mesh.Attributes["colorAttribute"].Datatype);

            colorAttribute.AddColor(Color.FromArgb(3, 0, 1, 2));
            Assert.AreEqual(0, colorAttribute.Values[0]);
            Assert.AreEqual(1, colorAttribute.Values[1]);
            Assert.AreEqual(2, colorAttribute.Values[2]);
            Assert.AreEqual(3, colorAttribute.Values[3]);
        }
Ejemplo n.º 6
0
        public Triangle()
        {
            _window              = Device.CreateWindow(800, 600, "Chapter 3:  Triangle");
            _window.Resize      += OnResize;
            _window.RenderFrame += OnRenderFrame;
            _sceneState          = new SceneState();
            _clearState          = new ClearState();

            string vs =
                @"#version 330

                  layout(location = og_positionVertexLocation) in vec4 position;
                  uniform mat4 og_modelViewPerspectiveMatrix;

                  void main()                     
                  {
                        gl_Position = og_modelViewPerspectiveMatrix * position; 
                  }";

            string fs =
                @"#version 330
                 
                  out vec3 fragmentColor;
                  uniform vec3 u_color;

                  void main()
                  {
                      fragmentColor = u_color;
                  }";
            ShaderProgram sp = Device.CreateShaderProgram(vs, fs);

            ((Uniform <Vector3F>)sp.Uniforms["u_color"]).Value = new Vector3F(1, 0, 0);

            ///////////////////////////////////////////////////////////////////

            Mesh mesh = new Mesh();

            VertexAttributeFloatVector3 positionsAttribute = new VertexAttributeFloatVector3("position", 3);

            mesh.Attributes.Add(positionsAttribute);

            IndicesUnsignedShort indices = new IndicesUnsignedShort(3);

            mesh.Indices = indices;

            IList <Vector3F> positions = positionsAttribute.Values;

            positions.Add(new Vector3F(0, 0, 0));
            positions.Add(new Vector3F(1, 0, 0));
            positions.Add(new Vector3F(0, 0, 1));

            indices.AddTriangle(new TriangleIndicesUnsignedShort(0, 1, 2));

            VertexArray va = _window.Context.CreateVertexArray(mesh, sp.VertexAttributes, BufferHint.StaticDraw);

            ///////////////////////////////////////////////////////////////////

            RenderState renderState = new RenderState();

            renderState.FacetCulling.Enabled = false;
            renderState.DepthTest.Enabled    = false;

            _drawState = new DrawState(renderState, sp, va);

            ///////////////////////////////////////////////////////////////////

            _sceneState.Camera.ZoomToTarget(1);
        }
Ejemplo n.º 7
0
        private void CreateScene()
        {
            // 设置窗口表面指令信息显示内容
            string text = "Granularity: " + _granularityInDegrees + " (left/right)\n";

            text += "Points: " + (_sampledPoints.Show ? "on" : "off") + " ('1')\n";
            text += "Polyline: " + (_polyline.Show ? "on" : "off") + " ('2')\n";
            text += "Plane: " + (_plane.Show ? "on" : "off") + " ('3')\n";
            text += "Semi-minor axis (up/down)\n";

            // 转换指令信息文字内容为图像纹理
            _instructions.Texture = Device.CreateTexture2D(
                Device.CreateBitmapFromText(text, new Font("Arial", 24)),
                TextureFormat.RedGreenBlueAlpha8, false);

            ///////////////////////////////////////////////////////////////////

            // 基于椭球形状计算表面采样点三维坐标
            IList <Vector3D> positions = _globeShape.ComputeCurve(
                _p, _q, Trig.ToRadians(_granularityInDegrees));

            // 设置椭球表面采样点billboard集合的位置和颜色
            _sampledPoints.Clear();
            _sampledPoints.Add(new Billboard()
            {
                Position = positions[0], Color = Color.Orange
            });
            _sampledPoints.Add(new Billboard()
            {
                Position = positions[positions.Count - 1], Color = Color.Orange
            });

            for (int i = 1; i < positions.Count - 1; ++i)
            {
                _sampledPoints.Add(new Billboard()
                {
                    Position = positions[i],
                    Color    = Color.Yellow
                });
            }

            ///////////////////////////////////////////////////////////////////

            // 设置椭球的尺寸形状信息
            _ellipsoid.Shape = _globeShape;

            ///////////////////////////////////////////////////////////////////

            // 计算椭球表面曲线位置和颜色
            VertexAttributeFloatVector3 positionAttribute = new VertexAttributeFloatVector3("position", positions.Count);
            VertexAttributeRGBA         colorAttribute    = new VertexAttributeRGBA("color", positions.Count);

            for (int i = 0; i < positions.Count; ++i)
            {
                positionAttribute.Values.Add(positions[i].ToVector3F());
                colorAttribute.AddColor(Color.Red);
            }

            // 创建椭球表面曲线
            Mesh mesh = new Mesh();

            mesh.PrimitiveType = PrimitiveType.LineStrip;
            mesh.Attributes.Add(positionAttribute);
            mesh.Attributes.Add(colorAttribute);

            _polyline.Set(_window.Context, mesh);

            ///////////////////////////////////////////////////////////////////

            // 设置显示参考面缩放使其略大于椭球
            double scale = 1.25 * _globeShape.Radii.MaximumComponent;

            // 设置参考面X轴穿过p点
            _plane.XAxis = scale * _p.Normalize();
            _plane.YAxis = scale * _p.Cross(_q).Cross(_p).Normalize();
        }
Ejemplo n.º 8
0
        public Triangle()
        {
            _window = Device.CreateWindow(800, 600, "Chapter 3:  Triangle");
            _window.Resize += OnResize;
            _window.RenderFrame += OnRenderFrame;
            _sceneState = new SceneState();
            _clearState = new ClearState();

            string vs =
                @"#version 330

                  layout(location = og_positionVertexLocation) in vec4 position;
                  uniform mat4 og_modelViewPerspectiveMatrix;

                  void main()                     
                  {
                        gl_Position = og_modelViewPerspectiveMatrix * position; 
                  }";

            string fs =
                @"#version 330
                 
                  out vec3 fragmentColor;
                  uniform vec3 u_color;

                  void main()
                  {
                      fragmentColor = u_color;
                  }";
            ShaderProgram sp = Device.CreateShaderProgram(vs, fs);
            ((Uniform<Vector3F>)sp.Uniforms["u_color"]).Value = new Vector3F(1, 0, 0);

            ///////////////////////////////////////////////////////////////////
            
            Mesh mesh = new Mesh();

            VertexAttributeFloatVector3 positionsAttribute = new VertexAttributeFloatVector3("position", 3);
            mesh.Attributes.Add(positionsAttribute);

            IndicesUnsignedShort indices = new IndicesUnsignedShort(3);
            mesh.Indices = indices;

            IList<Vector3F> positions = positionsAttribute.Values;
            positions.Add(new Vector3F(0, 0, 0));
            positions.Add(new Vector3F(1, 0, 0));
            positions.Add(new Vector3F(0, 0, 1));

            indices.AddTriangle(new TriangleIndicesUnsignedShort(0, 1, 2));

            VertexArray va = _window.Context.CreateVertexArray(mesh, sp.VertexAttributes, BufferHint.StaticDraw);

            ///////////////////////////////////////////////////////////////////

            RenderState renderState = new RenderState();
            renderState.FacetCulling.Enabled = false;
            renderState.DepthTest.Enabled = false;

            _drawState = new DrawState(renderState, sp, va);

            ///////////////////////////////////////////////////////////////////
            
            _sceneState.Camera.ZoomToTarget(1);
        }
Ejemplo n.º 9
0
        private void CreateScene()
        {
            DisposeScene();

            _ellipsoid       = new TessellatedGlobe();
            _ellipsoid.Shape = _globeShape;
            _ellipsoid.NumberOfSlicePartitions = 64;
            _ellipsoid.NumberOfStackPartitions = 32;

            ///////////////////////////////////////////////////////////////////

            // 计算椭球网格
            Mesh mesh = GeographicGridEllipsoidTessellator.Compute(_globeShape,
                                                                   64, 32, GeographicGridEllipsoidVertexAttributes.Position);

            // 创建椭球网格线框显示对象
            _wireframe       = new Wireframe(_window.Context, mesh);
            _wireframe.Width = 2;

            ///////////////////////////////////////////////////////////////////

            // 创建坐标轴显示对象
            _axes        = new Axes();
            _axes.Length = 1.5;
            _axes.Width  = 3;

            ///////////////////////////////////////////////////////////////////

            // 计算p点椭球表面坐标
            Vector3D p = _globeShape.ToVector3D(new Geodetic3D(0, Trig.ToRadians(45), 0));
            // 计算p点地理法线向量
            Vector3D deticNormal = _globeShape.GeodeticSurfaceNormal(p);
            // 计算p点地心法线向量
            Vector3D centricNormal = Ellipsoid.CentricSurfaceNormal(p);

            double normalLength = _globeShape.MaximumRadius;
            // 计算地理法线末端点三维坐标
            Vector3D pDetic   = p + (normalLength * deticNormal);
            Vector3D pCentric = p + (normalLength * centricNormal);

            VertexAttributeFloatVector3 positionAttribute = new VertexAttributeFloatVector3("position", 4);

            // 创建地理法线段顶点
            positionAttribute.Values.Add(p.ToVector3F());
            positionAttribute.Values.Add(pDetic.ToVector3F());
            // 创建地心法线段顶点
            positionAttribute.Values.Add(p.ToVector3F());
            positionAttribute.Values.Add(pCentric.ToVector3F());

            VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("color", 4);

            // 创建地理法线段顶点颜色
            colorAttribute.AddColor(Color.DarkGreen);
            colorAttribute.AddColor(Color.DarkGreen);
            // 创建地心法线段顶点颜色
            colorAttribute.AddColor(Color.DarkCyan);
            colorAttribute.AddColor(Color.DarkCyan);

            // 创建地理/地心发现段图形显示元语
            Mesh polyline = new Mesh();

            polyline.PrimitiveType = PrimitiveType.Lines;
            polyline.Attributes.Add(positionAttribute);
            polyline.Attributes.Add(colorAttribute);

            _normals = new Polyline();
            _normals.Set(_window.Context, polyline);
            _normals.Width = 3;

            ///////////////////////////////////////////////////////////////////
            Font           font         = new Font("Arial", 24);
            IList <Bitmap> labelBitmaps = new List <Bitmap>(2);

            labelBitmaps.Add(Device.CreateBitmapFromText("Geodetic", font));
            labelBitmaps.Add(Device.CreateBitmapFromText("Geocentric", font));
            font.Dispose();

            // 创建纹理压缩对象?
            TextureAtlas atlas = new TextureAtlas(labelBitmaps);

            _labels         = new BillboardCollection(_window.Context, 2);
            _labels.Texture = Device.CreateTexture2D(atlas.Bitmap, TextureFormat.RedGreenBlueAlpha8, false);
            _labels.Add(new Billboard()
            {
                Position = pDetic,
                // 取第一个纹理
                TextureCoordinates = atlas.TextureCoordinates[0],
                Color            = Color.DarkGreen,
                HorizontalOrigin = HorizontalOrigin.Right,
                VerticalOrigin   = VerticalOrigin.Bottom
            });
            _labels.Add(new Billboard()
            {
                Position = pCentric,
                // 取第二个纹理
                TextureCoordinates = atlas.TextureCoordinates[1],
                Color            = Color.DarkCyan,
                HorizontalOrigin = HorizontalOrigin.Right,
                VerticalOrigin   = VerticalOrigin.Bottom
            });

            atlas.Dispose();

            ///////////////////////////////////////////////////////////////////
            Vector3D east  = Vector3D.UnitZ.Cross(deticNormal);
            Vector3D north = deticNormal.Cross(east);

            // 创建p点切平面
            _tangentPlane              = new Plane(_window.Context);
            _tangentPlane.Origin       = p;
            _tangentPlane.XAxis        = east;
            _tangentPlane.YAxis        = north;
            _tangentPlane.OutlineWidth = 3;
        }
Ejemplo n.º 10
0
        private void CreateScene()
        {
            string text = "Granularity: " + _granularityInDegrees + " (left/right)\n";
            text += "Points: " + (_sampledPoints.Show ? "on" : "off") + " ('1')\n";
            text += "Polyline: " + (_polyline.Show ? "on" : "off") + " ('2')\n";
            text += "Plane: " + (_plane.Show ? "on" : "off") + " ('3')\n";
            text += "Semi-minor axis (up/down)\n";

            _instructions.Texture = Device.CreateTexture2D(
                Device.CreateBitmapFromText(text, new Font("Arial", 24)),
                TextureFormat.RedGreenBlueAlpha8, false);

            ///////////////////////////////////////////////////////////////////

            IList<Vector3D> positions = _globeShape.ComputeCurve(
                _p, _q, Trig.ToRadians(_granularityInDegrees));

            _sampledPoints.Clear();
            _sampledPoints.Add(new Billboard() { Position = positions[0], Color = Color.Orange });
            _sampledPoints.Add(new Billboard() { Position = positions[positions.Count - 1], Color = Color.Orange });

            for (int i = 1; i < positions.Count - 1; ++i)
            {
                _sampledPoints.Add(new Billboard() 
                { 
                    Position = positions[i], 
                    Color = Color.Yellow 
                });
            }

            ///////////////////////////////////////////////////////////////////

            _ellipsoid.Shape = _globeShape;

            ///////////////////////////////////////////////////////////////////
            
            VertexAttributeFloatVector3 positionAttribute = new VertexAttributeFloatVector3("position", positions.Count);
            VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("color", positions.Count);

            for (int i = 0; i < positions.Count; ++i)
            {
                positionAttribute.Values.Add(positions[i].ToVector3F());
                colorAttribute.AddColor(Color.Red);
            }

            Mesh mesh = new Mesh();
            mesh.PrimitiveType = PrimitiveType.LineStrip;
            mesh.Attributes.Add(positionAttribute);
            mesh.Attributes.Add(colorAttribute);

            _polyline.Set(_window.Context, mesh);

            ///////////////////////////////////////////////////////////////////

            double scale = 1.25 * _globeShape.Radii.MaximumComponent;
            _plane.XAxis = scale * _p.Normalize();
            _plane.YAxis = scale * _p.Cross(_q).Cross(_p).Normalize();
        }
        private void CreateScene()
        {
            DisposeScene();

            _ellipsoid = new TessellatedGlobe();
            _ellipsoid.Shape = _globeShape;
            _ellipsoid.NumberOfSlicePartitions = 64;
            _ellipsoid.NumberOfStackPartitions = 32;

            ///////////////////////////////////////////////////////////////////

            Mesh mesh = GeographicGridEllipsoidTessellator.Compute(_globeShape,
                64, 32, GeographicGridEllipsoidVertexAttributes.Position);

            _wireframe = new Wireframe(_window.Context, mesh);
            _wireframe.Width = 2;

            ///////////////////////////////////////////////////////////////////

            _axes = new Axes();
            _axes.Length = 1.5;
            _axes.Width = 3;

            ///////////////////////////////////////////////////////////////////

            Vector3D p = _globeShape.ToVector3D(new Geodetic3D(0, Trig.ToRadians(45), 0));
            Vector3D deticNormal = _globeShape.GeodeticSurfaceNormal(p);
            Vector3D centricNormal = Ellipsoid.CentricSurfaceNormal(p);

            double normalLength = _globeShape.MaximumRadius;
            Vector3D pDetic = p + (normalLength * deticNormal);
            Vector3D pCentric = p + (normalLength * centricNormal);

            VertexAttributeFloatVector3 positionAttribute = new VertexAttributeFloatVector3("position", 4);
            positionAttribute.Values.Add(p.ToVector3F());
            positionAttribute.Values.Add(pDetic.ToVector3F());
            positionAttribute.Values.Add(p.ToVector3F());
            positionAttribute.Values.Add(pCentric.ToVector3F());

            VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("color", 4);
            colorAttribute.AddColor(Color.DarkGreen);
            colorAttribute.AddColor(Color.DarkGreen);
            colorAttribute.AddColor(Color.DarkCyan);
            colorAttribute.AddColor(Color.DarkCyan);

            Mesh polyline = new Mesh();
            polyline.PrimitiveType = PrimitiveType.Lines;
            polyline.Attributes.Add(positionAttribute);
            polyline.Attributes.Add(colorAttribute);

            _normals = new Polyline();
            _normals.Set(_window.Context, polyline);
            _normals.Width = 3;

            ///////////////////////////////////////////////////////////////////
            Font font = new Font("Arial", 24);
            IList<Bitmap> labelBitmaps = new List<Bitmap>(2);
            labelBitmaps.Add(Device.CreateBitmapFromText("Geodetic", font));
            labelBitmaps.Add(Device.CreateBitmapFromText("Geocentric", font));
            font.Dispose();

            TextureAtlas atlas = new TextureAtlas(labelBitmaps);

            _labels = new BillboardCollection(_window.Context, 2);
            _labels.Texture = Device.CreateTexture2D(atlas.Bitmap, TextureFormat.RedGreenBlueAlpha8, false);
            _labels.Add(new Billboard()
            {
                Position = pDetic,
                TextureCoordinates = atlas.TextureCoordinates[0],
                Color = Color.DarkGreen,
                HorizontalOrigin = HorizontalOrigin.Right,
                VerticalOrigin = VerticalOrigin.Bottom
            });
            _labels.Add(new Billboard()
            {
                Position = pCentric,
                TextureCoordinates = atlas.TextureCoordinates[1],
                Color = Color.DarkCyan,
                HorizontalOrigin = HorizontalOrigin.Right,
                VerticalOrigin = VerticalOrigin.Bottom
            });

            atlas.Dispose();

            ///////////////////////////////////////////////////////////////////
            Vector3D east = Vector3D.UnitZ.Cross(deticNormal);
            Vector3D north = deticNormal.Cross(east);

            _tangentPlane = new Plane(_window.Context);
            _tangentPlane.Origin = p;
            _tangentPlane.XAxis = east;
            _tangentPlane.YAxis = north;
            _tangentPlane.OutlineWidth = 3;
        }