From 3eb601e55402536d752720e9474ab4ecb27d2f5f Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 19 Sep 2021 15:49:31 +0100 Subject: [PATCH] Pass lightmap variables around various renderers - Add lightmap parameters to the text, computer and printout renderers. - Printouts are always rendered using the current lightmap. When interacting with the GUI, we use the fullbright lightmap coordinate. - Pocket computers render their border using the lightmap. Terminal and light do not use the lightmap at all. There's some funkiness going on here with render types - it appears the "correct" position_color_tex_lightmap render type is actually one used for text. Fixes #919. This bug does occur on 1.16 too, but given how complex the rendering changes are between 1.16 and 1.17 I do /not/ want to have to implement this twice. Sorry. --- .../client/gui/FixedWidthFontRenderer.java | 51 ++++++++----- .../computercraft/client/gui/GuiComputer.java | 9 +-- .../computercraft/client/gui/GuiPrintout.java | 9 +-- .../client/render/ComputerBorderRenderer.java | 47 ++++++------ .../client/render/ItemMapLikeRenderer.java | 7 +- .../client/render/ItemPocketRenderer.java | 8 +-- .../client/render/ItemPrintoutRenderer.java | 17 +++-- .../client/render/PrintoutRenderer.java | 60 +++++++++------- .../client/render/RenderTypes.java | 71 ++++++++----------- .../computercraft/data/BasicCustomLoader.java | 5 -- .../peripheral/generic/data/DataHelpers.java | 2 +- 11 files changed, 146 insertions(+), 140 deletions(-) diff --git a/src/main/java/dan200/computercraft/client/gui/FixedWidthFontRenderer.java b/src/main/java/dan200/computercraft/client/gui/FixedWidthFontRenderer.java index a97c4afa4..f23467159 100644 --- a/src/main/java/dan200/computercraft/client/gui/FixedWidthFontRenderer.java +++ b/src/main/java/dan200/computercraft/client/gui/FixedWidthFontRenderer.java @@ -5,6 +5,7 @@ */ package dan200.computercraft.client.gui; +import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.Matrix4f; import dan200.computercraft.client.FrameInfo; @@ -13,18 +14,32 @@ import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.Palette; -import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; import net.minecraft.resources.ResourceLocation; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import static dan200.computercraft.client.render.RenderTypes.FULL_BRIGHT_LIGHTMAP; + +/** + * Handles rendering fixed width text and computer terminals. + * + * This class has several modes of usage: + * + */ public final class FixedWidthFontRenderer { - private static final RenderType TYPE = RenderTypes.TERMINAL_WITH_DEPTH; - public static final ResourceLocation FONT = new ResourceLocation( "computercraft", "textures/gui/term_font.png" ); public static final int FONT_HEIGHT = 9; @@ -48,7 +63,7 @@ public static int getColour( char c, Colour def ) return 15 - Terminal.getColour( c, def ); } - private static void drawChar( Matrix4f transform, VertexConsumer buffer, float x, float y, int index, float r, float g, float b ) + private static void drawChar( Matrix4f transform, VertexConsumer buffer, float x, float y, int index, float r, float g, float b, int light ) { // Short circuit to avoid the common case - the texture should be blank here after all. if( index == '\0' || index == ' ' ) return; @@ -59,12 +74,12 @@ private static void drawChar( Matrix4f transform, VertexConsumer buffer, float x int xStart = 1 + column * (FONT_WIDTH + 2); int yStart = 1 + row * (FONT_HEIGHT + 2); - buffer.vertex( transform, x, y, 0f ).color( r, g, b, 1.0f ).uv( xStart / WIDTH, yStart / WIDTH ).endVertex(); - buffer.vertex( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).uv( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex(); - buffer.vertex( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).uv( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).endVertex(); - buffer.vertex( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).uv( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).endVertex(); - buffer.vertex( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).uv( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex(); - buffer.vertex( transform, x + FONT_WIDTH, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).uv( (xStart + FONT_WIDTH) / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex(); + buffer.vertex( transform, x, y, 0f ).color( r, g, b, 1.0f ).uv( xStart / WIDTH, yStart / WIDTH ).uv2( light ).endVertex(); + buffer.vertex( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).uv( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).uv2( light ).endVertex(); + buffer.vertex( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).uv( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).uv2( light ).endVertex(); + buffer.vertex( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).uv( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).uv2( light ).endVertex(); + buffer.vertex( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).uv( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).uv2( light ).endVertex(); + buffer.vertex( transform, x + FONT_WIDTH, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).uv( (xStart + FONT_WIDTH) / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).uv2( light ).endVertex(); } private static void drawQuad( Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, float r, float g, float b ) @@ -137,7 +152,7 @@ private static void drawBackground( public static void drawString( @Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y, @Nonnull TextBuffer text, @Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour, - @Nonnull Palette palette, boolean greyscale, float leftMarginSize, float rightMarginSize + @Nonnull Palette palette, boolean greyscale, float leftMarginSize, float rightMarginSize, int light ) { if( backgroundColour != null ) @@ -163,7 +178,7 @@ public static void drawString( // Draw char int index = text.charAt( i ); if( index > 255 ) index = '?'; - drawChar( transform, renderer, x + i * FONT_WIDTH, y, index, r, g, b ); + drawChar( transform, renderer, x + i * FONT_WIDTH, y, index, r, g, b, light ); } } @@ -196,7 +211,7 @@ public static void drawTerminalWithoutCursor( drawString( transform, buffer, x, y + FixedWidthFontRenderer.FONT_HEIGHT * i, terminal.getLine( i ), terminal.getTextColourLine( i ), terminal.getBackgroundColourLine( i ), - palette, greyscale, leftMarginSize, rightMarginSize + palette, greyscale, leftMarginSize, rightMarginSize, FULL_BRIGHT_LIGHTMAP ); } } @@ -227,7 +242,7 @@ public static void drawCursor( b = (float) colour[2]; } - drawChar( transform, buffer, x + cursorX * FONT_WIDTH, y + cursorY * FONT_HEIGHT, '_', r, g, b ); + drawChar( transform, buffer, x + cursorX * FONT_WIDTH, y + cursorY * FONT_HEIGHT, '_', r, g, b, FULL_BRIGHT_LIGHTMAP ); } } @@ -246,10 +261,10 @@ public static void drawTerminal( float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize ) { - MultiBufferSource.BufferSource renderer = Minecraft.getInstance().renderBuffers().bufferSource(); + MultiBufferSource.BufferSource renderer = MultiBufferSource.immediate( Tesselator.getInstance().getBuilder() ); VertexConsumer buffer = renderer.getBuffer( RenderTypes.TERMINAL_WITH_DEPTH ); drawTerminal( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize ); - renderer.endBatch( RenderTypes.TERMINAL_WITH_DEPTH ); + renderer.endBatch(); } public static void drawEmptyTerminal( @Nonnull Matrix4f transform, @Nonnull MultiBufferSource renderer, float x, float y, float width, float height ) @@ -260,7 +275,7 @@ public static void drawEmptyTerminal( @Nonnull Matrix4f transform, @Nonnull Mult public static void drawEmptyTerminal( @Nonnull Matrix4f transform, float x, float y, float width, float height ) { - MultiBufferSource.BufferSource renderer = Minecraft.getInstance().renderBuffers().bufferSource(); + MultiBufferSource.BufferSource renderer = MultiBufferSource.immediate( Tesselator.getInstance().getBuilder() ); drawEmptyTerminal( transform, renderer, x, y, width, height ); renderer.endBatch(); } diff --git a/src/main/java/dan200/computercraft/client/gui/GuiComputer.java b/src/main/java/dan200/computercraft/client/gui/GuiComputer.java index 30379860e..9046c2ffa 100644 --- a/src/main/java/dan200/computercraft/client/gui/GuiComputer.java +++ b/src/main/java/dan200/computercraft/client/gui/GuiComputer.java @@ -5,12 +5,12 @@ */ package dan200.computercraft.client.gui; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import dan200.computercraft.ComputerCraft; import dan200.computercraft.client.gui.widgets.ComputerSidebar; import dan200.computercraft.client.gui.widgets.WidgetTerminal; import dan200.computercraft.client.render.ComputerBorderRenderer; +import dan200.computercraft.client.render.RenderTypes; import dan200.computercraft.shared.computer.inventory.ContainerComputerBase; import dan200.computercraft.shared.computer.inventory.ContainerViewComputer; import net.minecraft.network.chat.Component; @@ -76,9 +76,10 @@ protected WidgetTerminal createTerminal() public void renderBg( @Nonnull PoseStack stack, float partialTicks, int mouseX, int mouseY ) { // Draw a border around the terminal - RenderSystem.setShaderColor( 1, 1, 1, 1 ); - RenderSystem.setShaderTexture( 0, ComputerBorderRenderer.getTexture( family ) ); - ComputerBorderRenderer.render( terminal.x, terminal.y, getBlitOffset(), terminal.getWidth(), terminal.getHeight() ); + ComputerBorderRenderer.render( + ComputerBorderRenderer.getTexture( family ), terminal.x, terminal.y, getBlitOffset(), + RenderTypes.FULL_BRIGHT_LIGHTMAP, terminal.getWidth(), terminal.getHeight() + ); ComputerSidebar.renderBackground( stack, leftPos, topPos + sidebarYOffset ); } } diff --git a/src/main/java/dan200/computercraft/client/gui/GuiPrintout.java b/src/main/java/dan200/computercraft/client/gui/GuiPrintout.java index 918fc2552..546951d35 100644 --- a/src/main/java/dan200/computercraft/client/gui/GuiPrintout.java +++ b/src/main/java/dan200/computercraft/client/gui/GuiPrintout.java @@ -7,11 +7,11 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.math.Matrix4f; import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.shared.common.ContainerHeldItem; import dan200.computercraft.shared.media.items.ItemPrintout; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.network.chat.Component; @@ -21,6 +21,7 @@ import javax.annotation.Nonnull; import static dan200.computercraft.client.render.PrintoutRenderer.*; +import static dan200.computercraft.client.render.RenderTypes.FULL_BRIGHT_LIGHTMAP; public class GuiPrintout extends AbstractContainerScreen { @@ -97,10 +98,10 @@ protected void renderBg( @Nonnull PoseStack transform, float partialTicks, int m RenderSystem.setShaderColor( 1.0f, 1.0f, 1.0f, 1.0f ); RenderSystem.enableDepthTest(); - MultiBufferSource.BufferSource renderer = Minecraft.getInstance().renderBuffers().bufferSource(); + MultiBufferSource.BufferSource renderer = MultiBufferSource.immediate( Tesselator.getInstance().getBuilder() ); Matrix4f matrix = transform.last().pose(); - drawBorder( matrix, renderer, leftPos, topPos, getBlitOffset(), page, pages, book ); - drawText( matrix, renderer, leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * page, text, colours ); + drawBorder( matrix, renderer, leftPos, topPos, getBlitOffset(), page, pages, book, FULL_BRIGHT_LIGHTMAP ); + drawText( matrix, renderer, leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * page, FULL_BRIGHT_LIGHTMAP, text, colours ); renderer.endBatch(); } diff --git a/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java b/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java index 6df58f6fe..a20699087 100644 --- a/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java @@ -5,12 +5,13 @@ */ package dan200.computercraft.client.render; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.*; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.math.Matrix4f; import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.computer.core.ComputerFamily; -import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; import net.minecraft.resources.ResourceLocation; import javax.annotation.Nonnull; @@ -54,14 +55,16 @@ public class ComputerBorderRenderer private final Matrix4f transform; private final VertexConsumer builder; + private final int light; private final int z; private final float r, g, b; - public ComputerBorderRenderer( Matrix4f transform, VertexConsumer builder, int z, float r, float g, float b ) + public ComputerBorderRenderer( Matrix4f transform, VertexConsumer builder, int z, int light, float r, float g, float b ) { this.transform = transform; this.builder = builder; this.z = z; + this.light = light; this.r = r; this.g = g; this.b = b; @@ -83,32 +86,22 @@ public static ResourceLocation getTexture( @Nonnull ComputerFamily family ) } } - public static void render( int x, int y, int z, int width, int height ) + public static RenderType getRenderType( ResourceLocation location ) { - RenderSystem.setShader( GameRenderer::getPositionColorTexShader ); - Tesselator tessellator = Tesselator.getInstance(); - BufferBuilder buffer = tessellator.getBuilder(); - buffer.begin( VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX ); - - render( IDENTITY, buffer, x, y, z, width, height ); - - // TODO: RenderSystem.enableAlphaTest(); - tessellator.end(); + // See note in RenderTypes about why we use text rather than anything intuitive. + return RenderType.text( location ); } - public static void render( Matrix4f transform, VertexConsumer buffer, int x, int y, int z, int width, int height ) + public static void render( ResourceLocation location, int x, int y, int z, int light, int width, int height ) { - render( transform, buffer, x, y, z, width, height, 1, 1, 1 ); + MultiBufferSource.BufferSource source = MultiBufferSource.immediate( Tesselator.getInstance().getBuilder() ); + render( IDENTITY, source.getBuffer( getRenderType( location ) ), x, y, z, light, width, height, false, 1, 1, 1 ); + source.endBatch(); } - public static void render( Matrix4f transform, VertexConsumer buffer, int x, int y, int z, int width, int height, float r, float g, float b ) + public static void render( Matrix4f transform, VertexConsumer buffer, int x, int y, int z, int light, int width, int height, boolean withLight, float r, float g, float b ) { - render( transform, buffer, x, y, z, width, height, false, r, g, b ); - } - - public static void render( Matrix4f transform, VertexConsumer buffer, int x, int y, int z, int width, int height, boolean withLight, float r, float g, float b ) - { - new ComputerBorderRenderer( transform, buffer, z, r, g, b ).doRender( x, y, width, height, withLight ); + new ComputerBorderRenderer( transform, buffer, z, light, r, g, b ).doRender( x, y, width, height, withLight ); } public void doRender( int x, int y, int width, int height, boolean withLight ) @@ -158,9 +151,9 @@ private void renderTexture( int x, int y, int u, int v, int width, int height ) private void renderTexture( int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight ) { - builder.vertex( transform, x, y + height, z ).color( r, g, b, 1.0f ).uv( u * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).endVertex(); - builder.vertex( transform, x + width, y + height, z ).color( r, g, b, 1.0f ).uv( (u + textureWidth) * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).endVertex(); - builder.vertex( transform, x + width, y, z ).color( r, g, b, 1.0f ).uv( (u + textureWidth) * TEX_SCALE, v * TEX_SCALE ).endVertex(); - builder.vertex( transform, x, y, z ).color( r, g, b, 1.0f ).uv( u * TEX_SCALE, v * TEX_SCALE ).endVertex(); + builder.vertex( transform, x, y + height, z ).color( r, g, b, 1.0f ).uv( u * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).uv2( light ).endVertex(); + builder.vertex( transform, x + width, y + height, z ).color( r, g, b, 1.0f ).uv( (u + textureWidth) * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).uv2( light ).endVertex(); + builder.vertex( transform, x + width, y, z ).color( r, g, b, 1.0f ).uv( (u + textureWidth) * TEX_SCALE, v * TEX_SCALE ).uv2( light ).endVertex(); + builder.vertex( transform, x, y, z ).color( r, g, b, 1.0f ).uv( u * TEX_SCALE, v * TEX_SCALE ).uv2( light ).endVertex(); } } diff --git a/src/main/java/dan200/computercraft/client/render/ItemMapLikeRenderer.java b/src/main/java/dan200/computercraft/client/render/ItemMapLikeRenderer.java index b418b1df9..5f3346b5f 100644 --- a/src/main/java/dan200/computercraft/client/render/ItemMapLikeRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ItemMapLikeRenderer.java @@ -26,9 +26,10 @@ public abstract class ItemMapLikeRenderer * @param transform The matrix transformation stack * @param render The buffer to render to * @param stack The stack to render + * @param light The packed lightmap coordinates. * @see ItemInHandRenderer#renderItem(LivingEntity, ItemStack, ItemTransforms.TransformType, boolean, PoseStack, MultiBufferSource, int) */ - protected abstract void renderItem( PoseStack transform, MultiBufferSource render, ItemStack stack ); + protected abstract void renderItem( PoseStack transform, MultiBufferSource render, ItemStack stack, int light ); protected void renderItemFirstPerson( PoseStack transform, MultiBufferSource render, int lightTexture, InteractionHand hand, float pitch, float equipProgress, float swingProgress, ItemStack stack ) { @@ -90,7 +91,7 @@ private void renderItemFirstPersonSide( PoseStack transform, MultiBufferSource r transform.mulPose( Vector3f.XP.rotationDegrees( f2 * -45f ) ); transform.mulPose( Vector3f.YP.rotationDegrees( offset * f2 * -30f ) ); - renderItem( transform, render, stack ); + renderItem( transform, render, stack, combinedLight ); transform.popPose(); } @@ -135,6 +136,6 @@ private void renderItemFirstPersonCenter( PoseStack transform, MultiBufferSource transform.mulPose( Vector3f.XP.rotationDegrees( rX * 20.0F ) ); transform.scale( 2.0F, 2.0F, 2.0F ); - renderItem( transform, render, stack ); + renderItem( transform, render, stack, combinedLight ); } } diff --git a/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java b/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java index 63b7b7ee6..4a89c2d05 100644 --- a/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java @@ -54,7 +54,7 @@ public static void onRenderInHand( RenderHandEvent event ) } @Override - protected void renderItem( PoseStack transform, MultiBufferSource renderer, ItemStack stack ) + protected void renderItem( PoseStack transform, MultiBufferSource renderer, ItemStack stack, int light ) { ClientComputer computer = ItemPocketComputer.createClientComputer( stack ); Terminal terminal = computer == null ? null : computer.getTerminal(); @@ -91,7 +91,7 @@ protected void renderItem( PoseStack transform, MultiBufferSource renderer, Item int frameColour = item.getColour( stack ); Matrix4f matrix = transform.last().pose(); - renderFrame( matrix, renderer, family, frameColour, width, height ); + renderFrame( matrix, renderer, family, frameColour, light, width, height ); // Render the light int lightColour = ItemPocketComputer.getLightState( stack ); @@ -114,7 +114,7 @@ protected void renderItem( PoseStack transform, MultiBufferSource renderer, Item transform.popPose(); } - private static void renderFrame( Matrix4f transform, MultiBufferSource render, ComputerFamily family, int colour, int width, int height ) + private static void renderFrame( Matrix4f transform, MultiBufferSource render, ComputerFamily family, int colour, int light, int width, int height ) { ResourceLocation texture = colour != -1 ? ComputerBorderRenderer.BACKGROUND_COLOUR : ComputerBorderRenderer.getTexture( family ); @@ -122,7 +122,7 @@ private static void renderFrame( Matrix4f transform, MultiBufferSource render, C float g = ((colour >>> 8) & 0xFF) / 255.0f; float b = (colour & 0xFF) / 255.0f; - ComputerBorderRenderer.render( transform, render.getBuffer( RenderTypes.positionColorTex( texture ) ), 0, 0, 0, width, height, true, r, g, b ); + ComputerBorderRenderer.render( transform, render.getBuffer( ComputerBorderRenderer.getRenderType( texture ) ), 0, 0, 0, light, width, height, true, r, g, b ); } private static void renderLight( Matrix4f transform, MultiBufferSource render, int colour, int width, int height ) diff --git a/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java b/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java index 7e3f8cb7a..f3f17d3f5 100644 --- a/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java @@ -11,6 +11,7 @@ import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.media.items.ItemPrintout; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.item.ItemStack; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.RenderHandEvent; @@ -50,13 +51,13 @@ public static void onRenderInHand( RenderHandEvent event ) } @Override - protected void renderItem( PoseStack transform, MultiBufferSource render, ItemStack stack ) + protected void renderItem( PoseStack transform, MultiBufferSource render, ItemStack stack, int light ) { transform.mulPose( Vector3f.XP.rotationDegrees( 180f ) ); transform.scale( 0.42f, 0.42f, -0.42f ); transform.translate( -0.5f, -0.48f, 0.0f ); - drawPrintout( transform, render, stack ); + drawPrintout( transform, render, stack, light ); } @SubscribeEvent @@ -74,10 +75,11 @@ public static void onRenderInFrame( RenderItemInFrameEvent event ) transform.scale( 0.95f, 0.95f, -0.95f ); transform.translate( -0.5f, -0.5f, 0.0f ); - drawPrintout( transform, event.getBuffers(), stack ); + int light = event.getEntityItemFrame().getType() == EntityType.GLOW_ITEM_FRAME ? 0xf000d2 : event.getLight(); // See getLightVal. + drawPrintout( transform, event.getBuffers(), stack, light ); } - private static void drawPrintout( PoseStack transform, MultiBufferSource render, ItemStack stack ) + private static void drawPrintout( PoseStack transform, MultiBufferSource render, ItemStack stack, int light ) { int pages = ItemPrintout.getPageCount( stack ); boolean book = ((ItemPrintout) stack.getItem()).getType() == ItemPrintout.Type.BOOK; @@ -105,9 +107,10 @@ private static void drawPrintout( PoseStack transform, MultiBufferSource render, transform.translate( (max - width) / 2.0, (max - height) / 2.0, 0.0 ); Matrix4f matrix = transform.last().pose(); - drawBorder( matrix, render, 0, 0, -0.01f, 0, pages, book ); - drawText( matrix, render, - X_TEXT_MARGIN, Y_TEXT_MARGIN, 0, ItemPrintout.getText( stack ), ItemPrintout.getColours( stack ) + drawBorder( matrix, render, 0, 0, -0.01f, 0, pages, book, light ); + drawText( + matrix, render, X_TEXT_MARGIN, Y_TEXT_MARGIN, 0, light, + ItemPrintout.getText( stack ), ItemPrintout.getColours( stack ) ); } } diff --git a/src/main/java/dan200/computercraft/client/render/PrintoutRenderer.java b/src/main/java/dan200/computercraft/client/render/PrintoutRenderer.java index a8868cc84..983a42774 100644 --- a/src/main/java/dan200/computercraft/client/render/PrintoutRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/PrintoutRenderer.java @@ -54,32 +54,34 @@ public final class PrintoutRenderer private PrintoutRenderer() {} - public static void drawText( Matrix4f transform, MultiBufferSource renderer, int x, int y, int start, TextBuffer[] text, TextBuffer[] colours ) + public static void drawText( Matrix4f transform, MultiBufferSource renderer, int x, int y, int start, int light, TextBuffer[] text, TextBuffer[] colours ) { - VertexConsumer buffer = renderer.getBuffer( RenderTypes.TERMINAL_WITH_DEPTH ); + VertexConsumer buffer = renderer.getBuffer( RenderTypes.PRINTOUT_TEXT ); for( int line = 0; line < LINES_PER_PAGE && line < text.length; line++ ) { FixedWidthFontRenderer.drawString( transform, buffer, x, y + line * FONT_HEIGHT, text[start + line], colours[start + line], null, Palette.DEFAULT, - false, 0, 0 + false, 0, 0, + light ); } } - public static void drawText( Matrix4f transform, MultiBufferSource renderer, int x, int y, int start, String[] text, String[] colours ) + public static void drawText( Matrix4f transform, MultiBufferSource renderer, int x, int y, int start, int light, String[] text, String[] colours ) { - VertexConsumer buffer = renderer.getBuffer( RenderTypes.TERMINAL_WITH_DEPTH ); + VertexConsumer buffer = renderer.getBuffer( RenderTypes.PRINTOUT_TEXT ); for( int line = 0; line < LINES_PER_PAGE && line < text.length; line++ ) { FixedWidthFontRenderer.drawString( transform, buffer, x, y + line * FONT_HEIGHT, new TextBuffer( text[start + line] ), new TextBuffer( colours[start + line] ), - null, Palette.DEFAULT, false, 0, 0 + null, Palette.DEFAULT, false, 0, 0, + light ); } } - public static void drawBorder( Matrix4f transform, MultiBufferSource renderer, float x, float y, float z, int page, int pages, boolean isBook ) + public static void drawBorder( Matrix4f transform, MultiBufferSource renderer, float x, float y, float z, int page, int pages, boolean isBook, int light ) { int leftPages = page; int rightPages = pages - page - 1; @@ -94,64 +96,70 @@ public static void drawBorder( Matrix4f transform, MultiBufferSource renderer, f float right = x + X_SIZE + offset - 4; // Left and right border - drawTexture( transform, buffer, left - 4, y - 8, z - 0.02f, COVER_X, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2 ); - drawTexture( transform, buffer, right, y - 8, z - 0.02f, COVER_X + COVER_SIZE, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2 ); + drawTexture( transform, buffer, left - 4, y - 8, z - 0.02f, COVER_X, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2, light ); + drawTexture( transform, buffer, right, y - 8, z - 0.02f, COVER_X + COVER_SIZE, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2, light ); // Draw centre panel (just stretched texture, sorry). drawTexture( transform, buffer, x - offset, y, z - 0.02f, X_SIZE + offset * 2, Y_SIZE, - COVER_X + COVER_SIZE / 2.0f, COVER_SIZE, COVER_SIZE, Y_SIZE + COVER_X + COVER_SIZE / 2.0f, COVER_SIZE, COVER_SIZE, Y_SIZE, + light ); float borderX = left; while( borderX < right ) { double thisWidth = Math.min( right - borderX, X_SIZE ); - drawTexture( transform, buffer, borderX, y - 8, z - 0.02f, 0, COVER_Y, (float) thisWidth, COVER_SIZE ); - drawTexture( transform, buffer, borderX, y + Y_SIZE - 4, z - 0.02f, 0, COVER_Y + COVER_SIZE, (float) thisWidth, COVER_SIZE ); + drawTexture( transform, buffer, borderX, y - 8, z - 0.02f, 0, COVER_Y, (float) thisWidth, COVER_SIZE, light ); + drawTexture( transform, buffer, borderX, y + Y_SIZE - 4, z - 0.02f, 0, COVER_Y + COVER_SIZE, (float) thisWidth, COVER_SIZE, light ); borderX += thisWidth; } } // Left half - drawTexture( transform, buffer, x, y, z, X_FOLD_SIZE * 2, 0, X_SIZE / 2.0f, Y_SIZE ); + drawTexture( transform, buffer, x, y, z, X_FOLD_SIZE * 2, 0, X_SIZE / 2.0f, Y_SIZE, light ); for( int n = 0; n <= leftPages; n++ ) { drawTexture( transform, buffer, x - offsetAt( n ), y, z - 1e-3f * n, // Use the left "bold" fold for the outermost page n == leftPages ? 0 : X_FOLD_SIZE, 0, - X_FOLD_SIZE, Y_SIZE + X_FOLD_SIZE, Y_SIZE, light ); } // Right half - drawTexture( transform, buffer, x + X_SIZE / 2.0f, y, z, X_FOLD_SIZE * 2 + X_SIZE / 2.0f, 0, X_SIZE / 2.0f, Y_SIZE ); + drawTexture( transform, buffer, x + X_SIZE / 2.0f, y, z, X_FOLD_SIZE * 2 + X_SIZE / 2.0f, 0, X_SIZE / 2.0f, Y_SIZE, light ); for( int n = 0; n <= rightPages; n++ ) { drawTexture( transform, buffer, x + (X_SIZE - X_FOLD_SIZE) + offsetAt( n ), y, z - 1e-3f * n, // Two folds, then the main page. Use the right "bold" fold for the outermost page. X_FOLD_SIZE * 2 + X_SIZE + (n == rightPages ? X_FOLD_SIZE : 0), 0, - X_FOLD_SIZE, Y_SIZE + X_FOLD_SIZE, Y_SIZE, light ); } } - private static void drawTexture( Matrix4f matrix, VertexConsumer buffer, float x, float y, float z, float u, float v, float width, float height ) + private static void drawTexture( Matrix4f matrix, VertexConsumer buffer, float x, float y, float z, float u, float v, float width, float height, int light ) { - buffer.vertex( matrix, x, y + height, z ).uv( u / BG_SIZE, (v + height) / BG_SIZE ).endVertex(); - buffer.vertex( matrix, x + width, y + height, z ).uv( (u + width) / BG_SIZE, (v + height) / BG_SIZE ).endVertex(); - buffer.vertex( matrix, x + width, y, z ).uv( (u + width) / BG_SIZE, v / BG_SIZE ).endVertex(); - buffer.vertex( matrix, x, y, z ).uv( u / BG_SIZE, v / BG_SIZE ).endVertex(); + vertex( buffer, matrix, x, y + height, z, u / BG_SIZE, (v + height) / BG_SIZE, light ); + vertex( buffer, matrix, x + width, y + height, z, (u + width) / BG_SIZE, (v + height) / BG_SIZE, light ); + vertex( buffer, matrix, x + width, y, z, (u + width) / BG_SIZE, v / BG_SIZE, light ); + vertex( buffer, matrix, x, y, z, u / BG_SIZE, v / BG_SIZE, light ); } - private static void drawTexture( Matrix4f matrix, VertexConsumer buffer, float x, float y, float z, float width, float height, float u, float v, float tWidth, float tHeight ) + private static void drawTexture( Matrix4f matrix, VertexConsumer buffer, float x, float y, float z, float width, float height, float u, float v, float tWidth, float tHeight, int light ) { - buffer.vertex( matrix, x, y + height, z ).uv( u / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex(); - buffer.vertex( matrix, x + width, y + height, z ).uv( (u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex(); - buffer.vertex( matrix, x + width, y, z ).uv( (u + tWidth) / BG_SIZE, v / BG_SIZE ).endVertex(); - buffer.vertex( matrix, x, y, z ).uv( u / BG_SIZE, v / BG_SIZE ).endVertex(); + vertex( buffer, matrix, x, y + height, z, u / BG_SIZE, (v + tHeight) / BG_SIZE, light ); + vertex( buffer, matrix, x + width, y + height, z, (u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE, light ); + vertex( buffer, matrix, x + width, y, z, (u + tWidth) / BG_SIZE, v / BG_SIZE, light ); + vertex( buffer, matrix, x, y, z, u / BG_SIZE, v / BG_SIZE, light ); + } + + private static void vertex( VertexConsumer buffer, Matrix4f matrix, float x, float y, float z, float u, float v, int light ) + { + buffer.vertex( matrix, x, y, z ).color( 255, 255, 255, 255 ).uv( u, v ).uv2( light ).endVertex(); } public static float offsetAt( int page ) diff --git a/src/main/java/dan200/computercraft/client/render/RenderTypes.java b/src/main/java/dan200/computercraft/client/render/RenderTypes.java index 694791d6a..3b430e933 100644 --- a/src/main/java/dan200/computercraft/client/render/RenderTypes.java +++ b/src/main/java/dan200/computercraft/client/render/RenderTypes.java @@ -9,8 +9,6 @@ import com.mojang.blaze3d.vertex.VertexFormat; import dan200.computercraft.ComputerCraft; import dan200.computercraft.client.gui.FixedWidthFontRenderer; -import net.minecraft.Util; -import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.RenderStateShard; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.ShaderInstance; @@ -22,11 +20,12 @@ import javax.annotation.Nonnull; import java.io.IOException; -import java.util.function.Function; @Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD ) public class RenderTypes { + public static final int FULL_BRIGHT_LIGHTMAP = (0xF << 4) | (0xF << 20); + private static MonitorTextureBufferShader monitorTboShader; private static ShaderInstance terminalShader; @@ -34,16 +33,18 @@ public class RenderTypes public static final RenderType TERMINAL_BLOCKER = Types.TERMINAL_BLOCKER; public static final RenderType TERMINAL_WITH_DEPTH = Types.TERMINAL_WITH_DEPTH; public static final RenderType MONITOR_TBO = Types.MONITOR_TBO; + public static final RenderType PRINTOUT_TEXT = Types.PRINTOUT_TEXT; - public static final RenderType PRINTOUT_BACKGROUND = Types.PRINTOUT_BACKGROUND; + /** + * This looks wrong (it should be POSITION_COLOR_TEX_LIGHTMAP surely!) but the fragment/vertex shader for that + * appear to entirely ignore the lightmap. + * + * Note that vanilla maps do the same, so this isn't unreasonable. + */ + public static final RenderType PRINTOUT_BACKGROUND = RenderType.text( new ResourceLocation( "computercraft", "textures/gui/printout.png" ) ); public static final RenderType POSITION_COLOR = Types.POSITION_COLOR; - public static RenderType positionColorTex( ResourceLocation location ) - { - return Types.POSITION_COLOR_TEX.apply( location ); - } - @Nonnull static MonitorTextureBufferShader getMonitorTextureBufferShader() { @@ -88,6 +89,7 @@ private static final class Types extends RenderStateShard ); private static final VertexFormat TERM_FORMAT = DefaultVertexFormat.POSITION_COLOR_TEX; private static final VertexFormat.Mode TERM_MODE = VertexFormat.Mode.TRIANGLES; + private static final ShaderStateShard TERM_SHADER = new ShaderStateShard( RenderTypes::getTerminalShader ); static final RenderType MONITOR_TBO = RenderType.create( "monitor_tbo", DefaultVertexFormat.POSITION_TEX, VertexFormat.Mode.TRIANGLE_STRIP, 128, @@ -100,32 +102,44 @@ private static final class Types extends RenderStateShard ); static final RenderType TERMINAL_WITHOUT_DEPTH = RenderType.create( - "monitor_basic", TERM_FORMAT, TERM_MODE, 1024, + "terminal_without_depth", TERM_FORMAT, TERM_MODE, 1024, false, false, // useDelegate, needsSorting RenderType.CompositeState.builder() .setTextureState( TERM_FONT_TEXTURE ) - .setShaderState( new ShaderStateShard( RenderTypes::getTerminalShader ) ) + .setShaderState( TERM_SHADER ) .setWriteMaskState( COLOR_WRITE ) .createCompositeState( false ) ); static final RenderType TERMINAL_BLOCKER = RenderType.create( - "monitor_blocker", TERM_FORMAT, TERM_MODE, 256, + "terminal_blocker", TERM_FORMAT, TERM_MODE, 256, false, false, // useDelegate, needsSorting RenderType.CompositeState.builder() .setTextureState( TERM_FONT_TEXTURE ) - .setShaderState( new ShaderStateShard( RenderTypes::getTerminalShader ) ) + .setShaderState( TERM_SHADER ) .setWriteMaskState( DEPTH_WRITE ) - .setLightmapState( NO_LIGHTMAP ) .createCompositeState( false ) ); static final RenderType TERMINAL_WITH_DEPTH = RenderType.create( - "basic_terminal", TERM_FORMAT, TERM_MODE, 1024, + "terminal_with_depth", TERM_FORMAT, TERM_MODE, 1024, false, false, // useDelegate, needsSorting RenderType.CompositeState.builder() .setTextureState( TERM_FONT_TEXTURE ) - .setShaderState( POSITION_COLOR_TEX_SHADER ) + .setShaderState( TERM_SHADER ) + .createCompositeState( false ) + ); + + /** + * A variant of {@link #TERMINAL_WITH_DEPTH} which uses the lightmap rather than rendering fullbright. + */ + static final RenderType PRINTOUT_TEXT = RenderType.create( + "printout_text", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, TERM_MODE, 1024, + false, false, // useDelegate, needsSorting + RenderType.CompositeState.builder() + .setTextureState( TERM_FONT_TEXTURE ) + .setShaderState( RenderStateShard.RENDERTYPE_TEXT_SHADER ) + .setLightmapState( RenderStateShard.LIGHTMAP ) .createCompositeState( false ) ); @@ -137,31 +151,6 @@ private static final class Types extends RenderStateShard .createCompositeState( false ) ); - static final Function POSITION_COLOR_TEX = Util.memoize( location -> - { - return RenderType.create( - "position_color_tex", DefaultVertexFormat.POSITION_COLOR_TEX, VertexFormat.Mode.QUADS, 1024, - false, false, // useDelegate, needsSorting - RenderType.CompositeState.builder() - .setTextureState( new RenderStateShard.TextureStateShard( location, false, false ) )// blur, minimap - .setShaderState( POSITION_COLOR_TEX_SHADER ) - .createCompositeState( false ) - ); - } ); - - static final RenderType PRINTOUT_BACKGROUND = RenderType.create( - "printout_background", DefaultVertexFormat.POSITION_TEX, VertexFormat.Mode.QUADS, 1024, - false, false, // useDelegate, needsSorting - RenderType.CompositeState.builder() - .setTextureState( new RenderStateShard.TextureStateShard( - new ResourceLocation( "computercraft", "textures/gui/printout.png" ), - false, false // blur, minimap - ) ) - .setShaderState( new RenderStateShard.ShaderStateShard( GameRenderer::getPositionTexShader ) ) - .setLightmapState( NO_LIGHTMAP ) - .createCompositeState( false ) - ); - private Types( String name, Runnable setup, Runnable destroy ) { super( name, setup, destroy ); diff --git a/src/main/java/dan200/computercraft/data/BasicCustomLoader.java b/src/main/java/dan200/computercraft/data/BasicCustomLoader.java index ecfb4ff74..e11f1b8cf 100644 --- a/src/main/java/dan200/computercraft/data/BasicCustomLoader.java +++ b/src/main/java/dan200/computercraft/data/BasicCustomLoader.java @@ -24,11 +24,6 @@ protected BasicCustomLoader( ResourceLocation loaderId, T parent, ExistingFileHe this.extra = extra; } - public static > BiFunction> makeFactory( ResourceLocation id ) - { - return makeFactory( id, j -> { } ); - } - public static > BiFunction> makeFactory( ResourceLocation id, Consumer extra ) { return ( parent, x ) -> new BasicCustomLoader<>( id, parent, x, extra ); diff --git a/src/main/java/dan200/computercraft/shared/peripheral/generic/data/DataHelpers.java b/src/main/java/dan200/computercraft/shared/peripheral/generic/data/DataHelpers.java index f97954cd4..1cac3f384 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/generic/data/DataHelpers.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/generic/data/DataHelpers.java @@ -17,7 +17,7 @@ public final class DataHelpers { private DataHelpers() - { } + {} @Nonnull public static Map getTags( @Nonnull Collection tags )