content: package moe.ichinomiya.naven.utils;
  
  import net.minecraft.client.Minecraft;
  import net.minecraft.client.renderer.GlStateManager;
  import net.minecraft.client.shader.Framebuffer;
  import org.lwjgl.opengl.EXTFramebufferObject;
  import org.lwjgl.opengl.EXTPackedDepthStencil;
  import org.lwjgl.opengl.GL11;
  
  public class StencilUtils {
      private static final Minecraft mc = Minecraft.getMinecraft();
  
      // Stencil function
      public static void write(boolean renderClipLayer) {
          setupFBO();
  
          GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT);
          GL11.glEnable(GL11.GL_STENCIL_TEST);
          GL11.glStencilFunc(GL11.GL_ALWAYS, 1, 65535);
          GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
  
          if (!renderClipLayer) {
              GlStateManager.colorMask(false, false, false, false);
          }
      }
  
      public static void erase(boolean invert) {
          GlStateManager.colorMask(true, true, true, true);
          GL11.glStencilFunc(invert ? GL11.GL_EQUAL : GL11.GL_NOTEQUAL, 1, 65535);
          GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
      }
  
      public static void dispose() {
          GL11.glDisable(GL11.GL_STENCIL_TEST);
      }
  
      public static void setupFBO() {
          if (mc.getFramebuffer() != null && mc.getFramebuffer().depthBuffer > -1) {
              setupFBO(mc.getFramebuffer());
              mc.getFramebuffer().depthBuffer = -1;
          }
      }
  
      public static void setupFBO(Framebuffer fbo) {
          EXTFramebufferObject.glDeleteRenderbuffersEXT(fbo.depthBuffer);
          final int stencilDepthBufferID = EXTFramebufferObject.glGenRenderbuffersEXT();
          EXTFramebufferObject.glBindRenderbufferEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, stencilDepthBufferID);
          EXTFramebufferObject.glRenderbufferStorageEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, EXTPackedDepthStencil.GL_DEPTH_STENCIL_EXT, mc.displayWidth, mc.displayHeight);
          EXTFramebufferObject.glFramebufferRenderbufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_STENCIL_ATTACHMENT_EXT, EXTFramebufferObject.GL_RENDERBUFFER_EXT, stencilDepthBufferID);
          EXTFramebufferObject.glFramebufferRenderbufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_DEPTH_ATTACHMENT_EXT, EXTFramebufferObject.GL_RENDERBUFFER_EXT, stencilDepthBufferID);
      }
  }
  