1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-13 03:43:08 +00:00
Files
CC-Tweaked/src/main/java/dan200/computercraft/client/render/ItemPocketRenderer.java
Jonathan Coates 4228011b84 Support Occulus shaders
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.
2022-07-30 12:15:04 +01:00

145 lines
6.0 KiB
Java

/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.render;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Matrix4f;
import com.mojang.math.Vector3f;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.util.Colour;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderHandEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import static dan200.computercraft.client.render.ComputerBorderRenderer.*;
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_HEIGHT;
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_WIDTH;
/**
* Emulates map rendering for pocket computers.
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class ItemPocketRenderer extends ItemMapLikeRenderer
{
private static final ItemPocketRenderer INSTANCE = new ItemPocketRenderer();
private ItemPocketRenderer()
{
}
@SubscribeEvent
public static void onRenderInHand( RenderHandEvent event )
{
ItemStack stack = event.getItemStack();
if( !(stack.getItem() instanceof ItemPocketComputer) ) return;
event.setCanceled( true );
INSTANCE.renderItemFirstPerson(
event.getPoseStack(), event.getMultiBufferSource(), event.getPackedLight(),
event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack()
);
}
@Override
protected void renderItem( PoseStack transform, MultiBufferSource bufferSource, ItemStack stack, int light )
{
ClientComputer computer = ItemPocketComputer.createClientComputer( stack );
Terminal terminal = computer == null ? null : computer.getTerminal();
int termWidth, termHeight;
if( terminal == null )
{
termWidth = ComputerCraft.pocketTermWidth;
termHeight = ComputerCraft.pocketTermHeight;
}
else
{
termWidth = terminal.getWidth();
termHeight = terminal.getHeight();
}
int width = termWidth * FONT_WIDTH + MARGIN * 2;
int height = termHeight * FONT_HEIGHT + MARGIN * 2;
// Setup various transformations. Note that these are partially adapted from the corresponding method
// in ItemRenderer
transform.pushPose();
transform.mulPose( Vector3f.YP.rotationDegrees( 180f ) );
transform.mulPose( Vector3f.ZP.rotationDegrees( 180f ) );
transform.scale( 0.5f, 0.5f, 0.5f );
float scale = 0.75f / Math.max( width + BORDER * 2, height + BORDER * 2 + LIGHT_HEIGHT );
transform.scale( scale, scale, -1.0f );
transform.translate( -0.5 * width, -0.5 * height, 0 );
// Render the main frame
ItemPocketComputer item = (ItemPocketComputer) stack.getItem();
ComputerFamily family = item.getFamily();
int frameColour = item.getColour( stack );
Matrix4f matrix = transform.last().pose();
renderFrame( matrix, bufferSource, family, frameColour, light, width, height );
// Render the light
int lightColour = ItemPocketComputer.getLightState( stack );
if( lightColour == -1 ) lightColour = Colour.BLACK.getHex();
renderLight( transform, bufferSource, lightColour, width, height );
if( computer != null && terminal != null )
{
FixedWidthFontRenderer.drawTerminal(
FixedWidthFontRenderer.toVertexConsumer( transform, bufferSource.getBuffer( RenderTypes.TERMINAL ) ),
MARGIN, MARGIN, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN
);
}
else
{
FixedWidthFontRenderer.drawEmptyTerminal(
FixedWidthFontRenderer.toVertexConsumer( transform, bufferSource.getBuffer( RenderTypes.TERMINAL ) ),
0, 0, width, height
);
}
transform.popPose();
}
private static void renderFrame( Matrix4f transform, MultiBufferSource render, ComputerFamily family, int colour, int light, int width, int height )
{
ResourceLocation texture = colour != -1 ? ComputerBorderRenderer.BACKGROUND_COLOUR : ComputerBorderRenderer.getTexture( family );
float r = ((colour >>> 16) & 0xFF) / 255.0f;
float g = ((colour >>> 8) & 0xFF) / 255.0f;
float b = (colour & 0xFF) / 255.0f;
ComputerBorderRenderer.render( transform, render.getBuffer( ComputerBorderRenderer.getRenderType( texture ) ), 0, 0, 0, light, width, height, true, r, g, b );
}
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 );
FixedWidthFontRenderer.drawQuad(
FixedWidthFontRenderer.toVertexConsumer( transform, buffer ),
width - LIGHT_HEIGHT * 2, height + BORDER / 2.0f, 0.001f, LIGHT_HEIGHT * 2, LIGHT_HEIGHT,
c, RenderTypes.FULL_BRIGHT_LIGHTMAP
);
}
}