Skip to content

Commit

Permalink
implement Iris HandRenderer (#681)
Browse files Browse the repository at this point in the history
  • Loading branch information
kurrycat2004 authored Oct 28, 2024
1 parent 2dace70 commit e4e6578
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ public enum Mixins {
,"shaders.MixinGuiIngameForge"
,"shaders.MixinFramebuffer"
,"shaders.MixinItem"
,"shaders.MixinItemRenderer"
,"shaders.MixinLocale"
,"shaders.MixinOpenGlHelper"
,"shaders.MixinRender"
Expand Down
240 changes: 132 additions & 108 deletions src/main/java/net/coderbot/iris/pipeline/HandRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,157 +2,181 @@

import com.gtnewhorizons.angelica.compat.mojang.Camera;
import com.gtnewhorizons.angelica.compat.mojang.InteractionHand;
import com.gtnewhorizons.angelica.compat.toremove.MatrixStack;
import com.gtnewhorizons.angelica.compat.toremove.RenderLayer;
import com.gtnewhorizons.angelica.rendering.RenderingState;
import net.coderbot.iris.block_rendering.BlockRenderingSettings;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.Project;

import org.joml.Matrix4f;
import java.util.Map;

public class HandRenderer {
public static final HandRenderer INSTANCE = new HandRenderer();

private boolean ACTIVE;
private boolean renderingSolid;
public static final float DEPTH = 0.125F;

private void setupGlState(RenderGlobal gameRenderer, Camera camera, MatrixStack poseStack, float tickDelta) {
// final MatrixStack.Entry pose = poseStack.peek();

// We need to scale the matrix by 0.125 so the hand doesn't clip through blocks.
// Matrix4f scaleMatrix = new Matrix4f().scale(1F, 1F, DEPTH);
// TODO: ProjectionMatrix
// scaleMatrix.multiply(gameRenderer.getProjectionMatrix(camera, tickDelta, false));
// scaleMatrix.mul(projectionMatrix);
// RenderSystem.matrixMode(5889);
// RenderSystem.loadIdentity();
// RenderSystem.multMatrix(arg);
// RenderSystem.matrixMode(5888);

// pose.getModel().identity();
// pose.getNormal().identity();

// gameRenderer.invokeBobHurt(poseStack, tickDelta);
//
// if (Minecraft.getMinecraft().gameSettings.viewBobbing) {
//// gameRenderer.invokeBobView(poseStack, tickDelta);
// }
}

private boolean canRender(Camera camera, RenderGlobal gameRenderer) {
return (camera.isThirdPerson() || !(camera.getEntity() instanceof EntityPlayer) || Minecraft.getMinecraft().gameSettings.hideGUI || (camera.getEntity() instanceof EntityLiving && ((EntityLiving)camera.getEntity()).isPlayerSleeping()));

// return !(!gameRenderer.getRenderHand()
// || camera.isThirdPerson()
// || !(camera.getEntity() instanceof EntityPlayer)
// || gameRenderer.getPanoramicMode()
// || Minecraft.getMinecraft().gameSettings.hideGUI
// || (camera.getEntity() instanceof EntityLiving && ((EntityLiving)camera.getEntity()).isPlayerSleeping())
// // TODO: SPECTATOR
// /*|| Minecraft.getMinecraft().gameMode.getPlayerMode() == GameType.SPECTATOR*/);
}

public boolean isHandTranslucent(InteractionHand hand) {
public static final HandRenderer INSTANCE = new HandRenderer();

private boolean ACTIVE;
private boolean renderingSolid;
public static final float DEPTH = 0.125F;

private void setupGlState(RenderGlobal gameRenderer, Camera camera, float tickDelta) {
Minecraft mc = Minecraft.getMinecraft();

GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
// We need to scale the matrix by 0.125 so the hand doesn't clip through blocks.
GL11.glScalef(1.0F, 1.0F, DEPTH);

// TODO: Anaglyph
/*if (this.mc.gameSettings.anaglyph) {
GL11.glTranslatef((float) (-(anaglyphChannel * 2 - 1)) * 0.07F, 0.0F, 0.0F);
}*/

if (mc.entityRenderer.cameraZoom != 1.0D) {
GL11.glTranslatef((float) mc.entityRenderer.cameraYaw, (float) (-mc.entityRenderer.cameraPitch), 0.0F);
GL11.glScaled(mc.entityRenderer.cameraZoom, mc.entityRenderer.cameraZoom, 1.0D);
}

Project.gluPerspective(mc.entityRenderer.getFOVModifier(tickDelta, false), (float) mc.displayWidth / (float) mc.displayHeight, 0.05F, mc.entityRenderer.farPlaneDistance * 2.0F);


if (mc.playerController.enableEverythingIsScrewedUpMode()) {
GL11.glScalef(1.0F, 2 / 3f, 1.0F);
}

GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();

// TODO: Anaglyph
/*if (mc.gameSettings.anaglyph) {
GL11.glTranslatef((float) (anaglyphChannel * 2 - 1) * 0.1F, 0.0F, 0.0F);
}*/

mc.entityRenderer.hurtCameraEffect(tickDelta);

if (mc.gameSettings.viewBobbing) {
mc.entityRenderer.setupViewBobbing(tickDelta);
}
}

private boolean canRender(Camera camera, RenderGlobal gameRenderer) {
Minecraft mc = Minecraft.getMinecraft();

return mc.entityRenderer.debugViewDirection <= 0 &&
mc.gameSettings.thirdPersonView == 0 &&
!camera.getEntity().isPlayerSleeping() &&
!mc.gameSettings.hideGUI &&
// TODO: SPECTATOR
// mc.playerController.currentGameType
!mc.playerController.enableEverythingIsScrewedUpMode();
}

public boolean isHandTranslucent(InteractionHand hand) {
// TODO: Offhand
// Item item = Minecraft.getMinecraft().thePlayer.getItemBySlot(hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND).getItem();
ItemStack heldItem = Minecraft.getMinecraft().thePlayer.getHeldItem();
if (heldItem == null) {
return false;
}
Item item = heldItem.getItem();

if (item instanceof ItemBlock itemBlock) {
// TODO: RenderType
// return ItemBlockRenderTypes.getChunkRenderType(itemBlock.getBlock().defaultBlockState()) == RenderType.translucent();
return false;
}

return false;
}
}
Item item = heldItem.getItem();

public boolean isAnyHandTranslucent() {
return isHandTranslucent(InteractionHand.MAIN_HAND) || isHandTranslucent(InteractionHand.OFF_HAND);
}
if (item instanceof ItemBlock itemBlock) {
Map<Block, RenderLayer> blockTypeIds = BlockRenderingSettings.INSTANCE.getBlockTypeIds();
return blockTypeIds != null && blockTypeIds.get(itemBlock.field_150939_a) == RenderLayer.translucent();
}

public void renderSolid(MatrixStack poseStack, float tickDelta, Camera camera, RenderGlobal gameRenderer, WorldRenderingPipeline pipeline) {
if (!canRender(camera, gameRenderer) || !IrisApi.getInstance().isShaderPackInUse()) {
return;
}
return false;
}

ACTIVE = true;
public boolean isAnyHandTranslucent() {
return isHandTranslucent(InteractionHand.MAIN_HAND) || isHandTranslucent(InteractionHand.OFF_HAND);
}

pipeline.setPhase(WorldRenderingPhase.HAND_SOLID);
public void renderSolid(float tickDelta, Camera camera, RenderGlobal gameRenderer, WorldRenderingPipeline pipeline) {
if (!canRender(camera, gameRenderer) || !IrisApi.getInstance().isShaderPackInUse()) {
return;
}
Minecraft mc = Minecraft.getMinecraft();

// poseStack.push();
ACTIVE = true;

Minecraft.getMinecraft().mcProfiler.startSection("iris_hand");
pipeline.setPhase(WorldRenderingPhase.HAND_SOLID);

// TODO: Iris
// setupGlState(gameRenderer, camera, poseStack, tickDelta);
GL11.glPushMatrix();
GL11.glDepthMask(true); // actually write to the depth buffer, it's normally disabled at this point

renderingSolid = true;
// TODO: Hand
// Minecraft.getMinecraft().getItemInHandRenderer().renderHandsWithItems(tickDelta, poseStack, bufferSource, Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().getEntityRenderDispatcher().getPackedLightCoords(camera.getEntity(), tickDelta));
mc.mcProfiler.startSection("iris_hand");

Minecraft.getMinecraft().mcProfiler.endSection();
setupGlState(gameRenderer, camera, tickDelta);

// TODO: ProjectionMatrix
// gameRenderer.resetProjectionMatrix(CapturedRenderingState.INSTANCE.getGbufferProjection());
renderingSolid = true;
mc.entityRenderer.enableLightmap(tickDelta);
mc.entityRenderer.itemRenderer.renderItemInFirstPerson(tickDelta);
mc.entityRenderer.disableLightmap(tickDelta);

// poseStack.pop();
GL11.glDepthMask(false);
GL11.glPopMatrix();

// bufferSource.endBatch();
mc.mcProfiler.endSection();

renderingSolid = false;
resetProjectionMatrix();

pipeline.setPhase(WorldRenderingPhase.NONE);
renderingSolid = false;

ACTIVE = false;
}
pipeline.setPhase(WorldRenderingPhase.NONE);

public void renderTranslucent(MatrixStack poseStack, float tickDelta, Camera camera, RenderGlobal gameRenderer, WorldRenderingPipeline pipeline) {
if (!canRender(camera, gameRenderer) || !isAnyHandTranslucent() || !IrisApi.getInstance().isShaderPackInUse()) {
return;
}
ACTIVE = false;
}

ACTIVE = true;
// TODO: RenderType
public void renderTranslucent(float tickDelta, Camera camera, RenderGlobal gameRenderer, WorldRenderingPipeline pipeline) {
if (!canRender(camera, gameRenderer) || !isAnyHandTranslucent() || !IrisApi.getInstance().isShaderPackInUse()) {
return;
}
Minecraft mc = Minecraft.getMinecraft();

pipeline.setPhase(WorldRenderingPhase.HAND_TRANSLUCENT);
ACTIVE = true;

poseStack.push();
pipeline.setPhase(WorldRenderingPhase.HAND_TRANSLUCENT);

Minecraft.getMinecraft().mcProfiler.startSection("iris_hand_translucent");
GL11.glPushMatrix();

setupGlState(gameRenderer, camera, poseStack, tickDelta);
mc.mcProfiler.startSection("iris_hand_translucent");

// TODO: Hand
// Minecraft.getMinecraft().getItemInHandRenderer().renderHandsWithItems(tickDelta, poseStack, bufferSource, Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().getEntityRenderDispatcher().getPackedLightCoords(camera.getEntity(), tickDelta));
setupGlState(gameRenderer, camera, tickDelta);

poseStack.pop();
mc.entityRenderer.enableLightmap(tickDelta);
mc.entityRenderer.itemRenderer.renderItemInFirstPerson(tickDelta);
mc.entityRenderer.disableLightmap(tickDelta);

Minecraft.getMinecraft().mcProfiler.endSection();
GL11.glPopMatrix();

// TODO: ProjectionMatrix
// gameRenderer.resetProjectionMatrix(CapturedRenderingState.INSTANCE.getGbufferProjection());
resetProjectionMatrix();

// bufferSource.endBatch();
Minecraft.getMinecraft().mcProfiler.endSection();

pipeline.setPhase(WorldRenderingPhase.NONE);
pipeline.setPhase(WorldRenderingPhase.NONE);

ACTIVE = false;
}
ACTIVE = false;
}

public boolean isActive() {
return ACTIVE;
}
private void resetProjectionMatrix() {
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glMultMatrix(RenderingState.INSTANCE.getProjectionBuffer());
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}

public boolean isRenderingSolid() {
return renderingSolid;
}
public boolean isActive() {
return ACTIVE;
}

public boolean isRenderingSolid() {
return renderingSolid;
}
}
7 changes: 7 additions & 0 deletions src/main/resources/META-INF/angelica_at.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
public net.minecraft.block.Block func_149641_N()Ljava/lang/String; # getTextureName

public net.minecraft.client.renderer.EntityRenderer func_78476_b(FI)V # void renderHand(float, int)
public net.minecraft.client.renderer.EntityRenderer func_78481_a(FZ)F # float getFOVModifier(float, boolean)
public net.minecraft.client.renderer.EntityRenderer func_78482_e(F)V # void hurtCameraEffect(float)
public net.minecraft.client.renderer.EntityRenderer func_78475_f(F)V # void setupViewBobbing(float)
public net.minecraft.client.renderer.EntityRenderer field_78503_V # cameraZoom
public net.minecraft.client.renderer.EntityRenderer field_78502_W # cameraYaw
public net.minecraft.client.renderer.EntityRenderer field_78509_X # cameraPitch
public net.minecraft.client.renderer.EntityRenderer field_78530_s # farPlaneDistance

public net.minecraft.client.renderer.RenderGlobal field_72765_l # worldRenderers

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
import net.coderbot.iris.pipeline.WorldRenderingPipeline;
import net.coderbot.iris.uniforms.CapturedRenderingState;
import net.coderbot.iris.uniforms.SystemTimeUniforms;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.resources.IResourceManagerReloadListener;
Expand Down Expand Up @@ -44,18 +46,25 @@ public abstract class MixinEntityRenderer implements IResourceManagerReloadListe
pipeline.get().beginLevelRendering();
}

