Fully fix unshaded geometry in SBBs

This commit is contained in:
PepperCode1 2024-05-21 17:22:47 -07:00
parent 0d324ffdf9
commit 669c748bd1
11 changed files with 203 additions and 197 deletions

View file

@ -177,6 +177,8 @@ dependencies {
// implementation fg.deobf("com.railwayteam.railways:railways-1.18.2-1.1.1:all") { transitive = false }
// runtimeOnly fg.deobf("maven.modrinth:aether:1.19.2-1.0.0-beta.1.1-forge")
// runtimeOnly fg.deobf("maven.modrinth:spark:1.10.38-forge")
// runtimeOnly fg.deobf("curse.maven:xycraft-653786:4788862")
// runtimeOnly fg.deobf("curse.maven:xycraft-world-653789:4788863")
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings

View file

@ -4,18 +4,14 @@ import org.apache.commons.lang3.tuple.Pair;
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.jozufozu.flywheel.lib.model.ModelUtil;
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 com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.Contraption.RenderedBlocks;
import com.simibubi.create.content.contraptions.ContraptionWorld;
import com.simibubi.create.foundation.render.ShadeSeparatingVertexConsumer;
import com.simibubi.create.foundation.render.ShadedBlockSbbBuilder;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.render.VirtualRenderHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.RenderType;
@ -115,13 +111,8 @@ public class ContraptionRenderInfo {
RandomSource random = objects.random;
RenderedBlocks blocks = contraption.getRenderedBlocks();
ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper;
BufferBuilder shadedBuilder = objects.shadedBuilder;
BufferBuilder unshadedBuilder = objects.unshadedBuilder;
shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadeSeparatingWrapper.prepare(shadedBuilder, unshadedBuilder);
ShadedBlockSbbBuilder sbbBuilder = objects.sbbBuilder;
sbbBuilder.begin();
ModelBlockRenderer.enableCaching();
for (BlockPos pos : blocks.positions()) {
@ -135,22 +126,19 @@ public class ContraptionRenderInfo {
if (model.getRenderTypes(state, random, modelData).contains(layer)) {
poseStack.pushPose();
poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
renderer.tesselateBlock(renderWorld, model, state, pos, poseStack, shadeSeparatingWrapper, true, random, randomSeed, OverlayTexture.NO_OVERLAY, modelData, layer);
renderer.tesselateBlock(renderWorld, model, state, pos, poseStack, sbbBuilder, true, random, randomSeed, OverlayTexture.NO_OVERLAY, modelData, layer);
poseStack.popPose();
}
}
}
ModelBlockRenderer.clearCache();
shadeSeparatingWrapper.clear();
return VirtualRenderHelper.endAndCombine(shadedBuilder, unshadedBuilder);
return sbbBuilder.end();
}
private static class ThreadLocalObjects {
public final PoseStack poseStack = new PoseStack();
public final RandomSource random = RandomSource.createNewThreadLocalInstance();
public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer();
public final BufferBuilder shadedBuilder = new BufferBuilder(512);
public final BufferBuilder unshadedBuilder = new BufferBuilder(512);
public final ShadedBlockSbbBuilder sbbBuilder = new ShadedBlockSbbBuilder();
}
}

View file

