Compare commits

..
6 Commits
20 changed files with 658 additions and 75 deletions

No files matched your search

@@ -5222,26 +5222,36 @@ public class GLStateManager {
private static void invalidateDeletedBuffer(int buffer) {
if (buffer == 0) return;
if (boundVBO == buffer) glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
if (VAOManager.boundEBO == buffer) glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
if (boundPixelUnpackBuffer == buffer) glBindBuffer(GL21.GL_PIXEL_UNPACK_BUFFER, 0);
if (boundPixelPackBuffer == buffer) glBindBuffer(GL21.GL_PIXEL_PACK_BUFFER, 0);
final boolean locked = acquireDrawLock();
try {
if (boundVBO == buffer) glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
if (VAOManager.boundEBO == buffer) glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
if (boundPixelUnpackBuffer == buffer) glBindBuffer(GL21.GL_PIXEL_UNPACK_BUFFER, 0);
if (boundPixelPackBuffer == buffer) glBindBuffer(GL21.GL_PIXEL_PACK_BUFFER, 0);
VAOManager.onDeleteBuffer(buffer);
VAOManager.onDeleteBuffer(buffer);
} finally {
if (locked) releaseDrawLock();
}
}
public static void glBindBuffer(int target, int buffer) {
if (target == GL15.GL_ARRAY_BUFFER) {
// if (boundVBO == buffer) return; TODO figure out why this breaks switching async occlusion mode
boundVBO = buffer;
} else if (target == GL15.GL_ELEMENT_ARRAY_BUFFER) {
VAOManager.onBindEBO(buffer);
} else if (target == GL21.GL_PIXEL_UNPACK_BUFFER) {
boundPixelUnpackBuffer = buffer;
} else if (target == GL21.GL_PIXEL_PACK_BUFFER) {
boundPixelPackBuffer = buffer;
final boolean locked = acquireDrawLock();
try {
if (target == GL15.GL_ARRAY_BUFFER) {
// if (boundVBO == buffer) return; TODO figure out why this breaks switching async occlusion mode
boundVBO = buffer;
} else if (target == GL15.GL_ELEMENT_ARRAY_BUFFER) {
VAOManager.onBindEBO(buffer);
} else if (target == GL21.GL_PIXEL_UNPACK_BUFFER) {
boundPixelUnpackBuffer = buffer;
} else if (target == GL21.GL_PIXEL_PACK_BUFFER) {
boundPixelPackBuffer = buffer;
}
RENDER_BACKEND.bindBuffer(target, buffer);
} finally {
if (locked) releaseDrawLock();
}
RENDER_BACKEND.bindBuffer(target, buffer);
}
public static void forcePixelUnpackState(PixelUnpackState target) {
@@ -5576,22 +5586,32 @@ public class GLStateManager {
if (array == 0) {
array = defaultVAO;
}
if (boundVAO != array) {
boundVAO = array;
VAOManager.onBindVertexArrayPre(array);
RENDER_BACKEND.bindVertexArray(array);
final boolean locked = acquireDrawLock();
try {
if (boundVAO != array) {
boundVAO = array;
VAOManager.onBindVertexArrayPre(array);
RENDER_BACKEND.bindVertexArray(array);
}
} finally {
if (locked) releaseDrawLock();
}
}
public static void glDeleteVertexArrays(int array) {
VAOManager.onDeleteVertexArray(array);
if (array == boundVAO) {
// Deleting the bound VAO implicitly unbinds it. Rebind the default VAO.
boundVAO = defaultVAO;
VAOManager.onBindVertexArrayPre(defaultVAO);
RENDER_BACKEND.bindVertexArray(defaultVAO);
final boolean locked = acquireDrawLock();
try {
VAOManager.onDeleteVertexArray(array);
if (array == boundVAO) {
// Deleting the bound VAO implicitly unbinds it. Rebind the default VAO.
boundVAO = defaultVAO;
VAOManager.onBindVertexArrayPre(defaultVAO);
RENDER_BACKEND.bindVertexArray(defaultVAO);
}
RENDER_BACKEND.deleteVertexArrays(array);
} finally {
if (locked) releaseDrawLock();
}
RENDER_BACKEND.deleteVertexArrays(array);
}
public static int glGenVertexArrays() {
@@ -0,0 +1,15 @@
package com.gtnewhorizons.angelica.event;
import net.minecraftforge.eventbus.api.bus.EventBus;
import net.minecraftforge.eventbus.api.event.RecordEvent;
public class RenderChunkEvent implements RecordEvent {
public static final EventBus<RenderChunkEvent> BUS = EventBus.create(RenderChunkEvent.class);
private static final RenderChunkEvent INSTANCE = new RenderChunkEvent();
public static void post() {
if (!BUS.hasListeners()) return;
BUS.post(INSTANCE);
}
}
@@ -157,6 +157,7 @@ public enum Mixins implements IMixins {
.setPhase(Phase.EARLY)
.addClientMixins(
"angelica.itemrenderer.MixinItemRenderer",
"angelica.itemrenderer.MixinRenderItemFrame",
"angelica.itemrenderer.MixinRenderBlocks"
)
.setApplyIf(() -> AngelicaConfig.optimizeInWorldItemRendering)),
@@ -292,8 +293,12 @@ public enum Mixins implements IMixins {
, "shaders.MixinLocale"
, "shaders.MixinRender"
, "shaders.MixinRenderBiped"
, "shaders.MixinRenderBlocks_FaceNormals"
, "shaders.MixinRenderBlocks_FallingShading"
, "shaders.MixinRenderBlocks_ItemId"
, "shaders.MixinRenderDragon"
, "shaders.MixinRenderEntityFlame"
, "shaders.MixinRenderFallingBlock"
, "shaders.MixinRendererLivingEntity"
, "shaders.MixinRenderGlobal"
, "shaders.AccessorEntityHorse"
@@ -0,0 +1,83 @@
package com.gtnewhorizons.angelica.rendering;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraftforge.common.util.ForgeDirection;
public final class FallingBlockMetaAccess implements IBlockAccess {
private IBlockAccess delegate;
private int x;
private int y;
private int z;
private int metadata;
public FallingBlockMetaAccess set(IBlockAccess delegate, int x, int y, int z, int metadata) {
this.delegate = delegate;
this.x = x;
this.y = y;
this.z = z;
this.metadata = metadata;
return this;
}
public void clear() {
this.delegate = null;
}
@Override
public int getBlockMetadata(int x, int y, int z) {
if (x == this.x && y == this.y && z == this.z) {
return this.metadata;
}
return delegate.getBlockMetadata(x, y, z);
}
@Override
public Block getBlock(int x, int y, int z) {
return delegate.getBlock(x, y, z);
}
@Override
public TileEntity getTileEntity(int x, int y, int z) {
return delegate.getTileEntity(x, y, z);
}
@Override
public int getLightBrightnessForSkyBlocks(int x, int y, int z, int lightValue) {
return delegate.getLightBrightnessForSkyBlocks(x, y, z, lightValue);
}
@Override
public int isBlockProvidingPowerTo(int x, int y, int z, int direction) {
return delegate.isBlockProvidingPowerTo(x, y, z, direction);
}
@Override
public boolean isAirBlock(int x, int y, int z) {
return delegate.isAirBlock(x, y, z);
}
@Override
public BiomeGenBase getBiomeGenForCoords(int x, int z) {
return delegate.getBiomeGenForCoords(x, z);
}
@Override
public int getHeight() {
return delegate.getHeight();
}
@Override
public boolean extendedLevelsInChunkCache() {
return delegate.extendedLevelsInChunkCache();
}
@Override
public boolean isSideSolid(int x, int y, int z, ForgeDirection side, boolean _default) {
return delegate.isSideSolid(x, y, z, side, _default);
}
}
@@ -0,0 +1,56 @@
package com.gtnewhorizons.angelica.rendering;
import com.gtnewhorizon.gtnhlib.client.renderer.TessellatorManager;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
import net.coderbot.iris.block_rendering.BlockMaterialMapping;
import net.coderbot.iris.block_rendering.BlockRenderingSettings;
import net.coderbot.iris.gl.shader.ProgramCreator;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.block.Block;
import net.minecraft.world.IBlockAccess;
public final class FallingBlockRendering {
public static boolean active;
private static final FallingBlockMetaAccess META_ACCESS = new FallingBlockMetaAccess();
private FallingBlockRendering() {
}
public static FallingBlockMetaAccess metaAccess(IBlockAccess world, int x, int y, int z, int metadata) {
return META_ACCESS.set(world, x, y, z, metadata);
}
public static void setEntityAttribute(Block block, int metadata) {
if (!shadersActive()) return;
GLStateManager.glVertexAttrib2s(ProgramCreator.MC_ENTITY, (short) blockMaterialId(block, metadata), (short) 0);
}
public static void resetEntityAttribute() {
if (!shadersActive()) return;
GLStateManager.glVertexAttrib2s(ProgramCreator.MC_ENTITY, (short) -1, (short) -1);
}
private static int blockMaterialId(Block block, int metadata) {
final Reference2ObjectMap<Block, Int2IntMap> blockMetaMatches = BlockRenderingSettings.INSTANCE.getBlockMetaMatches();
if (blockMetaMatches == null) return -1;
final Int2IntMap metaMap = blockMetaMatches.get(block);
return metaMap != null ? BlockMaterialMapping.resolveId(metaMap, metadata) : -1;
}
public static boolean isActive() {
return active && shadersActive();
}
private static boolean shadersActive() {
return TessellatorManager.isOnMainThread() && IrisApi.getInstance().isShaderPackInUse();
}
public static boolean skipDirectionalShading() {
return isActive() && BlockRenderingSettings.INSTANCE.shouldDisableDirectionalShading();
}
}
@@ -12,6 +12,7 @@ public class BlockRenderListManager {
private static final BlockMeta key = new BlockMeta();
private static final Object2IntOpenHashMap<BlockMeta> displayListMap = new Object2IntOpenHashMap<>();
private static final int[] itemFrameDisplayLists = new int[8];
private static final int ISBRH_CUTOFF = 40;
@@ -36,6 +37,10 @@ public class BlockRenderListManager {
return displayListMap.getInt(key);
}
public static int getItemFrameDisplayList(int variant) {
return itemFrameDisplayLists[variant];
}
public static int startCompiling() {
final int list = GLStateManager.glGenLists(1);
GLStateManager.glNewList(list, GL11.GL_COMPILE);
@@ -43,9 +48,18 @@ public class BlockRenderListManager {
}
public static void endCompiling(int list, Block block, int meta) {
finishCompiling();
displayListMap.put(new BlockMeta(block, meta), list);
}
public static void endItemFrameCompiling(int list, int variant) {
finishCompiling();
itemFrameDisplayLists[variant] = list;
}
private static void finishCompiling() {
DisplayListManager.discardMatrixTransforms();
GLStateManager.glEndList();
displayListMap.put(new BlockMeta(block, meta), list);
}
public static void registerReloadListener(){
@@ -56,6 +70,12 @@ public class BlockRenderListManager {
GLStateManager.glDeleteLists(list, 1);
}
displayListMap.clear();
for (int i = 0; i < itemFrameDisplayLists.length; i++) {
if (itemFrameDisplayLists[i] != 0) {
GLStateManager.glDeleteLists(itemFrameDisplayLists[i], 1);
itemFrameDisplayLists[i] = 0;
}
}
});
}
@@ -7,6 +7,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.ChunkPosition;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -16,8 +17,9 @@ import java.util.function.Consumer;
/**
* Thread-safe wrapper around a tile entity map for chunkTileEntityMap.
* May wrap either a plain Object2ObjectOpenHashMap (vanilla) or a ColumnTileEntityMap (cubic chunks).
* Extends HashMap for binary compatibility with mods that cast chunkTileEntityMap to HashMap.
*/
public class ConcurrentTileEntityMap implements Map<ChunkPosition, TileEntity> {
public class ConcurrentTileEntityMap extends HashMap<ChunkPosition, TileEntity> {
private final Object2ObjectOpenHashMap<ChunkPosition, TileEntity> flatDelegate;
private final Map<ChunkPosition, TileEntity> delegate;
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
@@ -781,7 +781,11 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline, R
}
public boolean shouldOverrideShaders() {
return isRenderingWorld && !isRenderingFullScreenPass && !isPostChain && isMainBound;
return isRenderingLevelGeometry() && isMainBound;
}
public boolean isRenderingLevelGeometry() {
return isRenderingWorld && !isRenderingFullScreenPass && !isPostChain;
}
public Pass getActivePassProgram() {
@@ -1,5 +1,9 @@
package net.coderbot.iris.uniforms;
import net.coderbot.iris.Iris;
import net.coderbot.iris.pipeline.DeferredWorldRenderingPipeline;
import net.coderbot.iris.pipeline.WorldRenderingPipeline;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
/**
@@ -23,6 +27,13 @@ public class ItemIdManager {
CapturedRenderingState.INSTANCE.setCurrentRenderedItem(id);
}
/**
* Set the item ID for a Block rendered outside of terrain.
*/
public static void setBlockId(Block block, int metadata) {
CapturedRenderingState.INSTANCE.setCurrentRenderedItem(Math.max(0, ItemMaterialHelper.getMaterialId(block, metadata)));
}
/**
* Reset the item ID to 0.
* Used when entering/exiting render sections or before glint rendering.
@@ -30,4 +41,28 @@ public class ItemIdManager {
public static void resetItemId() {
CapturedRenderingState.INSTANCE.setCurrentRenderedItem(0);
}
/**
* The currently bound item ID.
*/
public static int getItemId() {
return CapturedRenderingState.INSTANCE.getCurrentRenderedItem();
}
/**
* Set an already-resolved item ID without performing a lookup.
*/
public static void setItemIdRaw(int id) {
CapturedRenderingState.INSTANCE.setCurrentRenderedItem(id);
}
/**
* Honestly I don't know why there's comments on a lot of these.
* Guess I thought documentation is good but man if you can't figure this out
* you're in trouble.
*/
public static boolean isWorldRenderActive() {
final WorldRenderingPipeline pipeline = Iris.getPipelineManager().getPipelineNullable();
return pipeline instanceof DeferredWorldRenderingPipeline drp && drp.isRenderingLevelGeometry();
}
}
@@ -23,6 +23,8 @@ public class ItemMaterialHelper {
private static final Reference2ObjectMap<Item, Int2IntMap> MATERIAL_CACHE = new Reference2ObjectOpenHashMap<>();
private static final int CACHE_MISS_SENTINEL = Integer.MIN_VALUE;
private static final Reference2ObjectMap<Item, NamespacedId> ITEM_NAME_CACHE = new Reference2ObjectOpenHashMap<>();
private static final Reference2ObjectMap<Block, Int2IntMap> BLOCK_MATERIAL_CACHE = new Reference2ObjectOpenHashMap<>();
/**
* Get the material ID for an ItemStack.
* For ItemBlock: checks block.properties first, then item.properties.
@@ -79,6 +81,52 @@ public class ItemMaterialHelper {
return materialId;
}
/**
* Get the material ID for a Block rendered outside of terrain.
*
* @return The material ID, or -1 if not found
*/
public static int getMaterialId(Block block, int metadata) {
if (block == null) {
return -1;
}
Int2IntMap metadataCache = BLOCK_MATERIAL_CACHE.get(block);
if (metadataCache != null) {
int cached = metadataCache.getOrDefault(metadata, CACHE_MISS_SENTINEL);
if (cached != CACHE_MISS_SENTINEL) {
return cached;
}
}
int materialId = lookupBlockMaterialId(block, metadata);
if (metadataCache == null) {
metadataCache = new Int2IntOpenHashMap();
metadataCache.defaultReturnValue(CACHE_MISS_SENTINEL);
BLOCK_MATERIAL_CACHE.put(block, metadataCache);
}
metadataCache.put(metadata, materialId);
return materialId;
}
private static int lookupBlockMaterialId(Block block, int metadata) {
Reference2ObjectMap<Block, Int2IntMap> blockMetaMatches = BlockRenderingSettings.INSTANCE.getBlockMetaMatches();
if (blockMetaMatches != null) {
Int2IntMap metaMap = blockMetaMatches.get(block);
if (metaMap != null) {
int id = BlockMaterialMapping.resolveId(metaMap, metadata);
if (id != -1) {
return id;
}
}
}
final Item item = Item.getItemFromBlock(block);
return item != null ? lookupItemPropertiesId(item) : -1;
}
/**
* Perform the actual material ID lookup without caching.
*
@@ -107,16 +155,17 @@ public class ItemMaterialHelper {
}
// Fall back to item.properties
Object2IntFunction<NamespacedId> itemIds = BlockRenderingSettings.INSTANCE.getItemIds();
if (itemIds != null) {
String itemIdString = Item.itemRegistry.getNameForObject(item);
if (itemIdString != null) {
ResourceLocation itemId = new ResourceLocation(itemIdString);
return itemIds.applyAsInt(new NamespacedId(itemId.getResourceDomain(), itemId.getResourcePath()));
}
return lookupItemPropertiesId(item);
}
private static int lookupItemPropertiesId(Item item) {
final Object2IntFunction<NamespacedId> itemIds = BlockRenderingSettings.INSTANCE.getItemIds();
if (itemIds == null) {
return -1;
}
return -1;
final NamespacedId name = getCachedItemName(item);
return name == null ? -1 : itemIds.applyAsInt(name);
}
/**
@@ -126,6 +175,7 @@ public class ItemMaterialHelper {
public static void clearCache() {
MATERIAL_CACHE.clear();
ITEM_NAME_CACHE.clear();
BLOCK_MATERIAL_CACHE.clear();
}
private static NamespacedId getCachedItemName(Item item) {
@@ -20,9 +20,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@@ -194,11 +192,6 @@ public abstract class MixinFontRenderer implements FontRendererAccessor, IFontPa
@Override
public void angelica$bindTexture(ResourceLocation location) { this.bindTexture(location); }
@ModifyConstant(method = "getCharWidth", constant = @Constant(intValue = 7))
private int angelica$maxCharWidth(int original) {
return Integer.MAX_VALUE;
}
@Inject(method = "getCharWidth", at = @At("HEAD"), cancellable = true)
public void getCharWidth(char c, CallbackInfoReturnable<Integer> cir) {
cir.setReturnValue((int) angelica$getBatcher().getCharWidthFine(c));
@@ -0,0 +1,56 @@
package com.gtnewhorizons.angelica.mixins.early.angelica.itemrenderer;
import com.gtnewhorizon.gtnhlib.client.renderer.TessellatorManager;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.rendering.items.BlockRenderListManager;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.tileentity.RenderItemFrame;
import net.minecraft.entity.item.EntityItemFrame;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(RenderItemFrame.class)
public class MixinRenderItemFrame {
@WrapOperation(
method = "doRender(Lnet/minecraft/entity/item/EntityItemFrame;DDDFF)V",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/tileentity/RenderItemFrame;renderFrameItemAsBlock(Lnet/minecraft/entity/item/EntityItemFrame;)V"
)
)
private void angelica$cacheFrame(RenderItemFrame renderer, EntityItemFrame frame, Operation<Void> original) {
angelica$renderCached(renderer, frame, original, frame.hangingDirection);
}
@WrapOperation(
method = "doRender(Lnet/minecraft/entity/item/EntityItemFrame;DDDFF)V",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/tileentity/RenderItemFrame;func_147915_b(Lnet/minecraft/entity/item/EntityItemFrame;)V"
)
)
private void angelica$cacheMapFrame(RenderItemFrame renderer, EntityItemFrame frame, Operation<Void> original) {
angelica$renderCached(renderer, frame, original, 4 + frame.hangingDirection);
}
@Unique
private static void angelica$renderCached(RenderItemFrame renderer, EntityItemFrame frame,
Operation<Void> original, int keyIndex) {
if (GLStateManager.isRecordingDisplayList() || TessellatorManager.isCurrentlyCapturing()
|| TessellatorManager.shouldInterceptDraw(Tessellator.instance)) {
original.call(renderer, frame);
return;
}
int list = BlockRenderListManager.getItemFrameDisplayList(keyIndex);
if (list == 0) {
list = BlockRenderListManager.startCompiling();
original.call(renderer, frame);
BlockRenderListManager.endItemFrameCompiling(list, keyIndex);
}
GLStateManager.glCallList(list);
}
}
@@ -2,6 +2,7 @@ package com.gtnewhorizons.angelica.mixins.early.celeritas.terrain;
import com.gtnewhorizons.angelica.compat.mojang.Camera;
import com.gtnewhorizons.angelica.compat.mojang.GameModeUtil;
import com.gtnewhorizons.angelica.event.RenderChunkEvent;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.mixins.interfaces.IRenderGlobalExt;
import com.gtnewhorizons.angelica.rendering.AngelicaRenderQueue;
@@ -164,6 +165,7 @@ public class MixinRenderGlobal implements IRenderGlobalExt {
} else {
mc.mcProfiler.endStartSection("draw_chunk_layer_translucent");
this.celeritas$renderer.drawChunkLayer(BlockRenderLayer.TRANSLUCENT, camX, camY, camZ);
RenderChunkEvent.post();
}
} finally {
RenderDevice.exitManagedCode();
@@ -8,7 +8,9 @@ import net.coderbot.iris.pipeline.HandRenderer;
import net.coderbot.iris.uniforms.ItemIdManager;
import net.irisshaders.iris.api.v0.IrisApi;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import net.minecraftforge.client.IItemRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@@ -16,7 +18,8 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* Mixin to handle item rendering in first-person.
* Mixin to handle item rendering in first-person, and to set the currentRenderedItem for every
* item rendered on an entity.
*/
@Mixin(ItemRenderer.class)
public class MixinItemRenderer {
@@ -53,6 +56,30 @@ public class MixinItemRenderer {
ItemIdManager.resetItemId();
}
/**
* Set the item ID for any item rendered on an entity.
*/
@Inject(
method = "renderItem(Lnet/minecraft/entity/EntityLivingBase;Lnet/minecraft/item/ItemStack;ILnet/minecraftforge/client/IItemRenderer$ItemRenderType;)V",
at = @At("HEAD"),
remap = false
)
private void iris$setEntityItemId(EntityLivingBase entity, ItemStack itemStack, int renderPass, IItemRenderer.ItemRenderType type, CallbackInfo ci) {
ItemIdManager.setItemId(itemStack);
}
/**
* Clear the ID once the item is drawn.
*/
@Inject(
method = "renderItem(Lnet/minecraft/entity/EntityLivingBase;Lnet/minecraft/item/ItemStack;ILnet/minecraftforge/client/IItemRenderer$ItemRenderType;)V",
at = @At("RETURN"),
remap = false
)
private void iris$clearEntityItemId(EntityLivingBase entity, ItemStack itemStack, int renderPass, IItemRenderer.ItemRenderType type, CallbackInfo ci) {
ItemIdManager.resetItemId();
}
/**
* Activate GLINT shader before rendering enchantment glint on held items (third person).
*/
@@ -4,10 +4,8 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.coderbot.iris.uniforms.ItemIdManager;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.entity.RenderBiped;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -39,17 +37,4 @@ public class MixinRenderBiped {
original.call(instance, model);
}
/**
* Set item ID when rendering held items on entities (third person).
*/
@WrapOperation(
method = "renderEquippedItems(Lnet/minecraft/entity/EntityLiving;F)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ItemRenderer;renderItem(Lnet/minecraft/entity/EntityLivingBase;Lnet/minecraft/item/ItemStack;I)V")
)
private void iris$setHeldItemId(ItemRenderer itemRenderer, EntityLivingBase entity, ItemStack itemStack, int renderPass, Operation<Void> original) {
ItemIdManager.setItemId(itemStack);
original.call(itemRenderer, entity, itemStack, renderPass);
}
}
@@ -0,0 +1,77 @@
package com.gtnewhorizons.angelica.mixins.early.shaders;
import com.gtnewhorizons.angelica.rendering.FallingBlockRendering;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.IIcon;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
/**
* Emits a per-face normal while a falling block is rendering, so shader packs can light it.
*/
@Mixin(RenderBlocks.class)
public class MixinRenderBlocks_FaceNormals {
@Redirect(
method = {"renderBlockSandFalling", "renderStandardBlockWithColorMultiplier",
"renderStandardBlockWithAmbientOcclusion", "renderStandardBlockWithAmbientOcclusionPartial"},
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBlocks;renderFaceYNeg(Lnet/minecraft/block/Block;DDDLnet/minecraft/util/IIcon;)V")
)
private void angelica$normalYNeg(RenderBlocks instance, Block block, double x, double y, double z, IIcon icon) {
if (FallingBlockRendering.isActive()) Tessellator.instance.setNormal(0.0F, -1.0F, 0.0F);
instance.renderFaceYNeg(block, x, y, z, icon);
}
@Redirect(
method = {"renderBlockSandFalling", "renderStandardBlockWithColorMultiplier",
"renderStandardBlockWithAmbientOcclusion", "renderStandardBlockWithAmbientOcclusionPartial"},
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBlocks;renderFaceYPos(Lnet/minecraft/block/Block;DDDLnet/minecraft/util/IIcon;)V")
)
private void angelica$normalYPos(RenderBlocks instance, Block block, double x, double y, double z, IIcon icon) {
if (FallingBlockRendering.isActive()) Tessellator.instance.setNormal(0.0F, 1.0F, 0.0F);
instance.renderFaceYPos(block, x, y, z, icon);
}
@Redirect(
method = {"renderBlockSandFalling", "renderStandardBlockWithColorMultiplier",
"renderStandardBlockWithAmbientOcclusion", "renderStandardBlockWithAmbientOcclusionPartial"},
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBlocks;renderFaceZNeg(Lnet/minecraft/block/Block;DDDLnet/minecraft/util/IIcon;)V")
)
private void angelica$normalZNeg(RenderBlocks instance, Block block, double x, double y, double z, IIcon icon) {
if (FallingBlockRendering.isActive()) Tessellator.instance.setNormal(0.0F, 0.0F, -1.0F);
instance.renderFaceZNeg(block, x, y, z, icon);
}
@Redirect(
method = {"renderBlockSandFalling", "renderStandardBlockWithColorMultiplier",
"renderStandardBlockWithAmbientOcclusion", "renderStandardBlockWithAmbientOcclusionPartial"},
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBlocks;renderFaceZPos(Lnet/minecraft/block/Block;DDDLnet/minecraft/util/IIcon;)V")
)
private void angelica$normalZPos(RenderBlocks instance, Block block, double x, double y, double z, IIcon icon) {
if (FallingBlockRendering.isActive()) Tessellator.instance.setNormal(0.0F, 0.0F, 1.0F);
instance.renderFaceZPos(block, x, y, z, icon);
}
@Redirect(
method = {"renderBlockSandFalling", "renderStandardBlockWithColorMultiplier",
"renderStandardBlockWithAmbientOcclusion", "renderStandardBlockWithAmbientOcclusionPartial"},
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBlocks;renderFaceXNeg(Lnet/minecraft/block/Block;DDDLnet/minecraft/util/IIcon;)V")
)
private void angelica$normalXNeg(RenderBlocks instance, Block block, double x, double y, double z, IIcon icon) {
if (FallingBlockRendering.isActive()) Tessellator.instance.setNormal(-1.0F, 0.0F, 0.0F);
instance.renderFaceXNeg(block, x, y, z, icon);
}
@Redirect(
method = {"renderBlockSandFalling", "renderStandardBlockWithColorMultiplier",
"renderStandardBlockWithAmbientOcclusion", "renderStandardBlockWithAmbientOcclusionPartial"},
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBlocks;renderFaceXPos(Lnet/minecraft/block/Block;DDDLnet/minecraft/util/IIcon;)V")
)
private void angelica$normalXPos(RenderBlocks instance, Block block, double x, double y, double z, IIcon icon) {
if (FallingBlockRendering.isActive()) Tessellator.instance.setNormal(1.0F, 0.0F, 0.0F);
instance.renderFaceXPos(block, x, y, z, icon);
}
}
@@ -0,0 +1,50 @@
package com.gtnewhorizons.angelica.mixins.early.shaders;
import com.gtnewhorizons.angelica.rendering.FallingBlockRendering;
import net.minecraft.client.renderer.RenderBlocks;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
/**
* Replace vanilla's baked per-face directional shading while a falling block is rendering.
*/
@Mixin(RenderBlocks.class)
public class MixinRenderBlocks_FallingShading {
@ModifyConstant(
method = {
"renderStandardBlockWithColorMultiplier",
"renderStandardBlockWithAmbientOcclusion",
"renderStandardBlockWithAmbientOcclusionPartial",
"renderBlockSandFalling"
},
constant = @Constant(floatValue = 0.5F))
private float angelica$flattenBottomShading(float original) {
return FallingBlockRendering.skipDirectionalShading() ? 1.0F : original;
}
@ModifyConstant(
method = {
"renderStandardBlockWithColorMultiplier",
"renderStandardBlockWithAmbientOcclusion",
"renderStandardBlockWithAmbientOcclusionPartial",
"renderBlockSandFalling"
},
constant = @Constant(floatValue = 0.8F))
private float angelica$flattenNorthSouthShading(float original) {
return FallingBlockRendering.skipDirectionalShading() ? 1.0F : original;
}
@ModifyConstant(
method = {
"renderStandardBlockWithColorMultiplier",
"renderStandardBlockWithAmbientOcclusion",
"renderStandardBlockWithAmbientOcclusionPartial",
"renderBlockSandFalling"
},
constant = @Constant(floatValue = 0.6F))
private float angelica$flattenEastWestShading(float original) {
return FallingBlockRendering.skipDirectionalShading() ? 1.0F : original;
}
}
@@ -0,0 +1,42 @@
package com.gtnewhorizons.angelica.mixins.early.shaders;
import com.gtnewhorizon.gtnhlib.client.renderer.TessellatorManager;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import net.coderbot.iris.uniforms.CapturedRenderingState;
import net.coderbot.iris.uniforms.ItemIdManager;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import org.spongepowered.asm.mixin.Mixin;
/**
* Sets the currentRenderedItem ID for blocks drawn outside of terrain.
*/
@Mixin(value = RenderBlocks.class, priority = 1500)
public class MixinRenderBlocks_ItemId {
@WrapMethod(method = "renderBlockAsItem")
private void iris$blockItemId(Block block, int metadata, float brightness, Operation<Void> original) {
// renderBlockAsItem is shared with GUI and HUD item rendering
if (!ItemIdManager.isWorldRenderActive() || !TessellatorManager.isOnMainThread()) {
original.call(block, metadata, brightness);
return;
}
final int prevItemId = ItemIdManager.getItemId();
final int prevBlockEntityId = CapturedRenderingState.INSTANCE.getCurrentRenderedBlockEntity();
CapturedRenderingState.INSTANCE.setCurrentBlockEntity(1);
if (prevItemId <= 0) {
ItemIdManager.setBlockId(block, metadata);
}
try {
original.call(block, metadata, brightness);
} finally {
ItemIdManager.setItemIdRaw(prevItemId);
CapturedRenderingState.INSTANCE.setCurrentBlockEntity(prevBlockEntityId);
}
}
}
@@ -0,0 +1,76 @@
package com.gtnewhorizons.angelica.mixins.early.shaders;
import com.gtnewhorizons.angelica.rendering.FallingBlockMetaAccess;
import com.gtnewhorizons.angelica.rendering.FallingBlockRendering;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.coderbot.iris.layer.GbufferPrograms;
import net.coderbot.iris.pipeline.WorldRenderingPhase;
import net.coderbot.iris.uniforms.CapturedRenderingState;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderFallingBlock;
import net.minecraft.entity.item.EntityFallingBlock;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
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;
/**
* Renders falling blocks through terrain.
*/
@Mixin(RenderFallingBlock.class)
public class MixinRenderFallingBlock {
@Inject(method = "doRender(Lnet/minecraft/entity/item/EntityFallingBlock;DDDFF)V", at = @At("HEAD"))
private void angelica$beginFallingBlock(EntityFallingBlock entity, double x, double y, double z, float entityYaw, float partialTicks, CallbackInfo ci) {
FallingBlockRendering.active = true;
CapturedRenderingState.INSTANCE.setCurrentBlockEntity(0);
GbufferPrograms.setOverridePhase(WorldRenderingPhase.TERRAIN_SOLID);
FallingBlockRendering.setEntityAttribute(entity.func_145805_f(), entity.field_145814_a);
}
@Inject(method = "doRender(Lnet/minecraft/entity/item/EntityFallingBlock;DDDFF)V", at = @At("RETURN"))
private void angelica$endFallingBlock(EntityFallingBlock entity, double x, double y, double z, float entityYaw, float partialTicks, CallbackInfo ci) {
FallingBlockRendering.active = false;
FallingBlockRendering.resetEntityAttribute();
GbufferPrograms.setOverridePhase(null);
CapturedRenderingState.INSTANCE.setCurrentBlockEntity(0);
}
@WrapOperation(
method = "doRender(Lnet/minecraft/entity/item/EntityFallingBlock;DDDFF)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBlocks;renderBlockSandFalling(Lnet/minecraft/block/Block;Lnet/minecraft/world/World;IIII)V")
)
private void angelica$aoFallingBlock(RenderBlocks renderBlocks, Block block, World world, int x, int y, int z, int metadata, Operation<Void> original) {
if (!FallingBlockRendering.isActive()) {
original.call(renderBlocks, block, world, x, y, z, metadata);
return;
}
final IBlockAccess prevAccess = renderBlocks.blockAccess;
final boolean prevRenderAllFaces = renderBlocks.renderAllFaces;
final FallingBlockMetaAccess access = FallingBlockRendering.metaAccess(world, x, y, z, metadata);
renderBlocks.blockAccess = access;
renderBlocks.renderAllFaces = true;
final Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.setTranslation(-x - 0.5D, -y - 0.5D, -z - 0.5D);
try {
renderBlocks.renderStandardBlock(block, x, y, z);
} finally {
tessellator.setTranslation(0.0D, 0.0D, 0.0D);
tessellator.draw();
renderBlocks.renderAllFaces = prevRenderAllFaces;
renderBlocks.blockAccess = prevAccess;
access.clear();
}
}
}
@@ -9,9 +9,7 @@ import net.coderbot.iris.uniforms.ItemIdManager;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.entity.RenderPlayer;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@@ -67,17 +65,4 @@ public class MixinRenderPlayerArmor {
original.call(modelBiped, scale);
ItemIdManager.resetItemId();
}
/**
* Set item ID when rendering held items in third person.
*/
@WrapOperation(
method = "renderEquippedItems(Lnet/minecraft/client/entity/AbstractClientPlayer;F)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ItemRenderer;renderItem(Lnet/minecraft/entity/EntityLivingBase;Lnet/minecraft/item/ItemStack;I)V")
)
private void iris$setHeldItemId(ItemRenderer itemRenderer, EntityLivingBase entity, ItemStack itemStack, int renderPass, Operation<Void> original) {
ItemIdManager.setItemId(itemStack);
original.call(itemRenderer, entity, itemStack, renderPass);
}
}