@Inject(method = "renderWorld(FJ)V", at = @At(value = "RETURN", shift = At.Shift.BEFORE))
@Inject(method = "renderWorld(FJ)V", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/client/ForgeHooksClient;dispatchRenderLast(Lnet/minecraft/client/renderer/RenderGlobal;F)V"))
private void iris$endLevelRender(float partialTicks, long limitTime, CallbackInfo callback, @Share("pipeline") LocalRef<WorldRenderingPipeline> pipeline) {
// TODO: Iris
final Camera camera = new Camera(mc.renderViewEntity, partialTicks);
HandRenderer.INSTANCE.renderTranslucent(null /*poseStack*/, partialTicks, camera, mc.renderGlobal, pipeline.get());
HandRenderer.INSTANCE.renderTranslucent(partialTicks, camera, mc.renderGlobal, pipeline.get());
Minecraft.getMinecraft().mcProfiler.endStartSection("iris_final");
pipeline.get().finalizeLevelRendering();
pipeline.set(null);
Program.unbind();
}

@Inject(at = @At(value= "INVOKE", target="Lnet/minecraft/client/renderer/RenderGlobal;clipRenderersByFrustum(Lnet/minecraft/client/renderer/culling/ICamera;F)V", shift=At.Shift.AFTER), method = "renderWorld(FJ)V")
@WrapOperation(method = "renderHand", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ItemRenderer;renderItemInFirstPerson(F)V"))
private void iris$disableVanillaRenderHand(ItemRenderer instance, float partialTicks, Operation<Void> original) {
if (!IrisApi.getInstance().isShaderPackInUse()) {
original.call(instance, partialTicks);
}
}

@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderGlobal;clipRenderersByFrustum(Lnet/minecraft/client/renderer/culling/ICamera;F)V", shift = At.Shift.AFTER), method = "renderWorld(FJ)V")
private void iris$beginEntities(float partialTicks, long startTime, CallbackInfo ci, @Share("pipeline") LocalRef<WorldRenderingPipeline> pipeline) {
final Camera camera = new Camera(mc.renderViewEntity, partialTicks);
pipeline.get().renderShadows((EntityRenderer) (Object) this, camera);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.gtnewhorizons.angelica.mixins.early.shaders;

import com.gtnewhorizons.angelica.compat.mojang.InteractionHand;
import net.coderbot.iris.pipeline.HandRenderer;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.client.renderer.ItemRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ItemRenderer.class)
public class MixinItemRenderer {
@Inject(method = "renderItemInFirstPerson", at = @At("HEAD"), cancellable = true)
private void iris$skipTranslucentHands(float partialTicks, CallbackInfo ci) {
if (IrisApi.getInstance().isShaderPackInUse()) {
// TODO: Offhand
boolean isHandTranslucent = HandRenderer.INSTANCE.isHandTranslucent(InteractionHand.MAIN_HAND);
if (HandRenderer.INSTANCE.isRenderingSolid() && isHandTranslucent) {
ci.cancel();
} else if (!HandRenderer.INSTANCE.isRenderingSolid() && !isHandTranslucent) {
ci.cancel();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,14 @@ public int sortAndRender(EntityLivingBase entity, int pass, double partialTicks)
if(pass == 0) {
pipeline.setPhase(WorldRenderingPhase.TERRAIN_CUTOUT);
} else if(pass == 1) {
pipeline.setPhase(WorldRenderingPhase.TERRAIN_TRANSLUCENT);
final Camera camera = new Camera(mc.renderViewEntity, (float) partialTicks);

// iris$beginTranslucents
pipeline.beginHand();
HandRenderer.INSTANCE.renderSolid(null /*poseStack*/, (float) partialTicks, camera, mc.renderGlobal, pipeline);
HandRenderer.INSTANCE.renderSolid((float) partialTicks, camera, mc.renderGlobal, pipeline);

mc.mcProfiler.endStartSection("iris_pre_translucent");
pipeline.setPhase(WorldRenderingPhase.TERRAIN_TRANSLUCENT);
pipeline.beginTranslucents();
this.renderEngine.bindTexture(TextureMap.locationBlocksTexture);
}
Expand Down

0 comments on commit e4e6578

Please sign in to comment.