mirror of
https://github.com/FabricMC/fabric.git
synced 2025-07-28 15:09:35 -04:00
19w38b API Fixes (#370)
* Fix compilation errors (untested) * Random fixes * Various modded rendering fixes * Restore contract of RenderAttachedBlockView * Bump versions as needed * Add API for BlockRenderLayer * Minor format / name cleanup Will do a more comprehensive pass as part of separate refactor PR * Bump versions not handled earlier * Bump loader/mc bounds for dependent modules * Update fabric-blockrenderlayer-v1/src/main/java/net/fabricmc/fabric/impl/blockrenderlayer/v1/BlockRenderLayerMapImpl.java Co-Authored-By: liach <7806504+liach@users.noreply.github.com> * Update fabric-blockrenderlayer-v1/src/main/java/net/fabricmc/fabric/impl/blockrenderlayer/v1/BlockRenderLayerMapImpl.java Co-Authored-By: liach <7806504+liach@users.noreply.github.com> * Minor clean ups * Improve docs, minor format corrections. * Update MC dependency
This commit is contained in:
parent
d32291da65
commit
d2ac651a7a
46 changed files with 677 additions and 366 deletions
fabric-blockrenderlayer-v1
build.gradle
src/main
java/net/fabricmc/fabric
api/blockrenderlayer/v1
impl/blockrenderlayer/v1
mixin/blockrenderlayer
resources
fabric-events-interaction-v0
build.gradle
src/main/java/net/fabricmc/fabric/mixin/eventsinteraction
fabric-item-groups-v0
fabric-loot-tables-v1
fabric-registry-sync-v0
fabric-renderer-api-v1
fabric-renderer-indigo
build.gradle
src/main
java/net/fabricmc/indigo/renderer
RenderMaterialImpl.java
accessor
mesh
mixin
MixinBufferBuilder.javaMixinChunkRebuildTask.javaMixinChunkRenderData.javaMixinChunkRenderTask.javaMixinChunkRenderer.java
render
resources
fabric-rendering-data-attachment-v1
build.gradle
src/main/java/net/fabricmc/fabric
fabric-rendering-fluids-v1
fabric-resource-loader-v0
settings.gradlesrc/main/resources
6
fabric-blockrenderlayer-v1/build.gradle
Normal file
6
fabric-blockrenderlayer-v1/build.gradle
Normal file
|
@ -0,0 +1,6 @@
|
|||
archivesBaseName = "fabric-blockrenderlayer-v1"
|
||||
version = getSubprojectVersion(project, "1.0.0")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.blockrenderlayer.v1;
|
||||
|
||||
import net.fabricmc.fabric.impl.blockrenderlayer.v1.BlockRenderLayerMapImpl;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockRenderLayer;
|
||||
import net.minecraft.fluid.Fluid;
|
||||
|
||||
/**
|
||||
* Use to associate blocks or fluids with block render layer other than default.
|
||||
* Replaces the {@code renderLayer} property previously on {@code Block}.<p>
|
||||
*
|
||||
* {@code BlockRenderLayer} controls how sprite pixels for fluids and blocks are blended
|
||||
* with the scene. Consult the vanilla {@code BlockRenderLayer} implementation for examples.<p>
|
||||
*
|
||||
* The Fabric Renderer API can be used to control this at a per-quad level at the code
|
||||
* via {@code BlendMode}.<p>
|
||||
*
|
||||
* Client-side only.
|
||||
*/
|
||||
public interface BlockRenderLayerMap {
|
||||
BlockRenderLayerMap INSTANCE = BlockRenderLayerMapImpl.INSTANCE;
|
||||
|
||||
/**
|
||||
* Map (or re-map) a block state with a render layer. Re-mapping is not recommended but if done, last one in wins.
|
||||
* Must be called from client thread prior to world load/rendering. Best practice will be to call from mod's client initializer.
|
||||
*
|
||||
* @param block Identifies block to be mapped.
|
||||
* @param renderLayer Render layer. Should be one of the layers used for terrain rendering.
|
||||
*/
|
||||
void putBlock(Block block, BlockRenderLayer renderLayer);
|
||||
|
||||
/**
|
||||
* Map (or re-map) a fluid state with a render layer. Re-mapping is not recommended but if done, last one in wins.
|
||||
* Must be called from client thread prior to world load/rendering. Best practice will be to call from mod's client initializer.
|
||||
*
|
||||
* @param fluid Identifies fluid to be mapped.
|
||||
* @param renderLayer Render layer. Should be one of the layers used for terrain rendering.
|
||||
*/
|
||||
void putFluid(Fluid fluid, BlockRenderLayer renderLayer);
|
||||
}
|
|
@ -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.blockrenderlayer.v1;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockRenderLayer;
|
||||
import net.minecraft.fluid.Fluid;
|
||||
|
||||
public class BlockRenderLayerMapImpl implements BlockRenderLayerMap {
|
||||
private BlockRenderLayerMapImpl() {}
|
||||
|
||||
@Override
|
||||
public void putBlock(Block block, BlockRenderLayer renderLayer) {
|
||||
if (block == null) {
|
||||
LOG.warn("Ignoring request to map null block to BlockRenderLayer");
|
||||
} else if (renderLayer == null) {
|
||||
LOG.warn("Ignoring request to map block " + block.toString() + " to null BlockRenderLayer");
|
||||
} else {
|
||||
blockHandler.accept(block, renderLayer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putFluid(Fluid fluid, BlockRenderLayer renderLayer) {
|
||||
if (fluid == null) {
|
||||
LOG.warn("Ignoring request to map null fluid to BlockRenderLayer");
|
||||
} else if (renderLayer == null) {
|
||||
LOG.warn("Ignoring request to map fluid " + fluid.toString() + " to null BlockRenderLayer");
|
||||
} else {
|
||||
fluidHandler.accept(fluid, renderLayer);
|
||||
}
|
||||
}
|
||||
|
||||
public static final BlockRenderLayerMap INSTANCE = new BlockRenderLayerMapImpl();
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger();
|
||||
|
||||
// These should never be used before our Mixin populates them because a non-null BRL instance is
|
||||
// a required parameter of our methods. They are given dummy consumers that log
|
||||
// warnings in case something goes wrong.
|
||||
|
||||
private static BiConsumer<Block, BlockRenderLayer> blockHandler = (b, l) -> {
|
||||
LOG.warn("Unable to map Block {} to BlockRenderLayer. Mapping handler not ready.", b);
|
||||
};
|
||||
|
||||
private static BiConsumer<Fluid, BlockRenderLayer> fluidHandler = (f, b) -> {
|
||||
LOG.warn("Unable to map Fluid {} to BlockRenderLayer. Mapping handler not ready.", f);
|
||||
};
|
||||
|
||||
public static void initialize(BiConsumer<Block, BlockRenderLayer> blockHandlerIn, BiConsumer<Fluid, BlockRenderLayer> fluidHandlerIn) {
|
||||
blockHandler = blockHandlerIn;
|
||||
fluidHandler = fluidHandlerIn;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.blockrenderlayer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
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.impl.blockrenderlayer.v1.BlockRenderLayerMapImpl;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockRenderLayer;
|
||||
import net.minecraft.fluid.Fluid;
|
||||
|
||||
@Mixin(BlockRenderLayer.class)
|
||||
public class MixinBlockRenderLayer {
|
||||
@Shadow private static Map<Block, BlockRenderLayer> field_20803;
|
||||
@Shadow private static Map<Fluid, BlockRenderLayer> field_20804;
|
||||
|
||||
@Inject(method = "<clinit>*", at = @At("RETURN"))
|
||||
private static void onInitialize(CallbackInfo info) {
|
||||
BlockRenderLayerMapImpl.initialize(field_20803::put, field_20804::put);
|
||||
}
|
||||
}
|
Binary file not shown.
After ![]() (image error) Size: 1.5 KiB |
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "net.fabricmc.fabric.mixin.blockrenderlayer",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"client": [
|
||||
"MixinBlockRenderLayer"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "fabric-blockrenderlayer-v1",
|
||||
"name": "Fabric BlockRenderLayer Registration (v1)",
|
||||
"version": "${version}",
|
||||
"environment": "client",
|
||||
"license": "Apache-2.0",
|
||||
"icon": "assets/fabric-blockrenderlayer-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.6.2",
|
||||
"minecraft": ">=1.15-alpha.19.38.b",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Registration utility for block and fluid render layers.",
|
||||
"mixins": [
|
||||
"fabric-blockrenderlayer-v1.mixins.json"
|
||||
]
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-events-interaction-v0"
|
||||
version = getSubprojectVersion(project, "0.1.2")
|
||||
version = getSubprojectVersion(project, "0.1.3")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -46,7 +46,7 @@ public class MixinServerPlayerInteractionManager {
|
|||
@Shadow
|
||||
public ServerPlayerEntity player;
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "method_14263", cancellable = true)
|
||||
@Inject(at = @At("HEAD"), method = "processBlockBreakingAction", cancellable = true)
|
||||
public void startBlockBreak(BlockPos pos, PlayerActionC2SPacket.Action playerAction, Direction direction, int i, CallbackInfo info) {
|
||||
ActionResult result = AttackBlockCallback.EVENT.invoker().interact(player, world, Hand.MAIN_HAND, pos, direction);
|
||||
if (result != ActionResult.PASS) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-item-groups-v0"
|
||||
version = getSubprojectVersion(project, "0.1.1")
|
||||
version = getSubprojectVersion(project, "0.1.2")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-loot-tables-v1"
|
||||
version = getSubprojectVersion(project, "0.1.0")
|
||||
version = getSubprojectVersion(project, "0.1.1")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-registry-sync-v0"
|
||||
version = getSubprojectVersion(project, "0.2.2")
|
||||
version = getSubprojectVersion(project, "0.2.3")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-renderer-api-v1"
|
||||
version = getSubprojectVersion(project, "0.1.1")
|
||||
version = getSubprojectVersion(project, "0.2.0")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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.renderer.v1.material;
|
||||
|
||||
import net.minecraft.block.BlockRenderLayer;
|
||||
|
||||
/**
|
||||
* Defines how sprite pixels will be blended with the scene.
|
||||
*/
|
||||
public enum BlendMode {
|
||||
/**
|
||||
* Emulate blending behavior of {@code BlockRenderLayer} associated with the block.
|
||||
*/
|
||||
DEFAULT(null),
|
||||
|
||||
/**
|
||||
* Fully opaque with depth test, no blending. Used for most normal blocks.
|
||||
*/
|
||||
SOLID(BlockRenderLayer.field_9178),
|
||||
|
||||
/**
|
||||
* Pixels with alpha > 0.5 are rendered as if {@code SOLID}. Other pixels are not rendered.
|
||||
* Texture mip-map enabled. Used for leaves.
|
||||
*/
|
||||
CUTOUT_MIPPED(BlockRenderLayer.CUTOUT_MIPPED),
|
||||
|
||||
/**
|
||||
* 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),
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
public final BlockRenderLayer blockRenderLayer;
|
||||
|
||||
private BlendMode(BlockRenderLayer blockRenderLayer) {
|
||||
this.blockRenderLayer = blockRenderLayer;
|
||||
}
|
||||
|
||||
public static BlendMode fromRenderLayer(BlockRenderLayer renderLayer) {
|
||||
if (renderLayer == BlockRenderLayer.field_9178) {
|
||||
return SOLID;
|
||||
} else if (renderLayer == BlockRenderLayer.CUTOUT_MIPPED) {
|
||||
return CUTOUT_MIPPED;
|
||||
} else if (renderLayer == BlockRenderLayer.field_9174) {
|
||||
return CUTOUT;
|
||||
} else if (renderLayer == BlockRenderLayer.field_9179) {
|
||||
return TRANSLUCENT;
|
||||
} else {
|
||||
return DEFAULT;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,10 +16,9 @@
|
|||
|
||||
package net.fabricmc.fabric.api.renderer.v1.material;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.fabricmc.fabric.api.renderer.v1.Renderer;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
|
||||
import net.minecraft.block.Block;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.minecraft.block.BlockRenderLayer;
|
||||
|
||||
/**
|
||||
|
@ -55,16 +54,28 @@ public interface MaterialFinder {
|
|||
/**
|
||||
* Defines how sprite pixels will be blended with the scene.
|
||||
* Accepts {link @BlockRenderLayer} values and blending behavior
|
||||
* will emulate the way that Minecraft renders each pass. But this does
|
||||
* will emulate the way that Minecraft renders those instances. This does
|
||||
* NOT mean the sprite will be rendered in a specific render pass - some
|
||||
* implementations may not use the standard Minecraft render passes.<p>
|
||||
* implementations may not use the standard vanilla render passes.<p>
|
||||
*
|
||||
* CAN be null and is null by default. A null value means the renderer
|
||||
* will use {@link Block#getRenderLayer()} for the associate block, or
|
||||
* {@link BlockRenderLayer#TRANSLUCENT} for item renders. (Normal Minecraft rendering)
|
||||
* will use the value normally associated with the block being rendered, or
|
||||
* {@code TRANSLUCENT} for item renders. (Normal Minecraft rendering)
|
||||
*
|
||||
* @deprecated Use {@code BlendMode} version instead.
|
||||
*/
|
||||
MaterialFinder blendMode(int spriteIndex, BlockRenderLayer blendMode);
|
||||
|
||||
@Deprecated
|
||||
default MaterialFinder blendMode(int spriteIndex, BlockRenderLayer renderLayer) {
|
||||
return blendMode(spriteIndex, BlendMode.fromRenderLayer(renderLayer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines how sprite pixels will be blended with the scene.<p>
|
||||
*
|
||||
* See {@link BlendMode} for more information.
|
||||
*/
|
||||
MaterialFinder blendMode(int spriteIndex, BlendMode blendMode);
|
||||
|
||||
/**
|
||||
* Vertex color(s) will be modified for quad color index unless disabled.<p>
|
||||
*/
|
||||
|
|
|
@ -21,7 +21,6 @@ import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
|||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
/**
|
||||
* Specialized {@link MutableQuadView} obtained via {@link MeshBuilder#getEmitter()}
|
||||
|
|
|
@ -18,7 +18,6 @@ package net.fabricmc.fabric.mixin.renderer.client;
|
|||
|
||||
import java.util.Random;
|
||||
|
||||
import net.fabricmc.fabric.impl.renderer.DamageModel;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
@ -28,8 +27,9 @@ import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
|||
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.block.BlockState;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.block.BlockModelRenderer;
|
||||
import net.minecraft.client.render.block.BlockRenderManager;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
|
@ -63,11 +63,11 @@ public abstract class MixinBlockRenderManager {
|
|||
*/
|
||||
@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, Sprite sprite, BlockRenderView blockView, CallbackInfo ci) {
|
||||
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, Tessellator.getInstance().getBufferBuilder(), true, this.random, blockState.getRenderingSeed(blockPos));
|
||||
this.renderer.tesselate(blockView, damageState.left, blockState, blockPos, bufferBuilder, true, this.random, blockState.getRenderingSeed(blockPos));
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.4.0",
|
||||
"fabricloader": ">=0.6.2",
|
||||
"minecraft": ">=1.15-alpha.19.38.b",
|
||||
"fabric-api-base": "*"
|
||||
},
|
||||
"description": "Defines rendering extensions for dynamic/fancy block and item models.",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-renderer-indigo"
|
||||
version = getSubprojectVersion(project, "0.1.13")
|
||||
version = getSubprojectVersion(project, "0.2.0")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -18,9 +18,9 @@ package net.fabricmc.indigo.renderer;
|
|||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder;
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
|
||||
import net.minecraft.block.BlockRenderLayer;
|
||||
|
||||
/**
|
||||
* Default implementation of the standard render materials.
|
||||
|
@ -29,9 +29,7 @@ import net.minecraft.block.BlockRenderLayer;
|
|||
* easy/fast interning via int/object hashmap.
|
||||
*/
|
||||
public abstract class RenderMaterialImpl {
|
||||
/** zero position (default value) will be NULL */
|
||||
private static final BlockRenderLayer[] BLEND_MODES = new BlockRenderLayer[5];
|
||||
|
||||
private static final BlendMode[] BLEND_MODES = BlendMode.values();
|
||||
|
||||
/**
|
||||
* Indigo currently support up to 3 sprite layers but is configured to recognize only one.
|
||||
|
@ -49,8 +47,6 @@ public abstract class RenderMaterialImpl {
|
|||
private static final int[] AO_FLAGS = new int[3];
|
||||
|
||||
static {
|
||||
System.arraycopy(BlockRenderLayer.values(), 0, BLEND_MODES, 1, 4);
|
||||
|
||||
int shift = Integer.bitCount(TEXTURE_DEPTH_MASK);
|
||||
for(int i = 0; i < 3; i++) {
|
||||
BLEND_MODE_SHIFT[i] = shift;
|
||||
|
@ -71,7 +67,7 @@ public abstract class RenderMaterialImpl {
|
|||
|
||||
protected int bits;
|
||||
|
||||
public BlockRenderLayer blendMode(int textureIndex) {
|
||||
public BlendMode blendMode(int textureIndex) {
|
||||
return BLEND_MODES[(bits >> BLEND_MODE_SHIFT[textureIndex]) & BLEND_MODE_MASK];
|
||||
}
|
||||
|
||||
|
@ -137,11 +133,11 @@ public abstract class RenderMaterialImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public MaterialFinder blendMode(int textureIndex, BlockRenderLayer blendMode) {
|
||||
public MaterialFinder blendMode(int textureIndex, BlendMode blendMode) {
|
||||
if (blendMode == null) blendMode = BlendMode.DEFAULT;
|
||||
final int shift = BLEND_MODE_SHIFT[textureIndex];
|
||||
// zero position is null (default) value
|
||||
final int ordinal = blendMode == null ? 0 : blendMode.ordinal() + 1;
|
||||
bits = (bits & ~(BLEND_MODE_MASK << shift)) | (ordinal << shift);
|
||||
bits = (bits & ~(BLEND_MODE_MASK << shift)) | (blendMode.ordinal() << shift);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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.minecraft.block.BlockRenderLayer;
|
||||
|
||||
public interface AccessChunkRendererData {
|
||||
/**
|
||||
* Mark internal tracking set that buffer has been initialized.
|
||||
*
|
||||
* @param renderLayer Layer to be initialized.
|
||||
* @return {@code true} if layer was not already initialized.
|
||||
*/
|
||||
boolean fabric_markInitialized(BlockRenderLayer renderLayer);
|
||||
|
||||
/**
|
||||
* Mark internal tracking set that buffer has content.
|
||||
*
|
||||
* @param renderLayer Layer with content.
|
||||
*/
|
||||
void fabric_markPopulated(BlockRenderLayer renderLayer);
|
||||
}
|
|
@ -36,17 +36,14 @@ public abstract class EncodingFormat {
|
|||
|
||||
// our internal format always include packed normals
|
||||
public static final int VERTEX_START_OFFSET = HEADER_STRIDE;
|
||||
static final int VANILLA_STRIDE = 28;
|
||||
public static final int NORMALS_OFFSET = VERTEX_START_OFFSET + VANILLA_STRIDE;
|
||||
static final int NORMALS_STRIDE = 4;
|
||||
public static final int NORMALS_OFFSET_VANILLA = VANILLA_STRIDE;
|
||||
static final int VANILLA_STRIDE = 32;
|
||||
// normals are followed by 0-2 sets of color/uv coordinates
|
||||
static final int TEXTURE_STRIDE = 12;
|
||||
/** is one tex stride less than the actual base, because when used tex index is >= 1 */
|
||||
static final int TEXTURE_OFFSET_MINUS = NORMALS_OFFSET + NORMALS_STRIDE - TEXTURE_STRIDE;
|
||||
static final int SECOND_TEXTURE_OFFSET = NORMALS_OFFSET + NORMALS_STRIDE;
|
||||
static final int TEXTURE_OFFSET_MINUS = HEADER_STRIDE + VANILLA_STRIDE - TEXTURE_STRIDE;
|
||||
static final int SECOND_TEXTURE_OFFSET = TEXTURE_OFFSET_MINUS + TEXTURE_STRIDE;
|
||||
static final int THIRD_TEXTURE_OFFSET = SECOND_TEXTURE_OFFSET + TEXTURE_STRIDE;
|
||||
public static final int MAX_STRIDE = HEADER_STRIDE + VANILLA_STRIDE + NORMALS_STRIDE
|
||||
public static final int MAX_STRIDE = HEADER_STRIDE + VANILLA_STRIDE
|
||||
+ TEXTURE_STRIDE * (RenderMaterialImpl.MAX_SPRITE_DEPTH - 1);
|
||||
|
||||
/** used for quick clearing of quad buffers */
|
||||
|
|
|
@ -17,14 +17,12 @@
|
|||
package net.fabricmc.indigo.renderer.mesh;
|
||||
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.EMPTY;
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.NORMALS_OFFSET;
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.VANILLA_STRIDE;
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.VERTEX_START_OFFSET;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.indigo.renderer.RenderMaterialImpl.Value;
|
||||
import net.fabricmc.indigo.renderer.IndigoRenderer;
|
||||
import net.fabricmc.indigo.renderer.RenderMaterialImpl.Value;
|
||||
import net.fabricmc.indigo.renderer.helper.ColorHelper.ShadeableQuad;
|
||||
import net.fabricmc.indigo.renderer.helper.GeometryHelper;
|
||||
import net.fabricmc.indigo.renderer.helper.NormalHelper;
|
||||
|
@ -98,19 +96,7 @@ public abstract class MutableQuadViewImpl extends QuadViewImpl implements QuadEm
|
|||
@Override
|
||||
public final MutableQuadViewImpl fromVanilla(int[] quadData, int startIndex, boolean isItem) {
|
||||
final int vertexStart = vertexStart();
|
||||
if(isItem) {
|
||||
System.arraycopy(quadData, startIndex, data, vertexStart, 6);
|
||||
System.arraycopy(quadData, startIndex + 7, data, vertexStart + 7, 6);
|
||||
System.arraycopy(quadData, startIndex + 14, data, vertexStart + 14, 6);
|
||||
System.arraycopy(quadData, startIndex + 21, data, vertexStart + 21, 6);
|
||||
final int normalsIndex = baseIndex + NORMALS_OFFSET;
|
||||
data[normalsIndex] = quadData[startIndex + 6];
|
||||
data[normalsIndex + 1] = quadData[startIndex + 13];
|
||||
data[normalsIndex + 2] = quadData[startIndex + 20];
|
||||
data[normalsIndex + 3] = quadData[startIndex + 27];
|
||||
} else {
|
||||
System.arraycopy(quadData, startIndex, data, vertexStart, 28);
|
||||
}
|
||||
System.arraycopy(quadData, startIndex, data, vertexStart, 32);
|
||||
this.invalidateShape();
|
||||
return this;
|
||||
}
|
||||
|
@ -127,7 +113,7 @@ public abstract class MutableQuadViewImpl extends QuadViewImpl implements QuadEm
|
|||
|
||||
@Override
|
||||
public MutableQuadViewImpl pos(int vertexIndex, float x, float y, float z) {
|
||||
final int index = vertexStart() + vertexIndex * 7;
|
||||
final int index = vertexStart() + vertexIndex * 8;
|
||||
data[index] = Float.floatToRawIntBits(x);
|
||||
data[index + 1] = Float.floatToRawIntBits(y);
|
||||
data[index + 2] = Float.floatToRawIntBits(z);
|
||||
|
@ -138,13 +124,27 @@ public abstract class MutableQuadViewImpl extends QuadViewImpl implements QuadEm
|
|||
@Override
|
||||
public MutableQuadViewImpl normal(int vertexIndex, float x, float y, float z) {
|
||||
normalFlags |= (1 << vertexIndex);
|
||||
data[baseIndex + VERTEX_START_OFFSET + VANILLA_STRIDE + vertexIndex] = NormalHelper.packNormal(x, y, z, 0);
|
||||
data[baseIndex + vertexIndex * 8 + 7 + VERTEX_START_OFFSET] = NormalHelper.packNormal(x, y, z, 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal helper method. Copies face normals to vertex normals lacking one.
|
||||
*/
|
||||
public final void populateMissingNormals() {
|
||||
final int normalFlags = this.normalFlags;
|
||||
if (normalFlags == 0b1111) return;
|
||||
final int packedFaceNormal = NormalHelper.packNormal(faceNormal(), 0);
|
||||
for (int v = 0; v < 4; v++) {
|
||||
if ((normalFlags & (1 << v)) == 0) {
|
||||
data[baseIndex + v * 8 + 7 + VERTEX_START_OFFSET] = packedFaceNormal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableQuadViewImpl lightmap(int vertexIndex, int lightmap) {
|
||||
data[baseIndex + vertexIndex * 7 + 6 + VERTEX_START_OFFSET] = lightmap;
|
||||
data[baseIndex + vertexIndex * 8 + 6 + VERTEX_START_OFFSET] = lightmap;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,12 +20,10 @@ import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.HEADER_BITS;
|
|||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.HEADER_COLOR_INDEX;
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.HEADER_MATERIAL;
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.HEADER_TAG;
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.NORMALS_OFFSET;
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.SECOND_TEXTURE_OFFSET;
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.TEXTURE_OFFSET_MINUS;
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.TEXTURE_STRIDE;
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.THIRD_TEXTURE_OFFSET;
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.VANILLA_STRIDE;
|
||||
import static net.fabricmc.indigo.renderer.mesh.EncodingFormat.VERTEX_START_OFFSET;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
|
@ -154,15 +152,7 @@ public class QuadViewImpl implements QuadView {
|
|||
|
||||
@Override
|
||||
public final void toVanilla(int textureIndex, int[] target, int targetIndex, boolean isItem) {
|
||||
System.arraycopy(data, vertexStart(), target, targetIndex, 28);
|
||||
|
||||
if(textureIndex > 0) {
|
||||
copyColorUV(textureIndex, target, targetIndex);
|
||||
}
|
||||
|
||||
if(isItem) {
|
||||
copyNormals(target, targetIndex);
|
||||
}
|
||||
System.arraycopy(data, vertexStart(), target, targetIndex, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -174,31 +164,18 @@ public class QuadViewImpl implements QuadView {
|
|||
int strideFrom;
|
||||
if(textureIndex == 0) {
|
||||
indexFrom = baseIndex + VERTEX_START_OFFSET + 3;
|
||||
strideFrom = 7;
|
||||
strideFrom = 8;
|
||||
} else {
|
||||
indexFrom = baseIndex + (textureIndex == 1 ? SECOND_TEXTURE_OFFSET : THIRD_TEXTURE_OFFSET);
|
||||
strideFrom = 3;
|
||||
}
|
||||
for(int i = 0; i < 4; i++) {
|
||||
System.arraycopy(data, indexFrom, target, indexTo, 3);
|
||||
indexTo += 7;
|
||||
indexTo += 8;
|
||||
indexFrom += strideFrom;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal helper method. Copies packed normals to target, assuming vanilla format.
|
||||
*/
|
||||
public final void copyNormals(int[] target, int targetIndex) {
|
||||
final int normalFlags = this.normalFlags;
|
||||
final int packedFaceNormal = normalFlags == 0b1111 ? 0 : NormalHelper.packNormal(faceNormal(), 0);
|
||||
final int normalsIndex = baseIndex + NORMALS_OFFSET;
|
||||
for(int v = 0; v < 4; v++) {
|
||||
final int packed = (normalFlags & (1 << v)) == 0 ? packedFaceNormal : data[normalsIndex + v];
|
||||
target[targetIndex + v * 7 + 6] = packed;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RenderMaterialImpl.Value material() {
|
||||
return material;
|
||||
|
@ -263,7 +240,7 @@ public class QuadViewImpl implements QuadView {
|
|||
if(target == null) {
|
||||
target = new Vector3f();
|
||||
}
|
||||
final int index = vertexStart() + vertexIndex * 7;
|
||||
final int index = vertexStart() + vertexIndex * 8;
|
||||
target.set(
|
||||
Float.intBitsToFloat(data[index]),
|
||||
Float.intBitsToFloat(data[index + 1]),
|
||||
|
@ -273,22 +250,22 @@ public class QuadViewImpl implements QuadView {
|
|||
|
||||
@Override
|
||||
public float posByIndex(int vertexIndex, int coordinateIndex) {
|
||||
return Float.intBitsToFloat(data[vertexStart() + vertexIndex * 7 + coordinateIndex]);
|
||||
return Float.intBitsToFloat(data[vertexStart() + vertexIndex * 8 + coordinateIndex]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float x(int vertexIndex) {
|
||||
return Float.intBitsToFloat(data[vertexStart() + vertexIndex * 7]);
|
||||
return Float.intBitsToFloat(data[vertexStart() + vertexIndex * 8]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float y(int vertexIndex) {
|
||||
return Float.intBitsToFloat(data[vertexStart() + vertexIndex * 7 + 1]);
|
||||
return Float.intBitsToFloat(data[vertexStart() + vertexIndex * 8 + 1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float z(int vertexIndex) {
|
||||
return Float.intBitsToFloat(data[vertexStart() + vertexIndex * 7 + 2]);
|
||||
return Float.intBitsToFloat(data[vertexStart() + vertexIndex * 8 + 2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -302,7 +279,7 @@ public class QuadViewImpl implements QuadView {
|
|||
if(target == null) {
|
||||
target = new Vector3f();
|
||||
}
|
||||
final int normal = data[vertexStart() + VANILLA_STRIDE + vertexIndex];
|
||||
final int normal = data[vertexStart() + vertexIndex * 8 + 7];
|
||||
target.set(
|
||||
NormalHelper.getPackedNormalComponent(normal, 0),
|
||||
NormalHelper.getPackedNormalComponent(normal, 1),
|
||||
|
@ -316,31 +293,31 @@ public class QuadViewImpl implements QuadView {
|
|||
@Override
|
||||
public float normalX(int vertexIndex) {
|
||||
return hasNormal(vertexIndex)
|
||||
? NormalHelper.getPackedNormalComponent(data[baseIndex + VERTEX_START_OFFSET + VANILLA_STRIDE + vertexIndex], 0)
|
||||
? NormalHelper.getPackedNormalComponent(data[vertexStart() + vertexIndex * 8 + 7], 0)
|
||||
: Float.NaN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float normalY(int vertexIndex) {
|
||||
return hasNormal(vertexIndex)
|
||||
? NormalHelper.getPackedNormalComponent(data[baseIndex + VERTEX_START_OFFSET + VANILLA_STRIDE + vertexIndex], 1)
|
||||
? NormalHelper.getPackedNormalComponent(data[vertexStart() + vertexIndex * 8 + 7], 1)
|
||||
: Float.NaN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float normalZ(int vertexIndex) {
|
||||
return hasNormal(vertexIndex)
|
||||
? NormalHelper.getPackedNormalComponent(data[baseIndex + VERTEX_START_OFFSET + VANILLA_STRIDE + vertexIndex], 2)
|
||||
? NormalHelper.getPackedNormalComponent(data[vertexStart() + vertexIndex * 8 + 7], 2)
|
||||
: Float.NaN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lightmap(int vertexIndex) {
|
||||
return data[baseIndex + vertexIndex * 7 + 6 + VERTEX_START_OFFSET];
|
||||
return data[baseIndex + vertexIndex * 8 + 6 + VERTEX_START_OFFSET];
|
||||
}
|
||||
|
||||
protected int colorIndex(int vertexIndex, int textureIndex) {
|
||||
return textureIndex == 0 ? vertexIndex * 7 + 3 + VERTEX_START_OFFSET : TEXTURE_OFFSET_MINUS + textureIndex * TEXTURE_STRIDE + vertexIndex * 3;
|
||||
return textureIndex == 0 ? vertexIndex * 8 + 3 + VERTEX_START_OFFSET : TEXTURE_OFFSET_MINUS + textureIndex * TEXTURE_STRIDE + vertexIndex * 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -36,13 +36,13 @@ public abstract class MixinBufferBuilder implements AccessBufferBuilder {
|
|||
@Shadow abstract int getCurrentSize();
|
||||
@Shadow public abstract VertexFormat getVertexFormat();
|
||||
|
||||
private static final int VERTEX_STRIDE_INTS = 7;
|
||||
private static final int VERTEX_STRIDE_INTS = 8;
|
||||
private static final int QUAD_STRIDE_INTS = VERTEX_STRIDE_INTS * 4;
|
||||
private static final int QUAD_STRIDE_BYTES = QUAD_STRIDE_INTS * 4;
|
||||
|
||||
@Override
|
||||
public void fabric_putQuad(QuadViewImpl quad) {
|
||||
if(Indigo.ENSURE_VERTEX_FORMAT_COMPATIBILITY) {
|
||||
if (Indigo.ENSURE_VERTEX_FORMAT_COMPATIBILITY) {
|
||||
bufferCompatibly(quad);
|
||||
} else {
|
||||
bufferFast(quad);
|
||||
|
@ -50,7 +50,8 @@ public abstract class MixinBufferBuilder implements AccessBufferBuilder {
|
|||
}
|
||||
|
||||
private void bufferFast(QuadViewImpl quad) {
|
||||
grow(QUAD_STRIDE_BYTES);
|
||||
grow(QUAD_STRIDE_BYTES + getVertexFormat().getVertexSize());
|
||||
bufInt.limit(bufInt.capacity());
|
||||
bufInt.position(getCurrentSize());
|
||||
bufInt.put(quad.data(), quad.vertexStart(), QUAD_STRIDE_INTS);
|
||||
vertexCount += 4;
|
||||
|
@ -93,9 +94,8 @@ public abstract class MixinBufferBuilder implements AccessBufferBuilder {
|
|||
break;
|
||||
|
||||
// these types should never occur and/or require no action
|
||||
case MATRIX:
|
||||
case BLEND_WEIGHT:
|
||||
case PADDING:
|
||||
case GENERIC:
|
||||
default:
|
||||
break;
|
||||
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* 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.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
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.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
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.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.block.BlockRenderManager;
|
||||
import net.minecraft.client.render.chunk.BlockLayeredBufferBuilder;
|
||||
import net.minecraft.client.render.chunk.ChunkBatcher;
|
||||
import net.minecraft.client.render.chunk.ChunkBatcher.ChunkRenderer;
|
||||
import net.minecraft.client.render.chunk.ChunkRendererRegion;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
/**
|
||||
* Implements the main hooks for terrain rendering. Attempts to tread
|
||||
* lightly. This means we are deliberately stepping over some minor
|
||||
* optimization opportunities.<p>
|
||||
*
|
||||
* Non-Fabric renderer implementations that are looking to maximize
|
||||
* performance will likely take a much more aggressive approach.
|
||||
* For that reason, mod authors who want compatibility with advanced
|
||||
* renderers will do well to steer clear of chunk rebuild hooks unless
|
||||
* they are creating a renderer.<p>
|
||||
*
|
||||
* These hooks are intended only for the Fabric default renderer and
|
||||
* aren't expected to be present when a different renderer is being used.
|
||||
* Renderer authors are responsible for creating the hooks they need.
|
||||
* (Though they can use these as an example if they wish.)
|
||||
*/
|
||||
@Mixin(targets = "net.minecraft.client.render.chunk.ChunkBatcher$ChunkRenderer$class_4578")
|
||||
public class MixinChunkRebuildTask {
|
||||
@Shadow protected ChunkRendererRegion field_20838;
|
||||
@Shadow protected ChunkRenderer field_20839;
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "method_22785")
|
||||
private void hookChunkBuild(
|
||||
float float_1,
|
||||
float float_2,
|
||||
float float_3,
|
||||
ChunkBatcher.ChunkRenderData renderData,
|
||||
BlockLayeredBufferBuilder builder,
|
||||
CallbackInfoReturnable<Set<BlockEntity>> ci) {
|
||||
if (field_20838 != null) {
|
||||
TerrainRenderContext renderer = TerrainRenderContext.POOL.get();
|
||||
renderer.prepare(field_20838, field_20839, renderData, builder);
|
||||
((AccessChunkRendererRegion)field_20838).fabric_setRenderer(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the hook that actually implements the rendering API for terrain rendering.<p>
|
||||
*
|
||||
* It's unusual to have a @Redirect in a Fabric library, but in this case
|
||||
* it is our explicit intention that {@link BlockRenderManager#tesselateBlock(BlockState, BlockPos, BlockRenderView, BufferBuilder, Random)}
|
||||
* does not execute for models that will be rendered by our renderer.<p>
|
||||
*
|
||||
* Any mod that wants to redirect this specific call is likely also a renderer, in which case this
|
||||
* renderer should not be present, or the mod should probably instead be relying on the renderer API
|
||||
* which was specifically created to provide for enhanced terrain rendering.<p>
|
||||
*
|
||||
* Note also that {@link BlockRenderManager#tesselateBlock(BlockState, BlockPos, BlockRenderView, BufferBuilder, Random)}
|
||||
* IS called if the block render type is something other than {@link BlockRenderType#MODEL}.
|
||||
* 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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all references. Probably not necessary but would be $#%! to debug if it is.
|
||||
*/
|
||||
@Inject(at = @At("RETURN"), method = "method_22785")
|
||||
private void hookRebuildChunkReturn(CallbackInfoReturnable<Set<BlockEntity>> ci) {
|
||||
TerrainRenderContext.POOL.get().release();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.util.Set;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import net.fabricmc.indigo.renderer.accessor.AccessChunkRendererData;
|
||||
import net.minecraft.block.BlockRenderLayer;
|
||||
import net.minecraft.client.render.chunk.ChunkBatcher.ChunkRenderData;
|
||||
|
||||
@Mixin(ChunkRenderData.class)
|
||||
public class MixinChunkRenderData implements AccessChunkRendererData {
|
||||
@Shadow private Set<BlockRenderLayer> initialized;
|
||||
@Shadow private Set<BlockRenderLayer> nonEmpty;
|
||||
@Shadow private boolean empty;
|
||||
|
||||
@Override
|
||||
public boolean fabric_markInitialized(BlockRenderLayer renderLayer) {
|
||||
return initialized.add(renderLayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fabric_markPopulated(BlockRenderLayer renderLayer) {
|
||||
empty = false;
|
||||
nonEmpty.add(renderLayer);
|
||||
}
|
||||
}
|
|
@ -1,50 +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 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.CallbackInfoReturnable;
|
||||
|
||||
import net.fabricmc.indigo.renderer.accessor.AccessChunkRendererRegion;
|
||||
import net.fabricmc.indigo.renderer.render.TerrainRenderContext;
|
||||
import net.minecraft.client.render.chunk.ChunkRenderTask;
|
||||
import net.minecraft.client.render.chunk.ChunkRendererRegion;
|
||||
|
||||
@Mixin(ChunkRenderTask.class)
|
||||
public abstract class MixinChunkRenderTask {
|
||||
@Shadow private ChunkRendererRegion region;
|
||||
|
||||
/**
|
||||
* The block view reference is voided when {@link ChunkRenderTask#getAndInvalidateWorldView()} is called during
|
||||
* chunk rebuild, but we need it and it is harder to make reliable, non-invasive changes there.
|
||||
* So we capture the block view before the reference is voided and send it to the renderer. <p>
|
||||
*
|
||||
* We also store a reference to the renderer in the view to avoid doing thread-local lookups for each block.
|
||||
*/
|
||||
@Inject(at = @At("HEAD"), method = "takeRegion")
|
||||
private void chunkDataHook(CallbackInfoReturnable<ChunkRendererRegion> info) {
|
||||
final ChunkRendererRegion blockView = region;
|
||||
if(blockView != null) {
|
||||
final TerrainRenderContext renderer = TerrainRenderContext.POOL.get();
|
||||
renderer.setBlockView(blockView);
|
||||
((AccessChunkRendererRegion)blockView).fabric_setRenderer(renderer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,121 +16,23 @@
|
|||
|
||||
package net.fabricmc.indigo.renderer.mixin;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
|
||||
import net.fabricmc.indigo.Indigo;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
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.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.fabricmc.indigo.renderer.accessor.AccessChunkRenderer;
|
||||
import net.fabricmc.indigo.renderer.accessor.AccessChunkRendererRegion;
|
||||
import net.fabricmc.indigo.renderer.render.TerrainRenderContext;
|
||||
import net.minecraft.block.BlockRenderLayer;
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.block.BlockRenderManager;
|
||||
import net.minecraft.client.render.chunk.ChunkRenderData;
|
||||
import net.minecraft.client.render.chunk.ChunkRenderTask;
|
||||
import net.minecraft.client.render.chunk.ChunkRenderer;
|
||||
import net.minecraft.client.render.chunk.ChunkBatcher.ChunkRenderer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
/**
|
||||
* Implements the main hooks for terrain rendering. Attempts to tread
|
||||
* lightly. This means we are deliberately stepping over some minor
|
||||
* optimization opportunities.<p>
|
||||
*
|
||||
* Non-Fabric renderer implementations that are looking to maximize
|
||||
* performance will likely take a much more aggressive approach.
|
||||
* For that reason, mod authors who want compatibility with advanced
|
||||
* renderers will do well to steer clear of chunk rebuild hooks unless
|
||||
* they are creating a renderer.<p>
|
||||
*
|
||||
* These hooks are intended only for the Fabric default renderer and
|
||||
* aren't expected to be present when a different renderer is being used.
|
||||
* Renderer authors are responsible for creating the hooks they need.
|
||||
* (Though they can use these as a example if they wish.)
|
||||
*/
|
||||
@Mixin(ChunkRenderer.class)
|
||||
public abstract class MixinChunkRenderer implements AccessChunkRenderer{
|
||||
@Shadow private BlockPos.Mutable origin;
|
||||
|
||||
@Shadow abstract void beginBufferBuilding(BufferBuilder bufferBuilder_1, BlockPos blockPos_1);
|
||||
@Shadow abstract void endBufferBuilding(BlockRenderLayer blockRenderLayer_1, float float_1, float float_2, float float_3, BufferBuilder bufferBuilder_1, ChunkRenderData chunkRenderData_1);
|
||||
@Shadow abstract void beginBufferBuilding(BufferBuilder builder, BlockPos pos);
|
||||
|
||||
/**
|
||||
* Access method for renderer.
|
||||
*/
|
||||
@Override
|
||||
public void fabric_beginBufferBuilding(BufferBuilder bufferBuilder_1, BlockPos blockPos_1) {
|
||||
beginBufferBuilding(bufferBuilder_1, blockPos_1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save task to renderer, this is the easiest place to capture it.
|
||||
*/
|
||||
@Inject(at = @At("HEAD"), method = "rebuildChunk")
|
||||
private void hookRebuildChunkHead(float float_1, float float_2, float float_3, ChunkRenderTask chunkRenderTask_1, CallbackInfo info) {
|
||||
if(chunkRenderTask_1 != null) {
|
||||
TerrainRenderContext renderer = TerrainRenderContext.POOL.get();
|
||||
renderer.setChunkTask(chunkRenderTask_1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Capture the block layer result flags when they are first created so our renderer
|
||||
* can update then when more than one layer is renderer for a single model.
|
||||
* This is also where we signal the renderer to prepare for a new chunk using
|
||||
* the data we've accumulated up to this point.
|
||||
*/
|
||||
@ModifyVariable(method = "rebuildChunk", at = @At(value = "STORE", ordinal = 0), allow = 1, require = 1)
|
||||
private boolean[] hookResultFlagsAndPrepare(boolean[] flagsIn) {
|
||||
TerrainRenderContext.POOL.get().prepare((ChunkRenderer)(Object)this, origin, flagsIn);
|
||||
return flagsIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the hook that actually implements the rendering API for terrain rendering.<p>
|
||||
*
|
||||
* It's unusual to have a @Redirect in a Fabric library, but in this case
|
||||
* it is our explicit intention that {@link BlockRenderManager#tesselateBlock(BlockState, BlockPos, BlockRenderView, BufferBuilder, Random)}
|
||||
* does not execute for models that will be rendered by our renderer.<p>
|
||||
*
|
||||
* Any mod that wants to redirect this specific call is likely also a renderer, in which case this
|
||||
* renderer should not be present, or the mod should probably instead be relying on the renderer API
|
||||
* which was specifically created to provide for enhanced terrain rendering.<p>
|
||||
*
|
||||
* Note also that {@link BlockRenderManager#tesselateBlock(BlockState, BlockPos, BlockRenderView, BufferBuilder, Random)}
|
||||
* IS called if the block render type is something other than {@link BlockRenderType#MODEL}.
|
||||
* 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 = "rebuildChunk", 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);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release all references. Probably not necessary but would be $#%! to debug if it is.
|
||||
*/
|
||||
@Inject(at = @At("RETURN"), method = "rebuildChunk")
|
||||
private void hookRebuildChunkReturn(float float_1, float float_2, float float_3, ChunkRenderTask chunkRenderTask_1, CallbackInfo info) {
|
||||
TerrainRenderContext.POOL.get().release();
|
||||
public void fabric_beginBufferBuilding(BufferBuilder builder, BlockPos pos) {
|
||||
beginBufferBuilding(builder, pos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
package net.fabricmc.indigo.renderer.render;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction;
|
||||
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.render.RenderContext.QuadTransform;
|
||||
|
@ -32,6 +32,7 @@ import net.fabricmc.indigo.renderer.helper.GeometryHelper;
|
|||
import net.fabricmc.indigo.renderer.mesh.EncodingFormat;
|
||||
import net.fabricmc.indigo.renderer.mesh.MeshImpl;
|
||||
import net.fabricmc.indigo.renderer.mesh.MutableQuadViewImpl;
|
||||
import net.minecraft.block.BlockRenderLayer;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
||||
/**
|
||||
|
@ -39,7 +40,7 @@ import net.minecraft.client.MinecraftClient;
|
|||
* "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, Int2ObjectFunction<AccessBufferBuilder> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
|
||||
protected AbstractMeshConsumer(BlockRenderInfo blockInfo, Function<BlockRenderLayer, AccessBufferBuilder> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
|
||||
super(blockInfo, bufferFunc, aoCalc, transform);
|
||||
}
|
||||
|
||||
|
@ -136,7 +137,7 @@ public abstract class AbstractMeshConsumer extends AbstractQuadRenderer implemen
|
|||
*/
|
||||
private void tesselateQuad(MutableQuadViewImpl quad, RenderMaterialImpl.Value mat, int textureIndex) {
|
||||
final int colorIndex = mat.disableColorIndex(textureIndex) ? -1 : quad.colorIndex();
|
||||
final int renderLayer = blockInfo.layerIndexOrDefault(mat.blendMode(textureIndex));
|
||||
final BlockRenderLayer renderLayer = blockInfo.effectiveRenderLayer(mat.blendMode(textureIndex));
|
||||
|
||||
if(blockInfo.defaultAo && !mat.disableAo(textureIndex)) {
|
||||
if(mat.emissive(textureIndex)) {
|
||||
|
|
|
@ -18,7 +18,8 @@ package net.fabricmc.indigo.renderer.render;
|
|||
|
||||
import static net.fabricmc.indigo.renderer.helper.GeometryHelper.LIGHT_FACE_FLAG;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction;
|
||||
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;
|
||||
|
@ -26,6 +27,7 @@ import net.fabricmc.indigo.renderer.helper.ColorHelper;
|
|||
import net.fabricmc.indigo.renderer.mesh.EncodingFormat;
|
||||
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.util.math.BlockPos;
|
||||
|
||||
|
@ -36,12 +38,12 @@ import net.minecraft.util.math.BlockPos;
|
|||
public abstract class AbstractQuadRenderer {
|
||||
private static final int FULL_BRIGHTNESS = 15 << 20 | 15 << 4;
|
||||
|
||||
protected final Int2ObjectFunction<AccessBufferBuilder> bufferFunc;
|
||||
protected final Function<BlockRenderLayer, AccessBufferBuilder> bufferFunc;
|
||||
protected final BlockRenderInfo blockInfo;
|
||||
protected final AoCalculator aoCalc;
|
||||
protected final QuadTransform transform;
|
||||
|
||||
AbstractQuadRenderer(BlockRenderInfo blockInfo, Int2ObjectFunction<AccessBufferBuilder> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
|
||||
AbstractQuadRenderer(BlockRenderInfo blockInfo, Function<BlockRenderLayer, AccessBufferBuilder> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
|
||||
this.blockInfo = blockInfo;
|
||||
this.bufferFunc = bufferFunc;
|
||||
this.aoCalc = aoCalc;
|
||||
|
@ -64,14 +66,14 @@ public abstract class AbstractQuadRenderer {
|
|||
}
|
||||
|
||||
/** final output step, common to all renders */
|
||||
private void bufferQuad(MutableQuadViewImpl quad, int renderLayer) {
|
||||
bufferFunc.get(renderLayer).fabric_putQuad(quad);
|
||||
private void bufferQuad(MutableQuadViewImpl quad, BlockRenderLayer renderLayer) {
|
||||
bufferFunc.apply(renderLayer).fabric_putQuad(quad);
|
||||
}
|
||||
|
||||
// routines below have a bit of copy-paste code reuse to avoid conditional execution inside a hot loop
|
||||
|
||||
/** for non-emissive mesh quads and all fallback quads with smooth lighting*/
|
||||
protected void tesselateSmooth(MutableQuadViewImpl q, int renderLayer, int blockColorIndex) {
|
||||
protected void tesselateSmooth(MutableQuadViewImpl q, BlockRenderLayer renderLayer, int blockColorIndex) {
|
||||
colorizeQuad(q, blockColorIndex);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
q.spriteColor(i, 0, ColorHelper.multiplyRGB(q.spriteColor(i, 0), aoCalc.ao[i]));
|
||||
|
@ -81,7 +83,7 @@ public abstract class AbstractQuadRenderer {
|
|||
}
|
||||
|
||||
/** for emissive mesh quads with smooth lighting*/
|
||||
protected void tesselateSmoothEmissive(MutableQuadViewImpl q, int renderLayer, int blockColorIndex) {
|
||||
protected void tesselateSmoothEmissive(MutableQuadViewImpl q, BlockRenderLayer renderLayer, int blockColorIndex) {
|
||||
colorizeQuad(q, blockColorIndex);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
q.spriteColor(i, 0, ColorHelper.multiplyRGB(q.spriteColor(i, 0), aoCalc.ao[i]));
|
||||
|
@ -91,7 +93,7 @@ public abstract class AbstractQuadRenderer {
|
|||
}
|
||||
|
||||
/** for non-emissive mesh quads and all fallback quads with flat lighting*/
|
||||
protected void tesselateFlat(MutableQuadViewImpl quad, int renderLayer, int blockColorIndex) {
|
||||
protected void tesselateFlat(MutableQuadViewImpl quad, BlockRenderLayer renderLayer, int blockColorIndex) {
|
||||
colorizeQuad(quad, blockColorIndex);
|
||||
final int brightness = flatBrightness(quad, blockInfo.blockState, blockInfo.blockPos);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
|
@ -101,7 +103,7 @@ public abstract class AbstractQuadRenderer {
|
|||
}
|
||||
|
||||
/** for emissive mesh quads with flat lighting*/
|
||||
protected void tesselateFlatEmissive(MutableQuadViewImpl quad, int renderLayer, int blockColorIndex, int[] lightmaps) {
|
||||
protected void tesselateFlatEmissive(MutableQuadViewImpl quad, BlockRenderLayer renderLayer, int blockColorIndex, int[] lightmaps) {
|
||||
colorizeQuad(quad, blockColorIndex);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
quad.lightmap(i, FULL_BRIGHTNESS);
|
||||
|
@ -115,18 +117,18 @@ public abstract class AbstractQuadRenderer {
|
|||
final int[] data = q.data();
|
||||
final int[] lightmaps = this.lightmaps;
|
||||
lightmaps[0] = data[EncodingFormat.VERTEX_START_OFFSET + 6];
|
||||
lightmaps[1] = data[EncodingFormat.VERTEX_START_OFFSET + 6 + 7];
|
||||
lightmaps[2] = data[EncodingFormat.VERTEX_START_OFFSET + 6 + 14];
|
||||
lightmaps[3] = data[EncodingFormat.VERTEX_START_OFFSET + 6 + 21];
|
||||
lightmaps[1] = data[EncodingFormat.VERTEX_START_OFFSET + 6 + 8];
|
||||
lightmaps[2] = data[EncodingFormat.VERTEX_START_OFFSET + 6 + 16];
|
||||
lightmaps[3] = data[EncodingFormat.VERTEX_START_OFFSET + 6 + 24];
|
||||
}
|
||||
|
||||
protected void restoreLightmaps(MutableQuadViewImpl q) {
|
||||
final int[] data = q.data();
|
||||
final int[] lightmaps = this.lightmaps;
|
||||
data[EncodingFormat.VERTEX_START_OFFSET + 6] = lightmaps[0];
|
||||
data[EncodingFormat.VERTEX_START_OFFSET + 6 + 7] = lightmaps[1];
|
||||
data[EncodingFormat.VERTEX_START_OFFSET + 6 + 14] = lightmaps[2];
|
||||
data[EncodingFormat.VERTEX_START_OFFSET + 6 + 21] = lightmaps[3];
|
||||
data[EncodingFormat.VERTEX_START_OFFSET + 6 + 8] = lightmaps[1];
|
||||
data[EncodingFormat.VERTEX_START_OFFSET + 6 + 16] = lightmaps[2];
|
||||
data[EncodingFormat.VERTEX_START_OFFSET + 6 + 24] = lightmaps[3];
|
||||
}
|
||||
|
||||
private final BlockPos.Mutable mpos = new BlockPos.Mutable();
|
||||
|
|
|
@ -18,8 +18,8 @@ package net.fabricmc.indigo.renderer.render;
|
|||
|
||||
import java.util.Random;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction;
|
||||
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;
|
||||
|
@ -29,6 +29,7 @@ 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.block.BlockRenderLayer;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.block.BlockModelRenderer;
|
||||
|
@ -70,7 +71,7 @@ public class BlockRenderContext extends AbstractRenderContext implements RenderC
|
|||
return blockView == null ? 1f : AoLuminanceFix.INSTANCE.apply(blockView, pos);
|
||||
}
|
||||
|
||||
private AccessBufferBuilder outputBuffer(int renderLayer) {
|
||||
private AccessBufferBuilder outputBuffer(BlockRenderLayer renderLayer) {
|
||||
didOutput = true;
|
||||
return fabricBuffer;
|
||||
}
|
||||
|
@ -108,7 +109,7 @@ public class BlockRenderContext extends AbstractRenderContext implements RenderC
|
|||
}
|
||||
|
||||
private class MeshConsumer extends AbstractMeshConsumer {
|
||||
MeshConsumer(BlockRenderInfo blockInfo, Int2ObjectFunction<AccessBufferBuilder> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
|
||||
MeshConsumer(BlockRenderInfo blockInfo, Function<BlockRenderLayer, AccessBufferBuilder> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
|
||||
super(blockInfo, bufferFunc, aoCalc, transform);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package net.fabricmc.indigo.renderer.render;
|
|||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
|
||||
import net.minecraft.block.BlockRenderLayer;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
@ -42,7 +43,7 @@ public class BlockRenderInfo {
|
|||
public BlockState blockState;
|
||||
public long seed;
|
||||
boolean defaultAo;
|
||||
int defaultLayerIndex;
|
||||
BlockRenderLayer defaultLayer;
|
||||
|
||||
public final Supplier<Random> randomSupplier = () -> {
|
||||
final Random result = random;
|
||||
|
@ -65,7 +66,8 @@ public class BlockRenderInfo {
|
|||
// in the unlikely case seed actually matches this, we'll simply retrieve it more than one
|
||||
seed = -1L;
|
||||
defaultAo = modelAO && MinecraftClient.isAmbientOcclusionEnabled() && blockState.getLuminance() == 0;
|
||||
defaultLayerIndex = blockState.getBlock().getRenderLayer().ordinal();
|
||||
|
||||
defaultLayer = BlockRenderLayer.method_22715(blockState);
|
||||
}
|
||||
|
||||
public void release() {
|
||||
|
@ -81,7 +83,7 @@ public class BlockRenderInfo {
|
|||
return true;
|
||||
}
|
||||
|
||||
int layerIndexOrDefault(BlockRenderLayer layer) {
|
||||
return layer == null ? this.defaultLayerIndex : layer.ordinal();
|
||||
BlockRenderLayer effectiveRenderLayer(BlendMode blendMode) {
|
||||
return blendMode == BlendMode.DEFAULT ? this.defaultLayer : blendMode.blockRenderLayer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,18 +18,20 @@ package net.fabricmc.indigo.renderer.render;
|
|||
|
||||
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;
|
||||
import net.fabricmc.indigo.renderer.mesh.MutableQuadViewImpl;
|
||||
import net.minecraft.block.Block.OffsetType;
|
||||
import net.minecraft.block.BlockRenderLayer;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.chunk.ChunkRenderData;
|
||||
import net.minecraft.client.render.chunk.ChunkRenderTask;
|
||||
import net.minecraft.client.render.chunk.ChunkRenderer;
|
||||
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.ChunkRendererRegion;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
@ -70,14 +72,12 @@ public class ChunkRenderInfo {
|
|||
|
||||
private final BlockRenderInfo blockInfo;
|
||||
private final BlockPos.Mutable chunkOrigin = new BlockPos.Mutable();
|
||||
ChunkRenderTask chunkTask;
|
||||
ChunkRenderData chunkData;
|
||||
AccessChunkRendererData chunkData;
|
||||
ChunkRenderer chunkRenderer;
|
||||
BlockLayeredBufferBuilder builders;
|
||||
BlockRenderView blockView;
|
||||
boolean [] resultFlags;
|
||||
|
||||
private final AccessBufferBuilder[] buffers = new AccessBufferBuilder[4];
|
||||
private final BlockRenderLayer[] LAYERS = BlockRenderLayer.values();
|
||||
private final Object2ObjectOpenHashMap<BlockRenderLayer, AccessBufferBuilder> buffers = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
private double chunkOffsetX;
|
||||
private double chunkOffsetY;
|
||||
|
@ -96,23 +96,17 @@ public class ChunkRenderInfo {
|
|||
aoLevelCache.defaultReturnValue(Float.MAX_VALUE);
|
||||
}
|
||||
|
||||
void setBlockView(ChunkRendererRegion blockView) {
|
||||
this.blockView = blockView;
|
||||
}
|
||||
|
||||
void setChunkTask(ChunkRenderTask chunkTask) {
|
||||
this.chunkTask = chunkTask;
|
||||
}
|
||||
|
||||
void prepare(ChunkRenderer chunkRenderer, BlockPos.Mutable chunkOrigin, boolean [] resultFlags) {
|
||||
this.chunkOrigin.set(chunkOrigin);
|
||||
this.chunkData = chunkTask.getRenderData();
|
||||
void prepare(
|
||||
ChunkRendererRegion blockView,
|
||||
ChunkRenderer chunkRenderer,
|
||||
ChunkRenderData chunkData,
|
||||
BlockLayeredBufferBuilder builders) {
|
||||
this.blockView = blockView;
|
||||
this.chunkOrigin.set(chunkRenderer.getOrigin());
|
||||
this.chunkData = (AccessChunkRendererData) chunkData;
|
||||
this.chunkRenderer = chunkRenderer;
|
||||
this.resultFlags = resultFlags;
|
||||
buffers[0] = null;
|
||||
buffers[1] = null;
|
||||
buffers[2] = null;
|
||||
buffers[3] = null;
|
||||
this.builders = builders;
|
||||
buffers.clear();
|
||||
chunkOffsetX = -chunkOrigin.getX();
|
||||
chunkOffsetY = -chunkOrigin.getY();
|
||||
chunkOffsetZ = -chunkOrigin.getZ();
|
||||
|
@ -122,12 +116,8 @@ public class ChunkRenderInfo {
|
|||
|
||||
void release() {
|
||||
chunkData = null;
|
||||
chunkTask = null;
|
||||
chunkRenderer = null;
|
||||
buffers[0] = null;
|
||||
buffers[1] = null;
|
||||
buffers[2] = null;
|
||||
buffers[3] = null;
|
||||
buffers.clear();
|
||||
}
|
||||
|
||||
void beginBlock() {
|
||||
|
@ -154,21 +144,18 @@ public class ChunkRenderInfo {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/** Lazily retrieves output buffer for given layer, initializing as needed. */
|
||||
public AccessBufferBuilder getInitializedBuffer(int layerIndex) {
|
||||
// redundant for first layer, but probably not faster to check
|
||||
resultFlags[layerIndex] = true;
|
||||
|
||||
AccessBufferBuilder result = buffers[layerIndex];
|
||||
public AccessBufferBuilder getInitializedBuffer(BlockRenderLayer renderLayer) {
|
||||
AccessBufferBuilder result = buffers.get(renderLayer);
|
||||
if (result == null) {
|
||||
BufferBuilder builder = chunkTask.getBufferBuilders().get(layerIndex);
|
||||
buffers[layerIndex] = (AccessBufferBuilder) builder;
|
||||
BlockRenderLayer layer = LAYERS[layerIndex];
|
||||
if (!chunkData.isBufferInitialized(layer)) {
|
||||
chunkData.markBufferInitialized(layer); // start buffer
|
||||
BufferBuilder builder = builders.get(renderLayer);
|
||||
result = (AccessBufferBuilder) builder;
|
||||
chunkData.fabric_markPopulated(renderLayer);
|
||||
buffers.put(renderLayer, result);
|
||||
if (chunkData.fabric_markInitialized(renderLayer)) {
|
||||
((AccessChunkRenderer) chunkRenderer).fabric_beginBufferBuilding(builder, chunkOrigin);
|
||||
}
|
||||
result = (AccessBufferBuilder) builder;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
|
|||
public void renderModel(FabricBakedModel model, int color, ItemStack stack, VanillaQuadHandler vanillaHandler) {
|
||||
this.color = color;
|
||||
|
||||
if(stack.isEmpty() && enchantmentStack != null) {
|
||||
if (stack.isEmpty() && enchantmentStack != null) {
|
||||
enchantment = true;
|
||||
this.itemStack = enchantmentStack;
|
||||
enchantmentStack = null;
|
||||
|
@ -110,7 +110,7 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
|
|||
model.emitItemQuads(stack, randomSupplier, this);
|
||||
tessellator.draw();
|
||||
|
||||
if(smoothShading) {
|
||||
if (smoothShading) {
|
||||
RenderSystem.shadeModel(GL11.GL_FLAT);
|
||||
smoothShading = false;
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
|
|||
final int[] data = m.data();
|
||||
final int limit = data.length;
|
||||
int index = 0;
|
||||
while(index < limit) {
|
||||
while (index < limit) {
|
||||
RenderMaterialImpl.Value mat = RenderMaterialImpl.byIndex(data[index]);
|
||||
final int stride = EncodingFormat.stride(mat.spriteDepth());
|
||||
System.arraycopy(data, index, editorQuad.data(), 0, stride);
|
||||
|
@ -164,7 +164,7 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
|
|||
* for every item, every frame.
|
||||
*/
|
||||
private void handleShading() {
|
||||
if(!smoothShading && editorQuad.hasVertexNormals()) {
|
||||
if (!smoothShading && editorQuad.hasVertexNormals()) {
|
||||
smoothShading = true;
|
||||
RenderSystem.shadeModel(GL11.GL_SMOOTH);
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
|
|||
|
||||
private void colorizeAndOutput(int quadColor) {
|
||||
final MutableQuadViewImpl q = editorQuad;
|
||||
for(int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int c = q.spriteColor(i, 0);
|
||||
c = ColorHelper.multiplyColor(quadColor, c);
|
||||
q.spriteColor(i, 0, ColorHelper.swapRedBlueIfNeeded(c));
|
||||
|
@ -192,7 +192,7 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
|
|||
|
||||
private void renderQuad() {
|
||||
final MutableQuadViewImpl quad = editorQuad;
|
||||
if(!transform(editorQuad)) {
|
||||
if (!transform(editorQuad)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -202,19 +202,17 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
|
|||
|
||||
handleShading();
|
||||
|
||||
// A bit of a hack - copy packed normals on top of lightmaps.
|
||||
// Violates normal encoding format but the editor content will be discarded
|
||||
// and this avoids the step of copying to a separate array.
|
||||
quad.copyNormals(quadData, EncodingFormat.VERTEX_START_OFFSET);
|
||||
quad.populateMissingNormals();
|
||||
quad.lightmap(0xF000F0, 0xF000F0, 0xF000F0, 0xF000F0);
|
||||
|
||||
colorizeAndOutput(!enchantment && mat.disableColorIndex(0) ? -1 : quadColor);
|
||||
|
||||
// no need to render additional textures for enchantment overlay
|
||||
if(!enchantment && textureCount > 1) {
|
||||
if (!enchantment && textureCount > 1) {
|
||||
quad.copyColorUV(1, quadData, EncodingFormat.VERTEX_START_OFFSET);
|
||||
colorizeAndOutput(mat.disableColorIndex(1) ? -1 : quadColor);
|
||||
|
||||
if(textureCount == 3) {
|
||||
if (textureCount == 3) {
|
||||
quad.copyColorUV(2, quadData, EncodingFormat.VERTEX_START_OFFSET);
|
||||
colorizeAndOutput(mat.disableColorIndex(2) ? -1 : quadColor);
|
||||
}
|
||||
|
@ -227,15 +225,15 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
|
|||
}
|
||||
|
||||
private void fallbackConsumer(BakedModel model) {
|
||||
if(hasTransform()) {
|
||||
if (hasTransform()) {
|
||||
// if there's a transform in effect, convert to mesh-based quads so that we can apply it
|
||||
for(int i = 0; i < 7; i++) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
random.setSeed(42L);
|
||||
final Direction cullFace = ModelHelper.faceFromIndex(i);
|
||||
renderFallbackWithTransform(bufferBuilder, model.getQuads((BlockState)null, cullFace, random), color, itemStack, cullFace);
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < 7; i++) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
random.setSeed(42L);
|
||||
vanillaHandler.accept(bufferBuilder, model.getQuads((BlockState)null, ModelHelper.faceFromIndex(i), random), color, itemStack);
|
||||
}
|
||||
|
@ -243,12 +241,12 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
|
|||
};
|
||||
|
||||
private void renderFallbackWithTransform(BufferBuilder bufferBuilder, List<BakedQuad> quads, int color, ItemStack stack, Direction cullFace) {
|
||||
if(quads.isEmpty()) {
|
||||
if (quads.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if(CompatibilityHelper.canRender(quads.get(0).getVertexData())) {
|
||||
if (CompatibilityHelper.canRender(quads.get(0).getVertexData())) {
|
||||
Maker editorQuad = this.editorQuad;
|
||||
for(BakedQuad q : quads) {
|
||||
for (BakedQuad q : quads) {
|
||||
editorQuad.clear();
|
||||
editorQuad.fromVanilla(q.getVertexData(), 0, false);
|
||||
editorQuad.cullFace(cullFace);
|
||||
|
|
|
@ -58,7 +58,7 @@ public class TerrainFallbackConsumer extends AbstractQuadRenderer implements Con
|
|||
private static Value MATERIAL_FLAT = (Value) IndigoRenderer.INSTANCE.materialFinder().disableAo(0, true).find();
|
||||
private static Value MATERIAL_SHADED = (Value) IndigoRenderer.INSTANCE.materialFinder().find();
|
||||
|
||||
private final int[] editorBuffer = new int[28];
|
||||
private final int[] editorBuffer = new int[32];
|
||||
private final ChunkRenderInfo chunkInfo;
|
||||
|
||||
TerrainFallbackConsumer(BlockRenderInfo blockInfo, ChunkRenderInfo chunkInfo, AoCalculator aoCalc, QuadTransform transform) {
|
||||
|
@ -90,7 +90,7 @@ public class TerrainFallbackConsumer extends AbstractQuadRenderer implements Con
|
|||
Direction face = ModelHelper.faceFromIndex(i);
|
||||
List<BakedQuad> quads = model.getQuads(blockState, face, random.get());
|
||||
final int count = quads.size();
|
||||
if(count != 0 && blockInfo.shouldDrawFace(face)) {
|
||||
if (count != 0 && blockInfo.shouldDrawFace(face)) {
|
||||
for(int j = 0; j < count; j++) {
|
||||
BakedQuad q = quads.get(j);
|
||||
renderQuad(q, face, defaultMaterial);
|
||||
|
@ -100,7 +100,7 @@ public class TerrainFallbackConsumer extends AbstractQuadRenderer implements Con
|
|||
|
||||
List<BakedQuad> quads = model.getQuads(blockState, null, random.get());
|
||||
final int count = quads.size();
|
||||
if(count != 0) {
|
||||
if (count != 0) {
|
||||
for(int j = 0; j < count; j++) {
|
||||
BakedQuad q = quads.get(j);
|
||||
renderQuad(q, null, defaultMaterial);
|
||||
|
@ -110,12 +110,12 @@ public class TerrainFallbackConsumer extends AbstractQuadRenderer implements Con
|
|||
|
||||
private void renderQuad(BakedQuad quad, Direction cullFace, Value defaultMaterial) {
|
||||
final int[] vertexData = quad.getVertexData();
|
||||
if(!CompatibilityHelper.canRender(vertexData)) {
|
||||
if (!CompatibilityHelper.canRender(vertexData)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final MutableQuadViewImpl editorQuad = this.editorQuad;
|
||||
System.arraycopy(vertexData, 0, editorBuffer, 0, 28);
|
||||
System.arraycopy(vertexData, 0, editorBuffer, 0, 32);
|
||||
editorQuad.cullFace(cullFace);
|
||||
final Direction lightFace = quad.getFace();
|
||||
editorQuad.lightFace(lightFace);
|
||||
|
@ -123,7 +123,7 @@ public class TerrainFallbackConsumer extends AbstractQuadRenderer implements Con
|
|||
editorQuad.colorIndex(quad.getColorIndex());
|
||||
editorQuad.material(defaultMaterial);
|
||||
|
||||
if(!transform.transform(editorQuad)) {
|
||||
if (!transform.transform(editorQuad)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ public class TerrainFallbackConsumer extends AbstractQuadRenderer implements Con
|
|||
editorQuad.invalidateShape();
|
||||
aoCalc.compute(editorQuad, true);
|
||||
chunkInfo.applyOffsets(editorQuad);
|
||||
tesselateSmooth(editorQuad, blockInfo.defaultLayerIndex, editorQuad.colorIndex());
|
||||
tesselateSmooth(editorQuad, blockInfo.defaultLayer, editorQuad.colorIndex());
|
||||
} else {
|
||||
// vanilla compatibility hack
|
||||
// For flat lighting, cull face drives everything and light face is ignored.
|
||||
|
@ -145,7 +145,7 @@ public class TerrainFallbackConsumer extends AbstractQuadRenderer implements Con
|
|||
editorQuad.lightFace(cullFace);
|
||||
}
|
||||
chunkInfo.applyOffsets(editorQuad);
|
||||
tesselateFlat(editorQuad, blockInfo.defaultLayerIndex, editorQuad.colorIndex());
|
||||
tesselateFlat(editorQuad, blockInfo.defaultLayer, editorQuad.colorIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,8 +24,9 @@ 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.block.BlockState;
|
||||
import net.minecraft.client.render.chunk.ChunkRenderTask;
|
||||
import net.minecraft.client.render.chunk.ChunkRenderer;
|
||||
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.util.crash.CrashException;
|
||||
|
@ -46,17 +47,13 @@ public class TerrainRenderContext extends AbstractRenderContext implements Rende
|
|||
private final TerrainMeshConsumer meshConsumer = new TerrainMeshConsumer(blockInfo, chunkInfo, aoCalc, this::transform);
|
||||
private final TerrainFallbackConsumer fallbackConsumer = new TerrainFallbackConsumer(blockInfo, chunkInfo, aoCalc, this::transform);
|
||||
|
||||
public void setBlockView(ChunkRendererRegion blockView) {
|
||||
blockInfo.setBlockView(blockView);
|
||||
chunkInfo.setBlockView(blockView);
|
||||
}
|
||||
|
||||
public void setChunkTask(ChunkRenderTask chunkTask) {
|
||||
chunkInfo.setChunkTask(chunkTask);
|
||||
}
|
||||
|
||||
public TerrainRenderContext prepare(ChunkRenderer chunkRenderer, BlockPos.Mutable chunkOrigin, boolean [] resultFlags) {
|
||||
chunkInfo.prepare(chunkRenderer, chunkOrigin, resultFlags);
|
||||
public TerrainRenderContext prepare(
|
||||
ChunkRendererRegion blockView,
|
||||
ChunkRenderer chunkRenderer,
|
||||
ChunkRenderData chunkData,
|
||||
BlockLayeredBufferBuilder builders) {
|
||||
blockInfo.setBlockView(blockView);
|
||||
chunkInfo.prepare(blockView, chunkRenderer, chunkData, builders);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -78,7 +75,8 @@ public class TerrainRenderContext extends AbstractRenderContext implements Rende
|
|||
CrashReportSection.addBlockInfo(crashReportElement_1, blockPos, blockState);
|
||||
throw new CrashException(crashReport_1);
|
||||
}
|
||||
return chunkInfo.resultFlags[blockInfo.defaultLayerIndex];
|
||||
// false because we've already marked the chunk as populated - caller doesn't need to
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,9 +9,10 @@
|
|||
"BufferBuilderOffsetAccessor",
|
||||
"MixinBlockModelRenderer",
|
||||
"MixinBufferBuilder",
|
||||
"MixinChunkRebuildTask",
|
||||
"MixinChunkRenderData",
|
||||
"MixinChunkRenderer",
|
||||
"MixinChunkRendererRegion",
|
||||
"MixinChunkRenderTask",
|
||||
"MixinItemRenderer"
|
||||
],
|
||||
"injectors": {
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.6.1",
|
||||
"minecraft": ">=1.15-",
|
||||
"fabricloader": ">=0.6.2",
|
||||
"minecraft": ">=1.15-alpha.19.38.b",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-renderer-api-v1": "*"
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-rendering-data-attachment-v1"
|
||||
version = getSubprojectVersion(project, "0.1.0")
|
||||
version = getSubprojectVersion(project, "0.1.1")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -40,7 +40,7 @@ import net.minecraft.world.BlockRenderView;
|
|||
* application from network packets and render chunk rebuilds. Use of {link #getCachedRenderData()}
|
||||
* will ensure consistency of model state with the rest of the chunk being rendered.<p>
|
||||
*
|
||||
* Models should avoid using {@link ExtendedBlockView#getBlockEntity(BlockPos)}
|
||||
* Models should avoid using {@link BlockRenderView#getBlockEntity(BlockPos)}
|
||||
* to ensure thread safety because this view may be accessed outside the main client thread.
|
||||
* Models that require Block Entity data should implement {@link RenderAttachmentBlockEntity}
|
||||
* and then use {@link #getBlockEntityRenderAttachment(BlockPos)} to retrieve it. When called from the
|
||||
|
@ -59,7 +59,7 @@ public interface RenderAttachedBlockView extends BlockRenderView {
|
|||
* @param pos Position of the block for the block model.
|
||||
*/
|
||||
default Object getBlockEntityRenderAttachment(BlockPos pos) {
|
||||
BlockEntity be = this.getBlockEntity(pos);
|
||||
BlockEntity be = ((BlockRenderView) this).getBlockEntity(pos);
|
||||
return be == null ? null : ((RenderAttachmentBlockEntity) be).getRenderAttachmentData();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
package net.fabricmc.fabric.mixin.rendering.data;
|
||||
|
||||
import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView;
|
||||
import net.minecraft.class_4538;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
/** Make {@link BlockRenderView} implement {@link RenderAttachedBlockView}. */
|
||||
@Mixin(BlockRenderView.class)
|
||||
@Mixin(class_4538.class)
|
||||
public interface MixinViewableWorld extends RenderAttachedBlockView {
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-rendering-fluids-v1"
|
||||
version = getSubprojectVersion(project, "0.1.1")
|
||||
version = getSubprojectVersion(project, "0.1.2")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
archivesBaseName = "fabric-resource-loader-v0"
|
||||
version = getSubprojectVersion(project, "0.1.3")
|
||||
version = getSubprojectVersion(project, "0.1.4")
|
||||
|
|
|
@ -15,6 +15,7 @@ rootProject.name = "fabric-api"
|
|||
include 'fabric-api-base'
|
||||
|
||||
include 'fabric-biomes-v1'
|
||||
include 'fabric-blockrenderlayer-v1'
|
||||
include 'fabric-commands-v0'
|
||||
include 'fabric-containers-v0'
|
||||
include 'fabric-content-registries-v0'
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.6.2",
|
||||
"minecraft": ">=1.15-alpha.19.38.a"
|
||||
"minecraft": "~1.15-alpha.19.38.b"
|
||||
},
|
||||
"description": "Core API module providing key hooks and intercompatibility features."
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue