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(); }
public void DrawShadowVolume(ShaderMaterial ShadowVolume) { RenderAPI.DbgPushGroup("Map DrawShadowVolume"); for (int ModelIdx = 0; ModelIdx < MapModels.Length; ModelIdx++) { MapModels[ModelIdx].DrawShadowVolume(ShadowVolume); } RenderAPI.DbgPopGroup(); }
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(); }
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(); }
public static void BeginDrawStencilMask(StencilMaskMode MaskMode) { RenderAPI.DbgPushGroup("BeginDrawStencilMask " + MaskMode); RenderState RS = Gfx.PeekRenderState(); RS.EnableStencilTest = true; RS.EnableBlend = false; RS.EnableCullFace = false; RS.SetColorMask(false); RS.EnableDepthMask = false; switch (MaskMode) { case StencilMaskMode.Intersection: RS.EnableDepthTest = true; RS.DepthFunc = DepthFunc.LessOrEqual; RS.StencilFunc(StencilFunction.Always, 0, 0); RS.StencilOpSeparate(StencilFace.Front, StencilOperation.Keep, StencilOperation.IncrWrap, StencilOperation.Keep); RS.StencilOpSeparate(StencilFace.Back, StencilOperation.Keep, StencilOperation.DecrWrap, StencilOperation.Keep); break; case StencilMaskMode.AnyFaceDepthTested: RS.EnableDepthTest = true; RS.DepthFunc = DepthFunc.Always; goto case StencilMaskMode.AnyFace; case StencilMaskMode.AnyFace: RS.StencilFunc(StencilFunction.Always, 0xFF, 0xFF); RS.StencilOp(StencilOperation.Keep, StencilOperation.Keep, StencilOperation.Replace); break; default: throw new InvalidOperationException(); } Gfx.PushRenderState(RS); Gfx.ClearStencil(); }
public static void BeginUseStencilMask(StencilFunction Func, int Ref, uint Mask, bool WriteDepth = true, bool CullFront = true) { RenderAPI.DbgPushGroup("BeginUseStencilMask"); RenderState RS = Gfx.PeekRenderState(); RS.EnableStencilTest = true; RS.StencilFunc(Func, Ref, Mask); RS.StencilOp(StencilOperation.Keep, StencilOperation.Keep, StencilOperation.Keep); RS.EnableDepthTest = false; //if (CullFront) { RS.EnableCullFace = true; RS.CullFace = CullFace.Front; //} RS.SetColorMask(true); RS.EnableDepthMask = WriteDepth; Gfx.PushRenderState(RS); }
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(); }
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(); }