Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import dev.dubhe.anvilcraft.AnvilCraft;
import dev.dubhe.anvilcraft.client.renderer.Line;
import dev.dubhe.anvilcraft.client.support.PowerGridSupport;
import dev.dubhe.anvilcraft.util.ColorUtil;
import dev.dubhe.anvilcraft.util.Line;
import dev.dubhe.anvilcraft.util.ShapeUtil;
import dev.dubhe.anvilcraft.util.VirtualThreadFactoryImpl;
import lombok.Getter;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package dev.dubhe.anvilcraft.api.rendering.foundation;

import dev.dubhe.anvilcraft.api.rendering.foundation.buffer.vertex.GlVertexBuffer;
import dev.dubhe.anvilcraft.api.rendering.foundation.buffer.vertex.QuadSortingState;
import lombok.EqualsAndHashCode;
import net.minecraft.client.renderer.RenderType;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector3f;
import org.lwjgl.system.MemoryUtil;

@EqualsAndHashCode
public final class CompileResult implements Disposable {
private static final MemoryUtil.MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false);
private final RenderType renderType;
private final int vertexCount;
private final int vertexSize;
private final long vertexBufferPtr;
private final int indexCount;
@Nullable
private final QuadSortingState sortingState;
private boolean freed = false;

public CompileResult(
RenderType renderType,
int vertexCount,
int vertexSize,
long vertexBufferPtr,
int indexCount,
@Nullable QuadSortingState sortingState
) {
this.renderType = renderType;
this.vertexCount = vertexCount;
this.vertexSize = vertexSize;
this.vertexBufferPtr = vertexBufferPtr;
this.indexCount = indexCount;
this.sortingState = sortingState;
}

public void upload(GlVertexBuffer vertexBuffer) {
vertexBuffer.upload(vertexBufferPtr, vertexCount * vertexSize, indexCount, sortingState, new Vector3f(), this);
}

