VertexConsumer-related clean up

- Clean up VertexWriter to closer match BufferBuilder
- Clean up MeshEmitter on Fabric/NeoForge and remove BufferBuilderAccessor
- Remove model data and model data lookup parameters in NeoForge model builders; use IBlockGetterExtension#getModelData instead
- Fix artifact Minecraft version
This commit is contained in:
PepperCode1 2024-11-04 13:16:08 -08:00
parent ad2f3c860b
commit 69f4899ac6
10 changed files with 65 additions and 128 deletions

View File

@ -14,9 +14,8 @@ class VertexWriter implements VertexConsumer {
private MemoryBlock data;
private int vertexCount;
private boolean filledPosition;
private boolean filledTexture;
private boolean filledNormal;
private boolean filledTexture = true;
private boolean filledNormal = true;
public VertexWriter() {
data = MemoryBlock.malloc(128 * STRIDE);
@ -24,20 +23,29 @@ class VertexWriter implements VertexConsumer {
@Override
public VertexConsumer addVertex(float x, float y, float z) {
if (!filledPosition) {
long ptr = vertexPtr();
MemoryUtil.memPutFloat(ptr, x);
MemoryUtil.memPutFloat(ptr + 4, y);
MemoryUtil.memPutFloat(ptr + 8, z);
filledPosition = true;
endLastVertex();
vertexCount++;
long byteSize = vertexCount * STRIDE;
long capacity = data.size();
if (byteSize > capacity) {
data = data.realloc(capacity * 2);
}
return endVertexIfNeeded();
filledTexture = false;
filledNormal = false;
long ptr = vertexPtr();
MemoryUtil.memPutFloat(ptr, x);
MemoryUtil.memPutFloat(ptr + 4, y);
MemoryUtil.memPutFloat(ptr + 8, z);
return this;
}
@Override
public VertexConsumer setColor(int red, int green, int blue, int alpha) {
// ignore color
return endVertexIfNeeded();
return this;
}
@Override
@ -48,19 +56,19 @@ class VertexWriter implements VertexConsumer {
MemoryUtil.memPutFloat(ptr + 16, v);
filledTexture = true;
}
return endVertexIfNeeded();
return this;
}
@Override
public VertexConsumer setUv1(int u, int v) {
// ignore overlay
return endVertexIfNeeded();
return this;
}
@Override
public VertexConsumer setUv2(int u, int v) {
// ignore light
return endVertexIfNeeded();
return this;
}
@Override
@ -72,26 +80,6 @@ class VertexWriter implements VertexConsumer {
MemoryUtil.memPutByte(ptr + 22, DataPacker.packNormI8(z));
filledNormal = true;
}
return endVertexIfNeeded();
}
public VertexConsumer endVertexIfNeeded() {
if (!filledPosition || !filledTexture || !filledNormal) {
// We do not throw here as that matched what vanilla does
return this;
}
filledPosition = false;
filledTexture = false;
filledNormal = false;
vertexCount++;
long byteSize = (vertexCount + 1) * STRIDE;
long capacity = data.size();
if (byteSize > capacity) {
data = data.realloc(capacity * 2);
}
return this;
}
@ -99,14 +87,23 @@ class VertexWriter implements VertexConsumer {
return data.ptr() + vertexCount * STRIDE;
}
private void endLastVertex() {
if (vertexCount != 0) {
if (!filledTexture || !filledNormal) {
throw new IllegalStateException("Missing elements in vertex");
}
}
}
public MemoryBlock copyDataAndReset() {
endLastVertex();
MemoryBlock dataCopy = MemoryBlock.mallocTracked(vertexCount * STRIDE);
data.copyTo(dataCopy);
vertexCount = 0;
filledPosition = false;
filledTexture = false;
filledNormal = false;
filledTexture = true;
filledNormal = true;
return dataCopy;
}

View File

@ -1,12 +0,0 @@
package dev.engine_room.flywheel.impl.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import com.mojang.blaze3d.vertex.BufferBuilder;
@Mixin(BufferBuilder.class)
public interface BufferBuilderAccessor {
@Accessor("building")
boolean flywheel$getBuilding();
}

View File

@ -6,7 +6,6 @@
"refmap": "flywheel.refmap.json",
"client": [
"BlockEntityTypeMixin",
"BufferBuilderAccessor",
"ClientChunkCacheMixin",
"EntityTypeMixin",
"LevelMixin",

View File

@ -7,12 +7,12 @@ import com.mojang.blaze3d.vertex.ByteBufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.VertexFormat;
import dev.engine_room.flywheel.impl.mixin.BufferBuilderAccessor;
import net.minecraft.client.renderer.RenderType;
class MeshEmitter {
private final RenderType renderType;
private final ByteBufferBuilder byteBufferBuilder;
@UnknownNullability
private BufferBuilder bufferBuilder;
private BakedModelBufferer.@UnknownNullability ResultConsumer resultConsumer;
@ -21,7 +21,6 @@ class MeshEmitter {
MeshEmitter(RenderType renderType) {
this.renderType = renderType;
this.byteBufferBuilder = new ByteBufferBuilder(renderType.bufferSize());
this.bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
}
public void prepare(BakedModelBufferer.ResultConsumer resultConsumer) {
@ -29,7 +28,7 @@ class MeshEmitter {
}
public void end() {
if (((BufferBuilderAccessor) bufferBuilder).flywheel$getBuilding()) {
if (bufferBuilder != null) {
emit();
}
resultConsumer = null;
@ -40,24 +39,24 @@ class MeshEmitter {
return bufferBuilder;
}
void prepareForGeometry(boolean shade) {
if (!((BufferBuilderAccessor) bufferBuilder).flywheel$getBuilding()) {
private void prepareForGeometry(boolean shade) {
if (bufferBuilder == null) {
bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
} else if (shade != currentShade) {
emit();
bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
}
currentShade = shade;
}
void emit() {
var renderedBuffer = bufferBuilder.build();
private void emit() {
var data = bufferBuilder.build();
bufferBuilder = null;
if (renderedBuffer != null) {
resultConsumer.accept(renderType, currentShade, renderedBuffer);
renderedBuffer.close();
if (data != null) {
resultConsumer.accept(renderType, currentShade, data);
data.close();
}
bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
}
}

View File

@ -1,7 +1,6 @@
package dev.engine_room.flywheel.lib.model.baked;
import java.util.Iterator;
import java.util.function.Function;
import org.jetbrains.annotations.Nullable;
@ -33,7 +32,7 @@ final class BakedModelBufferer {
private BakedModelBufferer() {
}
public static void bufferSingle(ModelBlockRenderer blockRenderer, @Nullable BlockAndTintGetter level, BakedModel model, @Nullable BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ResultConsumer resultConsumer) {
public static void bufferSingle(ModelBlockRenderer blockRenderer, @Nullable BlockAndTintGetter level, BakedModel model, @Nullable BlockState state, @Nullable PoseStack poseStack, ResultConsumer resultConsumer) {
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
if (level == null) {
if (state == null) {
@ -51,7 +50,7 @@ final class BakedModelBufferer {
RandomSource random = objects.random;
MeshEmitter[] emitters = objects.emitters;
modelData = model.getModelData(level, BlockPos.ZERO, state, modelData);
ModelData modelData = model.getModelData(level, BlockPos.ZERO, state, level.getModelData(BlockPos.ZERO));
random.setSeed(42L);
ChunkRenderTypeSet renderTypes = model.getRenderTypes(state, random, modelData);
@ -69,15 +68,15 @@ final class BakedModelBufferer {
}
}
public static void bufferBlock(BlockRenderDispatcher renderDispatcher, @Nullable BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ResultConsumer resultConsumer) {
public static void bufferBlock(BlockRenderDispatcher renderDispatcher, @Nullable BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, ResultConsumer resultConsumer) {
if (state.getRenderShape() != RenderShape.MODEL) {
return;
}
bufferSingle(renderDispatcher.getModelRenderer(), level, renderDispatcher.getBlockModel(state), state, poseStack, modelData, resultConsumer);
bufferSingle(renderDispatcher.getModelRenderer(), level, renderDispatcher.getBlockModel(state), state, poseStack, resultConsumer);
}
public static void bufferMultiBlock(BlockRenderDispatcher renderDispatcher, Iterator<BlockPos> posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, Function<BlockPos, ModelData> modelDataLookup, boolean renderFluids, ResultConsumer resultConsumer) {
public static void bufferMultiBlock(BlockRenderDispatcher renderDispatcher, Iterator<BlockPos> posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, boolean renderFluids, ResultConsumer resultConsumer) {
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
if (poseStack == null) {
poseStack = objects.identityPoseStack;
@ -116,8 +115,7 @@ final class BakedModelBufferer {
if (state.getRenderShape() == RenderShape.MODEL) {
long seed = state.getSeed(pos);
BakedModel model = renderDispatcher.getBlockModel(state);
ModelData modelData = modelDataLookup.apply(pos);
modelData = model.getModelData(level, pos, state, modelData);
ModelData modelData = model.getModelData(level, pos, state, level.getModelData(pos));
random.setSeed(seed);
ChunkRenderTypeSet renderTypes = model.getRenderTypes(state, random, modelData);

View File

@ -9,13 +9,13 @@ import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.VertexFormat;
import dev.engine_room.flywheel.impl.mixin.BufferBuilderAccessor;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.model.BakedQuad;
class MeshEmitter implements VertexConsumer {
private final RenderType renderType;
private final ByteBufferBuilder byteBufferBuilder;
@UnknownNullability
private BufferBuilder bufferBuilder;
private BakedModelBufferer.@UnknownNullability ResultConsumer resultConsumer;
@ -24,7 +24,6 @@ class MeshEmitter implements VertexConsumer {
MeshEmitter(RenderType renderType) {
this.renderType = renderType;
this.byteBufferBuilder = new ByteBufferBuilder(renderType.bufferSize());
this.bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
}
public void prepare(BakedModelBufferer.ResultConsumer resultConsumer) {
@ -32,7 +31,7 @@ class MeshEmitter implements VertexConsumer {
}
public void end() {
if (((BufferBuilderAccessor) bufferBuilder).flywheel$getBuilding()) {
if (bufferBuilder != null) {
emit();
}
resultConsumer = null;
@ -43,11 +42,12 @@ class MeshEmitter implements VertexConsumer {
return bufferBuilder;
}
void prepareForGeometry(boolean shade) {
if (!((BufferBuilderAccessor) bufferBuilder).flywheel$getBuilding()) {
private void prepareForGeometry(boolean shade) {
if (bufferBuilder == null) {
bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
} else if (shade != currentShade) {
emit();
bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
}
currentShade = shade;
@ -58,14 +58,13 @@ class MeshEmitter implements VertexConsumer {
}
private void emit() {
var renderedBuffer = bufferBuilder.build();
var data = bufferBuilder.build();
bufferBuilder = null;
if (renderedBuffer != null) {
resultConsumer.accept(renderType, currentShade, renderedBuffer);
renderedBuffer.close();
if (data != null) {
resultConsumer.accept(renderType, currentShade, data);
data.close();
}
bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
}
@Override

View File

@ -2,8 +2,6 @@ package dev.engine_room.flywheel.lib.model.baked;
import java.util.function.BiFunction;
import org.jetbrains.annotations.Nullable;
import com.mojang.blaze3d.vertex.PoseStack;
import dev.engine_room.flywheel.api.material.Material;
@ -15,12 +13,8 @@ import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.client.model.data.ModelData;
public final class NeoForgeBakedModelBuilder extends BakedModelBuilder {
@Nullable
private ModelData modelData;
public NeoForgeBakedModelBuilder(BakedModel bakedModel) {
super(bakedModel);
}
@ -49,23 +43,15 @@ public final class NeoForgeBakedModelBuilder extends BakedModelBuilder {
return this;
}
public NeoForgeBakedModelBuilder modelData(ModelData modelData) {
this.modelData = modelData;
return this;
}
@Override
public SimpleModel build() {
if (materialFunc == null) {
materialFunc = ModelUtil::getMaterial;
}
if (modelData == null) {
modelData = ModelData.EMPTY;
}
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
BakedModelBufferer.bufferSingle(ModelUtil.VANILLA_RENDERER.getModelRenderer(), level, bakedModel, blockState, poseStack, modelData, (renderType, shaded, data) -> {
BakedModelBufferer.bufferSingle(ModelUtil.VANILLA_RENDERER.getModelRenderer(), level, bakedModel, blockState, poseStack, (renderType, shaded, data) -> {
Material material = materialFunc.apply(renderType, shaded);
if (material != null) {
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BakedModelBuilder," + "bakedModel=" + bakedModel + ",renderType=" + renderType + ",shaded=" + shaded);

View File

@ -2,8 +2,6 @@ package dev.engine_room.flywheel.lib.model.baked;
import java.util.function.BiFunction;
import org.jetbrains.annotations.Nullable;
import com.mojang.blaze3d.vertex.PoseStack;
import dev.engine_room.flywheel.api.material.Material;
@ -14,12 +12,8 @@ import dev.engine_room.flywheel.lib.model.SimpleModel;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.client.model.data.ModelData;
public final class NeoForgeBlockModelBuilder extends BlockModelBuilder {
@Nullable
private ModelData modelData;
public NeoForgeBlockModelBuilder(BlockState state) {
super(state);
}
@ -42,23 +36,15 @@ public final class NeoForgeBlockModelBuilder extends BlockModelBuilder {
return this;
}
public NeoForgeBlockModelBuilder modelData(ModelData modelData) {
this.modelData = modelData;
return this;
}
@Override
public SimpleModel build() {
if (materialFunc == null) {
materialFunc = ModelUtil::getMaterial;
}
if (modelData == null) {
modelData = ModelData.EMPTY;
}
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
BakedModelBufferer.bufferBlock(ModelUtil.VANILLA_RENDERER, level, state, poseStack, modelData, (renderType, shaded, data) -> {
BakedModelBufferer.bufferBlock(ModelUtil.VANILLA_RENDERER, level, state, poseStack, (renderType, shaded, data) -> {
Material material = materialFunc.apply(renderType, shaded);
if (material != null) {
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BlockModelBuilder," + "blockState=" + state + ",renderType=" + renderType + ",shaded=" + shaded);

View File

@ -1,9 +1,6 @@
package dev.engine_room.flywheel.lib.model.baked;
import java.util.function.BiFunction;
import java.util.function.Function;
import org.jetbrains.annotations.Nullable;
import com.mojang.blaze3d.vertex.PoseStack;
@ -15,12 +12,8 @@ import dev.engine_room.flywheel.lib.model.SimpleModel;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockAndTintGetter;
import net.neoforged.neoforge.client.model.data.ModelData;
public final class NeoForgeMultiBlockModelBuilder extends MultiBlockModelBuilder {
@Nullable
private Function<BlockPos, ModelData> modelDataLookup;
public NeoForgeMultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions) {
super(level, positions);
}
@ -43,23 +36,15 @@ public final class NeoForgeMultiBlockModelBuilder extends MultiBlockModelBuilder
return this;
}
public NeoForgeMultiBlockModelBuilder modelDataLookup(Function<BlockPos, ModelData> modelDataLookup) {
this.modelDataLookup = modelDataLookup;
return this;
}
@Override
public SimpleModel build() {
if (materialFunc == null) {
materialFunc = ModelUtil::getMaterial;
}
if (modelDataLookup == null) {
modelDataLookup = pos -> ModelData.EMPTY;
}
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
BakedModelBufferer.bufferMultiBlock(ModelUtil.VANILLA_RENDERER, positions.iterator(), level, poseStack, modelDataLookup, renderFluids, (renderType, shaded, data) -> {
BakedModelBufferer.bufferMultiBlock(ModelUtil.VANILLA_RENDERER, positions.iterator(), level, poseStack, renderFluids, (renderType, shaded, data) -> {
Material material = materialFunc.apply(renderType, shaded);
if (material != null) {
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=MultiBlockModelBuilder," + "renderType=" + renderType + ",shaded=" + shaded);

View File

@ -36,4 +36,4 @@ iris_version = 1.8.0-beta.1+1.21
# Publication info
group = dev.engine_room.flywheel
artifact_minecraft_version = 1.21
artifact_minecraft_version = 1.21.1