Exemplo n.º 1
0
        public void Viewport_Paint()
        {
            if (SurfaceMesh != null)
            {
                Vector3[] Bounds     = SurfaceMesh.BoundingBoxCorners;
                Matrix4   ViewMatrix = Viewport.Camera.GetView();

                float MinDist = float.MaxValue;
                float MaxDist = -float.MaxValue;

                foreach (var corner in Bounds)
                {
                    float Dist = -Vector3.Transform(corner, ViewMatrix).Z;
                    MinDist = Math.Min(MinDist, Dist);
                    MaxDist = Math.Max(MaxDist, Dist);
                }

                MainWindow.Options.Viewport.Camera.ClipNear = Math.Max(1f, MinDist / 2);
                MainWindow.Options.Viewport.Camera.ClipFar  = Math.Max(2f, MaxDist * 2);
            }

            MeshProgram.Use();
            {
                MeshProgram.SetUniform("worldViewProjMatrix", MainWindow.Options.Viewport.Camera.GetViewProj());
                MeshProgram.SetUniform("surfaceOffset", (float)SurfaceOffset * MainWindow.Options.PixelScale.X);

                if (TomogramTexture != null)
                {
                    MeshProgram.SetUniform("useVolume", 1f);
                    MeshProgram.SetUniform("volScale", OpenGLHelper.Reciprocal(TomogramTexture.Scale));
                    MeshProgram.SetUniform("volOffset", TomogramTexture.Offset);
                    MeshProgram.SetUniform("texSize", OpenGLHelper.Reciprocal(TomogramTexture.Size));

                    GL.ActiveTexture(TextureUnit.Texture0);
                    GL.BindTexture(TextureTarget.Texture3D, TomogramTexture.Handle);
                }
                else
                {
                    MeshProgram.SetUniform("useVolume", 0f);
                }

                GL.ActiveTexture(TextureUnit.Texture1);
                GL.BindTexture(TextureTarget.Texture2D, SelectionTexture.Handle);

                float TraceStart  = TraceDepthOffset;
                float TraceLength = TraceDepth;
                MeshProgram.SetUniform("traceParams", new Vector2(TraceStart, TraceLength));
                MeshProgram.SetUniform("traceSharpening", (float)TraceSharpening / 100f);

                float RangeMin = (float)Math.Min(OutputRangeMin, OutputRangeMax), RangeMax = (float)Math.Max(OutputRangeMin, OutputRangeMax);
                MeshProgram.SetUniform("normalizeParams", new Vector2(RangeMin, RangeMax - RangeMin));

                Vector3 LightDirection = MainWindow.Options.Viewport.Camera.GetDirection();
                MeshProgram.SetUniform("lightDirection", LightDirection);
                MeshProgram.SetUniform("lightIntensity", OutputLight / 100f);

                if (SurfaceMesh != null)
                {
                    SurfaceMesh.Draw();
                }
            }

            // Draw point groups. There are 3 options for depiction:
            // - Boxes with custom size
            // - Same mesh for every point in a group, e. g. protein map from EMDB
            // - Individual mesh for every point in a group, e. g. isosurface within its enclosed volume
            {
                List <PointGroup> AllGroups = new List <PointGroup>(PointGroups);
                AllGroups.Add(PreviewGroup);
                foreach (PointGroup group in AllGroups.Where(g => g.IsVisible && g.Points.Count > 0))
                {
                    if (group.Depiction == PointDepiction.Box)
                    {
                        // Draw orientation gizmos
                        PointGizmoProgram.Use();
                        PointGizmoProgram.SetUniform("worldViewProjMatrix", MainWindow.Options.Viewport.Camera.GetViewProj());
                        GL.LineWidth(10f);
                        PointGizmoProgram.SetUniform("cubeSize", (float)group.Size * MainWindow.Options.PixelScale.X);
                        group.PointCloud.Draw();

                        // Draw boxes
                        PointProgram.Use();
                        PointProgram.SetUniform("worldViewProjMatrix", MainWindow.Options.Viewport.Camera.GetViewProj());

                        // Draw back faces first, then front, to ensure correct transparency (locally)
                        GL.Enable(EnableCap.CullFace);
                        GL.CullFace(CullFaceMode.Front);

                        PointProgram.SetUniform("cubeSize", (float)group.Size * MainWindow.Options.PixelScale.X);
                        group.PointCloud.Draw();

                        GL.CullFace(CullFaceMode.Back);
                        PointProgram.SetUniform("cubeSize", (float)group.Size * MainWindow.Options.PixelScale.X);
                        group.PointCloud.Draw();
                        GL.Disable(EnableCap.CullFace);
                    }
                    else if (group.Depiction == PointDepiction.Mesh)
                    {
                        PointModelProgram.Use();
                        PointModelProgram.SetUniform("modelColor", ColorHelper.ColorToVector(group.Color, true));
                        PointModelProgram.SetUniform("cameraDirection", Viewport.Camera.GetDirection());

                        foreach (var point in group.Points)
                        {
                            PointModelProgram.SetUniform("isSelected", point.IsSelected ? 1f : 0f);
                            Vector3 Offset = point.TransformedMatrix.Column2 * (float)group.DepictionMeshOffset;
                            PointModelProgram.SetUniform("worldViewProjMatrix", Matrix4.CreateTranslation(point.Position + Offset) * MainWindow.Options.Viewport.Camera.GetViewProj());
                            PointModelProgram.SetUniform("rotationMatrix", Matrix3.Transpose(point.TransformedMatrix));

                            group.DepictionMesh?.Draw();
                        }
                    }
                    else if (group.Depiction == PointDepiction.LocalSurface)
                    {
                        PointModelProgram.Use();
                        PointModelProgram.SetUniform("modelColor", ColorHelper.ColorToVector(group.Color, true));
                        PointModelProgram.SetUniform("cameraDirection", Viewport.Camera.GetDirection());

                        foreach (var point in group.Points)
                        {
                            PointModelProgram.SetUniform("isSelected", point.IsSelected ? 1f : 0f);
                            PointModelProgram.SetUniform("worldViewProjMatrix", Matrix4.CreateTranslation(point.Position) * MainWindow.Options.Viewport.Camera.GetViewProj());
                            PointModelProgram.SetUniform("rotationMatrix", Matrix3.Identity);

                            point.DepictionMesh?.Draw();
                        }

                        // Also draw the orientation stick
                        if (KeyboardHelper.CtrlDown())
                        {
                            PointGizmoProgram.Use();
                            PointGizmoProgram.SetUniform("worldViewProjMatrix", MainWindow.Options.Viewport.Camera.GetViewProj());
                            GL.LineWidth(10f);
                            PointGizmoProgram.SetUniform("cubeSize", (float)group.Size * MainWindow.Options.PixelScale.X);
                            group.PointCloud.Draw();
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        private void Viewport_Paint()
        {
            lock (RenderSync)
            {
                Viewport.MakeCurrent();

                Membrane.MeshProgram.Use();
                {
                    Membrane.MeshProgram.SetUniform("worldViewProjMatrix", Viewport.Camera.GetViewProj());
                    Membrane.MeshProgram.SetUniform("surfaceOffset",
                                                    (float)SurfaceOffset * MainWindow.Options.PixelScale.X);

                    if (Membrane.TomogramTexture != null)
                    {
                        Membrane.MeshProgram.SetUniform("useVolume", 1f);
                        Membrane.MeshProgram.SetUniform("volScale", OpenGLHelper.Reciprocal(Membrane.TomogramTexture.Scale));
                        Membrane.MeshProgram.SetUniform("volOffset", Membrane.TomogramTexture.Offset);
                        Membrane.MeshProgram.SetUniform("texSize", OpenGLHelper.Reciprocal(Membrane.TomogramTexture.Size));

                        GL.ActiveTexture(TextureUnit.Texture0);
                        GL.BindTexture(TextureTarget.Texture3D, Membrane.TomogramTexture.Handle);
                    }
                    else
                    {
                        Membrane.MeshProgram.SetUniform("useVolume", 0f);
                    }

                    GL.ActiveTexture(TextureUnit.Texture1);
                    GL.BindTexture(TextureTarget.Texture2D, Membrane.SelectionTexture.Handle);

                    float TraceStart  = TraceDepthOffset;
                    float TraceLength = TraceDepth;
                    Membrane.MeshProgram.SetUniform("traceParams", new Vector2(TraceStart, TraceLength));
                    Membrane.MeshProgram.SetUniform("traceSharpening", (float)TraceSharpening / 100f);

                    float RangeMin = (float)Math.Min(OutputRangeMin, OutputRangeMax),
                          RangeMax = (float)Math.Max(OutputRangeMin, OutputRangeMax);
                    Membrane.MeshProgram.SetUniform("normalizeParams", new Vector2(RangeMin, RangeMax - RangeMin));

                    Vector3 LightDirection = Viewport.Camera.GetDirection();
                    Membrane.MeshProgram.SetUniform("lightDirection", LightDirection);
                    Membrane.MeshProgram.SetUniform("lightIntensity", 0.0f);

                    SurfaceMesh?.Draw();
                }

                Membrane.PointProgram.Use();
                {
                    Membrane.PointProgram.SetUniform("worldViewProjMatrix",
                                                     MainWindow.Options.Viewport.Camera.GetViewProj());

                    // Draw back faces first, then front, to ensure correct transparency (locally)
                    GL.Enable(EnableCap.CullFace);
                    GL.CullFace(CullFaceMode.Front);
                    foreach (PointGroup group in PointGroups.Where(g => g.IsVisible && g.Points.Count > 0))
                    {
                        Membrane.PointProgram.SetUniform("cubeSize",
                                                         (float)group.Size * MainWindow.Options.PixelScale.X);
                        group.PointCloud.Draw();
                    }
                    GL.CullFace(CullFaceMode.Back);
                    foreach (PointGroup group in PointGroups.Where(g => g.IsVisible && g.Points.Count > 0))
                    {
                        Membrane.PointProgram.SetUniform("cubeSize",
                                                         (float)group.Size * MainWindow.Options.PixelScale.X);
                        group.PointCloud.Draw();
                    }
                    GL.Disable(EnableCap.CullFace);
                }
            }
        }