forked from FabricMC/fabric
[#111] fluid rendering hooks
This commit is contained in:
parent
59147463cc
commit
76d184ea21
10 changed files with 398 additions and 0 deletions
6
fabric-rendering-fluids-v1/build.gradle
Normal file
6
fabric-rendering-fluids-v1/build.gradle
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
archivesBaseName = "fabric-rendering-fluids-v1"
|
||||||
|
version = getSubprojectVersion(project, "0.1.0")
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.api.client.render.fluid.v1;
|
||||||
|
|
||||||
|
import net.minecraft.client.texture.Sprite;
|
||||||
|
import net.minecraft.fluid.FluidState;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.ExtendedBlockView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for handling the rendering of a FluidState.
|
||||||
|
*/
|
||||||
|
public interface FluidRenderHandler {
|
||||||
|
/**
|
||||||
|
* Get the sprites for a fluid being rendered at a given position.
|
||||||
|
* For optimal performance, the sprites should be loaded as part of a
|
||||||
|
* resource reload and *not* looked up every time the method is called!
|
||||||
|
*
|
||||||
|
* The "fabric-textures" module contains sprite rendering facilities, which may come in handy here.
|
||||||
|
*
|
||||||
|
* @param view The world view pertaining to the fluid. May be null!
|
||||||
|
* @param pos The position of the fluid in the world. May be null!
|
||||||
|
* @param state The current state of the fluid.
|
||||||
|
* @return An array of size two: the first entry contains the "still" sprite,
|
||||||
|
* while the second entry contains the "flowing" sprite.
|
||||||
|
*/
|
||||||
|
Sprite[] getFluidSprites(/* Nullable */ ExtendedBlockView view, /* Nullable */ BlockPos pos, FluidState state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the tint color for a fluid being rendered at a given position.
|
||||||
|
*
|
||||||
|
* NOTE: As of right now, our hook cannot handle setting a custom alpha
|
||||||
|
* tint here - as such, it must be contained in the texture itself!
|
||||||
|
*
|
||||||
|
* @param view The world view pertaining to the fluid. May be null!
|
||||||
|
* @param pos The position of the fluid in the world. May be null!
|
||||||
|
* @param state The current state of the fluid.
|
||||||
|
* @return The tint color of the fluid.
|
||||||
|
*/
|
||||||
|
default int getFluidColor(ExtendedBlockView view, BlockPos pos, FluidState state) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.api.client.render.fluid.v1;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.impl.client.render.fluid.FluidRenderHandlerRegistryImpl;
|
||||||
|
import net.minecraft.fluid.Fluid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registry for {@link FluidRenderHandler} instances.
|
||||||
|
*
|
||||||
|
* Notably, this supports querying, overriding and wrapping vanilla fluid
|
||||||
|
* rendering.
|
||||||
|
*/
|
||||||
|
public interface FluidRenderHandlerRegistry {
|
||||||
|
FluidRenderHandlerRegistry INSTANCE = FluidRenderHandlerRegistryImpl.INSTANCE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@link FluidRenderHandler} for a given Fluid.
|
||||||
|
* Supports vanilla and Fabric fluids.
|
||||||
|
*
|
||||||
|
* @param fluid The Fluid.
|
||||||
|
* @return The FluidRenderHandler.
|
||||||
|
*/
|
||||||
|
FluidRenderHandler get(Fluid fluid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a {@link FluidRenderHandler} for a given Fluid.
|
||||||
|
*
|
||||||
|
* @param fluid The Fluid.
|
||||||
|
* @param renderer The FluidRenderHandler.
|
||||||
|
*/
|
||||||
|
void register(Fluid fluid, FluidRenderHandler renderer);
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.impl.client.render.fluid;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler;
|
||||||
|
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
|
||||||
|
import net.minecraft.client.color.world.BiomeColors;
|
||||||
|
import net.minecraft.client.texture.Sprite;
|
||||||
|
import net.minecraft.fluid.Fluid;
|
||||||
|
import net.minecraft.fluid.FluidState;
|
||||||
|
import net.minecraft.fluid.Fluids;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.ExtendedBlockView;
|
||||||
|
import net.minecraft.world.biome.Biomes;
|
||||||
|
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class FluidRenderHandlerRegistryImpl implements FluidRenderHandlerRegistry {
|
||||||
|
public static final FluidRenderHandlerRegistryImpl INSTANCE = new FluidRenderHandlerRegistryImpl();
|
||||||
|
private final Map<Fluid, FluidRenderHandler> handlers = new IdentityHashMap<>();
|
||||||
|
private final Map<Fluid, FluidRenderHandler> modHandlers = new IdentityHashMap<>();
|
||||||
|
|
||||||
|
private FluidRenderHandlerRegistryImpl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FluidRenderHandler get(Fluid fluid) {
|
||||||
|
return handlers.get(fluid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FluidRenderHandler getOverride(Fluid fluid) {
|
||||||
|
return modHandlers.get(fluid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(Fluid fluid, FluidRenderHandler renderer) {
|
||||||
|
handlers.put(fluid, renderer);
|
||||||
|
modHandlers.put(fluid, renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onFluidRendererReload(Sprite[] waterSprites, Sprite[] lavaSprites) {
|
||||||
|
FluidRenderHandler waterHandler = new FluidRenderHandler() {
|
||||||
|
@Override
|
||||||
|
public Sprite[] getFluidSprites(ExtendedBlockView view, BlockPos pos, FluidState state) {
|
||||||
|
return waterSprites;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFluidColor(ExtendedBlockView view, BlockPos pos, FluidState state) {
|
||||||
|
if (view != null && pos != null) {
|
||||||
|
return BiomeColors.getWaterColor(view, pos);
|
||||||
|
} else {
|
||||||
|
return Biomes.DEFAULT.getWaterColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//noinspection Convert2Lambda
|
||||||
|
FluidRenderHandler lavaHandler = new FluidRenderHandler() {
|
||||||
|
@Override
|
||||||
|
public Sprite[] getFluidSprites(ExtendedBlockView view, BlockPos pos, FluidState state) {
|
||||||
|
return lavaSprites;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
register(Fluids.WATER, waterHandler);
|
||||||
|
register(Fluids.FLOWING_WATER, waterHandler);
|
||||||
|
register(Fluids.LAVA, lavaHandler);
|
||||||
|
register(Fluids.FLOWING_LAVA, lavaHandler);
|
||||||
|
handlers.putAll(modHandlers);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.impl.client.render.fluid;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler;
|
||||||
|
import net.minecraft.fluid.FluidState;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.ExtendedBlockView;
|
||||||
|
|
||||||
|
public class FluidRendererHookContainer {
|
||||||
|
public ExtendedBlockView view;
|
||||||
|
public BlockPos pos;
|
||||||
|
public FluidState state;
|
||||||
|
public FluidRenderHandler handler;
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
view = null;
|
||||||
|
pos = null;
|
||||||
|
state = null;
|
||||||
|
handler = null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.mixin.client.render.fluid;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler;
|
||||||
|
import net.fabricmc.fabric.impl.client.render.fluid.FluidRendererHookContainer;
|
||||||
|
import net.fabricmc.fabric.impl.client.render.fluid.FluidRenderHandlerRegistryImpl;
|
||||||
|
import net.minecraft.client.render.BufferBuilder;
|
||||||
|
import net.minecraft.client.render.block.FluidRenderer;
|
||||||
|
import net.minecraft.client.texture.Sprite;
|
||||||
|
import net.minecraft.fluid.FluidState;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.ExtendedBlockView;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Mixin(FluidRenderer.class)
|
||||||
|
public class MixinFluidRenderer {
|
||||||
|
@Shadow
|
||||||
|
private Sprite[] lavaSprites;
|
||||||
|
@Shadow
|
||||||
|
private Sprite[] waterSprites;
|
||||||
|
|
||||||
|
private final ThreadLocal<FluidRendererHookContainer> fabric_renderHandler = ThreadLocal.withInitial(FluidRendererHookContainer::new);
|
||||||
|
|
||||||
|
@Inject(at = @At("RETURN"), method = "onResourceReload")
|
||||||
|
public void onResourceReloadReturn(CallbackInfo info) {
|
||||||
|
FluidRenderHandlerRegistryImpl.INSTANCE.onFluidRendererReload(waterSprites, lavaSprites);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(at = @At("HEAD"), method = "tesselate", cancellable = true)
|
||||||
|
public void tesselate(ExtendedBlockView view, BlockPos pos, BufferBuilder bufferBuilder, FluidState state, CallbackInfoReturnable<Boolean> info) {
|
||||||
|
FluidRendererHookContainer ctr = fabric_renderHandler.get();
|
||||||
|
FluidRenderHandler handler = FluidRenderHandlerRegistryImpl.INSTANCE.getOverride(state.getFluid());
|
||||||
|
if (handler == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ActionResult hResult = handler.tesselate(view, pos, bufferBuilder, state);
|
||||||
|
if (hResult != ActionResult.PASS) {
|
||||||
|
info.setReturnValue(hResult == ActionResult.SUCCESS);
|
||||||
|
return;
|
||||||
|
} */
|
||||||
|
|
||||||
|
ctr.view = view;
|
||||||
|
ctr.pos = pos;
|
||||||
|
ctr.state = state;
|
||||||
|
ctr.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(at = @At("RETURN"), method = "tesselate")
|
||||||
|
public void tesselateReturn(ExtendedBlockView view, BlockPos pos, BufferBuilder bufferBuilder, FluidState state, CallbackInfoReturnable<Boolean> info) {
|
||||||
|
fabric_renderHandler.get().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ModifyVariable(at = @At(value = "INVOKE", target = "net/minecraft/client/render/block/FluidRenderer.isSameFluid(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;Lnet/minecraft/fluid/FluidState;)Z"), method = "tesselate", ordinal = 0)
|
||||||
|
public boolean modLavaCheck(boolean chk) {
|
||||||
|
return fabric_renderHandler.get().handler != null || chk;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ModifyVariable(at = @At(value = "INVOKE", target = "net/minecraft/client/render/block/FluidRenderer.isSameFluid(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;Lnet/minecraft/fluid/FluidState;)Z"), method = "tesselate", ordinal = 0)
|
||||||
|
public Sprite[] modSpriteArray(Sprite[] chk) {
|
||||||
|
FluidRendererHookContainer ctr = fabric_renderHandler.get();
|
||||||
|
return ctr.handler != null ? ctr.handler.getFluidSprites(ctr.view, ctr.pos, ctr.state) : chk;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ModifyVariable(at = @At(value = "CONSTANT", args = "intValue=16", ordinal = 0, shift = At.Shift.BEFORE), method = "tesselate", ordinal = 0)
|
||||||
|
public int modTintColor(int chk) {
|
||||||
|
FluidRendererHookContainer ctr = fabric_renderHandler.get();
|
||||||
|
return ctr.handler != null ? ctr.handler.getFluidColor(ctr.view, ctr.pos, ctr.state) : chk;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"package": "net.fabricmc.fabric.mixin.client.render.fluid",
|
||||||
|
"compatibilityLevel": "JAVA_8",
|
||||||
|
"client": [
|
||||||
|
"MixinFluidRenderer"
|
||||||
|
],
|
||||||
|
"injectors": {
|
||||||
|
"defaultRequire": 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"id": "fabric-rendering-fluids-v1",
|
||||||
|
"version": "${version}",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"depends": {
|
||||||
|
"fabricloader": ">=0.4.0",
|
||||||
|
"fabric-api-base": "*"
|
||||||
|
},
|
||||||
|
"recommends": {
|
||||||
|
"fabric-textures-v0": "*"
|
||||||
|
},
|
||||||
|
"mixins": [
|
||||||
|
"fabric-rendering-fluids-v1.mixins.json"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 FabricMC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.fabricmc.fabric.fluidrender;
|
||||||
|
|
||||||
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.client.render.FluidRenderHandler;
|
||||||
|
import net.fabricmc.fabric.api.client.render.FluidRenderHandlerRegistry;
|
||||||
|
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||||
|
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
|
||||||
|
import net.minecraft.fluid.Fluids;
|
||||||
|
import net.minecraft.resource.ResourceManager;
|
||||||
|
import net.minecraft.resource.ResourceType;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class FluidRendererModClient implements ClientModInitializer, SimpleSynchronousResourceReloadListener {
|
||||||
|
@Override
|
||||||
|
public void onInitializeClient() {
|
||||||
|
ResourceManagerHelper.get(ResourceType.ASSETS).registerReloadListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier getFabricId() {
|
||||||
|
return new Identifier("fabric:fluid_renderer_test");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(ResourceManager rm) {
|
||||||
|
FluidRenderHandler lavaHandler = FluidRenderHandlerRegistry.INSTANCE.get(Fluids.LAVA);
|
||||||
|
FluidRenderHandlerRegistry.INSTANCE.register(Fluids.WATER, lavaHandler);
|
||||||
|
FluidRenderHandlerRegistry.INSTANCE.register(Fluids.FLOWING_WATER, lavaHandler);
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ include 'fabric-networking-blockentity-v0'
|
||||||
include 'fabric-object-builders-v0'
|
include 'fabric-object-builders-v0'
|
||||||
include 'fabric-registry-sync-v0'
|
include 'fabric-registry-sync-v0'
|
||||||
include 'fabric-rendering-v0'
|
include 'fabric-rendering-v0'
|
||||||
|
include 'fabric-rendering-fluids-v1'
|
||||||
include 'fabric-resource-loader-v0'
|
include 'fabric-resource-loader-v0'
|
||||||
include 'fabric-tag-extensions-v0'
|
include 'fabric-tag-extensions-v0'
|
||||||
include 'fabric-textures-v0'
|
include 'fabric-textures-v0'
|
||||||
|
|
Loading…
Reference in a new issue