mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-08-26 07:22:18 +00:00
[Iris] Merge Rendering Experiments to 1.18.2 (#78)
* Quick and dirty test. - VBO monitor renderer path has been hijacked to test not using VBOs, instead we recreate the terminal geometry every frame. - Add an explicit call the BufferSource.endBatch(). This actually fixes the incompatibility with Batched Entity Rendering. Who knew it was that easy? Results: works with Iris without shaders enabled. * Use entity RenderType for rendering terminals in world. - FixedWidthFontRenderer now emits quads and fills out all the vertex elements needed for the entity vertex format, which is, well, *all* of them. - FixedWidthFontRenderer now takes a PoseStack so it can offset the char quads from the background. - TERMINAL_MODE changed to quads so remaining custom RenderTypes work with FWFR. New progress at this commit: - Iris and Canvas both render the hi-jacked VBO backend properly. Issues: - Char quads have a blacker background than empty quads due to mismatched lightmaps. - Items in hand have improper normals. - TBO renderer is untested. Need to make sure it wasn't broken. * More stuff Progress: - "VBO" code path now works fine with shaders. - Printout GUI has lightmap issue. - Pocket computer frames don't have right normals in world. - Pocket computer lights don't work. TODOs: - Investigate whether VBOs can be used again without breaking compat. If not, the code path needs to be renamed and the code for managing VBO resources should be removed. - Make sure TBO code path still works. Wouldn't be surprised if I broke something there. * Found a new rendertype for monitors, fixed normals Progress: - Monitors render fullbright in every direction. - Normals are right on pocket computers and printouts, so lighting effects like directional light and shadow maps looks correct. - BEST monitor renderer settings will detect shader mods and automatically enable shader compatible code path. Details: - The "textIntensity" rendertype is exactaly what we need for monitors. It's shader doesn't apply a directional light so monitors look fullbright consistent no matter what direction they're facing. - Consolidated all references to rendertypes into RenderTypes class. - Improved consistency of rendering classes. Methods pass a PoseStack instead of a Matrix4f down the chain where possible so that normals can be calculated, and most rendering classes now fill out all vertex elements so they can be used with any vanilla vertex format. - Rendering methods should prefer to take a VertexConsumer rather than a BufferSource, the caller should provide appropriate buffer as that's where the context for buffer choice is. TODO: - Investigate re-enabling VBOs, and, if not an option, clean up naming and VBO related resource code. * Re-enable vbos Things were extremely slow without them in torture tests. They seem to work fine with Iris. Will need to test with Canvas too. I don't know why that hack with the inverse view rotation uniform works but fog doesn't render correctly without it. Unfortunately, the z-offset method does cause visible artifacts. Background quads can sometimes be seen under the edges of adjacant characters, giving the monitor a stitched together look. Will have to investigate splitting all the background and char quads into two draw calls and using glPolygonOffset on the characters :( which probably means two vbos :( :( Co-authored-by: Toad-Dev <748280+toad-dev@users.noreply.github.com>
This commit is contained in:
parent
12a5f7daeb
commit
d8bb05f30e
@ -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
|
||||
* </li>
|
||||
* <li>{@link #drawTerminal}: Draw a terminal with a cursor. This is used by the various computer GUIs to render the
|
||||
* whole term.</li>
|
||||
* <li>{@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.</li>
|
||||
* </ul>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ public final class GuiComputer<T extends ContainerComputerBase> 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()
|
||||
);
|
||||
|
@ -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<ContainerHeldItem>
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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 )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
);
|
||||
|
||||
|
@ -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<TileMonitor>
|
||||
{
|
||||
@ -43,10 +43,17 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
||||
* {@link TileMonitor#RENDER_MARGIN}, but a tiny bit of additional padding to ensure that there is no space between
|
||||
* the monitor frame and contents.
|
||||
*/
|
||||
private static final float MARGIN = (float) (TileMonitor.RENDER_MARGIN * 1.1);
|
||||
private static final float MARGIN = (float) (TileMonitor.RENDER_MARGIN * 1.05);
|
||||
private static ByteBuffer tboContents;
|
||||
|
||||
private static final Matrix4f IDENTITY = Transformation.identity().getMatrix();
|
||||
private static final Matrix3f IDENTITY;
|
||||
|
||||
static
|
||||
{
|
||||
Matrix3f identity = new Matrix3f();
|
||||
identity.setIdentity();
|
||||
IDENTITY = identity;
|
||||
}
|
||||
|
||||
public TileEntityMonitorRenderer( BlockEntityRendererProvider.Context context )
|
||||
{
|
||||
@ -110,44 +117,33 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
||||
double xScale = xSize / pixelWidth;
|
||||
double yScale = ySize / pixelHeight;
|
||||
transform.pushPose();
|
||||
transform.scale( (float) xScale, (float) -yScale, 1.0f );
|
||||
// Avoid PoseStack#scale to preserve normal matrix.
|
||||
transform.last().pose().multiply( Matrix4f.createScaleMatrix( (float) xScale, (float) -yScale, 1.0f ) );
|
||||
|
||||
Matrix4f matrix = transform.last().pose();
|
||||
|
||||
renderTerminal( renderer, matrix, originTerminal, (float) (MARGIN / xScale), (float) (MARGIN / yScale) );
|
||||
renderTerminal( renderer, transform, originTerminal, (float) (MARGIN / xScale), (float) (MARGIN / yScale) );
|
||||
|
||||
// We don't draw the cursor with the VBO, as it's dynamic and so we'll end up refreshing far more than is
|
||||
// reasonable.
|
||||
FixedWidthFontRenderer.drawCursor(
|
||||
matrix, renderer.getBuffer( RenderTypes.TERMINAL_WITHOUT_DEPTH ),
|
||||
transform, renderer.getBuffer( RenderTypes.MONITOR ),
|
||||
0, 0, terminal, !originTerminal.isColour()
|
||||
);
|
||||
|
||||
transform.popPose();
|
||||
|
||||
FixedWidthFontRenderer.drawBlocker(
|
||||
transform.last().pose(), renderer,
|
||||
-MARGIN, MARGIN,
|
||||
(float) (xSize + 2 * MARGIN), (float) -(ySize + MARGIN * 2)
|
||||
);
|
||||
|
||||
// Force a flush of the blocker. WorldRenderer.updateCameraAndRender will "finish" all the built-in
|
||||
// buffers before calling renderer.finish, which means the blocker isn't actually rendered at that point!
|
||||
renderer.getBuffer( RenderType.solid() );
|
||||
}
|
||||
else
|
||||
{
|
||||
FixedWidthFontRenderer.drawEmptyTerminal(
|
||||
transform.last().pose(), renderer,
|
||||
transform, renderer.getBuffer( RenderTypes.MONITOR ),
|
||||
-MARGIN, MARGIN,
|
||||
(float) (xSize + 2 * MARGIN), (float) -(ySize + MARGIN * 2)
|
||||
(float) (xSize + 2 * MARGIN), (float) -(ySize + MARGIN * 2), FULL_BRIGHT_LIGHTMAP
|
||||
);
|
||||
}
|
||||
|
||||
transform.popPose();
|
||||
}
|
||||
|
||||
private static void renderTerminal( @Nonnull MultiBufferSource renderer, Matrix4f matrix, ClientMonitor monitor, float xMargin, float yMargin )
|
||||
private static void renderTerminal( @Nonnull MultiBufferSource renderer, PoseStack transform, ClientMonitor monitor, float xMargin, float yMargin )
|
||||
{
|
||||
Terminal terminal = monitor.getTerminal();
|
||||
|
||||
@ -198,15 +194,13 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
||||
MonitorTextureBufferShader shader = RenderTypes.getMonitorTextureBufferShader();
|
||||
shader.setupUniform( width, height, terminal.getPalette(), !monitor.isColour() );
|
||||
|
||||
Matrix4f matrix = transform.last().pose();
|
||||
VertexConsumer buffer = renderer.getBuffer( RenderTypes.MONITOR_TBO );
|
||||
tboVertex( buffer, matrix, -xMargin, -yMargin );
|
||||
tboVertex( buffer, matrix, -xMargin, pixelHeight + yMargin );
|
||||
tboVertex( buffer, matrix, pixelWidth + xMargin, -yMargin );
|
||||
tboVertex( buffer, matrix, pixelWidth + xMargin, pixelHeight + yMargin );
|
||||
|
||||
// And force things to flush. We strictly speaking do this later on anyway for the cursor, but nice to
|
||||
// be consistent.
|
||||
renderer.getBuffer( RenderTypes.TERMINAL_WITHOUT_DEPTH );
|
||||
break;
|
||||
}
|
||||
|
||||
@ -217,19 +211,32 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
||||
{
|
||||
Tesselator tessellator = Tesselator.getInstance();
|
||||
BufferBuilder builder = tessellator.getBuilder();
|
||||
builder.begin( RenderTypes.TERMINAL_WITHOUT_DEPTH.mode(), RenderTypes.TERMINAL_WITHOUT_DEPTH.format() );
|
||||
builder.begin( RenderTypes.MONITOR.mode(), RenderTypes.MONITOR.format() );
|
||||
|
||||
FixedWidthFontRenderer.drawTerminalWithoutCursor(
|
||||
IDENTITY, builder, 0, 0,
|
||||
terminal, !monitor.isColour(), yMargin, yMargin, xMargin, xMargin
|
||||
new PoseStack(), builder, 0, 0,
|
||||
terminal, !monitor.isColour(), yMargin, yMargin, xMargin, xMargin, FULL_BRIGHT_LIGHTMAP
|
||||
);
|
||||
|
||||
builder.end();
|
||||
vbo.upload( builder );
|
||||
}
|
||||
|
||||
renderer.getBuffer( RenderTypes.TERMINAL_WITHOUT_DEPTH );
|
||||
RenderTypes.TERMINAL_WITHOUT_DEPTH.setupRenderState();
|
||||
vbo.drawWithShader( matrix, RenderSystem.getProjectionMatrix(), RenderTypes.getTerminalShader() );
|
||||
Matrix3f popViewRotation = RenderSystem.getInverseViewRotationMatrix();
|
||||
RenderSystem.setInverseViewRotationMatrix( IDENTITY );
|
||||
|
||||
RenderTypes.MONITOR.setupRenderState();
|
||||
vbo.drawWithShader( transform.last().pose(), RenderSystem.getProjectionMatrix(), RenderTypes.getMonitorShader() );
|
||||
RenderTypes.MONITOR.clearRenderState();
|
||||
|
||||
RenderSystem.setInverseViewRotationMatrix( popViewRotation );
|
||||
|
||||
// How we would draw the terminal without using VBO, for reference until I need to delete this.
|
||||
//VertexConsumer buffer = renderer.getBuffer( RenderTypes.MONITOR );
|
||||
//FixedWidthFontRenderer.drawTerminalWithoutCursor(
|
||||
// transform, buffer, 0, 0,
|
||||
// terminal, !monitor.isColour(), yMargin, yMargin, xMargin, xMargin, FULL_BRIGHT_LIGHTMAP
|
||||
//);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -28,11 +28,6 @@ public class MixinGameRenderer
|
||||
@Inject( method = "reloadShaders", at = @At( value = "INVOKE_ASSIGN", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", ordinal = 53 ), locals = LocalCapture.CAPTURE_FAILSOFT )
|
||||
private void reloadShaders( ResourceManager manager, CallbackInfo info, List<Program> list, List<Pair<ShaderInstance, Consumer<ShaderInstance>>> 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",
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
@ -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<String> shaderModIds = Arrays.asList( "optifabric" );
|
||||
private static boolean shaderMod;
|
||||
private static final List<String> 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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user