This uses the system described in #409, to render monitors in a more
efficient manner.
Each monitor is backed by a texture buffer object (TBO) which contains
a relatively compact encoding of the terminal state. This is then
rendered using a shader, which consumes the TBO and uses it to index
into main font texture.
As we're transmitting significantly less data to the GPU (only 3 bytes
per character), this effectively reduces any update lag to 0. FPS appears
to be up by a small fraction (10-15fps on my machine, to ~110), possibly
as we're now only drawing a single quad (though doing much more work in
the shader).
On my laptop, with its Intel integrated graphics card, I'm able to draw
120 full-sized monitors (with an effective resolution of 3972 x 2330) at
a consistent 60fps. Updates still cause a slight spike, but we always
remain above 30fps - a significant improvement over VBOs, where updates
would go off the chart.
Many thanks to @Lignum and @Lemmmy for devising this scheme, and helping
test and review it! ♥
Unknown blit colours, such as " " will be translated to black for the
background or white for the foreground. This restores the behaviour from
before #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.
Most of the port is pretty simple. The main problems are regarding
changes to Minecraft's rendering system.
- Remove several rendering tweaks until Forge's compatibility it
brought up-to-date
- Map rendering for pocket computers and printouts
- Item frame rendering for printouts
- Custom block outlines for monitors and cables/wired modems
- Custom breaking progress for cables/wired modems
- Turtle "Dinnerbone" rendering is currently broken, as normals are not
correctly transformed.
- Rewrite FixedWidthFontRenderer to to the buffer in a single sweep.
In order to do this, the term_font now also bundles a "background"
section, which is just a blank region of the screen.
- Render monitors using a VBO instead of a call list. I haven't
compared performance yet, but it manages to render a 6x5 array of
_static_ monitors at almost 60fps, which seems pretty reasonable.
So very little works, but it compiles and runs.
Things to resolve over the next few days:
- Horrible mappings (should largely be resolved by tomorrow).
- Cannot send extra data over containers - we'll have to see what Forge
does here.
- Turtle models are broken
- No block drops yet - this will largely be cherry-picking whatever I
did on Fabric.
- Weird inventory desyncs (items don't show up initially when
interacting with a CC inventory).
- Probably lots of other things.
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
OK, so let's get this out of the way, there's some actual changes mixed
in here too. I'm really sorry:
- Turtles can now not be renamed with unnamed item tags (previously it
would clear the name, this seemed a little unideal).
- commands.getBlock(s)Data will also include NBT.
Now, onto the horror story which is these inspection changes:
- Make a lot of methods static
- Typo fixes
- Make utility classes final + private constructor
- Lots of reformatting (ifs -> ternary, invert control flow, etc...)
- ???
- Profit!
I'm so going to regret this - can pretty much guarantee this is going to
break something.
- Remove redundant constructors and super calls
- Standardise naming of texture fields
- Always use postfix notations for loops
- Cleanup several peripheral classes
Some methods act the same on both sides, and so can be in utility
classes. Others are only needed on one side, and so do not really need
to be part of the proxy.
- Remove TurtleVisionCamera. It would be possible to add this back in
the future, but for now it is unused and so should be removed.
- Move frame info (cursor blink, current render frame) into a
FrameInfo class.
- Move record methods (name, playing a record) into a RecordUtil class.
- Convert most recipes to JSON
- Add JSON factories for impostor and turtle recipes.
- Several mappings changes
- Migrate to Forge's new registry system
- Adds a 1px margin around every glyph. This is generally empty,
with the exception of teletext characters where it continues their
pattern.
- Uses GL_CLAMP with the font texture.
Closes#300
- Lower case all model and texture names
- Move model registration code into preInit - this ensures we don't
get texture/model errors in the preInit stage.
Updated the source code to the version shipped as the 1.80pr0 alpha
release. Also removed some unnecessary files from the LuaJ subfolder
which were bulking up the repository.