diff --git a/src/main/java/dan200/computercraft/client/gui/FixedWidthFontRenderer.java b/src/main/java/dan200/computercraft/client/gui/FixedWidthFontRenderer.java index 5bcb1c935..5e82c7091 100644 --- a/src/main/java/dan200/computercraft/client/gui/FixedWidthFontRenderer.java +++ b/src/main/java/dan200/computercraft/client/gui/FixedWidthFontRenderer.java @@ -5,8 +5,10 @@ */ package dan200.computercraft.client.gui; +import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Matrix3f; import com.mojang.math.Matrix4f; import dan200.computercraft.client.FrameInfo; import dan200.computercraft.client.render.RenderTypes; @@ -15,7 +17,7 @@ import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.Palette; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.client.renderer.texture.OverlayTexture; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -34,14 +36,10 @@ import static dan200.computercraft.client.render.RenderTypes.FULL_BRIGHT_LIGHTMA * *
  • {@link #drawTerminal}: Draw a terminal with a cursor. This is used by the various computer GUIs to render the * whole term.
  • - *
  • {@link #drawBlocker}: When rendering a terminal using {@link RenderTypes#TERMINAL_WITHOUT_DEPTH} you need to - * render an additional "depth blocker" on top of the monitor.
  • * */ public final class FixedWidthFontRenderer { - public static final ResourceLocation FONT = new ResourceLocation( "computercraft", "textures/gui/term_font.png" ); - public static final int FONT_HEIGHT = 9; public static final int FONT_WIDTH = 6; public static final float WIDTH = 256.0f; @@ -49,6 +47,8 @@ public final class FixedWidthFontRenderer public static final float BACKGROUND_START = (WIDTH - 6.0f) / WIDTH; public static final float BACKGROUND_END = (WIDTH - 4.0f) / WIDTH; + public static final float Z_EPSILON = 0.001f; + private FixedWidthFontRenderer() { } @@ -63,7 +63,7 @@ public final class FixedWidthFontRenderer 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, int light ) + private static void drawChar( PoseStack 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; @@ -74,25 +74,25 @@ public final class FixedWidthFontRenderer 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 ).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(); + Matrix4f matrix = transform.last().pose(); + Matrix3f normalMatrix = transform.last().normal(); + vertex( matrix, normalMatrix, buffer, x, y, Z_EPSILON, r, g, b, xStart / WIDTH, yStart / WIDTH, light ); + vertex( matrix, normalMatrix, buffer, x, y + FONT_HEIGHT, Z_EPSILON, r, g, b, xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH, light ); + vertex( matrix, normalMatrix, buffer, x + FONT_WIDTH, y + FONT_HEIGHT, Z_EPSILON, r, g, b, (xStart + FONT_WIDTH) / WIDTH, (yStart + FONT_HEIGHT) / WIDTH, light ); + vertex( matrix, normalMatrix, buffer, x + FONT_WIDTH, y, Z_EPSILON, r, g, b, (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH, light ); } - private static void drawQuad( Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, float r, float g, float b ) + private static void drawQuad( PoseStack transform, VertexConsumer buffer, float x, float y, float width, float height, float r, float g, float b, int light ) { - buffer.vertex( transform, x, y, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_START, BACKGROUND_START ).endVertex(); - buffer.vertex( transform, x, y + height, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_START, BACKGROUND_END ).endVertex(); - buffer.vertex( transform, x + width, y, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_END, BACKGROUND_START ).endVertex(); - buffer.vertex( transform, x + width, y, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_END, BACKGROUND_START ).endVertex(); - buffer.vertex( transform, x, y + height, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_START, BACKGROUND_END ).endVertex(); - buffer.vertex( transform, x + width, y + height, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_END, BACKGROUND_END ).endVertex(); + Matrix4f matrix = transform.last().pose(); + Matrix3f normalMatrix = transform.last().normal(); + vertex( matrix, normalMatrix, buffer, x, y, 0, r, g, b, BACKGROUND_START, BACKGROUND_START, light ); + vertex( matrix, normalMatrix, buffer, x, y + height, 0, r, g, b, BACKGROUND_START, BACKGROUND_END, light ); + vertex( matrix, normalMatrix, buffer, x + width, y + height, 0, r, g, b, BACKGROUND_END, BACKGROUND_END, light ); + vertex( matrix, normalMatrix, buffer, x + width, y, 0, r, g, b, BACKGROUND_END, BACKGROUND_START, light ); } - private static void drawQuad( Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, Palette palette, boolean greyscale, char colourIndex ) + private static void drawQuad( PoseStack transform, VertexConsumer buffer, float x, float y, float width, float height, Palette palette, boolean greyscale, char colourIndex, int light ) { double[] colour = palette.getColour( getColour( colourIndex, Colour.BLACK ) ); float r, g, b; @@ -107,23 +107,23 @@ public final class FixedWidthFontRenderer b = (float) colour[2]; } - drawQuad( transform, buffer, x, y, width, height, r, g, b ); + drawQuad( transform, buffer, x, y, width, height, r, g, b, light ); } private static void drawBackground( - @Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y, + @Nonnull PoseStack transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale, - float leftMarginSize, float rightMarginSize, float height + float leftMarginSize, float rightMarginSize, float height, int light ) { if( leftMarginSize > 0 ) { - drawQuad( transform, renderer, x - leftMarginSize, y, leftMarginSize, height, palette, greyscale, backgroundColour.charAt( 0 ) ); + drawQuad( transform, buffer, x - leftMarginSize, y, leftMarginSize, height, palette, greyscale, backgroundColour.charAt( 0 ), light ); } if( rightMarginSize > 0 ) { - drawQuad( transform, renderer, x + backgroundColour.length() * FONT_WIDTH, y, rightMarginSize, height, palette, greyscale, backgroundColour.charAt( backgroundColour.length() - 1 ) ); + drawQuad( transform, buffer, x + backgroundColour.length() * FONT_WIDTH, y, rightMarginSize, height, palette, greyscale, backgroundColour.charAt( backgroundColour.length() - 1 ), light ); } // Batch together runs of identical background cells. @@ -136,7 +136,7 @@ public final class FixedWidthFontRenderer if( blockColour != '\0' ) { - drawQuad( transform, renderer, x + blockStart * FONT_WIDTH, y, FONT_WIDTH * (i - blockStart), height, palette, greyscale, blockColour ); + drawQuad( transform, buffer, x + blockStart * FONT_WIDTH, y, FONT_WIDTH * (i - blockStart), height, palette, greyscale, blockColour, light ); } blockColour = colourIndex; @@ -145,19 +145,19 @@ public final class FixedWidthFontRenderer if( blockColour != '\0' ) { - drawQuad( transform, renderer, x + blockStart * FONT_WIDTH, y, FONT_WIDTH * (backgroundColour.length() - blockStart), height, palette, greyscale, blockColour ); + drawQuad( transform, buffer, x + blockStart * FONT_WIDTH, y, FONT_WIDTH * (backgroundColour.length() - blockStart), height, palette, greyscale, blockColour, light ); } } public static void drawString( - @Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y, + @Nonnull PoseStack transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull TextBuffer text, @Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale, float leftMarginSize, float rightMarginSize, int light ) { if( backgroundColour != null ) { - drawBackground( transform, renderer, x, y, backgroundColour, palette, greyscale, leftMarginSize, rightMarginSize, FONT_HEIGHT ); + drawBackground( transform, buffer, x, y, backgroundColour, palette, greyscale, leftMarginSize, rightMarginSize, FONT_HEIGHT, light ); } for( int i = 0; i < text.length(); i++ ) @@ -178,15 +178,15 @@ public final class FixedWidthFontRenderer // Draw char int index = text.charAt( i ); if( index > 255 ) index = '?'; - drawChar( transform, renderer, x + i * FONT_WIDTH, y, index, r, g, b, light ); + drawChar( transform, buffer, x + i * FONT_WIDTH, y, index, r, g, b, light ); } } public static void drawTerminalWithoutCursor( - @Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, + @Nonnull PoseStack transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull Terminal terminal, boolean greyscale, - float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize + float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize, int light ) { Palette palette = terminal.getPalette(); @@ -196,13 +196,13 @@ public final class FixedWidthFontRenderer drawBackground( transform, buffer, x, y - topMarginSize, terminal.getBackgroundColourLine( 0 ), palette, greyscale, - leftMarginSize, rightMarginSize, topMarginSize + leftMarginSize, rightMarginSize, topMarginSize, light ); drawBackground( transform, buffer, x, y + height * FONT_HEIGHT, terminal.getBackgroundColourLine( height - 1 ), palette, greyscale, - leftMarginSize, rightMarginSize, bottomMarginSize + leftMarginSize, rightMarginSize, bottomMarginSize, light ); // The main text @@ -217,7 +217,7 @@ public final class FixedWidthFontRenderer } public static void drawCursor( - @Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, + @Nonnull PoseStack transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull Terminal terminal, boolean greyscale ) { @@ -247,42 +247,44 @@ public final class FixedWidthFontRenderer } public static void drawTerminal( - @Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, + @Nonnull PoseStack transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull Terminal terminal, boolean greyscale, - float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize + float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize, int light ) { - drawTerminalWithoutCursor( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize ); + drawTerminalWithoutCursor( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize, light ); drawCursor( transform, buffer, x, y, terminal, greyscale ); } - public static void drawTerminal( - @Nonnull Matrix4f transform, float x, float y, @Nonnull Terminal terminal, boolean greyscale, + // Called by WidgetTerminal + public static void drawTerminalImmediate( + @Nonnull PoseStack transform, float x, float y, @Nonnull Terminal terminal, boolean greyscale, float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize ) { 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 ); + VertexConsumer buffer = renderer.getBuffer( RenderTypes.GUI_TERMINAL ); + drawTerminal( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize, FULL_BRIGHT_LIGHTMAP ); renderer.endBatch(); } - public static void drawEmptyTerminal( @Nonnull Matrix4f transform, @Nonnull MultiBufferSource renderer, float x, float y, float width, float height ) + public static void drawEmptyTerminal( @Nonnull PoseStack transform, @Nonnull VertexConsumer buffer, float x, float y, float width, float height, int light ) { Colour colour = Colour.BLACK; - drawQuad( transform, renderer.getBuffer( RenderTypes.TERMINAL_WITH_DEPTH ), x, y, width, height, colour.getR(), colour.getG(), colour.getB() ); + drawQuad( transform, buffer, x, y, width, height, colour.getR(), colour.getG(), colour.getB(), light ); } - public static void drawEmptyTerminal( @Nonnull Matrix4f transform, float x, float y, float width, float height ) + public static void drawEmptyTerminalImmediate( @Nonnull PoseStack transform, float x, float y, float width, float height ) { MultiBufferSource.BufferSource renderer = MultiBufferSource.immediate( Tesselator.getInstance().getBuilder() ); - drawEmptyTerminal( transform, renderer, x, y, width, height ); + VertexConsumer buffer = renderer.getBuffer( RenderTypes.GUI_TERMINAL ); + drawEmptyTerminal( transform, buffer, x, y, width, height, FULL_BRIGHT_LIGHTMAP ); renderer.endBatch(); } - public static void drawBlocker( @Nonnull Matrix4f transform, @Nonnull MultiBufferSource renderer, float x, float y, float width, float height ) + private static void vertex( Matrix4f poseMatrix, Matrix3f normalMatrix, VertexConsumer buffer, float x, float y, float z, float r, float g, float b, float u, float v, int light ) { - Colour colour = Colour.BLACK; - drawQuad( transform, renderer.getBuffer( RenderTypes.TERMINAL_BLOCKER ), x, y, width, height, colour.getR(), colour.getG(), colour.getB() ); + buffer.vertex( poseMatrix, x, y, z ).color( r, g, b, 1.0f ).uv( u, v ).overlayCoords( OverlayTexture.NO_OVERLAY ).uv2( light ).normal( normalMatrix, 0f, 0f, 1f ).endVertex(); } + } diff --git a/src/main/java/dan200/computercraft/client/gui/GuiComputer.java b/src/main/java/dan200/computercraft/client/gui/GuiComputer.java index d05f7e4e1..5eb8cbc8f 100644 --- a/src/main/java/dan200/computercraft/client/gui/GuiComputer.java +++ b/src/main/java/dan200/computercraft/client/gui/GuiComputer.java @@ -76,7 +76,7 @@ public final class GuiComputer extends Computer public void renderBg( @Nonnull PoseStack stack, float partialTicks, int mouseX, int mouseY ) { // Draw a border around the terminal - ComputerBorderRenderer.render( + ComputerBorderRenderer.renderFromGui( ComputerBorderRenderer.getTexture( family ), terminal.x, terminal.y, getBlitOffset(), RenderTypes.FULL_BRIGHT_LIGHTMAP, terminal.getWidth(), terminal.getHeight() ); diff --git a/src/main/java/dan200/computercraft/client/gui/GuiPrintout.java b/src/main/java/dan200/computercraft/client/gui/GuiPrintout.java index ed8e551d5..e5074a941 100644 --- a/src/main/java/dan200/computercraft/client/gui/GuiPrintout.java +++ b/src/main/java/dan200/computercraft/client/gui/GuiPrintout.java @@ -5,10 +5,10 @@ */ package dan200.computercraft.client.gui; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; -import com.mojang.math.Matrix4f; +import com.mojang.blaze3d.vertex.VertexConsumer; +import dan200.computercraft.client.render.RenderTypes; import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.shared.common.ContainerHeldItem; import dan200.computercraft.shared.media.items.ItemPrintout; @@ -100,13 +100,14 @@ public class GuiPrintout extends AbstractContainerScreen protected void renderBg( @Nonnull PoseStack transform, float partialTicks, int mouseX, int mouseY ) { // Draw the printout - RenderSystem.setShaderColor( 1.0f, 1.0f, 1.0f, 1.0f ); - RenderSystem.enableDepthTest(); - MultiBufferSource.BufferSource renderer = MultiBufferSource.immediate( Tesselator.getInstance().getBuilder() ); - Matrix4f matrix = transform.last().pose(); - 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 ); + + VertexConsumer borderBuffer = renderer.getBuffer( RenderTypes.GUI_PRINTOUT_BACKGROUND ); + drawBorder( transform, borderBuffer, leftPos, topPos, getBlitOffset(), page, pages, book, FULL_BRIGHT_LIGHTMAP ); + + VertexConsumer textBuffer = renderer.getBuffer( RenderTypes.GUI_PRINTOUT_TEXT ); + drawText( transform, textBuffer, 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/gui/widgets/WidgetTerminal.java b/src/main/java/dan200/computercraft/client/gui/widgets/WidgetTerminal.java index ebef85e1d..bae7fd8fd 100644 --- a/src/main/java/dan200/computercraft/client/gui/widgets/WidgetTerminal.java +++ b/src/main/java/dan200/computercraft/client/gui/widgets/WidgetTerminal.java @@ -6,7 +6,6 @@ package dan200.computercraft.client.gui.widgets; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Matrix4f; import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.computer.core.ClientComputer; @@ -313,15 +312,14 @@ public class WidgetTerminal extends AbstractWidget public void render( @Nonnull PoseStack transform, int mouseX, int mouseY, float partialTicks ) { if( !visible ) return; - Matrix4f matrix = transform.last().pose(); Terminal terminal = computer.getTerminal(); if( terminal != null ) { - FixedWidthFontRenderer.drawTerminal( matrix, innerX, innerY, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN ); + FixedWidthFontRenderer.drawTerminalImmediate( transform, innerX, innerY, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN ); } else { - FixedWidthFontRenderer.drawEmptyTerminal( matrix, x, y, width, height ); + FixedWidthFontRenderer.drawEmptyTerminalImmediate( transform, x, y, width, height ); } } diff --git a/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java b/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java index 225211d71..a17f50bc0 100644 --- a/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ComputerBorderRenderer.java @@ -5,13 +5,15 @@ */ package dan200.computercraft.client.render; +import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Matrix3f; import com.mojang.math.Matrix4f; import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.computer.core.ComputerFamily; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.resources.ResourceLocation; import javax.annotation.Nonnull; @@ -53,13 +55,13 @@ public class ComputerBorderRenderer public static final int TEX_SIZE = 256; private static final float TEX_SCALE = 1 / (float) TEX_SIZE; - private final Matrix4f transform; + private final PoseStack 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, int light, float r, float g, float b ) + public ComputerBorderRenderer( PoseStack transform, VertexConsumer builder, int z, int light, float r, float g, float b ) { this.transform = transform; this.builder = builder; @@ -86,20 +88,18 @@ public class ComputerBorderRenderer } } - public static RenderType getRenderType( ResourceLocation location ) + public static void renderFromGui( ResourceLocation location, int x, int y, int z, int light, int width, int height ) { - // See note in RenderTypes about why we use text rather than anything intuitive. - return RenderType.text( location ); + PoseStack identityStack = new PoseStack(); + MultiBufferSource.BufferSource renderer = MultiBufferSource.immediate( Tesselator.getInstance().getBuilder() ); + render( + identityStack, renderer.getBuffer( RenderTypes.guiComputerBorder( location ) ), + x, y, z, light, width, height, false, 1, 1, 1 + ); + renderer.endBatch(); } - public static void render( ResourceLocation location, int x, int y, int z, int light, int width, int height ) - { - 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 light, int width, int height, boolean withLight, float r, float g, float b ) + public static void render( PoseStack transform, VertexConsumer buffer, int x, int y, int z, int light, int width, int height, boolean withLight, float r, float g, float b ) { new ComputerBorderRenderer( transform, buffer, z, light, r, g, b ).doRender( x, y, width, height, withLight ); } @@ -151,9 +151,11 @@ public class ComputerBorderRenderer 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 ).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(); + Matrix4f poseMatrix = transform.last().pose(); + Matrix3f normalMatrix = transform.last().normal(); + builder.vertex( poseMatrix, x, y + height, z ).color( r, g, b, 1.0f ).uv( u * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).overlayCoords( OverlayTexture.NO_OVERLAY ).uv2( light ).normal( normalMatrix, 0f, 0f, 1f ).endVertex(); + builder.vertex( poseMatrix, x + width, y + height, z ).color( r, g, b, 1.0f ).uv( (u + textureWidth) * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).overlayCoords( OverlayTexture.NO_OVERLAY ).uv2( light ).normal( normalMatrix, 0f, 0f, 1f ).endVertex(); + builder.vertex( poseMatrix, x + width, y, z ).color( r, g, b, 1.0f ).uv( (u + textureWidth) * TEX_SCALE, v * TEX_SCALE ).overlayCoords( OverlayTexture.NO_OVERLAY ).uv2( light ).normal( normalMatrix, 0f, 0f, 1f ).endVertex(); + builder.vertex( poseMatrix, x, y, z ).color( r, g, b, 1.0f ).uv( u * TEX_SCALE, v * TEX_SCALE ).overlayCoords( OverlayTexture.NO_OVERLAY ).uv2( light ).normal( normalMatrix, 0f, 0f, 1f ).endVertex(); } } diff --git a/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java b/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java index 6806aa089..9ab59b94b 100644 --- a/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java @@ -6,6 +6,7 @@ package dan200.computercraft.client.render; import com.mojang.blaze3d.vertex.*; +import com.mojang.math.Matrix3f; import com.mojang.math.Matrix4f; import com.mojang.math.Vector3f; import dan200.computercraft.ComputerCraft; @@ -16,12 +17,13 @@ import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.util.Colour; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; -import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; -import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH; +import static dan200.computercraft.client.gui.FixedWidthFontRenderer.*; import static dan200.computercraft.client.render.ComputerBorderRenderer.*; +import static dan200.computercraft.client.render.RenderTypes.FULL_BRIGHT_LIGHTMAP; /** * Emulates map rendering for pocket computers. @@ -63,7 +65,9 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer transform.scale( 0.5f, 0.5f, 0.5f ); float scale = 0.75f / Math.max( width + BORDER * 2, height + BORDER * 2 + LIGHT_HEIGHT ); - transform.scale( scale, scale, -1.0f ); + // Avoid PoseStack#scale to preserve normal matrix, and fix the normals ourselves. + transform.last().pose().multiply( Matrix4f.createScaleMatrix( scale, scale, -1.0f ) ); + transform.last().normal().mul( -1.0f ); transform.translate( -0.5 * width, -0.5 * height, 0 ); // Render the main frame @@ -71,31 +75,32 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer ComputerFamily family = item.getFamily(); int frameColour = item.getColour( stack ); - Matrix4f matrix = transform.last().pose(); - renderFrame( matrix, renderer, family, frameColour, light, width, height ); + renderFrame( transform, renderer, family, frameColour, light, width, height ); // Render the light int lightColour = ItemPocketComputer.getLightState( stack ); if( lightColour == -1 ) lightColour = Colour.BLACK.getHex(); - renderLight( matrix, renderer, lightColour, width, height ); + renderLight( transform, renderer, lightColour, width, height ); + VertexConsumer buffer = renderer.getBuffer( RenderTypes.ITEM_POCKET_TERMINAL ); if( computer != null && terminal != null ) { FixedWidthFontRenderer.drawTerminal( - matrix, renderer.getBuffer( RenderTypes.TERMINAL_WITHOUT_DEPTH ), - MARGIN, MARGIN, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN + transform, buffer, + MARGIN, MARGIN, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN, FULL_BRIGHT_LIGHTMAP ); - FixedWidthFontRenderer.drawBlocker( transform.last().pose(), renderer, 0, 0, width, height ); } else { - FixedWidthFontRenderer.drawEmptyTerminal( matrix, 0, 0, width, height ); + FixedWidthFontRenderer.drawEmptyTerminal( + transform, buffer, + 0, 0, width, height, 0 ); } transform.popPose(); } - private static void renderFrame( Matrix4f transform, MultiBufferSource render, ComputerFamily family, int colour, int light, int width, int height ) + private static void renderFrame( PoseStack transform, MultiBufferSource renderer, ComputerFamily family, int colour, int light, int width, int height ) { ResourceLocation texture = colour != -1 ? ComputerBorderRenderer.BACKGROUND_COLOUR : ComputerBorderRenderer.getTexture( family ); @@ -103,20 +108,23 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer float g = ((colour >>> 8) & 0xFF) / 255.0f; float b = (colour & 0xFF) / 255.0f; - ComputerBorderRenderer.render( transform, render.getBuffer( ComputerBorderRenderer.getRenderType( texture ) ), 0, 0, 0, light, width, height, true, r, g, b ); + VertexConsumer buffer = renderer.getBuffer( RenderTypes.itemPocketBorder( texture ) ); + ComputerBorderRenderer.render( transform, buffer, 0, 0, 0, light, width, height, true, r, g, b ); } - private static void renderLight( Matrix4f transform, MultiBufferSource render, int colour, int width, int height ) + private static void renderLight( PoseStack transform, MultiBufferSource renderer, int colour, int width, int height ) { float r = ((colour >>> 16) & 0xFF) / 255.0f; float g = ((colour >>> 8) & 0xFF) / 255.0f; float b = (colour & 0xFF) / 255.0f; float z = 0.001f; - VertexConsumer buffer = render.getBuffer( RenderTypes.POSITION_COLOR ); - buffer.vertex( transform, width - LIGHT_HEIGHT * 2, height + LIGHT_HEIGHT + BORDER / 2.0f, z ).color( r, g, b, 1.0f ).endVertex(); - buffer.vertex( transform, width, height + LIGHT_HEIGHT + BORDER / 2.0f, z ).color( r, g, b, 1.0f ).endVertex(); - buffer.vertex( transform, width, height + BORDER / 2.0f, z ).color( r, g, b, 1.0f ).endVertex(); - buffer.vertex( transform, width - LIGHT_HEIGHT * 2, height + BORDER / 2.0f, z ).color( r, g, b, 1.0f ).endVertex(); + VertexConsumer buffer = renderer.getBuffer( RenderTypes.ITEM_POCKET_LIGHT ); + Matrix4f poseMatrix = transform.last().pose(); + Matrix3f normalMatrix = transform.last().normal(); + buffer.vertex( poseMatrix, width - LIGHT_HEIGHT * 2, height + LIGHT_HEIGHT + BORDER / 2.0f, z ).color( r, g, b, 1.0f ).uv( BACKGROUND_START, BACKGROUND_START ).overlayCoords( OverlayTexture.NO_OVERLAY ).uv2( FULL_BRIGHT_LIGHTMAP ).normal( normalMatrix, 0f, 0f, 1f ).endVertex(); + buffer.vertex( poseMatrix, width, height + LIGHT_HEIGHT + BORDER / 2.0f, z ).color( r, g, b, 1.0f ).uv( BACKGROUND_START, BACKGROUND_END ).overlayCoords( OverlayTexture.NO_OVERLAY ).uv2( FULL_BRIGHT_LIGHTMAP ).normal( normalMatrix, 0f, 0f, 1f ).endVertex(); + buffer.vertex( poseMatrix, width, height + BORDER / 2.0f, z ).color( r, g, b, 1.0f ).uv( BACKGROUND_END, BACKGROUND_END ).overlayCoords( OverlayTexture.NO_OVERLAY ).uv2( FULL_BRIGHT_LIGHTMAP ).normal( normalMatrix, 0f, 0f, 1f ).endVertex(); + buffer.vertex( poseMatrix, width - LIGHT_HEIGHT * 2, height + BORDER / 2.0f, z ).color( r, g, b, 1.0f ).uv( BACKGROUND_END, BACKGROUND_START ).overlayCoords( OverlayTexture.NO_OVERLAY ).uv2( FULL_BRIGHT_LIGHTMAP ).normal( normalMatrix, 0f, 0f, 1f ).endVertex(); } } diff --git a/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java b/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java index 8d07b890c..422370065 100644 --- a/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/ItemPrintoutRenderer.java @@ -29,32 +29,38 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer { } - public boolean renderInFrame( PoseStack matrixStack, MultiBufferSource consumerProvider, ItemStack stack, int light ) + public boolean renderInFrame( PoseStack transform, MultiBufferSource renderer, ItemStack stack, int light ) { if( !(stack.getItem() instanceof ItemPrintout) ) return false; // Move a little bit forward to ensure we're not clipping with the frame - matrixStack.translate( 0.0f, 0.0f, -0.001f ); - matrixStack.mulPose( Vector3f.ZP.rotationDegrees( 180f ) ); - matrixStack.scale( 0.95f, 0.95f, -0.95f ); - matrixStack.translate( -0.5f, -0.5f, 0.0f ); + transform.translate( 0.0f, 0.0f, -0.001f ); + transform.mulPose( Vector3f.ZP.rotationDegrees( 180f ) ); + // Avoid PoseStack#scale to preserve normal matrix, and fix the normals ourselves. + transform.last().pose().multiply( Matrix4f.createScaleMatrix( 0.95f, 0.95f, -0.95f ) ); + transform.last().normal().mul( -1.0f ); - drawPrintout( matrixStack, consumerProvider, stack, light ); + //transform.last().normal().mul( -1.0f ); + transform.translate( -0.5f, -0.5f, 0.0f ); + + drawPrintout( transform, renderer, stack, light ); return true; } @Override - protected void renderItem( PoseStack transform, MultiBufferSource render, ItemStack stack, int light ) + protected void renderItem( PoseStack transform, MultiBufferSource renderer, ItemStack stack, int light ) { transform.mulPose( Vector3f.XP.rotationDegrees( 180f ) ); - transform.scale( 0.42f, 0.42f, -0.42f ); + // Avoid PoseStack#scale to preserve normal matrix, and fix the normals ourselves. + transform.last().pose().multiply( Matrix4f.createScaleMatrix( 0.42f, 0.42f, -0.42f ) ); + transform.last().normal().mul( -1.0f ); transform.translate( -0.5f, -0.48f, 0.0f ); - drawPrintout( transform, render, stack, light ); + drawPrintout( transform, renderer, stack, light ); } - private static void drawPrintout( PoseStack transform, MultiBufferSource render, ItemStack stack, int light ) + private static void drawPrintout( PoseStack transform, MultiBufferSource renderer, ItemStack stack, int light ) { int pages = ItemPrintout.getPageCount( stack ); boolean book = ((ItemPrintout) stack.getItem()).getType() == ItemPrintout.Type.BOOK; @@ -81,11 +87,13 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer transform.scale( scale, scale, scale ); 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, light ); + drawBorder( + transform, renderer.getBuffer( RenderTypes.ITEM_PRINTOUT_BACKGROUND ), + 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 ) + transform, renderer.getBuffer( RenderTypes.ITEM_PRINTOUT_TEXT ), + 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 58bef2984..af35f2253 100644 --- a/src/main/java/dan200/computercraft/client/render/PrintoutRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/PrintoutRenderer.java @@ -5,12 +5,14 @@ */ package dan200.computercraft.client.render; +import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Matrix3f; import com.mojang.math.Matrix4f; import dan200.computercraft.client.gui.FixedWidthFontRenderer; import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.shared.util.Palette; -import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.texture.OverlayTexture; import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT; import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAGE; @@ -54,9 +56,8 @@ public final class PrintoutRenderer private PrintoutRenderer() {} - public static void drawText( Matrix4f transform, MultiBufferSource renderer, int x, int y, int start, int light, TextBuffer[] text, TextBuffer[] colours ) + public static void drawText( PoseStack transform, VertexConsumer buffer, int x, int y, int start, int light, TextBuffer[] text, TextBuffer[] colours ) { - VertexConsumer buffer = renderer.getBuffer( RenderTypes.PRINTOUT_TEXT ); for( int line = 0; line < LINES_PER_PAGE && line < text.length; line++ ) { FixedWidthFontRenderer.drawString( transform, buffer, @@ -67,9 +68,8 @@ public final class PrintoutRenderer } } - public static void drawText( Matrix4f transform, MultiBufferSource renderer, int x, int y, int start, int light, String[] text, String[] colours ) + public static void drawText( PoseStack transform, VertexConsumer buffer, int x, int y, int start, int light, String[] text, String[] colours ) { - VertexConsumer buffer = renderer.getBuffer( RenderTypes.PRINTOUT_TEXT ); for( int line = 0; line < LINES_PER_PAGE && line < text.length; line++ ) { FixedWidthFontRenderer.drawString( transform, buffer, @@ -81,13 +81,11 @@ public final class PrintoutRenderer } } - public static void drawBorder( Matrix4f transform, MultiBufferSource renderer, float x, float y, float z, int page, int pages, boolean isBook, int light ) + public static void drawBorder( PoseStack transform, VertexConsumer buffer, float x, float y, float z, int page, int pages, boolean isBook, int light ) { int leftPages = page; int rightPages = pages - page - 1; - VertexConsumer buffer = renderer.getBuffer( RenderTypes.PRINTOUT_BACKGROUND ); - if( isBook ) { // Border @@ -144,25 +142,29 @@ public final class PrintoutRenderer } } - private static void drawTexture( Matrix4f matrix, VertexConsumer buffer, float x, float y, float z, float u, float v, float width, float height, int light ) + private static void drawTexture( PoseStack transform, VertexConsumer buffer, float x, float y, float z, float u, float v, float width, float height, int light ) { - 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 ); + Matrix4f poseMatrix = transform.last().pose(); + Matrix3f normalMatrix = transform.last().normal(); + vertex( poseMatrix, normalMatrix, buffer, x, y + height, z, u / BG_SIZE, (v + height) / BG_SIZE, light ); + vertex( poseMatrix, normalMatrix, buffer, x + width, y + height, z, (u + width) / BG_SIZE, (v + height) / BG_SIZE, light ); + vertex( poseMatrix, normalMatrix, buffer, x + width, y, z, (u + width) / BG_SIZE, v / BG_SIZE, light ); + vertex( poseMatrix, normalMatrix, buffer, 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, int light ) + private static void drawTexture( PoseStack transform, VertexConsumer buffer, float x, float y, float z, float width, float height, float u, float v, float tWidth, float tHeight, int light ) { - 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 ); + Matrix4f poseMatrix = transform.last().pose(); + Matrix3f normalMatrix = transform.last().normal(); + vertex( poseMatrix, normalMatrix, buffer, x, y + height, z, u / BG_SIZE, (v + tHeight) / BG_SIZE, light ); + vertex( poseMatrix, normalMatrix, buffer, x + width, y + height, z, (u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE, light ); + vertex( poseMatrix, normalMatrix, buffer, x + width, y, z, (u + tWidth) / BG_SIZE, v / BG_SIZE, light ); + vertex( poseMatrix, normalMatrix, buffer, 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 ) + private static void vertex( Matrix4f poseMatrix, Matrix3f normalMatrix, VertexConsumer buffer, 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(); + buffer.vertex( poseMatrix, x, y, z ).color( 255, 255, 255, 255 ).uv( u, v ).overlayCoords( OverlayTexture.NO_OVERLAY ).uv2( light ).normal( normalMatrix, 0f, 0f, 1f ).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 21d407b6e..57d1d5e32 100644 --- a/src/main/java/dan200/computercraft/client/render/RenderTypes.java +++ b/src/main/java/dan200/computercraft/client/render/RenderTypes.java @@ -7,7 +7,7 @@ package dan200.computercraft.client.render; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.VertexFormat; -import dan200.computercraft.client.gui.FixedWidthFontRenderer; +import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.RenderStateShard; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.ShaderInstance; @@ -15,28 +15,41 @@ import net.minecraft.resources.ResourceLocation; import javax.annotation.Nonnull; + public class RenderTypes { + public static final ResourceLocation FONT = new ResourceLocation( "computercraft", "textures/gui/term_font.png" ); + public static final ResourceLocation PRINTOUT_BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/printout.png" ); public static final int FULL_BRIGHT_LIGHTMAP = (0xF << 4) | (0xF << 20); - public static MonitorTextureBufferShader monitorTboShader; - public static ShaderInstance terminalShader; - - public static final RenderType TERMINAL_WITHOUT_DEPTH = Types.TERMINAL_WITHOUT_DEPTH; - 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 MONITOR = RenderType.textIntensity( FONT ); - /** - * 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 ITEM_POCKET_TERMINAL = RenderType.textIntensity( FONT ); + public static final RenderType ITEM_POCKET_LIGHT = RenderType.textIntensity( FONT ); + public static final RenderType ITEM_PRINTOUT_BACKGROUND = RenderType.entityCutout( PRINTOUT_BACKGROUND ); + public static final RenderType ITEM_PRINTOUT_TEXT = RenderType.entityCutout( FONT ); - public static final RenderType POSITION_COLOR = Types.POSITION_COLOR; + public static final RenderType GUI_TERMINAL = RenderType.text( FONT ); + public static final RenderType GUI_PRINTOUT_BACKGROUND = RenderType.text( PRINTOUT_BACKGROUND ); + public static final RenderType GUI_PRINTOUT_TEXT = RenderType.text( FONT ); + + public static ShaderInstance getMonitorShader() + { + return GameRenderer.getRendertypeTextIntensityShader(); + } + + public static RenderType itemPocketBorder( ResourceLocation location ) + { + return RenderType.entityCutout( location ); + } + + public static RenderType guiComputerBorder( ResourceLocation location ) + { + return RenderType.text( location ); + } + + public static MonitorTextureBufferShader monitorTboShader; @Nonnull static MonitorTextureBufferShader getMonitorTextureBufferShader() @@ -45,22 +58,12 @@ public class RenderTypes return monitorTboShader; } - @Nonnull - static ShaderInstance getTerminalShader() - { - if( terminalShader == null ) throw new NullPointerException( "MonitorTboShader has not been registered" ); - return terminalShader; - } - private static final class Types extends RenderStateShard { private static final RenderStateShard.TextureStateShard TERM_FONT_TEXTURE = new TextureStateShard( - FixedWidthFontRenderer.FONT, + FONT, false, false // blur, minimap ); - 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, @@ -68,57 +71,6 @@ public class RenderTypes RenderType.CompositeState.builder() .setTextureState( TERM_FONT_TEXTURE ) .setShaderState( new ShaderStateShard( RenderTypes::getMonitorTextureBufferShader ) ) - .setWriteMaskState( COLOR_WRITE ) - .createCompositeState( false ) - ); - - static final RenderType TERMINAL_WITHOUT_DEPTH = RenderType.create( - "terminal_without_depth", TERM_FORMAT, TERM_MODE, 1024, - false, false, // useDelegate, needsSorting - RenderType.CompositeState.builder() - .setTextureState( TERM_FONT_TEXTURE ) - .setShaderState( TERM_SHADER ) - .setWriteMaskState( COLOR_WRITE ) - .createCompositeState( false ) - ); - - static final RenderType TERMINAL_BLOCKER = RenderType.create( - "terminal_blocker", TERM_FORMAT, TERM_MODE, 256, - false, false, // useDelegate, needsSorting - RenderType.CompositeState.builder() - .setTextureState( TERM_FONT_TEXTURE ) - .setShaderState( TERM_SHADER ) - .setWriteMaskState( DEPTH_WRITE ) - .createCompositeState( false ) - ); - - static final RenderType TERMINAL_WITH_DEPTH = RenderType.create( - "terminal_with_depth", TERM_FORMAT, TERM_MODE, 1024, - false, false, // useDelegate, needsSorting - RenderType.CompositeState.builder() - .setTextureState( TERM_FONT_TEXTURE ) - .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 ) - ); - - static final RenderType POSITION_COLOR = RenderType.create( - "position_color", DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.QUADS, 128, - false, false, // useDelegate, needsSorting - RenderType.CompositeState.builder() - .setShaderState( POSITION_COLOR_SHADER ) .createCompositeState( false ) ); diff --git a/src/main/java/dan200/computercraft/client/render/TileEntityMonitorRenderer.java b/src/main/java/dan200/computercraft/client/render/TileEntityMonitorRenderer.java index 7c71f4a0f..5cc3c97a5 100644 --- a/src/main/java/dan200/computercraft/client/render/TileEntityMonitorRenderer.java +++ b/src/main/java/dan200/computercraft/client/render/TileEntityMonitorRenderer.java @@ -9,8 +9,8 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.MemoryTracker; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.*; +import com.mojang.math.Matrix3f; import com.mojang.math.Matrix4f; -import com.mojang.math.Transformation; import com.mojang.math.Vector3f; import dan200.computercraft.ComputerCraft; import dan200.computercraft.client.FrameInfo; @@ -23,7 +23,6 @@ import dan200.computercraft.shared.peripheral.monitor.TileMonitor; import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.DirectionUtil; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.core.BlockPos; @@ -36,6 +35,7 @@ import javax.annotation.Nonnull; import java.nio.ByteBuffer; import static dan200.computercraft.client.gui.FixedWidthFontRenderer.*; +import static dan200.computercraft.client.render.RenderTypes.FULL_BRIGHT_LIGHTMAP; public class TileEntityMonitorRenderer implements BlockEntityRenderer { @@ -43,10 +43,17 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer list, List>> list2 ) throws IOException { - list2.add( Pair.of( new ShaderInstance( - manager, - "terminal", - RenderTypes.TERMINAL_WITHOUT_DEPTH.format() - ), shader -> RenderTypes.terminalShader = shader ) ); list2.add( Pair.of( new MonitorTextureBufferShader( manager, "monitor_tbo", diff --git a/src/main/java/dan200/computercraft/shared/integration/ModMenuIntegration.java b/src/main/java/dan200/computercraft/shared/integration/ModMenuIntegration.java index 0193fe67c..dfb583e3e 100644 --- a/src/main/java/dan200/computercraft/shared/integration/ModMenuIntegration.java +++ b/src/main/java/dan200/computercraft/shared/integration/ModMenuIntegration.java @@ -7,7 +7,6 @@ package dan200.computercraft.shared.integration; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; -import dan200.computercraft.ComputerCraft; import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer; import dan200.computercraft.shared.util.Config; import me.shedaniel.clothconfig2.api.ConfigBuilder; @@ -33,20 +32,60 @@ public class ModMenuIntegration implements ModMenuApi Config.clientSpec.correct( Config.clientConfig ); Config.sync(); Config.save(); - ComputerCraft.log.info( "Monitor renderer: {}", ComputerCraft.monitorRenderer ); } ); ConfigCategory client = builder.getOrCreateCategory( new TextComponent( "Client" ) ); ConfigEntryBuilder entryBuilder = builder.entryBuilder(); - client.addEntry( entryBuilder.startEnumSelector( new TextComponent( "Monitor Renderer" ), MonitorRenderer.class, ComputerCraft.monitorRenderer ) + client.addEntry( entryBuilder + .startEnumSelector( + new TextComponent( "Monitor Renderer" ), + MonitorRenderer.class, + Config.clientConfig.getEnum( "monitor_renderer", MonitorRenderer.class ) + ) .setDefaultValue( MonitorRenderer.BEST ) .setSaveConsumer( renderer -> Config.clientConfig.set( "monitor_renderer", renderer ) ) - .setTooltip( Component.nullToEmpty( Config.clientConfig.getComment( "monitor_renderer" ) ) ) + .setTooltip( Component.nullToEmpty( rewrapComment( Config.clientConfig.getComment( "monitor_renderer" ) ) ) ) .build() ); return builder.build(); }; } + + private static String rewrapComment( String comment ) + { + String[] words = comment.strip().replaceAll( "[\r\n]", "" ).split( " " ); + + StringBuilder builder = new StringBuilder(); + int lineLength = 0; + for( String word : words ) + { + int wordLength = word.length(); + + if( lineLength + wordLength + 1 > 50 ) + { + builder.append( "\n" ); + lineLength = 0; + builder.append( word ); + lineLength += wordLength; + } + else + { + if( builder.length() == 0 ) + { + builder.append( word ); + lineLength += wordLength; + } + else + { + builder.append( " " ); + builder.append( word ); + lineLength += wordLength + 1; + } + } + } + + return new String( builder ); + } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorRenderer.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorRenderer.java index 18e88f26d..3eac19b1d 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorRenderer.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorRenderer.java @@ -8,7 +8,6 @@ package dan200.computercraft.shared.peripheral.monitor; import dan200.computercraft.ComputerCraft; import dan200.computercraft.client.render.TileEntityMonitorRenderer; import net.fabricmc.loader.api.FabricLoader; -import org.lwjgl.opengl.GL; import javax.annotation.Nonnull; import java.util.Arrays; @@ -49,61 +48,33 @@ public enum MonitorRenderer @Nonnull public static MonitorRenderer current() { - MonitorRenderer current = ComputerCraft.monitorRenderer; - switch( current ) - { - case BEST: - return best(); - case TBO: - checkCapabilities(); - if( !textureBuffer ) - { - ComputerCraft.log.warn( "Texture buffers are not supported on your graphics card. Falling back to default." ); - ComputerCraft.monitorRenderer = BEST; - return best(); - } + if( !initialised ) initialise(); - return TBO; - default: - return current; - } + MonitorRenderer current = ComputerCraft.monitorRenderer; + if( current == BEST ) return best(); + return current; } private static MonitorRenderer best() { - if( !initialised ) + if( shaderMod ) { - checkCapabilities(); - checkForShaderMods(); - if( textureBuffer && shaderMod ) - { - ComputerCraft.log.warn( "Shader mod detected. Enabling VBO renderer for compatibility." ); - } - - initialised = true; + ComputerCraft.log.warn( "Shader mod detected. Enabling VBO monitor renderer for compatibility." ); + return ComputerCraft.monitorRenderer = VBO; } - - return textureBuffer && !shaderMod ? TBO : VBO; + return ComputerCraft.monitorRenderer = TBO; } private static boolean initialised = false; - private static boolean textureBuffer = false; - private static boolean shaderMod = false; - //TODO find out which shader mods do better with VBOs and add them here. - private static List shaderModIds = Arrays.asList( "optifabric" ); + private static boolean shaderMod; + private static final List shaderModIds = Arrays.asList( "iris", "canvas", "optifabric" ); - private static void checkCapabilities() - { - if( initialised ) return; - - textureBuffer = GL.getCapabilities().OpenGL31; - initialised = true; - } - - private static void checkForShaderMods() + private static void initialise() { shaderMod = FabricLoader.getInstance().getAllMods().stream() .map( modContainer -> modContainer.getMetadata().getId() ) - .anyMatch( id -> shaderModIds.contains( id ) ); + .anyMatch( shaderModIds::contains ); + + initialised = true; } }