* This is so that we can render to and from the framebuffer in a way that is familiar to us, instead of needing to * apply scales and translations manually. */ private static Matrix4f createProjectionMatrix(int width, int height) { Matrix4f projMatrix = new Matrix4f(); projMatrix.setIdentity(); projMatrix.m00 = 2.0F / (float) width; projMatrix.m11 = 2.0F / (float) (-height); projMatrix.m22 = -0.0020001999F; projMatrix.m33 = 1.0F; projMatrix.m03 = -1.0F; projMatrix.m13 = 1.0F; projMatrix.m23 = -1.0001999F; return projMatrix; } private static final double lastBgBlurFactor = -1; private static void blurBackground(OutputStuff output, float blurFactor) { if (!OpenGlHelper.isFramebufferEnabled() || !OpenGlHelper.areShadersSupported()) return; int width = Minecraft.getMinecraft().displayWidth; int height = Minecraft.getMinecraft().displayHeight; GlStateManager.matrixMode(GL11.GL_PROJECTION); GlStateManager.loadIdentity(); GlStateManager.ortho(0.0D, width, height, 0.0D, 1000.0D, 3000.0D); GlStateManager.matrixMode(GL11.GL_MODELVIEW); GlStateManager.loadIdentity(); GlStateManager.translate(0.0F, 0.0F, -2000.0F); if (blurOutputHorz == null) { blurOutputHorz = new Framebuffer(width, height, false); blurOutputHorz.setFramebufferFilter(GL11.GL_NEAREST); } if (blurOutputHorz == null || output == null) { return; } if (blurOutputHorz.framebufferWidth != width || blurOutputHorz.framebufferHeight != height) { blurOutputHorz.createBindFramebuffer(width, height); Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false); } if (output.blurShaderHorz == null) { try { output.blurShaderHorz = new Shader(Minecraft.getMinecraft().getResourceManager(), "blur", output.framebuffer, blurOutputHorz ); output.blurShaderHorz.getShaderManager().getShaderUniform("BlurDir").set(1, 0); output.blurShaderHorz.setProjectionMatrix(createProjectionMatrix(width, height)); } catch (Exception ignored) { } } if (output.blurShaderVert == null) { try { output.blurShaderVert = new Shader(Minecraft.getMinecraft().getResourceManager(), "blur", blurOutputHorz, output.framebuffer ); output.blurShaderVert.getShaderManager().getShaderUniform("BlurDir").set(0, 1); output.blurShaderVert.setProjectionMatrix(createProjectionMatrix(width, height)); } catch (Exception ignored) { } } if (output.blurShaderHorz != null && output.blurShaderVert != null) { if (output.blurShaderHorz.getShaderManager().getShaderUniform("Radius") == null) { //Corrupted shader? return; } output.blurShaderHorz.getShaderManager().getShaderUniform("Radius").set(blurFactor); output.blurShaderVert.getShaderManager().getShaderUniform("Radius").set(blurFactor); GL11.glPushMatrix(); GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, Minecraft.getMinecraft().getFramebuffer().framebufferObject); GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, output.framebuffer.framebufferObject); GL30.glBlitFramebuffer(0, 0, width, height, 0, 0, output.framebuffer.framebufferWidth, output.framebuffer.framebufferHeight, GL11.GL_COLOR_BUFFER_BIT, GL11.GL_NEAREST ); output.blurShaderHorz.loadShader(0); output.blurShaderVert.loadShader(0); GlStateManager.enableDepth(); GL11.glPopMatrix(); } Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false); } public static void renderBlurredBackground( float blurStrength, int screenWidth, int screenHeight, int x, int y, int blurWidth, int blurHeight ) { renderBlurredBackground(blurStrength, screenWidth, screenHeight, x, y, blurWidth, blurHeight, false); } /** * Renders a subsection of the blurred framebuffer on to the corresponding section of the screen. * Essentially, this method will "blur" the background inside the bounds specified by [x->x+blurWidth, y->y+blurHeight] */ public static void renderBlurredBackground( float blurStrength, int screenWidth, int screenHeight, int x, int y, int blurWidth, int blurHeight, boolean forcedUpdate ) { if (!OpenGlHelper.isFramebufferEnabled() || !OpenGlHelper.areShadersSupported()) return; if (blurStrength < 0.5) return; requestedBlurs.add(blurStrength); long currentTime = System.currentTimeMillis(); if (currentTime - lastBlur > 300) { shouldBlur = true; if (currentTime - lastBlur > 400 && forcedUpdate) return; } if (blurOutput.isEmpty()) return; OutputStuff out = blurOutput.get(blurStrength); if (out == null) { out = blurOutput.values().iterator().next(); } float uMin = x / (float) screenWidth; float uMax = (x + blurWidth) / (float) screenWidth; float vMin = (screenHeight - y) / (float) screenHeight; float vMax = (screenHeight - y - blurHeight) / (float) screenHeight; GlStateManager.depthMask(false); Gui.drawRect(x, y, x + blurWidth, y + blurHeight, fogColour); out.framebuffer.bindFramebufferTexture(); GlStateManager.color(1f, 1f, 1f, 1f); RenderUtils.drawTexturedRect(x, y, blurWidth, blurHeight, uMin, uMax, vMin, vMax); out.framebuffer.unbindFramebufferTexture(); GlStateManager.depthMask(true); } }