diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/AtlasSkinElement.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/AtlasSkinElement.kt index ad0a1c839..a48a6582a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/AtlasSkinElement.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/AtlasSkinElement.kt @@ -86,7 +86,7 @@ class AtlasSkinElement( WidgetAtlasHolder.INSTANCE.queueRebuild() } - val renderTypeGUI by lazy { + val renderTypeNoDepth by lazy { val builder = RenderType.CompositeState.builder() builder.setTextureState(TextureStateShard(WidgetAtlasHolder.LOCATION, false, false)) @@ -100,7 +100,29 @@ class AtlasSkinElement( })) @Suppress("INACCESSIBLE_TYPE") - RenderType.create("gui_element", + RenderType.create("otm_gui_element_no_depth", + DefaultVertexFormat.POSITION_COLOR_TEX, + VertexFormat.Mode.QUADS, + 2048, + false, + false, + builder.createCompositeState(false)) as RenderType + } + + val renderTypeDepth by lazy { + val builder = RenderType.CompositeState.builder() + + builder.setTextureState(TextureStateShard(WidgetAtlasHolder.LOCATION, false, false)) + builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionColorTexShader)) + builder.setTransparencyState(RenderStateShard.TransparencyStateShard("normal_blend", { + RenderSystem.enableBlend() + RenderSystem.defaultBlendFunc() + }, { + RenderSystem.disableBlend() + })) + + @Suppress("INACCESSIBLE_TYPE") + RenderType.create("otm_gui_element_depth", DefaultVertexFormat.POSITION_COLOR_TEX, VertexFormat.Mode.QUADS, 2048, @@ -122,10 +144,10 @@ class AtlasSkinElement( })) @Suppress("INACCESSIBLE_TYPE") - RenderType.create("gui_element_world", + RenderType.create("otm_gui_element_world", DefaultVertexFormat.POSITION_COLOR_TEX, VertexFormat.Mode.QUADS, - 2048, + 8192, false, false, builder.createCompositeState(false)) as RenderType diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/DynamicBufferSource.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/DynamicBufferSource.kt index a2b2b427e..c6da52cbd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/DynamicBufferSource.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/DynamicBufferSource.kt @@ -57,56 +57,81 @@ private fun equals(existing: ImmutableList?, types: ImmutableList? = null, - val immutableAfter: Boolean = false + immutableAfter: Boolean = false, + chained: Boolean = true ) { + val immutableAfter: Boolean + val chained: Boolean + + init { + if ( + type.name == "forge_text" || + type.name == "text_intensity" || + type.name == "forge_text_see_through" + ) { + after = ImmutableList.of(Sheets.signSheet()) + this.immutableAfter = true + this.chained = true + } else { + this.immutableAfter = immutableAfter + this.chained = chained + } + } + + val dependants = ArrayList(0) var priority = -1 var dirty: Boolean = false val builder by lazy { - BufferBuilder(type.bufferSize()) + BufferBuilder(type.bufferSize().coerceAtLeast(minimalBufferSize)) } } + @Suppress("BooleanLiteralArgument") private val bufferList = ArrayList().also { - var next = State(Sheets.solidBlockSheet(), null, true) + var next = State(Sheets.solidBlockSheet(), null, true, false) it.add(next) - next = State(Sheets.cutoutBlockSheet(), ImmutableList.of(next.type), true) + next = State(Sheets.cutoutBlockSheet(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(Sheets.bannerSheet(), ImmutableList.of(next.type), true) + next = State(Sheets.bannerSheet(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(Sheets.translucentCullBlockSheet(), ImmutableList.of(next.type), true) + next = State(Sheets.translucentCullBlockSheet(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(Sheets.shieldSheet(), ImmutableList.of(next.type), true) + next = State(Sheets.shieldSheet(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(Sheets.bedSheet(), ImmutableList.of(next.type), true) + next = State(Sheets.bedSheet(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(Sheets.shulkerBoxSheet(), ImmutableList.of(next.type), true) + next = State(Sheets.shulkerBoxSheet(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(Sheets.signSheet(), ImmutableList.of(next.type), true) + next = State(Sheets.signSheet(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(Sheets.chestSheet(), ImmutableList.of(next.type), true) + next = State(Sheets.chestSheet(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(RenderType.translucentNoCrumbling(), ImmutableList.of(next.type), true) + next = State(RenderType.translucentNoCrumbling(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(RenderType.armorGlint(), ImmutableList.of(next.type), true) + next = State(RenderType.armorGlint(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(RenderType.armorEntityGlint(), ImmutableList.of(next.type), true) + next = State(RenderType.armorEntityGlint(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(RenderType.glint(), ImmutableList.of(next.type), true) + next = State(RenderType.glint(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(RenderType.glintDirect(), ImmutableList.of(next.type), true) + next = State(RenderType.glintDirect(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(RenderType.glintTranslucent(), ImmutableList.of(next.type), true) + next = State(RenderType.glintTranslucent(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(RenderType.entityGlint(), ImmutableList.of(next.type), true) + next = State(RenderType.entityGlint(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(RenderType.entityGlintDirect(), ImmutableList.of(next.type), true) + next = State(RenderType.entityGlintDirect(), ImmutableList.of(next.type), true, false) it.add(next) - next = State(RenderType.waterMask(), ImmutableList.of(next.type), true) + next = State(RenderType.waterMask(), ImmutableList.of(next.type), true, false) it.add(next) + + it.add(State(AtlasSkinElement.renderTypeDepth, ImmutableList.of(RenderType.waterMask()), true)) + it.add(State(AtlasSkinElement.renderTypeNoDepth, ImmutableList.of(RenderType.waterMask()), true)) + it.add(State(AtlasSkinElement.renderTypeWorld, ImmutableList.of(Sheets.signSheet()), true)) } private fun determineHeight(input: State, seen: MutableSet) { @@ -125,6 +150,11 @@ class DynamicBufferSource : MultiBufferSource { } input.priority = input.priority.coerceAtLeast(input2.priority + 1) + + if (input.chained) { + input2.dependants.add(input) + } + break } } @@ -139,6 +169,7 @@ class DynamicBufferSource : MultiBufferSource { private fun sortBufferList() { for (state in bufferList) { state.priority = -1 + state.dependants.clear() } for (state in bufferList) { @@ -156,6 +187,10 @@ class DynamicBufferSource : MultiBufferSource { for (v in bufferList) it[v.type] = v } + init { + sortBufferList() + } + override fun getBuffer(renderType: RenderType): VertexConsumer { var getState = buffers[renderType] @@ -318,7 +353,48 @@ class DynamicBufferSource : MultiBufferSource { } } + fun endBatchChain(type: RenderType) { + val state = buffers[type] ?: return + + if (state.dirty) { + state.dirty = false + type.end(state.builder, 0, 0, 0) + } + + for (ustate in state.dependants) { + endBatchChain(ustate) + } + } + + private fun endBatchChain(state: State) { + if (state.dirty) { + state.dirty = false + state.type.end(state.builder, 0, 0, 0) + } + + for (ustate in state.dependants) { + endBatchChain(ustate) + } + } + companion object { val GUI = DynamicBufferSource() + val WORLD = DynamicBufferSource(8192) + + /** + * Called from LevelRenderer + */ + @JvmStatic + fun renderHook(type: RenderType) { + WORLD.endBatchChain(type) + } + + /** + * Called from LevelRenderer + */ + @JvmStatic + fun renderHook() { + WORLD.endBatch() + } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt index bc7961c43..d3e26ad2e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt @@ -13,6 +13,8 @@ import ru.dbotthepony.mc.otm.block.entity.BatteryBankBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.block.entity.matter.MatterCapacitorBankBlockEntity import ru.dbotthepony.mc.otm.client.render.AbstractSkinElement +import ru.dbotthepony.mc.otm.client.render.AtlasSkinElement +import ru.dbotthepony.mc.otm.client.render.DynamicBufferSource import ru.dbotthepony.mc.otm.client.render.SkinElement import ru.dbotthepony.mc.otm.client.render.is3DContext import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel @@ -35,9 +37,6 @@ abstract class BankRenderer(private val context: BlockEn is3DContext = true try { - RenderSystem.enableDepthTest() - RenderSystem.depthFunc(GL_LEQUAL) - stack.pushPose() val facing = blockEntity.blockState[RotatableMatteryBlock.FACING] @@ -55,7 +54,10 @@ abstract class BankRenderer(private val context: BlockEn val width = 9f val heightMax = 39.36f - texture.renderPartial(stack, + val buffer = DynamicBufferSource.WORLD.getBuffer(AtlasSkinElement.renderTypeWorld) + + texture.uploadOntoPartialColor(stack, + buffer, x = 25f - width / 2f, y = 30f, width = width, @@ -64,7 +66,8 @@ abstract class BankRenderer(private val context: BlockEn stack.mulPose(Vector3f.YP.rotation(PI.toFloat())) stack.translate(-50.0, 0.0, -101.0) - texture.renderPartial(stack, + texture.uploadOntoPartialColor(stack, + buffer, x = 25f - width / 2f, y = 30f, width = width, diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 6d2453c24..449e99d0e 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -47,3 +47,5 @@ protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_9 protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen m_97782_(Lnet/minecraft/world/item/ItemStack;IILjava/lang/String;)V # renderFloatingItem protected net.minecraft.client.resources.TextureAtlasHolder f_118884_ # textureAtlas + +public net.minecraft.client.renderer.RenderStateShard f_110133_ # name diff --git a/src/main/resources/coremods/code_injector.js b/src/main/resources/coremods/code_injector.js index 1f93f6a08..a775279e7 100644 --- a/src/main/resources/coremods/code_injector.js +++ b/src/main/resources/coremods/code_injector.js @@ -685,6 +685,58 @@ function initializeCoreMod() { } }, + 'LevelRenderer DynamicBufferSource callback': { + 'target': { + 'type': 'METHOD', + 'class': 'net.minecraft.client.renderer.LevelRenderer', + 'methodName': ASMAPI.mapMethod('m_109599_'), // renderLevel + 'methodDesc': '(Lcom/mojang/blaze3d/vertex/PoseStack;FJZLnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/GameRenderer;Lnet/minecraft/client/renderer/LightTexture;Lcom/mojang/math/Matrix4f;)V' + }, + + 'transformer': function(node) { + var endBatchName = ASMAPI.mapMethod('m_109912_') // net/minecraft/client/renderer/MultiBufferSource$BufferSource#endBatch + var endBatchDesc = '(Lnet/minecraft/client/renderer/RenderType;)V' + + var endBatchName2 = ASMAPI.mapMethod('m_109911_') // net/minecraft/client/renderer/MultiBufferSource$BufferSource#endBatch + var endBatchDesc2 = '()V' + + var ourLocalIndex = node.maxLocals++ + + for (i = 0; i < node.instructions.size(); i++) { + var instruction = node.instructions.get(i) + + if (instruction.getOpcode() == opcodesRemapped.invokevirtual && instruction.name == endBatchName && instruction.desc == endBatchDesc) { + node.instructions.insert(node.instructions.get(i - 1), new InsnNode(opcodesRemapped.dup_x1)) + node.instructions.insert(instruction, new MethodInsnNode( + opcodesRemapped.invokestatic, + 'ru/dbotthepony/mc/otm/client/render/DynamicBufferSource', + 'renderHook', + '(Lnet/minecraft/client/renderer/RenderType;)V', + false + )) + + i += 2 + continue + } + + if (instruction.getOpcode() == opcodesRemapped.invokevirtual && instruction.name == endBatchName2 && instruction.desc == endBatchDesc2) { + node.instructions.insert(instruction, new MethodInsnNode( + opcodesRemapped.invokestatic, + 'ru/dbotthepony/mc/otm/client/render/DynamicBufferSource', + 'renderHook', + '()V', + false + )) + + i += 2 + continue + } + } + + return node + } + }, + 'EnchantmentHelper#getSweepingDamageRatio patch for energy sword': { 'target': { 'type': 'METHOD',