2023-03-15 21:52:13 +00:00
|
|
|
// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: LicenseRef-CCPL
|
|
|
|
|
2018-07-06 22:35:01 +00:00
|
|
|
package dan200.computercraft.client.render;
|
|
|
|
|
2022-07-30 11:04:28 +00:00
|
|
|
import com.mojang.blaze3d.vertex.PoseStack;
|
2021-08-03 20:46:53 +00:00
|
|
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
2022-04-26 15:27:24 +00:00
|
|
|
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
2022-11-04 22:31:56 +00:00
|
|
|
import dan200.computercraft.core.terminal.Palette;
|
2022-11-06 18:27:21 +00:00
|
|
|
import dan200.computercraft.core.terminal.TextBuffer;
|
2024-04-25 20:32:48 +00:00
|
|
|
import dan200.computercraft.shared.media.items.PrintoutData;
|
2021-08-03 20:46:53 +00:00
|
|
|
import net.minecraft.client.renderer.MultiBufferSource;
|
2022-12-08 19:45:02 +00:00
|
|
|
import org.joml.Matrix4f;
|
2018-07-06 22:35:01 +00:00
|
|
|
|
2024-04-25 20:32:48 +00:00
|
|
|
import java.util.List;
|
|
|
|
|
2022-04-26 15:27:24 +00:00
|
|
|
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_HEIGHT;
|
2024-04-25 20:32:48 +00:00
|
|
|
import static dan200.computercraft.shared.media.items.PrintoutData.LINES_PER_PAGE;
|
2018-07-06 22:35:01 +00:00
|
|
|
|
2023-06-02 20:47:52 +00:00
|
|
|
/**
|
|
|
|
* Renders printed pages or books, either for a GUI ({@link dan200.computercraft.client.gui.PrintoutScreen}) or
|
|
|
|
* {@linkplain PrintoutItemRenderer in-hand/item frame printouts}.
|
|
|
|
*/
|
2019-03-29 21:21:39 +00:00
|
|
|
public final class PrintoutRenderer {
|
2020-01-22 11:14:30 +00:00
|
|
|
private static final float BG_SIZE = 256.0f;
|
2018-07-06 22:35:01 +00:00
|
|
|
|
|
|
|
/**
|
2019-10-27 15:16:47 +00:00
|
|
|
* Width of a page.
|
2018-07-06 22:35:01 +00:00
|
|
|
*/
|
|
|
|
public static final int X_SIZE = 172;
|
|
|
|
|
|
|
|
/**
|
2019-10-27 15:16:47 +00:00
|
|
|
* Height of a page.
|
2018-07-06 22:35:01 +00:00
|
|
|
*/
|
|
|
|
public static final int Y_SIZE = 209;
|
|
|
|
|
|
|
|
/**
|
2019-10-27 15:16:47 +00:00
|
|
|
* Padding between the left and right of a page and the text.
|
2018-07-06 22:35:01 +00:00
|
|
|
*/
|
|
|
|
public static final int X_TEXT_MARGIN = 13;
|
|
|
|
|
|
|
|
/**
|
2019-10-27 15:16:47 +00:00
|
|
|
* Padding between the top and bottom of a page and the text.
|
2018-07-06 22:35:01 +00:00
|
|
|
*/
|
|
|
|
public static final int Y_TEXT_MARGIN = 11;
|
|
|
|
|
|
|
|
/**
|
2019-10-27 15:16:47 +00:00
|
|
|
* Width of the extra page texture.
|
2018-07-06 22:35:01 +00:00
|
|
|
*/
|
|
|
|
private static final int X_FOLD_SIZE = 12;
|
|
|
|
|
|
|
|
/**
|
2019-10-27 15:16:47 +00:00
|
|
|
* Size of the leather cover.
|
2018-07-06 22:35:01 +00:00
|
|
|
*/
|
|
|
|
public static final int COVER_SIZE = 12;
|
|
|
|
|
|
|
|
private static final int COVER_Y = Y_SIZE;
|
|
|
|
private static final int COVER_X = X_SIZE + 4 * X_FOLD_SIZE;
|
|
|
|
|
2019-03-29 21:21:39 +00:00
|
|
|
private PrintoutRenderer() {
|
|
|
|
}
|
|
|
|
|
2022-07-30 11:04:28 +00:00
|
|
|
public static void drawText(PoseStack transform, MultiBufferSource bufferSource, int x, int y, int start, int light, TextBuffer[] text, TextBuffer[] colours) {
|
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
|
|
|
var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_TEXT);
|
|
|
|
var emitter = FixedWidthFontRenderer.toVertexConsumer(transform, buffer);
|
2018-12-30 16:14:07 +00:00
|
|
|
for (var line = 0; line < LINES_PER_PAGE && line < text.length; line++) {
|
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
|
|
|
FixedWidthFontRenderer.drawString(emitter,
|
2022-04-26 16:56:22 +00:00
|
|
|
x, y + line * FONT_HEIGHT, text[start + line], colours[start + line],
|
2022-10-21 17:26:57 +00:00
|
|
|
Palette.DEFAULT, light
|
2020-01-22 11:14:30 +00:00
|
|
|
);
|
2018-07-06 22:35:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-25 20:32:48 +00:00
|
|
|
public static void drawText(PoseStack transform, MultiBufferSource bufferSource, int x, int y, int start, int light, List<PrintoutData.Line> lines) {
|
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
|
|
|
var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_TEXT);
|
|
|
|
var emitter = FixedWidthFontRenderer.toVertexConsumer(transform, buffer);
|
2024-04-25 20:32:48 +00:00
|
|
|
for (var line = 0; line < LINES_PER_PAGE && line < lines.size(); line++) {
|
|
|
|
var lineContents = lines.get(start + line);
|
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
|
|
|
FixedWidthFontRenderer.drawString(emitter,
|
2020-01-30 10:07:47 +00:00
|
|
|
x, y + line * FONT_HEIGHT,
|
2024-04-25 20:32:48 +00:00
|
|
|
new TextBuffer(lineContents.text()), new TextBuffer(lineContents.foreground()),
|
2022-10-21 17:26:57 +00:00
|
|
|
Palette.DEFAULT, light
|
2020-01-30 10:07:47 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2018-07-06 22:35:01 +00:00
|
|
|
|
2022-07-30 11:04:28 +00:00
|
|
|
public static void drawBorder(PoseStack transform, MultiBufferSource bufferSource, float x, float y, float z, int page, int pages, boolean isBook, int light) {
|
|
|
|
var matrix = transform.last().pose();
|
2018-07-06 22:35:01 +00:00
|
|
|
var leftPages = page;
|
|
|
|
var rightPages = pages - page - 1;
|
|
|
|
|
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
|
|
|
var buffer = bufferSource.getBuffer(RenderTypes.PRINTOUT_BACKGROUND);
|
2020-01-30 10:07:47 +00:00
|
|
|
|
2018-07-06 22:35:01 +00:00
|
|
|
if (isBook) {
|
|
|
|
// Border
|
2020-01-30 10:07:47 +00:00
|
|
|
var offset = offsetAt(pages);
|
|
|
|
var left = x - 4 - offset;
|
|
|
|
var right = x + X_SIZE + offset - 4;
|
2018-07-06 22:35:01 +00:00
|
|
|
|
|
|
|
// Left and right border
|
2022-07-30 11:04:28 +00:00
|
|
|
drawTexture(matrix, buffer, left - 4, y - 8, z - 0.02f, COVER_X, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2, light);
|
|
|
|
drawTexture(matrix, buffer, right, y - 8, z - 0.02f, COVER_X + COVER_SIZE, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2, light);
|
2018-07-06 22:35:01 +00:00
|
|
|
|
|
|
|
// Draw centre panel (just stretched texture, sorry).
|
2022-07-30 11:04:28 +00:00
|
|
|
drawTexture(matrix, buffer,
|
2020-01-30 10:07:47 +00:00
|
|
|
x - offset, y, z - 0.02f, X_SIZE + offset * 2, Y_SIZE,
|
2021-09-19 14:49:31 +00:00
|
|
|
COVER_X + COVER_SIZE / 2.0f, COVER_SIZE, COVER_SIZE, Y_SIZE,
|
|
|
|
light
|
2018-07-06 22:35:01 +00:00
|
|
|
);
|
|
|
|
|
2020-01-30 10:07:47 +00:00
|
|
|
var borderX = left;
|
2018-07-06 22:35:01 +00:00
|
|
|
while (borderX < right) {
|
|
|
|
double thisWidth = Math.min(right - borderX, X_SIZE);
|
2022-07-30 11:04:28 +00:00
|
|
|
drawTexture(matrix, buffer, borderX, y - 8, z - 0.02f, 0, COVER_Y, (float) thisWidth, COVER_SIZE, light);
|
|
|
|
drawTexture(matrix, buffer, borderX, y + Y_SIZE - 4, z - 0.02f, 0, COVER_Y + COVER_SIZE, (float) thisWidth, COVER_SIZE, light);
|
2022-11-10 15:48:26 +00:00
|
|
|
borderX = (float) (borderX + thisWidth);
|
2018-07-06 22:35:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-20 23:36:46 +00:00
|
|
|
// Current page background: Z-offset is interleaved between the "zeroth" left/right page and the first
|
|
|
|
// left/right page, so that the "bold" border can be drawn over the edge where appropriate.
|
2022-07-30 11:04:28 +00:00
|
|
|
drawTexture(matrix, buffer, x, y, z - 1e-3f * 0.5f, X_FOLD_SIZE * 2, 0, X_SIZE, Y_SIZE, light);
|
2022-01-20 23:36:46 +00:00
|
|
|
|
|
|
|
// Left pages
|
2018-07-06 22:35:01 +00:00
|
|
|
for (var n = 0; n <= leftPages; n++) {
|
2022-07-30 11:04:28 +00:00
|
|
|
drawTexture(matrix, buffer,
|
2020-01-30 10:07:47 +00:00
|
|
|
x - offsetAt(n), y, z - 1e-3f * n,
|
2018-07-06 22:35:01 +00:00
|
|
|
// Use the left "bold" fold for the outermost page
|
|
|
|
n == leftPages ? 0 : X_FOLD_SIZE, 0,
|
2021-09-19 14:49:31 +00:00
|
|
|
X_FOLD_SIZE, Y_SIZE, light
|
2018-07-06 22:35:01 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-01-20 23:36:46 +00:00
|
|
|
// Right pages
|
2018-07-06 22:35:01 +00:00
|
|
|
for (var n = 0; n <= rightPages; n++) {
|
2022-07-30 11:04:28 +00:00
|
|
|
drawTexture(matrix, buffer,
|
2020-01-30 10:07:47 +00:00
|
|
|
x + (X_SIZE - X_FOLD_SIZE) + offsetAt(n), y, z - 1e-3f * n,
|
2018-07-06 22:35:01 +00:00
|
|
|
// Two folds, then the main page. Use the right "bold" fold for the outermost page.
|
|
|
|
X_FOLD_SIZE * 2 + X_SIZE + (n == rightPages ? X_FOLD_SIZE : 0), 0,
|
2021-09-19 14:49:31 +00:00
|
|
|
X_FOLD_SIZE, Y_SIZE, light
|
2018-07-06 22:35:01 +00:00
|
|
|
);
|
|
|
|
}
|
2020-01-30 10:07:47 +00:00
|
|
|
}
|
2018-07-06 22:35:01 +00:00
|
|
|
|
2021-09-19 14:49:31 +00:00
|
|
|
private static void drawTexture(Matrix4f matrix, 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);
|
2018-07-06 22:35:01 +00:00
|
|
|
}
|
|
|
|
|
2021-09-19 14:49:31 +00:00
|
|
|
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) {
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void vertex(VertexConsumer buffer, Matrix4f matrix, 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();
|
2018-07-06 22:35:01 +00:00
|
|
|
}
|
|
|
|
|
2020-01-30 10:07:47 +00:00
|
|
|
public static float offsetAt(int page) {
|
|
|
|
return (float) (32 * (1 - Math.pow(1.2, -page)));
|
2018-07-06 22:35:01 +00:00
|
|
|
}
|
|
|
|
}
|