protected override void Draw3DContent(UiContext context, RectangleF rect)
        {
            var cam = GetCamera(3f, context, rect);

            context.CommandBuffer.StartFrame(context.RenderContext);
            Skeleton.GetTransforms(Matrix4x4.Identity,
                                   out var headTransform,
                                   out var leftTransform,
                                   out var rightTransform
                                   );
            var lighting = Lighting.Empty;

            Skeleton.UploadBoneData(context.CommandBuffer.BonesBuffer);
            Skeleton.Body.SetSkinning(Skeleton.BodySkinning);
            Skeleton.Body.Update(cam, 0.0, 0.0);
            Skeleton.Body.DrawBuffer(context.CommandBuffer, Matrix4x4.Identity, ref lighting);
            if (Skeleton.Head != null)
            {
                Skeleton.Head.SetSkinning(Skeleton.HeadSkinning);
                Skeleton.Head.Update(cam, 0.0, 0.0);
                Skeleton.Head.DrawBuffer(context.CommandBuffer, headTransform, ref lighting);
            }
            if (Skeleton.LeftHand != null)
            {
                Skeleton.LeftHand.SetSkinning(Skeleton.LeftHandSkinning);
                Skeleton.LeftHand.Update(cam, 0.0, 0.0);
                Skeleton.LeftHand.DrawBuffer(context.CommandBuffer, leftTransform, ref lighting);
            }
            if (Skeleton.RightHand != null)
            {
                Skeleton.RightHand.SetSkinning(Skeleton.RightHandSkinning);
                Skeleton.RightHand.Update(cam, 0.0, 0.0);
                Skeleton.RightHand.DrawBuffer(context.CommandBuffer, rightTransform, ref lighting);
            }
            context.CommandBuffer.DrawOpaque(context.RenderContext);
            context.RenderContext.DepthWrite = false;
            context.CommandBuffer.DrawTransparent(context.RenderContext);
            context.RenderContext.DepthWrite = true;
        }
        void DrawGL(int renderWidth, int renderHeight, bool viewport)
        {
            if (_window.Config.BackgroundGradient && viewport && doBackground)
            {
                _window.Renderer2D.Start(renderWidth, renderHeight);
                _window.Renderer2D.DrawVerticalGradient(new Rectangle(0, 0, renderWidth, renderHeight), _window.Config.Background, _window.Config.Background2);
                _window.Renderer2D.Finish();
            }
            rstate.DepthEnabled = true;
            rstate.Cull         = true;
            ICamera cam;
            //Draw Model
            var lookAtCam = new LookAtCamera();
            var rot       = Matrix4x4.CreateRotationX(modelViewport.CameraRotation.Y) *
                            Matrix4x4.CreateRotationY(modelViewport.CameraRotation.X);
            var dir = Vector3.Transform(-Vector3.UnitZ, rot);
            var to  = modelViewport.CameraOffset + (dir * 10);

            if (modelViewport.Mode == CameraModes.Arcball)
            {
                to = Vector3.Zero;
            }
            lookAtCam.Update(renderWidth, renderHeight, modelViewport.CameraOffset, to, rot);
            ThnCamera tcam  = null;
            float     znear = 0;
            float     zfar  = 0;

            if (modelViewport.Mode == CameraModes.Cockpit)
            {
                var vp = new Viewport(0, 0, renderWidth, renderHeight);
                tcam = new ThnCamera(vp);
                tcam.Transform.AspectRatio = renderWidth / (float)renderHeight;
                var tr = Matrix4x4.Identity;
                if (!string.IsNullOrEmpty(cameraPart.Construct?.ParentName))
                {
                    tr = cameraPart.Construct.LocalTransform *
                         vmsModel.Parts[cameraPart.Construct.ParentName].LocalTransform;
                }
                else if (cameraPart.Construct != null)
                {
                    tr = cameraPart.Construct.LocalTransform;
                }
                tcam.Transform.Orientation = Matrix4x4.CreateFromQuaternion(tr.ExtractRotation());
                tcam.Transform.Position    = Vector3.Transform(Vector3.Zero, tr);
                znear = cameraPart.Camera.Znear;
                zfar  = cameraPart.Camera.Zfar;
                tcam.Transform.Znear = 0.001f;
                tcam.Transform.Zfar  = 1000;
                tcam.Transform.FovH  = MathHelper.RadiansToDegrees(cameraPart.Camera.Fovx);
                tcam.frameNo         = fR++;
                tcam.Update();
                cam = tcam;
            }
            else
            {
                cam = lookAtCam;
            }
            if (showGrid && viewport &&
                !(drawable is SphFile) &&
                modelViewport.Mode != CameraModes.Starsphere)
            {
                GridRender.Draw(rstate, cam, _window.Config.GridColor);
            }
            _window.DebugRender.StartFrame(cam, rstate);
            if (drawable is DF.DfmFile dfm)
            {
                skel.UploadBoneData(buffer.BonesBuffer);
                dfm.SetSkinning(skel.BodySkinning);
                dfm.Update(cam, TimeSpan.Zero, TimeSpan.FromSeconds(_window.TotalTime));
            }
            if (vmsModel != null)
            {
                vmsModel.UpdateTransform();
                vmsModel.Update(cam, TimeSpan.FromSeconds(_window.TotalTime), _window.Resources);
            }
            if (viewMode != M_NONE)
            {
                int drawCount = (modelViewport.Mode == CameraModes.Cockpit) ? 2 : 1;
                for (int i = 0; i < drawCount; i++)
                {
                    buffer.StartFrame(rstate);
                    if (i == 1)
                    {
                        rstate.ClearDepth();
                        tcam.Transform.Zfar  = zfar;
                        tcam.Transform.Znear = znear;
                        tcam.frameNo         = fR++;
                        tcam.Update();
                    }
                    DrawSimple(cam, false);
                    buffer.DrawOpaque(rstate);
                    rstate.DepthWrite = false;
                    buffer.DrawTransparent(rstate);
                    rstate.DepthWrite = true;
                }
            }
            if (doWireframe)
            {
                buffer.StartFrame(rstate);
                GL.PolygonOffset(1, 1);
                rstate.Wireframe = true;
                DrawSimple(cam, true);
                GL.PolygonOffset(0, 0);
                buffer.DrawOpaque(rstate);
                rstate.Wireframe = false;
            }
            if (drawVMeshWire)
            {
                DrawWires();
            }
            //Draw VMeshWire (if used)
            _window.DebugRender.Render();
            //Draw Sur
            if (surs != null)
            {
                RenderSurs(cam);
            }
            //Draw hardpoints
            DrawHardpoints(cam);
            if (drawSkeleton)
            {
                DrawSkeleton(cam);
            }
        }