Пример #1
0
        private void Render(IViewPort target)
        {
            XnaCameraMan cameraMan = _viewports[target];
            if (cameraMan.DrawSatelliteImagery && _lakeTextureAvailible)
            {
                _device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.White, 1.0f, 0);
            }
            else
            {
                _device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);
            }
            if (this.Replay.Boats[_viewports[target].SelectedBoat].ProjectedPoint != null)
            {
                cameraMan.FollowBoat(ProjectedPointToWorld(this.Replay.Boats[_viewports[target].SelectedBoat].ProjectedPoint));
                Camera camera = cameraMan.Camera;
                camera.UpdatePosition();
                camera.ConfigureBasicEffect(_instruments);

                Viewport viewport = _device.Viewport;
                if (target.RenderTarget.Height <= _device.PresentationParameters.BackBufferHeight)
                {
                    viewport.Height = target.RenderTarget.Height;
                }
                else
                {
                    viewport.Height = _device.PresentationParameters.BackBufferHeight;
                }
                if (target.RenderTarget.Width <= _device.PresentationParameters.BackBufferWidth)
                {
                    viewport.Width = target.RenderTarget.Width;
                }
                else
                {
                    viewport.Width = _device.PresentationParameters.BackBufferWidth;
                }
                viewport.X = 0;
                viewport.Y = 0;
                _device.Viewport = viewport;

                if (cameraMan.DrawSatelliteImagery)
                {
                    if (_lakeTextureAvailible)
                    {
                        VertexPositionTexture[] textureTris = new VertexPositionTexture[4];
                        textureTris[0] = new VertexPositionTexture(ProjectedPointToWorld(this.Race.Lake.TopLeftInMeters), new Vector2(0, 0));
                        textureTris[1] = new VertexPositionTexture(ProjectedPointToWorld(this.Race.Lake.BottomLeftInMeters), new Vector2(0, 1));
                        textureTris[2] = new VertexPositionTexture(ProjectedPointToWorld(this.Race.Lake.TopRightInMeters), new Vector2(1, 0));
                        textureTris[3] = new VertexPositionTexture(ProjectedPointToWorld(this.Race.Lake.BottomRightInMeters), new Vector2(1, 1));
                        textureTris[0].Position.Y = -0.5f;
                        textureTris[0].Position.Y = -0.5f;
                        textureTris[0].Position.Y = -0.5f;
                        textureTris[0].Position.Y = -0.5f;
                        camera.ConfigureBasicEffect(_lakeTextureEffect);
                        _lakeTextureEffect.World = Matrix.Identity;
                        _lakeTextureEffect.Begin();
                        foreach (EffectPass pass in _lakeTextureEffect.CurrentTechnique.Passes)
                        {
                            pass.Begin();
                            _device.VertexDeclaration = VertexDeclarationHelper.Get(typeof(VertexPositionTexture));
                            _device.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, textureTris, 0, 2);
                            pass.End();
                        }
                        _lakeTextureEffect.End();
                    }
                    camera.ConfigureBasicEffect(_skyBoxEffect);
                    _skyBoxEffect.World = Matrix.Identity;
                    _skyBoxEffect.Begin();
                    foreach (EffectPass pass in _skyBoxEffect.CurrentTechnique.Passes)
                    {
                        pass.Begin();
                        _device.VertexDeclaration = VertexDeclarationHelper.Get(typeof(VertexPositionTexture));
                        _device.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, _skybox, 0, 8);
                        pass.End();
                    }
                    _skyBoxEffect.End();
                }

                if (cameraMan.DrawGrid)
                {
                    _instruments.World = Matrix.Identity;
                    _instruments.Begin();
                    foreach (EffectPass pass in _instruments.CurrentTechnique.Passes)
                    {
                        pass.Begin();
                        _device.VertexDeclaration = VertexDeclarationHelper.Get(typeof(VertexPositionColor));
                        _device.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, _gridLines, 0, _gridLines.Length / 2);
                        pass.End();
                    }
                    _instruments.End();
                }
                Dictionary<ReplayBoat, Vector2> locations = new Dictionary<ReplayBoat, Vector2>();
                foreach (ReplayBoat b in this.Replay.Boats)
                {
                    DrawHUD(b,_device, cameraMan, this.Replay.SimulationTime, _coordinateDivisor);
                    if (cameraMan.ShowAnyIdentifiers || target.ClickedPoint != null || cameraMan.PhotoMode != CameraMan.PhotoDisplayMode.Disabled)
                    {
                        if (b.ProjectedPoint != null)
                        {
                            Vector3 twoD = viewport.Project(ProjectedPointToWorld(b.ProjectedPoint), camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
                            if (twoD.Z < 1f)
                            {
                                locations.Add(b, new Vector2(twoD.X, twoD.Y));
                            }
                        }
                    }
                }
                foreach (ReplayBoat b in this.Replay.Boats)
                {
                    DrawBoat(b,_device, cameraMan, this.Replay.SimulationTime);
                }

                Dictionary<Bouy, Vector2> bouyLocations = new Dictionary<Bouy, Vector2>();
                foreach (Mark m in this.Replay.Race.Course.Marks)
                {
                    foreach (Bouy b in m.Bouys)
                    {
                        DrawBouy(b, _device, camera);
                        if (cameraMan.ShowMarkNames)
                        {
                            Vector3 twoD = viewport.Project(ProjectedPointToWorld(b.CoordinatePoint.Project()), camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
                            if (twoD.Z < 1f)
                            {
                                bouyLocations.Add(b, new Vector2(twoD.X, twoD.Y));
                            }
                        }
                    }
                }

                ////course navigation debug lines
                //List<VertexPositionColor> markRoundLines = new List<VertexPositionColor>();
                //for (int i = 0; i < this.Race.Course.Route.Count; i++)
                //{
                //    if (i > 0 && i < this.Race.Course.Route.Count - 1)
                //    {
                //        Vector3 a = ProjectedPointToWorld(this.Race.Course.Route[i].AveragedLocation.Project());
                //        Vector3 b = ProjectedPointToWorld(this.Race.Course.Route[i].FindMarkRoundPoint(this.Race.Course.Route[i - 1], this.Race.Course.Route[i + 1]));

                //        VertexPositionColor vpcA = new VertexPositionColor(a, Color.Red);
                //        VertexPositionColor vpcB = new VertexPositionColor(b, Color.Red);
                //        markRoundLines.Add(vpcA);
                //        markRoundLines.Add(vpcB);
                //    }
                //}
                //_instruments.World = Matrix.Identity;
                //_instruments.Begin();
                //foreach (EffectPass pass in _instruments.CurrentTechnique.Passes)
                //{
                //    pass.Begin();
                //    _device.VertexDeclaration = VertexDeclarationHelper.Get(typeof(VertexPositionColor));
                //    _device.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, markRoundLines.ToArray(), 0, markRoundLines.Count / 2);
                //    pass.End();
                //}
                //_instruments.End();
                ////end course navigation debug

                DrawMouseInstructions(DateTime.Now - target.CreatedAt, viewport.Width, viewport.Height);

                if (cameraMan.ShowAnyIdentifiers || cameraMan.ShowMarkNames || cameraMan.DrawPlaybackSpeed || cameraMan.PhotoMode != CameraMan.PhotoDisplayMode.Disabled)
                {
                    _batch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState);
                    List<BoundingBox> labelBoxBounds = new List<BoundingBox>();

                    //if (cameraMan.PhotoMode != CameraMan.PhotoDisplayMode.Disabled)
                    //{
                    //    BoundingBox box = DrawPhoto(locations, target, cameraMan);
                    //    if (box != default(BoundingBox))
                    //    {
                    //        labelBoxBounds.Add(box);
                    //    }
                    //}

                    if (cameraMan.DrawPlaybackSpeed)
                    {
                        
                        string playString = "";
                        if (Replay.Speed == 0 /*|| _play==false*/)
                        {
                            playString = "||";
                        }
                        else if (Replay.Speed == 1)
                        {
                            playString = ">";
                        }
                        else if (Replay.Speed > 1)
                        {
                            playString = ">> " + Replay.Speed + "x";
                        }
                        else if (Replay.Speed == -1)
                        {
                            playString = "<";
                        }
                        else if (Replay.Speed < -1)
                        {
                            playString = "<< " + Replay.Speed + "x";
                        }
                        else
                        {
                            playString = "?";
                        }
                        _batch.DrawString(_font, playString, new Vector2(50, 50), new Color(new Vector4(1, 1, 1, .75f)));
                    }

                    if (cameraMan.ShowAnyIdentifiers)
                    {
                        foreach (ReplayBoat b in locations.Keys)
                        {
                            Vector2 p = locations[b];
                            if (IsBoatOnScreen(p, target))
                            {
                                List<string> text = new List<string>();
                                string topRow = "";

                                if (cameraMan.ShowName)
                                {
                                    topRow = topRow + b.Name;
                                }

                                if (cameraMan.ShowNumber)
                                {
                                    topRow = topRow + " " + b.Number;
                                }

                                if (cameraMan.ShowPosition)
                                {
                                    int pos = b.GetCurrentPosition(this.Replay.SimulationTime);
                                    string v = VerbageHelper.PositionString(pos);
                                    if (v.Length > 0)
                                    {
                                        topRow = topRow + " (" + v + ")";
                                    }
                                }

                                if (topRow.Length > 0)
                                {
                                    text.Add(topRow);
                                }

                                if (cameraMan.ShowSpeed)
                                {
                                    
                                    text.Add(ExtractBoatStatisticString(b, target, "Speed", this.Replay.SimulationTime));
                                }
                                if (cameraMan.ShowVMGToCourse)
                                {
                                    text.Add(ExtractBoatStatisticString(b, target, "VMG to Course", this.Replay.SimulationTime));
                                }
                                if (cameraMan.ShowDistanceToMark)
                                {
                                    text.Add(ExtractBoatStatisticString(b, target, "Distance to Mark", this.Replay.SimulationTime));
                                }
                                if (cameraMan.ShowDistanceToCourse)
                                {
                                    text.Add(ExtractBoatStatisticString(b, target, "Distance to Course", this.Replay.SimulationTime));
                                }
                                if (cameraMan.ShowAngleToMark)
                                {
                                    text.Add(ExtractBoatStatisticString(b, target, "Angle to Mark", this.Replay.SimulationTime));
                                }
                                if (cameraMan.ShowAngleToWind)
                                {
                                    text.Add(ExtractBoatStatisticString(b, target, "Angle to Wind", this.Replay.SimulationTime));
                                }
                                if (cameraMan.ShowAngleToCourse)
                                {
                                    text.Add(ExtractBoatStatisticString(b, target, "Angle to Course", this.Replay.SimulationTime));
                                }

                                DrawLabelBox(p, _batch, new Color(b.Color.R, b.Color.G, b.Color.B, b.Color.A), text, ref labelBoxBounds, viewport.Width, viewport.Height);
                            }
                        }
                    }

                    if (cameraMan.ShowMarkNames)
                    {
                        foreach (Bouy b in bouyLocations.Keys)
                        {
                            Vector2 p = bouyLocations[b];
                            if (p.X > 0 && p.X < viewport.Width && p.Y > 0 && p.Y < viewport.Height)
                            {
                                List<string> text = new List<string>();
                                text.Add(b.Mark.Name);
                                DrawLabelBox(p, _batch, new Color(new Vector3(1, 0.5f, 0)), text, ref labelBoxBounds, viewport.Width, viewport.Height);
                            }
                        }
                    }

                    _batch.End();
                }

                if (target.ClickedPoint != null)
                {
                    Vector2 clicked = new Vector2((float)target.ClickedPoint.Value.X, (float)target.ClickedPoint.Value.Y);
                    float minDistance = float.MaxValue;
                    int selectedIndex = -1;
                    for (int i = 0; i < locations.Keys.Count; i++)
                    {
                        float distance = Vector2.Distance(clicked, locations[locations.Keys.ElementAt(i)]);
                        if (distance < minDistance)
                        {
                            selectedIndex = i;
                            minDistance = distance;
                        }
                    }
                    if (minDistance < 25f)
                    {
                        target.SetSelectedBoatIndex(selectedIndex);
                    }
                    target.ClickedPoint = null;
                }

                try
                {
                    //make sure we have a handle before we try and draw
                    if (target.HasHandle)
                    {
                        lock (target.RenderTarget)
                        {
                            _device.Present(new Rectangle(0, 0, _device.Viewport.Width, _device.Viewport.Height), new Rectangle(0, 0, _device.Viewport.Width, _device.Viewport.Height), target.RenderTarget.Handle);

                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("No Handle");
                    }
                }
                catch (Exception)
                {
                    //if the windows are being docked/undocked or similiar, the handle might get destroyed mid-draw
                    //it's ok if this happens, we'll just draw again on the next frame.
                    //this is hacky, but i can't find a better way to prevent or catch this issue
                }

                if (target.Record == RecorderState.Recording && _xnaAviWriter != null && _xnaAviWriter.Recording)
                {
                    try
                    {
                        _xnaAviWriter.AddFrame();
                    }
                    catch
                    {
                        MessageBox.Show("The video codec or compression you selected is not compatible with VisualSail");
                        target.Record = RecorderState.Ready;
                    }
                }
            }
        }
