2023-03-15 21:52:13 +00:00
|
|
|
// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: LicenseRef-CCPL
|
|
|
|
|
2022-11-09 23:58:56 +00:00
|
|
|
package dan200.computercraft.client.render.monitor;
|
2017-05-01 13:32:39 +00:00
|
|
|
|
2019-06-08 12:36:31 +00:00
|
|
|
import com.mojang.blaze3d.platform.GlStateManager;
|
2021-08-03 20:46:53 +00:00
|
|
|
import com.mojang.blaze3d.platform.MemoryTracker;
|
|
|
|
import com.mojang.blaze3d.systems.RenderSystem;
|
2023-06-08 08:48:37 +00:00
|
|
|
import com.mojang.blaze3d.vertex.*;
|
2022-12-08 19:45:02 +00:00
|
|
|
import com.mojang.math.Axis;
|
2024-01-31 20:55:14 +00:00
|
|
|
import dan200.computercraft.annotations.ForgeOverride;
|
2018-12-27 11:58:08 +00:00
|
|
|
import dan200.computercraft.client.FrameInfo;
|
2022-11-09 21:05:27 +00:00
|
|
|
import dan200.computercraft.client.integration.ShaderMod;
|
2022-11-09 23:58:56 +00:00
|
|
|
import dan200.computercraft.client.render.RenderTypes;
|
2022-04-26 17:25:49 +00:00
|
|
|
import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer;
|
2022-04-26 15:27:24 +00:00
|
|
|
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
2022-11-09 23:58:56 +00:00
|
|
|
import dan200.computercraft.client.render.vbo.DirectBuffers;
|
|
|
|
import dan200.computercraft.client.render.vbo.DirectVertexBuffer;
|
2022-11-09 18:58:31 +00:00
|
|
|
import dan200.computercraft.core.terminal.Terminal;
|
2022-11-09 20:10:24 +00:00
|
|
|
import dan200.computercraft.shared.config.Config;
|
2018-02-14 21:21:00 +00:00
|
|
|
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
2022-11-09 23:58:56 +00:00
|
|
|
import dan200.computercraft.shared.peripheral.monitor.MonitorBlockEntity;
|
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.
2020-04-21 09:43:26 +00:00
|
|
|
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
|
2017-05-01 13:32:39 +00:00
|
|
|
import dan200.computercraft.shared.util.DirectionUtil;
|
2021-08-03 20:46:53 +00:00
|
|
|
import net.minecraft.client.renderer.MultiBufferSource;
|
|
|
|
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
|
|
|
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
2024-01-31 20:55:14 +00:00
|
|
|
import net.minecraft.world.phys.AABB;
|
2022-12-08 19:45:02 +00:00
|
|
|
import org.joml.Matrix3f;
|
|
|
|
import org.joml.Matrix4f;
|
2017-05-01 13:32:39 +00:00
|
|
|
import org.lwjgl.opengl.GL11;
|
2020-05-13 13:36:39 +00:00
|
|
|
import org.lwjgl.opengl.GL20;
|
Add a monitor renderer using TBOs (#443)
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! ♥
2020-05-05 12:05:23 +00:00
|
|
|
import org.lwjgl.opengl.GL31;
|
2020-01-22 11:14:30 +00:00
|
|
|
|
2022-11-09 18:58:31 +00:00
|
|
|
import javax.annotation.Nullable;
|
Add a monitor renderer using TBOs (#443)
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! ♥
2020-05-05 12:05:23 +00:00
|
|
|
import java.nio.ByteBuffer;
|
2022-07-30 11:04:28 +00:00
|
|
|
import java.util.function.Consumer;
|
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.
2020-04-21 09:43:26 +00:00
|
|
|
|
2022-04-26 18:14:37 +00:00
|
|
|
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_HEIGHT;
|
|
|
|
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_WIDTH;
|
2022-11-09 18:58:31 +00:00
|
|
|
import static dan200.computercraft.core.util.Nullability.assertNonNull;
|
2017-05-01 13:32:39 +00:00
|
|
|
|
2022-11-09 23:58:56 +00:00
|
|
|
public class MonitorBlockEntityRenderer implements BlockEntityRenderer<MonitorBlockEntity> {
|
2020-01-22 11:14:30 +00:00
|
|
|
/**
|
2022-11-09 23:58:56 +00:00
|
|
|
* {@link MonitorBlockEntity#RENDER_MARGIN}, but a tiny bit of additional padding to ensure that there is no space between
|
2020-01-22 11:14:30 +00:00
|
|
|
* the monitor frame and contents.
|
|
|
|
*/
|
2022-11-09 23:58:56 +00:00
|
|
|
private static final float MARGIN = (float) (MonitorBlockEntity.RENDER_MARGIN * 1.1);
|
2022-07-30 11:04:28 +00:00
|
|
|
|
2022-12-08 19:45:02 +00:00
|
|
|
private static final Matrix3f IDENTITY_NORMAL = new Matrix3f().identity();
|
2022-07-30 11:04:28 +00:00
|
|
|
|
2022-11-09 18:58:31 +00:00
|
|
|
private static @Nullable ByteBuffer backingBuffer;
|
2020-01-22 11:14:30 +00:00
|
|
|
|
2023-02-17 08:42:29 +00:00
|
|
|
private static long lastFrame = -1;
|
|
|
|
|
2022-11-09 23:58:56 +00:00
|
|
|
public MonitorBlockEntityRenderer(BlockEntityRendererProvider.Context context) {
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
|
2020-01-22 11:14:30 +00:00
|
|
|
@Override
|
2022-11-09 23:58:56 +00:00
|
|
|
public void render(MonitorBlockEntity monitor, float partialTicks, PoseStack transform, MultiBufferSource bufferSource, int lightmapCoord, int overlayLight) {
|
2017-05-01 13:32:39 +00:00
|
|
|
// Render from the origin monitor
|
Don't cache the client monitor
When rendering non-origin monitors, we would fetch the origin monitor,
read its client state, and then cache that on the current monitor to
avoid repeated lookups.
However, if the origin monitor is unloaded/removed on the client, and
then loaded agin, this cache will be not be invalidated, causing us to
render both the old and new monitor!
I think the correct thing to do here is cache the origin monitor. This
allows us to check when the origin monitor has been removed, and
invalidate the cache if needed.
However, I'm wary of any other edge cases here, so for now we do
something much simpler, and remove the cache entirely. This does mean
that monitors now need to perform extra block entity lookups, but the
performance cost doesn't appear to be too bad.
Fixes #1741
2024-03-10 10:57:56 +00:00
|
|
|
var originTerminal = monitor.getOriginClientMonitor();
|
2018-02-14 21:21:00 +00:00
|
|
|
if (originTerminal == null) return;
|
Don't cache the client monitor
When rendering non-origin monitors, we would fetch the origin monitor,
read its client state, and then cache that on the current monitor to
avoid repeated lookups.
However, if the origin monitor is unloaded/removed on the client, and
then loaded agin, this cache will be not be invalidated, causing us to
render both the old and new monitor!
I think the correct thing to do here is cache the origin monitor. This
allows us to check when the origin monitor has been removed, and
invalidate the cache if needed.
However, I'm wary of any other edge cases here, so for now we do
something much simpler, and remove the cache entirely. This does mean
that monitors now need to perform extra block entity lookups, but the
performance cost doesn't appear to be too bad.
Fixes #1741
2024-03-10 10:57:56 +00:00
|
|
|
|
2018-02-14 21:21:00 +00:00
|
|
|
var origin = originTerminal.getOrigin();
|
2022-11-09 19:52:29 +00:00
|
|
|
var renderState = originTerminal.getRenderState(MonitorRenderState::new);
|
2021-01-09 19:22:58 +00:00
|
|
|
var monitorPos = monitor.getBlockPos();
|
2017-05-01 13:32:39 +00:00
|
|
|
|
2018-03-29 11:31:20 +00:00
|
|
|
// Ensure each monitor terminal is rendered only once. We allow rendering a specific tile
|
2018-12-23 17:46:58 +00:00
|
|
|
// multiple times in a single frame to ensure compatibility with shaders which may run a
|
2018-03-29 11:31:20 +00:00
|
|
|
// pass multiple times.
|
2019-01-12 16:27:40 +00:00
|
|
|
var renderFrame = FrameInfo.getRenderFrame();
|
2022-11-09 19:52:29 +00:00
|
|
|
if (renderState.lastRenderFrame == renderFrame && !monitorPos.equals(renderState.lastRenderPos)) {
|
2017-05-01 13:32:39 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-02-17 08:42:29 +00:00
|
|
|
lastFrame = renderFrame;
|
2022-11-09 19:52:29 +00:00
|
|
|
renderState.lastRenderFrame = renderFrame;
|
|
|
|
renderState.lastRenderPos = monitorPos;
|
2018-03-29 11:31:20 +00:00
|
|
|
|
2021-01-09 19:22:58 +00:00
|
|
|
var originPos = origin.getBlockPos();
|
2017-05-01 13:32:39 +00:00
|
|
|
|
|
|
|
// Determine orientation
|
2019-06-08 12:36:31 +00:00
|
|
|
var dir = origin.getDirection();
|
|
|
|
var front = origin.getFront();
|
2021-01-09 19:22:58 +00:00
|
|
|
var yaw = dir.toYRot();
|
2017-05-01 13:32:39 +00:00
|
|
|
var pitch = DirectionUtil.toPitchAngle(front);
|
|
|
|
|
2020-01-22 11:14:30 +00:00
|
|
|
// Setup initial transform
|
2021-01-09 19:22:58 +00:00
|
|
|
transform.pushPose();
|
2020-01-22 11:14:30 +00:00
|
|
|
transform.translate(
|
|
|
|
originPos.getX() - monitorPos.getX() + 0.5,
|
|
|
|
originPos.getY() - monitorPos.getY() + 0.5,
|
|
|
|
originPos.getZ() - monitorPos.getZ() + 0.5
|
|
|
|
);
|
|
|
|
|
2022-12-08 19:45:02 +00:00
|
|
|
transform.mulPose(Axis.YN.rotationDegrees(yaw));
|
|
|
|
transform.mulPose(Axis.XP.rotationDegrees(pitch));
|
2020-01-22 11:14:30 +00:00
|
|
|
transform.translate(
|
2022-11-09 23:58:56 +00:00
|
|
|
-0.5 + MonitorBlockEntity.RENDER_BORDER + MonitorBlockEntity.RENDER_MARGIN,
|
|
|
|
origin.getHeight() - 0.5 - (MonitorBlockEntity.RENDER_BORDER + MonitorBlockEntity.RENDER_MARGIN) + 0,
|
2020-01-22 11:14:30 +00:00
|
|
|
0.5
|
|
|
|
);
|
2022-11-09 23:58:56 +00:00
|
|
|
var xSize = origin.getWidth() - 2.0 * (MonitorBlockEntity.RENDER_MARGIN + MonitorBlockEntity.RENDER_BORDER);
|
|
|
|
var ySize = origin.getHeight() - 2.0 * (MonitorBlockEntity.RENDER_MARGIN + MonitorBlockEntity.RENDER_BORDER);
|
2020-01-22 11:14:30 +00:00
|
|
|
|
|
|
|
// Draw the contents
|
|
|
|
var terminal = originTerminal.getTerminal();
|
2022-11-09 21:05:27 +00:00
|
|
|
if (terminal != null && !ShaderMod.get().isRenderingShadowPass()) {
|
2020-01-22 11:14:30 +00:00
|
|
|
// Draw a terminal
|
2020-05-13 13:36:39 +00:00
|
|
|
int width = terminal.getWidth(), height = terminal.getHeight();
|
|
|
|
int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT;
|
|
|
|
var xScale = xSize / pixelWidth;
|
|
|
|
var yScale = ySize / pixelHeight;
|
2021-01-09 19:22:58 +00:00
|
|
|
transform.pushPose();
|
2020-01-22 11:14:30 +00:00
|
|
|
transform.scale((float) xScale, (float) -yScale, 1.0f);
|
2017-05-01 13:32:39 +00:00
|
|
|
|
2021-01-09 19:22:58 +00:00
|
|
|
var matrix = transform.last().pose();
|
2017-05-01 13:32:39 +00:00
|
|
|
|
2022-11-09 19:52:29 +00:00
|
|
|
renderTerminal(matrix, originTerminal, renderState, terminal, (float) (MARGIN / xScale), (float) (MARGIN / yScale));
|
2017-05-04 21:38:24 +00:00
|
|
|
|
2021-01-09 19:22:58 +00:00
|
|
|
transform.popPose();
|
2020-01-22 11:14:30 +00:00
|
|
|
} else {
|
|
|
|
FixedWidthFontRenderer.drawEmptyTerminal(
|
2022-07-30 11:04:28 +00:00
|
|
|
FixedWidthFontRenderer.toVertexConsumer(transform, bufferSource.getBuffer(RenderTypes.TERMINAL)),
|
2020-01-22 11:14:30 +00:00
|
|
|
-MARGIN, MARGIN,
|
|
|
|
(float) (xSize + 2 * MARGIN), (float) -(ySize + MARGIN * 2)
|
|
|
|
);
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
2020-01-22 11:14:30 +00:00
|
|
|
|
2021-01-09 19:22:58 +00:00
|
|
|
transform.popPose();
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
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.
2020-04-21 09:43:26 +00:00
|
|
|
|
2022-11-09 19:52:29 +00:00
|
|
|
private static void renderTerminal(
|
|
|
|
Matrix4f matrix, ClientMonitor monitor, MonitorRenderState renderState, Terminal terminal, float xMargin, float yMargin
|
|
|
|
) {
|
Don't render cursors separately
- For TBOs, we now pass cursor position, colour and blink state as
variables to the shader, and use them to overlay the cursor texture
in the right place.
As we no longer need to render the cursor, we can skip the depth
buffer, meaning we have to do one fewer upload+draw cycle.
- For VBOs, we bake the cursor into the main VBO, and switch between
rendering n and n+1 quads. We still need the depth blocker, but can
save one upload+draw cycle when the cursor is visible.
This saves significant time on the TBO renderer - somewhere between 4
and 7ms/frame, which bumps us up from 35 to 47fps on my test world (480
full-sized monitors, changing every tick). [Taken on 1.18, but should be
similar on 1.16]
2022-04-26 19:01:45 +00:00
|
|
|
int width = terminal.getWidth(), height = terminal.getHeight();
|
|
|
|
int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT;
|
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.
2020-04-21 09:43:26 +00:00
|
|
|
|
2022-11-09 19:52:29 +00:00
|
|
|
var renderType = currentRenderer();
|
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.
2020-04-21 09:43:26 +00:00
|
|
|
var redraw = monitor.pollTerminalChanged();
|
2022-11-09 19:52:29 +00:00
|
|
|
if (renderState.createBuffer(renderType)) redraw = true;
|
2022-11-03 23:43:14 +00:00
|
|
|
|
2020-05-13 13:36:39 +00:00
|
|
|
switch (renderType) {
|
Add a monitor renderer using TBOs (#443)
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! ♥
2020-05-05 12:05:23 +00:00
|
|
|
case TBO -> {
|
|
|
|
if (redraw) {
|
2022-04-26 21:17:17 +00:00
|
|
|
var terminalBuffer = getBuffer(width * height * 3);
|
2022-04-26 18:14:37 +00:00
|
|
|
MonitorTextureBufferShader.setTerminalData(terminalBuffer, terminal);
|
2022-11-09 19:52:29 +00:00
|
|
|
DirectBuffers.setBufferData(GL31.GL_TEXTURE_BUFFER, renderState.tboBuffer, terminalBuffer, GL20.GL_STATIC_DRAW);
|
2022-11-03 23:43:14 +00:00
|
|
|
|
2022-04-26 21:17:17 +00:00
|
|
|
var uniformBuffer = getBuffer(MonitorTextureBufferShader.UNIFORM_SIZE);
|
2022-10-21 17:26:57 +00:00
|
|
|
MonitorTextureBufferShader.setUniformData(uniformBuffer, terminal);
|
2022-11-09 19:52:29 +00:00
|
|
|
DirectBuffers.setBufferData(GL31.GL_UNIFORM_BUFFER, renderState.tboUniform, uniformBuffer, GL20.GL_STATIC_DRAW);
|
Add a monitor renderer using TBOs (#443)
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! ♥
2020-05-05 12:05:23 +00:00
|
|
|
}
|
|
|
|
|
2020-05-13 13:36:39 +00:00
|
|
|
// Nobody knows what they're doing!
|
2021-08-03 20:46:53 +00:00
|
|
|
var active = GlStateManager._getActiveTexture();
|
|
|
|
RenderSystem.activeTexture(MonitorTextureBufferShader.TEXTURE_INDEX);
|
2022-11-09 19:52:29 +00:00
|
|
|
GL11.glBindTexture(GL31.GL_TEXTURE_BUFFER, renderState.tboTexture);
|
2021-08-03 20:46:53 +00:00
|
|
|
RenderSystem.activeTexture(active);
|
2022-11-03 23:43:14 +00:00
|
|
|
|
2021-08-03 20:46:53 +00:00
|
|
|
var shader = RenderTypes.getMonitorTextureBufferShader();
|
2022-11-09 19:52:29 +00:00
|
|
|
shader.setupUniform(renderState.tboUniform);
|
2022-11-03 23:43:14 +00:00
|
|
|
|
2022-07-16 21:07:23 +00:00
|
|
|
var buffer = Tesselator.getInstance().getBuilder();
|
|
|
|
buffer.begin(RenderTypes.MONITOR_TBO.mode(), RenderTypes.MONITOR_TBO.format());
|
2021-08-03 20:46:53 +00:00
|
|
|
tboVertex(buffer, matrix, -xMargin, -yMargin);
|
|
|
|
tboVertex(buffer, matrix, -xMargin, pixelHeight + yMargin);
|
|
|
|
tboVertex(buffer, matrix, pixelWidth + xMargin, -yMargin);
|
|
|
|
tboVertex(buffer, matrix, pixelWidth + xMargin, pixelHeight + yMargin);
|
2023-06-08 08:48:37 +00:00
|
|
|
RenderTypes.MONITOR_TBO.end(buffer, VertexSorting.DISTANCE_TO_ORIGIN);
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
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.
2020-04-21 09:43:26 +00:00
|
|
|
case VBO -> {
|
2022-11-09 19:52:29 +00:00
|
|
|
var backgroundBuffer = assertNonNull(renderState.backgroundBuffer);
|
|
|
|
var foregroundBuffer = assertNonNull(renderState.foregroundBuffer);
|
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.
2020-04-21 09:43:26 +00:00
|
|
|
if (redraw) {
|
2022-07-30 11:04:28 +00:00
|
|
|
var size = DirectFixedWidthFontRenderer.getVertexCount(terminal);
|
2022-04-26 17:25:49 +00:00
|
|
|
|
2022-07-30 11:04:28 +00:00
|
|
|
// In an ideal world we could upload these both into one buffer. However, we can't render VBOs with
|
|
|
|
// and starting and ending offset, and so need to use two buffers instead.
|
2022-04-26 17:25:49 +00:00
|
|
|
|
2022-07-30 11:04:28 +00:00
|
|
|
renderToBuffer(backgroundBuffer, size, sink ->
|
2022-10-25 21:36:21 +00:00
|
|
|
DirectFixedWidthFontRenderer.drawTerminalBackground(sink, 0, 0, terminal, yMargin, yMargin, xMargin, xMargin));
|
Don't render cursors separately
- For TBOs, we now pass cursor position, colour and blink state as
variables to the shader, and use them to overlay the cursor texture
in the right place.
As we no longer need to render the cursor, we can skip the depth
buffer, meaning we have to do one fewer upload+draw cycle.
- For VBOs, we bake the cursor into the main VBO, and switch between
rendering n and n+1 quads. We still need the depth blocker, but can
save one upload+draw cycle when the cursor is visible.
This saves significant time on the TBO renderer - somewhere between 4
and 7ms/frame, which bumps us up from 35 to 47fps on my test world (480
full-sized monitors, changing every tick). [Taken on 1.18, but should be
similar on 1.16]
2022-04-26 19:01:45 +00:00
|
|
|
|
2022-07-30 11:04:28 +00:00
|
|
|
renderToBuffer(foregroundBuffer, size, sink -> {
|
2022-10-25 21:36:21 +00:00
|
|
|
DirectFixedWidthFontRenderer.drawTerminalForeground(sink, 0, 0, terminal);
|
2022-07-30 11:04:28 +00:00
|
|
|
// If the cursor is visible, we append it to the end of our buffer. When rendering, we can either
|
|
|
|
// render n or n+1 quads and so toggle the cursor on and off.
|
2022-10-25 21:36:21 +00:00
|
|
|
DirectFixedWidthFontRenderer.drawCursor(sink, 0, 0, terminal);
|
2022-07-30 11:04:28 +00:00
|
|
|
});
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
|
2024-04-25 19:17:43 +00:00
|
|
|
// Our VBO renders coordinates in monitor-space rather than world space. A full sized monitor (8x6) will
|
|
|
|
// use positions from (0, 0) to (164*FONT_WIDTH, 81*FONT_HEIGHT) = (984, 729). This is far outside the
|
|
|
|
// normal render distance (~200), and the edges of the monitor fade out due to fog.
|
|
|
|
// There's not really a good way around this, at least without using a custom render type (which the VBO
|
|
|
|
// renderer is trying to avoid!). Instead, we just disable fog entirely by setting the fog start to an
|
|
|
|
// absurdly high value.
|
|
|
|
var oldFogStart = RenderSystem.getShaderFogStart();
|
|
|
|
RenderSystem.setShaderFogStart(1e4f);
|
2022-07-30 11:04:28 +00:00
|
|
|
|
|
|
|
RenderTypes.TERMINAL.setupRenderState();
|
|
|
|
|
2024-04-25 19:17:43 +00:00
|
|
|
// Compose the existing model view matrix with our transformation matrix.
|
|
|
|
var modelView = new Matrix4f(RenderSystem.getModelViewMatrix()).mul(matrix);
|
|
|
|
|
2022-07-30 11:04:28 +00:00
|
|
|
// Render background geometry
|
2022-10-16 08:50:17 +00:00
|
|
|
backgroundBuffer.bind();
|
2024-04-25 19:17:43 +00:00
|
|
|
backgroundBuffer.drawWithShader(modelView, RenderSystem.getProjectionMatrix(), RenderTypes.getTerminalShader());
|
2022-07-30 11:04:28 +00:00
|
|
|
|
|
|
|
// Render foreground geometry with glPolygonOffset enabled.
|
2022-12-15 21:24:38 +00:00
|
|
|
RenderSystem.polygonOffset(-1.0f, -10.0f);
|
|
|
|
RenderSystem.enablePolygonOffset();
|
2022-10-16 08:50:17 +00:00
|
|
|
|
|
|
|
foregroundBuffer.bind();
|
2022-07-30 11:04:28 +00:00
|
|
|
foregroundBuffer.drawWithShader(
|
2024-04-25 19:17:43 +00:00
|
|
|
modelView, RenderSystem.getProjectionMatrix(), RenderTypes.getTerminalShader(),
|
2022-04-26 21:17:17 +00:00
|
|
|
// As mentioned in the above comment, render the extra cursor quad if it is visible this frame. Each
|
|
|
|
// // quad has an index count of 6.
|
2022-07-30 11:04:28 +00:00
|
|
|
FixedWidthFontRenderer.isCursorVisible(terminal) && FrameInfo.getGlobalCursorBlink()
|
|
|
|
? foregroundBuffer.getIndexCount() + 6 : foregroundBuffer.getIndexCount()
|
Don't render cursors separately
- For TBOs, we now pass cursor position, colour and blink state as
variables to the shader, and use them to overlay the cursor texture
in the right place.
As we no longer need to render the cursor, we can skip the depth
buffer, meaning we have to do one fewer upload+draw cycle.
- For VBOs, we bake the cursor into the main VBO, and switch between
rendering n and n+1 quads. We still need the depth blocker, but can
save one upload+draw cycle when the cursor is visible.
This saves significant time on the TBO renderer - somewhere between 4
and 7ms/frame, which bumps us up from 35 to 47fps on my test world (480
full-sized monitors, changing every tick). [Taken on 1.18, but should be
similar on 1.16]
2022-04-26 19:01:45 +00:00
|
|
|
);
|
|
|
|
|
2022-07-30 11:04:28 +00:00
|
|
|
// Clear state
|
2022-12-15 21:24:38 +00:00
|
|
|
RenderSystem.polygonOffset(0.0f, -0.0f);
|
|
|
|
RenderSystem.disablePolygonOffset();
|
2022-07-30 11:04:28 +00:00
|
|
|
RenderTypes.TERMINAL.clearRenderState();
|
2022-10-16 08:50:17 +00:00
|
|
|
VertexBuffer.unbind();
|
2022-07-30 11:04:28 +00:00
|
|
|
|
2024-04-25 19:17:43 +00:00
|
|
|
RenderSystem.setShaderFogStart(oldFogStart);
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
2022-11-10 15:48:26 +00:00
|
|
|
case BEST -> throw new IllegalStateException("Impossible: Should never use BEST renderer");
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
}
|
2021-08-03 20:46:53 +00:00
|
|
|
|
2022-07-30 11:04:28 +00:00
|
|
|
private static void renderToBuffer(DirectVertexBuffer vbo, int size, Consumer<DirectFixedWidthFontRenderer.QuadEmitter> draw) {
|
2022-11-09 23:58:56 +00:00
|
|
|
var sink = ShaderMod.get().getQuadEmitter(size, MonitorBlockEntityRenderer::getBuffer);
|
2022-07-30 11:04:28 +00:00
|
|
|
var buffer = sink.buffer();
|
|
|
|
|
|
|
|
draw.accept(sink);
|
|
|
|
buffer.flip();
|
|
|
|
vbo.upload(buffer.limit() / sink.format().getVertexSize(), RenderTypes.TERMINAL.mode(), sink.format(), buffer);
|
|
|
|
}
|
|
|
|
|
2021-08-03 20:46:53 +00:00
|
|
|
private static void tboVertex(VertexConsumer builder, Matrix4f matrix, float x, float y) {
|
|
|
|
// We encode position in the UV, as that's not transformed by the matrix.
|
|
|
|
builder.vertex(matrix, x, y, 0).uv(x, y).endVertex();
|
|
|
|
}
|
|
|
|
|
Cleanup and optimise terminal rendering (#1057)
- Remove the POSITION_COLOR render type. Instead we just render a
background terminal quad as the pocket computer light - it's a little
(lot?) more cheaty, but saves having to create a render type.
- Use the existing position_color_tex shader instead of our copy. I
looked at using RenderType.text, but had a bunch of problems with GUI
terminals. Its possible we can fix it, but didn't want to spend too
much time on it.
- Remove some methods from FixedWidthFontRenderer, inlining them into
the call site.
- Switch back to using GL_QUADS rather than GL_TRIANGLES. I know Lig
will shout at me for this, but the rest of MC uses QUADS, so I don't
think best practice really matters here.
- Fix the TBO backend monitor not rendering monitors with fog.
Unfortunately we can't easily do this to the VBO one without writing
a custom shader (which defeats the whole point of the VBO backend!),
as the distance calculation of most render types expect an
already-transformed position (camera-relative I think!) while we pass
a world-relative one.
- When rendering to a VBO we push vertices to a ByteBuffer directly,
rather than going through MC's VertexConsumer system. This removes
the overhead which comes with VertexConsumer, significantly improving
performance.
- Pre-convert palette colours to bytes, storing both the coloured and
greyscale versions as a byte array. This allows us to remove the
multiple casts and conversions (double -> float -> (greyscale) ->
byte), offering noticeable performance improvements (multiple ms per
frame).
We're using a byte[] here rather than a record of three bytes as
notionally it provides better performance when writing to a
ByteBuffer directly compared to calling .put() four times. [^1]
- Memorize getRenderBoundingBox. This was taking about 5% of the total
time on the render thread[^2], so worth doing.
I don't actually think the allocation is the heavy thing here -
VisualVM says it's toWorldPos being slow. I'm not sure why - possibly
just all the block property lookups? [^2]
Note that none of these changes improve compatibility with Optifine.
Right now there's some serious issues where monitors are writing _over_
blocks in front of them. To fix this, we probably need to remove the
depth blocker and just render characters with a z offset. Will do that
in a separate commit, as I need to evaluate how well that change will
work first.
The main advantage of this commit is the improved performance. In my
stress test with 120 monitors updating every tick, I'm getting 10-20fps
[^3] (still much worse than TBOs, which manages a solid 60-100).
In practice, we'll actually be much better than this. Our network
bandwidth limits means only 40 change in a single tick - and so FPS is
much more reasonable (+60fps).
[^1]: In general, put(byte[]) is faster than put(byte) multiple times.
Just not clear if this is true when dealing with a small (and loop
unrolled) number of bytes.
[^2]: To be clear, this is with 120 monitors and no other block entities
with custom renderers. so not really representative.
[^3]: I wish I could provide a narrower range, but it varies so much
between me restarting the game. Makes it impossible to benchmark
anything!
2022-04-02 09:54:03 +00:00
|
|
|
private static ByteBuffer getBuffer(int capacity) {
|
|
|
|
var buffer = backingBuffer;
|
|
|
|
if (buffer == null || buffer.capacity() < capacity) {
|
2022-04-26 21:17:17 +00:00
|
|
|
buffer = backingBuffer = buffer == null ? MemoryTracker.create(capacity) : MemoryTracker.resize(buffer, capacity);
|
Cleanup and optimise terminal rendering (#1057)
- Remove the POSITION_COLOR render type. Instead we just render a
background terminal quad as the pocket computer light - it's a little
(lot?) more cheaty, but saves having to create a render type.
- Use the existing position_color_tex shader instead of our copy. I
looked at using RenderType.text, but had a bunch of problems with GUI
terminals. Its possible we can fix it, but didn't want to spend too
much time on it.
- Remove some methods from FixedWidthFontRenderer, inlining them into
the call site.
- Switch back to using GL_QUADS rather than GL_TRIANGLES. I know Lig
will shout at me for this, but the rest of MC uses QUADS, so I don't
think best practice really matters here.
- Fix the TBO backend monitor not rendering monitors with fog.
Unfortunately we can't easily do this to the VBO one without writing
a custom shader (which defeats the whole point of the VBO backend!),
as the distance calculation of most render types expect an
already-transformed position (camera-relative I think!) while we pass
a world-relative one.
- When rendering to a VBO we push vertices to a ByteBuffer directly,
rather than going through MC's VertexConsumer system. This removes
the overhead which comes with VertexConsumer, significantly improving
performance.
- Pre-convert palette colours to bytes, storing both the coloured and
greyscale versions as a byte array. This allows us to remove the
multiple casts and conversions (double -> float -> (greyscale) ->
byte), offering noticeable performance improvements (multiple ms per
frame).
We're using a byte[] here rather than a record of three bytes as
notionally it provides better performance when writing to a
ByteBuffer directly compared to calling .put() four times. [^1]
- Memorize getRenderBoundingBox. This was taking about 5% of the total
time on the render thread[^2], so worth doing.
I don't actually think the allocation is the heavy thing here -
VisualVM says it's toWorldPos being slow. I'm not sure why - possibly
just all the block property lookups? [^2]
Note that none of these changes improve compatibility with Optifine.
Right now there's some serious issues where monitors are writing _over_
blocks in front of them. To fix this, we probably need to remove the
depth blocker and just render characters with a z offset. Will do that
in a separate commit, as I need to evaluate how well that change will
work first.
The main advantage of this commit is the improved performance. In my
stress test with 120 monitors updating every tick, I'm getting 10-20fps
[^3] (still much worse than TBOs, which manages a solid 60-100).
In practice, we'll actually be much better than this. Our network
bandwidth limits means only 40 change in a single tick - and so FPS is
much more reasonable (+60fps).
[^1]: In general, put(byte[]) is faster than put(byte) multiple times.
Just not clear if this is true when dealing with a small (and loop
unrolled) number of bytes.
[^2]: To be clear, this is with 120 monitors and no other block entities
with custom renderers. so not really representative.
[^3]: I wish I could provide a narrower range, but it varies so much
between me restarting the game. Makes it impossible to benchmark
anything!
2022-04-02 09:54:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
buffer.clear();
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
2021-08-03 20:46:53 +00:00
|
|
|
@Override
|
|
|
|
public int getViewDistance() {
|
2022-11-09 20:10:24 +00:00
|
|
|
return Config.monitorDistance;
|
2021-08-03 20:46:53 +00:00
|
|
|
}
|
2022-11-09 19:52:29 +00:00
|
|
|
|
2024-01-31 20:55:14 +00:00
|
|
|
@ForgeOverride
|
|
|
|
public AABB getRenderBoundingBox(MonitorBlockEntity monitor) {
|
|
|
|
return monitor.getRenderBoundingBox();
|
|
|
|
}
|
|
|
|
|
2023-02-17 08:42:29 +00:00
|
|
|
/**
|
|
|
|
* Determine if any monitors were rendered this frame.
|
|
|
|
*
|
|
|
|
* @return Whether any monitors were rendered.
|
|
|
|
*/
|
|
|
|
public static boolean hasRenderedThisFrame() {
|
|
|
|
return FrameInfo.getRenderFrame() == lastFrame;
|
|
|
|
}
|
2022-11-09 19:52:29 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the current renderer to use.
|
|
|
|
*
|
|
|
|
* @return The current renderer. Will not return {@link MonitorRenderer#BEST}.
|
|
|
|
*/
|
|
|
|
public static MonitorRenderer currentRenderer() {
|
2022-11-09 20:10:24 +00:00
|
|
|
var current = Config.monitorRenderer;
|
|
|
|
if (current == MonitorRenderer.BEST) current = Config.monitorRenderer = bestRenderer();
|
2022-11-09 19:52:29 +00:00
|
|
|
return current;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static MonitorRenderer bestRenderer() {
|
2023-02-17 08:42:29 +00:00
|
|
|
return MonitorRenderer.VBO;
|
2022-11-09 19:52:29 +00:00
|
|
|
}
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|