public ScreenSpaceReflections(VolumetricShadingMod mod) { _mod = mod; _game = mod.CApi.GetClient(); _platform = _game.GetClientPlatformWindows(); RegisterInjectorProperties(); mod.CApi.Event.ReloadShader += ReloadShaders; mod.Events.PreFinalRender += OnSetFinalUniforms; mod.ShaderPatcher.OnReload += RegeneratePatches; _enabled = ModSettings.ScreenSpaceReflectionsEnabled; _rainEnabled = ModSettings.SSRRainReflectionsEnabled; _refractionsEnabled = ModSettings.SSRRefractionsEnabled; _causticsEnabled = ModSettings.SSRCausticsEnabled; mod.CApi.Settings.AddWatcher <bool>("volumetricshading_screenSpaceReflections", OnEnabledChanged); mod.CApi.Settings.AddWatcher <bool>("volumetricshading_SSRRainReflections", OnRainReflectionsChanged); mod.CApi.Settings.AddWatcher <bool>("volumetricshading_SSRRefractions", OnRefractionsChanged); mod.CApi.Settings.AddWatcher <bool>("volumetricshading_SSRCaustics", OnCausticsChanged); mod.CApi.Event.RegisterRenderer(this, EnumRenderStage.Opaque, "ssrWorldSpace"); mod.CApi.Event.RegisterRenderer(this, EnumRenderStage.AfterOIT, "ssrOut"); _textureIdsField = typeof(ChunkRenderer).GetField("textureIds", BindingFlags.Instance | BindingFlags.NonPublic); mod.Events.RebuildFramebuffers += SetupFramebuffers; SetupFramebuffers(_platform.FrameBuffers); }
public static void Blit(this ClientPlatformWindows platform, MeshRef quad, int source) { var blit = ShaderPrograms.Blit; blit.Use(); blit.Scene2D = source; platform.RenderFullscreenTriangle(quad); blit.Stop(); }
public static MeshRef GetScreenQuad(this ClientPlatformWindows platform) { var quad = (MeshRef)typeof(ClientPlatformWindows) .GetField("screenQuad", BindingFlags.Instance | BindingFlags.NonPublic) ?.GetValue(platform); if (quad == null) { throw new Exception("Could not fetch screen quad"); } return(quad); }
public DeferredLighting(VolumetricShadingMod mod) { _mod = mod; _platform = _mod.CApi.GetClientPlatformWindows(); _mod.CApi.Settings.AddWatcher <bool>("volumetricshading_deferredLighting", OnDeferredLightingChanged); _mod.CApi.Settings.AddWatcher <int>("ssaoQuality", OnSSAOQualityChanged); _enabled = ModSettings.DeferredLightingEnabled; _mod.CApi.Event.RegisterRenderer(new DeferredLightingPreparer(this), EnumRenderStage.Opaque, "vsmod-deferred-lighting-prepare"); _mod.CApi.Event.RegisterRenderer(new DeferredLightingRenderer(this), EnumRenderStage.Opaque, "vsmod-deferred-lighting"); _mod.ShaderInjector.RegisterBoolProperty("VSMOD_DEFERREDLIGHTING", () => _enabled); _mod.CApi.Event.ReloadShader += OnReloadShaders; _mod.Events.RebuildFramebuffers += SetupFramebuffers; SetupFramebuffers(_platform.FrameBuffers); }
public static MeshRef GetScreenQuad(this ClientPlatformWindows platform) => platform.GetField <MeshRef>("screenQuad");
public static int LoadTextureArray(this ClientPlatformWindows platform, IBitmap[] bmps, int width, int height, bool bmpext = false, bool linearMag = false, int clampMode = 0, bool generateMipmaps = false) { if (System.Threading.Thread.CurrentThread.ManagedThreadId != RuntimeEnv.MainThreadId) { throw new InvalidOperationException("Texture uploads must happen in the main thread. We only have one OpenGL context."); } int id = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2DArray, id); GL.TexStorage3D(TextureTarget3d.Texture2DArray, 0, SizedInternalFormat.Rgba16, width, height, bmps.Length); if (platform.ENABLE_ANISOTROPICFILTERING) { float maxAniso = GL.GetFloat((GetPName)ExtTextureFilterAnisotropic.MaxTextureMaxAnisotropyExt); GL.TexParameter(TextureTarget.Texture2DArray, (TextureParameterName)ExtTextureFilterAnisotropic.TextureMaxAnisotropyExt, maxAniso); } if (clampMode == 1) { GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); } if (bmpext) { IntPtr[] pointers = new IntPtr[bmps.Length]; for (int i = 0; i < bmps.Length; i++) { var bmp = bmps[i]; var bmpExt = bmp as BitmapExternal; Bitmap bitmap = bmpExt.bmp; BitmapData bmp_data = bitmap.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); pointers[i] = bmp_data.Scan0; bitmap.UnlockBits(bmp_data); } GL.TexSubImage3D(TextureTarget.Texture2DArray, 0, 0, 0, 0, width, height, bmps.Length, PixelFormat.Bgra, PixelType.UnsignedByte, pointers); } else { byte[,] texels2d = new byte[bmps.Length, width *height * 4]; for (int i = 0; i < bmps.Length; i++) { var bmp = bmps[i]; for (int j = 0; j < bmp.Pixels.Length; j++) { byte[] bytes = ColorUtil.ToRGBABytes(bmp.Pixels[j]); texels2d[i, j * 4 + 0] = bytes[0]; texels2d[i, j * 4 + 1] = bytes[1]; texels2d[i, j * 4 + 2] = bytes[2]; texels2d[i, j * 4 + 3] = bytes[3]; } } byte[] texels = new byte[bmps.Length * width * height * 4]; int index = 0; for (int x = 0; x < texels2d.GetUpperBound(0); x++) { for (int y = 0; y < texels2d.GetUpperBound(1); y++) { texels[index++] = texels2d[x, y]; } } GL.TexSubImage3D(TextureTarget.Texture2DArray, 0, 0, 0, 0, width, height, bmps.Length, PixelFormat.Bgra, PixelType.UnsignedByte, texels); } if (platform.ENABLE_MIPMAPS && generateMipmaps) { int[] MipMapCount = new int[1]; GL.GetTexParameter(TextureTarget.Texture2DArray, GetTextureParameter.TextureMaxLevel, out MipMapCount[0]); if (MipMapCount[0] == 0) { GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); } else { GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.NearestMipmapLinear); } GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter, linearMag ? (int)TextureMagFilter.Linear : (int)TextureMagFilter.Nearest); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureLodBias, 0f); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMaxLevel, ClientSettings.MipMapLevel); // Causes seams between blocks :/ //GL.TexParameter(TextureTarget.Texture2D, (TextureParameterName)ExtTextureFilterAnisotropic.TextureMaxAnisotropyExt, 4); GL.GenerateMipmap(GenerateMipmapTarget.Texture2DArray); } else { GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter, linearMag ? (int)TextureMagFilter.Linear : (int)TextureMagFilter.Nearest); } return(id); }