@ -4,16 +4,12 @@ import java.util.LinkedHashMap;
import java.util.Map;
import com.jozufozu.flywheel.lib.model.ModelUtil;
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 com.simibubi.create.content.schematics.SchematicWorld;
import com.simibubi.create.foundation.render.ShadedBlockSbbBuilder;
import com.simibubi.create.foundation.render.BlockEntityRenderHelper;
import com.simibubi.create.foundation.render.ShadeSeparatingVertexConsumer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.SuperRenderTypeBuffer;
import com.simibubi.create.foundation.render.VirtualRenderHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
@ -99,13 +95,8 @@ public class SchematicRenderer {
SchematicWorld renderWorld = schematic;
BoundingBox bounds = renderWorld.getBounds();
ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper;
BufferBuilder shadedBuilder = objects.shadedBuilder;
BufferBuilder unshadedBuilder = objects.unshadedBuilder;
shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadeSeparatingWrapper.prepare(shadedBuilder, unshadedBuilder);
ShadedBlockSbbBuilder sbbBuilder = objects.sbbBuilder;
sbbBuilder.begin();
renderWorld.renderMode = true;
ModelBlockRenderer.enableCaching();
@ -124,7 +115,7 @@ public class SchematicRenderer {
poseStack.pushPose();
poseStack.translate(localPos.getX(), localPos.getY(), localPos.getZ());
renderer.tesselateBlock(renderWorld, model, state, pos, poseStack, shadeSeparatingWrapper, true,
renderer.tesselateBlock(renderWorld, model, state, pos, poseStack, sbbBuilder, true,
random, seed, OverlayTexture.NO_OVERLAY, modelData, layer);
poseStack.popPose();
@ -134,8 +125,7 @@ public class SchematicRenderer {
ModelBlockRenderer.clearCache();
renderWorld.renderMode = false;
shadeSeparatingWrapper.clear();
return VirtualRenderHelper.endAndCombine(shadedBuilder, unshadedBuilder);
return sbbBuilder.end();
}
private static int getLayerCount() {
@ -147,9 +137,7 @@ public class SchematicRenderer {
public final PoseStack poseStack = new PoseStack();
public final RandomSource random = RandomSource.createNewThreadLocalInstance();
public final BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer();
public final BufferBuilder shadedBuilder = new BufferBuilder(512);
public final BufferBuilder unshadedBuilder = new BufferBuilder(512);
public final ShadedBlockSbbBuilder sbbBuilder = new ShadedBlockSbbBuilder();
}
}

View file

@ -0,0 +1,12 @@
package com.simibubi.create.foundation.mixin.accessor;
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("vertices")
int create$getVertices();
}

View file

@ -8,23 +8,19 @@ import java.util.function.Consumer;
import com.jozufozu.flywheel.lib.model.ModelUtil;
import com.jozufozu.flywheel.lib.transform.TransformStack;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.SheetedDecalTextureGenerator;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.outliner.AABBOutline;
import com.simibubi.create.foundation.ponder.PonderScene;
import com.simibubi.create.foundation.ponder.PonderWorld;
import com.simibubi.create.foundation.ponder.Selection;
import com.simibubi.create.foundation.render.ShadedBlockSbbBuilder;
import com.simibubi.create.foundation.render.BlockEntityRenderHelper;
import com.simibubi.create.foundation.render.ShadeSeparatingVertexConsumer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.render.SuperRenderTypeBuffer;
import com.simibubi.create.foundation.render.VirtualRenderHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.utility.VecHelper;
@ -415,13 +411,8 @@ public class WorldSectionElement extends AnimatedSceneElement {
PoseStack poseStack = objects.poseStack;
RandomSource random = objects.random;
ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper;
BufferBuilder shadedBuilder = objects.shadedBuilder;
BufferBuilder unshadedBuilder = objects.unshadedBuilder;
shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadeSeparatingWrapper.prepare(shadedBuilder, unshadedBuilder);
ShadedBlockSbbBuilder sbbBuilder = objects.sbbBuilder;
sbbBuilder.begin();
world.setMask(this.section);
ModelBlockRenderer.enableCaching();
@ -429,8 +420,11 @@ public class WorldSectionElement extends AnimatedSceneElement {
BlockState state = world.getBlockState(pos);
FluidState fluidState = world.getFluidState(pos);
poseStack.pushPose();
poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
if (!fluidState.isEmpty() && ItemBlockRenderTypes.getRenderLayer(fluidState) == layer) {
// FIXME: The fluid renderer modulos translation to 0-15 on all axes,
// so fluids at positions outside this range will render at the wrong spot.
dispatcher.renderLiquid(pos, world, sbbBuilder.unwrap(true), state, fluidState);
}
if (state.getRenderShape() == RenderShape.MODEL) {
BakedModel model = dispatcher.getBlockModel(state);
@ -439,30 +433,26 @@ public class WorldSectionElement extends AnimatedSceneElement {
modelData = model.getModelData(world, pos, state, modelData);
long seed = state.getSeed(pos);
random.setSeed(seed);
if (model.getRenderTypes(state, random, modelData).contains(layer)) {
renderer.tesselateBlock(world, model, state, pos, poseStack, shadeSeparatingWrapper, true,
poseStack.pushPose();
poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
renderer.tesselateBlock(world, model, state, pos, poseStack, sbbBuilder, true,
random, seed, OverlayTexture.NO_OVERLAY, modelData, layer);
poseStack.popPose();
}
}
if (!fluidState.isEmpty() && ItemBlockRenderTypes.getRenderLayer(fluidState) == layer)
dispatcher.renderLiquid(pos, world, shadedBuilder, state, fluidState);
poseStack.popPose();
});
ModelBlockRenderer.clearCache();
world.clearMask();
shadeSeparatingWrapper.clear();
return VirtualRenderHelper.endAndCombine(shadedBuilder, unshadedBuilder);
return sbbBuilder.end();
}
private static class ThreadLocalObjects {
public final PoseStack poseStack = new PoseStack();
public final RandomSource random = RandomSource.createNewThreadLocalInstance();
public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer();
public final BufferBuilder shadedBuilder = new BufferBuilder(512);
public final BufferBuilder unshadedBuilder = new BufferBuilder(512);
public final ShadedBlockSbbBuilder sbbBuilder = new ShadedBlockSbbBuilder();
}
}

View file

@ -1,84 +0,0 @@
package com.simibubi.create.foundation.render;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.block.model.BakedQuad;
public class ShadeSeparatingVertexConsumer implements VertexConsumer {
protected VertexConsumer shadedConsumer;
protected VertexConsumer unshadedConsumer;
public void prepare(VertexConsumer shadedConsumer, VertexConsumer unshadedConsumer) {
this.shadedConsumer = shadedConsumer;
this.unshadedConsumer = unshadedConsumer;
}
public void clear() {
shadedConsumer = null;
unshadedConsumer = null;
}
@Override
public void putBulkData(PoseStack.Pose poseEntry, BakedQuad quad, float[] colorMuls, float red, float green, float blue, int[] combinedLights, int combinedOverlay, boolean mulColor) {
if (quad.isShade()) {
shadedConsumer.putBulkData(poseEntry, quad, colorMuls, red, green, blue, combinedLights, combinedOverlay, mulColor);
} else {
unshadedConsumer.putBulkData(poseEntry, quad, colorMuls, red, green, blue, combinedLights, combinedOverlay, mulColor);
}
}
@Override
public void putBulkData(PoseStack.Pose matrixEntry, BakedQuad bakedQuad, float[] baseBrightness, float red, float green, float blue, float alpha, int[] lightmapCoords, int overlayCoords, boolean readExistingColor) {
if (bakedQuad.isShade()) {
shadedConsumer.putBulkData(matrixEntry, bakedQuad, baseBrightness, red, green, blue, alpha, lightmapCoords, overlayCoords, readExistingColor);
} else {
unshadedConsumer.putBulkData(matrixEntry, bakedQuad, baseBrightness, red, green, blue, alpha, lightmapCoords, overlayCoords, readExistingColor);
}
}
@Override
public VertexConsumer vertex(double x, double y, double z) {
throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!");
}
@Override
public VertexConsumer color(int red, int green, int blue, int alpha) {
throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!");
}
@Override
public VertexConsumer uv(float u, float v) {
throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!");
}
@Override
public VertexConsumer overlayCoords(int u, int v) {
throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!");
}
@Override
public VertexConsumer uv2(int u, int v) {
throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!");
}
@Override
public VertexConsumer normal(float x, float y, float z) {
throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!");
}
@Override
public void endVertex() {
throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!");
}
@Override
public void defaultColor(int red, int green, int blue, int alpha) {
throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!");
}
@Override
public void unsetDefaultColor() {
throw new UnsupportedOperationException("ShadeSeparatingVertexConsumer only supports putBulkData!");
}
}

View file

@ -0,0 +1,126 @@
package com.simibubi.create.foundation.render;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.simibubi.create.foundation.mixin.accessor.BufferBuilderAccessor;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import net.minecraft.client.renderer.block.model.BakedQuad;
public class ShadedBlockSbbBuilder implements VertexConsumer {
protected final BufferBuilder bufferBuilder;
protected final IntList shadeSwapVertices = new IntArrayList();
protected boolean currentShade;
public ShadedBlockSbbBuilder(BufferBuilder bufferBuilder) {
this.bufferBuilder = bufferBuilder;
}
public ShadedBlockSbbBuilder() {
this(new BufferBuilder(512));
}
public void begin() {
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadeSwapVertices.clear();
currentShade = true;
}
public SuperByteBuffer end() {
RenderedBuffer data = bufferBuilder.end();
int vertexCount = data.drawState().vertexCount();
MutableTemplateMesh mutableMesh = new MutableTemplateMesh(vertexCount);
VirtualRenderHelper.transferBlockVertexData(data.vertexBuffer(), data.drawState().format().getVertexSize(), 0, mutableMesh, 0, vertexCount);
return new SuperByteBuffer(mutableMesh.toImmutable(), shadeSwapVertices.toIntArray());
}
public BufferBuilder unwrap(boolean shade) {
prepareForGeometry(shade);
return bufferBuilder;
}
private void prepareForGeometry(boolean shade) {
if (shade != currentShade) {
shadeSwapVertices.add(((BufferBuilderAccessor) bufferBuilder).create$getVertices());
currentShade = shade;
}
}
private void prepareForGeometry(BakedQuad quad) {
prepareForGeometry(quad.isShade());
}
@Override
public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float red, float green, float blue, int light, int overlay) {
prepareForGeometry(quad);
bufferBuilder.putBulkData(pose, quad, red, green, blue, light, overlay);
}
@Override
public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float red, float green, float blue, float alpha, int light, int overlay, boolean readExistingColor) {
prepareForGeometry(quad);
bufferBuilder.putBulkData(pose, quad, red, green, blue, alpha, light, overlay, readExistingColor);
}
@Override
public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float[] brightnesses, float red, float green, float blue, int[] lights, int overlay, boolean readExistingColor) {
prepareForGeometry(quad);
bufferBuilder.putBulkData(pose, quad, brightnesses, red, green, blue, lights, overlay, readExistingColor);
}
@Override
public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float[] brightnesses, float red, float green, float blue, float alpha, int[] lights, int overlay, boolean readExistingColor) {
prepareForGeometry(quad);
bufferBuilder.putBulkData(pose, quad, brightnesses, red, green, blue, alpha, lights, overlay, readExistingColor);
}
@Override
public VertexConsumer vertex(double x, double y, double z) {
throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!");
}
@Override
public VertexConsumer color(int red, int green, int blue, int alpha) {
throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!");
}
@Override
public VertexConsumer uv(float u, float v) {
throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!");
}
@Override
public VertexConsumer overlayCoords(int u, int v) {
throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!");
}
@Override
public VertexConsumer uv2(int u, int v) {
throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!");
}
@Override
public VertexConsumer normal(float x, float y, float z) {
throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!");
}
@Override
public void endVertex() {
throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!");
}
@Override
public void defaultColor(int red, int green, int blue, int alpha) {
throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!");
}
@Override
public void unsetDefaultColor() {
throw new UnsupportedOperationException("ShadedBlockSbbBuilder only supports putBulkData!");
}
}

