Wip 19w39a ()

* 19w39a fixes ()

* Bump versions

* Breaks: BlockEntityRendererRegistry and EntityRendererRegistry

* Remove broken parts of rendering, bump major version

* Add renderer-registries, replaces broken parts of rendering api

* Slap a band-aid on renderer/Indigo - won't render properly, but runs

* Bump distribution versions, add renderer-registries to main build

* Clean up blockrenderlayer implementation package name
This commit is contained in:
Modmuss50 2019-09-29 02:07:04 +01:00 committed by grondag
parent 128a6b25c0
commit 9c45b1ef78
58 changed files with 335 additions and 462 deletions
build.gradle
fabric-blockrenderlayer-v1
build.gradle
src/main/java/net/fabricmc/fabric
api/blockrenderlayer/v1
impl/blockrenderlayer
mixin/blockrenderlayer
fabric-item-groups-v0
build.gradle
src/main/java/net/fabricmc/fabric
fabric-loot-tables-v1
fabric-renderer-api-v1
build.gradle
src/main
java/net/fabricmc/fabric
api/renderer/v1
mixin/renderer/client
resources
fabric-renderer-indigo
fabric-renderer-registries-v1
fabric-rendering-fluids-v1
build.gradle
src/main/java/net/fabricmc/fabric/mixin/client/render/fluid
fabric-rendering-v0
fabric-textures-v0
build.gradle
src/main/java/net/fabricmc/fabric/mixin/client/texture
settings.gradle
src/main/resources

View file

@ -12,9 +12,9 @@ plugins {
def ENV = System.getenv()
class Globals {
static def baseVersion = "0.3.4"
static def mcVersion = "19w38b"
static def yarnVersion = "+build.4"
static def baseVersion = "0.4.0"
static def mcVersion = "19w39a"
static def yarnVersion = "+build.1"
}
import org.apache.commons.codec.digest.DigestUtils

View file

@ -1,5 +1,5 @@
archivesBaseName = "fabric-blockrenderlayer-v1"
version = getSubprojectVersion(project, "1.0.0")
version = getSubprojectVersion(project, "1.0.1")
dependencies {
compile project(path: ':fabric-api-base', configuration: 'dev')

View file

@ -16,7 +16,7 @@
package net.fabricmc.fabric.api.blockrenderlayer.v1;
import net.fabricmc.fabric.impl.blockrenderlayer.v1.BlockRenderLayerMapImpl;
import net.fabricmc.fabric.impl.blockrenderlayer.BlockRenderLayerMapImpl;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderLayer;
import net.minecraft.fluid.Fluid;

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package net.fabricmc.fabric.impl.blockrenderlayer.v1;
package net.fabricmc.fabric.impl.blockrenderlayer;
import java.util.function.BiConsumer;

View file

@ -24,7 +24,7 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.fabricmc.fabric.impl.blockrenderlayer.v1.BlockRenderLayerMapImpl;
import net.fabricmc.fabric.impl.blockrenderlayer.BlockRenderLayerMapImpl;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderLayer;
import net.minecraft.fluid.Fluid;

View file

@ -1,5 +1,5 @@
archivesBaseName = "fabric-item-groups-v0"
version = getSubprojectVersion(project, "0.1.2")
version = getSubprojectVersion(project, "0.1.3")
dependencies {
compile project(path: ':fabric-api-base', configuration: 'dev')

View file

@ -60,7 +60,7 @@ public class FabricCreativeGuiComponents {
if (this.visible) {
MinecraftClient minecraftClient = MinecraftClient.getInstance();
minecraftClient.getTextureManager().method_22813(BUTTON_TEX);
minecraftClient.getTextureManager().bindTexture(BUTTON_TEX);
RenderSystem.disableLighting();
RenderSystem.color4f(1F, 1F, 1F, 1F);
this.blit(this.x, this.y, (type == Type.NEXT ? 12 : 0), (active ? 0 : 12), 12, 12);

View file

@ -42,7 +42,7 @@ public abstract class MixinCreativePlayerInventoryGui extends AbstractInventoryS
protected abstract void setSelectedTab(ItemGroup itemGroup_1);
@Shadow
public abstract int method_2469(); /* XXX getSelectedTab XXX */
public abstract int getSelectedTab(); /* XXX getSelectedTab XXX */
// "static" matches selectedTab
private static int fabric_currentPage = 0;
@ -103,7 +103,7 @@ public abstract class MixinCreativePlayerInventoryGui extends AbstractInventoryS
private void fabric_updateSelection() {
int minPos = fabric_getPageOffset(fabric_currentPage);
int maxPos = fabric_getPageOffset(fabric_currentPage + 1) - 1;
int curPos = method_2469();
int curPos = getSelectedTab();
if (curPos < minPos || curPos > maxPos) {
setSelectedTab(ItemGroup.GROUPS[fabric_getPageOffset(fabric_currentPage)]);
@ -129,7 +129,7 @@ public abstract class MixinCreativePlayerInventoryGui extends AbstractInventoryS
}
}
@Inject(method = "method_2471", at = @At("HEAD"), cancellable = true)
@Inject(method = "renderTabTooltipIfHovered", at = @At("HEAD"), cancellable = true)
private void method_2471(ItemGroup itemGroup, int mx, int my, CallbackInfoReturnable<Boolean> info) {
if (!fabric_isGroupVisible(itemGroup)) {
info.setReturnValue(false);
@ -143,7 +143,7 @@ public abstract class MixinCreativePlayerInventoryGui extends AbstractInventoryS
}
}
@Inject(method = "method_2468", at = @At("HEAD"), cancellable = true)
@Inject(method = "renderTabIcon", at = @At("HEAD"), cancellable = true)
private void method_2468(ItemGroup itemGroup, CallbackInfo info) {
if (!fabric_isGroupVisible(itemGroup)) {
info.cancel();

View file

@ -1,5 +1,5 @@
archivesBaseName = "fabric-loot-tables-v1"
version = getSubprojectVersion(project, "0.1.1")
version = getSubprojectVersion(project, "0.1.2")
dependencies {
compile project(path: ':fabric-api-base', configuration: 'dev')

View file

@ -17,7 +17,7 @@
package net.fabricmc.fabric.api.loot.v1;
import net.minecraft.world.loot.LootPool;
import net.minecraft.world.loot.LootSupplier;
import net.minecraft.world.loot.LootTable;
import net.minecraft.world.loot.context.LootContextType;
import net.minecraft.world.loot.function.LootFunction;
@ -28,8 +28,8 @@ import java.util.List;
* Fabric API is present. Contains accessors for various fields.
*/
public interface FabricLootSupplier {
default LootSupplier asVanilla() {
return (LootSupplier) this;
default LootTable asVanilla() {
return (LootTable) this;
}
List<LootPool> getPools();
List<LootFunction> getFunctions();

View file

@ -18,18 +18,18 @@ package net.fabricmc.fabric.api.loot.v1;
import net.fabricmc.fabric.mixin.loot.LootSupplierBuilderHooks;
import net.minecraft.world.loot.LootPool;
import net.minecraft.world.loot.LootSupplier;
import net.minecraft.world.loot.LootTable;
import net.minecraft.world.loot.context.LootContextType;
import net.minecraft.world.loot.function.LootFunction;
import java.util.Collection;
public class FabricLootSupplierBuilder extends LootSupplier.Builder {
public class FabricLootSupplierBuilder extends LootTable.Builder {
private final LootSupplierBuilderHooks extended = (LootSupplierBuilderHooks) this;
protected FabricLootSupplierBuilder() {}
private FabricLootSupplierBuilder(LootSupplier supplier) {
private FabricLootSupplierBuilder(LootTable supplier) {
copyFrom(supplier, true);
}
@ -75,7 +75,7 @@ public class FabricLootSupplierBuilder extends LootSupplier.Builder {
* Copies the pools and functions of the {@code supplier} to this builder.
* This is equal to {@code copyFrom(supplier, false)}.
*/
public FabricLootSupplierBuilder copyFrom(LootSupplier supplier) {
public FabricLootSupplierBuilder copyFrom(LootTable supplier) {
return copyFrom(supplier, false);
}
@ -83,7 +83,7 @@ public class FabricLootSupplierBuilder extends LootSupplier.Builder {
* Copies the pools and functions of the {@code supplier} to this builder.
* If {@code copyType} is true, the {@link FabricLootSupplier#getType type} of the supplier is also copied.
*/
public FabricLootSupplierBuilder copyFrom(LootSupplier supplier, boolean copyType) {
public FabricLootSupplierBuilder copyFrom(LootTable supplier, boolean copyType) {
FabricLootSupplier extendedSupplier = (FabricLootSupplier) supplier;
extended.getPools().addAll(extendedSupplier.getPools());
extended.getFunctions().addAll(extendedSupplier.getFunctions());
@ -99,7 +99,7 @@ public class FabricLootSupplierBuilder extends LootSupplier.Builder {
return new FabricLootSupplierBuilder();
}
public static FabricLootSupplierBuilder of(LootSupplier supplier) {
public static FabricLootSupplierBuilder of(LootTable supplier) {
return new FabricLootSupplierBuilder(supplier);
}
}

View file

@ -22,7 +22,7 @@ import net.fabricmc.fabric.api.loot.v1.FabricLootSupplierBuilder;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.minecraft.world.loot.LootManager;
import net.minecraft.world.loot.LootSupplier;
import net.minecraft.world.loot.LootTable;
/**
* An event handler that is called when loot tables are loaded.
@ -32,7 +32,7 @@ import net.minecraft.world.loot.LootSupplier;
public interface LootTableLoadingCallback {
@FunctionalInterface
interface LootTableSetter {
void set(LootSupplier supplier);
void set(LootTable supplier);
}
final Event<LootTableLoadingCallback> EVENT = EventFactory.createArrayBacked(

View file

@ -17,14 +17,14 @@
package net.fabricmc.fabric.mixin.loot;
import net.minecraft.world.loot.LootPool;
import net.minecraft.world.loot.LootSupplier;
import net.minecraft.world.loot.LootTable;
import net.minecraft.world.loot.function.LootFunction;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
@Mixin(LootSupplier.Builder.class)
@Mixin(LootTable.Builder.class)
public interface LootSupplierBuilderHooks {
@Accessor
List<LootPool> getPools();

View file

@ -24,7 +24,7 @@ import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.profiler.Profiler;
import net.minecraft.world.loot.LootManager;
import net.minecraft.world.loot.LootSupplier;
import net.minecraft.world.loot.LootTable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@ -36,11 +36,11 @@ import java.util.Map;
@Mixin(LootManager.class)
public class MixinLootManager {
@Shadow private Map<Identifier, LootSupplier> suppliers;
@Shadow private Map<Identifier, LootTable> suppliers;
@Inject(method = "method_20712", at = @At("RETURN"))
private void apply(Map<Identifier, JsonObject> objectMap, ResourceManager manager, Profiler profiler, CallbackInfo info) {
Map<Identifier, LootSupplier> newSuppliers = new HashMap<>();
Map<Identifier, LootTable> newSuppliers = new HashMap<>();
suppliers.forEach((id, supplier) -> {
FabricLootSupplierBuilder builder = FabricLootSupplierBuilder.of(supplier);

View file

@ -18,7 +18,7 @@ package net.fabricmc.fabric.mixin.loot;
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplier;
import net.minecraft.world.loot.LootPool;
import net.minecraft.world.loot.LootSupplier;
import net.minecraft.world.loot.LootTable;
import net.minecraft.world.loot.context.LootContextType;
import net.minecraft.world.loot.function.LootFunction;
import org.spongepowered.asm.mixin.Final;
@ -29,7 +29,7 @@ import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.Arrays;
import java.util.List;
@Mixin(LootSupplier.class)
@Mixin(LootTable.class)
public abstract class MixinLootSupplier implements FabricLootSupplier {
@Shadow @Final private LootPool[] pools;
@Shadow @Final private LootFunction[] functions;

View file

@ -1,5 +1,5 @@
archivesBaseName = "fabric-renderer-api-v1"
version = getSubprojectVersion(project, "0.2.1")
version = getSubprojectVersion(project, "0.2.2")
dependencies {
compile project(path: ':fabric-api-base', configuration: 'dev')

View file

@ -30,7 +30,7 @@ public enum BlendMode {
/**
* Fully opaque with depth test, no blending. Used for most normal blocks.
*/
SOLID(BlockRenderLayer.field_9178),
SOLID(BlockRenderLayer.SOLID),
/**
* Pixels with alpha > 0.5 are rendered as if {@code SOLID}. Other pixels are not rendered.
@ -42,13 +42,13 @@ public enum BlendMode {
* Pixels with alpha > 0.5 are rendered as if {@code SOLID}. Other pixels are not rendered.
* Texture mip-map disabled. Used for iron bars, glass and other cutout sprites with hard edges.
*/
CUTOUT(BlockRenderLayer.field_9174),
CUTOUT(BlockRenderLayer.CUTOUT),
/**
* Pixels are blended with the background according to alpha color values. Some performance cost,
* use in moderation. Texture mip-map enabled. Used for stained glass.
*/
TRANSLUCENT(BlockRenderLayer.field_9179);
TRANSLUCENT(BlockRenderLayer.TRANSLUCENT);
public final BlockRenderLayer blockRenderLayer;
@ -57,13 +57,13 @@ public enum BlendMode {
}
public static BlendMode fromRenderLayer(BlockRenderLayer renderLayer) {
if (renderLayer == BlockRenderLayer.field_9178) {
if (renderLayer == BlockRenderLayer.SOLID) {
return SOLID;
} else if (renderLayer == BlockRenderLayer.CUTOUT_MIPPED) {
return CUTOUT_MIPPED;
} else if (renderLayer == BlockRenderLayer.field_9174) {
} else if (renderLayer == BlockRenderLayer.CUTOUT) {
return CUTOUT;
} else if (renderLayer == BlockRenderLayer.field_9179) {
} else if (renderLayer == BlockRenderLayer.TRANSLUCENT) {
return TRANSLUCENT;
} else {
return DEFAULT;

View file

@ -75,12 +75,18 @@ public abstract class ModelHelper {
@SuppressWarnings("unchecked")
final ImmutableList.Builder<BakedQuad>[] builders = new ImmutableList.Builder[7];
for (int i = 0; i < 7; i++) {
builders[i] = ImmutableList.builder();
}
if (mesh == null) {
return null;
}
mesh.forEach(q -> {
final int limit = q.material().spriteDepth();
for (int l = 0; l < limit; l++) {
Direction face = q.cullFace();
builders[face == null ? 6 : face.getId()].add(q.toBakedQuad(l, finder.find(q, l), false));

View file

@ -28,6 +28,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.fabric.impl.renderer.DamageModel;
import net.minecraft.class_4587;
import net.minecraft.class_4588;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.block.BlockModelRenderer;
@ -42,35 +44,36 @@ import net.minecraft.world.BlockRenderView;
*/
@Mixin(BlockRenderManager.class)
public abstract class MixinBlockRenderManager {
@Shadow
private BlockModelRenderer renderer;
@Shadow
private Random random;
// TODO: temporarily disabled - may no longer be needed
// @Shadow
// private BlockModelRenderer renderer;
// @Shadow
// private Random random;
private static final ThreadLocal<MutablePair<DamageModel, BakedModel>> DAMAGE_STATE = ThreadLocal.withInitial(() -> MutablePair.of(new DamageModel(), null));
// private static final ThreadLocal<MutablePair<DamageModel, BakedModel>> DAMAGE_STATE = ThreadLocal.withInitial(() -> MutablePair.of(new DamageModel(), null));
/**
* Intercept the model assignment from getModel() - simpler than capturing entire LVT.
*/
@ModifyVariable(method = "tesselateDamage", at = @At(value = "STORE", ordinal = 0), allow = 1, require = 1)
private BakedModel hookTesselateDamageModel(BakedModel modelIn) {
DAMAGE_STATE.get().right = modelIn;
return modelIn;
}
// /**
// * Intercept the model assignment from getModel() - simpler than capturing entire LVT.
// */
// @ModifyVariable(method = "tesselateDamage", at = @At(value = "STORE", ordinal = 0), allow = 1, require = 1)
// private BakedModel hookTesselateDamageModel(BakedModel modelIn) {
// DAMAGE_STATE.get().right = modelIn;
// return modelIn;
// }
/**
* If the model we just captured is a fabric model, render it using a specialized
* damage render context and cancel rest of the logic. Avoids creating a bunch of
* vanilla quads for complex meshes and honors dynamic model geometry.
*/
@Inject(method = "tesselateDamage", cancellable = true, at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/client/render/block/BlockModels;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BakedModel;"))
private void hookTesselateDamage(BufferBuilder bufferBuilder, BlockState blockState, BlockPos blockPos, Sprite sprite, BlockRenderView blockView, CallbackInfo ci) {
MutablePair<DamageModel, BakedModel> damageState = DAMAGE_STATE.get();
if (damageState.right != null && !((FabricBakedModel) damageState.right).isVanillaAdapter()) {
damageState.left.prepare(damageState.right, sprite, blockState, blockPos);
this.renderer.tesselate(blockView, damageState.left, blockState, blockPos, bufferBuilder, true, this.random, blockState.getRenderingSeed(blockPos));
ci.cancel();
}
}
// /**
// * If the model we just captured is a fabric model, render it using a specialized
// * damage render context and cancel rest of the logic. Avoids creating a bunch of
// * vanilla quads for complex meshes and honors dynamic model geometry.
// */
// @Inject(method = "tesselateDamage", cancellable = true, at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/client/render/block/BlockModels;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BakedModel;"))
// private void hookTesselateDamage(BlockState blockState, BlockPos blockPos, BlockRenderView blockView, class_4587 matrix, class_4588 buffer, CallbackInfo ci) {
// MutablePair<DamageModel, BakedModel> damageState = DAMAGE_STATE.get();
//
// if (damageState.right != null && !((FabricBakedModel) damageState.right).isVanillaAdapter()) {
// damageState.left.prepare(damageState.right, sprite, blockState, blockPos);
// this.renderer.tesselate(blockView, damageState.left, blockState, blockPos, matrix, buffer, true, this.random, blockState.getRenderingSeed(blockPos));
// ci.cancel();
// }
// }
}

View file

@ -17,7 +17,7 @@
],
"depends": {
"fabricloader": ">=0.6.2",
"minecraft": ">=1.15-alpha.19.38.b",
"minecraft": ">=1.15-alpha.19.39.a",
"fabric-api-base": "*"
},
"description": "Defines rendering extensions for dynamic/fancy block and item models.",

View file

@ -1,5 +1,5 @@
archivesBaseName = "fabric-renderer-indigo"
version = getSubprojectVersion(project, "0.2.1")
version = getSubprojectVersion(project, "0.2.2")
dependencies {
compile project(path: ':fabric-api-base', configuration: 'dev')

View file

@ -1,23 +0,0 @@
/*
* 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.indigo.renderer.accessor;
import net.fabricmc.indigo.renderer.mesh.QuadViewImpl;
public interface AccessBufferBuilder {
void fabric_putQuad(QuadViewImpl quad);
}

View file

@ -17,8 +17,7 @@
package net.fabricmc.indigo.renderer.accessor;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.util.math.BlockPos;
public interface AccessChunkRenderer {
void fabric_beginBufferBuilding(BufferBuilder bufferBuilder_1, BlockPos blockPos_1);
void fabric_beginBufferBuilding(BufferBuilder bufferBuilder);
}

View file

@ -59,11 +59,11 @@ public abstract class EncodingFormat {
VERTEX_X = HEADER_STRIDE + 0;
VERTEX_Y = HEADER_STRIDE + 1;
VERTEX_Z = HEADER_STRIDE + 2;
VERTEX_COLOR = HEADER_STRIDE + (format.getColorOffset() >> 2);
VERTEX_U = HEADER_STRIDE + (format.getUvOffset(0) >> 2);
VERTEX_COLOR = HEADER_STRIDE + 4;
VERTEX_U = HEADER_STRIDE + 5;
VERTEX_V = VERTEX_U + 1;
VERTEX_LIGHTMAP = HEADER_STRIDE + (format.getUvOffset(1) >> 2);
VERTEX_NORMAL = HEADER_STRIDE + (format.getNormalOffset() >> 2);
VERTEX_LIGHTMAP = HEADER_STRIDE + 6;
VERTEX_NORMAL = HEADER_STRIDE + 7;
VERTEX_STRIDE = format.getVertexSizeInteger();
QUAD_STRIDE = VERTEX_STRIDE * 4;
QUAD_STRIDE_BYTES = QUAD_STRIDE * 4;

View file

@ -30,9 +30,10 @@ import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.indigo.renderer.accessor.AccessBlockModelRenderer;
import net.fabricmc.indigo.renderer.aocalc.VanillaAoHelper;
import net.fabricmc.indigo.renderer.render.BlockRenderContext;
import net.minecraft.class_4587;
import net.minecraft.class_4588;
import net.minecraft.block.BlockState;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.block.BlockModelRenderer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.util.math.BlockPos;
@ -50,12 +51,12 @@ public abstract class MixinBlockModelRenderer implements AccessBlockModelRendere
private final ThreadLocal<BlockRenderContext> CONTEXTS = ThreadLocal.withInitial(BlockRenderContext::new);
@Inject(at = @At("HEAD"), method = "tesselate", cancellable = true)
private void hookTesselate(BlockRenderView blockView, BakedModel model, BlockState state, BlockPos pos, BufferBuilder buffer, boolean checkSides, Random rand, long seed, CallbackInfoReturnable<Boolean> ci) {
private void hookTesselate(BlockRenderView blockView, BakedModel model, BlockState state, BlockPos pos, class_4587 matrix, class_4588 buffer, boolean checkSides, Random rand, long seed, CallbackInfoReturnable<Boolean> ci) {
if (!((FabricBakedModel) model).isVanillaAdapter()) {
BlockRenderContext context = CONTEXTS.get();
if (!context.isCallingVanilla()) {
ci.setReturnValue(CONTEXTS.get().tesselate((BlockModelRenderer) (Object) this, blockView, model, state, pos, buffer, seed));
ci.setReturnValue(CONTEXTS.get().tesselate((BlockModelRenderer)(Object) this, blockView, model, state, pos, matrix, buffer, checkSides, seed));
}
}
}

View file

@ -1,115 +0,0 @@
/*
* 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.indigo.renderer.mixin;
import java.nio.IntBuffer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import net.fabricmc.indigo.Indigo;
import net.fabricmc.indigo.renderer.accessor.AccessBufferBuilder;
import net.fabricmc.indigo.renderer.mesh.EncodingFormat;
import net.fabricmc.indigo.renderer.mesh.QuadViewImpl;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormatElement;
@Mixin(BufferBuilder.class)
public abstract class MixinBufferBuilder implements AccessBufferBuilder {
@Shadow
private IntBuffer bufInt;
@Shadow
private int vertexCount;
@Shadow
abstract void grow(int size);
@Shadow
abstract int getCurrentSize();
@Shadow
public abstract VertexFormat getVertexFormat();
@Override
public void fabric_putQuad(QuadViewImpl quad) {
if (Indigo.ENSURE_VERTEX_FORMAT_COMPATIBILITY) {
bufferCompatibly(quad);
} else {
bufferFast(quad);
}
}
private void bufferFast(QuadViewImpl quad) {
grow(EncodingFormat.QUAD_STRIDE_BYTES + getVertexFormat().getVertexSize());
bufInt.limit(bufInt.capacity());
bufInt.position(getCurrentSize());
bufInt.put(quad.data(), quad.vertexStart(), EncodingFormat.QUAD_STRIDE);
vertexCount += 4;
}
/**
* Uses buffer vertex format to drive buffer population.
* Relies on logic elsewhere to ensure coordinates don't include chunk offset
* (because buffer builder will handle that.)<p>
*
* Calling putVertexData() would likely be a little faster but this approach
* gives us a chance to pass vertex normals to shaders, which isn't possible
* with the standard block format. It also doesn't require us to encode a specific
* custom format directly, which would be prone to breakage outside our control.
*/
private void bufferCompatibly(QuadViewImpl quad) {
final VertexFormat format = getVertexFormat();
final int elementCount = format.getElementCount();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < elementCount; j++) {
VertexFormatElement e = format.getElement(j);
switch (e.getType()) {
case COLOR:
final int c = quad.spriteColor(i, 0);
((BufferBuilder) (Object) this).color(c & 0xFF, (c >>> 8) & 0xFF, (c >>> 16) & 0xFF, (c >>> 24) & 0xFF);
break;
case NORMAL:
((BufferBuilder) (Object) this).normal(quad.normalX(i), quad.normalY(i), quad.normalZ(i));
break;
case POSITION:
((BufferBuilder) (Object) this).vertex(quad.x(i), quad.y(i), quad.z(i));
break;
case UV:
if (e.getIndex() == 0) {
((BufferBuilder) (Object) this).texture(quad.spriteU(i, 0), quad.spriteV(i, 0));
} else {
final int b = quad.lightmap(i);
((BufferBuilder) (Object) this).texture((b >> 16) & 0xFFFF, b & 0xFFFF);
}
break;
// these types should never occur and/or require no action
case PADDING:
case GENERIC:
default:
break;
}
}
((BufferBuilder) (Object) this).next();
}
}
}

View file

@ -30,6 +30,8 @@ import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.indigo.Indigo;
import net.fabricmc.indigo.renderer.accessor.AccessChunkRendererRegion;
import net.fabricmc.indigo.renderer.render.TerrainRenderContext;
import net.minecraft.class_4587;
import net.minecraft.class_4588;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
@ -91,17 +93,19 @@ public class MixinChunkRebuildTask {
* Normally this does nothing but will allow mods to create rendering hooks that are
* driven off of render type. (Not recommended or encouraged, but also not prevented.)
*/
@Redirect(method = "method_22785", require = 1, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockRenderManager;tesselateBlock(Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/BlockRenderView;Lnet/minecraft/client/render/BufferBuilder;Ljava/util/Random;)Z"))
private boolean hookChunkBuildTesselate(BlockRenderManager renderManager, BlockState blockState, BlockPos blockPos, BlockRenderView blockView, BufferBuilder bufferBuilder, Random random) {
if (blockState.getRenderType() == BlockRenderType.MODEL) {
final BakedModel model = renderManager.getModel(blockState);
@Redirect(method = "method_22785", require = 1, at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/render/block/BlockRenderManager;tesselateBlock(Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/BlockRenderView;Lnet/minecraft/class_4587;Lnet/minecraft/class_4588;ZLjava/util/Random;)Z"))
private boolean hookChunkBuildTesselate(BlockRenderManager renderManager, BlockState blockState, BlockPos blockPos, BlockRenderView blockView, class_4587 matrix, class_4588 bufferBuilder, boolean checkSides, Random random) {
// TODO: temporarily disabled
// if (blockState.getRenderType() == BlockRenderType.MODEL) {
// final BakedModel model = renderManager.getModel(blockState);
//
// if (Indigo.ALWAYS_TESSELATE_INDIGO || !((FabricBakedModel) model).isVanillaAdapter()) {
// return ((AccessChunkRendererRegion) blockView).fabric_getRenderer().tesselateBlock(blockState, blockPos, model, matrix);
// }
// }
if (Indigo.ALWAYS_TESSELATE_INDIGO || !((FabricBakedModel) model).isVanillaAdapter()) {
return ((AccessChunkRendererRegion) blockView).fabric_getRenderer().tesselateBlock(blockState, blockPos, model);
}
}
return renderManager.tesselateBlock(blockState, blockPos, blockView, bufferBuilder, random);
return renderManager.tesselateBlock(blockState, blockPos, blockView, matrix, bufferBuilder, checkSides, random);
}
/**

View file

@ -22,18 +22,17 @@ import org.spongepowered.asm.mixin.Shadow;
import net.fabricmc.indigo.renderer.accessor.AccessChunkRenderer;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.chunk.ChunkBatcher.ChunkRenderer;
import net.minecraft.util.math.BlockPos;
@Mixin(ChunkRenderer.class)
public abstract class MixinChunkRenderer implements AccessChunkRenderer {
@Shadow
abstract void beginBufferBuilding(BufferBuilder builder, BlockPos pos);
abstract void beginBufferBuilding(BufferBuilder builder);
/**
* Access method for renderer.
*/
@Override
public void fabric_beginBufferBuilding(BufferBuilder builder, BlockPos pos) {
beginBufferBuilding(builder, pos);
public void fabric_beginBufferBuilding(BufferBuilder builder) {
beginBufferBuilding(builder);
}
}

View file

@ -16,50 +16,38 @@
package net.fabricmc.indigo.renderer.mixin;
import java.util.List;
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.callback.CallbackInfo;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.indigo.renderer.render.ItemRenderContext;
import net.minecraft.client.color.item.ItemColors;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.item.ItemStack;
@Mixin(ItemRenderer.class)
public abstract class MixinItemRenderer {
@Shadow
protected abstract void renderQuads(BufferBuilder bufferBuilder, List<BakedQuad> quads, int color, ItemStack stack);
@Shadow
protected ItemColors colorMap;
private final ThreadLocal<ItemRenderContext> CONTEXTS = ThreadLocal.withInitial(() -> new ItemRenderContext(colorMap));
/**
* Save stack for enchantment glint renders - we won't otherwise have access to it
* during the glint render because it receives an empty stack.
*/
@Inject(at = @At("HEAD"), method = "renderItemAndGlow")
private void hookRenderItemAndGlow(ItemStack stack, BakedModel model, CallbackInfo ci) {
if (stack.hasEnchantmentGlint() && !((FabricBakedModel) model).isVanillaAdapter()) {
CONTEXTS.get().enchantmentStack = stack;
}
}
@Inject(at = @At("HEAD"), method = "renderModel", cancellable = true)
private void hookRenderModel(BakedModel model, int color, ItemStack stack, CallbackInfo ci) {
final FabricBakedModel fabricModel = (FabricBakedModel) model;
if (!fabricModel.isVanillaAdapter()) {
CONTEXTS.get().renderModel(fabricModel, color, stack, this::renderQuads);
ci.cancel();
}
}
// TODO: temporarily disabled
// @Shadow
// protected abstract void renderQuads(BufferBuilder bufferBuilder, List<BakedQuad> quads, int color, ItemStack stack);
//
// @Shadow
// protected ItemColors colorMap;
// private final ThreadLocal<ItemRenderContext> CONTEXTS = ThreadLocal.withInitial(() -> new ItemRenderContext(colorMap));
//
// /**
// * Save stack for enchantment glint renders - we won't otherwise have access to it
// * during the glint render because it receives an empty stack.
// */
// @Inject(at = @At("HEAD"), method = "renderItemAndGlow")
// private void hookRenderItemAndGlow(ItemStack stack, BakedModel model, CallbackInfo ci) {
// if (stack.hasEnchantmentGlint() && !((FabricBakedModel) model).isVanillaAdapter()) {
// CONTEXTS.get().enchantmentStack = stack;
// }
// }
//
// @Inject(at = @At("HEAD"), method = "renderModel", cancellable = true)
// private void hookRenderModel(BakedModel model, int color, ItemStack stack, CallbackInfo ci) {
// final FabricBakedModel fabricModel = (FabricBakedModel) model;
//
// if (!fabricModel.isVanillaAdapter()) {
// CONTEXTS.get().renderModel(fabricModel, color, stack, this::renderQuads);
// ci.cancel();
// }
// }
}

View file

@ -24,7 +24,6 @@ import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext.QuadTransform;
import net.fabricmc.indigo.renderer.IndigoRenderer;
import net.fabricmc.indigo.renderer.RenderMaterialImpl;
import net.fabricmc.indigo.renderer.accessor.AccessBufferBuilder;
import net.fabricmc.indigo.renderer.aocalc.AoCalculator;
import net.fabricmc.indigo.renderer.helper.ColorHelper;
import net.fabricmc.indigo.renderer.helper.GeometryHelper;
@ -33,13 +32,14 @@ import net.fabricmc.indigo.renderer.mesh.MeshImpl;
import net.fabricmc.indigo.renderer.mesh.MutableQuadViewImpl;
import net.minecraft.block.BlockRenderLayer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.BufferBuilder;
/**
* Consumer for pre-baked meshes. Works by copying the mesh data to a
* "editor" quad held in the instance, where all transformations are applied before buffering.
*/
public abstract class AbstractMeshConsumer extends AbstractQuadRenderer implements Consumer<Mesh> {
protected AbstractMeshConsumer(BlockRenderInfo blockInfo, Function<BlockRenderLayer, AccessBufferBuilder> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
protected AbstractMeshConsumer(BlockRenderInfo blockInfo, Function<BlockRenderLayer, BufferBuilder> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
super(blockInfo, bufferFunc, aoCalc, transform);
}
@ -102,13 +102,9 @@ public abstract class AbstractMeshConsumer extends AbstractQuadRenderer implemen
aoCalc.compute(q, false);
}
applyOffsets(q);
tesselateQuad(q, mat, 0);
}
protected abstract void applyOffsets(MutableQuadViewImpl quad);
/**
* Determines color index and render layer, then routes to appropriate
* tesselate routine based on material properties.

View file

@ -21,13 +21,14 @@ import static net.fabricmc.indigo.renderer.helper.GeometryHelper.LIGHT_FACE_FLAG
import java.util.function.Function;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext.QuadTransform;
import net.fabricmc.indigo.renderer.accessor.AccessBufferBuilder;
import net.fabricmc.indigo.renderer.aocalc.AoCalculator;
import net.fabricmc.indigo.renderer.helper.ColorHelper;
import net.fabricmc.indigo.renderer.mesh.MutableQuadViewImpl;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderLayer;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.util.math.Matrix4f;
import net.minecraft.util.math.BlockPos;
/**
@ -37,12 +38,14 @@ import net.minecraft.util.math.BlockPos;
public abstract class AbstractQuadRenderer {
static final int FULL_BRIGHTNESS = 0xF000F0;
protected final Function<BlockRenderLayer, AccessBufferBuilder> bufferFunc;
protected final Function<BlockRenderLayer, BufferBuilder> bufferFunc;
protected final BlockRenderInfo blockInfo;
protected final AoCalculator aoCalc;
protected final QuadTransform transform;
AbstractQuadRenderer(BlockRenderInfo blockInfo, Function<BlockRenderLayer, AccessBufferBuilder> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
protected abstract Matrix4f matrix();
AbstractQuadRenderer(BlockRenderInfo blockInfo, Function<BlockRenderLayer, BufferBuilder> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
this.blockInfo = blockInfo;
this.bufferFunc = bufferFunc;
this.aoCalc = aoCalc;
@ -65,7 +68,19 @@ public abstract class AbstractQuadRenderer {
/** final output step, common to all renders */
private void bufferQuad(MutableQuadViewImpl quad, BlockRenderLayer renderLayer) {
bufferFunc.apply(renderLayer).fabric_putQuad(quad);
bufferQuad(bufferFunc.apply(renderLayer), quad, matrix());
}
public static void bufferQuad(BufferBuilder buff, MutableQuadViewImpl quad, Matrix4f matrix) {
for (int i = 0; i < 4; i++) {
buff.method_22918(matrix, quad.x(i), quad.y(i), quad.z(i));
final int color = quad.spriteColor(i, 0);
buff.color(color & 0xFF, (color >> 8) & 0xFF, (color >> 16) & 0xFF, (color >> 24) & 0xFF);
buff.method_22913(quad.spriteU(i, 0), quad.spriteV(i, 0));
buff.method_22916(quad.lightmap(i));
buff.method_22914(quad.normalX(i),quad.normalY(i), quad.normalZ(i));
buff.next();
}
}
// routines below have a bit of copy-paste code reuse to avoid conditional execution inside a hot loop

View file

@ -19,10 +19,26 @@ package net.fabricmc.indigo.renderer.render;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.minecraft.class_4587;
import net.minecraft.block.BlockState;
import net.minecraft.client.util.math.Matrix4f;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.BlockRenderView;
abstract class AbstractRenderContext implements RenderContext {
private final ObjectArrayList<QuadTransform> transformStack = new ObjectArrayList<>();
private static final QuadTransform NO_TRANSFORM = (q) -> true;
protected class_4587 matrixStack;
protected Matrix4f matrix;
protected void prepareMatrix(BlockState blockState, BlockPos blockPos, BlockRenderView blockView, class_4587 matrixStack) {
this.matrixStack = matrixStack;
Vec3d vec = blockState.getOffsetPos(blockView, blockPos);
matrixStack.method_22903();
matrixStack.method_22904((double)(blockPos.getX() & 15) + vec.x, (double)(blockPos.getY() & 15) + vec.y, (double)(blockPos.getZ() & 15) + vec.z);
matrix = matrixStack.method_22910();
}
private final QuadTransform stackTransform = (q) -> {
int i = transformStack.size() - 1;

View file

@ -24,16 +24,16 @@ import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.fabricmc.indigo.renderer.accessor.AccessBufferBuilder;
import net.fabricmc.indigo.renderer.aocalc.AoCalculator;
import net.fabricmc.indigo.renderer.aocalc.AoLuminanceFix;
import net.fabricmc.indigo.renderer.mesh.MutableQuadViewImpl;
import net.fabricmc.indigo.renderer.mixin.BufferBuilderOffsetAccessor;
import net.minecraft.class_4587;
import net.minecraft.class_4588;
import net.minecraft.block.BlockRenderLayer;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.block.BlockModelRenderer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.util.math.Matrix4f;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockRenderView;
@ -46,15 +46,11 @@ public class BlockRenderContext extends AbstractRenderContext implements RenderC
private final MeshConsumer meshConsumer = new MeshConsumer(blockInfo, this::outputBuffer, aoCalc, this::transform);
private final Random random = new Random();
private BlockModelRenderer vanillaRenderer;
private AccessBufferBuilder fabricBuffer;
private BufferBuilder bufferBuilder;
private long seed;
private boolean isCallingVanilla = false;
private boolean didOutput = false;
private double offsetX;
private double offsetY;
private double offsetZ;
public boolean isCallingVanilla() {
return isCallingVanilla;
}
@ -72,57 +68,47 @@ public class BlockRenderContext extends AbstractRenderContext implements RenderC
return blockView == null ? 1f : AoLuminanceFix.INSTANCE.apply(blockView, pos);
}
private AccessBufferBuilder outputBuffer(BlockRenderLayer renderLayer) {
private BufferBuilder outputBuffer(BlockRenderLayer renderLayer) {
didOutput = true;
return fabricBuffer;
return bufferBuilder;
}
public boolean tesselate(BlockModelRenderer vanillaRenderer, BlockRenderView blockView, BakedModel model, BlockState state, BlockPos pos, BufferBuilder buffer, long seed) {
public boolean tesselate(BlockModelRenderer vanillaRenderer, BlockRenderView blockView, BakedModel model, BlockState state, BlockPos pos, class_4587 matrixStack, class_4588 buffer, boolean checkSides, long seed) {
this.vanillaRenderer = vanillaRenderer;
this.fabricBuffer = (AccessBufferBuilder) buffer;
this.bufferBuilder = (BufferBuilder) buffer;
this.prepareMatrix(state, pos, blockView, matrixStack);
this.seed = seed;
this.didOutput = false;
aoCalc.clear();
blockInfo.setBlockView(blockView);
blockInfo.prepareForBlock(state, pos, model.useAmbientOcclusion());
setupOffsets();
((FabricBakedModel) model).emitBlockQuads(blockView, state, pos, blockInfo.randomSupplier, this);
this.vanillaRenderer = null;
blockInfo.release();
this.fabricBuffer = null;
this.bufferBuilder = null;
matrixStack.method_22909();
return didOutput;
}
protected void acceptVanillaModel(BakedModel model) {
isCallingVanilla = true;
didOutput = didOutput && vanillaRenderer.tesselate(blockInfo.blockView, model, blockInfo.blockState, blockInfo.blockPos, (BufferBuilder) fabricBuffer, false, random, seed);
didOutput = didOutput && vanillaRenderer.tesselate(blockInfo.blockView, model, blockInfo.blockState, blockInfo.blockPos, matrixStack, (class_4588) bufferBuilder, false, random, seed);
isCallingVanilla = false;
}
private void setupOffsets() {
final BufferBuilderOffsetAccessor buffer = (BufferBuilderOffsetAccessor) fabricBuffer;
final BlockPos pos = blockInfo.blockPos;
offsetX = buffer.getOffsetX() + pos.getX();
offsetY = buffer.getOffsetY() + pos.getY();
offsetZ = buffer.getOffsetZ() + pos.getZ();
}
private class MeshConsumer extends AbstractMeshConsumer {
MeshConsumer(BlockRenderInfo blockInfo, Function<BlockRenderLayer, AccessBufferBuilder> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
MeshConsumer(BlockRenderInfo blockInfo, Function<BlockRenderLayer, BufferBuilder> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
super(blockInfo, bufferFunc, aoCalc, transform);
}
@Override
protected void applyOffsets(MutableQuadViewImpl q) {
final double x = offsetX;
final double y = offsetY;
final double z = offsetZ;
for (int i = 0; i < 4; i++) {
q.pos(i, (float) (q.x(i) + x), (float) (q.y(i) + y), (float) (q.z(i) + z));
}
protected Matrix4f matrix() {
return matrix;
}
}

View file

@ -20,7 +20,6 @@ import it.unimi.dsi.fastutil.longs.Long2FloatOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.fabricmc.indigo.Indigo;
import net.fabricmc.indigo.renderer.accessor.AccessBufferBuilder;
import net.fabricmc.indigo.renderer.accessor.AccessChunkRenderer;
import net.fabricmc.indigo.renderer.accessor.AccessChunkRendererData;
import net.fabricmc.indigo.renderer.aocalc.AoLuminanceFix;
@ -77,7 +76,7 @@ public class ChunkRenderInfo {
BlockLayeredBufferBuilder builders;
BlockRenderView blockView;
private final Object2ObjectOpenHashMap<BlockRenderLayer, AccessBufferBuilder> buffers = new Object2ObjectOpenHashMap<>();
private final Object2ObjectOpenHashMap<BlockRenderLayer, BufferBuilder> buffers = new Object2ObjectOpenHashMap<>();
private double chunkOffsetX;
private double chunkOffsetY;
@ -141,17 +140,17 @@ public class ChunkRenderInfo {
}
/** Lazily retrieves output buffer for given layer, initializing as needed. */
public AccessBufferBuilder getInitializedBuffer(BlockRenderLayer renderLayer) {
AccessBufferBuilder result = buffers.get(renderLayer);
public BufferBuilder getInitializedBuffer(BlockRenderLayer renderLayer) {
BufferBuilder result = buffers.get(renderLayer);
if (result == null) {
BufferBuilder builder = builders.get(renderLayer);
result = (AccessBufferBuilder) builder;
result = (BufferBuilder) builder;
chunkData.fabric_markPopulated(renderLayer);
buffers.put(renderLayer, result);
if (chunkData.fabric_markInitialized(renderLayer)) {
((AccessChunkRenderer) chunkRenderer).fabric_beginBufferBuilding(builder, chunkOrigin);
((AccessChunkRenderer) chunkRenderer).fabric_beginBufferBuilding(builder);
}
}
return result;

View file

@ -32,7 +32,6 @@ import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.fabricmc.indigo.renderer.RenderMaterialImpl;
import net.fabricmc.indigo.renderer.accessor.AccessBufferBuilder;
import net.fabricmc.indigo.renderer.helper.ColorHelper;
import net.fabricmc.indigo.renderer.helper.GeometryHelper;
import net.fabricmc.indigo.renderer.mesh.EncodingFormat;
@ -45,6 +44,7 @@ import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.util.math.Matrix4f;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.Direction;
@ -67,7 +67,6 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
private final Random random = new Random();
private final Consumer<BakedModel> fallbackConsumer;
BufferBuilder bufferBuilder;
AccessBufferBuilder fabricBuffer;
private int color;
private ItemStack itemStack;
private VanillaQuadHandler vanillaHandler;
@ -109,7 +108,6 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
this.vanillaHandler = vanillaHandler;
Tessellator tessellator = Tessellator.getInstance();
bufferBuilder = tessellator.getBufferBuilder();
fabricBuffer = (AccessBufferBuilder) this.bufferBuilder;
bufferBuilder.begin(7, VertexFormats.POSITION_COLOR_UV_NORMAL);
model.emitItemQuads(stack, randomSupplier, this);
@ -121,7 +119,6 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
}
bufferBuilder = null;
fabricBuffer = null;
tessellator = null;
this.itemStack = null;
this.vanillaHandler = null;
@ -137,7 +134,8 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
public Maker emit() {
lightFace(GeometryHelper.lightFace(this));
ColorHelper.applyDiffuseShading(this, false);
renderQuad();
//TODO: populate
renderQuad(null);
clear();
return this;
}
@ -155,7 +153,8 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
System.arraycopy(data, index, editorQuad.data(), 0, EncodingFormat.TOTAL_STRIDE);
editorQuad.load();
index += EncodingFormat.TOTAL_STRIDE;
renderQuad();
//TODO: populate
renderQuad(null);
}
};
@ -185,7 +184,7 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
return quadColor;
}
private void colorizeAndOutput(int quadColor) {
private void colorizeAndOutput(int quadColor, Matrix4f matrix) {
final MutableQuadViewImpl q = editorQuad;
for (int i = 0; i < 4; i++) {
@ -194,10 +193,10 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
q.spriteColor(i, 0, ColorHelper.swapRedBlueIfNeeded(c));
}
fabricBuffer.fabric_putQuad(q);
AbstractQuadRenderer.bufferQuad(bufferBuilder, q, matrix);
}
private void renderQuad() {
private void renderQuad(Matrix4f matrix) {
final MutableQuadViewImpl quad = editorQuad;
if (!transform(editorQuad)) {
@ -212,7 +211,7 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
quad.populateMissingNormals();
quad.lightmap(FULL_BRIGHTNESS, FULL_BRIGHTNESS, FULL_BRIGHTNESS, FULL_BRIGHTNESS);
colorizeAndOutput(!enchantment && mat.disableColorIndex(0) ? -1 : quadColor);
colorizeAndOutput(!enchantment && mat.disableColorIndex(0) ? -1 : quadColor, matrix);
}
@Override
@ -252,7 +251,8 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
editorQuad.lightFace(lightFace);
editorQuad.nominalFace(lightFace);
editorQuad.colorIndex(q.getColorIndex());
renderQuad();
//TODO: populate
renderQuad(null);
}
} else {
vanillaHandler.accept(bufferBuilder, quads, color, stack);

View file

@ -33,6 +33,7 @@ import net.fabricmc.indigo.renderer.mesh.MutableQuadViewImpl;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.util.math.Matrix4f;
import net.minecraft.util.math.Direction;
/**
@ -60,10 +61,17 @@ public class TerrainFallbackConsumer extends AbstractQuadRenderer implements Con
private final int[] editorBuffer = new int[EncodingFormat.TOTAL_STRIDE];
private final ChunkRenderInfo chunkInfo;
private final Supplier<Matrix4f> matrixSupplier;
TerrainFallbackConsumer(BlockRenderInfo blockInfo, ChunkRenderInfo chunkInfo, AoCalculator aoCalc, QuadTransform transform) {
TerrainFallbackConsumer(BlockRenderInfo blockInfo, ChunkRenderInfo chunkInfo, AoCalculator aoCalc, QuadTransform transform, Supplier<Matrix4f> matrixSupplier) {
super(blockInfo, chunkInfo::getInitializedBuffer, aoCalc, transform);
this.chunkInfo = chunkInfo;
this.matrixSupplier = matrixSupplier;
}
@Override
protected Matrix4f matrix() {
return matrixSupplier.get();
}
private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() {

View file

@ -16,20 +16,22 @@
package net.fabricmc.indigo.renderer.render;
import java.util.function.Supplier;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext.QuadTransform;
import net.fabricmc.indigo.renderer.aocalc.AoCalculator;
import net.fabricmc.indigo.renderer.mesh.MutableQuadViewImpl;
import net.minecraft.client.util.math.Matrix4f;
public class TerrainMeshConsumer extends AbstractMeshConsumer {
private final ChunkRenderInfo chunkInfo;
final Supplier<Matrix4f> matrixSupplier;
TerrainMeshConsumer(TerrainBlockRenderInfo blockInfo, ChunkRenderInfo chunkInfo, AoCalculator aoCalc, QuadTransform transform) {
TerrainMeshConsumer(TerrainBlockRenderInfo blockInfo, ChunkRenderInfo chunkInfo, AoCalculator aoCalc, QuadTransform transform, Supplier<Matrix4f> matrixSupplier) {
super(blockInfo, chunkInfo::getInitializedBuffer, aoCalc, transform);
this.chunkInfo = chunkInfo;
this.matrixSupplier = matrixSupplier;
}
@Override
protected void applyOffsets(MutableQuadViewImpl quad) {
chunkInfo.applyOffsets(quad);
protected Matrix4f matrix() {
return matrixSupplier.get();
}
}

View file

@ -23,12 +23,14 @@ import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.fabricmc.indigo.renderer.aocalc.AoCalculator;
import net.minecraft.class_4587;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.chunk.BlockLayeredBufferBuilder;
import net.minecraft.client.render.chunk.ChunkBatcher.ChunkRenderData;
import net.minecraft.client.render.chunk.ChunkBatcher.ChunkRenderer;
import net.minecraft.client.render.chunk.BlockLayeredBufferBuilder;
import net.minecraft.client.render.chunk.ChunkRendererRegion;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.util.math.Matrix4f;
import net.minecraft.util.crash.CrashException;
import net.minecraft.util.crash.CrashReport;
import net.minecraft.util.crash.CrashReportSection;
@ -44,8 +46,8 @@ public class TerrainRenderContext extends AbstractRenderContext implements Rende
private final TerrainBlockRenderInfo blockInfo = new TerrainBlockRenderInfo();
private final ChunkRenderInfo chunkInfo = new ChunkRenderInfo(blockInfo);
private final AoCalculator aoCalc = new AoCalculator(blockInfo, chunkInfo::cachedBrightness, chunkInfo::cachedAoLevel);
private final TerrainMeshConsumer meshConsumer = new TerrainMeshConsumer(blockInfo, chunkInfo, aoCalc, this::transform);
private final TerrainFallbackConsumer fallbackConsumer = new TerrainFallbackConsumer(blockInfo, chunkInfo, aoCalc, this::transform);
private final TerrainMeshConsumer meshConsumer = new TerrainMeshConsumer(blockInfo, chunkInfo, aoCalc, this::transform, this::matrix);
private final TerrainFallbackConsumer fallbackConsumer = new TerrainFallbackConsumer(blockInfo, chunkInfo, aoCalc, this::transform, this::matrix);
public TerrainRenderContext prepare(ChunkRendererRegion blockView, ChunkRenderer chunkRenderer, ChunkRenderData chunkData, BlockLayeredBufferBuilder builders) {
blockInfo.setBlockView(blockView);
@ -58,8 +60,13 @@ public class TerrainRenderContext extends AbstractRenderContext implements Rende
blockInfo.release();
}
protected Matrix4f matrix() {
return matrix;
}
/** Called from chunk renderer hook. */
public boolean tesselateBlock(BlockState blockState, BlockPos blockPos, final BakedModel model) {
public boolean tesselateBlock(BlockState blockState, BlockPos blockPos, final BakedModel model, class_4587 matrixStack) {
prepareMatrix(blockState, blockPos, blockInfo.blockView, matrixStack);
try {
aoCalc.clear();
blockInfo.prepareForBlock(blockState, blockPos, model.useAmbientOcclusion());
@ -71,6 +78,7 @@ public class TerrainRenderContext extends AbstractRenderContext implements Rende
CrashReportSection.addBlockInfo(crashReportElement_1, blockPos, blockState);
throw new CrashException(crashReport_1);
}
matrixStack.method_22909();
// false because we've already marked the chunk as populated - caller doesn't need to
return false;
}

View file

@ -6,10 +6,8 @@
"mixins": [
],
"client": [
"BufferBuilderOffsetAccessor",
"MixinAmbientOcclusionCalculator",
"MixinBlockModelRenderer",
"MixinBufferBuilder",
"MixinChunkRebuildTask",
"MixinChunkRenderData",
"MixinChunkRenderer",

View file

@ -17,7 +17,7 @@
],
"depends": {
"fabricloader": ">=0.6.2",
"minecraft": ">=1.15-alpha.19.38.b",
"minecraft": ">=1.15-alpha.19.39.a",
"fabric-api-base": "*",
"fabric-renderer-api-v1": "*"
},

View file

@ -0,0 +1,6 @@
archivesBaseName = "fabric-renderer-registries-v1"
version = getSubprojectVersion(project, "1.0.0")
dependencies {
compile project(path: ':fabric-api-base', configuration: 'dev')
}

View file

@ -14,27 +14,25 @@
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.client.render;
package net.fabricmc.fabric.api.client.rendereregistry.v1;
import net.fabricmc.fabric.api.client.render.BlockEntityRendererRegistry;
import net.fabricmc.fabric.mixin.client.rendereregistry.MixinBlockEntityRenderDispatcher;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
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.callback.CallbackInfo;
import java.util.Map;
/**
* Helper class for registering BlockEntityRenderers.
*/
public class BlockEntityRendererRegistry {
public static final BlockEntityRendererRegistry INSTANCE = new BlockEntityRendererRegistry();
@Mixin(BlockEntityRenderDispatcher.class)
public class MixinBlockEntityRenderManager {
@Shadow
private Map<Class<? extends BlockEntity>, BlockEntityRenderer<? extends BlockEntity>> renderers;
private BlockEntityRendererRegistry() {
@Inject(method = "<init>()V", at = @At("RETURN"))
public void init(CallbackInfo info) {
BlockEntityRendererRegistry.INSTANCE.initialize((BlockEntityRenderDispatcher) (Object) this, renderers);
}
public <E extends BlockEntity> void register(BlockEntityType<E> blockEntityType, BlockEntityRenderer<E> blockEntityRenderer) {
((MixinBlockEntityRenderDispatcher) BlockEntityRenderDispatcher.INSTANCE).invoke_method_23078(blockEntityType, blockEntityRenderer);
}
}

View file

@ -14,13 +14,14 @@
* limitations under the License.
*/
package net.fabricmc.fabric.api.client.render;
package net.fabricmc.fabric.api.client.rendereregistry.v1;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.resource.ReloadableResourceManager;
import java.util.HashMap;
@ -40,9 +41,9 @@ public class EntityRendererRegistry {
private final TextureManager textureManager;
private final ReloadableResourceManager resourceManager;
private final ItemRenderer itemRenderer;
private final Map<Class<? extends Entity>, EntityRenderer<? extends Entity>> rendererMap;
private final Map<EntityType<?>, EntityRenderer<?>> rendererMap;
private Context(TextureManager textureManager, ReloadableResourceManager resourceManager, ItemRenderer itemRenderer, Map<Class<? extends Entity>, EntityRenderer<? extends Entity>> rendererMap) {
private Context(TextureManager textureManager, ReloadableResourceManager resourceManager, ItemRenderer itemRenderer,Map<EntityType<?>, EntityRenderer<?>> rendererMap) {
this.textureManager = textureManager;
this.resourceManager = resourceManager;
this.itemRenderer = itemRenderer;
@ -64,32 +65,34 @@ public class EntityRendererRegistry {
public static final EntityRendererRegistry INSTANCE = new EntityRendererRegistry();
private final Map<EntityRenderDispatcher, Context> renderManagerMap = new WeakHashMap<>();
private final Map<Class<? extends Entity>, EntityRendererRegistry.Factory> renderSupplierMap = new HashMap<>();
private final Map<EntityType<?>, EntityRendererRegistry.Factory> renderSupplierMap = new HashMap<>();
private EntityRendererRegistry() {
}
public void initialize(EntityRenderDispatcher manager, TextureManager textureManager, ReloadableResourceManager resourceManager, ItemRenderer itemRenderer, Map<Class<? extends Entity>, EntityRenderer<? extends Entity>> map) {
public void initialize(EntityRenderDispatcher manager, TextureManager textureManager, ReloadableResourceManager resourceManager, ItemRenderer itemRenderer, Map<EntityType<?>, EntityRenderer<?>> renderers) {
synchronized (renderSupplierMap) {
if (renderManagerMap.containsKey(manager)) {
return;
}
Context context = new Context(textureManager, resourceManager, itemRenderer, map);
Context context = new Context(textureManager, resourceManager, itemRenderer, renderers);
renderManagerMap.put(manager, context);
for (Class<? extends Entity> c : renderSupplierMap.keySet()) {
map.put(c, renderSupplierMap.get(c).create(manager, context));
for (EntityType<?> c : renderSupplierMap.keySet()) {
renderers.put(c, renderSupplierMap.get(c).create(manager, context));
}
}
}
public void register(Class<? extends Entity> entityClass, EntityRendererRegistry.Factory factory) {
public void register(EntityType<?> entityType, EntityRendererRegistry.Factory factory) {
synchronized (renderSupplierMap) {
// TODO: warn on duplicate
renderSupplierMap.put(entityClass, factory);
renderSupplierMap.put(entityType, factory);
for (EntityRenderDispatcher manager : renderManagerMap.keySet()) {
renderManagerMap.get(manager).rendererMap.put(entityClass, factory.create(manager, renderManagerMap.get(manager)));
renderManagerMap.get(manager).rendererMap.put(entityType, factory.create(manager, renderManagerMap.get(manager)));
}
}
}

View file

@ -14,20 +14,18 @@
* limitations under the License.
*/
package net.fabricmc.indigo.renderer.mixin;
package net.fabricmc.fabric.mixin.client.rendereregistry;
import net.minecraft.client.render.BufferBuilder;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(BufferBuilder.class)
public interface BufferBuilderOffsetAccessor {
@Accessor
double getOffsetX();
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
@Accessor
double getOffsetY();
@Accessor
double getOffsetZ();
@Mixin(BlockEntityRenderDispatcher.class)
public interface MixinBlockEntityRenderDispatcher {
@Invoker(value="method_23078")
@SuppressWarnings("rawtypes")
void invoke_method_23078(BlockEntityType blockEntityType, BlockEntityRenderer blockEntityRenderer);
}

View file

@ -14,14 +14,16 @@
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.client.render;
package net.fabricmc.fabric.mixin.client.rendereregistry;
import net.fabricmc.fabric.api.client.render.EntityRendererRegistry;
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.options.GameOptions;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.resource.ReloadableResourceManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -32,12 +34,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Map;
@Mixin(EntityRenderDispatcher.class)
public class MixinEntityRenderManager {
public class MixinEntityRenderDispatcher {
@Shadow
private Map<Class<? extends Entity>, EntityRenderer<? extends Entity>> renderers;
Map<EntityType<?>, EntityRenderer<?>> renderers;
@Inject(method = "<init>(Lnet/minecraft/client/texture/TextureManager;Lnet/minecraft/client/render/item/ItemRenderer;Lnet/minecraft/resource/ReloadableResourceManager;)V", at = @At("RETURN"), require = 0)
public void init(TextureManager textureManager, ItemRenderer itemRenderer, ReloadableResourceManager manager, CallbackInfo info) {
@Inject(method = "<init>(Lnet/minecraft/client/texture/TextureManager;Lnet/minecraft/client/render/item/ItemRenderer;Lnet/minecraft/resource/ReloadableResourceManager;Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/client/options/GameOptions;)V", at = @At("RETURN"), require = 0)
public void init(TextureManager textureManager, ItemRenderer itemRenderer, ReloadableResourceManager manager, TextRenderer textRenderer, GameOptions gameOptions, CallbackInfo info) {
EntityRendererRegistry.INSTANCE.initialize((EntityRenderDispatcher) (Object) this, textureManager, manager, itemRenderer, renderers);
}
}

Binary file not shown.

After

(image error) Size: 1.5 KiB

View file

@ -0,0 +1,12 @@
{
"required": true,
"package": "net.fabricmc.fabric.mixin.client.rendereregistry",
"compatibilityLevel": "JAVA_8",
"client": [
"MixinBlockEntityRenderDispatcher",
"MixinEntityRenderDispatcher"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -0,0 +1,27 @@
{
"schemaVersion": 1,
"id": "fabric-renderer-registries-v1",
"name": "Fabric Renderer Registries (v1)",
"version": "${version}",
"environment": "client",
"license": "Apache-2.0",
"icon": "assets/renderer-registries-v1/icon.png",
"contact": {
"homepage": "https://fabricmc.net",
"irc": "irc://irc.esper.net:6667/fabric",
"issues": "https://github.com/FabricMC/fabric/issues",
"sources": "https://github.com/FabricMC/fabric"
},
"authors": [
"FabricMC"
],
"depends": {
"fabricloader": ">=0.4.0",
"minecraft": ">=1.15-alpha.19.39.a",
"fabric-api-base": "*"
},
"description": "Registries for entity and block renderers.",
"mixins": [
"fabric-renderer-registries-v1.mixins.json"
]
}

View file

@ -1,5 +1,5 @@
archivesBaseName = "fabric-rendering-fluids-v1"
version = getSubprojectVersion(project, "0.1.2")
version = getSubprojectVersion(project, "0.1.3")
dependencies {
compile project(path: ':fabric-api-base', configuration: 'dev')

View file

@ -19,6 +19,7 @@ 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.class_4588;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.block.FluidRenderer;
import net.minecraft.client.texture.Sprite;
@ -49,7 +50,7 @@ public class MixinFluidRenderer {
}
@Inject(at = @At("HEAD"), method = "tesselate", cancellable = true)
public void tesselate(BlockRenderView view, BlockPos pos, BufferBuilder bufferBuilder, FluidState state, CallbackInfoReturnable<Boolean> info) {
public void tesselate(BlockRenderView view, BlockPos pos, class_4588 class_4588, FluidState state, CallbackInfoReturnable<Boolean> info) {
FluidRendererHookContainer ctr = fabric_renderHandler.get();
FluidRenderHandler handler = FluidRenderHandlerRegistryImpl.INSTANCE.getOverride(state.getFluid());
@ -70,7 +71,7 @@ public class MixinFluidRenderer {
}
@Inject(at = @At("RETURN"), method = "tesselate")
public void tesselateReturn(BlockRenderView view, BlockPos pos, BufferBuilder bufferBuilder, FluidState state, CallbackInfoReturnable<Boolean> info) {
public void tesselateReturn(BlockRenderView view, BlockPos pos, class_4588 class_4588, FluidState state, CallbackInfoReturnable<Boolean> info) {
fabric_renderHandler.get().clear();
}

View file

@ -1,5 +1,5 @@
archivesBaseName = "fabric-rendering-v0"
version = getSubprojectVersion(project, "0.1.2")
version = getSubprojectVersion(project, "1.0.0")
dependencies {
compile project(path: ':fabric-api-base', configuration: 'dev')

View file

@ -1,64 +0,0 @@
/*
* 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.render;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import java.util.HashMap;
import java.util.Map;
/**
* Helper class for registering BlockEntityRenderers.
*/
public class BlockEntityRendererRegistry {
public static final BlockEntityRendererRegistry INSTANCE = new BlockEntityRendererRegistry();
private Map<Class<? extends BlockEntity>, BlockEntityRenderer<? extends BlockEntity>> renderers = null;
private Map<Class<? extends BlockEntity>, BlockEntityRenderer<? extends BlockEntity>> renderersTmp = new HashMap<>();
private BlockEntityRendererRegistry() {
}
public void initialize(BlockEntityRenderDispatcher instance, Map<Class<? extends BlockEntity>, BlockEntityRenderer<? extends BlockEntity>> map) {
if (renderers != null && renderers != map) {
throw new RuntimeException("Tried to set renderers twice!");
}
if (renderers == map) {
return;
}
renderers = map;
for (BlockEntityRenderer renderer : renderersTmp.values()) {
renderer.setRenderManager(instance);
}
renderers.putAll(renderersTmp);
renderersTmp = null;
}
public void register(Class<? extends BlockEntity> blockEntityClass, BlockEntityRenderer<? extends BlockEntity> blockEntityRenderer) {
// TODO: warn on duplicate
if (renderers != null) {
renderers.put(blockEntityClass, blockEntityRenderer);
blockEntityRenderer.setRenderManager(BlockEntityRenderDispatcher.INSTANCE);
} else {
renderersTmp.put(blockEntityClass, blockEntityRenderer);
}
}
}

View file

@ -4,8 +4,6 @@
"compatibilityLevel": "JAVA_8",
"client": [
"MixinBlockColorMap",
"MixinBlockEntityRenderManager",
"MixinEntityRenderManager",
"MixinItemColorMap",
"MixinWorldRenderer"
],

View file

@ -17,6 +17,7 @@
],
"depends": {
"fabricloader": ">=0.4.0",
"minecraft": ">=1.15-alpha.19.39.a",
"fabric-api-base": "*"
},
"description": "Hooks and registries for rendering-related things.",

View file

@ -1,5 +1,5 @@
archivesBaseName = "fabric-textures-v0"
version = getSubprojectVersion(project, "0.1.4")
version = getSubprojectVersion(project, "0.1.5")
dependencies {
compile project(path: ':fabric-api-base', configuration: 'dev')

View file

@ -17,7 +17,7 @@
package net.fabricmc.fabric.mixin.client.texture;
import net.fabricmc.fabric.impl.client.texture.SpriteAtlasTextureHooks;
import net.minecraft.client.texture.Texture;
import net.minecraft.client.texture.AbstractTexture;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
@ -28,7 +28,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(TextureManager.class)
public class MixinTextureManager {
@Inject(at = @At("RETURN"), method = "registerTexture")
private void afterRegisterTexture(Identifier identifier, Texture texture, CallbackInfoReturnable<Boolean> info) {
private void afterRegisterTexture(Identifier identifier, AbstractTexture texture, CallbackInfoReturnable<Boolean> info) {
if (texture instanceof SpriteAtlasTextureHooks) {
((SpriteAtlasTextureHooks) texture).onRegisteredAs(identifier);
}

View file

@ -33,6 +33,7 @@ include 'fabric-object-builders-v0'
include 'fabric-registry-sync-v0'
include 'fabric-renderer-api-v1'
include 'fabric-renderer-indigo'
include 'fabric-renderer-registries-v1'
include 'fabric-rendering-v0'
include 'fabric-rendering-data-attachment-v1'
include 'fabric-rendering-fluids-v1'

View file

@ -17,7 +17,7 @@
],
"depends": {
"fabricloader": ">=0.6.2",
"minecraft": "~1.15-alpha.19.38.b"
"minecraft": "~1.15-alpha.19.39.a"
},
"description": "Core API module providing key hooks and intercompatibility features."
}