/// <summary> /// Renders the entire GameEngine2D. /// </summary> private void Render() { GraphicsUtil.CheckError("Render - Pre"); if (!UseLightEngine) { GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Disable(EnableCap.DepthTest); GL.DepthMask(false); GL.Viewport(0, 0, Window.Width / Pixelation, Window.Height / Pixelation); Shaders.ColorMult2DShader.Bind(); MainRenderContext.CalcShadows = false; Scaler = OriginalScaler; Adder = OriginalAdder; GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(Scaler.X, Scaler.Y, MainRenderContext.AspectHelper)); GL.Uniform2(2, ref Adder); MainRenderContext.Scaler = Scaler; MainRenderContext.Adder = Adder; RenderAll(false, null); return; } GraphicsUtil.CheckError("Render - Begin"); if (Lights.Count > 0) { GL.BindFramebuffer(FramebufferTarget.Framebuffer, Lights[0].FBO); GL.DrawBuffer(DrawBufferMode.ColorAttachment0); } // TODO: Discard fully out-of-view lights! if (OneDLights) { Shader_Lightmap1D.Bind(); GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.Zero); GL.Enable(EnableCap.DepthTest); GL.DepthMask(true); } else { Shader_Lightmap.Bind(); } GraphicsUtil.CheckError("Render - Before Light Precalcer"); MainRenderContext.CalcShadows = true; for (int i = 0; i < Lights.Count; i++) { Lights[i].PrepareLightmap(); GraphicsUtil.CheckError("Render - Light Precalcer (Prep)"); Scaler = Lights[i].GetScaler(); GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(Scaler.X, Scaler.Y, MainRenderContext.AspectHelper)); GL.Uniform2(2, Adder = Lights[i].GetAdder()); if (OneDLights) { GL.ClearBuffer(ClearBuffer.Depth, 0, new float[] { 1f }); GL.Uniform4(21, new Vector4(ViewCenterInverse.X / OriginalScaler.X, Math.Max(OriginalScaler.X, OriginalScaler.Y), ViewCenterInverse.Y / OriginalScaler.Y + 1.0f, Lights[i].IsSkyLight ? 1.0f : 0.0f)); } MainRenderContext.Scaler = Scaler; MainRenderContext.Adder = Adder; GraphicsUtil.CheckError("Render - Light Precalcer"); RenderAll(true, Lights[i].ShouldShadow); } if (OneDLights) { GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Disable(EnableCap.DepthTest); GL.DepthMask(false); } MainRenderContext.CalcShadows = false; GraphicsUtil.CheckError("Render - Lights precalced"); GL.Viewport(0, 0, Window.Width / Pixelation, Window.Height / Pixelation); Shaders.ColorMult2DShader.Bind(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, c_FBO); GL.ClearBuffer(ClearBuffer.Color, 0, new float[] { 0, 0, 0, 1 }); Scaler = OriginalScaler; Adder = OriginalAdder; GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(Scaler.X, Scaler.Y, MainRenderContext.AspectHelper)); GL.Uniform2(2, ref Adder); MainRenderContext.Scaler = Scaler; MainRenderContext.Adder = Adder; GraphicsUtil.CheckError("Render - Lights prepped"); RenderAll(false, null); if (OneDLights) { Shader_ApplyLights1D.Bind(); } else { Shader_Combine.Bind(); } GL.BindFramebuffer(FramebufferTarget.Framebuffer, l_FBO); GL.ClearBuffer(ClearBuffer.Color, 0, new float[] { 0, 0, 0, 1 }); Scaler = Vector2.One; Adder = Vector2.Zero; GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(Scaler.X, Scaler.Y, MainRenderContext.AspectHelper)); GL.Uniform2(2, ref Adder); MainRenderContext.Scaler = Scaler; MainRenderContext.Adder = Adder; MainRenderContext.Engine = this; GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One); GraphicsUtil.CheckError("Render - Setup Lights combine"); for (int i = 0; i < Lights.Count; i++) { GL.Uniform2(3, Lights[i].GetSecondScaler(MainRenderContext)); GL.Uniform2(4, Lights[i].GetSecondAdder(MainRenderContext)); GL.Uniform4(6, new Vector4(Lights[i].Color.R, Lights[i].Color.G, Lights[i].Color.B, Lights[i].Color.A)); if (!OneDLights) { GL.Uniform1(5, (float)Lights[i].Width); GL.Uniform1(8, Lights[i].SubDivider); } else { GL.Uniform1(8, Lights[i].ExtraLightDist); GL.Uniform4(21, new Vector4(ViewCenterInverse.X / OriginalScaler.X, Math.Max(OriginalScaler.X, OriginalScaler.Y), ViewCenterInverse.Y / OriginalScaler.Y + 1.0f, Lights[i].IsSkyLight ? 1.0f : 0.0f)); } GL.BindTexture(OneDLights ? TextureTarget.Texture1D : TextureTarget.Texture2D, Lights[i].FBO_Tex); RenderHelper.RenderRectangle(MainRenderContext, -1, -1, 1, 1); } GraphicsUtil.CheckError("Render - Lights combined"); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, l_FBO_Tex); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, c_FBO_Tex); GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); GL.DrawBuffer(DrawBufferMode.Back); Shader_Addlighttoscene.Bind(); Scaler = Vector2.One; Adder = Vector2.Zero; GL.Uniform3(ShaderLocations.Common2D.SCALER, new Vector3(Scaler.X, Scaler.Y, MainRenderContext.AspectHelper)); GL.Uniform2(2, ref Adder); MainRenderContext.Scaler = Scaler; MainRenderContext.Adder = Adder; GL.Viewport(0, 0, Window.Width, Window.Height); RenderHelper.RenderRectangle(MainRenderContext, -1, -1, 1, 1); GraphicsUtil.CheckError("Render - Added"); GL.BindTexture(TextureTarget.Texture2D, 0); GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(TextureTarget.Texture2D, 0); GL.ActiveTexture(TextureUnit.Texture0); Shaders.ColorMult2DShader.Bind(); GraphicsUtil.CheckError("Render - Complete"); }