View file

@ -25,7 +25,7 @@ import net.minecraft.world.level.Level;
public class SuperByteBuffer implements TransformStack<SuperByteBuffer> {
private final TemplateMesh template;
private final int unshadedStartVertex;
private final int[] shadeSwapVertices;
// Vertex Position and Normals
private final PoseStack transforms = new PoseStack();
@ -52,13 +52,17 @@ public class SuperByteBuffer implements TransformStack<SuperByteBuffer> {
// Temporary
private static final Long2IntMap WORLD_LIGHT_CACHE = new Long2IntOpenHashMap();
public SuperByteBuffer(TemplateMesh template, int unshadedStartVertex) {
public SuperByteBuffer(TemplateMesh template, int[] shadeSwapVertices) {
this.template = template;
this.unshadedStartVertex = unshadedStartVertex;
this.shadeSwapVertices = shadeSwapVertices;
transforms.pushPose();
}
public SuperByteBuffer(TemplateMesh template) {
this(template, new int[0]);
}
public void renderInto(PoseStack input, VertexConsumer builder) {
if (isEmpty())
return;
@ -105,8 +109,18 @@ public class SuperByteBuffer implements TransformStack<SuperByteBuffer> {
}
}
boolean shaded = true;
int shadeSwapIndex = 0;
int nextShadeSwapVertex = shadeSwapIndex < shadeSwapVertices.length ? shadeSwapVertices[shadeSwapIndex] : -1;
final int vertexCount = template.vertexCount();
for (int i = 0; i < vertexCount; i++) {
if (i == nextShadeSwapVertex) {
shaded = !shaded;
shadeSwapIndex++;
nextShadeSwapVertex = shadeSwapIndex < shadeSwapVertices.length ? shadeSwapVertices[shadeSwapIndex] : -1;
}
float x = template.x(i);
float y = template.y(i);
float z = template.z(i);
@ -139,7 +153,7 @@ public class SuperByteBuffer implements TransformStack<SuperByteBuffer> {
if (!disableDiffuseMult) {
// Transformed normal is in camera space, but it is needed in world space to calculate diffuse.
normal.mul(RenderSystem.getInverseViewRotationMatrix());
float diffuse = diffuseCalculator.getDiffuse(normal.x(), normal.y(), normal.z(), i < unshadedStartVertex);
float diffuse = diffuseCalculator.getDiffuse(normal.x(), normal.y(), normal.z(), shaded);
r *= diffuse;
g *= diffuse;
b *= diffuse;

View file

@ -9,11 +9,7 @@ import com.jozufozu.flywheel.lib.model.ModelCache;
import com.jozufozu.flywheel.lib.model.ModelUtil;
import com.jozufozu.flywheel.lib.model.baked.ForgeBakedModelBuilder;
import com.jozufozu.flywheel.lib.model.baked.VirtualEmptyBlockGetter;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.renderer.block.ModelBlockRenderer;
@ -63,62 +59,34 @@ public class VirtualRenderHelper {
}
RandomSource random = objects.random;
ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper;
BufferBuilder shadedBuilder = objects.shadedBuilder;
BufferBuilder unshadedBuilder = objects.unshadedBuilder;
shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadeSeparatingWrapper.prepare(shadedBuilder, unshadedBuilder);
ShadedBlockSbbBuilder sbbBuilder = objects.sbbBuilder;
sbbBuilder.begin();
ModelData modelData = model.getModelData(VirtualEmptyBlockGetter.INSTANCE, BlockPos.ZERO, state, VIRTUAL_DATA);
poseStack.pushPose();
renderer.tesselateBlock(VirtualEmptyBlockGetter.INSTANCE, model, state, BlockPos.ZERO, poseStack, shadeSeparatingWrapper, false, random, 42L, OverlayTexture.NO_OVERLAY, modelData, null);
renderer.tesselateBlock(VirtualEmptyBlockGetter.INSTANCE, model, state, BlockPos.ZERO, poseStack, sbbBuilder, false, random, 42L, OverlayTexture.NO_OVERLAY, modelData, null);
poseStack.popPose();
shadeSeparatingWrapper.clear();
return endAndCombine(shadedBuilder, unshadedBuilder);
return sbbBuilder.end();
}
public static void transferBlockVertexData(ByteBuffer vertexBuffer, int vertexCount, int stride, MutableTemplateMesh mutableMesh, int dstIndex) {
public static void transferBlockVertexData(ByteBuffer vertexBuffer, int stride, int srcIndex, MutableTemplateMesh mutableMesh, int dstIndex, int vertexCount) {
for (int i = 0; i < vertexCount; i++) {
mutableMesh.x(i, vertexBuffer.getFloat(i * stride));
mutableMesh.y(i, vertexBuffer.getFloat(i * stride + 4));
mutableMesh.z(i, vertexBuffer.getFloat(i * stride + 8));
mutableMesh.color(i, vertexBuffer.getInt(i * stride + 12));
mutableMesh.u(i, vertexBuffer.getFloat(i * stride + 16));
mutableMesh.v(i, vertexBuffer.getFloat(i * stride + 20));
mutableMesh.overlay(i, OverlayTexture.NO_OVERLAY);
mutableMesh.light(i, vertexBuffer.getInt(i * stride + 24));
mutableMesh.normal(i, vertexBuffer.getInt(i * stride + 28));
mutableMesh.x(dstIndex + i, vertexBuffer.getFloat(srcIndex + i * stride));
mutableMesh.y(dstIndex + i, vertexBuffer.getFloat(srcIndex + i * stride + 4));
mutableMesh.z(dstIndex + i, vertexBuffer.getFloat(srcIndex + i * stride + 8));
mutableMesh.color(dstIndex + i, vertexBuffer.getInt(srcIndex + i * stride + 12));
mutableMesh.u(dstIndex + i, vertexBuffer.getFloat(srcIndex + i * stride + 16));
mutableMesh.v(dstIndex + i, vertexBuffer.getFloat(srcIndex + i * stride + 20));
mutableMesh.overlay(dstIndex + i, OverlayTexture.NO_OVERLAY);
mutableMesh.light(dstIndex + i, vertexBuffer.getInt(srcIndex + i * stride + 24));
mutableMesh.normal(dstIndex + i, vertexBuffer.getInt(srcIndex + i * stride + 28));
}
}
public static SuperByteBuffer endAndCombine(BufferBuilder shadedBuilder, BufferBuilder unshadedBuilder) {
RenderedBuffer shadedData = shadedBuilder.end();
int totalVertexCount = shadedData.drawState().vertexCount();
int unshadedStartVertex = totalVertexCount;
RenderedBuffer unshadedData = unshadedBuilder.endOrDiscardIfEmpty();
if (unshadedData != null) {
if (shadedData.drawState().format() != unshadedData.drawState().format()) {
throw new IllegalStateException("Buffer formats are not equal!");
}
totalVertexCount += unshadedData.drawState().vertexCount();
}
MutableTemplateMesh mutableMesh = new MutableTemplateMesh(totalVertexCount);
transferBlockVertexData(shadedData.vertexBuffer(), shadedData.drawState().vertexCount(), shadedData.drawState().format().getVertexSize(), mutableMesh, 0);
if (unshadedData != null) {
transferBlockVertexData(unshadedData.vertexBuffer(), unshadedData.drawState().vertexCount(), unshadedData.drawState().format().getVertexSize(), mutableMesh, unshadedStartVertex);
}
return new SuperByteBuffer(mutableMesh.toImmutable(), unshadedStartVertex);
}
private static class ThreadLocalObjects {
public final PoseStack identityPoseStack = new PoseStack();
public final RandomSource random = RandomSource.createNewThreadLocalInstance();
public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer();
public final BufferBuilder shadedBuilder = new BufferBuilder(512);
public final BufferBuilder unshadedBuilder = new BufferBuilder(512);
public final ShadedBlockSbbBuilder sbbBuilder = new ShadedBlockSbbBuilder();
}
}

View file

@ -10,6 +10,7 @@ import javax.annotation.Nullable;
import com.google.common.collect.ImmutableMap;
import com.jozufozu.flywheel.api.Flywheel;
import com.jozufozu.flywheel.api.backend.Backend;
import com.jozufozu.flywheel.api.backend.BackendManager;
import com.mojang.blaze3d.platform.GlUtil;
import com.simibubi.create.Create;
@ -79,7 +80,7 @@ public class DebugInformation {
.getVersion()
.toString())
.orElse("None"))
.put("Flywheel Backend", () -> BackendManager.getBackend().toString())
.put("Flywheel Backend", () -> Backend.REGISTRY.getIdOrThrow(BackendManager.getBackend()).toString())
.put("OpenGL Renderer", GlUtil::getRenderer)
.put("OpenGL Version", GlUtil::getOpenGLVersion)
.put("Graphics Mode", () -> Minecraft.getInstance().options.graphicsMode().toString())

View file

@ -27,6 +27,7 @@
],
"client": [
"accessor.AgeableListModelAccessor",
"accessor.BufferBuilderAccessor",
"accessor.GameRendererAccessor",
"accessor.HumanoidArmorLayerAccessor",
"accessor.ParticleEngineAccessor",