mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 23:47:09 +01:00
Add partial support for non-shaded quads
- Add ShadeSeparatedBufferBuilder and other code to allow separating all non-shaded vertices to the end of the buffer - Add ShadedVertexList to allow defining if a certain vertex is shaded or not - Add new methods to ModelUtil with arguments for more flexibility - Refactor VirtualEmptyBlockGetter to allow defining arbitrary light values - Add shaded argument to DiffuseLightCalculator
This commit is contained in:
parent
52f66dec9d
commit
0c74be53f6
14 changed files with 371 additions and 108 deletions
|
@ -0,0 +1,5 @@
|
||||||
|
package com.jozufozu.flywheel.api.vertex;
|
||||||
|
|
||||||
|
public interface ShadedVertexList extends VertexList {
|
||||||
|
boolean isShaded(int index);
|
||||||
|
}
|
|
@ -12,6 +12,8 @@ import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
*/
|
*/
|
||||||
public interface BufferBuilderExtension {
|
public interface BufferBuilderExtension {
|
||||||
|
|
||||||
|
int flywheel$getVertices();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees the internal ByteBuffer, if it exists.
|
* Frees the internal ByteBuffer, if it exists.
|
||||||
*/
|
*/
|
||||||
|
@ -24,4 +26,12 @@ public interface BufferBuilderExtension {
|
||||||
* @param vertexCount The number of vertices in the buffer.
|
* @param vertexCount The number of vertices in the buffer.
|
||||||
*/
|
*/
|
||||||
void flywheel$injectForRender(ByteBuffer buffer, VertexFormat format, int vertexCount);
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import com.jozufozu.flywheel.core.QuadConverter;
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* IModel model = ...;
|
* Model model = ...;
|
||||||
* VecBuffer into = ...;
|
* VecBuffer into = ...;
|
||||||
*
|
*
|
||||||
* int initial = VecBuffer.unwrap().position();
|
* int initial = VecBuffer.unwrap().position();
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package com.jozufozu.flywheel.core.model;
|
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.api.vertex.VertexList;
|
||||||
import com.jozufozu.flywheel.util.DiffuseLightCalculator;
|
import com.jozufozu.flywheel.util.DiffuseLightCalculator;
|
||||||
import com.jozufozu.flywheel.util.transform.Transform;
|
import com.jozufozu.flywheel.util.transform.Transform;
|
||||||
|
@ -19,12 +22,18 @@ public class ModelTransformer {
|
||||||
|
|
||||||
private final Model model;
|
private final Model model;
|
||||||
private final VertexList reader;
|
private final VertexList reader;
|
||||||
|
private final IntPredicate shadedPredicate;
|
||||||
|
|
||||||
public final Context context = new Context();
|
public final Context context = new Context();
|
||||||
|
|
||||||
public ModelTransformer(Model model) {
|
public ModelTransformer(Model model) {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
reader = model.getReader();
|
reader = model.getReader();
|
||||||
|
if (reader instanceof ShadedVertexList shaded) {
|
||||||
|
shadedPredicate = shaded::isShaded;
|
||||||
|
} else {
|
||||||
|
shadedPredicate = index -> true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderInto(Params params, PoseStack input, VertexConsumer builder) {
|
public void renderInto(Params params, PoseStack input, VertexConsumer builder) {
|
||||||
|
@ -82,7 +91,7 @@ public class ModelTransformer {
|
||||||
a = reader.getA(i);
|
a = reader.getA(i);
|
||||||
}
|
}
|
||||||
if (context.outputColorDiffuse) {
|
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 colorR = transformColor(r, instanceDiffuse);
|
||||||
int colorG = transformColor(g, instanceDiffuse);
|
int colorG = transformColor(g, instanceDiffuse);
|
||||||
int colorB = transformColor(b, instanceDiffuse);
|
int colorB = transformColor(b, instanceDiffuse);
|
||||||
|
|
|
@ -38,6 +38,8 @@ public class ModelUtil {
|
||||||
*/
|
*/
|
||||||
public static final BlockRenderDispatcher VANILLA_RENDERER = createVanillaRenderer();
|
public static final BlockRenderDispatcher VANILLA_RENDERER = createVanillaRenderer();
|
||||||
|
|
||||||
|
private static final ThreadLocal<ThreadLocalObjects> THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
|
||||||
|
|
||||||
private static BlockRenderDispatcher createVanillaRenderer() {
|
private static BlockRenderDispatcher createVanillaRenderer() {
|
||||||
BlockRenderDispatcher defaultDispatcher = Minecraft.getInstance().getBlockRenderer();
|
BlockRenderDispatcher defaultDispatcher = Minecraft.getInstance().getBlockRenderer();
|
||||||
BlockRenderDispatcher dispatcher = new BlockRenderDispatcher(null, null, null);
|
BlockRenderDispatcher dispatcher = new BlockRenderDispatcher(null, null, null);
|
||||||
|
@ -54,23 +56,47 @@ public class ModelUtil {
|
||||||
return dispatcher;
|
return dispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack ms) {
|
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 = VANILLA_RENDERER.getModelRenderer();
|
ModelBlockRenderer blockRenderer = VANILLA_RENDERER.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);
|
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||||
blockRenderer.tesselateBlock(VirtualEmptyBlockGetter.INSTANCE, model, referenceState, BlockPos.ZERO, ms, builder,
|
unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||||
false, new Random(), 42, OverlayTexture.NO_OVERLAY, VirtualEmptyModelData.INSTANCE);
|
shadeSeparatingWrapper.prepare(builder, unshadedBuilder);
|
||||||
|
blockRenderer.tesselateBlock(renderWorld, model, referenceState, BlockPos.ZERO, poseStack, shadeSeparatingWrapper,
|
||||||
|
false, objects.random, 42, OverlayTexture.NO_OVERLAY, VirtualEmptyModelData.INSTANCE);
|
||||||
|
shadeSeparatingWrapper.clear();
|
||||||
|
unshadedBuilder.end();
|
||||||
|
builder.appendUnshadedVertices(unshadedBuilder);
|
||||||
builder.end();
|
builder.end();
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks) {
|
public static ShadeSeparatedBufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks) {
|
||||||
ModelBlockRenderer modelRenderer = VANILLA_RENDERER.getModelRenderer();
|
return getBufferBuilderFromTemplate(renderWorld, layer, blocks, new PoseStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ShadeSeparatedBufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks, PoseStack poseStack) {
|
||||||
|
ModelBlockRenderer modelRenderer = VANILLA_RENDERER.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);
|
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||||
|
unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||||
|
shadeSeparatingWrapper.prepare(builder, unshadedBuilder);
|
||||||
|
|
||||||
ForgeHooksClient.setRenderType(layer);
|
ForgeHooksClient.setRenderType(layer);
|
||||||
ModelBlockRenderer.enableCaching();
|
ModelBlockRenderer.enableCaching();
|
||||||
|
@ -84,16 +110,20 @@ public class ModelUtil {
|
||||||
|
|
||||||
BlockPos pos = info.pos;
|
BlockPos pos = info.pos;
|
||||||
|
|
||||||
ms.pushPose();
|
poseStack.pushPose();
|
||||||
ms.translate(pos.getX(), pos.getY(), pos.getZ());
|
poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
|
||||||
modelRenderer.tesselateBlock(renderWorld, VANILLA_RENDERER.getBlockModel(state), state, pos, ms, builder,
|
modelRenderer.tesselateBlock(renderWorld, VANILLA_RENDERER.getBlockModel(state), state, pos, poseStack, shadeSeparatingWrapper,
|
||||||
true, random, 42, OverlayTexture.NO_OVERLAY, EmptyModelData.INSTANCE);
|
true, random, 42, OverlayTexture.NO_OVERLAY, EmptyModelData.INSTANCE);
|
||||||
ms.popPose();
|
poseStack.popPose();
|
||||||
}
|
}
|
||||||
ModelBlockRenderer.clearCache();
|
ModelBlockRenderer.clearCache();
|
||||||
ForgeHooksClient.setRenderType(null);
|
ForgeHooksClient.setRenderType(null);
|
||||||
|
|
||||||
|
shadeSeparatingWrapper.clear();
|
||||||
|
unshadedBuilder.end();
|
||||||
|
builder.appendUnshadedVertices(unshadedBuilder);
|
||||||
builder.end();
|
builder.end();
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,4 +137,10 @@ public class ModelUtil {
|
||||||
return stack;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.jozufozu.flywheel.core.model;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.model.BufferBuilderExtension;
|
||||||
|
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();
|
||||||
|
unshadedStartVertex = ((BufferBuilderExtension) this).flywheel$getVertices();
|
||||||
|
((BufferBuilderExtension) this).flywheel$appendBufferUnsafe(data.getSecond());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUnshadedStartVertex() {
|
||||||
|
return unshadedStartVertex;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package com.jozufozu.flywheel.core.model;
|
||||||
|
|
||||||
|
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!");
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import com.jozufozu.flywheel.api.vertex.VertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||||
|
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
@ -57,6 +58,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) {
|
public VertexList createReader(BufferBuilder bufferBuilder) {
|
||||||
// TODO: try to avoid virtual model rendering
|
// TODO: try to avoid virtual model rendering
|
||||||
Pair<BufferBuilder.DrawState, ByteBuffer> pair = bufferBuilder.popNextBuffer();
|
Pair<BufferBuilder.DrawState, ByteBuffer> pair = bufferBuilder.popNextBuffer();
|
||||||
|
@ -66,6 +71,10 @@ Vertex FLWCreateVertex() {
|
||||||
throw new RuntimeException("Cannot use BufferBuilder with " + drawState.format());
|
throw new RuntimeException("Cannot use BufferBuilder with " + drawState.format());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BlockVertexListUnsafe(pair.getSecond(), drawState.vertexCount());
|
if (bufferBuilder instanceof ShadeSeparatedBufferBuilder separated) {
|
||||||
|
return createReader(pair.getSecond(), drawState.vertexCount(), separated.getUnshadedStartVertex());
|
||||||
|
} else {
|
||||||
|
return createReader(pair.getSecond(), drawState.vertexCount());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@ package com.jozufozu.flywheel.core.vertex;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexList;
|
import com.jozufozu.flywheel.api.vertex.VertexList;
|
||||||
|
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.util.RenderMath;
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
@ -104,4 +106,20 @@ public class BlockVertexList implements VertexList {
|
||||||
return vertexCount;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexList;
|
import com.jozufozu.flywheel.api.vertex.VertexList;
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.util.RenderMath;
|
||||||
|
|
||||||
|
@ -97,4 +98,21 @@ public class BlockVertexListUnsafe implements VertexList {
|
||||||
public int getVertexCount() {
|
public int getVertexCount() {
|
||||||
return vertexCount;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,115 +22,119 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
import net.minecraft.world.level.material.Fluids;
|
import net.minecraft.world.level.material.Fluids;
|
||||||
|
|
||||||
public enum VirtualEmptyBlockGetter implements BlockAndTintGetter {
|
public interface VirtualEmptyBlockGetter extends BlockAndTintGetter {
|
||||||
INSTANCE;
|
public static final VirtualEmptyBlockGetter INSTANCE = new StaticLightImpl(0, 15);
|
||||||
|
public static final VirtualEmptyBlockGetter FULL_BRIGHT = new StaticLightImpl(15, 15);
|
||||||
private final LevelLightEngine lightEngine = new LevelLightEngine(new LightChunkGetter() {
|
public static final VirtualEmptyBlockGetter FULL_DARK = new StaticLightImpl(0, 0);
|
||||||
@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) {
|
public static boolean is(BlockAndTintGetter blockGetter) {
|
||||||
return blockGetter == INSTANCE;
|
return blockGetter instanceof VirtualEmptyBlockGetter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity getBlockEntity(BlockPos pos) {
|
default BlockEntity getBlockEntity(BlockPos pos) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlockState(BlockPos pos) {
|
default BlockState getBlockState(BlockPos pos) {
|
||||||
return Blocks.AIR.defaultBlockState();
|
return Blocks.AIR.defaultBlockState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FluidState getFluidState(BlockPos pos) {
|
default FluidState getFluidState(BlockPos pos) {
|
||||||
return Fluids.EMPTY.defaultFluidState();
|
return Fluids.EMPTY.defaultFluidState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getHeight() {
|
default int getHeight() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinBuildHeight() {
|
default int getMinBuildHeight() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getShade(Direction direction, boolean bool) {
|
default float getShade(Direction direction, boolean shaded) {
|
||||||
return 1f;
|
return 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LevelLightEngine getLightEngine() {
|
default int getBlockTint(BlockPos pos, ColorResolver resolver) {
|
||||||
return lightEngine;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBlockTint(BlockPos pos, ColorResolver resolver) {
|
|
||||||
Biome plainsBiome = Minecraft.getInstance().getConnection().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getOrThrow(Biomes.PLAINS);
|
Biome plainsBiome = Minecraft.getInstance().getConnection().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getOrThrow(Biomes.PLAINS);
|
||||||
return resolver.getColor(plainsBiome, pos.getX(), pos.getZ());
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,16 +20,10 @@ public abstract class BufferBuilderMixin implements BufferBuilderExtension {
|
||||||
private ByteBuffer buffer;
|
private ByteBuffer buffer;
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
private boolean building;
|
private int nextElementByte;
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
public abstract void begin(VertexFormat.Mode p_166780_, VertexFormat p_166781_);
|
private int vertices;
|
||||||
|
|
||||||
@Shadow
|
|
||||||
private VertexFormat.Mode mode;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
private VertexFormat format;
|
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -39,7 +33,22 @@ public abstract class BufferBuilderMixin implements BufferBuilderExtension {
|
||||||
private int elementIndex;
|
private int elementIndex;
|
||||||
|
|
||||||
@Shadow
|
@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
|
@Override
|
||||||
public void flywheel$freeBuffer() {
|
public void flywheel$freeBuffer() {
|
||||||
|
@ -61,4 +70,29 @@ public abstract class BufferBuilderMixin implements BufferBuilderExtension {
|
||||||
this.currentElement = this.format.getElements().get(0);
|
this.currentElement = this.format.getElements().get(0);
|
||||||
this.elementIndex = 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,9 @@ package com.jozufozu.flywheel.util;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraftforge.client.model.pipeline.LightUtil;
|
|
||||||
|
|
||||||
public interface DiffuseLightCalculator {
|
public interface DiffuseLightCalculator {
|
||||||
DiffuseLightCalculator DEFAULT = LightUtil::diffuseLight;
|
DiffuseLightCalculator DEFAULT = RenderMath::diffuseLight;
|
||||||
DiffuseLightCalculator NETHER = RenderMath::diffuseLightNether;
|
DiffuseLightCalculator NETHER = RenderMath::diffuseLightNether;
|
||||||
|
|
||||||
static DiffuseLightCalculator forCurrentLevel() {
|
static DiffuseLightCalculator forCurrentLevel() {
|
||||||
|
@ -16,5 +15,5 @@ public interface DiffuseLightCalculator {
|
||||||
return level.effects().constantAmbientLight() ? NETHER : DEFAULT;
|
return level.effects().constantAmbientLight() ? NETHER : DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getDiffuse(float normalX, float normalY, float normalZ);
|
float getDiffuse(float normalX, float normalY, float normalZ, boolean shaded);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.jozufozu.flywheel.util;
|
package com.jozufozu.flywheel.util;
|
||||||
|
|
||||||
|
import net.minecraftforge.client.model.pipeline.LightUtil;
|
||||||
|
|
||||||
public class RenderMath {
|
public class RenderMath {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,7 +70,17 @@ public class RenderMath {
|
||||||
return (float) (((((target - current) % 360) + 540) % 360) - 180);
|
return (float) (((((target - current) % 360) + 540) % 360) - 180);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float diffuseLightNether(float x, float y, float z) {
|
public static float diffuseLight(float x, float y, float z, boolean shaded) {
|
||||||
|
if (!shaded) {
|
||||||
|
return 1f;
|
||||||
|
}
|
||||||
|
return LightUtil.diffuseLight(x, y, 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);
|
return Math.min(x * x * 0.6f + y * y * 0.9f + z * z * 0.8f, 1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue