예제 #1
0
 public void DrawEntityShadowVolume(DynamicLight Light, ShaderMaterial ShadowVolume)
 {
     RenderAPI.DbgPushGroup("Entity DrawShadowVolume");
     for (int i = 0; i < Entities.Length; i++)
     {
         Entities[i].DrawShadowVolume(Light.GetBoundingSphere(), ShadowVolume);
     }
     RenderAPI.DbgPopGroup();
 }
예제 #2
0
 public void DrawShadowVolume(ShaderMaterial ShadowVolume)
 {
     RenderAPI.DbgPushGroup("Map DrawShadowVolume");
     for (int ModelIdx = 0; ModelIdx < MapModels.Length; ModelIdx++)
     {
         MapModels[ModelIdx].DrawShadowVolume(ShadowVolume);
     }
     RenderAPI.DbgPopGroup();
 }
예제 #3
0
        public virtual void DrawViewModel()
        {
            RenderAPI.DbgPushGroup("Player DrawViewModel");

            ViewModelCamera.Position = Camera.Position;
            ViewModelCamera.Rotation = Camera.Rotation;

            Camera OldCam = ShaderUniforms.Current.Camera;

            ShaderUniforms.Current.Camera = ViewModelCamera;
            CurrentWeapon?.DrawViewModel(this);
            ShaderUniforms.Current.Camera = OldCam;

            RenderAPI.DbgPopGroup();
        }
예제 #4
0
        public void DrawTransparent()
        {
            RenderAPI.DbgPushGroup("Map DrawTransparent");
            for (int ModelIdx = 0; ModelIdx < MapModels.Length; ModelIdx++)
            {
                MapModels[ModelIdx].DrawTransparent();
            }
            RenderAPI.DbgPopGroup();

            RenderAPI.DbgPushGroup("Entity DrawTransparent");
            for (int EntityIdx = 0; EntityIdx < Entities.Length; EntityIdx++)
            {
                Entities[EntityIdx]?.DrawTransparent();
            }
            RenderAPI.DbgPopGroup();
        }
예제 #5
0
        public override void DrawMesh(Mesh3D Mesh)
        {
            RenderAPI.DbgPushGroup("Fog DrawMesh");

            RenderAPI.DbgPushGroup("Depth capture");
            DepthCapture.Push();
            {
                Gfx.Clear(Color.Transparent);
                RenderState RS = Gfx.PeekRenderState();
                RS.EnableBlend = true;
                RS.BlendFunc(BlendFactor.One, BlendFactor.One);
                RS.EnableDepthTest = false;


                RS.EnableCullFace = true;
                RS.CullFace       = CullFace.Back;
                RS.SetColorMask(true, true, false, false);

                DepthThicknessShader.Bind(ShaderUniforms.Current);

                // First pass
                RenderAPI.DbgPushGroup("Draw front face");
                Gfx.PushRenderState(RS);
                {
                    DepthThicknessShader.Uniform1f("Scale", 1.0f);
                    Mesh.Draw();
                }
                Gfx.PopRenderState();
                RenderAPI.DbgPopGroup();

                // Second pass
                RS.CullFace = CullFace.Front;
                RS.SetColorMask(true, false, false, false);
                RenderAPI.DbgPushGroup("Draw back face");
                Gfx.PushRenderState(RS);
                {
                    DepthThicknessShader.Uniform1f("Scale", -1.0f);
                    Mesh.Draw();
                }
                Gfx.PopRenderState();
                RenderAPI.DbgPopGroup();

                DepthThicknessShader.Unbind();
            }
            DepthCapture.Pop();
            RenderAPI.DbgPopGroup();

            RenderAPI.DbgPushGroup("Fog render");
            FogShader.Bind(ShaderUniforms.Current);
            ThicknessTex.BindTextureUnit();
            // Final pass
            {
                /*// Depth sort to make sure fragment shader executes only once
                 * RenderState RS = Gfx.PeekRenderState();
                 * RS.SetColorMask(false);
                 * RS.EnableDepthMask = true;
                 * Gfx.PushRenderState(RS);
                 * Mesh.Draw();
                 * Gfx.PopRenderState();
                 *
                 * // Actual shading
                 * RS.SetColorMask(true);
                 * RS.EnableDepthMask = false;
                 * RS.DepthFunc = DepthFunc.Equal;
                 * Gfx.PushRenderState(RS);
                 * Mesh.Draw();
                 * Gfx.PopRenderState();*/

                EngineRenderer.BeginDrawStencilMask(StencilMaskMode.AnyFaceDepthTested);
                Mesh.Draw();
                EngineRenderer.EndDrawStencilMask();

                EngineRenderer.BeginUseStencilMask(StencilFunction.Equal, 0xFF, 0xFF, false);
                Mesh.Draw();
                EngineRenderer.EndUseStencilMask();
            }

            ThicknessTex.UnbindTextureUnit();
            FogShader.Unbind();
            RenderAPI.DbgPopGroup();

            RenderAPI.DbgPopGroup();
        }
