Backport 1.15's terminal rendering code (#412)

This is a backport of 1.15's terminal rendering code with some further
improvements. This duplicates a fair bit of code, and is much more
efficient.

I expect the work done in #409 will supersede this, but that's unlikely
to make its way into the next release so it's worth getting this in for
now.

 - Refactor a lot of common terminal code into
   `FixedWithFontRenderer`. This shouldn't change any behaviour, but
   makes a lot of our terminal renderers (printed pages, terminals,
   monitors) a lot cleaner.

 - Terminal rendering is done using a single mode/vertex format. Rather
   than drawing an untextured quad for the background colours, we use an
   entirely white piece of the terminal font. This allows us to batch
   draws together more elegantly.

 - Some minor optimisations:
   - Skip rendering `"\0"` and `" "` characters. These characters occur
     pretty often, especially on blank monitors and, as the font is empty
     here, it is safe to skip them.
   - Batch together adjacent background cells of the same colour. Again,
     most terminals will have large runs of the same colour, so this is a
     worthwhile optimisation.

   These optimisations do mean that terminal performance is no longer
   consistent as "noisy" terminals will have worse performance. This is
   annoying, but still worthwhile.

 - Switch monitor rendering over to use VBOs.

   We also add a config option to switch between rendering backends. By
   default we'll choose the best one compatible with your GPU, but there
   is a config option to switch between VBOS (reasonable performance) and
   display lists (bad).

When benchmarking 30 full-sized monitors rendering a static image, this
improves my FPS[^1] from 7 to 95. This is obviously an extreme case -
monitor updates are still slow, and so more frequently updating screens
will still be less than stellar.

[^1]: My graphics card is an Intel HD Graphics 520. Obviously numbers
      will vary.
This commit is contained in:
Jonathan Coates authored and GitHub committed 2020-04-21 10:43:26 +01:00
1 parent 7c1154ddfc
commit 11bf601db9
13 files changed
+594 -521

No files matched your search

@@ -11,6 +11,7 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.core.apis.AddressPredicate;
import dan200.computercraft.core.apis.http.websocket.Websocket;
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
import net.minecraftforge.common.config.ConfigCategory;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.common.config.Configuration;
@@ -69,6 +70,7 @@ public final class Config
private static Property modemRangeDuringStorm;
private static Property modemHighAltitudeRangeDuringStorm;
private static Property maxNotesPerTick;
private static Property monitorRenderer;
private static Property turtlesNeedFuel;
private static Property turtleFuelLimit;
@@ -264,9 +266,15 @@ public final class Config
maxNotesPerTick.setComment( "Maximum amount of notes a speaker can play at once" );
maxNotesPerTick.setMinValue( 1 );
monitorRenderer = config.get( CATEGORY_PERIPHERAL, "monitor_renderer", ComputerCraft.monitorRenderer.displayName() );
monitorRenderer.setComment( "The renderer to use for monitors. Generally this should be kept at \"best\" - if " +
"monitors have performance issues, you may wish to experiment with alternative renderers." );
monitorRenderer.setValidValues( MonitorRenderer.NAMES );
setOrder(
CATEGORY_PERIPHERAL,
commandBlockEnabled, modemRange, modemHighAltitudeRange, modemRangeDuringStorm, modemHighAltitudeRangeDuringStorm, maxNotesPerTick
commandBlockEnabled, modemRange, modemHighAltitudeRange, modemRangeDuringStorm, modemHighAltitudeRangeDuringStorm, maxNotesPerTick,
monitorRenderer
);
}
@@ -459,6 +467,7 @@ public final class Config
ComputerCraft.modem_highAltitudeRange = Math.min( modemHighAltitudeRange.getInt(), MODEM_MAX_RANGE );
ComputerCraft.modem_rangeDuringStorm = Math.min( modemRangeDuringStorm.getInt(), MODEM_MAX_RANGE );
ComputerCraft.modem_highAltitudeRangeDuringStorm = Math.min( modemHighAltitudeRangeDuringStorm.getInt(), MODEM_MAX_RANGE );
ComputerCraft.monitorRenderer = MonitorRenderer.ofString( monitorRenderer.getString() );
// Turtles
ComputerCraft.turtlesNeedFuel = turtlesNeedFuel.getBoolean();