Merge branch '1.18/dev' into 1.19/dev

Conflicts:
	src/main/java/com/jozufozu/flywheel/core/model/BakedModelBuilder.java
	src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java
	src/main/java/com/jozufozu/flywheel/core/model/Bufferable.java
	src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java
	src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java
	src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java
This commit is contained in:
PepperCode1 2023-07-03 14:59:58 -07:00
commit af3d9f7425
14 changed files with 189 additions and 119 deletions

View file

@ -117,10 +117,10 @@ dependencies {
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
// switch to implementation for debugging
compileOnly fg.deobf("maven.modrinth:starlight-forge:1.1.1+1.19")
compileOnly fg.deobf('maven.modrinth:starlight-forge:1.1.1+1.19')
compileOnly fg.deobf("maven.modrinth:rubidium:0.6.2b")
compileOnly fg.deobf("maven.modrinth:oculus:1.19.2-1.6.4")
compileOnly fg.deobf('maven.modrinth:rubidium:0.6.2b')
compileOnly fg.deobf('maven.modrinth:oculus:1.19.2-1.6.4')
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings

View file

@ -25,11 +25,11 @@ public interface Material<D extends InstanceData> {
Instancer<D> model(Object key, Supplier<Model> modelSupplier);
default Instancer<D> getModel(PartialModel partial, BlockState referenceState) {
return model(partial, () -> new BlockModel(partial.get(), referenceState));
return model(partial, () -> BlockModel.of(partial.get(), referenceState));
}
default Instancer<D> getModel(PartialModel partial) {
return model(partial, () -> new BlockModel(partial.get(), Blocks.AIR.defaultBlockState()));
return model(partial, () -> BlockModel.of(partial.get(), Blocks.AIR.defaultBlockState()));
}
default Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir) {
@ -37,10 +37,10 @@ public interface Material<D extends InstanceData> {
}
default Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier<PoseStack> modelTransform) {
return model(Pair.of(dir, partial), () -> new BlockModel(partial.get(), referenceState, modelTransform.get()));
return model(Pair.of(dir, partial), () -> BlockModel.of(partial.get(), referenceState, modelTransform.get()));
}
default Instancer<D> getModel(BlockState toRender) {
return model(toRender, () -> new BlockModel(toRender));
return model(toRender, () -> BlockModel.of(toRender));
}
}

View file

@ -41,4 +41,7 @@ public interface VertexList {
default boolean isEmpty() {
return getVertexCount() == 0;
}
default void delete() {
}
}

View file

