Skip to content

Commit

Permalink
back by unpopular demand
Browse files Browse the repository at this point in the history
emissives.json works, and is now resourcepackable
  • Loading branch information
TropheusJ committed Oct 10, 2023
1 parent 1232161 commit 4cd4c0a
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
import com.fusionflux.portalcubed.client.packet.PortalCubedClientPackets;
import com.fusionflux.portalcubed.client.render.models.PortalCubedModelLoadingPlugin;
import com.fusionflux.portalcubed.client.render.PortalHud;
import com.fusionflux.portalcubed.client.render.block.EmissiveSpriteRegistry;
import com.fusionflux.portalcubed.client.render.block.entity.*;
import com.fusionflux.portalcubed.client.render.entity.*;
import com.fusionflux.portalcubed.client.render.entity.animatedtextures.AnimatedEntityTextures;
import com.fusionflux.portalcubed.client.render.entity.model.*;
import com.fusionflux.portalcubed.client.render.models.emissive.EmissiveLoader;
import com.fusionflux.portalcubed.client.render.portal.PortalRenderPhase;
import com.fusionflux.portalcubed.client.render.portal.PortalRendererImpl;
import com.fusionflux.portalcubed.client.render.portal.PortalRenderers;
Expand All @@ -38,7 +38,7 @@
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import com.mojang.brigadier.arguments.BoolArgumentType;
import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin;
import net.fabricmc.fabric.api.client.model.loading.v1.PreparableModelLoadingPlugin;
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
import net.fabricmc.fabric.api.client.render.fluid.v1.SimpleFluidRenderHandler;
import net.fabricmc.fabric.api.client.rendering.v1.*;
Expand All @@ -63,7 +63,6 @@
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.GsonHelper;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
Expand Down Expand Up @@ -92,13 +91,10 @@
import org.quiltmc.qsl.networking.api.PacketByteBufs;
import org.quiltmc.qsl.networking.api.client.ClientLoginConnectionEvents;
import org.quiltmc.qsl.networking.api.client.ClientPlayNetworking;

import xyz.amymialee.visiblebarriers.VisibleBarriers;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.text.DecimalFormat;
import java.util.*;

Expand Down Expand Up @@ -158,12 +154,11 @@ public void onInitializeClient(ModContainer mod) {

registerEntityRenderers();
registerColorProviders();
registerEmissiveModels(mod);
PortalCubedClientPackets.registerPackets();
PortalCubedKeyBindings.register();
AnimatedEntityTextures.init();

ModelLoadingPlugin.register(PortalCubedModelLoadingPlugin.INSTANCE);
PreparableModelLoadingPlugin.register(EmissiveLoader.INSTANCE, PortalCubedModelLoadingPlugin.INSTANCE);

HudRenderCallback.EVENT.register(PortalHud::renderPortals);

Expand Down Expand Up @@ -630,22 +625,6 @@ public static void transformCameraIntersectingPortal(Camera camera, Entity camer
}
}

private void registerEmissiveModels(ModContainer mod) {
try (Reader reader = Files.newBufferedReader(mod.getPath("emissives.json"), StandardCharsets.UTF_8)) {
for (final var entry : GsonHelper.parse(reader).entrySet()) {
if (entry.getValue().isJsonArray()) {
for (final var value : entry.getValue().getAsJsonArray()) {
EmissiveSpriteRegistry.register(id(entry.getKey()), id(value.getAsString()));
}
} else {
EmissiveSpriteRegistry.register(id(entry.getKey()), id(entry.getValue().getAsString()));
}
}
} catch (IOException e) {
PortalCubed.LOGGER.error("Failed to load emissives.json", e);
}
}

