From c0de9efee25cb1956cc47504f5d54ff0fe0e9674 Mon Sep 17 00:00:00 2001 From: nea Date: Wed, 6 Sep 2023 01:48:31 +0200 Subject: Improve performance of Item List --- .../moe/nea/firmament/rei/FirmamentReiPlugin.kt | 2 +- .../moe/nea/firmament/rei/NEUItemEntryRenderer.kt | 146 ++++++++++++++++++++- .../moe/nea/firmament/rei/SBItemEntryDefinition.kt | 22 ++-- 3 files changed, 156 insertions(+), 14 deletions(-) (limited to 'src/main/kotlin') diff --git a/src/main/kotlin/moe/nea/firmament/rei/FirmamentReiPlugin.kt b/src/main/kotlin/moe/nea/firmament/rei/FirmamentReiPlugin.kt index b39dafa..de743c6 100644 --- a/src/main/kotlin/moe/nea/firmament/rei/FirmamentReiPlugin.kt +++ b/src/main/kotlin/moe/nea/firmament/rei/FirmamentReiPlugin.kt @@ -37,7 +37,7 @@ class FirmamentReiPlugin : REIClientPlugin { companion object { fun EntryStack.asItemEntry(): EntryStack { - return EntryStack.of(VanillaEntryTypes.ITEM, value.asItemStack()) + return EntryStack.of(VanillaEntryTypes.ITEM, value.asImmutableItemStack()) } val SKYBLOCK_ITEM_TYPE_ID = Identifier("firmament", "skyblockitems") diff --git a/src/main/kotlin/moe/nea/firmament/rei/NEUItemEntryRenderer.kt b/src/main/kotlin/moe/nea/firmament/rei/NEUItemEntryRenderer.kt index a123fa8..b3e5a10 100644 --- a/src/main/kotlin/moe/nea/firmament/rei/NEUItemEntryRenderer.kt +++ b/src/main/kotlin/moe/nea/firmament/rei/NEUItemEntryRenderer.kt @@ -1,20 +1,34 @@ /* * SPDX-FileCopyrightText: 2023 Linnea Gräf + * SPDX-FileCopyrightText: 2018-2023 shedaniel * * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-License-Identifier: MIT */ package moe.nea.firmament.rei +import com.mojang.blaze3d.platform.GlStateManager.DstFactor +import com.mojang.blaze3d.platform.GlStateManager.SrcFactor +import com.mojang.blaze3d.systems.RenderSystem import me.shedaniel.math.Rectangle +import me.shedaniel.rei.api.client.entry.renderer.BatchedEntryRenderer import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer import me.shedaniel.rei.api.client.gui.widgets.Tooltip import me.shedaniel.rei.api.client.gui.widgets.TooltipContext import me.shedaniel.rei.api.common.entry.EntryStack -import net.minecraft.client.gui.DrawContext import moe.nea.firmament.rei.FirmamentReiPlugin.Companion.asItemEntry +import net.minecraft.client.MinecraftClient +import net.minecraft.client.gui.DrawContext +import net.minecraft.client.render.DiffuseLighting +import net.minecraft.client.render.OverlayTexture +import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.render.model.BakedModel +import net.minecraft.client.render.model.json.ModelTransformationMode +import net.minecraft.client.texture.SpriteAtlasTexture +import net.minecraft.item.ItemStack -object NEUItemEntryRenderer : EntryRenderer { +object NEUItemEntryRenderer : EntryRenderer, BatchedEntryRenderer { override fun render( entry: EntryStack, context: DrawContext, @@ -26,8 +40,136 @@ object NEUItemEntryRenderer : EntryRenderer { entry.asItemEntry().render(context, bounds, mouseX, mouseY, delta) } + val minecraft = MinecraftClient.getInstance() + override fun getTooltip(entry: EntryStack, tooltipContext: TooltipContext): Tooltip? { return entry.asItemEntry().getTooltip(tooltipContext, false) } + override fun getExtraData(entry: EntryStack): BakedModel { + return minecraft.itemRenderer.getModel(entry.asItemEntry().value, minecraft.world, minecraft.player, 0) + } + + override fun getBatchIdentifier(entry: EntryStack?, bounds: Rectangle?, extraData: BakedModel): Int { + return 1738923 + if (extraData.isSideLit) 1 else 0 + } + + override fun startBatch( + entry: EntryStack, + model: BakedModel, + graphics: DrawContext, + delta: Float + ) { + setupGL(model) + val modelViewStack = RenderSystem.getModelViewStack() + modelViewStack.push() + modelViewStack.scale(20.0f, -20.0f, 1.0f) + RenderSystem.applyModelViewMatrix() + } + + fun setupGL(model: BakedModel) { + minecraft.textureManager.getTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE) + .setFilter(false, false) + RenderSystem.setShaderTexture(0, SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE) + RenderSystem.enableBlend() + RenderSystem.blendFunc(SrcFactor.SRC_ALPHA, DstFactor.ONE_MINUS_SRC_ALPHA) + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f) + val sideLit = model.isSideLit + if (!sideLit) { + DiffuseLighting.disableGuiDepthLighting() + } + } + + override fun renderBase( + entry: EntryStack, + model: BakedModel, + graphics: DrawContext, + immediate: VertexConsumerProvider.Immediate, + bounds: Rectangle, + mouseX: Int, + mouseY: Int, + delta: Float + ) { + if (entry.isEmpty) return + val value = entry.asItemEntry().value + graphics.matrices.push() + graphics.matrices.translate(bounds.centerX.toFloat() / 20.0f, bounds!!.centerY.toFloat() / -20.0f, 0.0f) + graphics.matrices.scale( + bounds.getWidth().toFloat() / 20.0f, + (bounds.getWidth() + bounds.getHeight()).toFloat() / 2.0f / 20.0f, + 1.0f + ) + minecraft + .itemRenderer + .renderItem( + value, + ModelTransformationMode.GUI, + false, + graphics.matrices, + immediate, + 15728880, + OverlayTexture.DEFAULT_UV, + model + ) + graphics.matrices.pop() + + } + + override fun afterBase( + entry: EntryStack, + model: BakedModel, + graphics: DrawContext, + delta: Float + ) { + this.endGL(model) + RenderSystem.getModelViewStack().pop() + RenderSystem.applyModelViewMatrix() + } + + fun endGL(model: BakedModel) { + RenderSystem.enableDepthTest() + val sideLit = model.isSideLit + if (!sideLit) { + DiffuseLighting.enableGuiDepthLighting() + } + } + + override fun renderOverlay( + entry: EntryStack, + extraData: BakedModel, + graphics: DrawContext, + immediate: VertexConsumerProvider.Immediate, + bounds: Rectangle, + mouseX: Int, + mouseY: Int, + delta: Float + ) { + val modelViewStack = RenderSystem.getModelViewStack() + modelViewStack.push() + modelViewStack.multiplyPositionMatrix(graphics.matrices.peek().positionMatrix) + modelViewStack.translate(bounds.x.toFloat(), bounds.y.toFloat(), 0.0f) + modelViewStack.scale( + bounds.width.toFloat() / 16.0f, + (bounds.getWidth() + bounds.getHeight()).toFloat() / 2.0f / 16.0f, + 1.0f + ) + RenderSystem.applyModelViewMatrix() + renderOverlay(DrawContext(minecraft, graphics.vertexConsumers), entry.asItemEntry()) + modelViewStack.pop() + RenderSystem.applyModelViewMatrix() + } + fun renderOverlay(graphics: DrawContext, entry: EntryStack) { + if (!entry.isEmpty) { + graphics.drawItemInSlot(MinecraftClient.getInstance().textRenderer, entry.value, 0, 0, null) + } + } + + override fun endBatch( + entry: EntryStack?, + extraData: BakedModel?, + graphics: DrawContext?, + delta: Float + ) { + } + } diff --git a/src/main/kotlin/moe/nea/firmament/rei/SBItemEntryDefinition.kt b/src/main/kotlin/moe/nea/firmament/rei/SBItemEntryDefinition.kt index fc0db3d..25c450a 100644 --- a/src/main/kotlin/moe/nea/firmament/rei/SBItemEntryDefinition.kt +++ b/src/main/kotlin/moe/nea/firmament/rei/SBItemEntryDefinition.kt @@ -9,7 +9,6 @@ package moe.nea.firmament.rei import io.github.moulberry.repo.data.NEUIngredient import io.github.moulberry.repo.data.NEUItem import io.github.moulberry.repo.data.Rarity -import java.util.stream.Stream import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer import me.shedaniel.rei.api.common.entry.EntrySerializer import me.shedaniel.rei.api.common.entry.EntryStack @@ -17,20 +16,17 @@ import me.shedaniel.rei.api.common.entry.comparison.ComparisonContext import me.shedaniel.rei.api.common.entry.type.EntryDefinition import me.shedaniel.rei.api.common.entry.type.EntryType import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes -import net.minecraft.item.ItemStack -import net.minecraft.registry.tag.TagKey -import net.minecraft.text.Text -import net.minecraft.util.Identifier import moe.nea.firmament.rei.FirmamentReiPlugin.Companion.asItemEntry import moe.nea.firmament.repo.ExpLadders import moe.nea.firmament.repo.ItemCache import moe.nea.firmament.repo.ItemCache.asItemStack import moe.nea.firmament.repo.RepoManager -import moe.nea.firmament.util.FirmFormatters -import moe.nea.firmament.util.HypixelPetInfo -import moe.nea.firmament.util.SkyblockId -import moe.nea.firmament.util.petData -import moe.nea.firmament.util.skyBlockId +import moe.nea.firmament.util.* +import net.minecraft.item.ItemStack +import net.minecraft.registry.tag.TagKey +import net.minecraft.text.Text +import net.minecraft.util.Identifier +import java.util.stream.Stream // TODO: add in extra data like pet info, into this structure data class PetData( @@ -67,7 +63,7 @@ data class SBItemStack( RepoManager.getPotentialStubPetData(skyblockId) ) - private val itemStack by lazy { + private val itemStack by lazy(LazyThreadSafetyMode.NONE) { if (skyblockId == SkyblockId.COINS) return@lazy ItemCache.coinItem(stackSize) val replacementData = mutableMapOf() @@ -87,6 +83,10 @@ data class SBItemStack( return@lazy neuItem.asItemStack(idHint = skyblockId, replacementData).copyWithCount(stackSize) } + fun asImmutableItemStack(): ItemStack { + return itemStack + } + fun asItemStack(): ItemStack { return itemStack.copy() } -- cgit