mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-26 15:06:28 +01:00
Improve virtual model rendering
- Use VirtualEmptyBlockGetter instead of mc.level - Move getBufferBuilder from BlockModel to ModelUtil - Add static .is method to VirtualEmptyModelData
This commit is contained in:
parent
26c35e31b6
commit
810cae681a
4 changed files with 181 additions and 46 deletions
|
@ -1,24 +1,14 @@
|
|||
package com.jozufozu.flywheel.core.model;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||
import com.jozufozu.flywheel.core.Formats;
|
||||
import com.jozufozu.flywheel.util.BufferBuilderReader;
|
||||
import com.jozufozu.flywheel.util.RenderMath;
|
||||
import com.jozufozu.flywheel.util.VirtualEmptyModelData;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
|
||||
import net.minecraft.client.renderer.block.ModelBlockRenderer;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
|
@ -42,7 +32,7 @@ public class BlockModel implements Model {
|
|||
}
|
||||
|
||||
public BlockModel(BakedModel model, BlockState referenceState, PoseStack ms) {
|
||||
reader = new BufferBuilderReader(getBufferBuilder(model, referenceState, ms));
|
||||
reader = new BufferBuilderReader(ModelUtil.getBufferBuilder(model, referenceState, ms));
|
||||
name = referenceState.toString();
|
||||
}
|
||||
|
||||
|
@ -76,32 +66,4 @@ public class BlockModel implements Model {
|
|||
buffer.endVertex();
|
||||
}
|
||||
}
|
||||
|
||||
public static BufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack ms) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
BlockRenderDispatcher dispatcher = mc.getBlockRenderer();
|
||||
ModelBlockRenderer blockRenderer = dispatcher.getModelRenderer();
|
||||
BufferBuilder builder = new BufferBuilder(512);
|
||||
|
||||
// BakedQuadWrapper quadReader = new BakedQuadWrapper();
|
||||
//
|
||||
// IModelData modelData = model.getModelData(mc.world, BlockPos.ZERO.up(255), referenceState, VirtualEmptyModelData.INSTANCE);
|
||||
// List<BakedQuad> quads = Arrays.stream(dirs)
|
||||
// .flatMap(dir -> model.getQuads(referenceState, dir, mc.world.rand, modelData).stream())
|
||||
// .collect(Collectors.toList());
|
||||
|
||||
builder.begin(com.mojang.blaze3d.vertex.VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
blockRenderer.tesselateBlock(mc.level, model, referenceState, BlockPos.ZERO.above(255), ms, builder, true, mc.level.random, 42, OverlayTexture.NO_OVERLAY, VirtualEmptyModelData.INSTANCE);
|
||||
builder.end();
|
||||
return builder;
|
||||
}
|
||||
|
||||
// DOWN, UP, NORTH, SOUTH, WEST, EAST, null
|
||||
private static final Direction[] dirs;
|
||||
|
||||
static {
|
||||
Direction[] directions = Direction.values();
|
||||
|
||||
dirs = Arrays.copyOf(directions, directions.length + 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
package com.jozufozu.flywheel.core.model;
|
||||
|
||||
import static com.mojang.blaze3d.vertex.VertexFormat.Mode.QUADS;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Random;
|
||||
|
||||
import com.jozufozu.flywheel.util.Lazy;
|
||||
import com.jozufozu.flywheel.util.VirtualEmptyBlockGetter;
|
||||
import com.jozufozu.flywheel.util.VirtualEmptyModelData;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ItemBlockRenderTypes;
|
||||
|
@ -16,7 +18,9 @@ import net.minecraft.client.renderer.RenderType;
|
|||
import net.minecraft.client.renderer.block.BlockModelShaper;
|
||||
import net.minecraft.client.renderer.block.ModelBlockRenderer;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -26,13 +30,42 @@ import net.minecraftforge.client.model.data.EmptyModelData;
|
|||
|
||||
public class ModelUtil {
|
||||
private static final Lazy<ModelBlockRenderer> MODEL_RENDERER = Lazy.of(() -> new ModelBlockRenderer(Minecraft.getInstance().getBlockColors()));
|
||||
private static final Lazy<BlockModelShaper> BLOCK_MODELS = Lazy.of(() -> Minecraft.getInstance().getModelManager().getBlockModelShaper());
|
||||
|
||||
// DOWN, UP, NORTH, SOUTH, WEST, EAST, null
|
||||
private static final Direction[] CULL_FACES;
|
||||
|
||||
static {
|
||||
Direction[] directions = Direction.values();
|
||||
|
||||
CULL_FACES = Arrays.copyOf(directions, directions.length + 1);
|
||||
}
|
||||
|
||||
public static BufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack ms) {
|
||||
ModelBlockRenderer blockRenderer = Minecraft.getInstance().getBlockRenderer().getModelRenderer();
|
||||
BufferBuilder builder = new BufferBuilder(512);
|
||||
|
||||
// BakedQuadWrapper quadReader = new BakedQuadWrapper();
|
||||
//
|
||||
// IModelData modelData = model.getModelData(VirtualEmptyBlockGetter.INSTANCE, BlockPos.ZERO, referenceState, VirtualEmptyModelData.INSTANCE);
|
||||
// List<BakedQuad> quads = Arrays.stream(CULL_FACES)
|
||||
// .flatMap(dir -> model.getQuads(referenceState, dir, new Random(), modelData).stream())
|
||||
// .collect(Collectors.toList());
|
||||
|
||||
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
blockRenderer.tesselateBlock(VirtualEmptyBlockGetter.INSTANCE, model, referenceState, BlockPos.ZERO, ms, builder,
|
||||
true, new Random(), 42, OverlayTexture.NO_OVERLAY, VirtualEmptyModelData.INSTANCE);
|
||||
builder.end();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static BufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks) {
|
||||
ModelBlockRenderer modelRenderer = MODEL_RENDERER.get();
|
||||
BlockModelShaper blockModels = Minecraft.getInstance().getModelManager().getBlockModelShaper();
|
||||
|
||||
PoseStack ms = new PoseStack();
|
||||
Random random = new Random();
|
||||
BufferBuilder builder = new BufferBuilder(DefaultVertexFormat.BLOCK.getIntegerSize());
|
||||
builder.begin(QUADS, DefaultVertexFormat.BLOCK);
|
||||
BufferBuilder builder = new BufferBuilder(512);
|
||||
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
|
||||
ForgeHooksClient.setRenderType(layer);
|
||||
ModelBlockRenderer.enableCaching();
|
||||
|
@ -48,8 +81,8 @@ public class ModelUtil {
|
|||
|
||||
ms.pushPose();
|
||||
ms.translate(pos.getX(), pos.getY(), pos.getZ());
|
||||
MODEL_RENDERER.get().tesselateBlock(renderWorld, BLOCK_MODELS.get().getBlockModel(state), state, pos, ms, builder, true,
|
||||
random, 42, OverlayTexture.NO_OVERLAY, EmptyModelData.INSTANCE);
|
||||
modelRenderer.tesselateBlock(renderWorld, blockModels.getBlockModel(state), state, pos, ms, builder,
|
||||
true, random, 42, OverlayTexture.NO_OVERLAY, EmptyModelData.INSTANCE);
|
||||
ms.popPose();
|
||||
}
|
||||
ModelBlockRenderer.clearCache();
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
package com.jozufozu.flywheel.util;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.ColorResolver;
|
||||
import net.minecraft.world.level.LightLayer;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.DataLayer;
|
||||
import net.minecraft.world.level.chunk.LightChunkGetter;
|
||||
import net.minecraft.world.level.lighting.LayerLightEventListener;
|
||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
|
||||
public enum VirtualEmptyBlockGetter implements BlockAndTintGetter {
|
||||
INSTANCE;
|
||||
|
||||
private final LevelLightEngine lightEngine = new LevelLightEngine(new LightChunkGetter() {
|
||||
@Override
|
||||
public BlockGetter getChunkForLighting(int p_63023_, int p_63024_) {
|
||||
return VirtualEmptyBlockGetter.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockGetter getLevel() {
|
||||
return VirtualEmptyBlockGetter.this;
|
||||
}
|
||||
}, false, false) {
|
||||
private static final LayerLightEventListener SKY_DUMMY_LISTENER = new LayerLightEventListener() {
|
||||
@Override
|
||||
public void checkBlock(BlockPos pos) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockEmissionIncrease(BlockPos pos, int p_164456_) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLightWork() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int runUpdates(int p_164449_, boolean p_164450_, boolean p_164451_) {
|
||||
return p_164449_;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSectionStatus(SectionPos pos, boolean p_75838_) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableLightSources(ChunkPos pos, boolean p_164453_) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataLayer getDataLayerData(SectionPos pos) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightValue(BlockPos pos) {
|
||||
return 15;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public LayerLightEventListener getLayerListener(LightLayer layer) {
|
||||
if (layer == LightLayer.BLOCK) {
|
||||
return LayerLightEventListener.DummyLightLayerEventListener.INSTANCE;
|
||||
} else {
|
||||
return SKY_DUMMY_LISTENER;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRawBrightness(BlockPos pos, int skyDarken) {
|
||||
return 15 - skyDarken;
|
||||
}
|
||||
};
|
||||
|
||||
public static boolean is(BlockAndTintGetter blockGetter) {
|
||||
return blockGetter == INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity getBlockEntity(BlockPos pos) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidState getFluidState(BlockPos pos) {
|
||||
return Fluids.EMPTY.defaultFluidState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinBuildHeight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getShade(Direction direction, boolean bool) {
|
||||
return Minecraft.getInstance().level.getShade(direction, bool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelLightEngine getLightEngine() {
|
||||
return lightEngine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockTint(BlockPos pos, ColorResolver resolver) {
|
||||
Biome plainsBiome = Minecraft.getInstance().getConnection().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getOrThrow(Biomes.PLAINS);
|
||||
return resolver.getColor(plainsBiome, pos.getX(), pos.getZ());
|
||||
}
|
||||
}
|
|
@ -12,6 +12,10 @@ public enum VirtualEmptyModelData implements IModelData {
|
|||
|
||||
INSTANCE;
|
||||
|
||||
public static boolean is(IModelData data) {
|
||||
return data == INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasProperty(ModelProperty<?> prop) {
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue