forked from FabricMC/fabric
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Support for Custom ColorResolvers (FabricMC#3503)
* Add support for custom color resolvers * Add ColorResolverRegistry * Fix checkstyle * Statically initialize all BiomeColorCaches
- Loading branch information
1 parent
a67ffb5
commit 6fd945a
Showing
10 changed files
with
341 additions
and
0 deletions.
There are no files selected for viewing
81 changes: 81 additions & 0 deletions
81
...v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/ColorResolverRegistry.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
* Copyright (c) 2016, 2017, 2018, 2019 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.rendering.v1; | ||
|
||
import java.util.Set; | ||
|
||
import org.jetbrains.annotations.UnmodifiableView; | ||
|
||
import net.minecraft.client.color.world.BiomeColors; | ||
import net.minecraft.world.BlockRenderView; | ||
import net.minecraft.world.biome.ColorResolver; | ||
|
||
import net.fabricmc.fabric.impl.client.rendering.ColorResolverRegistryImpl; | ||
|
||
/** | ||
* The registry for custom {@link ColorResolver}s. Custom resolvers must be registered during client initialization for | ||
* them to be usable in {@link BlockRenderView#getColor}. Calling this method may throw an exception if the passed | ||
* resolver is not registered with this class. Vanilla resolvers found in {@link BiomeColors} are automatically | ||
* registered. | ||
* | ||
* <p>Other mods may also require custom resolvers to be registered if they provide additional functionality related to | ||
* color resolvers. | ||
*/ | ||
public final class ColorResolverRegistry { | ||
private ColorResolverRegistry() { | ||
} | ||
|
||
/** | ||
* Registers a custom {@link ColorResolver} for use in {@link BlockRenderView#getColor}. This method should be | ||
* called during client initialization. | ||
* | ||
* @param resolver the resolver to register | ||
*/ | ||
public static void register(ColorResolver resolver) { | ||
ColorResolverRegistryImpl.register(resolver); | ||
} | ||
|
||
/** | ||
* Gets a view of all registered {@link ColorResolver}s, including all vanilla resolvers. | ||
* | ||
* @return a view of all registered resolvers | ||
*/ | ||
@UnmodifiableView | ||
public static Set<ColorResolver> getAllResolvers() { | ||
return ColorResolverRegistryImpl.getAllResolvers(); | ||
} | ||
|
||
/** | ||
* Gets a view of all registered {@link ColorResolver}s, not including vanilla resolvers. | ||
* | ||
* @return a view of all registered custom resolvers | ||
*/ | ||
@UnmodifiableView | ||
public static Set<ColorResolver> getCustomResolvers() { | ||
return ColorResolverRegistryImpl.getCustomResolvers(); | ||
} | ||
|
||
/** | ||
* Checks whether the given {@link ColorResolver} is registered. Vanilla resolvers are always registered. | ||
* | ||
* @param resolver the resolver | ||
* @return whether the given resolver is registered | ||
*/ | ||
public static boolean isRegistered(ColorResolver resolver) { | ||
return getAllResolvers().contains(resolver); | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
.../src/client/java/net/fabricmc/fabric/impl/client/rendering/ColorResolverRegistryImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* Copyright (c) 2016, 2017, 2018, 2019 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.rendering; | ||
|
||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
import java.util.function.Function; | ||
|
||
import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap; | ||
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; | ||
import org.jetbrains.annotations.UnmodifiableView; | ||
|
||
import net.minecraft.client.color.world.BiomeColors; | ||
import net.minecraft.client.world.BiomeColorCache; | ||
import net.minecraft.world.biome.ColorResolver; | ||
|
||
public final class ColorResolverRegistryImpl { | ||
// Includes vanilla resolvers | ||
private static final Set<ColorResolver> ALL_RESOLVERS = new HashSet<>(); | ||
// Does not include vanilla resolvers | ||
private static final Set<ColorResolver> CUSTOM_RESOLVERS = new HashSet<>(); | ||
private static final Set<ColorResolver> ALL_RESOLVERS_VIEW = Collections.unmodifiableSet(ALL_RESOLVERS); | ||
private static final Set<ColorResolver> CUSTOM_RESOLVERS_VIEW = Collections.unmodifiableSet(CUSTOM_RESOLVERS); | ||
|
||
static { | ||
ALL_RESOLVERS.add(BiomeColors.GRASS_COLOR); | ||
ALL_RESOLVERS.add(BiomeColors.FOLIAGE_COLOR); | ||
ALL_RESOLVERS.add(BiomeColors.WATER_COLOR); | ||
} | ||
|
||
private ColorResolverRegistryImpl() { | ||
} | ||
|
||
public static void register(ColorResolver resolver) { | ||
ALL_RESOLVERS.add(resolver); | ||
CUSTOM_RESOLVERS.add(resolver); | ||
} | ||
|
||
@UnmodifiableView | ||
public static Set<ColorResolver> getAllResolvers() { | ||
return ALL_RESOLVERS_VIEW; | ||
} | ||
|
||
@UnmodifiableView | ||
public static Set<ColorResolver> getCustomResolvers() { | ||
return CUSTOM_RESOLVERS_VIEW; | ||
} | ||
|
||
public static Reference2ReferenceMap<ColorResolver, BiomeColorCache> createCustomCacheMap(Function<ColorResolver, BiomeColorCache> cacheFactory) { | ||
Reference2ReferenceOpenHashMap<ColorResolver, BiomeColorCache> map = new Reference2ReferenceOpenHashMap<>(); | ||
|
||
for (ColorResolver resolver : CUSTOM_RESOLVERS) { | ||
map.put(resolver, cacheFactory.apply(resolver)); | ||
} | ||
|
||
map.trim(); | ||
return map; | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
...ering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/ClientWorldMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
* Copyright (c) 2016, 2017, 2018, 2019 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.rendering; | ||
|
||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue; | ||
import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap; | ||
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.Inject; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
|
||
import net.minecraft.client.world.BiomeColorCache; | ||
import net.minecraft.client.world.ClientWorld; | ||
import net.minecraft.util.math.BlockPos; | ||
import net.minecraft.util.math.ChunkPos; | ||
import net.minecraft.world.biome.ColorResolver; | ||
|
||
import net.fabricmc.fabric.impl.client.rendering.ColorResolverRegistryImpl; | ||
|
||
@Mixin(ClientWorld.class) | ||
public abstract class ClientWorldMixin { | ||
// Do not use the vanilla map because it is an Object2ObjectArrayMap. Array maps have O(n) retrievals compared to | ||
// hash maps' O(1) retrievals. If many custom ColorResolvers are registered, this may have a non-negligible | ||
// performance impact. | ||
@Unique | ||
private final Reference2ReferenceMap<ColorResolver, BiomeColorCache> customColorCache = ColorResolverRegistryImpl.createCustomCacheMap(resolver -> new BiomeColorCache(pos -> calculateColor(pos, resolver))); | ||
|
||
@Shadow | ||
public abstract int calculateColor(BlockPos pos, ColorResolver colorResolver); | ||
|
||
@Inject(method = "resetChunkColor(Lnet/minecraft/util/math/ChunkPos;)V", at = @At("RETURN")) | ||
private void onResetChunkColor(ChunkPos chunkPos, CallbackInfo ci) { | ||
for (BiomeColorCache cache : customColorCache.values()) { | ||
cache.reset(chunkPos.x, chunkPos.z); | ||
} | ||
} | ||
|
||
@Inject(method = "reloadColor()V", at = @At("RETURN")) | ||
private void onReloadColor(CallbackInfo ci) { | ||
for (BiomeColorCache cache : customColorCache.values()) { | ||
cache.reset(); | ||
} | ||
} | ||
|
||
@ModifyExpressionValue(method = "getColor(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/biome/ColorResolver;)I", at = @At(value = "INVOKE", target = "it/unimi/dsi/fastutil/objects/Object2ObjectArrayMap.get(Ljava/lang/Object;)Ljava/lang/Object;")) | ||
private Object modifyNullCache(/* BiomeColorCache */ Object cache, BlockPos pos, ColorResolver resolver) { | ||
if (cache == null) { | ||
cache = customColorCache.get(resolver); | ||
|
||
if (cache == null) { | ||
throw new UnsupportedOperationException("ClientWorld.getColor called with unregistered ColorResolver " + resolver); | ||
} | ||
} | ||
|
||
return cache; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
...g-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/CustomColorResolverTestInit.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright (c) 2016, 2017, 2018, 2019 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.test.rendering; | ||
|
||
import net.minecraft.block.AbstractBlock; | ||
import net.minecraft.block.Block; | ||
import net.minecraft.item.BlockItem; | ||
import net.minecraft.item.Item; | ||
import net.minecraft.registry.Registries; | ||
import net.minecraft.registry.Registry; | ||
import net.minecraft.util.Identifier; | ||
|
||
import net.fabricmc.api.ModInitializer; | ||
|
||
public class CustomColorResolverTestInit implements ModInitializer { | ||
public static final Block CUSTOM_COLOR_BLOCK = new Block(AbstractBlock.Settings.create()); | ||
public static final Item CUSTOM_COLOR_BLOCK_ITEM = new BlockItem(CUSTOM_COLOR_BLOCK, new Item.Settings()); | ||
|
||
@Override | ||
public void onInitialize() { | ||
Registry.register(Registries.BLOCK, new Identifier("fabric-rendering-v1-testmod", "custom_color_block"), CUSTOM_COLOR_BLOCK); | ||
Registry.register(Registries.ITEM, new Identifier("fabric-rendering-v1-testmod", "custom_color_block"), CUSTOM_COLOR_BLOCK_ITEM); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
...testmodClient/java/net/fabricmc/fabric/test/rendering/client/CustomColorResolverTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* Copyright (c) 2016, 2017, 2018, 2019 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.test.rendering.client; | ||
|
||
import net.minecraft.world.biome.ColorResolver; | ||
|
||
import net.fabricmc.api.ClientModInitializer; | ||
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry; | ||
import net.fabricmc.fabric.api.client.rendering.v1.ColorResolverRegistry; | ||
import net.fabricmc.fabric.test.rendering.CustomColorResolverTestInit; | ||
|
||
public class CustomColorResolverTest implements ClientModInitializer { | ||
public static final ColorResolver TEST_COLOR_RESOLVER = (biome, x, z) -> { | ||
if (biome.hasPrecipitation()) { | ||
return 0xFFFF00FF; | ||
} else { | ||
return 0xFFFFFF00; | ||
} | ||
}; | ||
|
||
@Override | ||
public void onInitializeClient() { | ||
ColorResolverRegistry.register(TEST_COLOR_RESOLVER); | ||
|
||
ColorProviderRegistry.BLOCK.register((state, world, pos, tintIndex) -> { | ||
if (world != null && pos != null) { | ||
return world.getColor(pos, TEST_COLOR_RESOLVER); | ||
} else { | ||
return -1; | ||
} | ||
}, CustomColorResolverTestInit.CUSTOM_COLOR_BLOCK); | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
...odClient/resources/assets/fabric-rendering-v1-testmod/blockstates/custom_color_block.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"variants": { | ||
"": { "model": "fabric-rendering-v1-testmod:block/custom_color_block" } | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
...dClient/resources/assets/fabric-rendering-v1-testmod/models/block/custom_color_block.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"parent": "block/block", | ||
"textures": { | ||
"all": "fabric-rendering-v1-testmod:block/blank", | ||
"particle": "#all" | ||
}, | ||
"elements": [ | ||
{ "from": [ 0, 0, 0 ], | ||
"to": [ 16, 16, 16 ], | ||
"faces": { | ||
"down": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "cullface": "down" }, | ||
"up": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "tintindex": 0, "cullface": "up" }, | ||
"north": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "cullface": "north" }, | ||
"south": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "cullface": "south" }, | ||
"west": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "cullface": "west" }, | ||
"east": { "uv": [ 0, 0, 16, 16 ], "texture": "#all", "cullface": "east" } | ||
} | ||
} | ||
] | ||
} |
Binary file added
BIN
+83 Bytes
...modClient/resources/assets/fabric-rendering-v1-testmod/textures/block/blank.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.