Skip to content

Commit

Permalink
Support Occulus shaders
Browse files Browse the repository at this point in the history
This is mostly copied from the work Toad and I did for CC:R.

Instead of not writing to the depth buffer when rendering terminals, we
now render terminal forgrounds with a small glPolygonOffset (or an
emulation of it where not possible). This removes the need for custom
render types, while still avoiding z-fighting between the terminal
foreground and background.

The VBO monitors backend now uses Iris's TextVertexSink API when
available: Iris overwrites the vertex format for RenderType.text, and so
we need to use this API to avoid rendering garbage.

Performance is maybe a little worse than before (<3ms) and definitely
worse than CC:R. Unfortunately we can't do our upload batching as that
conflicts with Optifine's patches - instead we need to maintain two
separate VBOs. This is a bit slower, but not so bad it's unworkable.
  • Loading branch information
SquidDev committed Jul 30, 2022
1 parent bd19fdf commit 4228011
Show file tree
Hide file tree
Showing 13 changed files with 362 additions and 208 deletions.
8 changes: 8 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ repositories {
name "SquidDev"
url "https://squiddev.cc/maven"
}
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
}
}
}

configurations {
Expand All @@ -150,6 +157,7 @@ dependencies {

extraModsCompileOnly fg.deobf("mezz.jei:jei-1.18.2:9.4.1.116:api")
extraModsRuntimeOnly fg.deobf("mezz.jei:jei-1.18.2:9.4.1.116")
extraModsCompileOnly fg.deobf("maven.modrinth:oculus:1.18.2-1.2.5")

shade 'org.squiddev:Cobalt:0.5.5'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.math.Matrix4f;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.common.ContainerHeldItem;
import dan200.computercraft.shared.media.items.ItemPrintout;
Expand Down Expand Up @@ -99,9 +98,8 @@ protected void renderBg( @Nonnull PoseStack transform, float partialTicks, int m
RenderSystem.enableDepthTest();

MultiBufferSource.BufferSource renderer = MultiBufferSource.immediate( Tesselator.getInstance().getBuilder() );
Matrix4f matrix = transform.last().pose();
drawBorder( matrix, renderer, leftPos, topPos, getBlitOffset(), page, pages, book, FULL_BRIGHT_LIGHTMAP );
drawText( matrix, renderer, leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * page, FULL_BRIGHT_LIGHTMAP, text, colours );
drawBorder( transform, renderer, leftPos, topPos, getBlitOffset(), page, pages, book, FULL_BRIGHT_LIGHTMAP );
drawText( transform, renderer, leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * page, FULL_BRIGHT_LIGHTMAP, text, colours );
renderer.endBatch();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.math.Matrix4f;
import dan200.computercraft.client.render.RenderTypes;
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.Terminal;
Expand Down Expand Up @@ -316,11 +315,10 @@ public void onFocusedChanged( boolean focused )
public void render( @Nonnull PoseStack transform, int mouseX, int mouseY, float partialTicks )
{
if( !visible ) return;
Matrix4f matrix = transform.last().pose();
Terminal terminal = computer.getTerminal();

var bufferSource = MultiBufferSource.immediate( Tesselator.getInstance().getBuilder() );
var emitter = FixedWidthFontRenderer.toVertexConsumer( matrix, bufferSource.getBuffer( RenderTypes.TERMINAL_WITH_DEPTH ) );
var emitter = FixedWidthFontRenderer.toVertexConsumer( transform, bufferSource.getBuffer( RenderTypes.TERMINAL ) );

if( terminal != null )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,23 +96,19 @@ protected void renderItem( PoseStack transform, MultiBufferSource bufferSource,
// Render the light
int lightColour = ItemPocketComputer.getLightState( stack );
if( lightColour == -1 ) lightColour = Colour.BLACK.getHex();
renderLight( matrix, bufferSource, lightColour, width, height );
renderLight( transform, bufferSource, lightColour, width, height );

if( computer != null && terminal != null )
{
FixedWidthFontRenderer.drawTerminal(
FixedWidthFontRenderer.toVertexConsumer( matrix, bufferSource.getBuffer( RenderTypes.TERMINAL_WITHOUT_DEPTH ) ),
FixedWidthFontRenderer.toVertexConsumer( transform, bufferSource.getBuffer( RenderTypes.TERMINAL ) ),
MARGIN, MARGIN, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN
);
FixedWidthFontRenderer.drawBlocker(
FixedWidthFontRenderer.toVertexConsumer( matrix, bufferSource.getBuffer( RenderTypes.TERMINAL_BLOCKER ) ),
0, 0, width, height
);
}
else
{
FixedWidthFontRenderer.drawEmptyTerminal(
FixedWidthFontRenderer.toVertexConsumer( matrix, bufferSource.getBuffer( RenderTypes.TERMINAL_WITH_DEPTH ) ),
FixedWidthFontRenderer.toVertexConsumer( transform, bufferSource.getBuffer( RenderTypes.TERMINAL ) ),
0, 0, width, height
);
}
Expand All @@ -131,14 +127,14 @@ private static void renderFrame( Matrix4f transform, MultiBufferSource render, C
ComputerBorderRenderer.render( transform, render.getBuffer( ComputerBorderRenderer.getRenderType( texture ) ), 0, 0, 0, light, width, height, true, r, g, b );
}

private static void renderLight( Matrix4f transform, MultiBufferSource render, int colour, int width, int height )
private static void renderLight( PoseStack transform, MultiBufferSource render, int colour, int width, int height )
{
byte r = (byte) ((colour >>> 16) & 0xFF);
byte g = (byte) ((colour >>> 8) & 0xFF);
byte b = (byte) (colour & 0xFF);
byte[] c = new byte[] { r, g, b, (byte) 255 };

VertexConsumer buffer = render.getBuffer( RenderTypes.TERMINAL_WITH_DEPTH );
VertexConsumer buffer = render.getBuffer( RenderTypes.TERMINAL );
FixedWidthFontRenderer.drawQuad(
FixedWidthFontRenderer.toVertexConsumer( transform, buffer ),
width - LIGHT_HEIGHT * 2, height + BORDER / 2.0f, 0.001f, LIGHT_HEIGHT * 2, LIGHT_HEIGHT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package dan200.computercraft.client.render;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import com.mojang.math.Vector3f;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.media.items.ItemPrintout;
Expand Down Expand Up @@ -106,10 +105,9 @@ private static void drawPrintout( PoseStack transform, MultiBufferSource render,
transform.scale( scale, scale, scale );
transform.translate( (max - width) / 2.0, (max - height) / 2.0, 0.0 );

Matrix4f matrix = transform.last().pose();
drawBorder( matrix, render, 0, 0, -0.01f, 0, pages, book, light );
drawBorder( transform, render, 0, 0, -0.01f, 0, pages, book, light );
drawText(
matrix, render, X_TEXT_MARGIN, Y_TEXT_MARGIN, 0, light,
transform, render, X_TEXT_MARGIN, Y_TEXT_MARGIN, 0, light,
ItemPrintout.getText( stack ), ItemPrintout.getColours( stack )
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
package dan200.computercraft.client.render;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Matrix4f;
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
Expand Down Expand Up @@ -54,7 +55,7 @@ public final class PrintoutRenderer

private PrintoutRenderer() {}

public static void drawText( Matrix4f transform, MultiBufferSource bufferSource, int x, int y, int start, int light, TextBuffer[] text, TextBuffer[] colours )
public static void drawText( PoseStack transform, MultiBufferSource bufferSource, int x, int y, int start, int light, TextBuffer[] text, TextBuffer[] colours )
{
var buffer = bufferSource.getBuffer( RenderTypes.PRINTOUT_TEXT );
var emitter = FixedWidthFontRenderer.toVertexConsumer( transform, buffer );
Expand All @@ -67,7 +68,7 @@ public static void drawText( Matrix4f transform, MultiBufferSource bufferSource,
}
}

public static void drawText( Matrix4f transform, MultiBufferSource bufferSource, int x, int y, int start, int light, String[] text, String[] colours )
public static void drawText( PoseStack transform, MultiBufferSource bufferSource, int x, int y, int start, int light, String[] text, String[] colours )
{
var buffer = bufferSource.getBuffer( RenderTypes.PRINTOUT_TEXT );
var emitter = FixedWidthFontRenderer.toVertexConsumer( transform, buffer );
Expand All @@ -81,8 +82,9 @@ public static void drawText( Matrix4f transform, MultiBufferSource bufferSource,
}
}

public static void drawBorder( Matrix4f transform, MultiBufferSource bufferSource, float x, float y, float z, int page, int pages, boolean isBook, int light )
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();
int leftPages = page;
int rightPages = pages - page - 1;

Expand All @@ -96,11 +98,11 @@ public static void drawBorder( Matrix4f transform, MultiBufferSource bufferSourc
float right = x + X_SIZE + offset - 4;

// Left and right border
drawTexture( transform, buffer, left - 4, y - 8, z - 0.02f, COVER_X, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2, light );
drawTexture( transform, buffer, right, y - 8, z - 0.02f, COVER_X + COVER_SIZE, 0, COVER_SIZE, Y_SIZE + COVER_SIZE * 2, light );
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 );

// Draw centre panel (just stretched texture, sorry).
drawTexture( transform, buffer,
drawTexture( matrix, buffer,
x - offset, y, z - 0.02f, X_SIZE + offset * 2, Y_SIZE,
COVER_X + COVER_SIZE / 2.0f, COVER_SIZE, COVER_SIZE, Y_SIZE,
light
Expand All @@ -110,20 +112,20 @@ public static void drawBorder( Matrix4f transform, MultiBufferSource bufferSourc
while( borderX < right )
{
double thisWidth = Math.min( right - borderX, X_SIZE );
drawTexture( transform, buffer, borderX, y - 8, z - 0.02f, 0, COVER_Y, (float) thisWidth, COVER_SIZE, light );
drawTexture( transform, buffer, borderX, y + Y_SIZE - 4, z - 0.02f, 0, COVER_Y + COVER_SIZE, (float) thisWidth, COVER_SIZE, light );
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 );
borderX += thisWidth;
}
}

// 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.
drawTexture( transform, buffer, x, y, z - 1e-3f * 0.5f, X_FOLD_SIZE * 2, 0, X_SIZE, Y_SIZE, light );
drawTexture( matrix, buffer, x, y, z - 1e-3f * 0.5f, X_FOLD_SIZE * 2, 0, X_SIZE, Y_SIZE, light );

// Left pages
for( int n = 0; n <= leftPages; n++ )
{
drawTexture( transform, buffer,
drawTexture( matrix, buffer,
x - offsetAt( n ), y, z - 1e-3f * n,
// Use the left "bold" fold for the outermost page
n == leftPages ? 0 : X_FOLD_SIZE, 0,
Expand All @@ -134,7 +136,7 @@ public static void drawBorder( Matrix4f transform, MultiBufferSource bufferSourc
// Right pages
for( int n = 0; n <= rightPages; n++ )
{
drawTexture( transform, buffer,
drawTexture( matrix, buffer,
x + (X_SIZE - X_FOLD_SIZE) + offsetAt( n ), y, z - 1e-3f * n,
// 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,
Expand Down
55 changes: 4 additions & 51 deletions src/main/java/dan200/computercraft/client/render/RenderTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,9 @@ public class RenderTypes
private static MonitorTextureBufferShader monitorTboShader;

/**
* Renders a fullbright terminal without writing to the depth layer. This is used in combination with
* {@link #TERMINAL_BLOCKER} to ensure we can render a terminal without z-fighting.
* Renders a fullbright terminal.
*/
public static final RenderType TERMINAL_WITHOUT_DEPTH = Types.TERMINAL_WITHOUT_DEPTH;

/**
* A transparent texture which only writes to the depth layer.
*/
public static final RenderType TERMINAL_BLOCKER = Types.TERMINAL_BLOCKER;

/**
* Renders a fullbright terminal which also writes to the depth layer. This is used when z-fighting isn't an issue -
* for instance rendering an empty terminal or inside a GUI.
*
* This is identical to <em>vanilla's</em> {@link RenderType#text}. Forge overrides one with a definition which sets
* sortOnUpload to true, which is entirely broken!
*/
public static final RenderType TERMINAL_WITH_DEPTH = Types.TERMINAL_WITH_DEPTH;
public static final RenderType TERMINAL = RenderType.text( FixedWidthFontRenderer.FONT );

/**
* Renders a monitor with the TBO shader.
Expand All @@ -57,7 +42,7 @@ public class RenderTypes
public static final RenderType MONITOR_TBO = Types.MONITOR_TBO;

/**
* A variant of {@link #TERMINAL_WITH_DEPTH} which uses the lightmap rather than rendering fullbright.
* A variant of {@link #TERMINAL} which uses the lightmap rather than rendering fullbright.
*/
public static final RenderType PRINTOUT_TEXT = RenderType.text( FixedWidthFontRenderer.FONT );

Expand All @@ -77,7 +62,7 @@ static MonitorTextureBufferShader getMonitorTextureBufferShader()
@Nonnull
static ShaderInstance getTerminalShader()
{
return GameRenderer.getPositionColorTexShader();
return GameRenderer.getRendertypeTextShader();
}

@SubscribeEvent
Expand All @@ -99,8 +84,6 @@ private static final class Types extends RenderStateShard
FixedWidthFontRenderer.FONT,
false, false // blur, minimap
);
private static final VertexFormat TERM_FORMAT = DefaultVertexFormat.POSITION_COLOR_TEX;
private static final ShaderStateShard TERM_SHADER = new ShaderStateShard( RenderTypes::getTerminalShader );

static final RenderType MONITOR_TBO = RenderType.create(
"monitor_tbo", DefaultVertexFormat.POSITION_TEX, VertexFormat.Mode.TRIANGLE_STRIP, 128,
Expand All @@ -111,36 +94,6 @@ private static final class Types extends RenderStateShard
.createCompositeState( false )
);

static final RenderType TERMINAL_WITHOUT_DEPTH = RenderType.create(
"terminal_without_depth", TERM_FORMAT, VertexFormat.Mode.QUADS, 1024,
false, false, // useDelegate, needsSorting
RenderType.CompositeState.builder()
.setTextureState( TERM_FONT_TEXTURE )
.setShaderState( TERM_SHADER )
.setLightmapState( LIGHTMAP )
.setWriteMaskState( COLOR_WRITE )
.createCompositeState( false )
);

static final RenderType TERMINAL_BLOCKER = RenderType.create(
"terminal_blocker", DefaultVertexFormat.POSITION, VertexFormat.Mode.QUADS, 256,
false, false, // useDelegate, needsSorting
RenderType.CompositeState.builder()
.setShaderState( POSITION_SHADER )
.setWriteMaskState( DEPTH_WRITE )
.createCompositeState( false )
);

static final RenderType TERMINAL_WITH_DEPTH = RenderType.create(
"terminal_with_depth", TERM_FORMAT, VertexFormat.Mode.QUADS, 1024,
false, false, // useDelegate, needsSorting
RenderType.CompositeState.builder()
.setTextureState( TERM_FONT_TEXTURE )
.setShaderState( TERM_SHADER )
.setLightmapState( LIGHTMAP )
.createCompositeState( false )
);

private Types( String name, Runnable setup, Runnable destroy )
{
super( name, setup, destroy );
Expand Down
Loading

0 comments on commit 4228011

Please sign in to comment.