/// <summary> /// Adds refraction data to the G-Buffer ("FBO"). /// </summary> public void RenderPass_RefractionBuffer(Stopwatch timer) { FBOid = FBOID.REFRACT; TheClient.s_fbov_refract = TheClient.s_fbov_refract.Bind(); GL.Uniform1(6, (float)TheClient.GlobalTickTimeLocal); GL.UniformMatrix4(1, false, ref PrimaryMatrix); GL.UniformMatrix4(2, false, ref IdentityMatrix); GL.Uniform2(8, new Vector2(TheClient.sl_min, TheClient.sl_max)); TheClient.s_fbo_refract = TheClient.s_fbo_refract.Bind(); GL.Uniform1(6, (float)TheClient.GlobalTickTimeLocal); GL.UniformMatrix4(1, false, ref PrimaryMatrix); GL.UniformMatrix4(2, false, ref IdentityMatrix); GL.DepthMask(false); if (TheClient.CVars.r_3d_enable.ValueB) { GL.Viewport(Width / 2, 0, Width / 2, Height); Render3D(this); CFrust = cf2; GL.Viewport(0, 0, Width / 2, Height); CameraPos = cameraBasePos - cameraAdjust; TheClient.s_fbov_refract = TheClient.s_fbov_refract.Bind(); GL.UniformMatrix4(1, false, ref PrimaryMatrix_OffsetFor3D); TheClient.s_fbo_refract = TheClient.s_fbo_refract.Bind(); GL.UniformMatrix4(1, false, ref PrimaryMatrix_OffsetFor3D); Render3D(this); GL.Viewport(0, 0, Width, Height); CameraPos = cameraBasePos + cameraAdjust; CFrust = camFrust; } else { Render3D(this); } CheckError("AfterRefract"); GL.DepthMask(true); RenderLights = false; RenderSpecular = false; RS4P.Unbind(); FBOid = FBOID.NONE; timer.Stop(); FBOTime = (double)timer.ElapsedMilliseconds / 1000f; if (FBOTime > FBOSpikeTime) { FBOSpikeTime = FBOTime; } }
/// <summary> /// Set up the rendering engine. /// </summary> public void RenderPass_Setup() { Location camup = CameraUp(); BEPUutilities.Quaternion cammod = CameraModifier(); Location camforward = ForwardVec; camup = new Location(BEPUutilities.Quaternion.Transform(camup.ToBVector(), cammod)); camforward = new Location(BEPUutilities.Quaternion.Transform(camforward.ToBVector(), cammod)); CameraForward = camforward; GL.BindFramebuffer(FramebufferTarget.Framebuffer, CurrentFBO); GL.DrawBuffer(CurrentFBO == 0 ? DrawBufferMode.Back : DrawBufferMode.ColorAttachment0); StandardBlend(); GL.Enable(EnableCap.DepthTest); RenderTextures = true; GL.ClearBuffer(ClearBuffer.Color, 0, ClearColor); GL.ClearBuffer(ClearBuffer.Depth, 0, new float[] { 1.0f }); cameraBasePos = CameraPos; cameraAdjust = -camforward.CrossProduct(camup) * 0.25; RenderRelative = CameraPos; SetViewport(); CameraTarget = CameraPos + camforward; OffsetWorld = Matrix4d.CreateTranslation(ClientUtilities.ConvertD(-CameraPos)); Matrix4 proj = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(TheClient.CVars.r_fov.ValueF), (float)Width / (float)Height, TheClient.CVars.r_znear.ValueF, TheClient.CVars.r_zfar.ValueF); // TODO: View3D-level vars? Location bx = TheClient.CVars.r_3d_enable.ValueB ? (cameraAdjust) : Location.Zero; Matrix4 view = Matrix4.LookAt(ClientUtilities.Convert(bx), ClientUtilities.Convert(bx + camforward), ClientUtilities.Convert(camup)); PrimaryMatrix = view * proj; if (TheClient.CVars.r_3d_enable.ValueB) { Matrix4 view2 = Matrix4.LookAt(ClientUtilities.Convert(-cameraAdjust), ClientUtilities.Convert(-cameraAdjust + camforward), ClientUtilities.Convert(camup)); PrimaryMatrix_OffsetFor3D = view2 * proj; } Matrix4d projd = Matrix4d.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(TheClient.CVars.r_fov.ValueF), (float)Width / (float)Height, TheClient.CVars.r_znear.ValueF, TheClient.CVars.r_zfar.ValueF); // TODO: View3D-level vars? Location bxd = TheClient.CVars.r_3d_enable.ValueB ? (CameraPos + cameraAdjust) : CameraPos; Matrix4d viewd = Matrix4d.LookAt(ClientUtilities.ConvertD(bxd), ClientUtilities.ConvertD(bxd + camforward), ClientUtilities.ConvertD(camup)); PrimaryMatrixd = viewd * projd; Matrix4d PrimaryMatrix_OffsetFor3Dd = Matrix4d.Identity; if (TheClient.CVars.r_3d_enable.ValueB) { Matrix4d view2d = Matrix4d.LookAt(ClientUtilities.ConvertD(CameraPos - cameraAdjust), ClientUtilities.ConvertD(CameraPos - cameraAdjust + camforward), ClientUtilities.ConvertD(camup)); PrimaryMatrix_OffsetFor3Dd = view2d * projd; } camFrust = new Frustum(PrimaryMatrixd); cf2 = new Frustum(PrimaryMatrix_OffsetFor3Dd); CFrust = camFrust; CheckError("AfterSetup"); }
/// <summary> /// Generate the G-Buffer ("FBO") for lighting and final passes. /// </summary> public void RenderPass_GBuffer() { Stopwatch timer = new Stopwatch(); timer.Start(); SetViewport(); TheClient.s_fbov = TheClient.s_fbov.Bind(); GL.Uniform1(6, (float)TheClient.GlobalTickTimeLocal); GL.UniformMatrix4(1, false, ref PrimaryMatrix); GL.UniformMatrix4(2, false, ref IdentityMatrix); GL.Uniform2(8, new Vector2(TheClient.sl_min, TheClient.sl_max)); TheClient.s_fbot = TheClient.s_fbot.Bind(); GL.Uniform1(6, (float)TheClient.GlobalTickTimeLocal); GL.UniformMatrix4(1, false, ref PrimaryMatrix); GL.UniformMatrix4(2, false, ref IdentityMatrix); TheClient.s_fbo = TheClient.s_fbo.Bind(); GL.Uniform1(6, (float)TheClient.GlobalTickTimeLocal); GL.UniformMatrix4(1, false, ref PrimaryMatrix); GL.UniformMatrix4(2, false, ref IdentityMatrix); FBOid = FBOID.MAIN; RenderingShadows = false; CFrust = camFrust; GL.ActiveTexture(TextureUnit.Texture0); RS4P.Bind(); RenderLights = true; RenderSpecular = true; TheClient.Rendering.SetColor(Color4.White); StandardBlend(); if (TheClient.CVars.r_3d_enable.ValueB) { GL.Viewport(Width / 2, 0, Width / 2, Height); Render3D(this); CFrust = cf2; GL.Viewport(0, 0, Width / 2, Height); CameraPos = cameraBasePos - cameraAdjust; TheClient.s_fbov = TheClient.s_fbov.Bind(); GL.UniformMatrix4(1, false, ref PrimaryMatrix); TheClient.s_fbot = TheClient.s_fbot.Bind(); GL.UniformMatrix4(1, false, ref PrimaryMatrix); TheClient.s_fbo = TheClient.s_fbo.Bind(); GL.UniformMatrix4(1, false, ref PrimaryMatrix); Render3D(this); GL.Viewport(0, 0, Width, Height); CameraPos = cameraBasePos + cameraAdjust; CFrust = camFrust; } else { Render3D(this); } CheckError("AfterFBO"); RenderPass_RefractionBuffer(timer); }
void renderTranspInt(ref int lightc, Frustum frustumToUse) { if (frustumToUse == null) { frustumToUse = camFrust; } if (TheClient.CVars.r_transplighting.ValueB) { RenderLights = true; for (int i = 0; i < Lights.Count; i++) { if (Lights[i] is SkyLight || frustumToUse == null || frustumToUse.ContainsSphere(Lights[i].EyePos.ToBVector(), Lights[i].MaxDistance)) { for (int x = 0; x < Lights[i].InternalLights.Count; x++) { lightc++; } } } int c = 0; float[] l_dats1 = new float[LIGHTS_MAX * 16]; float[] l_dats2 = new float[LIGHTS_MAX * 16]; float[] s_mats = new float[LIGHTS_MAX * 16]; for (int i = 0; i < Lights.Count; i++) { if (Lights[i] is SkyLight || frustumToUse == null || frustumToUse.ContainsSphere(Lights[i].EyePos.ToBVector(), Lights[i].MaxDistance)) { for (int x = 0; x < Lights[i].InternalLights.Count; x++) { Matrix4 lmat = Lights[i].InternalLights[x].GetMatrix(); float maxrange = (Lights[i].InternalLights[x] is LightOrtho) ? LightMaximum : Lights[i].InternalLights[x].maxrange; Matrix4 matxyz = new Matrix4(Vector4.Zero, Vector4.Zero, Vector4.Zero, Vector4.Zero); matxyz[0, 0] = maxrange <= 0 ? LightMaximum : maxrange; // TODO: Diffuse Albedo matxyz[0, 1] = 0.7f; matxyz[0, 2] = 0.7f; matxyz[0, 3] = 0.7f; // TODO: Specular Albedo matxyz[1, 0] = 0.7f; matxyz[1, 3] = (Lights[i] is SpotLight) ? 1f : 0f; matxyz[2, 0] = (Lights[i].InternalLights[x] is LightOrtho) ? 1f : 0f; matxyz[2, 1] = 1f / TheClient.CVars.r_shadowquality.ValueI; matxyz[2, 2] = 0.5f; matxyz[2, 3] = (float)lightc; matxyz[3, 0] = (float)ambient.X; matxyz[3, 1] = (float)ambient.Y; matxyz[3, 2] = (float)ambient.Z; Matrix4 matabc = new Matrix4(Vector4.Zero, Vector4.Zero, Vector4.Zero, Vector4.Zero); matabc[0, 0] = 0f; matabc[0, 1] = 0f; matabc[0, 2] = 0f; matabc[1, 0] = (float)(Lights[i].EyePos.X - CameraPos.X); matabc[1, 1] = (float)(Lights[i].EyePos.Y - CameraPos.Y); matabc[1, 2] = (float)(Lights[i].EyePos.Z - CameraPos.Z); matabc[2, 0] = MainEXP; matabc[0, 3] = Lights[i].InternalLights[x].color.X; matabc[2, 1] = Lights[i].InternalLights[x].color.Y; matabc[2, 2] = Lights[i].InternalLights[x].color.Z; for (int mx = 0; mx < 4; mx++) { for (int my = 0; my < 4; my++) { s_mats[c * 16 + mx * 4 + my] = lmat[mx, my]; l_dats1[c * 16 + mx * 4 + my] = matxyz[mx, my]; l_dats2[c * 16 + mx * 4 + my] = matabc[mx, my]; } } c++; if (c >= LIGHTS_MAX) { goto lights_apply; } } } } lights_apply: CheckError("PreRenderTranspLights"); if (TheClient.CVars.r_transpshadows.ValueB && TheClient.CVars.r_shadows.ValueB) { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlyvoxlitsh_ll = TheClient.s_transponlyvoxlitsh_ll.Bind(); } else { TheClient.s_transponlyvoxlitsh = TheClient.s_transponlyvoxlitsh.Bind(); } } else { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlyvoxlit_ll = TheClient.s_transponlyvoxlit_ll.Bind(); } else { TheClient.s_transponlyvoxlit = TheClient.s_transponlyvoxlit.Bind(); } } GL.UniformMatrix4(2, false, ref IdentityMatrix); GL.Uniform1(7, (float)TheClient.GlobalTickTimeLocal); GL.Uniform2(8, new Vector2(Width, Height)); GL.Uniform1(9, (float)c); GL.UniformMatrix4(10, LIGHTS_MAX, false, s_mats); GL.UniformMatrix4(20, LIGHTS_MAX, false, l_dats1); GL.UniformMatrix4(30, LIGHTS_MAX, false, l_dats2); if (TheClient.CVars.r_transpshadows.ValueB && TheClient.CVars.r_shadows.ValueB) { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlylitsh_ll = TheClient.s_transponlylitsh_ll.Bind(); } else { TheClient.s_transponlylitsh = TheClient.s_transponlylitsh.Bind(); } } else { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlylit_ll = TheClient.s_transponlylit_ll.Bind(); } else { TheClient.s_transponlylit = TheClient.s_transponlylit.Bind(); } } GL.UniformMatrix4(2, false, ref IdentityMatrix); GL.Uniform2(8, new Vector2(Width, Height)); GL.Uniform1(9, (float)c); GL.UniformMatrix4(10, LIGHTS_MAX, false, s_mats); GL.UniformMatrix4(20, LIGHTS_MAX, false, l_dats1); GL.UniformMatrix4(30, LIGHTS_MAX, false, l_dats2); GL.ActiveTexture(TextureUnit.Texture4); GL.BindTexture(TextureTarget.Texture2DArray, fbo_shadow_tex); GL.ActiveTexture(TextureUnit.Texture0); Render3D(this); CheckError("PostRenderTranspLights"); GL.ActiveTexture(TextureUnit.Texture2); GL.BindTexture(TextureTarget.Texture2D, 0); GL.ActiveTexture(TextureUnit.Texture0); RenderLights = false; } else { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlyvox_ll.Bind(); // GL.UniformMatrix4(1, false, ref combined); GL.UniformMatrix4(2, false, ref IdentityMatrix); Matrix4 matabc = new Matrix4(Vector4.Zero, Vector4.Zero, Vector4.Zero, Vector4.Zero); matabc[0, 3] = (float)Width; matabc[1, 3] = (float)Height; GL.UniformMatrix4(9, false, ref matabc); TheClient.s_transponly_ll.Bind(); //GL.UniformMatrix4(1, false, ref combined); GL.UniformMatrix4(2, false, ref IdentityMatrix); GL.UniformMatrix4(9, false, ref matabc); } else { TheClient.s_transponlyvox.Bind(); //GL.UniformMatrix4(1, false, ref combined); GL.UniformMatrix4(2, false, ref IdentityMatrix); TheClient.s_transponly.Bind(); //GL.UniformMatrix4(1, false, ref combined); GL.UniformMatrix4(2, false, ref IdentityMatrix); } Render3D(this); } }
/// <summary> /// Render transparent objects into a temporary buffer. /// </summary> void RenderTransp(ref int lightc, Frustum frustumToUse = null) { if (TheClient.CVars.r_transpll.ValueB) { GL.ActiveTexture(TextureUnit.Texture4); GL.BindTexture(TextureTarget.Texture2DArray, TransTexs[0]); GL.BindImageTexture(4, TransTexs[0], 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.R32ui); GL.ActiveTexture(TextureUnit.Texture5); GL.BindTexture(TextureTarget.TextureBuffer, TransTexs[1]); GL.BindImageTexture(5, TransTexs[1], 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba32f); GL.ActiveTexture(TextureUnit.Texture6); GL.BindTexture(TextureTarget.TextureBuffer, TransTexs[2]); GL.BindImageTexture(6, TransTexs[2], 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.R32ui); GL.ActiveTexture(TextureUnit.Texture7); GL.BindTexture(TextureTarget.TextureBuffer, TransTexs[3]); GL.BindImageTexture(7, TransTexs[3], 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.R32ui); GL.ActiveTexture(TextureUnit.Texture0); TheClient.s_ll_clearer.Bind(); GL.Uniform2(4, new Vector2(Width, Height)); Matrix4 flatProj = Matrix4.CreateOrthographicOffCenter(-1, 1, 1, -1, -1, 1); GL.UniformMatrix4(1, false, ref flatProj); GL.UniformMatrix4(2, false, ref IdentityMatrix); GL.Uniform2(4, new Vector2(Width, Height)); TheClient.Rendering.RenderRectangle(-1, -1, 1, 1); GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits); //s_whatever.Bind(); //GL.Uniform2(4, new Vector2(Window.Width, Window.Height)); //GL.ClearBuffer(ClearBuffer.Color, 0, new float[] { 0f, 0f, 0f, 1f }); //GL.ClearBuffer(ClearBuffer.Depth, 0, new float[] { 1f }); //Matrix4 proj = Matrix4.CreatePerspectiveFieldOfView(FOV, Window.Width / (float)Window.Height, ZNear, ZFar); //Matrix4 view = Matrix4.LookAt(CamPos, CamGoal, Vector3.UnitZ); //Matrix4 combined = view * proj; //GL.UniformMatrix4(1, false, ref combined); renderTranspInt(ref lightc, frustumToUse); GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits); TheClient.s_ll_fpass.Bind(); GL.Uniform2(4, new Vector2(Width, Height)); GL.UniformMatrix4(1, false, ref flatProj); GL.UniformMatrix4(2, false, ref IdentityMatrix); GL.Uniform2(4, new Vector2(Width, Height)); TheClient.Rendering.RenderRectangle(-1, -1, 1, 1); } else { renderTranspInt(ref lightc, frustumToUse); } }
public int RenderPass_Transparents() { if (TheClient.CVars.r_transplighting.ValueB) { if (TheClient.CVars.r_transpshadows.ValueB && TheClient.CVars.r_shadows.ValueB) { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlyvoxlitsh_ll = TheClient.s_transponlyvoxlitsh_ll.Bind(); } else { TheClient.s_transponlyvoxlitsh = TheClient.s_transponlyvoxlitsh.Bind(); } } else { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlyvoxlit_ll = TheClient.s_transponlyvoxlit_ll.Bind(); } else { TheClient.s_transponlyvoxlit = TheClient.s_transponlyvoxlit.Bind(); } } } else { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlyvox_ll = TheClient.s_transponlyvox_ll.Bind(); } else { TheClient.s_transponlyvox = TheClient.s_transponlyvox.Bind(); } } GL.UniformMatrix4(1, false, ref PrimaryMatrix); GL.UniformMatrix4(2, false, ref IdentityMatrix); GL.Uniform1(4, DesaturationAmount); if (TheClient.CVars.r_transplighting.ValueB) { if (TheClient.CVars.r_transpshadows.ValueB && TheClient.CVars.r_shadows.ValueB) { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlylitsh_ll = TheClient.s_transponlylitsh_ll.Bind(); FBOid = FBOID.TRANSP_SHADOWS_LL; } else { TheClient.s_transponlylitsh = TheClient.s_transponlylitsh.Bind(); FBOid = FBOID.TRANSP_SHADOWS; } } else { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlylit_ll = TheClient.s_transponlylit_ll.Bind(); FBOid = FBOID.TRANSP_LIT_LL; } else { TheClient.s_transponlylit = TheClient.s_transponlylit.Bind(); FBOid = FBOID.TRANSP_LIT; } } } else { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponly_ll = TheClient.s_transponly_ll.Bind(); FBOid = FBOID.TRANSP_LL; } else { TheClient.s_transponly = TheClient.s_transponly.Bind(); FBOid = FBOID.TRANSP_UNLIT; } } GL.UniformMatrix4(1, false, ref PrimaryMatrix); GL.UniformMatrix4(2, false, ref IdentityMatrix); GL.Uniform1(4, DesaturationAmount); GL.DepthMask(false); if (TheClient.CVars.r_transpll.ValueB) { StandardBlend(); } else { TranspBlend(); } GL.BindFramebuffer(FramebufferTarget.Framebuffer, transp_fbo_main); GL.DrawBuffer(DrawBufferMode.ColorAttachment0); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, RS4P.fbo); GL.BlitFramebuffer(0, 0, Width, Height, 0, 0, Width, Height, ClearBufferMask.DepthBufferBit, BlitFramebufferFilter.Nearest); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, 0); GL.ClearBuffer(ClearBuffer.Color, 0, new float[] { 0f, 0f, 0f, 0f }); int lightc = 0; CheckError("PreTransp"); if (TheClient.CVars.r_3d_enable.ValueB) { GL.Viewport(Width / 2, 0, Width / 2, Height); CameraPos = cameraBasePos + cameraAdjust; RenderTransp(ref lightc); CFrust = cf2; GL.Viewport(0, 0, Width / 2, Height); CFrust = cf2; if (TheClient.CVars.r_transplighting.ValueB) { if (TheClient.CVars.r_transpshadows.ValueB && TheClient.CVars.r_shadows.ValueB) { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlyvoxlitsh_ll = TheClient.s_transponlyvoxlitsh_ll.Bind(); } else { TheClient.s_transponlyvoxlitsh = TheClient.s_transponlyvoxlitsh.Bind(); } } else { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlyvoxlit_ll = TheClient.s_transponlyvoxlit_ll.Bind(); } else { TheClient.s_transponlyvoxlit = TheClient.s_transponlyvoxlit.Bind(); } } } else { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlyvox_ll = TheClient.s_transponlyvox_ll.Bind(); } else { TheClient.s_transponlyvox = TheClient.s_transponlyvox.Bind(); } } GL.UniformMatrix4(1, false, ref PrimaryMatrix_OffsetFor3D); if (TheClient.CVars.r_transplighting.ValueB) { if (TheClient.CVars.r_transpshadows.ValueB && TheClient.CVars.r_shadows.ValueB) { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlylitsh_ll = TheClient.s_transponlylitsh_ll.Bind(); FBOid = FBOID.TRANSP_SHADOWS_LL; } else { TheClient.s_transponlylitsh = TheClient.s_transponlylitsh.Bind(); FBOid = FBOID.TRANSP_SHADOWS; } } else { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponlylit_ll = TheClient.s_transponlylit_ll.Bind(); FBOid = FBOID.TRANSP_LIT_LL; } else { TheClient.s_transponlylit = TheClient.s_transponlylit.Bind(); FBOid = FBOID.TRANSP_LIT; } } } else { if (TheClient.CVars.r_transpll.ValueB) { TheClient.s_transponly_ll = TheClient.s_transponly_ll.Bind(); FBOid = FBOID.TRANSP_LL; } else { TheClient.s_transponly = TheClient.s_transponly.Bind(); FBOid = FBOID.TRANSP_UNLIT; } } GL.UniformMatrix4(1, false, ref PrimaryMatrix_OffsetFor3D); CameraPos = cameraBasePos - cameraAdjust; RenderTransp(ref lightc, cf2); GL.Viewport(0, 0, Width, Height); CameraPos = cameraBasePos + cameraAdjust; CFrust = camFrust; } else { RenderTransp(ref lightc); } if (lightc == 0) { lightc = 1; } CheckError("AfterTransp"); return lightc; }
/// <summary> /// Calculate shadow maps for the later (lighting) render passes. /// </summary> public void RenderPass_Shadows() { if (TheClient.shouldRedrawShadows && ShadowingAllowed) { Stopwatch timer = new Stopwatch(); timer.Start(); TheClient.s_shadow = TheClient.s_shadow.Bind(); TheClient.FixPersp = Matrix4.Identity; RenderingShadows = true; ShadowsOnly = true; LightsC = 0; Location campos = CameraPos; int n = 0; Frustum tcf = CFrust; for (int i = 0; i < Lights.Count; i++) { if (Lights[i] is SkyLight || camFrust == null || camFrust.ContainsSphere(Lights[i].EyePos.ToBVector(), Lights[i].MaxDistance)) { if (Lights[i] is SkyLight || Lights[i].EyePos.DistanceSquared(CameraPos) < TheClient.CVars.r_lightmaxdistance.ValueD * TheClient.CVars.r_lightmaxdistance.ValueD + Lights[i].MaxDistance * Lights[i].MaxDistance * 6) { LightsC++; for (int x = 0; x < Lights[i].InternalLights.Count; x++) { GL.BindFramebuffer(FramebufferTarget.Framebuffer, fbo_shadow[n]); if (Lights[i].InternalLights[x].color.LengthSquared <= 0.01) { continue; } if (Lights[i].InternalLights[x] is LightOrtho) { CFrust = null; } else { CFrust = new Frustum(ClientUtilities.ConvertToD(Lights[i].InternalLights[x].GetMatrix())); } CameraPos = ClientUtilities.ConvertD(Lights[i].InternalLights[x].eye); TheClient.s_shadowvox = TheClient.s_shadowvox.Bind(); GL.UniformMatrix4(2, false, ref IdentityMatrix); Lights[i].InternalLights[x].SetProj(); if (Lights[i].InternalLights[x] is LightOrtho) { GL.Uniform1(3, 1.0f); } else { GL.Uniform1(3, 0.0f); } GL.Uniform1(4, Lights[i].InternalLights[x].transp ? 1.0f : 0.0f); FBOid = FBOID.SHADOWS; TheClient.s_shadow = TheClient.s_shadow.Bind(); GL.UniformMatrix4(2, false, ref IdentityMatrix); if (Lights[i].InternalLights[x] is LightOrtho) { GL.Uniform1(3, 1.0f); } else { GL.Uniform1(3, 0.0f); } GL.Uniform1(4, Lights[i].InternalLights[x].transp ? 1.0f : 0.0f); TranspShadows = Lights[i].InternalLights[x].transp; Lights[i].InternalLights[x].SetProj(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, fbo_shadow[n]); GL.DrawBuffer(DrawBufferMode.ColorAttachment0); GL.ClearBuffer(ClearBuffer.Depth, 0, new float[] { 1f }); GL.ClearBuffer(ClearBuffer.Color, 0, new float[] { 1f }); GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.Zero); Render3D(this); FBOid = FBOID.NONE; n++; if (n >= LIGHTS_MAX) { goto complete; } } } } } complete: CFrust = tcf; GL.BindFramebuffer(FramebufferTarget.Framebuffer, CurrentFBO); GL.DrawBuffer(CurrentFBO == 0 ? DrawBufferMode.Back : DrawBufferMode.ColorAttachment0); CameraPos = campos; RenderingShadows = false; ShadowsOnly = false; timer.Stop(); ShadowTime = (double)timer.ElapsedMilliseconds / 1000f; if (ShadowTime > ShadowSpikeTime) { ShadowSpikeTime = ShadowTime; } StandardBlend(); CheckError("AfterShadows"); } }