/* * Copyright (C) 2022 NotEnoughUpdates contributors * * This file is part of NotEnoughUpdates. * * NotEnoughUpdates is free software: you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * NotEnoughUpdates is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with NotEnoughUpdates. If not, see . */ package io.github.moulberry.notenoughupdates.miscfeatures; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.util.NEUResourceManager; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.entity.RenderItem; import net.minecraft.client.renderer.texture.TextureUtil; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.shader.Framebuffer; import net.minecraft.client.shader.Shader; import net.minecraft.item.ItemStack; import net.minecraft.util.Matrix4f; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL14; import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.GL45; import java.awt.*; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.HashMap; public class ItemRarityHalo { public static Framebuffer itemFramebuffer1 = null; public static Framebuffer itemFramebuffer2 = null; public static HashMap itemHaloTexMap = new HashMap<>(); public static Matrix4f projectionMatrix = null; public static Shader colourShader = null; public static Shader blurShaderHorz = null; public static Shader blurShaderVert = null; private static int oldScaledResolution = 0; public static void onItemRender(ItemStack stack, int x, int y) { if (x == 0 && y == 0) return; if (!OpenGlHelper.isFramebufferEnabled() || !OpenGlHelper.areShadersSupported()) return; NotEnoughUpdates neu = NotEnoughUpdates.INSTANCE; if (!neu.isOnSkyblock()) return; //if(neu.manager.config.itemHighlightOpacity.value <= 1) return; if (neu.manager.getInternalNameForItem(stack) == null) return; ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); int size = 16 * scaledresolution.getScaleFactor(); if (projectionMatrix == null) { projectionMatrix = Utils.createProjectionMatrix(size, size); } itemFramebuffer1 = checkFramebufferSizes(itemFramebuffer1, size, size); itemFramebuffer2 = checkFramebufferSizes(itemFramebuffer2, size, size); try { if (colourShader == null) { colourShader = new Shader(new NEUResourceManager(Minecraft.getMinecraft().getResourceManager()), "setrgbtoalpha", itemFramebuffer1, itemFramebuffer2 ); upload(colourShader, size, size); } if (blurShaderHorz == null) { blurShaderHorz = new Shader(new NEUResourceManager(Minecraft.getMinecraft().getResourceManager()), "blur", itemFramebuffer2, itemFramebuffer1 ); blurShaderHorz.getShaderManager().getShaderUniform("BlurDir").set(1, 0); blurShaderHorz.getShaderManager().getShaderUniform("Radius").set(5f); blurShaderHorz.getShaderManager().getShaderUniform("AlphaMult").set(2f); upload(blurShaderHorz, size, size); } if (blurShaderVert == null) { blurShaderVert = new Shader(new NEUResourceManager(Minecraft.getMinecraft().getResourceManager()), "blur", itemFramebuffer1, itemFramebuffer2 ); blurShaderVert.getShaderManager().getShaderUniform("BlurDir").set(0, 1); blurShaderVert.getShaderManager().getShaderUniform("Radius").set(5f); blurShaderVert.getShaderManager().getShaderUniform("AlphaMult").set(2f); upload(blurShaderVert, size, size); } } catch (Exception e) { return; } if (oldScaledResolution != scaledresolution.getScaleFactor()) { resetItemHaloCache(); oldScaledResolution = scaledresolution.getScaleFactor(); } int currentBuffer = GL11.glGetInteger(GL30.GL_FRAMEBUFFER_BINDING); IntBuffer currentViewport = BufferUtils.createIntBuffer(16); GL11.glGetInteger(GL11.GL_VIEWPORT, currentViewport); try { if (!itemHaloTexMap.containsKey(stack)) { int texture1 = TextureUtil.glGenTextures(); int texture2 = TextureUtil.glGenTextures(); GlStateManager.bindTexture(texture1); GL11.glTexImage2D( GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, size, size, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, ((ByteBuffer) null) ); itemFramebuffer1.bindFramebuffer(false); OpenGlHelper.glFramebufferTexture2D( OpenGlHelper.GL_FRAMEBUFFER, OpenGlHelper.GL_COLOR_ATTACHMENT0, 3553, texture1, 0 ); GlStateManager.bindTexture(texture2); GL11.glTexImage2D( GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, size, size, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, ((ByteBuffer) null) ); itemFramebuffer2.bindFramebuffer(false); OpenGlHelper.glFramebufferTexture2D( OpenGlHelper.GL_FRAMEBUFFER, OpenGlHelper.GL_COLOR_ATTACHMENT0, 3553, texture2, 0 ); itemFramebuffer1.framebufferClear(); itemFramebuffer2.framebufferClear(); GlStateManager.pushMatrix(); { GlStateManager.matrixMode(5889); GlStateManager.loadIdentity(); GlStateManager.ortho(0.0D, size, size, 0.0D, 1000.0D, 3000.0D); GlStateManager.matrixMode(5888); GlStateManager.loadIdentity(); GlStateManager.translate(0.0F, 0.0F, -2000.0F); GL11.glScalef(scaledresolution.getScaleFactor(), scaledresolution.getScaleFactor(), 1); itemFramebuffer1.bindFramebuffer(true); RenderItem itemRender = Minecraft.getMinecraft().getRenderItem(); RenderHelper.enableGUIStandardItemLighting(); float zLevel = itemRender.zLevel; itemRender.zLevel = -145; //Negates the z-offset of the below method. itemRender.renderItemAndEffectIntoGUI(stack, 0, 0); itemRender.zLevel = zLevel; RenderHelper.disableStandardItemLighting(); } GlStateManager.popMatrix(); GlStateManager.pushMatrix(); { GL45.glTextureBarrier(); GL11.glFlush(); GL11.glFinish(); executeShader(colourShader); //GL45.glTextureBarrier(); GL11.glFlush(); GL11.glFinish(); //executeShader(blurShaderHorz); //GL45.glTextureBarrier(); GL11.glFlush(); GL11.glFinish(); //executeShader(blurShaderVert); //GL45.glTextureBarrier(); GL11.glFlush(); GL11.glFinish(); } GlStateManager.popMatrix(); GlStateManager.matrixMode(5889); GlStateManager.loadIdentity(); GlStateManager.ortho( 0.0D, scaledresolution.getScaledWidth_double(), scaledresolution.getScaledHeight_double(), 0.0D, 1000.0D, 3000.0D ); GlStateManager.matrixMode(5888); OpenGlHelper.glBindFramebuffer(OpenGlHelper.GL_FRAMEBUFFER, currentBuffer); GlStateManager.viewport( currentViewport.get(), currentViewport.get(), currentViewport.get(), currentViewport.get() ); //TextureUtil.deleteTexture(texture1); itemHaloTexMap.put(stack, texture2); } OpenGlHelper.glBindFramebuffer(OpenGlHelper.GL_FRAMEBUFFER, currentBuffer); GlStateManager.viewport( currentViewport.get(), currentViewport.get(), currentViewport.get(), currentViewport.get() ); GlStateManager.bindTexture(itemHaloTexMap.get(stack)); Color color = Utils.getPrimaryColour(stack.getDisplayName()); //GlStateManager.color(color.getRed()/255f, color.getGreen()/255f, color.getBlue()/255f, // NotEnoughUpdates.INSTANCE.manager.config.itemHighlightOpacity.value.floatValue()/255f); Utils.drawTexturedRect(x, y, 16, 16, 0, 1, 1, 0, GL11.GL_NEAREST ); GlStateManager.bindTexture(0); } catch (Exception e) { e.printStackTrace(); OpenGlHelper.glBindFramebuffer(OpenGlHelper.GL_FRAMEBUFFER, currentBuffer); GlStateManager.viewport( currentViewport.get(), currentViewport.get(), currentViewport.get(), currentViewport.get() ); } } private static Framebuffer checkFramebufferSizes(Framebuffer framebuffer, int width, int height) { if (framebuffer == null || framebuffer.framebufferWidth != width || framebuffer.framebufferHeight != height) { if (framebuffer == null) { framebuffer = new Framebuffer(width, height, true); } else { framebuffer.createBindFramebuffer(width, height); } framebuffer.setFramebufferFilter(GL11.GL_NEAREST); } return framebuffer; } public static void resetItemHaloCache() { ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); int size = 16 * scaledresolution.getScaleFactor(); for (int tex : itemHaloTexMap.values()) { TextureUtil.deleteTexture(tex); } itemHaloTexMap.clear(); if (NotEnoughUpdates.INSTANCE.isOnSkyblock()) { projectionMatrix = Utils.createProjectionMatrix(size, size); upload(colourShader, size, size); upload(blurShaderHorz, size, size); upload(blurShaderVert, size, size); } } private static void upload(Shader shader, int width, int height) { if (shader == null) return; shader.getShaderManager().getShaderUniformOrDefault("ProjMat").set(projectionMatrix); shader.getShaderManager().getShaderUniformOrDefault("InSize").set(width, height); shader.getShaderManager().getShaderUniformOrDefault("OutSize").set(width, height); shader.getShaderManager().getShaderUniformOrDefault("ScreenSize").set((float) width, (float) height); } private static void executeShader(Shader shader) { GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.disableBlend(); GlStateManager.disableDepth(); GlStateManager.disableAlpha(); GlStateManager.disableFog(); GlStateManager.disableLighting(); GlStateManager.disableColorMaterial(); GlStateManager.enableTexture2D(); GlStateManager.bindTexture(0); float f = (float) shader.framebufferOut.framebufferTextureWidth; float f1 = (float) shader.framebufferOut.framebufferTextureHeight; GlStateManager.viewport(0, 0, (int) f, (int) f1); shader.getShaderManager().useShader(); shader.getShaderManager().addSamplerTexture("DiffuseSampler", shader.framebufferIn); shader.framebufferOut.framebufferClear(); shader.framebufferOut.bindFramebuffer(false); GlStateManager.depthMask(false); GlStateManager.enableAlpha(); GlStateManager.enableBlend(); GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); Tessellator tessellator = Tessellator.getInstance(); WorldRenderer worldrenderer = tessellator.getWorldRenderer(); worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR); worldrenderer.pos(0.0D, f1, 500.0D).color(255, 255, 255, 255).endVertex(); worldrenderer.pos(f, f1, 500.0D).color(255, 255, 255, 255).endVertex(); worldrenderer.pos(f, 0.0D, 500.0D).color(255, 255, 255, 255).endVertex(); worldrenderer.pos(0.0D, 0.0D, 500.0D).color(255, 255, 255, 255).endVertex(); tessellator.draw(); GlStateManager.depthMask(true); shader.getShaderManager().endShader(); shader.framebufferOut.unbindFramebuffer(); shader.framebufferIn.unbindFramebufferTexture(); } }