Beispiel #1
0
        public void Execute(IScene scene, ICamera camera, IOffScreen offScreen, float timestamp, IPropertyBag settings)
        {
            var drawBackground = settings.SearchValue<bool>(DrawBackgroundProp);
            var drawHighlight = settings.SearchValue<bool>(DrawHighlightProp);
            var drawSketch = settings.SearchValue<bool>(DrawSketchProp);

            if (drawBackground)
                offScreen.Framebuffer.ClearColor(0, scene.BackgroundColor.ToOgl());
            offScreen.Framebuffer.ClearDepthStencil(DepthStencil.Both, 1f, 0);

            var glContext = infra.GlContext;
            var commonObjects = infra.CommonObjects;

            glContext.States.ScreenClipping.United.Viewport.Set(offScreen.Width, offScreen.Height);

            var aspectRatio = GraphicsHelper.AspectRatio(offScreen.Width, offScreen.Height);
            var viewFrame = camera.GetGlobalFrame();
            var viewProjMat = viewFrame.GetViewMat() * camera.GetProjectionMat(aspectRatio);

            if (drawBackground && scene.Skybox != null)
            {
                var glTextureCubemap = scene.Skybox.CacheContainer.GetOrAddCache(Tuples.Pair(infra, scene.Skybox), x => new SkyboxCache(x.First, x.Second)).GetGlTextureCubemap();
                skyboxDrawer.Draw(glTextureCubemap, viewFrame, camera.GetFov(), aspectRatio);
            }

            void FillForSubtree(ISceneNode subtreeRoot, bool alreadyFocus, bool alreadyHighlighted, bool alreadyOverlay)
            {
                var effects = subtreeRoot
                    .SearchComponents<IVisualComponent>()
                    .SelectMany(x => x.GetVisualEffects());
                foreach (var effect in effects)
                    switch (effect)
                    {
                        case FocusVisualEffect _:
                            alreadyFocus = true;
                            break;
                        case HighlightVisualEffect _:
                            alreadyHighlighted = true;
                            break;
                    }
                var elements = subtreeRoot
                    .SearchComponents<IVisualComponent>()
                    .SelectMany(x => x.GetVisualElements());
                foreach (var element in elements.Where(x => !x.Hide))
                {
                    var handler = handlerContainer.ChooseHandler(element);
                    var queueItem = new RenderQueueItem(element, handler, subtreeRoot, alreadyHighlighted);
                    if (alreadyOverlay)
                        overlayQueue.Add(Tuples.Pair(queueItem, handler));
                    else if (alreadyFocus)
                        focusedQueue.Add(Tuples.Pair(queueItem, handler));
                    else
                        regularQueue.Add(Tuples.Pair(queueItem, handler));
                }

                foreach (var childNode in subtreeRoot.ChildNodes)
                    FillForSubtree(childNode, alreadyFocus, alreadyHighlighted, alreadyOverlay);
            }

            FillForSubtree(scene.Root, false, false, false);
            foreach (var auxuliaryNode in scene.AuxuliaryNodes)
                FillForSubtree(auxuliaryNode, false, false, true);

            

            glContext.States.Rasterizer.FrontFace.Set(FrontFaceDirection.Ccw);
            glContext.States.Rasterizer.CullFaceEnable.Set(false);
            glContext.States.Rasterizer.CullFace.Set(CullFaceMode.Back);
            glContext.States.DepthStencil.DepthTestEnable.Set(true);
            glContext.States.DepthStencil.DepthMask.Set(true);
            glContext.GL.Enable((int)All.FramebufferSrgb);

            commonObjects.CameraUb.SetData(viewProjMat);
            commonObjects.CameraExtraUb.SetData(viewFrame.Eye);
            var lightPos = viewFrame.Eye + 0.5f * viewFrame.Right + 0.5f * viewFrame.Up;
            commonObjects.LightUb.SetData(lightPos);
            commonObjects.GlobalUb.SetData(new GlobalUniform
            {
                ScreenWidth = offScreen.Width,
                ScreenHeight = offScreen.Height,
                Time = timestamp
            });

            commonObjects.TransformUb.Bind(glContext, 0);
            commonObjects.CameraUb.Bind(glContext, 1);
            commonObjects.CameraExtraUb.Bind(glContext, 2);
            commonObjects.LightUb.Bind(glContext, 3);
            commonObjects.MaterialUb.Bind(glContext, 4);
            commonObjects.GlobalUb.Bind(glContext, 5);

            RenderSceneSubset(camera, aspectRatio, regularQueue);
            
            if (focusedQueue.HasItems())
            {
                offScreen.Resolve();
                glContext.Bindings.Framebuffers.Draw.Set(offScreen.Framebuffer);
                blurDrawer.Draw(offScreen.ResolvedTex);
                offScreen.Framebuffer.ClearDepthStencil(DepthStencil.Depth, 1f, 0);
                RenderSceneSubset(camera, aspectRatio, focusedQueue);
            }
            if (drawHighlight)
                highlightDrawer.Draw(offScreen.Framebuffer, offScreen.DepthBuffer);

            offScreen.Framebuffer.ClearDepthStencil(DepthStencil.Depth, 1f, 0);
            RenderSceneSubset(camera, aspectRatio, overlayQueue);

            if (drawSketch)
                sketchDrawer.Draw();

            if (camera.VeilColor.A > 0)
                veilDrawer.Draw(camera.VeilColor);
            
            regularQueue.Clear();
            focusedQueue.Clear();
            overlayQueue.Clear();
        }