public void dispose() {
if (freed) return;
ALLOCATOR.free(vertexBufferPtr);
freed = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dev.dubhe.anvilcraft.api.rendering.foundation;

public interface Disposable {
/**
* It is guaranteed to run on Render Thread.
*/
void dispose();
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
package dev.dubhe.anvilcraft.api.rendering;
package dev.dubhe.anvilcraft.api.rendering.foundation;

import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.ByteBufferBuilder;
import com.mojang.blaze3d.vertex.MeshData;
import com.mojang.blaze3d.vertex.VertexBuffer;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.VertexFormat;
import dev.dubhe.anvilcraft.api.rendering.foundation.buffer.vertex.GlVertexBuffer;
import dev.dubhe.anvilcraft.api.rendering.foundation.buffer.vertex.QuadSortingState;
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2IntMaps;
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
import lombok.Getter;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import org.lwjgl.system.MemoryUtil;

import javax.annotation.ParametersAreNonnullByDefault;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.concurrent.ConcurrentHashMap;

@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class FullyBufferedBufferSource extends MultiBufferSource.BufferSource implements AutoCloseable {
public class FullyBufferedBufferSource extends MultiBufferSource.BufferSource implements Disposable {
private static final MemoryUtil.MemoryAllocator ALLOCATOR = MemoryUtil.getAllocator(false);
private final Map<RenderType, ByteBufferBuilder> byteBuffers = new HashMap<>();
private final Map<RenderType, BufferBuilder> bufferBuilders = new HashMap<>();
final Reference2IntMap<RenderType> indexCountMap = new Reference2IntOpenHashMap<>();
private final Map<RenderType, ByteBufferBuilder> byteBuffers = new ConcurrentHashMap<>();
private final Map<RenderType, BufferBuilder> bufferBuilders = new ConcurrentHashMap<>();
@Getter
private final Reference2IntMap<RenderType> indexCountMap = Reference2IntMaps.synchronize(new Reference2IntOpenHashMap<>());

public FullyBufferedBufferSource() {
super(null, null);
Expand All @@ -50,12 +53,9 @@ public boolean isEmpty() {
public void endBatch(RenderType renderType) {
}

public void upload(
Function<RenderType, VertexBuffer> vertexBufferGetter,
Consumer<Runnable> runner
) {
public void upload(CompileContext context) {
for (RenderType renderType : bufferBuilders.keySet()) {
runner.accept(() -> {
context.submitUploadTask(() -> {
BufferBuilder bufferBuilder = bufferBuilders.get(renderType);
ByteBufferBuilder byteBuffer = byteBuffers.get(renderType);
long ptr = byteBuffer.pointer;
Expand All @@ -64,19 +64,23 @@ public void upload(
long allocated = ALLOCATOR.malloc(compiledVertices);
MemoryUtil.memCopy(ptr, allocated, compiledVertices);
MeshData mesh = bufferBuilder.build();
if (mesh != null) {
mesh.close();
if (mesh == null) return;
QuadSortingState state = null;

if (renderType.sortOnUpload) {
state = QuadSortingState.fromMesh(mesh);
}
mesh.close();
CompileResult compileResult = new CompileResult(
renderType,
bufferBuilder.vertices,
renderType.format.getVertexSize(),
allocated,
renderType.mode.indexCount(bufferBuilder.vertices)
renderType.mode.indexCount(bufferBuilder.vertices),
state
);
indexCountMap.put(renderType, renderType.mode.indexCount(bufferBuilder.vertices));
compileResult.upload(vertexBufferGetter.apply(renderType));
compileResult.free();
compileResult.upload(context.getOrCreateBuffer(renderType, mesh.drawState().indexType()));
}
byteBuffer.close();
bufferBuilders.remove(renderType);
Expand All @@ -90,7 +94,13 @@ public void close(RenderType renderType) {
builder.close();
}

public void close() {
public void dispose() {
byteBuffers.keySet().forEach(this::close);
}

public interface CompileContext {
GlVertexBuffer getOrCreateBuffer(RenderType renderType, VertexFormat.IndexType indexType);

void submitUploadTask(Runnable runnable);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dev.dubhe.anvilcraft.api.rendering.foundation;

import dev.dubhe.anvilcraft.api.rendering.foundation.buffer.vertex.QuadSortingState;
import it.unimi.dsi.fastutil.ints.IntArrays;
import org.joml.Vector3f;

public class QuadSorter {
public static int[] buildSortedIndexByDistance(QuadSortingState state, Vector3f point){

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [Checkstyle] <com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAroundCheck> reported by reviewdog 🐶
WhitespaceAround: '{' is not preceded with whitespace.

float[] distances = new float[state.quadCenters().length];
int[] indexes = new int[state.quadCenters().length];

for (int i = 0; i < state.quadCenters().length; i++) {
distances[i] = state.quadCenters()[i].distanceSquared(point);
indexes[i] = i;
}
IntArrays.mergeSort(indexes, (a,b) -> Float.compare(distances[a], distances[b]));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [Checkstyle] <com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAfterCheck> reported by reviewdog 🐶
',' is not followed by whitespace.

return indexes;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package dev.dubhe.anvilcraft.api.rendering.foundation.buffer;

public interface BufferHost {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package dev.dubhe.anvilcraft.api.rendering.foundation.buffer;

import dev.dubhe.anvilcraft.api.rendering.foundation.Disposable;
import org.lwjgl.opengl.GL;

import static org.lwjgl.opengl.GL45.*;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [Checkstyle] <com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck> reported by reviewdog 🐶
Using the '.' form of import should be avoided - org.lwjgl.opengl.GL45..


public abstract class GlBufferStorage implements Disposable {
public static final boolean BUFFER_STORAGE_SUPPORT = GL.getCapabilities().GL_ARB_buffer_storage;
protected final int glBufferId;
protected final int target;
protected boolean valid = true;

GlBufferStorage(int target) {
this.target = target;
this.glBufferId = glGenBuffers();
}

public abstract void setupBufferState();

public void upload(long ptr, long size, Disposable uploadSrc) {
this.upload(ptr, size);
uploadSrc.dispose();
}

/**
* Runs on worker thread
*/
public abstract void upload(long ptr, long size);

public void bind() {
glBindBuffer(target, glBufferId);
}

@Override
public void dispose() {
if (!valid) return;
bind();
glDeleteBuffers(glBufferId);
unbind();
valid = false;
}

public void unbind() {
glBindBuffer(target, 0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package dev.dubhe.anvilcraft.api.rendering.foundation.buffer;

import com.mojang.blaze3d.systems.RenderSystem;
import dev.dubhe.anvilcraft.api.rendering.foundation.Disposable;

import static org.lwjgl.opengl.GL45.*;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [Checkstyle] <com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck> reported by reviewdog 🐶
Using the '.' form of import should be avoided - org.lwjgl.opengl.GL45..


public abstract class GlBufferStorageLegacy extends GlBufferStorage {

protected GlBufferStorageLegacy(int target) {
super(target);
bind();
this.setupBufferState();
unbind();
}

@Override
public void upload(long ptr, long size, Disposable disposable) {
if (RenderSystem.isOnRenderThread()) {
nglBufferData(this.target, size, ptr, GL_STATIC_DRAW);
disposable.dispose();
return;
}
RenderSystem.recordRenderCall(() -> {
nglBufferData(this.target, size, ptr, GL_STATIC_DRAW);
disposable.dispose();
}
);
}

public void upload(long ptr, long size) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package dev.dubhe.anvilcraft.api.rendering.foundation.buffer;

import net.minecraft.client.renderer.RenderType;
import org.lwjgl.opengl.ARBBufferStorage;
import org.lwjgl.system.MemoryUtil;

import static org.lwjgl.opengl.GL45.*;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [Checkstyle] <com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck> reported by reviewdog 🐶
Using the '.' form of import should be avoided - org.lwjgl.opengl.GL45..


public abstract class GlBufferStorageModern extends GlBufferStorage {
public static final long BUFFER_SIZE = RenderType.SMALL_BUFFER_SIZE;
public static final int FLAGS = ARBBufferStorage.GL_MAP_PERSISTENT_BIT
| ARBBufferStorage.GL_MAP_COHERENT_BIT
| GL_MAP_WRITE_BIT
| GL_DYNAMIC_STORAGE_BIT;

private long clientPtr;

protected GlBufferStorageModern(int target) {
super(target);
bind();
this.setupBufferState();
ARBBufferStorage.glBufferStorage(
target,
BUFFER_SIZE,
FLAGS
);
clientPtr = nglMapBufferRange(target, 0, BUFFER_SIZE, FLAGS);
unbind();
}

@Override
public void dispose() {
if (!valid)return;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [Checkstyle] <com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAroundCheck> reported by reviewdog 🐶
WhitespaceAround: 'return' is not preceded with whitespace.

bind();
glUnmapBuffer(target);
clientPtr = 0;
super.dispose();
}

@Override
public void upload(long ptr, long size) {
MemoryUtil.memCopy(ptr, clientPtr, size);
}
}
Loading
Loading