Пример #2
0
        private void Render(IViewPort target)
        {
            //get our cameraman
            GdiCameraMan cameraMan = _viewports[target];

            //check the buffer size, make sure it matches the window
            //if not rebuild it
            if ((target.RenderTarget.Height > 0 && target.RenderTarget.Width>0) && (target.RenderTarget.Width != _buffers[target].Width || target.RenderTarget.Height != _buffers[target].Height))
            {
                lock (_buffers)
                {
                    _buffers[target].Dispose();
                    _buffers.Remove(target);
                    _buffers.Add(target, new Bitmap(target.RenderTarget.Width, target.RenderTarget.Height));
                }

                lock (_graphics)
                {
                    _graphics[target].Dispose();
                    _graphics.Remove(target);
                    _graphics.Add(target, Graphics.FromImage(_buffers[target]));
                }

                if (target.RenderTarget.IsHandleCreated)
                {
                    lock (_targetGraphics)
                    {
                        if (_targetGraphics[target] != null)
                        {
                            _targetGraphics[target].Dispose();
                            _targetGraphics.Remove(target);
                        }
                        _targetGraphics.Add(target, Graphics.FromHwnd(target.RenderTarget.Handle));
                    }
                }
            }


            _graphics[target].Transform = new System.Drawing.Drawing2D.Matrix();

            //clear the buffer to black
            _graphics[target].Clear(Color.Black);
            //_graphics[target].FillRectangle(Brushes.Black, 0, 0, _buffers[target].Width, _buffers[target].Height);

            int xOffset = target.RenderTarget.Width / 2;
            int yOffset = target.RenderTarget.Height / 2;
            _graphics[target].TranslateTransform(xOffset, yOffset, System.Drawing.Drawing2D.MatrixOrder.Prepend);
            _graphics[target].RotateTransform(cameraMan.Rotation, System.Drawing.Drawing2D.MatrixOrder.Prepend);
            


            ReplayBoat boat=this.Replay.Boats[cameraMan.SelectedBoat];
            if (boat.ProjectedPoint != null)
            {
                cameraMan.X = 0;
                cameraMan.Y = 0;
                cameraMan.FollowBoat(ProjectedPointToWorld(boat.ProjectedPoint, cameraMan));
            }

            float lakeX = ProjectedPointToWorld(Replay.Race.Lake.TopLeftInMeters,cameraMan).X;
            float lakeY = ProjectedPointToWorld(Replay.Race.Lake.TopLeftInMeters,cameraMan).Y;
            float lakeWidth = ProjectedPointToWorld(Replay.Race.Lake.BottomRightInMeters,cameraMan).X - lakeX;
            float lakeHeight = ProjectedPointToWorld(Replay.Race.Lake.BottomRightInMeters,cameraMan).Y - lakeY;

            

            _graphics[target].DrawImage(_lakeTexture, lakeX, lakeY, lakeWidth, lakeHeight);

            DateTime lineStart = this.Replay.SimulationTime;
            DateTime lineEnd = this.Replay.SimulationTime;

            if (cameraMan.DrawFuturePath)
            {
                lineEnd = this.Replay.SimulationTime + new TimeSpan(0, 0, cameraMan.DrawPathLength);
            }
            if (cameraMan.DrawPastPath)
            {
                lineStart = this.Replay.SimulationTime - new TimeSpan(0, 0, cameraMan.DrawPathLength);
            }

            foreach (ReplayBoat b in this.Replay.Boats)
            {
                if (b.ProjectedPoint != null)
                {
                    _graphics[target].FillRectangle(new SolidBrush(b.Color), ProjectedPointToWorld(b.ProjectedPoint,cameraMan).X-2, ProjectedPointToWorld(b.ProjectedPoint,cameraMan).Y-2, 4, 4);

                    if (cameraMan.DrawFuturePath || cameraMan.DrawPastPath)
                    {
                        var points = from pp in _boatTracks[b]
                                     where pp.Key >= lineStart
                                     && pp.Key <= lineEnd
                                     select pp.Value;

                        var projectedPoints = from pp in points
                                              select ProjectedPointToWorld(pp, cameraMan);

                        var drawPoints = (from pp in projectedPoints
                                         select new System.Drawing.Point((int)pp.X, (int)pp.Y)).ToArray();

                        _graphics[target].DrawLines(new Pen(new SolidBrush(b.Color)), drawPoints);
                    }
                }
            }

            foreach (Mark mark in this.Replay.Race.Course.Marks)
            {
                foreach (Bouy bouy in mark.Bouys)
                {
                    _graphics[target].FillRectangle(Brushes.Orange, ProjectedPointToWorld(bouy.CoordinatePoint.Project(),cameraMan).X - 2, ProjectedPointToWorld(bouy.CoordinatePoint.Project(),cameraMan).Y - 2, 4, 4);
                }
            }

            _graphics[target].Flush();
            _targetGraphics[target].DrawImage(_buffers[target], 0, 0);
            _targetGraphics[target].Flush();
            
            //Graphics targetGraphics = _targetGraphics[target];
            //buffer.Save("C:\\test.bmp");
            //targetGraphics.DrawImage(buffer, 0, 0);

            //    if (cameraMan.DrawGrid)
            //    {
            //        _instruments.World = Matrix.Identity;
            //        _instruments.Begin();
            //        foreach (EffectPass pass in _instruments.CurrentTechnique.Passes)
            //        {
            //            pass.Begin();
            //            _device.VertexDeclaration = VertexDeclarationHelper.Get(typeof(VertexPositionColor));
            //            _device.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, _gridLines, 0, _gridLines.Length / 2);
            //            pass.End();
            //        }
            //        _instruments.End();
            //    }
            //    Dictionary<ReplayBoat, Vector2> locations = new Dictionary<ReplayBoat, Vector2>();
            //    foreach (ReplayBoat b in this.Replay.Boats)
            //    {
            //        DrawHUD(b, _device, cameraMan, this.Replay.SimulationTime, _coordinateDivisor);
            //        if (cameraMan.ShowAnyIdentifiers || target.ClickedPoint != null || cameraMan.PhotoMode != CameraMan.PhotoDisplayMode.Disabled)
            //        {
            //            if (b.ProjectedPoint != null)
            //            {
            //                Vector3 twoD = viewport.Project(b.ProjectedPoint.ToWorld(), camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
            //                if (twoD.Z < 1f)
            //                {
            //                    locations.Add(b, new Vector2(twoD.X, twoD.Y));
            //                }
            //            }
            //        }
            //    }
            //    foreach (ReplayBoat b in this.Replay.Boats)
            //    {
            //        DrawBoat(b, _device, cameraMan, this.Replay.SimulationTime);
            //    }

            //    Dictionary<Bouy, Vector2> bouyLocations = new Dictionary<Bouy, Vector2>();
            //    foreach (Mark m in this.Replay.Race.Course.Marks)
            //    {
            //        foreach (Bouy b in m.Bouys)
            //        {
            //            DrawBouy(b, _device, camera);
            //            if (cameraMan.ShowMarkNames)
            //            {
            //                Vector3 twoD = viewport.Project(b.CoordinatePoint.Project().ToWorld(), camera.ProjectionMatrix, camera.ViewMatrix, Matrix.Identity);
            //                if (twoD.Z < 1f)
            //                {
            //                    bouyLocations.Add(b, new Vector2(twoD.X, twoD.Y));
            //                }
            //            }
            //        }
            //    }

            //    ////course navigation debug lines
            //    //List<VertexPositionColor> markRoundLines = new List<VertexPositionColor>();
            //    //for (int i = 0; i < this.Race.Course.Route.Count; i++)
            //    //{
            //    //    if (i > 0 && i < this.Race.Course.Route.Count - 1)
            //    //    {
            //    //        Vector3 a = this.Race.Course.Route[i].AveragedLocation.Project().ToWorld();
            //    //        Vector2 b2 = this.Race.Course.Route[i].FindMarkRoundPoint(this.Race.Course.Route[i - 1], this.Race.Course.Route[i + 1]);
            //    //        Vector3 b = a;
            //    //        b.X = b2.X;
            //    //        b.Z = b2.Y;

            //    //        VertexPositionColor vpcA = new VertexPositionColor(a, Color.Red);
            //    //        VertexPositionColor vpcB = new VertexPositionColor(b, Color.Red);
            //    //        markRoundLines.Add(vpcA);
            //    //        markRoundLines.Add(vpcB);
            //    //    }
            //    //}

            //    //instruments.World = Matrix.Identity;
            //    //instruments.Begin();
            //    //foreach (EffectPass pass in instruments.CurrentTechnique.Passes)
            //    //{
            //    //    pass.Begin();
            //    //    device.VertexDeclaration = VertexDeclarationHelper.Get(typeof(VertexPositionColor));
            //    //    device.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, markRoundLines.ToArray(), 0, markRoundLines.Count/2);
            //    //    pass.End();
            //    //}
            //    //instruments.End();

            //    DrawMouseInstructions(DateTime.Now - target.CreatedAt, viewport.Width, viewport.Height);

            //    if (cameraMan.ShowAnyIdentifiers || cameraMan.ShowMarkNames || cameraMan.DrawPlaybackSpeed || cameraMan.PhotoMode != CameraMan.PhotoDisplayMode.Disabled)
            //    {
            //        _batch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState);
            //        List<BoundingBox> labelBoxBounds = new List<BoundingBox>();

            //        //if (cameraMan.PhotoMode != CameraMan.PhotoDisplayMode.Disabled)
            //        //{
            //        //    BoundingBox box = DrawPhoto(locations, target, cameraMan);
            //        //    if (box != default(BoundingBox))
            //        //    {
            //        //        labelBoxBounds.Add(box);
            //        //    }
            //        //}

            //        if (cameraMan.DrawPlaybackSpeed)
            //        {

            //            string playString = "";
            //            if (Replay.Speed == 0 /*|| _play==false*/)
            //            {
            //                playString = "||";
            //            }
            //            else if (Replay.Speed == 1)
            //            {
            //                playString = ">";
            //            }
            //            else if (Replay.Speed > 1)
            //            {
            //                playString = ">> " + Replay.Speed + "x";
            //            }
            //            else if (Replay.Speed == -1)
            //            {
            //                playString = "<";
            //            }
            //            else if (Replay.Speed < -1)
            //            {
            //                playString = "<< " + Replay.Speed + "x";
            //            }
            //            else
            //            {
            //                playString = "?";
            //            }
            //            _batch.DrawString(_font, playString, new Vector2(50, 50), new Color(new Vector4(1, 1, 1, .75f)));
            //        }

            //        if (cameraMan.ShowAnyIdentifiers)
            //        {
            //            foreach (ReplayBoat b in locations.Keys)
            //            {
            //                Vector2 p = locations[b];
            //                if (IsBoatOnScreen(p, target))
            //                {
            //                    List<string> text = new List<string>();
            //                    string topRow = "";

            //                    if (cameraMan.ShowName)
            //                    {
            //                        topRow = topRow + b.Name;
            //                    }

            //                    if (cameraMan.ShowNumber)
            //                    {
            //                        topRow = topRow + " " + b.Number;
            //                    }

            //                    if (cameraMan.ShowPosition)
            //                    {
            //                        int pos = b.GetCurrentPosition(this.Replay.SimulationTime);
            //                        string v = VerbageHelper.PositionString(pos);
            //                        if (v.Length > 0)
            //                        {
            //                            topRow = topRow + " (" + v + ")";
            //                        }
            //                    }

            //                    if (topRow.Length > 0)
            //                    {
            //                        text.Add(topRow);
            //                    }

            //                    if (cameraMan.ShowSpeed)
            //                    {

            //                        text.Add(ExtractBoatStatisticString(b, target, "Speed", this.Replay.SimulationTime));
            //                    }
            //                    if (cameraMan.ShowVMGToCourse)
            //                    {
            //                        text.Add(ExtractBoatStatisticString(b, target, "VMG to Course", this.Replay.SimulationTime));
            //                    }
            //                    if (cameraMan.ShowDistanceToMark)
            //                    {
            //                        text.Add(ExtractBoatStatisticString(b, target, "Distance to Mark", this.Replay.SimulationTime));
            //                    }
            //                    if (cameraMan.ShowDistanceToCourse)
            //                    {
            //                        text.Add(ExtractBoatStatisticString(b, target, "Distance to Course", this.Replay.SimulationTime));
            //                    }
            //                    if (cameraMan.ShowAngleToMark)
            //                    {
            //                        text.Add(ExtractBoatStatisticString(b, target, "Angle to Mark", this.Replay.SimulationTime));
            //                    }
            //                    if (cameraMan.ShowAngleToWind)
            //                    {
            //                        text.Add(ExtractBoatStatisticString(b, target, "Angle to Wind", this.Replay.SimulationTime));
            //                    }
            //                    if (cameraMan.ShowAngleToCourse)
            //                    {
            //                        text.Add(ExtractBoatStatisticString(b, target, "Angle to Course", this.Replay.SimulationTime));
            //                    }

            //                    DrawLabelBox(p, _batch, new Color(b.Color.R, b.Color.G, b.Color.B, b.Color.A), text, ref labelBoxBounds, viewport.Width, viewport.Height);
            //                }
            //            }
            //        }

            //        if (cameraMan.ShowMarkNames)
            //        {
            //            foreach (Bouy b in bouyLocations.Keys)
            //            {
            //                Vector2 p = bouyLocations[b];
            //                if (p.X > 0 && p.X < viewport.Width && p.Y > 0 && p.Y < viewport.Height)
            //                {
            //                    List<string> text = new List<string>();
            //                    text.Add(b.Mark.Name);
            //                    DrawLabelBox(p, _batch, new Color(new Vector3(1, 0.5f, 0)), text, ref labelBoxBounds, viewport.Width, viewport.Height);
            //                }
            //            }
            //        }

            //        _batch.End();
            //    }

            if (target.ClickedPoint != null)
            {
                Vector3 clicked = new Vector3((float)target.ClickedPoint.Value.X-xOffset, (float)target.ClickedPoint.Value.Y-yOffset,0f);
                float minDistance = float.MaxValue;
                int selectedIndex = -1;
                for (int i = 0; i < Replay.Boats.Count; i++)
                {
                    Vector3 boatLocation = ProjectedPointToWorld(Replay.Boats[i].ProjectedPoint, cameraMan);
                    float distance = Vector3.Distance(clicked, boatLocation);
                    if (distance < minDistance)
                    {
                        selectedIndex = i;
                        minDistance = distance;
                    }
                }
                if (minDistance < 25f)
                {
                    target.SetSelectedBoatIndex(selectedIndex);
                }
                target.ClickedPoint = null;
            }

            //    try
            //    {
            //        //make sure we have a handle before we try and draw
            //        if (target.HasHandle)
            //        {
            //            lock (target.RenderTarget)
            //            {
            //                _device.Present(new Rectangle(0, 0, _device.Viewport.Width, _device.Viewport.Height), new Rectangle(0, 0, _device.Viewport.Width, _device.Viewport.Height), target.RenderTarget.Handle);

            //            }
            //        }
            //        else
            //        {
            //            throw new InvalidOperationException("No Handle");
            //        }
            //    }
            //    catch (Exception)
            //    {
            //        //if the windows are being docked/undocked or similiar, the handle might get destroyed mid-draw
            //        //it's ok if this happens, we'll just draw again on the next frame.
            //        //this is hacky, but i can't find a better way to prevent or catch this issue
            //    }

            //    if (target.Record == RecorderState.Recording && _xnaAviWriter != null && _xnaAviWriter.Recording)
            //    {
            //        try
            //        {
            //            _xnaAviWriter.AddFrame();
            //        }
            //        catch
            //        {
            //            MessageBox.Show("The video codec or compression you selected is not compatible with VisualSail");
            //            target.Record = RecorderState.Ready;
            //        }
            //    }
            //}
        }