Skip to content

Commit

Permalink
Add support for Iris's new text sink API
Browse files Browse the repository at this point in the history
  • Loading branch information
SquidDev committed Jun 7, 2022
1 parent c7f8e56 commit 3093de6
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 23 deletions.
8 changes: 7 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,13 @@ dependencies {

//modRuntimeOnly "me.shedaniel:RoughlyEnoughItems-api-fabric:6.0.254-alpha"
//modRuntimeOnly "me.shedaniel:RoughlyEnoughItems-fabric:6.0.254-alpha"
modCompileOnly 'maven.modrinth:iris:1.18.x-v1.2.4'

modCompileOnly "maven.modrinth:iris:1.18.x-v1.2.5"

// For running with Iris. Can be ignored most of the time.
// modCompileOnly "maven.modrinth:sodium:mc1.18.2-0.4.1"
// runtimeOnly "org.joml:joml:1.10.2"
// runtimeOnly "org.anarres:jcpp:1.4.14"

testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,28 +191,27 @@ private static void renderTerminal( @Nonnull MultiBufferSource bufferSource, Pos
var vbo = monitor.buffer;
if( redraw )
{
int vertexSize = RenderTypes.MONITOR.format().getVertexSize();

// Draw the background contents of the terminal into one vbo.
ByteBuffer buffer = getBuffer( DirectFixedWidthFontRenderer.getVertexCount( terminal ) * vertexSize );

DirectFixedWidthFontRenderer.drawTerminalBackground(
buffer, 0, 0, terminal, !monitor.isColour(), yMargin, yMargin, xMargin, xMargin
var sink = IrisCompat.INSTANCE.getVertexSink(
DirectFixedWidthFontRenderer.getVertexCount( terminal ),
TileEntityMonitorRenderer::getBuffer
);
int vertexSize = sink.getFormat().getVertexSize();
var buffer = sink.buffer();

DirectFixedWidthFontRenderer.drawTerminalBackground( sink, 0, 0, terminal, !monitor.isColour(), yMargin, yMargin, xMargin, xMargin );
int backgroundBytes = buffer.position();
DirectFixedWidthFontRenderer.drawTerminalForeground(
buffer, 0, 0, terminal, !monitor.isColour(), yMargin, yMargin, xMargin, xMargin
);
DirectFixedWidthFontRenderer.drawTerminalForeground( sink, 0, 0, terminal, !monitor.isColour(), yMargin, yMargin, xMargin, xMargin );
int termVertices = buffer.position() / vertexSize;
monitor.backgroundVertexCount = backgroundBytes / vertexSize;
monitor.foregroundVertexCount = termVertices - monitor.backgroundVertexCount;

// 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.
DirectFixedWidthFontRenderer.drawCursor( buffer, 0, 0, terminal, !monitor.isColour() );
DirectFixedWidthFontRenderer.drawCursor( sink, 0, 0, terminal, !monitor.isColour() );

buffer.flip();
vbo.upload( termVertices, RenderTypes.MONITOR.mode(), RenderTypes.MONITOR.format(), buffer );
vbo.upload( buffer.position() / vertexSize, RenderTypes.MONITOR.mode(), sink.getFormat(), buffer );
}

// TODO Figure out how to setup the inverse view rotation matrix properly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import com.mojang.blaze3d.platform.MemoryTracker;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.VertexFormat;
import dan200.computercraft.client.render.RenderTypes;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.util.Colour;
Expand All @@ -21,7 +23,7 @@
import static org.lwjgl.system.MemoryUtil.*;

/**
* An optimised copy of {@link FixedWidthFontRenderer} emitter emits directly to a {@link ByteBuffer} rather than
* An optimised copy of {@link FixedWidthFontRenderer} emitter emits directly to a {@link QuadSink} rather than
* emitting to {@link VertexConsumer}. This allows us to emit vertices very quickly, when using the VBO renderer.
*
* There are some limitations here:
Expand All @@ -43,7 +45,7 @@ private DirectFixedWidthFontRenderer()
{
}

private static void drawChar( ByteBuffer buffer, float x, float y, int index, byte[] colour )
private static void drawChar( QuadSink buffer, float x, float y, int index, byte[] colour )
{
// Short circuit to avoid the common case - the texture should be blank here after all.
if( index == '\0' || index == ' ' ) return;
Expand All @@ -60,14 +62,14 @@ private static void drawChar( ByteBuffer buffer, float x, float y, int index, by
);
}

private static void drawQuad( ByteBuffer emitter, float x, float y, float width, float height, Palette palette, boolean greyscale, char colourIndex )
private static void drawQuad( QuadSink emitter, float x, float y, float width, float height, Palette palette, boolean greyscale, char colourIndex )
{
byte[] colour = palette.getByteColour( getColour( colourIndex, Colour.BLACK ), greyscale );
quad( emitter, x, y, x + width, y + height, 0f, colour, BACKGROUND_START, BACKGROUND_START, BACKGROUND_END, BACKGROUND_END );
}

private static void drawBackground(
@Nonnull ByteBuffer buffer, float x, float y, @Nonnull TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale,
@Nonnull QuadSink buffer, float x, float y, @Nonnull TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale,
float leftMarginSize, float rightMarginSize, float height
)
{
Expand Down Expand Up @@ -104,7 +106,7 @@ private static void drawBackground(
}
}

private static void drawString( @Nonnull ByteBuffer buffer, float x, float y, @Nonnull TextBuffer text, @Nonnull TextBuffer textColour, @Nonnull Palette palette, boolean greyscale )
private static void drawString( @Nonnull QuadSink buffer, float x, float y, @Nonnull TextBuffer text, @Nonnull TextBuffer textColour, @Nonnull Palette palette, boolean greyscale )
{
for( int i = 0; i < text.length(); i++ )
{
Expand All @@ -117,7 +119,7 @@ private static void drawString( @Nonnull ByteBuffer buffer, float x, float y, @N
}

public static void drawTerminalForeground(
@Nonnull ByteBuffer buffer, float x, float y, @Nonnull Terminal terminal, boolean greyscale,
@Nonnull QuadSink buffer, float x, float y, @Nonnull Terminal terminal, boolean greyscale,
float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize
)
{
Expand All @@ -136,7 +138,7 @@ public static void drawTerminalForeground(
}

public static void drawTerminalBackground(
@Nonnull ByteBuffer buffer, float x, float y, @Nonnull Terminal terminal, boolean greyscale,
@Nonnull QuadSink buffer, float x, float y, @Nonnull Terminal terminal, boolean greyscale,
float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize
)
{
Expand Down Expand Up @@ -166,7 +168,7 @@ public static void drawTerminalBackground(
}

public static void drawTerminalWithoutCursor(
@Nonnull ByteBuffer buffer, float x, float y, @Nonnull Terminal terminal, boolean greyscale,
@Nonnull QuadSink buffer, float x, float y, @Nonnull Terminal terminal, boolean greyscale,
float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize
)
{
Expand All @@ -180,7 +182,7 @@ public static void drawTerminalWithoutCursor(
);
}

public static void drawCursor( @Nonnull ByteBuffer buffer, float x, float y, @Nonnull Terminal terminal, boolean greyscale )
public static void drawCursor( @Nonnull QuadSink buffer, float x, float y, @Nonnull Terminal terminal, boolean greyscale )
{
if( isCursorVisible( terminal ) )
{
Expand All @@ -191,10 +193,39 @@ public static void drawCursor( @Nonnull ByteBuffer buffer, float x, float y, @No

public static int getVertexCount( Terminal terminal )
{
return (terminal.getHeight() + 2) * (terminal.getWidth() + 2) * 2 * 4;
return (terminal.getHeight() + 2) * (terminal.getWidth() + 2) * 2;
}

private static void quad( ByteBuffer buffer, float x1, float y1, float x2, float y2, float z, byte[] rgba, float u1, float v1, float u2, float v2 )
private static void quad( QuadSink buffer, float x1, float y1, float x2, float y2, float z, byte[] rgba, float u1, float v1, float u2, float v2 )
{
buffer.quad( x1, y1, x2, y2, z, rgba, u1, v1, u2, v2 );
}

public interface QuadSink
{
VertexFormat getFormat();

ByteBuffer buffer();

void quad( float x1, float y1, float x2, float y2, float z, byte[] rgba, float u1, float v1, float u2, float v2 );
}

public record ByteBufferSink(ByteBuffer buffer) implements QuadSink
{
@Override
public VertexFormat getFormat()
{
return RenderTypes.MONITOR.format();
}

@Override
public void quad( float x1, float y1, float x2, float y2, float z, byte[] rgba, float u1, float v1, float u2, float v2 )
{
DirectFixedWidthFontRenderer.quad( buffer, x1, y1, x2, y2, z, rgba, u1, v1, u2, v2 );
}
}

static void quad( ByteBuffer buffer, float x1, float y1, float x2, float y2, float z, byte[] rgba, float u1, float v1, float u2, float v2 )
{
// Emit a single quad to our buffer. This uses Unsafe (well, LWJGL's MemoryUtil) to directly blit bytes to the
// underlying buffer. This allows us to have a single bounds check up-front, rather than one for every write.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@
*/
package dan200.computercraft.shared.integration;

import com.mojang.blaze3d.vertex.VertexFormat;
import dan200.computercraft.client.render.RenderTypes;
import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer;
import net.fabricmc.loader.api.FabricLoader;
import net.irisshaders.iris.api.v0.IrisApi;
import net.irisshaders.iris.api.v0.IrisTextVertexSink;

import java.nio.ByteBuffer;
import java.util.function.IntFunction;

public class IrisCompat
{
Expand All @@ -17,12 +24,60 @@ public boolean isRenderingShadowPass()
return false;
}

public DirectFixedWidthFontRenderer.QuadSink getVertexSink( int vertexCount, IntFunction<ByteBuffer> makeBuffer )
{
return new DirectFixedWidthFontRenderer.ByteBufferSink(
makeBuffer.apply( RenderTypes.MONITOR.format().getVertexSize() * vertexCount * 4 )
);
}

private static class Impl extends IrisCompat
{
@Override
public boolean isRenderingShadowPass()
{
return IrisApi.getInstance().isRenderingShadowPass();
}

@Override
public DirectFixedWidthFontRenderer.QuadSink getVertexSink( int vertexCount, IntFunction<ByteBuffer> makeBuffer )
{
return IrisApi.getInstance().getMinorApiRevision() >= 1
? new IrisQuadSink( vertexCount, makeBuffer )
: super.getVertexSink( vertexCount, makeBuffer );
}
}

private static final class IrisQuadSink implements DirectFixedWidthFontRenderer.QuadSink
{
private final IrisTextVertexSink sink;

private IrisQuadSink( int vertexCount, IntFunction<ByteBuffer> makeBuffer )
{
sink = IrisApi.getInstance().createTextVertexSink( vertexCount, makeBuffer );
}

@Override
public VertexFormat getFormat()
{
return sink.getUnderlyingVertexFormat();
}

@Override
public ByteBuffer buffer()
{
return sink.getUnderlyingByteBuffer();
}

@Override
public void quad( float x1, float y1, float x2, float y2, float z, byte[] rgba, float u1, float v1, float u2, float v2 )
{
sink.quad( x1, y1, x2, y2, z, pack( rgba[0], rgba[1], rgba[2], rgba[3] ), u1, v1, u2, v2, RenderTypes.FULL_BRIGHT_LIGHTMAP );
}

private static int pack( int r, int g, int b, int a )
{
return (a & 255) << 24 | (b & 255) << 16 | (g & 255) << 8 | r & 255;
}
}
}

0 comments on commit 3093de6

Please sign in to comment.