private void registerColorProviders() {
ColorProviderRegistry.ITEM.register(
(stack, tintIndex) -> tintIndex > 0 ? -1 : ((PortalGun) stack.getItem()).getSidedColor(stack),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.fusionflux.portalcubed.client.render.block;

import com.fusionflux.portalcubed.client.render.models.emissive.EmissiveBakedModel;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.resources.ResourceLocation;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,51 +1,18 @@
package com.fusionflux.portalcubed.client.render.models;

import com.fusionflux.portalcubed.accessor.BlockElementExt;
import com.fusionflux.portalcubed.client.render.models.rendertype.MultiRenderTypeUnbakedModel;
import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin;
import com.fusionflux.portalcubed.client.render.models.emissive.EmissiveData;
import com.fusionflux.portalcubed.client.render.models.emissive.EmissiveWrapper;
import com.fusionflux.portalcubed.client.render.models.rendertype.MultiRenderTypeWrapper;
import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin.Context;
import net.fabricmc.fabric.api.client.model.loading.v1.ModelModifier;
import net.fabricmc.fabric.api.client.model.loading.v1.ModelModifier.BeforeBake;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.fabricmc.fabric.api.client.model.loading.v1.PreparableModelLoadingPlugin;

import net.minecraft.client.renderer.block.model.BlockElement;
import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.client.resources.model.UnbakedModel;

public enum PortalCubedModelLoadingPlugin implements ModelLoadingPlugin {
public enum PortalCubedModelLoadingPlugin implements PreparableModelLoadingPlugin<EmissiveData> {
INSTANCE;

@Override
public void onInitializeModelLoader(Context ctx) {
Event<BeforeBake> beforeBake = ctx.modifyModelBeforeBake();
beforeBake.register(ModelModifier.WRAP_PHASE, MultiRenderTypeWrapper.INSTANCE);
beforeBake.register(ModelModifier.WRAP_PHASE, EmissiveWrapper.INSTANCE);
}

private enum MultiRenderTypeWrapper implements BeforeBake {
INSTANCE;

@Override
public UnbakedModel modifyModelBeforeBake(UnbakedModel model, Context context) {
if (model instanceof BlockModel blockModel) {
for (BlockElement element : blockModel.getElements()) {
RenderMaterial material = ((BlockElementExt) element).portalcubed$getRenderMaterial();
if (material != null) {
return new MultiRenderTypeUnbakedModel(blockModel);
}
}
}

return model;
}
}

private enum EmissiveWrapper implements BeforeBake {
INSTANCE;

@Override
public UnbakedModel modifyModelBeforeBake(UnbakedModel model, Context context) {
return model;
}
public void onInitializeModelLoader(EmissiveData emissiveData, Context ctx) {
ctx.modifyModelBeforeBake().register(ModelModifier.WRAP_PHASE, new MultiRenderTypeWrapper());
ctx.modifyModelAfterBake().register(ModelModifier.WRAP_PHASE, new EmissiveWrapper(emissiveData));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.fusionflux.portalcubed.client.render.models;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import com.fusionflux.portalcubed.PortalCubed;
Expand All @@ -11,26 +12,32 @@
import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.fabricmc.fabric.api.util.TriState;
import org.jetbrains.annotations.Nullable;

import net.minecraft.Util;

public class RenderMaterials {
private static final Renderer renderer = RendererAccess.INSTANCE.getRenderer();
private static final MaterialFinder finder = renderer == null ? null : renderer.materialFinder();
@Nullable
private static final MaterialFinder finder = Util.make(() -> {
Renderer renderer = RendererAccess.INSTANCE.getRenderer();
return renderer == null ? null : renderer.materialFinder();
});

public static final boolean ARE_SUPPORTED = checkSupport();

public static final Map<String, RenderMaterial> BY_NAME = new HashMap<>();

public static final RenderMaterial DEFAULT = makeMaterial("default", BlendMode.DEFAULT, false);
public static final RenderMaterial SOLID = makeMaterial("solid", BlendMode.SOLID, false);
public static final RenderMaterial CUTOUT = makeMaterial("cutout", BlendMode.CUTOUT, false);
public static final RenderMaterial CUTOUT_MIPPED = makeMaterial("cutout_mipped", BlendMode.CUTOUT_MIPPED, false);
public static final RenderMaterial TRANSLUCENT = makeMaterial("translucent", BlendMode.TRANSLUCENT, false);
public static final RenderMaterial DEFAULT = makeMaterial(BlendMode.DEFAULT, false);
public static final RenderMaterial SOLID = makeMaterial(BlendMode.SOLID, false);
public static final RenderMaterial CUTOUT = makeMaterial(BlendMode.CUTOUT, false);
public static final RenderMaterial CUTOUT_MIPPED = makeMaterial(BlendMode.CUTOUT_MIPPED, false);
public static final RenderMaterial TRANSLUCENT = makeMaterial(BlendMode.TRANSLUCENT, false);

public static final RenderMaterial DEFAULT_EMISSIVE = makeMaterial("default_emissive", BlendMode.DEFAULT, true);
public static final RenderMaterial SOLID_EMISSIVE = makeMaterial("solid_emissive", BlendMode.SOLID, true);
public static final RenderMaterial CUTOUT_EMISSIVE = makeMaterial("cutout_emissive", BlendMode.CUTOUT, true);
public static final RenderMaterial CUTOUT_MIPPED_EMISSIVE = makeMaterial("cutout_mipped_emissive", BlendMode.CUTOUT_MIPPED, true);
public static final RenderMaterial TRANSLUCENT_EMISSIVE = makeMaterial("translucent_emissive", BlendMode.TRANSLUCENT, true);
public static final RenderMaterial DEFAULT_EMISSIVE = makeMaterial(BlendMode.DEFAULT, true);
public static final RenderMaterial SOLID_EMISSIVE = makeMaterial(BlendMode.SOLID, true);
public static final RenderMaterial CUTOUT_EMISSIVE = makeMaterial(BlendMode.CUTOUT, true);
public static final RenderMaterial CUTOUT_MIPPED_EMISSIVE = makeMaterial(BlendMode.CUTOUT_MIPPED, true);
public static final RenderMaterial TRANSLUCENT_EMISSIVE = makeMaterial(BlendMode.TRANSLUCENT, true);

public static final String SUPPORTED_TYPES = String.join(", ", BY_NAME.keySet());

Expand All @@ -52,23 +59,25 @@ public static RenderMaterial parse(String name) {
return material;
}

private static RenderMaterial makeMaterial(String name, BlendMode mode, boolean emissive) {
private static RenderMaterial makeMaterial(BlendMode mode, boolean emissive) {
if (finder == null)
return null;

finder.clear().blendMode(mode);
String name = mode.name().toLowerCase(Locale.ROOT);
if (emissive) {
finder.emissive(true)
.disableDiffuse(true)
.ambientOcclusion(TriState.FALSE);
name += "_emissive";
}
RenderMaterial material = finder.find();
BY_NAME.put(name, material);
return material;
}

private static boolean checkSupport() {
if (renderer == null) {
if (finder == null) {
PortalCubed.LOGGER.error("No renderer present, rendering will be wrong. If you have Sodium, install Indium!");
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,108 +1,29 @@
package com.fusionflux.portalcubed.client.render.models.emissive;

import com.fusionflux.portalcubed.client.render.block.EmissiveSpriteRegistry;
import java.util.Collection;

import com.fusionflux.portalcubed.client.render.models.RenderMaterials;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import com.fusionflux.portalcubed.client.render.models.rendertype.MultiRenderTypeBakedModel;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
import net.fabricmc.fabric.api.renderer.v1.model.SpriteFinder;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext.QuadTransform;
import net.fabricmc.fabric.api.util.TriState;
import net.minecraft.client.Minecraft;
import org.apache.commons.lang3.tuple.Triple;

import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.client.resources.model.SimpleBakedModel;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource;
import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Supplier;

public final class EmissiveBakedModel extends ForwardingBakedModel {

private static final Map<ResourceLocation, Function<BakedModel, EmissiveBakedModel>> WRAPPERS = new Object2ObjectOpenHashMap<>();

public static void register(ResourceLocation modelId) {
WRAPPERS.put(modelId, EmissiveBakedModel::new);
}

public static Optional<BakedModel> wrap(ResourceLocation modelId, BakedModel model) {
if (!RenderMaterials.ARE_SUPPORTED)
return Optional.empty();
final Function<BakedModel, EmissiveBakedModel> wrapper = WRAPPERS.get(new ResourceLocation(modelId.getNamespace(), modelId.getPath()));
if (wrapper != null) return Optional.of(wrapper.apply(model));
return Optional.empty();
}

private static final Map<RenderMaterial, RenderMaterial> TO_EMISSIVE = new ConcurrentHashMap<>();

private final QuadTransform emissiveTransform;

EmissiveBakedModel(BakedModel model) {
this.wrapped = model;
this.emissiveTransform = quad -> {
TextureAtlasSprite sprite = getSpriteFinder().find(quad);
if (EmissiveSpriteRegistry.isEmissive(sprite.contents().name())) {
RenderMaterial material = quad.material();
quad.material(getEmissiveMaterial(material));
public class EmissiveBakedModel extends MultiRenderTypeBakedModel {
public EmissiveBakedModel(SimpleBakedModel model, Collection<ResourceLocation> emissiveTextures) {
super(model);
for (int i = 0; i < this.quads.size(); i++) {
Triple<BakedQuad, RenderMaterial, Direction> triple = quads.get(i);
ResourceLocation texture = triple.getLeft().getSprite().contents().name();
if (emissiveTextures.contains(texture)) {
RenderMaterial material = triple.getMiddle();
RenderMaterial emissive = RenderMaterials.get(material.blendMode(), true);
Triple<BakedQuad, RenderMaterial, Direction> newTriple = Triple.of(triple.getLeft(), emissive, triple.getRight());
quads.set(i, newTriple);
}
return true;
};
}

@Override
public boolean isVanillaAdapter() {
return false;
}

@Override
public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier<RandomSource> randomSupplier, RenderContext context) {
context.pushTransform(emissiveTransform);
super.emitBlockQuads(blockView, state, pos, randomSupplier, context);
context.popTransform();
}

@Override
public void emitItemQuads(ItemStack stack, Supplier<RandomSource> randomSupplier, RenderContext context) {
context.pushTransform(emissiveTransform);
super.emitItemQuads(stack, randomSupplier, context);
context.popTransform();
}

@Override
public List<BakedQuad> getQuads(BlockState blockState, Direction face, RandomSource rand) {
throw new UnsupportedOperationException("isVanillaAdapter is false! call emitBlockQuads/emitItemQuads!");
}

public static RenderMaterial getEmissiveMaterial(RenderMaterial base) {
return TO_EMISSIVE.computeIfAbsent(base, EmissiveBakedModel::makeEmissiveMaterial);
}

private static RenderMaterial makeEmissiveMaterial(RenderMaterial base) {
throw new RuntimeException("a");
// return RenderMaterials.FINDER.copyFrom(base)
// .emissive(true)
// .disableDiffuse(true)
// .ambientOcclusion(TriState.FALSE)
// .find();
}

private static SpriteFinder getSpriteFinder() {
TextureAtlas blockAtlas = Minecraft.getInstance()
.getModelManager()
.getAtlas(InventoryMenu.BLOCK_ATLAS);
return SpriteFinder.get(blockAtlas);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.fusionflux.portalcubed.client.render.models.emissive;

import java.util.Collection;

import com.google.common.collect.Multimap;

import net.minecraft.resources.ResourceLocation;

public record EmissiveData(Multimap<ResourceLocation, ResourceLocation> map) {
public Collection<ResourceLocation> getEmissiveTexturesForModel(ResourceLocation modelId) {
return map.get(modelId);
}
}

0 comments on commit 4cd4c0a

Please sign in to comment.