예제 #6
0
 public static void EndUseStencilMask()
 {
     Gfx.PopRenderState();
     RenderAPI.DbgPopGroup();
 }
예제 #7
0
        public static void Draw(float Dt, bool AmbientLighting = true, bool PointLighting = true)
        {
            RenderDoc.StartFrame();
            Engine.GetTexture("skybox").BindTextureUnit(10);

            DbgDraw.Enabled = Engine.DebugDraw;
            ShaderUniforms.Current.Resolution = Engine.Window.WindowSize;

            // Deferred opaque pass
            RenderAPI.DbgPushGroup("Deferred opaque pass");
            Engine.GBuffer.Push();

            {
                RenderState RS = Gfx.PeekRenderState();
                RS.EnableBlend = false;
                Gfx.PushRenderState(RS);
                Gfx.Clear(Color.Transparent);

                ShaderUniforms.Current.Camera = Engine.Camera3D;

                Engine.Map?.DrawOpaque();
                Engine.Game.DrawOpaque();

                Gfx.PopRenderState();
            }
            Engine.GBuffer.Pop();
            RenderAPI.DbgPopGroup();

            // Lighting/transparency pass
            RenderAPI.DbgPushGroup("Lighting/transparency pass");
            Engine.ScreenRT.Push();
            {
                // Clear canvas, copy depth buffer, draw skybox
                RenderAPI.DbgMessage("Lighting/transparency pass");

                Gfx.Clear(Color.Black);
                Engine.GBuffer.Framebuffer.Blit(false, true, false, Destination: Engine.ScreenRT.Framebuffer);
                Engine.Map?.DrawSkybox();

                Engine.GBuffer.Color.BindTextureUnit(0);
                Engine.GBuffer.Position.BindTextureUnit(1);
                Engine.GBuffer.Normal.BindTextureUnit(2);
                Engine.GBuffer.DepthStencil.BindTextureUnit(3);

                {
                    RenderState State = Gfx.PeekRenderState();
                    State.FrontFace       = FrontFace.CounterClockwise;
                    State.EnableBlend     = true;
                    State.BlendFunc_Src   = BlendFactor.SrcAlpha;
                    State.BlendFunc_Dst   = BlendFactor.One;
                    State.EnableDepthTest = false;

                    Gfx.PushRenderState(State);
                    ShaderUniforms.Current.Camera = Engine.Camera2D;

                    if (AmbientLighting)
                    {
                        RenderAPI.DbgPushGroup("Deferred ambient");
                        // Ambient lighting
                        ShaderProgram AmbientShader = Engine.GetShader("deferred_ambient");
                        AmbientShader.Bind(ShaderUniforms.Current);
                        Engine.ScreenQuad.Draw();
                        AmbientShader.Unbind();
                        RenderAPI.DbgPopGroup();
                    }

                    // Point lighting
                    Gfx.PopRenderState();
                    State.FrontFace         = FrontFace.CounterClockwise;
                    State.EnableDepthMask   = false;
                    State.EnableDepthTest   = true;
                    State.EnableStencilTest = true;
                    Gfx.PushRenderState(State);
                    ShaderUniforms.Current.Camera = Engine.Camera3D;

                    if (Engine.Map != null && PointLighting)
                    {
                        DynamicLight[] Lights = Engine.Map.GetLights();
                        RenderAPI.DbgPushGroup("Point lighting");

                        for (int i = 0; i < Lights.Length; i++)
                        {
                            DbgDraw.DrawCross(Lights[i].Position);

                            State.SetColorMask(false);
                            State.EnableBlend     = false;
                            State.EnableDepthTest = true;
                            State.EnableCullFace  = false;

                            State.StencilFunc(StencilFunction.Always, 0, 0);
                            State.StencilOpSeparate(StencilFace.Front, StencilOperation.Keep, StencilOperation.IncrWrap, StencilOperation.Keep);
                            State.StencilOpSeparate(StencilFace.Back, StencilOperation.Keep, StencilOperation.DecrWrap, StencilOperation.Keep);

                            State.DepthFunc = DepthFunc.LessOrEqual;

                            Gfx.PushRenderState(State);
                            Gfx.ClearStencil();

                            DrawPointLightMask(Lights[i]);
                            DrawPointLightShadow(Lights[i]);

                            Gfx.PopRenderState();

                            State.EnableBlend = true;
                            State.SetColorMask(true);
                            State.EnableDepthTest = false;
                            State.EnableCullFace  = true;
                            State.StencilFunc(StencilFunction.Equal, 1, 0xFF);
                            State.StencilOp(StencilOperation.Keep, StencilOperation.Keep, StencilOperation.Keep);
                            Gfx.PushRenderState(State);

                            ShadePointLight(Lights[i]);

                            Gfx.PopRenderState();
                        }

                        RenderAPI.DbgPopGroup();
                    }

                    Gfx.PopRenderState();
                }
                Engine.GBuffer.DepthStencil.UnbindTextureUnit(3);
                Engine.GBuffer.Normal.UnbindTextureUnit(2);
                Engine.GBuffer.Position.UnbindTextureUnit(1);
                Engine.GBuffer.Color.UnbindTextureUnit(0);

                // Draw transparent items
                RenderAPI.DbgPushGroup("Transparent items");
                Engine.Map?.DrawTransparent();
                Engine.Game.DrawTransparent();
                RenderAPI.DbgPopGroup();

                // Draw debug lines
                DbgDraw.FinalizeDraw((long)(Engine.Time * 1000));
            }
            Engine.ScreenRT.Pop();
            RenderAPI.DbgPopGroup();

            RenderAPI.DbgPushGroup("2D pass");
            {
                RenderState State = Gfx.PeekRenderState();
                State.EnableDepthTest = false;
                Gfx.PushRenderState(State);
                {
                    Gfx.Clear();
                    ShaderUniforms.Current.Camera           = Engine.Camera2D;
                    ShaderUniforms.Current.TextureSize      = Engine.ScreenRT.Color.Size;
                    ShaderUniforms.Current.MultisampleCount = Engine.ScreenRT.Color.Multisamples;
                    Gfx.TexturedRectangle(0, 0, Engine.Window.WindowWidth, Engine.Window.WindowHeight, Texture: Engine.ScreenRT.Color, Shader: Engine.GetShader("framebuffer"));

                    Engine.GUI.Draw(() => {
                        float FT           = Engine.FrameTime.Average();
                        float FPS          = 1.0f / FT;
                        string DebugString = string.Format("{0} ms\n{1} FPS\n{2} Lights", FT, FPS, Engine.Map.GetLights().Length);
                        int Lines          = 3;

                        Gfx.DrawText(Engine.UI.DebugFont, new Vector2(2, Engine.WindowHeight - Engine.UI.DebugFont.ScaledLineHeight * Lines - 2), DebugString, Color.White);

                        Engine.UI.Draw();
                        Engine.Game.DrawGUI(Dt);
                    });
                }
                Gfx.PopRenderState();
            }
            RenderAPI.DbgPopGroup();
            Engine.Window.SwapBuffers();

            RenderDoc.EndFrame();
        }