mirror of
https://github.com/wisplite/crystalline-sky.git
synced 2026-10-30 13:32:18 -05:00
Skybox I
basic functioning on fabric
This commit is contained in:
+8
@@ -1,8 +1,11 @@
|
||||
package io.github.slimeistdev.crystalline_sky.fabric;
|
||||
|
||||
import io.github.slimeistdev.crystalline_sky.CrystallineSkyClient;
|
||||
import io.github.slimeistdev.crystalline_sky.fabric.events.RegisterMaterialAtlasesEvent;
|
||||
import io.github.slimeistdev.crystalline_sky.fabric.render_tmp.SkyboxModelLoadingPlugin;
|
||||
import io.github.slimeistdev.crystalline_sky.multiloader.fabric.ItemGroupRegistrationEventImpl;
|
||||
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
|
||||
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineAtlases;
|
||||
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineRenderTypes;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.api.EnvType;
|
||||
@@ -23,9 +26,14 @@ public class CrystallineSkyClientImpl implements ClientModInitializer {
|
||||
ItemGroupRegistrationEventImpl.register();
|
||||
|
||||
Consumer<Block> makeSky = b -> BlockRenderLayerMap.INSTANCE.putBlock(b, CrystallineRenderTypes.SKY);
|
||||
Consumer<Block> makeSkybox = b -> BlockRenderLayerMap.INSTANCE.putBlock(b, CrystallineRenderTypes.SKYBOX);
|
||||
CrystallineBlocks.SKY.onRegistered(makeSky);
|
||||
CrystallineBlocks.WEEPING_SKY.onRegistered(makeSky);
|
||||
CrystallineBlocks.SKYBOX_TEST.onRegistered(makeSkybox);
|
||||
|
||||
ClientTickEvents.END_CLIENT_TICK.register(CrystallineSkyClient::onEndTick);
|
||||
|
||||
RegisterMaterialAtlasesEvent.EVENT.register(ctx -> CrystallineAtlases.register(ctx::addAtlas));
|
||||
SkyboxModelLoadingPlugin.register();
|
||||
}
|
||||
}
|
||||
|
||||
+31
@@ -5,8 +5,10 @@ import com.google.gson.JsonObject;
|
||||
import io.github.slimeistdev.crystalline_sky.CrystallineSky;
|
||||
import io.github.slimeistdev.crystalline_sky.registry.CrystallineBlocks;
|
||||
import io.github.slimeistdev.crystalline_sky.registry.CrystallineItems;
|
||||
import io.github.slimeistdev.crystalline_sky.registry.client.CrystallineAtlases;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.data.models.BlockModelGenerators;
|
||||
import net.minecraft.data.models.ItemModelGenerators;
|
||||
import net.minecraft.data.models.blockstates.MultiVariantGenerator;
|
||||
@@ -24,8 +26,20 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static net.minecraft.data.models.model.TexturedModel.createDefault;
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
public class CrystallineSkyModelProvider extends FabricModelProvider {
|
||||
private static ResourceLocation getSkyboxBlockTexture(Block block) {
|
||||
ResourceLocation resourceLocation = BuiltInRegistries.BLOCK.getKey(block);
|
||||
return resourceLocation.withPrefix("crystalline_sky_skybox/");
|
||||
}
|
||||
|
||||
private static final TexturedModel.Provider SKYBOX_CUBE = createDefault(
|
||||
block -> TextureMapping.cube(getSkyboxBlockTexture(block)),
|
||||
ModelTemplates.CUBE_ALL
|
||||
);
|
||||
|
||||
public CrystallineSkyModelProvider(FabricDataOutput output) {
|
||||
super(output);
|
||||
}
|
||||
@@ -38,6 +52,8 @@ public class CrystallineSkyModelProvider extends FabricModelProvider {
|
||||
|
||||
gen.createAirLikeBlock(CrystallineBlocks.WEEPING_SKY_LIGHT.value(), CrystallineItems.WEEPING_SKY_LIGHT.value());
|
||||
gen.createSimpleFlatItemModel(CrystallineItems.WEEPING_SKY_LIGHT.value());
|
||||
|
||||
registerSkyboxBlock(gen, CrystallineBlocks.SKYBOX_TEST.value());
|
||||
}
|
||||
|
||||
private void registerSkyBlock(BlockModelGenerators gen, Block block) {
|
||||
@@ -54,6 +70,21 @@ public class CrystallineSkyModelProvider extends FabricModelProvider {
|
||||
gen.createSimpleFlatItemModel(block);
|
||||
}
|
||||
|
||||
private void registerSkyboxBlock(BlockModelGenerators gen, Block block) {
|
||||
gen.blockStateOutput.accept(BlockModelGenerators.createSimpleBlock(block, SKYBOX_CUBE.create(
|
||||
block,
|
||||
(id, json) -> {
|
||||
gen.modelOutput.accept(id, () -> {
|
||||
JsonObject root = json.get().getAsJsonObject();
|
||||
root.addProperty("render_type", CrystallineSky.id("skybox").toString());
|
||||
root.addProperty(CrystallineSky.id("atlas").toString(), CrystallineAtlases.SKYBOXES.texture.toString());
|
||||
return root;
|
||||
});
|
||||
}
|
||||
)));
|
||||
gen.createSimpleFlatItemModel(block);
|
||||
}
|
||||
|
||||
private void registerSkyLightBlock(BlockModelGenerators gen, Block block, Item item) {
|
||||
gen.skipAutoItemBlock(block);
|
||||
PropertyDispatch.C1<Integer> singleProperty = PropertyDispatch.property(BlockStateProperties.LEVEL);
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package io.github.slimeistdev.crystalline_sky.fabric.events;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public interface RegisterMaterialAtlasesEvent {
|
||||
Event<RegisterMaterialAtlasesEvent> EVENT = EventFactory.createArrayBacked(RegisterMaterialAtlasesEvent.class, (callbacks) -> (context) -> {
|
||||
for (RegisterMaterialAtlasesEvent callback : callbacks) {
|
||||
callback.run(context);
|
||||
}
|
||||
});
|
||||
|
||||
@ApiStatus.Internal
|
||||
static Map<ResourceLocation, ResourceLocation> gatherMaterialAtlases(Map<ResourceLocation, ResourceLocation> vanillaAtlases) {
|
||||
Map<ResourceLocation, ResourceLocation> atlases = new HashMap<>(vanillaAtlases);
|
||||
EVENT.invoker().run(((atlasLocation, atlasInfoLocation) -> {
|
||||
ResourceLocation oldAtlasInfoLoc = atlases.putIfAbsent(atlasLocation, atlasInfoLocation);
|
||||
if (oldAtlasInfoLoc != null) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Duplicate registration of atlas: %s (old info: %s, new info: %s)",
|
||||
atlasLocation,
|
||||
oldAtlasInfoLoc,
|
||||
atlasInfoLocation));
|
||||
}
|
||||
}));
|
||||
return Map.copyOf(atlases);
|
||||
}
|
||||
|
||||
void run(Context context);
|
||||
|
||||
@FunctionalInterface
|
||||
interface Context {
|
||||
void addAtlas(ResourceLocation atlasLocation, ResourceLocation atlasInfoLocation);
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package io.github.slimeistdev.crystalline_sky.fabric.mixin.client;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import io.github.slimeistdev.crystalline_sky.fabric.events.RegisterMaterialAtlasesEvent;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.resources.model.AtlasSet;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(ModelManager.class)
|
||||
public class ModelManagerMixin {
|
||||
@WrapOperation(method = "<init>", at = @At(value = "NEW", target = "(Ljava/util/Map;Lnet/minecraft/client/renderer/texture/TextureManager;)Lnet/minecraft/client/resources/model/AtlasSet;"))
|
||||
private AtlasSet addCustomAtlases(Map<ResourceLocation, ResourceLocation> atlasMap, TextureManager textureManager, Operation<AtlasSet> original) {
|
||||
return original.call(RegisterMaterialAtlasesEvent.gatherMaterialAtlases(atlasMap), textureManager);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
public class ChunkRenderOverrider_AxiomChunkOverrideLayerMixin {
|
||||
@Inject(method = "fromVanilla", at = @At("HEAD"), cancellable = true)
|
||||
private static void unexplodeSky(RenderType layer, CallbackInfoReturnable<ChunkRenderOverrider.AxiomChunkOverrideLayer> cir) {
|
||||
if (layer == CrystallineRenderTypes.SKY) {
|
||||
if (layer == CrystallineRenderTypes.SKY || layer == CrystallineRenderTypes.SKYBOX) {
|
||||
cir.setReturnValue(ChunkRenderOverrider.AxiomChunkOverrideLayer.CUTOUT_MIPPED);
|
||||
}
|
||||
}
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
package io.github.slimeistdev.crystalline_sky.fabric.render_tmp;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.Renderer;
|
||||
import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.ShadeMode;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.fabricmc.fabric.api.util.TriState;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.RandomSource;
|
||||
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.function.Supplier;
|
||||
|
||||
public class SkyboxBakedModel extends ForwardingBakedModel {
|
||||
private static final RenderMaterial FULL_BRIGHT_MATERIAL;
|
||||
static {
|
||||
Renderer renderer = RendererAccess.INSTANCE.getRenderer();
|
||||
if (renderer == null) {
|
||||
FULL_BRIGHT_MATERIAL = null;
|
||||
} else {
|
||||
FULL_BRIGHT_MATERIAL = renderer.materialFinder()
|
||||
.shadeMode(ShadeMode.VANILLA)
|
||||
.ambientOcclusion(TriState.FALSE)
|
||||
.emissive(true)
|
||||
.disableDiffuse(true)
|
||||
.disableColorIndex(true)
|
||||
.find();
|
||||
}
|
||||
}
|
||||
|
||||
public SkyboxBakedModel(BakedModel wrapped) {
|
||||
super(wrapped);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAmbientOcclusion() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesBlockLight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVanillaAdapter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// copied from net.fabricmc.fabric.impl.renderer.VanillaModelEncoder.emitBlockQuads
|
||||
@Override
|
||||
public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier<RandomSource> randomSupplier, RenderContext context) {
|
||||
/*TextureAtlasSprite sprite = getParticleIcon();
|
||||
float u0 = sprite.getU0();
|
||||
float v0 = sprite.getV0();
|
||||
int u1 = (int) (sprite.getU1() * 0xffff);
|
||||
int v1 = (int) (sprite.getV1() * 0xffff);
|
||||
|
||||
int color = (u1 << 16) | v1;
|
||||
var emitter = context.getEmitter()
|
||||
.square(Direction.UP, 0, 0, 1, 1, 0)
|
||||
.material(FULLBRIGHT_MATERIAL);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
emitter
|
||||
.color(i, color)
|
||||
.lightmap(i, LightTexture.FULL_BRIGHT)
|
||||
.normal(i, 0, 1, 0)
|
||||
.uv(i, u0, v0);
|
||||
}
|
||||
emitter.emit();*/
|
||||
|
||||
QuadEmitter emitter = context.getEmitter();
|
||||
|
||||
for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) {
|
||||
final Direction cullFace = ModelHelper.faceFromIndex(i);
|
||||
|
||||
if (!context.hasTransform() && context.isFaceCulled(cullFace)) {
|
||||
// Skip entire quad list if possible
|
||||
continue;
|
||||
}
|
||||
|
||||
final List<BakedQuad> quads = getQuads(state, cullFace, randomSupplier.get());
|
||||
|
||||
for (final BakedQuad q : quads) {
|
||||
emitter.fromVanilla(q, FULL_BRIGHT_MATERIAL, cullFace); // fixme view bobbing breaks projection, use TextureMatrix to pass a view projection matrix along :)
|
||||
TextureAtlasSprite sprite = q.getSprite();
|
||||
float u0 = sprite.getU0();
|
||||
float v0 = sprite.getV0();
|
||||
int u1 = (int) (sprite.getU1() * 0xffff);
|
||||
int v1 = (int) (sprite.getV1() * 0xffff);
|
||||
int uv1 = (u1 << 16) | v1;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
emitter.uv(j, u0, v0);
|
||||
emitter.color(j, uv1);
|
||||
}
|
||||
emitter.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitItemQuads(ItemStack stack, Supplier<RandomSource> randomSupplier, RenderContext context) {
|
||||
super.emitItemQuads(stack, randomSupplier, context);
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package io.github.slimeistdev.crystalline_sky.fabric.render_tmp;
|
||||
|
||||
import io.github.slimeistdev.crystalline_sky.CrystallineSky;
|
||||
import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class SkyboxModelLoadingPlugin implements ModelLoadingPlugin {
|
||||
private SkyboxModelLoadingPlugin() {}
|
||||
|
||||
@Override
|
||||
public void onInitializeModelLoader(Context pluginContext) {
|
||||
pluginContext.modifyModelAfterBake().register((model, ctx) -> {
|
||||
if (model == null) return null;
|
||||
|
||||
ResourceLocation id = ctx.resourceId();
|
||||
if (id == null) {
|
||||
id = ctx.topLevelId().id();
|
||||
}
|
||||
if (!id.equals(CrystallineSky.id("block/skybox_test"))) return model;
|
||||
|
||||
return new SkyboxBakedModel(model);
|
||||
});
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
ModelLoadingPlugin.register(new SkyboxModelLoadingPlugin());
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
"mixins": [
|
||||
],
|
||||
"client": [
|
||||
"client.ModelManagerMixin",
|
||||
"client.RenderTypeMixin",
|
||||
"client.compat.axiom.ChunkRenderOverrider_AxiomChunkOverrideLayerMixin"
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user