Merge remote-tracking branch 'origin/1.18/dev' into 1.18/fabric/dev

Conflicts:
	src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java
	src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java
	src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java
	src/main/java/com/jozufozu/flywheel/util/RenderMath.java
This commit is contained in:
PepperCode1 2022-02-21 15:28:26 -08:00
commit f5b15f3dff
22 changed files with 456 additions and 130 deletions

View file

@ -0,0 +1,5 @@
package com.jozufozu.flywheel.api.vertex;
public interface ShadedVertexList extends VertexList {
boolean isShaded(int index);
}

View file

@ -44,7 +44,7 @@ public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialG
.onAMDWindows()) {
this.allocator = FallbackAllocator.INSTANCE;
} else {
this.allocator = new ModelPool(Formats.POS_TEX_NORMAL, 2048);
this.allocator = new ModelPool(Formats.POS_TEX_NORMAL);
}
}

View file

@ -12,6 +12,8 @@ import com.mojang.blaze3d.vertex.VertexFormat;
*/
public interface BufferBuilderExtension {
int flywheel$getVertices();
/**
* Frees the internal ByteBuffer, if it exists.
*/
@ -24,4 +26,12 @@ public interface BufferBuilderExtension {
* @param vertexCount The number of vertices in the buffer.
*/
void flywheel$injectForRender(ByteBuffer buffer, VertexFormat format, int vertexCount);
/**
* Appends the remaining bytes from the given buffer to this BufferBuilder.
* @param buffer The buffer from which to copy bytes.
* @throws IllegalStateException If this BufferBuilder is not started or is the process of writing a vertex
* @throws IllegalArgumentException If the given buffer does not contain a whole number of vertices
*/
void flywheel$appendBufferUnsafe(ByteBuffer buffer);
}

View file

@ -35,16 +35,14 @@ public class ModelPool implements ModelAllocator {
* Create a new model pool.
*
* @param vertexType The vertex type of the models that will be stored in the pool.
* @param initialSize The initial size of the pool, in vertices.
*/
public ModelPool(VertexType vertexType, int initialSize) {
public ModelPool(VertexType vertexType) {
this.vertexType = vertexType;
int stride = vertexType.getStride();
vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER);
vbo.bind();
vbo.ensureCapacity((long) stride * initialSize);
vbo.setGrowthMargin(stride * 64);
}

View file

@ -1,13 +1,18 @@
package com.jozufozu.flywheel.core;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.gl.GLSLVersion;
import com.jozufozu.flywheel.core.compile.FragmentTemplateData;
import com.jozufozu.flywheel.core.compile.InstancingTemplateData;
import com.jozufozu.flywheel.core.compile.OneShotTemplateData;
import com.jozufozu.flywheel.core.compile.Template;
import com.jozufozu.flywheel.core.source.FileResolution;
import com.jozufozu.flywheel.core.source.Resolver;
public class Templates {
public static final FileResolution DIFFUSE_FILE = Resolver.INSTANCE.get(Flywheel.rl("core/diffuse.glsl"));
public static final Template<InstancingTemplateData> INSTANCING = new Template<>(GLSLVersion.V330, InstancingTemplateData::new);
public static final Template<OneShotTemplateData> ONE_SHOT = new Template<>(GLSLVersion.V150, OneShotTemplateData::new);
public static final Template<FragmentTemplateData> FRAGMENT = new Template<>(GLSLVersion.V150, FragmentTemplateData::new);

View file

@ -5,6 +5,7 @@ import java.util.Objects;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
import com.jozufozu.flywheel.core.Templates;
import com.jozufozu.flywheel.core.shader.StateSnapshot;
import com.jozufozu.flywheel.core.source.FileIndexImpl;
import com.jozufozu.flywheel.core.source.FileResolution;
@ -40,6 +41,7 @@ public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
FileIndexImpl index = new FileIndexImpl();
Templates.DIFFUSE_FILE.getFile().generateFinalSource(index, finalSource);
header.getFile().generateFinalSource(index, finalSource);
key.file.generateFinalSource(index, finalSource);

View file

@ -16,7 +16,7 @@ import com.jozufozu.flywheel.core.QuadConverter;
* </p>
*
* <pre>{@code
* IModel model = ...;
* Model model = ...;
* VecBuffer into = ...;
*
* int initial = VecBuffer.unwrap().position();

View file

@ -1,5 +1,8 @@
package com.jozufozu.flywheel.core.model;
import java.util.function.IntPredicate;
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.util.DiffuseLightCalculator;
import com.jozufozu.flywheel.util.transform.Transform;
@ -19,12 +22,18 @@ public class ModelTransformer {
private final Model model;
private final VertexList reader;
private final IntPredicate shadedPredicate;
public final Context context = new Context();
public ModelTransformer(Model model) {
this.model = model;
reader = model.getReader();
if (reader instanceof ShadedVertexList shaded) {
shadedPredicate = shaded::isShaded;
} else {
shadedPredicate = index -> true;
}
}
public void renderInto(Params params, PoseStack input, VertexConsumer builder) {
@ -82,7 +91,7 @@ public class ModelTransformer {
a = reader.getA(i);
}
if (context.outputColorDiffuse) {
float instanceDiffuse = diffuseCalculator.getDiffuse(nx, ny, nz);
float instanceDiffuse = diffuseCalculator.getDiffuse(nx, ny, nz, shadedPredicate.test(i));
int colorR = transformColor(r, instanceDiffuse);
int colorG = transformColor(g, instanceDiffuse);
int colorB = transformColor(b, instanceDiffuse);

View file

@ -30,25 +30,53 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
public class ModelUtil {
public static BufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack ms) {
private static final ThreadLocal<ThreadLocalObjects> THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
public static ShadeSeparatedBufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack poseStack) {
return getBufferBuilder(VirtualEmptyBlockGetter.INSTANCE, model, referenceState, poseStack);
}
public static ShadeSeparatedBufferBuilder getBufferBuilder(BlockAndTintGetter renderWorld, BakedModel model, BlockState referenceState, PoseStack poseStack) {
ModelBlockRenderer blockRenderer = Minecraft.getInstance().getBlockRenderer().getModelRenderer();
BufferBuilder builder = new BufferBuilder(512);
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper;
ShadeSeparatedBufferBuilder builder = new ShadeSeparatedBufferBuilder(512);
BufferBuilder unshadedBuilder = objects.unshadedBuilder;
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadeSeparatingWrapper.prepare(builder, unshadedBuilder);
model = DefaultLayerFilteringBakedModel.wrap(model);
blockRenderer.tesselateBlock(VirtualEmptyBlockGetter.INSTANCE, model, referenceState, BlockPos.ZERO, ms, builder,
false, new Random(), 42, OverlayTexture.NO_OVERLAY);
model = shadeSeparatingWrapper.wrapModel(model);
blockRenderer.tesselateBlock(renderWorld, model, referenceState, BlockPos.ZERO, poseStack, shadeSeparatingWrapper,
false, objects.random, 42, OverlayTexture.NO_OVERLAY);
shadeSeparatingWrapper.clear();
unshadedBuilder.end();
builder.appendUnshadedVertices(unshadedBuilder);
builder.end();
return builder;
}
public static BufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks) {
BlockRenderDispatcher dispatcher = Minecraft.getInstance().getBlockRenderer();
ModelBlockRenderer modelRenderer = dispatcher.getModelRenderer();
public static ShadeSeparatedBufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks) {
return getBufferBuilderFromTemplate(renderWorld, layer, blocks, new PoseStack());
}
public static ShadeSeparatedBufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks, PoseStack poseStack) {
BlockRenderDispatcher dispatcher = Minecraft.getInstance().getBlockRenderer();
ModelBlockRenderer modelRenderer = dispatcher.getModelRenderer();
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
Random random = objects.random;
ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper;
ShadeSeparatedBufferBuilder builder = new ShadeSeparatedBufferBuilder(512);
BufferBuilder unshadedBuilder = objects.unshadedBuilder;
PoseStack ms = new PoseStack();
Random random = new Random();
BufferBuilder builder = new BufferBuilder(512);
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadeSeparatingWrapper.prepare(builder, unshadedBuilder);
ModelBlockRenderer.enableCaching();
for (StructureTemplate.StructureBlockInfo info : blocks) {
@ -65,19 +93,24 @@ public class ModelUtil {
} else {
model = CullingBakedModel.wrap(model);
model = LayerFilteringBakedModel.wrap(model, layer);
model = shadeSeparatingWrapper.wrapModel(model);
}
BlockPos pos = info.pos;
ms.pushPose();
ms.translate(pos.getX(), pos.getY(), pos.getZ());
modelRenderer.tesselateBlock(renderWorld, model, state, pos, ms, builder,
poseStack.pushPose();
poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
modelRenderer.tesselateBlock(renderWorld, model, state, pos, poseStack, shadeSeparatingWrapper,
true, random, 42, OverlayTexture.NO_OVERLAY);
ms.popPose();
poseStack.popPose();
}
ModelBlockRenderer.clearCache();
shadeSeparatingWrapper.clear();
unshadedBuilder.end();
builder.appendUnshadedVertices(unshadedBuilder);
builder.end();
return builder;
}
@ -91,4 +124,10 @@ public class ModelUtil {
return stack;
};
}
private static class ThreadLocalObjects {
public final Random random = new Random();
public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer();
public final BufferBuilder unshadedBuilder = new BufferBuilder(512);
}
}

View file

@ -0,0 +1,28 @@
package com.jozufozu.flywheel.core.model;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.model.BufferBuilderExtension;
import com.jozufozu.flywheel.fabric.helper.BufferBuilderHelper;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.datafixers.util.Pair;
public class ShadeSeparatedBufferBuilder extends BufferBuilder {
protected int unshadedStartVertex;
public ShadeSeparatedBufferBuilder(int capacity) {
super(capacity);
}
public void appendUnshadedVertices(BufferBuilder unshadedBuilder) {
Pair<DrawState, ByteBuffer> data = unshadedBuilder.popNextBuffer();
ByteBuffer buffer = data.getSecond();
BufferBuilderHelper.fixByteOrder(unshadedBuilder, buffer);
unshadedStartVertex = ((BufferBuilderExtension) this).flywheel$getVertices();
((BufferBuilderExtension) this).flywheel$appendBufferUnsafe(buffer);
}
public int getUnshadedStartVertex() {
return unshadedStartVertex;
}
}

View file

@ -0,0 +1,122 @@
package com.jozufozu.flywheel.core.model;
import java.util.Random;
import java.util.function.Supplier;
import com.jozufozu.flywheel.fabric.model.FabricModelUtil;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext.QuadTransform;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
public class ShadeSeparatingVertexConsumer implements VertexConsumer {
private final ShadeSeparatingBakedModel modelWrapper = new ShadeSeparatingBakedModel();
protected VertexConsumer shadedConsumer;
protected VertexConsumer unshadedConsumer;
protected VertexConsumer activeConsumer;
public void prepare(VertexConsumer shadedConsumer, VertexConsumer unshadedConsumer) {
this.shadedConsumer = shadedConsumer;
this.unshadedConsumer = unshadedConsumer;
}
public void clear() {
shadedConsumer = null;
unshadedConsumer = null;
activeConsumer = null;
}
public BakedModel wrapModel(BakedModel model) {
modelWrapper.setWrapped(model);
return modelWrapper;
}
protected void setActiveConsumer(boolean shaded) {
activeConsumer = shaded ? shadedConsumer : unshadedConsumer;
}
@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 VertexConsumer vertex(double x, double y, double z) {
activeConsumer.vertex(x, y, z);
return this;
}
@Override
public VertexConsumer color(int red, int green, int blue, int alpha) {
activeConsumer.color(red, green, blue, alpha);
return this;
}
@Override
public VertexConsumer uv(float u, float v) {
activeConsumer.uv(u, v);
return this;
}
@Override
public VertexConsumer overlayCoords(int u, int v) {
activeConsumer.overlayCoords(u, v);
return this;
}
@Override
public VertexConsumer uv2(int u, int v) {
activeConsumer.uv2(u, v);
return this;
}
@Override
public VertexConsumer normal(float x, float y, float z) {
activeConsumer.normal(x, y, z);
return this;
}
@Override
public void endVertex() {
activeConsumer.endVertex();
}
@Override
public void defaultColor(int red, int green, int blue, int alpha) {
activeConsumer.defaultColor(red, green, blue, alpha);
}
@Override
public void unsetDefaultColor() {
activeConsumer.unsetDefaultColor();
}
private class ShadeSeparatingBakedModel extends ForwardingBakedModel {
private final QuadTransform quadTransform = quad -> {
ShadeSeparatingVertexConsumer.this.setActiveConsumer(FabricModelUtil.isShaded(quad));
return true;
};
private void setWrapped(BakedModel model) {
wrapped = model;
}
@Override
public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
context.pushTransform(quadTransform);
super.emitBlockQuads(blockView, state, pos, randomSupplier, context);
context.popTransform();
}
}
}

View file

@ -6,6 +6,7 @@ import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.core.layout.BufferLayout;
import com.jozufozu.flywheel.core.layout.CommonItems;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
import com.jozufozu.flywheel.fabric.helper.BufferBuilderHelper;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
@ -58,6 +59,10 @@ Vertex FLWCreateVertex() {
""";
}
public BlockVertexListUnsafe.Shaded createReader(ByteBuffer buffer, int vertexCount, int unshadedStartVertex) {
return new BlockVertexListUnsafe.Shaded(buffer, vertexCount, unshadedStartVertex);
}
public VertexList createReader(BufferBuilder bufferBuilder) {
// TODO: try to avoid virtual model rendering
Pair<BufferBuilder.DrawState, ByteBuffer> pair = bufferBuilder.popNextBuffer();
@ -69,6 +74,10 @@ Vertex FLWCreateVertex() {
ByteBuffer buffer = pair.getSecond();
BufferBuilderHelper.fixByteOrder(bufferBuilder, buffer);
return new BlockVertexListUnsafe(buffer, drawState.vertexCount());
if (bufferBuilder instanceof ShadeSeparatedBufferBuilder separated) {
return createReader(buffer, drawState.vertexCount(), separated.getUnshadedStartVertex());
} else {
return createReader(buffer, drawState.vertexCount());
}
}
}

View file

@ -2,7 +2,9 @@ package com.jozufozu.flywheel.core.vertex;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
import com.jozufozu.flywheel.fabric.helper.BufferBuilderHelper;
import com.jozufozu.flywheel.util.RenderMath;
import com.mojang.blaze3d.vertex.BufferBuilder;
@ -106,4 +108,20 @@ public class BlockVertexList implements VertexList {
return vertexCount;
}
public static class Shaded extends BlockVertexList implements ShadedVertexList {
private final int unshadedStartVertex;
public Shaded(ShadeSeparatedBufferBuilder builder) {
super(builder);
unshadedStartVertex = builder.getUnshadedStartVertex();
}
@Override
public boolean isShaded(int index) {
return index < unshadedStartVertex;
}
}
}

View file

@ -4,6 +4,7 @@ import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.util.RenderMath;
@ -97,4 +98,21 @@ public class BlockVertexListUnsafe implements VertexList {
public int getVertexCount() {
return vertexCount;
}
public static class Shaded extends BlockVertexListUnsafe implements ShadedVertexList {
private final int unshadedStartVertex;
public Shaded(ByteBuffer buffer, int vertexCount, int unshadedStartVertex) {
super(buffer, vertexCount);
this.unshadedStartVertex = unshadedStartVertex;
}
@Override
public boolean isShaded(int index) {
return index < unshadedStartVertex;
}
}
}

View file

@ -22,115 +22,119 @@ 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 interface VirtualEmptyBlockGetter extends BlockAndTintGetter {
public static final VirtualEmptyBlockGetter INSTANCE = new StaticLightImpl(0, 15);
public static final VirtualEmptyBlockGetter FULL_BRIGHT = new StaticLightImpl(15, 15);
public static final VirtualEmptyBlockGetter FULL_DARK = new StaticLightImpl(0, 0);
public static boolean is(BlockAndTintGetter blockGetter) {
return blockGetter == INSTANCE;
return blockGetter instanceof VirtualEmptyBlockGetter;
}
@Override
public BlockEntity getBlockEntity(BlockPos pos) {
default BlockEntity getBlockEntity(BlockPos pos) {
return null;
}
@Override
public BlockState getBlockState(BlockPos pos) {
default BlockState getBlockState(BlockPos pos) {
return Blocks.AIR.defaultBlockState();
}
@Override
public FluidState getFluidState(BlockPos pos) {
default FluidState getFluidState(BlockPos pos) {
return Fluids.EMPTY.defaultFluidState();
}
@Override
public int getHeight() {
default int getHeight() {
return 1;
}
@Override
public int getMinBuildHeight() {
default int getMinBuildHeight() {
return 0;
}
@Override
public float getShade(Direction direction, boolean bool) {
default float getShade(Direction direction, boolean shaded) {
return 1f;
}
@Override
public LevelLightEngine getLightEngine() {
return lightEngine;
}
@Override
public int getBlockTint(BlockPos pos, ColorResolver resolver) {
default 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());
}
public static class StaticLightImpl implements VirtualEmptyBlockGetter {
private final LevelLightEngine lightEngine;
public StaticLightImpl(int blockLight, int skyLight) {
lightEngine = new LevelLightEngine(new LightChunkGetter() {
@Override
public BlockGetter getChunkForLighting(int p_63023_, int p_63024_) {
return StaticLightImpl.this;
}
@Override
public BlockGetter getLevel() {
return StaticLightImpl.this;
}
}, false, false) {
private final LayerLightEventListener blockListener = createStaticListener(blockLight);
private final LayerLightEventListener skyListener = createStaticListener(skyLight);
@Override
public LayerLightEventListener getLayerListener(LightLayer layer) {
return layer == LightLayer.BLOCK ? blockListener : skyListener;
}
};
}
private static LayerLightEventListener createStaticListener(int light) {
return 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 light;
}
};
}
@Override
public LevelLightEngine getLightEngine() {
return lightEngine;
}
}
}

View file

@ -6,9 +6,12 @@ import com.jozufozu.flywheel.Flywheel;
import io.vram.frex.api.material.MaterialConstants;
import io.vram.frex.fabric.compat.FabricMaterial;
import io.vram.frex.fabric.compat.FabricQuadView;
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView;
import net.fabricmc.fabric.impl.client.indigo.renderer.RenderMaterialImpl;
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.QuadViewImpl;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.RenderType;
@ -19,6 +22,7 @@ public class FabricModelUtil {
public static final boolean FREX_LOADED = FabricLoader.getInstance().isModLoaded("frex");
private static final BlendModeGetter BLEND_MODE_GETTER = createBlendModeGetter();
private static final ShadedPredicate SHADED_PREDICATE = createShadedPredicate();
private static BlendModeGetter createBlendModeGetter() {
if (FREX_LOADED) {
@ -50,7 +54,7 @@ public class FabricModelUtil {
return BlendMode.DEFAULT;
};
} catch (Exception e) {
Flywheel.LOGGER.error("Detected FREX but failed to load wrapper field.", e);
Flywheel.LOGGER.error("Detected FREX but failed to load material wrapper field.", e);
return material -> BlendMode.DEFAULT;
}
} else if (INDIUM_LOADED) {
@ -60,10 +64,38 @@ public class FabricModelUtil {
}
}
private static ShadedPredicate createShadedPredicate() {
if (FREX_LOADED) {
try {
Field frexQuadViewField = FabricQuadView.class.getDeclaredField("wrapped");
frexQuadViewField.setAccessible(true);
return quad -> {
try {
io.vram.frex.api.mesh.QuadView frexQuadView = (io.vram.frex.api.mesh.QuadView) frexQuadViewField.get(quad);
return !frexQuadView.material().disableDiffuse();
} catch (Exception e) {
}
return true;
};
} catch (Exception e) {
Flywheel.LOGGER.error("Detected FREX but failed to load quad view wrapper field.", e);
return quad -> true;
}
} else if (INDIUM_LOADED) {
return quad -> ((link.infra.indium.renderer.mesh.QuadViewImpl) quad).hasShade();
} else {
return quad -> ((QuadViewImpl) quad).hasShade();
}
}
public static BlendMode getBlendMode(RenderMaterial material) {
return BLEND_MODE_GETTER.getBlendMode(material);
}
public static boolean isShaded(QuadView quad) {
return SHADED_PREDICATE.isShaded(quad);
}
public static boolean doesLayerMatch(BlockState modelState, RenderType layer) {
return ItemBlockRenderTypes.getChunkRenderType(modelState) == layer;
}
@ -71,4 +103,8 @@ public class FabricModelUtil {
private interface BlendModeGetter {
BlendMode getBlendMode(RenderMaterial material);
}
private interface ShadedPredicate {
boolean isShaded(QuadView quad);
}
}

View file

@ -20,16 +20,10 @@ public abstract class BufferBuilderMixin implements BufferBuilderExtension {
private ByteBuffer buffer;
@Shadow
private boolean building;
private int nextElementByte;
@Shadow
public abstract void begin(VertexFormat.Mode p_166780_, VertexFormat p_166781_);
@Shadow
private VertexFormat.Mode mode;
@Shadow
private VertexFormat format;
private int vertices;
@Shadow
@Nullable
@ -39,7 +33,22 @@ public abstract class BufferBuilderMixin implements BufferBuilderExtension {
private int elementIndex;
@Shadow
private int vertices;
private VertexFormat format;
@Shadow
private VertexFormat.Mode mode;
@Shadow
private boolean building;
@Shadow
private void ensureCapacity(int increaseAmount) {
}
@Override
public int flywheel$getVertices() {
return vertices;
}
@Override
public void flywheel$freeBuffer() {
@ -61,4 +70,29 @@ public abstract class BufferBuilderMixin implements BufferBuilderExtension {
this.currentElement = this.format.getElements().get(0);
this.elementIndex = 0;
}
@Override
public void flywheel$appendBufferUnsafe(ByteBuffer buffer) {
if (!building) {
throw new IllegalStateException("BufferBuilder not started");
}
if (elementIndex != 0) {
throw new IllegalStateException("Cannot append buffer while building vertex");
}
int numBytes = buffer.remaining();
if (numBytes % format.getVertexSize() != 0) {
throw new IllegalArgumentException("Cannot append buffer with non-whole number of vertices");
}
int numVertices = numBytes / format.getVertexSize();
ensureCapacity(numBytes + format.getVertexSize());
int originalPosition = this.buffer.position();
this.buffer.position(nextElementByte);
MemoryUtil.memCopy(buffer, this.buffer);
this.buffer.position(originalPosition);
nextElementByte += numBytes;
vertices += numVertices;
}
}

View file

@ -15,5 +15,5 @@ public interface DiffuseLightCalculator {
return level.effects().constantAmbientLight() ? NETHER : DEFAULT;
}
float getDiffuse(float normalX, float normalY, float normalZ);
float getDiffuse(float normalX, float normalY, float normalZ, boolean shaded);
}

View file

@ -68,11 +68,17 @@ public class RenderMath {
return (float) (((((target - current) % 360) + 540) % 360) - 180);
}
public static float diffuseLight(float x, float y, float z) {
public static float diffuseLight(float x, float y, float z, boolean shaded) {
if (!shaded) {
return 1f;
}
return Math.min(x * x * 0.6f + y * y * ((3f + y) / 4f) + z * z * 0.8f, 1f);
}
public static float diffuseLightNether(float x, float y, float z) {
public static float diffuseLightNether(float x, float y, float z, boolean shaded) {
if (!shaded) {
return 0.9f;
}
return Math.min(x * x * 0.6f + y * y * 0.9f + z * z * 0.8f, 1f);
}
}

View file

@ -1,15 +0,0 @@
package com.jozufozu.flywheel.util;
import net.minecraft.client.renderer.RenderType;
/**
* This is a silly hack that's needed because flywheel does things too different from vanilla.
*
* <p>
* When a {@link RenderType} is setup, the associated textures are "bound" within RenderSystem, but not actually
* bound via opengl. This class provides a helper function to forward the bindings to opengl.
* </p>
*/
public class TextureBinder {
}

View file

@ -1,5 +1,4 @@
#use "flywheel:context/fog.glsl"
#use "flywheel:core/diffuse.glsl"
uniform float uTime;
uniform mat4 uViewProjection;

View file

@ -1,5 +1,4 @@
#use "flywheel:context/fog.glsl"
#use "flywheel:core/diffuse.glsl"
uniform float uTime;
uniform mat4 uViewProjection;