@ -3,10 +3,10 @@ package com.jozufozu.flywheel.backend.instancing;
import java.nio.ByteBuffer;
import org.jetbrains.annotations.ApiStatus;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.backend.model.BufferBuilderExtension;
import com.jozufozu.flywheel.backend.model.DirectVertexConsumer;
import com.mojang.blaze3d.platform.MemoryTracker;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.RenderType;
@ -48,10 +48,10 @@ public class DrawBuffer {
int byteSize = format.getVertexSize() * (vertexCount + 1);
if (backingBuffer == null) {
backingBuffer = MemoryTracker.create(byteSize);
backingBuffer = MemoryUtil.memAlloc(byteSize);
}
if (byteSize > backingBuffer.capacity()) {
backingBuffer = MemoryTracker.resize(backingBuffer, byteSize);
backingBuffer = MemoryUtil.memRealloc(backingBuffer, byteSize);
}
return new DirectVertexConsumer(backingBuffer, format, vertexCount);

View file

@ -10,7 +10,6 @@ import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.core.Formats;
import com.jozufozu.flywheel.core.model.Model;
import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe;
import com.mojang.blaze3d.platform.MemoryTracker;
public class ModelPart implements Model {
@ -29,7 +28,7 @@ public class ModelPart implements Model {
this.vertices = vertices;
}
ByteBuffer buffer = MemoryTracker.create(size());
ByteBuffer buffer = MemoryUtil.memAlloc(size());
PosTexNormalWriterUnsafe writer = Formats.POS_TEX_NORMAL.createWriter(buffer);
for (PartBuilder.CuboidBuilder cuboid : cuboids) {
cuboid.buffer(writer);
@ -65,12 +64,6 @@ public class ModelPart implements Model {
@Override
public void delete() {
if (reader instanceof AutoCloseable closeable) {
try {
closeable.close();
} catch (Exception e) {
//
}
}
reader.delete();
}
}

View file

@ -40,7 +40,15 @@ public final class BakedModelBuilder implements Bufferable {
}
@Override
public void bufferInto(ModelBlockRenderer blockRenderer, VertexConsumer consumer, RandomSource random) {
public void bufferInto(VertexConsumer consumer, ModelBlockRenderer blockRenderer, RandomSource random) {
blockRenderer.tesselateBlock(renderWorld, model, referenceState, BlockPos.ZERO, poseStack, consumer, false, random, 42, OverlayTexture.NO_OVERLAY, ModelUtil.VIRTUAL_DATA, null);
}
public BlockModel toModel(String name) {
return BlockModel.of(this, name);
}
public BlockModel toModel() {
return toModel(referenceState.toString());
}
}

View file

@ -14,10 +14,9 @@ import com.jozufozu.flywheel.backend.gl.buffer.GlBufferUsage;
import com.jozufozu.flywheel.backend.model.ElementBuffer;
import com.jozufozu.flywheel.core.Formats;
import com.jozufozu.flywheel.core.QuadConverter;
import com.jozufozu.flywheel.util.Pair;
import com.mojang.blaze3d.platform.MemoryTracker;
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.IndexType;
@ -34,46 +33,69 @@ public class BlockModel implements Model {
private final String name;
private final EBOSupplier eboSupplier;
public BlockModel(BlockState state) {
this(Minecraft.getInstance()
.getBlockRenderer()
.getBlockModel(state), state);
}
public BlockModel(ByteBuffer vertexBuffer, ByteBuffer indexBuffer, BufferBuilder.DrawState drawState, int unshadedStartVertex, String name) {
if (drawState.format() != DefaultVertexFormat.BLOCK) {
throw new RuntimeException("Cannot use buffered data with non-block format '" + drawState.format() + "'");
}
public BlockModel(BakedModel model, BlockState referenceState) {
this(new BakedModelBuilder(model).withReferenceState(referenceState), referenceState.toString());
}
reader = Formats.BLOCK.createReader(vertexBuffer, drawState.vertexCount(), unshadedStartVertex);
public BlockModel(BakedModel model, BlockState referenceState, PoseStack ms) {
this(new BakedModelBuilder(model).withReferenceState(referenceState)
.withPoseStack(ms), referenceState.toString());
}
public BlockModel(Bufferable bufferable, String name) {
this(bufferable.build(), name);
}
public BlockModel(Pair<RenderedBuffer, Integer> pair, String name) {
this(pair, name, true);
}
public BlockModel(Pair<RenderedBuffer, Integer> pair, String name, boolean releaseBuffer) {
this.name = name;
RenderedBuffer renderedBuffer = pair.first();
BufferBuilder.DrawState drawState = renderedBuffer.drawState();
reader = Formats.BLOCK.createReader(renderedBuffer, pair.second());
if (!drawState.sequentialIndex()) {
eboSupplier = new BufferEBOSupplier(renderedBuffer.indexBuffer(), drawState.indexCount(), drawState.indexType());
eboSupplier = new BufferEBOSupplier(indexBuffer, drawState.indexCount(), drawState.indexType());
} else {
eboSupplier = () -> QuadConverter.getInstance()
.quads2Tris(vertexCount() / 4);
}
}
if (releaseBuffer) {
renderedBuffer.release();
public BlockModel(ByteBuffer vertexBuffer, ByteBuffer indexBuffer, BufferBuilder.DrawState drawState, String name) {
if (drawState.format() != DefaultVertexFormat.BLOCK) {
throw new RuntimeException("Cannot use buffered data with non-block format '" + drawState.format() + "'");
}
reader = Formats.BLOCK.createReader(vertexBuffer, drawState.vertexCount());
this.name = name;
if (!drawState.sequentialIndex()) {
eboSupplier = new BufferEBOSupplier(indexBuffer, drawState.indexCount(), drawState.indexType());
} else {
eboSupplier = () -> QuadConverter.getInstance()
.quads2Tris(vertexCount() / 4);
}
}
public BlockModel(ShadeSeparatedBufferedData data, String name) {
this(data.vertexBuffer(), data.indexBuffer(), data.drawState(), data.unshadedStartVertex(), name);
}
public static BlockModel of(Bufferable bufferable, String name) {
ShadeSeparatedBufferedData data = bufferable.build();
BlockModel model = new BlockModel(data, name);
data.release();
return model;
}
public static BlockModel of(BakedModel model, BlockState referenceState) {
ShadeSeparatedBufferedData data = ModelUtil.getBufferedData(model, referenceState);
BlockModel blockModel = new BlockModel(data, referenceState.toString());
data.release();
return blockModel;
}
public static BlockModel of(BlockState state) {
return of(Minecraft.getInstance()
.getBlockRenderer()
.getBlockModel(state), state);
}
public static BlockModel of(BakedModel model, BlockState referenceState, PoseStack ms) {
ShadeSeparatedBufferedData data = ModelUtil.getBufferedData(model, referenceState, ms);
BlockModel blockModel = new BlockModel(data, referenceState.toString());
data.release();
return blockModel;
}
@Override
@ -103,13 +125,7 @@ public class BlockModel implements Model {
@Override
public void delete() {
if (reader instanceof AutoCloseable closeable) {
try {
closeable.close();
} catch (Exception e) {
//
}
}
reader.delete();
eboSupplier.delete();
}

View file

@ -1,20 +1,18 @@
package com.jozufozu.flywheel.core.model;
import com.jozufozu.flywheel.util.Pair;
import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.block.ModelBlockRenderer;
import net.minecraft.util.RandomSource;
/**
* An interface for objects that can "rendered" into a BufferBuilder.
* An interface for objects that can buffered into a VertexConsumer.
*/
public interface Bufferable {
void bufferInto(ModelBlockRenderer renderer, VertexConsumer consumer, RandomSource random);
void bufferInto(VertexConsumer consumer, ModelBlockRenderer renderer, RandomSource random);
default Pair<RenderedBuffer, Integer> build() {
return ModelUtil.getRenderedBuffer(this);
default ShadeSeparatedBufferedData build() {
return ModelUtil.getBufferedData(this);
}
}

View file

@ -6,7 +6,6 @@ import java.util.function.Supplier;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.model.BufferBuilderExtension;
import com.jozufozu.flywheel.util.Pair;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer;
@ -60,7 +59,7 @@ public class ModelUtil {
return data.has(ModelUtil.VIRTUAL_PROPERTY) && data.get(ModelUtil.VIRTUAL_PROPERTY);
}
public static Pair<RenderedBuffer, Integer> endShadeSeparated(BufferBuilder shadedBuilder, BufferBuilder unshadedBuilder) {
public static ShadeSeparatedBufferedData endAndCombine(BufferBuilder shadedBuilder, BufferBuilder unshadedBuilder) {
int unshadedStartVertex = ((BufferBuilderExtension) shadedBuilder).flywheel$getVertices();
RenderedBuffer unshadedBuffer = unshadedBuilder.endOrDiscardIfEmpty();
if (unshadedBuffer != null) {
@ -69,40 +68,45 @@ public class ModelUtil {
unshadedBuffer.release();
}
RenderedBuffer buffer = shadedBuilder.end();
return Pair.of(buffer, unshadedStartVertex);
return new ShadeSeparatedBufferedData.NativeImpl(buffer.vertexBuffer(), buffer.indexBuffer(), buffer.drawState(), unshadedStartVertex);
}
public static Pair<RenderedBuffer, Integer> getRenderedBuffer(Bufferable bufferable) {
public static ShadeSeparatedBufferedData getBufferedData(Bufferable bufferable) {
ModelBlockRenderer blockRenderer = VANILLA_RENDERER.getModelRenderer();
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
objects.begin();
bufferable.bufferInto(blockRenderer, objects.shadeSeparatingWrapper, objects.random);
bufferable.bufferInto(objects.shadeSeparatingWrapper, blockRenderer, objects.random);
return objects.end();
}
public static Pair<RenderedBuffer, Integer> getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack poseStack) {
public static ShadeSeparatedBufferedData getBufferedData(BakedModel model, BlockState referenceState) {
return new BakedModelBuilder(model).withReferenceState(referenceState)
.build();
}
public static ShadeSeparatedBufferedData getBufferedData(BakedModel model, BlockState referenceState, PoseStack poseStack) {
return new BakedModelBuilder(model).withReferenceState(referenceState)
.withPoseStack(poseStack)
.build();
}
public static Pair<RenderedBuffer, Integer> getBufferBuilder(BlockAndTintGetter renderWorld, BakedModel model, BlockState referenceState, PoseStack poseStack) {
public static ShadeSeparatedBufferedData getBufferedData(BlockAndTintGetter renderWorld, BakedModel model, BlockState referenceState, PoseStack poseStack) {
return new BakedModelBuilder(model).withReferenceState(referenceState)
.withPoseStack(poseStack)
.withRenderWorld(renderWorld)
.build();
}
public static Pair<RenderedBuffer, Integer> getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks) {
public static ShadeSeparatedBufferedData getBufferedDataFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks) {
return new WorldModelBuilder(layer).withRenderWorld(renderWorld)
.withBlocks(blocks)
.build();
}
public static Pair<RenderedBuffer, Integer> getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks, PoseStack poseStack) {
public static ShadeSeparatedBufferedData getBufferedDataFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks, PoseStack poseStack) {
return new WorldModelBuilder(layer).withRenderWorld(renderWorld)
.withBlocks(blocks)
.withPoseStack(poseStack)
@ -132,9 +136,9 @@ public class ModelUtil {
this.shadeSeparatingWrapper.prepare(this.shadedBuilder, this.unshadedBuilder);
}
private Pair<RenderedBuffer, Integer> end() {
private ShadeSeparatedBufferedData end() {
this.shadeSeparatingWrapper.clear();
return ModelUtil.endShadeSeparated(shadedBuilder, unshadedBuilder);
return ModelUtil.endAndCombine(shadedBuilder, unshadedBuilder);
}
}
}

View file

@ -0,0 +1,61 @@
package com.jozufozu.flywheel.core.model;
import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.util.FlwUtil;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.BufferBuilder.DrawState;
public interface ShadeSeparatedBufferedData {
ByteBuffer vertexBuffer();
ByteBuffer indexBuffer();
BufferBuilder.DrawState drawState();
int unshadedStartVertex();
void release();
static final class NativeImpl implements ShadeSeparatedBufferedData {
private final ByteBuffer vertexBuffer;
private final ByteBuffer indexBuffer;
private final BufferBuilder.DrawState drawState;
private final int unshadedStartVertex;
public NativeImpl(ByteBuffer vertexBuffer, ByteBuffer indexBuffer, BufferBuilder.DrawState drawState, int unshadedStartVertex) {
this.vertexBuffer = FlwUtil.copyBuffer(vertexBuffer);
this.indexBuffer = FlwUtil.copyBuffer(indexBuffer);
this.drawState = drawState;
this.unshadedStartVertex = unshadedStartVertex;
}
@Override
public ByteBuffer vertexBuffer() {
return vertexBuffer;
}
@Override
public ByteBuffer indexBuffer() {
return indexBuffer;
}
@Override
public DrawState drawState() {
return drawState;
}
@Override
public int unshadedStartVertex() {
return unshadedStartVertex;
}
@Override
public void release() {
MemoryUtil.memFree(vertexBuffer);
MemoryUtil.memFree(indexBuffer);
}
}
}

View file

@ -33,7 +33,7 @@ public final class WorldModelBuilder implements Bufferable {
}
@Override
public void bufferInto(ModelBlockRenderer modelRenderer, VertexConsumer consumer, RandomSource random) {
public void bufferInto(VertexConsumer consumer, ModelBlockRenderer modelRenderer, RandomSource random) {
ModelBlockRenderer.enableCaching();
for (StructureTemplate.StructureBlockInfo info : this.blocks) {
BlockState state = info.state;
@ -77,7 +77,7 @@ public final class WorldModelBuilder implements Bufferable {
return this;
}
public BlockModel intoMesh(String name) {
return new BlockModel(this, name);
public BlockModel toModel(String name) {
return BlockModel.of(this, name);
}
}

View file

@ -1,39 +1,31 @@
package com.jozufozu.flywheel.core.vertex;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.mojang.blaze3d.platform.MemoryTracker;
import com.jozufozu.flywheel.util.FlwUtil;
public abstract class AbstractVertexList implements VertexList, AutoCloseable {
public abstract class AbstractVertexList implements VertexList {
protected final ByteBuffer contents;
protected final long base;
protected final int vertexCount;
protected AbstractVertexList(ByteBuffer copyFrom, int vertexCount) {
this.contents = MemoryTracker.create(copyFrom.capacity());
this.contents = FlwUtil.copyBuffer(copyFrom);
this.vertexCount = vertexCount;
this.base = MemoryUtil.memAddress(this.contents);
init(copyFrom);
}
private void init(ByteBuffer copyFrom) {
this.contents.order(copyFrom.order());
this.contents.put(copyFrom);
((Buffer) this.contents).flip();
}
@Override
public void close() {
MemoryUtil.memFree(contents);
}
@Override
public int getVertexCount() {
return vertexCount;
}
@Override
public void delete() {
MemoryUtil.memFree(contents);
}
}

View file

@ -2,12 +2,9 @@ package com.jozufozu.flywheel.core.vertex;
import java.nio.ByteBuffer;
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.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
public class BlockVertex implements VertexType {
@ -35,6 +32,10 @@ public class BlockVertex implements VertexType {
return new BlockVertexListUnsafe(buffer, vertexCount);
}
public BlockVertexListUnsafe.Shaded createReader(ByteBuffer buffer, int vertexCount, int unshadedStartVertex) {
return new BlockVertexListUnsafe.Shaded(buffer, vertexCount, unshadedStartVertex);
}
@Override
public String getShaderHeader() {
return """
@ -55,26 +56,4 @@ Vertex FLWCreateVertex() {
}
""";
}
public BlockVertexListUnsafe.Shaded createReader(ByteBuffer buffer, int vertexCount, int unshadedStartVertex) {
return new BlockVertexListUnsafe.Shaded(buffer, vertexCount, unshadedStartVertex);
}
public VertexList createReader(BufferBuilder.RenderedBuffer renderedBuffer, int unshadedStartVertex) {
// TODO: try to avoid virtual model rendering
BufferBuilder.DrawState drawState = renderedBuffer.drawState();
if (drawState.format() != DefaultVertexFormat.BLOCK) {
throw new RuntimeException("Cannot use BufferBuilder with " + drawState.format());
}
ByteBuffer vertexBuffer = renderedBuffer.vertexBuffer();
int vertexCount = drawState.vertexCount();
if (unshadedStartVertex >= 0 && unshadedStartVertex < vertexCount) {
return createReader(vertexBuffer, vertexCount, unshadedStartVertex);
} else {
return createReader(vertexBuffer, vertexCount);
}
}
}

View file

@ -1,9 +1,12 @@
package com.jozufozu.flywheel.util;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Stream;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.mixin.BlockEntityRenderDispatcherAccessor;
import net.minecraft.client.Minecraft;
@ -73,4 +76,17 @@ public class FlwUtil {
public static <R> Stream<R> mapValues(Map<?, R> map) {
return map.values().stream();
}
/**
* The returned buffer is backed by native memory and will cause a memory leak if not freed using {@link MemoryUtil#memFree(java.nio.Buffer)}.
*/
public static ByteBuffer copyBuffer(ByteBuffer buffer) {
int pos = buffer.position();
ByteBuffer copy = MemoryUtil.memAlloc(buffer.remaining());
copy.order(buffer.order());
copy.put(buffer);
buffer.position(pos);
copy.flip();
return copy;
}
}