From 689a6da815bcc67c6f9b6bbd558750f57b5c4ec8 Mon Sep 17 00:00:00 2001 From: Vladislav Laetansky Date: Sat, 20 Aug 2022 19:19:40 +0300 Subject: [PATCH 1/4] Eliminate Z-fighting, render potions and glint --- .../client/render/SurfaceItemRenderer.java | 184 ++++++++++++++++++ .../client/render/TileEntityBaseRenderer.java | 6 +- .../common/blocks/StorageLocal.java | 17 +- 3 files changed, 188 insertions(+), 19 deletions(-) create mode 100644 src/main/java/mcp/mobius/betterbarrels/client/render/SurfaceItemRenderer.java diff --git a/src/main/java/mcp/mobius/betterbarrels/client/render/SurfaceItemRenderer.java b/src/main/java/mcp/mobius/betterbarrels/client/render/SurfaceItemRenderer.java new file mode 100644 index 0000000..dfd1bd5 --- /dev/null +++ b/src/main/java/mcp/mobius/betterbarrels/client/render/SurfaceItemRenderer.java @@ -0,0 +1,184 @@ +package mcp.mobius.betterbarrels.client.render; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +/** + * This class is specifically designed to render items on top of surfaces in the world with both glint effect and + * through all render passes with no z-fighting using polygon offset. + * + * @author jaquadro + */ +public class SurfaceItemRenderer extends RenderItem { + + private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); + + private RenderBlocks renderBlocksRi = new RenderBlocks(); + + @Override + public byte getMiniBlockCount (ItemStack stack, byte original) { + return 1; + } + + @Override + public boolean shouldBob () { + return false; + } + + @Override + public boolean shouldSpreadItems () { + return false; + } + + // The default Mojang code for item render does not handle glinted or multi-pass items gracefully in a non-UI + // setting. This modified implementation will render these items without unsightly Z-fighting. + @Override + public void renderItemIntoGUI (FontRenderer fontRenderer, TextureManager texManager, ItemStack itemStack, int x, int y, boolean renderEffect) { + if (itemStack.getItemSpriteNumber() == 0 && RenderBlocks.renderItemIn3d(Block.getBlockFromItem(itemStack.getItem()).getRenderType())) { + renderItemIntoGUIBlock(fontRenderer, texManager, itemStack, x, y, renderEffect); + return; + } + + Item item = itemStack.getItem(); + int meta = itemStack.getItemDamage(); + + ResourceLocation loc = itemStack.getItem().requiresMultipleRenderPasses() + ? (item.getSpriteNumber() == 0 ? TextureMap.locationBlocksTexture : TextureMap.locationItemsTexture) + : (texManager.getResourceLocation(itemStack.getItemSpriteNumber())); + + for (int i = 0; i < item.getRenderPasses(meta); ++i) { + OpenGlHelper.glBlendFunc(770, 771, 1, 0); + texManager.bindTexture(loc); + + IIcon icon = itemStack.getItem().requiresMultipleRenderPasses() + ? item.getIcon(itemStack, i) + : itemStack.getIconIndex(); + + if (icon == null) + continue; + + int color = itemStack.getItem().getColorFromItemStack(itemStack, i); + float r = (float)(color >> 16 & 255) / 255.0F; + float g = (float)(color >> 8 & 255) / 255.0F; + float b = (float)(color & 255) / 255.0F; + + if (renderWithColor) + GL11.glColor4f(r, g, b, 1.0F); + + GL11.glEnable(GL11.GL_POLYGON_OFFSET_FILL); + GL11.glPolygonOffset(-1f, -1); + + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_ALPHA_TEST); + + renderIcon(x, y, icon, 16, 16); + + GL11.glDisable(GL11.GL_ALPHA_TEST); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + + if (renderEffect && itemStack.hasEffect(i)) + renderEffect(texManager, x, y); + + GL11.glDisable(GL11.GL_POLYGON_OFFSET_FILL); + } + } + + @Override + public void renderEffect (TextureManager manager, int x, int y) { + GL11.glDepthFunc(GL11.GL_EQUAL); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDepthMask(false); + manager.bindTexture(RES_ITEM_GLINT); + GL11.glEnable(GL11.GL_ALPHA_TEST); + GL11.glEnable(GL11.GL_BLEND); + GL11.glColor4f(0.5F, 0.25F, 0.8F, 1.0F); + renderGlint(x, y, 16, 16); + GL11.glDepthMask(true); + GL11.glDisable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_ALPHA_TEST); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDepthFunc(GL11.GL_LEQUAL); + } + + private void renderGlint (int x, int y, int w, int h) + { + for (int i = 0; i < 2; ++i) + { + OpenGlHelper.glBlendFunc(772, 1, 0, 0); + float uScale = 0.00390625F; + float vScale = 0.00390625F; + float u = (Minecraft.getSystemTime() % (3000 + i * 1873)) / (3000.0F + i * 1873) * 256.0F; + float v = 0.0F; + + float hScale = (i < 1) ? 4.0F : -1.0F; + + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(x + 0, y + h, 0, (u + (float)h * hScale) * uScale, (v + (float)h) * vScale); + tessellator.addVertexWithUV(x + w, y + h, 0, (u + (float)w + (float)h * hScale) * uScale, (v + (float)h) * vScale); + tessellator.addVertexWithUV(x + w, y + 0, 0, (u + (float)w) * uScale, (v + 0.0F) * vScale); + tessellator.addVertexWithUV(x + 0, y + 0, 0, (u + 0.0F) * uScale, (v + 0.0F) * vScale); + tessellator.draw(); + } + } + + private void renderItemIntoGUIBlock (FontRenderer fontRenderer, TextureManager texManager, ItemStack itemStack, int x, int y, boolean renderEffect) { + texManager.bindTexture(TextureMap.locationBlocksTexture); + Block block = Block.getBlockFromItem(itemStack.getItem()); + + if (block.getRenderBlockPass() != 0) { + GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); + GL11.glEnable(GL11.GL_BLEND); + OpenGlHelper.glBlendFunc(770, 771, 1, 0); + } + else { + GL11.glAlphaFunc(GL11.GL_GREATER, 0.5F); + GL11.glDisable(GL11.GL_BLEND); + } + + GL11.glPushMatrix(); + GL11.glTranslatef(x - 2, y + 3, zLevel - 3); + GL11.glScalef(10, 10, 10); + GL11.glTranslatef(1, 0.5f, 1); + GL11.glScalef(1, 1, -1); + GL11.glRotatef(210, 1, 0, 0); + GL11.glRotatef(45, 0, 1, 0); + + int color = itemStack.getItem().getColorFromItemStack(itemStack, 0); + float r = (float)(color >> 16 & 255) / 255.0F; + float g = (float)(color >> 8 & 255) / 255.0F; + float b = (float)(color & 255) / 255.0F; + + if (this.renderWithColor) + GL11.glColor4f(r * 1, g * 1, b * 1, 1.0F); + + GL11.glRotatef(-90, 0, 1, 0); + GL11.glEnable(GL11.GL_POLYGON_OFFSET_FILL); + GL11.glPolygonOffset(-1f, -1f); + + this.renderBlocksRi.useInventoryTint = this.renderWithColor; + this.renderBlocksRi.renderBlockAsItem(block, itemStack.getItemDamage(), 1); + this.renderBlocksRi.useInventoryTint = true; + + GL11.glDisable(GL11.GL_POLYGON_OFFSET_FILL); + + if (block.getRenderBlockPass() == 0) + GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F); + + GL11.glPopMatrix(); + } +} diff --git a/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java b/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java index f87e989..43fcb71 100644 --- a/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java +++ b/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java @@ -22,7 +22,7 @@ public abstract class TileEntityBaseRenderer extends TileEntitySpecialRenderer { protected float scale = 1f/256f; protected RenderBlocks renderBlocks = new RenderBlocks(); - protected RenderItem renderItem = new RenderItem(); + protected RenderItem renderItem = new SurfaceItemRenderer(); protected Minecraft mc = Minecraft.getMinecraft(); protected TextureManager texManager = mc.renderEngine; @@ -95,10 +95,10 @@ protected void renderStackOnBlock(ItemStack stack, ForgeDirection side, ForgeDir GL11.glPushMatrix(); this.alignRendering(side, orientation, barrelPos); - this.moveRendering(size, posx, posy, -0.001); + this.moveRendering(size, posx, posy, 0); if (!ForgeHooksClient.renderInventoryItem(this.renderBlocks, this.texManager, stack, true, 0.0F, 0.0F, 0.0F)) { - this.renderItem.renderItemIntoGUI(this.renderFont, this.texManager, stack, 0, 0); + this.renderItem.renderItemIntoGUI(this.renderFont, this.texManager, stack, 0, 0, true); } GL11.glPopMatrix(); diff --git a/src/main/java/mcp/mobius/betterbarrels/common/blocks/StorageLocal.java b/src/main/java/mcp/mobius/betterbarrels/common/blocks/StorageLocal.java index 086ed21..4998085 100644 --- a/src/main/java/mcp/mobius/betterbarrels/common/blocks/StorageLocal.java +++ b/src/main/java/mcp/mobius/betterbarrels/common/blocks/StorageLocal.java @@ -22,7 +22,6 @@ public class StorageLocal implements IBarrelStorage { private ItemStack outputStack = null; // Slot 1 private ItemStack prevOutputStack = null; private ItemStack itemTemplate = null; - private ItemStack renderingTemplate = null; private int totalAmount = 0; //Total number of items private int stackAmount = 64; //Number of items in a stack @@ -60,18 +59,7 @@ public StorageLocal(int nupgrades) { public ItemStack getItem() { return this.itemTemplate; } @Override public ItemStack getItemForRender() { - if (this.renderingTemplate == null) { - this.renderingTemplate = this.itemTemplate.copy(); - if (this.renderingTemplate.hasTagCompound() && this.renderingTemplate.getTagCompound().hasKey("ench")) - this.renderingTemplate.getTagCompound().removeTag("ench"); - if (this.renderingTemplate.hasTagCompound() && this.renderingTemplate.getTagCompound().hasKey("CustomPotionEffects")) - this.renderingTemplate.getTagCompound().removeTag("CustomPotionEffects"); - if (this.renderingTemplate.getItem() == Items.potionitem) - this.renderingTemplate.setItemDamage(0); - if (this.renderingTemplate.getItem() == Items.experience_bottle) - this.renderingTemplate = new ItemStack(Items.potionitem, 0, 0); - } - return this.renderingTemplate; + return itemTemplate; } @Override @@ -81,12 +69,9 @@ public void setItem(ItemStack stack) { this.itemTemplate.stackSize = 0; this.stackAmount = stack.getMaxStackSize(); this.cachedBarrelOreItem = new ItemImmut(Item.getIdFromItem(this.itemTemplate.getItem()), this.itemTemplate.getItemDamage()); - // Force reset the render template - this.renderingTemplate = null; this.getItemForRender(); } else { this.itemTemplate = null; - this.renderingTemplate = null; this.stackAmount = 64; this.cachedBarrelOreItem = null; } From 3ef95fca573f6cd8a075bab87cb2e602c907154b Mon Sep 17 00:00:00 2001 From: Vladislav Laetansky Date: Sat, 20 Aug 2022 19:44:48 +0300 Subject: [PATCH 2/4] Simplify GL state saving --- .../render/TileEntityBarrelRenderer.java | 8 ++++--- .../client/render/TileEntityBaseRenderer.java | 24 ++++--------------- 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBarrelRenderer.java b/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBarrelRenderer.java index d188259..d962a0e 100644 --- a/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBarrelRenderer.java +++ b/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBarrelRenderer.java @@ -39,14 +39,16 @@ public void renderTileEntityAt(TileEntity tileEntity, double xpos, double ypos, // the following is how it was set, enabling lighting makes it look better with smooth lighting, mostly... bottom labels are abit dark // will need to actually properly calculate lighting, but for now this looks better on smooth lit barrels than the full bright it was before // found another bug: disabling lighting causes grass to look white, and a few other quirks, putting this on hold for the momment - int[][] savedGLState = modifyGLState(new int[]{ GL11.GL_BLEND, GL11.GL_LIGHTING }, null); + GL11.glPushAttrib(GL11.GL_BLEND | GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); ForgeDirection orientation = ((TileEntityBarrel) tileEntity).orientation; ForgeDirection rotation = ((TileEntityBarrel) tileEntity).rotation; TileEntityBarrel barrelEntity = (TileEntityBarrel)tileEntity; Coordinates barrelPos = new Coordinates(0, xpos, ypos, zpos); - boolean isHammer = this.mc.thePlayer.getHeldItem() != null ? this.mc.thePlayer.getHeldItem().getItem() instanceof IOverlayItem ? true : false : false; + boolean isHammer = this.mc.thePlayer.getHeldItem() != null && this.mc.thePlayer.getHeldItem().getItem() instanceof IOverlayItem; boolean hasItem = barrelEntity.getStorage().hasItem(); int color = StructuralLevel.LEVELS[barrelEntity.coreUpgrades.levelStructural].clientData.getTextColor(); @@ -118,7 +120,7 @@ else if (this.isItemDisplaySide(barrelEntity, forgeSide)) { } } - this.restoreGlState(savedGLState); + GL11.glPopAttrib(); this.loadBoundTexture(); } } diff --git a/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java b/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java index 43fcb71..7d513c2 100644 --- a/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java +++ b/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java @@ -91,7 +91,7 @@ protected void renderTextOnBlock(String renderString, ForgeDirection side, Forge protected void renderStackOnBlock(ItemStack stack, ForgeDirection side, ForgeDirection orientation, Coordinates barrelPos, float size, double posx, double posy){ if (stack == null) { return; } - int[][] savedGLState =saveGLState(new int[]{ GL11.GL_ALPHA_TEST, GL11.GL_LIGHTING }); + GL11.glPushAttrib(GL11.GL_ALPHA_TEST | GL11.GL_LIGHTING); GL11.glPushMatrix(); this.alignRendering(side, orientation, barrelPos); @@ -102,13 +102,13 @@ protected void renderStackOnBlock(ItemStack stack, ForgeDirection side, ForgeDir } GL11.glPopMatrix(); - restoreGlState(savedGLState); + GL11.glPopAttrib(); } protected void renderIconOnBlock(IIcon icon, int sheet, ForgeDirection side, ForgeDirection orientation, Coordinates barrelPos, float size, double posx, double posy, double zdepth){ if (icon == null) { return ; } - int[][] savedGLState = modifyGLState(new int[]{ GL11.GL_LIGHTING }, new int[]{ GL11.GL_ALPHA_TEST }); + GL11.glPushAttrib(GL11.GL_ALPHA_TEST | GL11.GL_LIGHTING); GL11.glPushMatrix(); this.alignRendering(side, orientation, barrelPos); @@ -118,7 +118,7 @@ protected void renderIconOnBlock(IIcon icon, int sheet, ForgeDirection side, Fo this.drawIcon(0, 0, icon, side); GL11.glPopMatrix(); - restoreGlState(savedGLState); + GL11.glPopAttrib(); } protected void renderIconOnBlock(int index, ForgeDirection side, ForgeDirection orientation, Coordinates barrelPos, float size, double posx, double posy, double zdepth){ @@ -197,22 +197,6 @@ protected void loadBoundTexture(){ GL11.glBindTexture(GL11.GL_TEXTURE_2D, boundTexIndex); } - protected int[][] saveGLState(int[] bitsToSave) { - if (bitsToSave == null) { return null; } - - int[][] savedGLState = new int[bitsToSave.length][2]; - int count = 0; - - for (int glBit : bitsToSave) { - savedGLState[count][0] = glBit; - savedGLState[count++][1] = GL11.glIsEnabled(glBit) ? 1: 0; - } - return savedGLState; - } - - protected int[][] modifyGLState(int[] bitsToDisable, int[] bitsToEnable) { - return modifyGLState(bitsToDisable, bitsToEnable, null); - } protected int[][] modifyGLState(int[] bitsToDisable, int[] bitsToEnable, int[] bitsToSave) { if (bitsToDisable == null && bitsToEnable == null && bitsToSave == null) { return null; } From 913fd81474e913bdd633bb43740b805449d90fd0 Mon Sep 17 00:00:00 2001 From: Vladislav Laetansky Date: Sat, 20 Aug 2022 20:19:01 +0300 Subject: [PATCH 3/4] Actually save GL state --- .../betterbarrels/client/render/TileEntityBarrelRenderer.java | 2 +- .../betterbarrels/client/render/TileEntityBaseRenderer.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBarrelRenderer.java b/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBarrelRenderer.java index d962a0e..d2faac5 100644 --- a/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBarrelRenderer.java +++ b/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBarrelRenderer.java @@ -39,7 +39,7 @@ public void renderTileEntityAt(TileEntity tileEntity, double xpos, double ypos, // the following is how it was set, enabling lighting makes it look better with smooth lighting, mostly... bottom labels are abit dark // will need to actually properly calculate lighting, but for now this looks better on smooth lit barrels than the full bright it was before // found another bug: disabling lighting causes grass to look white, and a few other quirks, putting this on hold for the momment - GL11.glPushAttrib(GL11.GL_BLEND | GL11.GL_LIGHTING); + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); GL11.glDisable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_LIGHTING); diff --git a/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java b/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java index 7d513c2..4f1f6f9 100644 --- a/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java +++ b/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java @@ -91,7 +91,7 @@ protected void renderTextOnBlock(String renderString, ForgeDirection side, Forge protected void renderStackOnBlock(ItemStack stack, ForgeDirection side, ForgeDirection orientation, Coordinates barrelPos, float size, double posx, double posy){ if (stack == null) { return; } - GL11.glPushAttrib(GL11.GL_ALPHA_TEST | GL11.GL_LIGHTING); + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); GL11.glPushMatrix(); this.alignRendering(side, orientation, barrelPos); @@ -108,7 +108,7 @@ protected void renderStackOnBlock(ItemStack stack, ForgeDirection side, ForgeDir protected void renderIconOnBlock(IIcon icon, int sheet, ForgeDirection side, ForgeDirection orientation, Coordinates barrelPos, float size, double posx, double posy, double zdepth){ if (icon == null) { return ; } - GL11.glPushAttrib(GL11.GL_ALPHA_TEST | GL11.GL_LIGHTING); + GL11.glPushAttrib(GL11.GL_ENABLE_BIT); GL11.glPushMatrix(); this.alignRendering(side, orientation, barrelPos); From 2eca5515d9b31e2fd8d86e5541f3f0b155addbd4 Mon Sep 17 00:00:00 2001 From: Vladislav Laetansky Date: Sun, 21 Aug 2022 18:49:42 +0300 Subject: [PATCH 4/4] Increase depth offset --- .../betterbarrels/client/render/TileEntityBaseRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java b/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java index 4f1f6f9..d99d562 100644 --- a/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java +++ b/src/main/java/mcp/mobius/betterbarrels/client/render/TileEntityBaseRenderer.java @@ -95,7 +95,7 @@ protected void renderStackOnBlock(ItemStack stack, ForgeDirection side, ForgeDir GL11.glPushMatrix(); this.alignRendering(side, orientation, barrelPos); - this.moveRendering(size, posx, posy, 0); + this.moveRendering(size, posx, posy, -0.001); if (!ForgeHooksClient.renderInventoryItem(this.renderBlocks, this.texManager, stack, true, 0.0F, 0.0F, 0.0F)) { this.renderItem.renderItemIntoGUI(this.renderFont, this.texManager, stack, 0, 0, true);