From 55f30283c3af188e88095a27d2d9308ae245cf09 Mon Sep 17 00:00:00 2001 From: mewhenthe Date: Wed, 22 Apr 2026 22:30:23 +0200 Subject: [PATCH] Render screen texture on block --- .../client/NeoComputersFabricClient.java | 13 +++++ .../org/neoflock/neocomputers/NeoComputers.kt | 21 ++++++++ .../neocomputers/block/ScreenBlock.kt | 14 +++-- .../neocomputers/entity/ScreenEntity.kt | 38 ++++++++++++++ .../neoflock/neocomputers/gui/menu/Menus.kt | 3 +- .../neocomputers/gui/menu/ScreenMenu.kt | 12 ++++- .../neocomputers/gui/render/BufferRenderer.kt | 18 +++---- .../gui/render/ScreenEntityRenderer.kt | 51 +++++++++++++++++++ .../neocomputers/gui/screen/ScreenScreen.kt | 21 +++----- src/main/resources/fabric.mod.json | 3 ++ 10 files changed, 166 insertions(+), 28 deletions(-) create mode 100644 src/main/java/org/neoflock/neocomputers/platforms/fabric/client/NeoComputersFabricClient.java create mode 100644 src/main/kotlin/org/neoflock/neocomputers/gui/render/ScreenEntityRenderer.kt diff --git a/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/NeoComputersFabricClient.java b/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/NeoComputersFabricClient.java new file mode 100644 index 0000000..11406f9 --- /dev/null +++ b/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/NeoComputersFabricClient.java @@ -0,0 +1,13 @@ +package org.neoflock.neocomputers.platforms.fabric.client; + +import net.fabricmc.api.ClientModInitializer; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderers; +import org.neoflock.neocomputers.entity.BlockEntities; +import org.neoflock.neocomputers.gui.render.ScreenEntityRenderer; + +public class NeoComputersFabricClient implements ClientModInitializer { + @Override + public void onInitializeClient() { + BlockEntityRenderers.register(BlockEntities.INSTANCE.getSCREEN_ENTITY().get(), ScreenEntityRenderer::new); + } +} diff --git a/src/main/kotlin/org/neoflock/neocomputers/NeoComputers.kt b/src/main/kotlin/org/neoflock/neocomputers/NeoComputers.kt index ed77ec1..c5132b5 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/NeoComputers.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/NeoComputers.kt @@ -1,5 +1,7 @@ package org.neoflock.neocomputers +import com.mojang.blaze3d.vertex.DefaultVertexFormat +import com.mojang.blaze3d.vertex.VertexFormat import dev.architectury.event.events.client.ClientLifecycleEvent import dev.architectury.event.events.common.PlayerEvent import dev.architectury.event.events.common.TickEvent @@ -11,11 +13,15 @@ import org.neoflock.neocomputers.gui.menu.Menus import dev.architectury.utils.Env import dev.architectury.utils.EnvExecutor import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.RenderStateShard +import net.minecraft.client.renderer.RenderType import net.minecraft.server.level.ServerPlayer import org.neoflock.neocomputers.block.NodeBlockEntity import org.neoflock.neocomputers.block.NodeSynchronizer +import org.neoflock.neocomputers.gui.buffer.BufferRenderer import org.neoflock.neocomputers.gui.render.ScreenRenderer import org.neoflock.neocomputers.gui.widget.ComponentRoles +import org.neoflock.neocomputers.item.GPUCard import org.neoflock.neocomputers.item.Items import org.neoflock.neocomputers.item.Tabs import org.neoflock.neocomputers.network.Networking @@ -24,12 +30,19 @@ import org.neoflock.neocomputers.utils.FontProvider import org.neoflock.neocomputers.utils.GenericContainerScreen import org.slf4j.Logger import org.slf4j.LoggerFactory +import java.nio.Buffer object NeoComputers { const val MODID: String = "neocomputers" val LOGGER: Logger = LoggerFactory.getLogger("NeoComputers") var PLATFORM: ModPlatform? = null + val BlockEntityRenderType: RenderType = RenderType.create( + "nc_blockentities", + DefaultVertexFormat.POSITION_TEX, + VertexFormat.Mode.QUADS, + 0xc000, RenderType.CompositeState.builder().setShaderState(RenderStateShard.POSITION_TEX_SHADER).createCompositeState(false)) // TODO: figure out correct buffer size and composite state + fun entrypoint(platform: ModPlatform?) { PLATFORM = platform @@ -51,6 +64,14 @@ object NeoComputers { ClientLifecycleEvent.CLIENT_STARTED.register { FontProvider.load(ResourceLocation.fromNamespaceAndPath(MODID, "font/unscii.hex")) ScreenRenderer.genUnboundTex(); + + var buffer: MutableList = mutableListOf(BufferRenderer.GPUChar('h'), BufferRenderer.GPUChar('i')) + for (i in 0..398) { + buffer.add(BufferRenderer.GPUChar(' ')) + } + + var renderer: BufferRenderer = BufferRenderer(20, 20, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "screen/test"), buffer) + renderer.drawBuffer() } ClientLifecycleEvent.CLIENT_STOPPING.register { diff --git a/src/main/kotlin/org/neoflock/neocomputers/block/ScreenBlock.kt b/src/main/kotlin/org/neoflock/neocomputers/block/ScreenBlock.kt index c4557e0..66afd4e 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/block/ScreenBlock.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/block/ScreenBlock.kt @@ -1,8 +1,10 @@ package org.neoflock.neocomputers.block; +import dev.architectury.registry.menu.ExtendedMenuProvider import dev.architectury.registry.menu.MenuRegistry import net.minecraft.core.BlockPos import net.minecraft.core.Direction +import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.chat.Component import net.minecraft.server.level.ServerPlayer import net.minecraft.world.InteractionHand @@ -35,6 +37,7 @@ import kotlin.math.max class ScreenBlock() : NodeBlock() { companion object { val FACING: EnumProperty = EnumProperty.create("facing", Direction::class.java) + val ENERGY: Long = 5 } init { @@ -56,14 +59,19 @@ class ScreenBlock() : NodeBlock() { ): InteractionResult { if(!level.isClientSide) { val screenState = level.getBlockEntity(blockPos, BlockEntities.SCREEN_ENTITY.get()).get() - if(!screenState.node.consumeEnergy(5)) { + if(!screenState.node.consumeEnergy(ENERGY)) { player.sendSystemMessage(Component.literal("Not enough power.")) return InteractionResult.SUCCESS }; - MenuRegistry.openMenu(player as ServerPlayer, object : MenuProvider { + MenuRegistry.openExtendedMenu(player as ServerPlayer, object : ExtendedMenuProvider { override fun getDisplayName(): Component = Component.literal("SCREEEEEN!") override fun createMenu(i: Int, inventory: Inventory, player: Player): AbstractContainerMenu { - return Menus.SCREEN_MENU.get().create(i, inventory); +// return Menus.SCREEN_MENU.get().create(i, inventory); + return ScreenMenu(i, inventory, level.getBlockEntity(blockPos, BlockEntities.SCREEN_ENTITY.get()).get()) + } + + override fun saveExtraData(buf: FriendlyByteBuf?) { + buf!!.writeBlockPos(blockPos) } }) } diff --git a/src/main/kotlin/org/neoflock/neocomputers/entity/ScreenEntity.kt b/src/main/kotlin/org/neoflock/neocomputers/entity/ScreenEntity.kt index 00492e3..bed3d98 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/entity/ScreenEntity.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/entity/ScreenEntity.kt @@ -1,8 +1,12 @@ package org.neoflock.neocomputers.entity; import net.minecraft.core.BlockPos +import net.minecraft.resources.ResourceLocation +import net.minecraft.world.level.Level import net.minecraft.world.level.block.state.BlockState +import org.neoflock.neocomputers.NeoComputers import org.neoflock.neocomputers.block.NodeBlockEntity +import org.neoflock.neocomputers.gui.buffer.BufferRenderer import org.neoflock.neocomputers.network.Networking import org.neoflock.neocomputers.network.PowerRole @@ -10,4 +14,38 @@ class ScreenEntity(blockPos: BlockPos, blockState: BlockState) : NodeBlockEntity(BlockEntities.SCREEN_ENTITY.get(), blockPos, blockState) { override val node = Networking.Node() + var bound = "screen/unbound" + var render_on_block = false + + private var cleanrenderer: () -> Unit = { }; // TODO: THIS SUCKS, FIND A BETTER WAY + + override fun setChanged() { + super.setChanged() + if (bound == "screen/unbound") { + createscreenstuffs() + } + } + + override fun setRemoved() { + super.setRemoved() + cleanrenderer() + } + + private fun createscreenstuffs() { + bound = "screen/"+node.address.toString().replace("-", "_") + NeoComputers.LOGGER.info(bound) + if (level!!.isClientSide) { + var buffer: MutableList = mutableListOf() + for(char in node.address.toString()) { + buffer.add(BufferRenderer.GPUChar(char, 0xFFFF00, 0x0000FF)) + } + for (i in 0..((40*20)-36)) { + buffer.add(BufferRenderer.GPUChar(' ')) + } + + var renderer: BufferRenderer = BufferRenderer(40, 20, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, bound), buffer) + renderer.drawBuffer() + cleanrenderer = { renderer.clean() } + } + } } \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/gui/menu/Menus.kt b/src/main/kotlin/org/neoflock/neocomputers/gui/menu/Menus.kt index cd2cff9..ac67e9b 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/gui/menu/Menus.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/gui/menu/Menus.kt @@ -17,7 +17,8 @@ import org.neoflock.neocomputers.gui.screen.ScreenScreen object Menus { val MENUS: DeferredRegister> = DeferredRegister.create(NeoComputers.MODID, Registries.MENU) - val SCREEN_MENU: RegistrySupplier> = MENUS.register("screen_menu") { MenuType(::ScreenMenu, FeatureFlagSet.of()) } +// val SCREEN_MENU: RegistrySupplier> = MENUS.register("screen_menu") { MenuType(::ScreenMenu, FeatureFlagSet.of()) } + val SCREEN_MENU: RegistrySupplier> = MENUS.register("screen_menu") { MenuRegistry.ofExtended(::ScreenMenu) } val COMBUSTGEN_MENU: RegistrySupplier> = MENUS.register("combustgen_menu") { MenuType(::CombustionGeneratorMenu, FeatureFlagSet.of() ) } val CASE_MENU: RegistrySupplier> = MENUS.register("case_menu") { MenuType(::CaseMenu, FeatureFlagSet.of() )} diff --git a/src/main/kotlin/org/neoflock/neocomputers/gui/menu/ScreenMenu.kt b/src/main/kotlin/org/neoflock/neocomputers/gui/menu/ScreenMenu.kt index b0427d2..384d7da 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/gui/menu/ScreenMenu.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/gui/menu/ScreenMenu.kt @@ -1,5 +1,6 @@ package org.neoflock.neocomputers.gui.menu; +import net.minecraft.network.FriendlyByteBuf import net.minecraft.world.SimpleContainer import net.minecraft.world.entity.player.Inventory import org.neoflock.neocomputers.gui.menu.Menus; @@ -7,7 +8,16 @@ import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu import net.minecraft.world.inventory.MenuType import net.minecraft.world.item.ItemStack +import net.minecraft.world.level.block.entity.BlockEntity +import org.neoflock.neocomputers.entity.ScreenEntity import org.neoflock.neocomputers.utils.GenericContainerMenu -class ScreenMenu(i: Int, inv: Inventory) : GenericContainerMenu(Menus.SCREEN_MENU.get(), i, SimpleContainer(0)) { +class ScreenMenu : GenericContainerMenu { + var entity: ScreenEntity? = null + + constructor(i: Int, inv: Inventory, buf: FriendlyByteBuf) : this(i, inv, inv.player.level().getBlockEntity(buf.readBlockPos())) + constructor(i: Int, inv: Inventory, entity: BlockEntity?) : super(Menus.SCREEN_MENU.get(), i, SimpleContainer(0)) { + this.entity = entity as ScreenEntity + } + } \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/gui/render/BufferRenderer.kt b/src/main/kotlin/org/neoflock/neocomputers/gui/render/BufferRenderer.kt index 771fe59..b8bfcc3 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/gui/render/BufferRenderer.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/gui/render/BufferRenderer.kt @@ -20,14 +20,18 @@ class BufferRenderer(private var width: Int, private var height: Int, private va private var image: NativeImage = NativeImage(texwidth, texheight, true); // idk what the boolean is private var tex: DynamicTexture = DynamicTexture(image) + init { + Minecraft.getInstance().textureManager.register(this.id, tex) + } + fun dump(path: String) { image.writeToFile(File(path)) NeoComputers.LOGGER.info("DUMPED!!!") } - fun toRGBA(color: Int): Int { - return color.shl(8).or(0xFF) - } +// fun toRGBA(color: Int): Int { +// return color.shl(8).or(0xFF) +// } fun drawGlyph(x: Int, y: Int, c: Char, fg: Int) { var glyph: ArrayList = FontProvider.map[c]!! @@ -36,7 +40,7 @@ class BufferRenderer(private var width: Int, private var height: Int, private va for (i in 0.. 0) image.setPixelRGBA(x+i, y+j, toRGBA(fg)) + if (pixel > 0) image.setPixelRGBA(x+i, y+j, 0xFF000000.toInt()+fg) } } } @@ -59,15 +63,11 @@ class BufferRenderer(private var width: Int, private var height: Int, private va buffer[y*width+x] = c } - fun register() { - Minecraft.getInstance().textureManager.register(this.id, tex) // also idk how to unregister this - } - fun clean() { Minecraft.getInstance().textureManager.release(this.id) image.close() tex.close() } - data class GPUChar(val c: Char, val fg: Int =0xFFFFFF, val bg: Int = 0) + data class GPUChar(val c: Char, val fg: Int =0xFFFFFF, val bg: Int = 0) // all is bgr } \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/gui/render/ScreenEntityRenderer.kt b/src/main/kotlin/org/neoflock/neocomputers/gui/render/ScreenEntityRenderer.kt new file mode 100644 index 0000000..5d84b36 --- /dev/null +++ b/src/main/kotlin/org/neoflock/neocomputers/gui/render/ScreenEntityRenderer.kt @@ -0,0 +1,51 @@ +package org.neoflock.neocomputers.gui.render + +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.PoseStack +import com.mojang.math.Axis +import net.minecraft.client.renderer.MultiBufferSource +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider +import net.minecraft.core.Direction +import net.minecraft.resources.ResourceLocation +import net.minecraft.world.level.block.state.properties.EnumProperty +import org.neoflock.neocomputers.NeoComputers +import org.neoflock.neocomputers.NeoComputers.BlockEntityRenderType +import org.neoflock.neocomputers.block.ScreenBlock +import org.neoflock.neocomputers.entity.ScreenEntity + +class ScreenEntityRenderer(val context: BlockEntityRendererProvider.Context?) : BlockEntityRenderer { + + override fun render(entity: ScreenEntity, partialTick: Float, mat: PoseStack, bufferSource: MultiBufferSource, packedLight: Int, packedOverlay: Int) { + mat.pushPose() + handleDirection(entity, mat) + mat.translate(2 / 16f, 2 / 16f, 0.0001f) // am i epstein or am i just retarded +// mat.mulPose(Axis.YP.rotationDegrees(180f)) +// handleDirection(entity, mat) + + // RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderTexture(0, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, entity.bound)) + + val buffer = bufferSource.getBuffer(BlockEntityRenderType) // idk the correct rendertype for ts + buffer.addVertex(mat.last(), 3 / 4f, 0f, 0f).setUv(1f, 1f) + buffer.addVertex(mat.last(), 3 / 4f, 3 / 4f, 0f).setUv(1f, 0f) + buffer.addVertex(mat.last(), 0f, 3 / 4f, 0f).setUv(0f, 0f) + buffer.addVertex(mat.last(), 0f, 0f, 0f).setUv(0f, 1f) + mat.popPose() + } + + private fun handleDirection(ent: ScreenEntity, mat: PoseStack) { // TODO: separate up and down from cardinal directions + when (ent.blockState.getValue(ScreenBlock.FACING)) { + Direction.SOUTH -> { mat.translate(0F, 0F, 1F) } + Direction.EAST -> { mat.mulPose(Axis.YP.rotationDegrees(90F)); mat.translate(-1F, 0F, 1F) } + Direction.WEST -> { mat.mulPose(Axis.YN.rotationDegrees(90F)); } + Direction.NORTH -> {mat.mulPose(Axis.YP.rotationDegrees(180F)); mat.translate(-1F, 0F, 0F) } + Direction.UP -> { mat.mulPose(Axis.XN.rotationDegrees(90F)); mat.mulPose(Axis.ZP.rotationDegrees(180F)); mat.translate(-1.0001F, 0F, 1F) } // idek + Direction.DOWN -> { mat.mulPose(Axis.XP.rotationDegrees(90F)); mat.mulPose(Axis.ZN.rotationDegrees(180F)); mat.translate(-1F, -1F, 0F) } + else -> return + } + } +// private fun handleDirection(ent: ScreenEntity, mat: PoseStack?) { +// `when`(ent.getBlockState().get) +// } +} \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/gui/screen/ScreenScreen.kt b/src/main/kotlin/org/neoflock/neocomputers/gui/screen/ScreenScreen.kt index 4a328dd..3720c0b 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/gui/screen/ScreenScreen.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/gui/screen/ScreenScreen.kt @@ -10,6 +10,7 @@ import net.minecraft.network.chat.Component import net.minecraft.resources.ResourceLocation import net.minecraft.world.entity.player.Inventory import org.neoflock.neocomputers.NeoComputers +import org.neoflock.neocomputers.entity.ScreenEntity import org.neoflock.neocomputers.gui.buffer.BufferRenderer import org.neoflock.neocomputers.gui.menu.ScreenMenu import org.neoflock.neocomputers.gui.render.ScreenRenderer @@ -17,17 +18,9 @@ import org.neoflock.neocomputers.gui.render.ScreenRenderer class ScreenScreen : AbstractContainerScreen{ private var renderer: ScreenRenderer = ScreenRenderer(); - private var bufferRenderer: BufferRenderer? = null; constructor(abstractContainerMenu: ScreenMenu, inventory: Inventory, component: Component) : super(abstractContainerMenu, inventory, component) { - val buffer: ArrayList = arrayListOf(BufferRenderer.GPUChar('h'), BufferRenderer.GPUChar('a'), BufferRenderer.GPUChar('i')) - for (i in 0..<(400-3)) { - buffer.add(BufferRenderer.GPUChar(' ')) - } - bufferRenderer = BufferRenderer(20, 20, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "screen/test"), buffer) - bufferRenderer!!.register() - bufferRenderer!!.drawBuffer() - - renderer.bind(ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "screen/test")) + var ent: ScreenEntity = abstractContainerMenu.entity!!; + renderer.bind(ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, ent.bound)) } override fun renderBg(guiGraphics: GuiGraphics, f: Float, i: Int, j: Int) {} override fun render(graphics: GuiGraphics, mouseX: Int, mouseY: Int, something: Float) { @@ -35,8 +28,8 @@ class ScreenScreen : AbstractContainerScreen{ renderer.render(graphics, 50, 50, 100, 200) } - override fun onClose() { - super.onClose() - bufferRenderer!!.clean() - } +// override fun onClose() { +// super.onClose() +// renderer. +// } } \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index e9b07a5..4faae5d 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -21,6 +21,9 @@ ], "main": [ "org.neoflock.neocomputers.platforms.fabric.NeoComputersFabric" + ], + "client": [ + "org.neoflock.neocomputers.platforms.fabric.client.NeoComputersFabricClient" ] }, "mixins": [