mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-15 00:36:08 +01:00
Bit off a bigger batch than I could chew
- Implement crumbling for batching engine. - It's ugly! (the code) - Need to support translucency sorting in batching. - Plumb RenderType#sortOnUpload through to DrawBuffer. - Allocate room in DrawBuffer for BufferBuilder to write indices. - Set nextElementByte on injectForRender. - Remove RenderStage from DrawBuffer, isn't really needed. - Make some fields public, so they can be accessed by BatchedCrumbling. - Track TransformCalls in BatchedInstancer. -
This commit is contained in:
parent
b668d10036
commit
8c86a66f18
15 changed files with 238 additions and 39 deletions
|
@ -30,6 +30,8 @@ public interface Engine extends InstancerProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the given instances as a crumbling overlay.
|
* Render the given instances as a crumbling overlay.
|
||||||
|
* <br>
|
||||||
|
* This is guaranteed to be called between the first and last calls to {@link #renderStage}.
|
||||||
*
|
*
|
||||||
* @param executor The task executor running the frame plan.
|
* @param executor The task executor running the frame plan.
|
||||||
* @param context The render context for this frame.
|
* @param context The render context for this frame.
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package com.jozufozu.flywheel.api.vertex;
|
package com.jozufozu.flywheel.api.vertex;
|
||||||
|
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A read only view of a vertex buffer.
|
* A read only view of a vertex buffer.
|
||||||
*
|
*
|
||||||
|
@ -73,4 +76,12 @@ public interface VertexList {
|
||||||
default boolean isEmpty() {
|
default boolean isEmpty() {
|
||||||
return vertexCount() == 0;
|
return vertexCount() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default Vector3f getNormal(int i, Vector3f dest) {
|
||||||
|
return dest.set(normalX(i), normalY(i), normalZ(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
default Vector4f getPos(int i, Vector4f dest) {
|
||||||
|
return dest.set(x(i), y(i), z(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
package com.jozufozu.flywheel.backend.engine.batching;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.backend.Engine;
|
||||||
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
|
import com.jozufozu.flywheel.api.model.Mesh;
|
||||||
|
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||||
|
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
|
||||||
|
import com.jozufozu.flywheel.extension.RenderTypeExtension;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.Pair;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.resources.model.ModelBakery;
|
||||||
|
|
||||||
|
public class BatchedCrumbling {
|
||||||
|
static void renderCrumbling(List<Engine.CrumblingBlock> crumblingBlocks, BatchContext batchContext, BatchedDrawTracker drawTracker) {
|
||||||
|
var instancesPerType = doCrumblingSort(crumblingBlocks);
|
||||||
|
|
||||||
|
for (var entry : instancesPerType.entrySet()) {
|
||||||
|
// TODO: separate concept of renderstage from drawbuffer
|
||||||
|
var drawBuffer = RenderTypeExtension.getDrawBufferSet(entry.getKey())
|
||||||
|
.getBuffer(RenderStage.AFTER_BLOCK_ENTITIES);
|
||||||
|
|
||||||
|
var bucket = entry.getValue();
|
||||||
|
|
||||||
|
drawBuffer.prepare(bucket.vertexCount);
|
||||||
|
|
||||||
|
ReusableVertexList vertexList = drawBuffer.slice(0, 0);
|
||||||
|
long basePtr = vertexList.ptr();
|
||||||
|
|
||||||
|
int totalVertices = 0;
|
||||||
|
|
||||||
|
for (var pair : bucket.instances) {
|
||||||
|
var instance = pair.first();
|
||||||
|
var instancer = pair.second();
|
||||||
|
|
||||||
|
totalVertices += bufferOne(instancer, totalVertices, vertexList, drawBuffer, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
vertexList.ptr(basePtr);
|
||||||
|
vertexList.vertexCount(totalVertices);
|
||||||
|
|
||||||
|
// apply these in bulk
|
||||||
|
BatchingTransforms.applyDecalUVs(vertexList);
|
||||||
|
BatchingTransforms.applyMatrices(vertexList, batchContext.matrices());
|
||||||
|
|
||||||
|
drawTracker._draw(drawBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static Map<RenderType, CrumblingBucket> doCrumblingSort(List<Engine.CrumblingBlock> crumblingBlocks) {
|
||||||
|
Map<RenderType, CrumblingBucket> out = new HashMap<>();
|
||||||
|
|
||||||
|
for (Engine.CrumblingBlock crumblingBlock : crumblingBlocks) {
|
||||||
|
var crumblingType = ModelBakery.DESTROY_TYPES.get(crumblingBlock.progress());
|
||||||
|
|
||||||
|
for (Instance instance : crumblingBlock.instances()) {
|
||||||
|
if (!(instance.handle() instanceof InstanceHandleImpl impl)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!(impl.instancer instanceof BatchedInstancer<?> instancer)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bucket = out.computeIfAbsent(crumblingType, $ -> new CrumblingBucket());
|
||||||
|
bucket.instances.add(Pair.of(instance, instancer));
|
||||||
|
|
||||||
|
for (TransformCall<?> transformCall : instancer.getTransformCalls()) {
|
||||||
|
var mesh = transformCall.mesh;
|
||||||
|
bucket.vertexCount += mesh.getVertexCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <I extends Instance> int bufferOne(BatchedInstancer<I> batchedInstancer, int baseVertex, ReusableVertexList vertexList, DrawBuffer drawBuffer, Instance instance) {
|
||||||
|
int totalVertices = 0;
|
||||||
|
|
||||||
|
for (TransformCall<I> transformCall : batchedInstancer.getTransformCalls()) {
|
||||||
|
Mesh mesh = transformCall.mesh.mesh;
|
||||||
|
|
||||||
|
vertexList.ptr(drawBuffer.ptrForVertex(baseVertex + totalVertices));
|
||||||
|
vertexList.vertexCount(mesh.vertexCount());
|
||||||
|
|
||||||
|
mesh.write(vertexList);
|
||||||
|
batchedInstancer.type.getVertexTransformer()
|
||||||
|
.transform(vertexList, (I) instance);
|
||||||
|
|
||||||
|
totalVertices += mesh.vertexCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalVertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class CrumblingBucket {
|
||||||
|
private int vertexCount;
|
||||||
|
private final List<Pair<Instance, BatchedInstancer<?>>> instances = new ArrayList<>();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
|
||||||
class BatchedDrawManager extends InstancerStorage<BatchedInstancer<?>> {
|
class BatchedDrawManager extends InstancerStorage<BatchedInstancer<?>> {
|
||||||
private final BatchedDrawTracker drawTracker = new BatchedDrawTracker();
|
public final BatchedDrawTracker drawTracker = new BatchedDrawTracker();
|
||||||
private final Map<RenderStage, BatchedStagePlan> stagePlans = new EnumMap<>(RenderStage.class);
|
private final Map<RenderStage, BatchedStagePlan> stagePlans = new EnumMap<>(RenderStage.class);
|
||||||
private final Map<VertexFormat, BatchedMeshPool> meshPools = new HashMap<>();
|
private final Map<VertexFormat, BatchedMeshPool> meshPools = new HashMap<>();
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.extension.BufferBuilderExtension;
|
import com.jozufozu.flywheel.extension.BufferBuilderExtension;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
|
|
||||||
public class BatchedDrawTracker {
|
public class BatchedDrawTracker {
|
||||||
|
@ -25,16 +26,17 @@ public class BatchedDrawTracker {
|
||||||
((BufferBuilderExtension) scratch).flywheel$freeBuffer();
|
((BufferBuilderExtension) scratch).flywheel$freeBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markActive(DrawBuffer buffer) {
|
public void markActive(RenderStage stage, DrawBuffer buffer) {
|
||||||
synchronized (activeBuffers) {
|
synchronized (activeBuffers) {
|
||||||
activeBuffers.get(buffer.getRenderStage())
|
activeBuffers.get(stage)
|
||||||
.add(buffer);
|
.add(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markInactive(DrawBuffer buffer) {
|
// TODO: remove?
|
||||||
|
public void markInactive(RenderStage stage, DrawBuffer buffer) {
|
||||||
synchronized (activeBuffers) {
|
synchronized (activeBuffers) {
|
||||||
activeBuffers.get(buffer.getRenderStage())
|
activeBuffers.get(stage)
|
||||||
.remove(buffer);
|
.remove(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,12 +69,12 @@ public class BatchedDrawTracker {
|
||||||
buffers.clear();
|
buffers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _draw(DrawBuffer buffer) {
|
public void _draw(DrawBuffer buffer) {
|
||||||
if (buffer.hasVertices()) {
|
if (buffer.hasVertices()) {
|
||||||
BufferBuilderExtension scratch = (BufferBuilderExtension) this.scratch;
|
BufferBuilderExtension scratch = (BufferBuilderExtension) this.scratch;
|
||||||
buffer.inject(scratch);
|
buffer.inject(scratch);
|
||||||
buffer.getRenderType()
|
buffer.getRenderType()
|
||||||
.end(this.scratch, null);
|
.end(this.scratch, RenderSystem.getVertexSorting());
|
||||||
}
|
}
|
||||||
buffer.reset();
|
buffer.reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.engine.batching;
|
package com.jozufozu.flywheel.backend.engine.batching;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
|
@ -7,6 +8,8 @@ import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
||||||
|
|
||||||
public class BatchedInstancer<I extends Instance> extends AbstractInstancer<I> {
|
public class BatchedInstancer<I extends Instance> extends AbstractInstancer<I> {
|
||||||
|
private final List<TransformCall<I>> transformCalls = new ArrayList<>();
|
||||||
|
|
||||||
public BatchedInstancer(InstanceType<I> type) {
|
public BatchedInstancer(InstanceType<I> type) {
|
||||||
super(type);
|
super(type);
|
||||||
}
|
}
|
||||||
|
@ -26,4 +29,12 @@ public class BatchedInstancer<I extends Instance> extends AbstractInstancer<I> {
|
||||||
public void update() {
|
public void update() {
|
||||||
removeDeletedInstances();
|
removeDeletedInstances();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addTransformCall(TransformCall<I> transformCall) {
|
||||||
|
transformCalls.add(transformCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TransformCall<I>> getTransformCalls() {
|
||||||
|
return transformCalls;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,7 +150,7 @@ public class BatchedMeshPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BufferedMesh {
|
public class BufferedMesh {
|
||||||
private final Mesh mesh;
|
public final Mesh mesh;
|
||||||
private final int byteSize;
|
private final int byteSize;
|
||||||
private final int vertexCount;
|
private final int vertexCount;
|
||||||
private final Vector4fc boundingSphere;
|
private final Vector4fc boundingSphere;
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class BatchedStagePlan implements SimplyComposedPlan<BatchContext> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tracker.markActive(buffer);
|
tracker.markActive(stage, buffer);
|
||||||
buffer.prepare(vertexCount);
|
buffer.prepare(vertexCount);
|
||||||
|
|
||||||
var vertexCounter = new AtomicInteger(0);
|
var vertexCounter = new AtomicInteger(0);
|
||||||
|
|
|
@ -45,7 +45,10 @@ public class BatchingEngine extends AbstractEngine {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderCrumblingInstances(TaskExecutor executor, RenderContext context, List<CrumblingBlock> crumblingBlocks) {
|
public void renderCrumblingInstances(TaskExecutor executor, RenderContext context, List<CrumblingBlock> crumblingBlocks) {
|
||||||
// TODO: implement
|
executor.syncUntil(flushFlag::isRaised);
|
||||||
|
|
||||||
|
var batchContext = BatchContext.create(context, this.renderOrigin);
|
||||||
|
BatchedCrumbling.renderCrumbling(crumblingBlocks, batchContext, this.drawManager.drawTracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.jozufozu.flywheel.backend.engine.batching;
|
||||||
|
|
||||||
|
import org.joml.Matrix3f;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||||
|
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||||
|
import com.jozufozu.flywheel.lib.vertex.VertexTransformations;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import com.mojang.blaze3d.vertex.SheetedDecalTextureGenerator;
|
||||||
|
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
|
||||||
|
public class BatchingTransforms {
|
||||||
|
public static void applyMatrices(MutableVertexList vertexList, PoseStack.Pose matrices) {
|
||||||
|
Matrix4f modelMatrix = matrices.pose();
|
||||||
|
Matrix3f normalMatrix = matrices.normal();
|
||||||
|
|
||||||
|
for (int i = 0; i < vertexList.vertexCount(); i++) {
|
||||||
|
VertexTransformations.transformPos(vertexList, i, modelMatrix);
|
||||||
|
VertexTransformations.transformNormal(vertexList, i, normalMatrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the same operation as {@link SheetedDecalTextureGenerator} in-place.
|
||||||
|
* <br>
|
||||||
|
* Call this in world space.
|
||||||
|
*
|
||||||
|
* @param vertexList The vertex list to apply the transformations to.
|
||||||
|
*/
|
||||||
|
public static void applyDecalUVs(ReusableVertexList vertexList) {
|
||||||
|
Vector3f normal = new Vector3f();
|
||||||
|
Vector4f pos = new Vector4f();
|
||||||
|
|
||||||
|
for (int i = 0; i < vertexList.vertexCount(); i++) {
|
||||||
|
vertexList.getPos(i, pos);
|
||||||
|
vertexList.getNormal(i, normal);
|
||||||
|
|
||||||
|
Direction direction = Direction.getNearest(normal.x(), normal.y(), normal.z());
|
||||||
|
pos.rotateY((float)Math.PI);
|
||||||
|
pos.rotateX((-(float)Math.PI / 2F));
|
||||||
|
pos.rotate(direction.getRotation());
|
||||||
|
float u = -pos.x();
|
||||||
|
float v = -pos.y();
|
||||||
|
|
||||||
|
vertexList.u(i, u);
|
||||||
|
vertexList.v(i, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,19 +14,20 @@ import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.util.Mth;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A byte buffer that can be used to draw vertices through multiple {@link ReusableVertexList}s.
|
* A byte buffer that can be used to draw vertices through multiple {@link ReusableVertexList}s.
|
||||||
*
|
* <br>
|
||||||
* The number of vertices needs to be known ahead of time.
|
* Note: The number of vertices needs to be known ahead of time.
|
||||||
*/
|
*/
|
||||||
public class DrawBuffer {
|
public class DrawBuffer {
|
||||||
private static final List<DrawBuffer> ALL = new ArrayList<>();
|
private static final List<DrawBuffer> ALL = new ArrayList<>();
|
||||||
|
|
||||||
private final RenderType renderType;
|
private final RenderType renderType;
|
||||||
private final RenderStage renderStage;
|
|
||||||
private final VertexFormat format;
|
private final VertexFormat format;
|
||||||
private final int stride;
|
private final int stride;
|
||||||
|
private final boolean sortOnUpload;
|
||||||
private final VertexListProvider provider;
|
private final VertexListProvider provider;
|
||||||
|
|
||||||
private MemoryBlock data;
|
private MemoryBlock data;
|
||||||
|
@ -36,11 +37,11 @@ public class DrawBuffer {
|
||||||
private int vertexCount;
|
private int vertexCount;
|
||||||
private int verticesToDraw;
|
private int verticesToDraw;
|
||||||
|
|
||||||
public DrawBuffer(RenderType renderType, RenderStage renderStage, VertexFormat format, int stride, VertexListProvider provider) {
|
public DrawBuffer(RenderType renderType, VertexFormat format, int stride, boolean sortOnUpload, VertexListProvider provider) {
|
||||||
this.renderType = renderType;
|
this.renderType = renderType;
|
||||||
this.renderStage = renderStage;
|
|
||||||
this.format = format;
|
this.format = format;
|
||||||
this.stride = stride;
|
this.stride = stride;
|
||||||
|
this.sortOnUpload = sortOnUpload;
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
|
|
||||||
ALL.add(this);
|
ALL.add(this);
|
||||||
|
@ -64,6 +65,15 @@ public class DrawBuffer {
|
||||||
// is called and reallocates the buffer if there is not space for one more vertex.
|
// is called and reallocates the buffer if there is not space for one more vertex.
|
||||||
int byteSize = stride * (vertexCount + 1);
|
int byteSize = stride * (vertexCount + 1);
|
||||||
|
|
||||||
|
// We'll need to allocate space for the index buffer if this render type needs sorting.
|
||||||
|
if (sortOnUpload) {
|
||||||
|
int i = renderType.mode()
|
||||||
|
.indexCount(vertexCount);
|
||||||
|
VertexFormat.IndexType indexType = VertexFormat.IndexType.least(i);
|
||||||
|
int extraBytes = Mth.roundToward(i * indexType.bytes, 4);
|
||||||
|
byteSize += extraBytes;
|
||||||
|
}
|
||||||
|
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
data = MemoryBlock.malloc(byteSize);
|
data = MemoryBlock.malloc(byteSize);
|
||||||
buffer = data.asBuffer();
|
buffer = data.asBuffer();
|
||||||
|
@ -116,10 +126,6 @@ public class DrawBuffer {
|
||||||
return renderType;
|
return renderType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RenderStage getRenderStage() {
|
|
||||||
return renderStage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VertexFormat getVertexFormat() {
|
public VertexFormat getVertexFormat() {
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,18 +13,20 @@ import net.minecraft.client.renderer.RenderType;
|
||||||
public class DrawBufferSet {
|
public class DrawBufferSet {
|
||||||
private final RenderType renderType;
|
private final RenderType renderType;
|
||||||
private final VertexFormat format;
|
private final VertexFormat format;
|
||||||
|
private final boolean sortOnUpload;
|
||||||
private final int stride;
|
private final int stride;
|
||||||
private final VertexListProvider provider;
|
private final VertexListProvider provider;
|
||||||
private final Map<RenderStage, DrawBuffer> buffers = new EnumMap<>(RenderStage.class);
|
private final Map<RenderStage, DrawBuffer> buffers = new EnumMap<>(RenderStage.class);
|
||||||
|
|
||||||
public DrawBufferSet(RenderType renderType) {
|
public DrawBufferSet(RenderType renderType, boolean sortOnUpload) {
|
||||||
this.renderType = renderType;
|
this.renderType = renderType;
|
||||||
|
this.sortOnUpload = sortOnUpload;
|
||||||
format = renderType.format();
|
format = renderType.format();
|
||||||
stride = format.getVertexSize();
|
stride = format.getVertexSize();
|
||||||
provider = VertexListProviderRegistry.getProvider(format);
|
provider = VertexListProviderRegistry.getProvider(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DrawBuffer getBuffer(RenderStage stage) {
|
public DrawBuffer getBuffer(RenderStage stage) {
|
||||||
return buffers.computeIfAbsent(stage, renderStage -> new DrawBuffer(renderType, renderStage, format, stride, provider));
|
return buffers.computeIfAbsent(stage, renderStage -> new DrawBuffer(renderType, format, stride, sortOnUpload, provider));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,6 @@ package com.jozufozu.flywheel.backend.engine.batching;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.joml.FrustumIntersection;
|
import org.joml.FrustumIntersection;
|
||||||
import org.joml.Matrix3f;
|
|
||||||
import org.joml.Matrix4f;
|
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
import org.joml.Vector4fc;
|
import org.joml.Vector4fc;
|
||||||
|
|
||||||
|
@ -14,22 +12,25 @@ import com.jozufozu.flywheel.api.instance.InstanceVertexTransformer;
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.api.material.MaterialVertexTransformer;
|
import com.jozufozu.flywheel.api.material.MaterialVertexTransformer;
|
||||||
import com.jozufozu.flywheel.api.task.Plan;
|
import com.jozufozu.flywheel.api.task.Plan;
|
||||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
|
||||||
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||||
import com.jozufozu.flywheel.lib.task.ForEachSlicePlan;
|
import com.jozufozu.flywheel.lib.task.ForEachSlicePlan;
|
||||||
import com.jozufozu.flywheel.lib.vertex.VertexTransformations;
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
|
||||||
public class TransformCall<I extends Instance> {
|
public class TransformCall<I extends Instance> {
|
||||||
private final BatchedInstancer<I> instancer;
|
public final BatchedInstancer<I> instancer;
|
||||||
private final int meshVertexCount;
|
public final Material material;
|
||||||
|
public final BatchedMeshPool.BufferedMesh mesh;
|
||||||
|
|
||||||
|
private final int meshVertexCount;
|
||||||
private final Plan<PlanContext> drawPlan;
|
private final Plan<PlanContext> drawPlan;
|
||||||
|
|
||||||
public TransformCall(BatchedInstancer<I> instancer, Material material, BatchedMeshPool.BufferedMesh mesh) {
|
public TransformCall(BatchedInstancer<I> instancer, Material material, BatchedMeshPool.BufferedMesh mesh) {
|
||||||
this.instancer = instancer;
|
this.instancer = instancer;
|
||||||
|
this.material = material;
|
||||||
|
this.mesh = mesh;
|
||||||
|
instancer.addTransformCall(this);
|
||||||
|
|
||||||
InstanceVertexTransformer<I> instanceVertexTransformer = instancer.type.getVertexTransformer();
|
InstanceVertexTransformer<I> instanceVertexTransformer = instancer.type.getVertexTransformer();
|
||||||
InstanceBoundingSphereTransformer<I> boundingSphereTransformer = instancer.type.getBoundingSphereTransformer();
|
InstanceBoundingSphereTransformer<I> boundingSphereTransformer = instancer.type.getBoundingSphereTransformer();
|
||||||
|
@ -56,7 +57,7 @@ public class TransformCall<I extends Instance> {
|
||||||
mesh.copyTo(vertexList.ptr());
|
mesh.copyTo(vertexList.ptr());
|
||||||
instanceVertexTransformer.transform(vertexList, instance);
|
instanceVertexTransformer.transform(vertexList, instance);
|
||||||
materialVertexTransformer.transform(vertexList, ctx.level);
|
materialVertexTransformer.transform(vertexList, ctx.level);
|
||||||
applyMatrices(vertexList, ctx.matrices);
|
BatchingTransforms.applyMatrices(vertexList, ctx.matrices);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -73,16 +74,6 @@ public class TransformCall<I extends Instance> {
|
||||||
return drawPlan;
|
return drawPlan;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void applyMatrices(MutableVertexList vertexList, PoseStack.Pose matrices) {
|
|
||||||
Matrix4f modelMatrix = matrices.pose();
|
|
||||||
Matrix3f normalMatrix = matrices.normal();
|
|
||||||
|
|
||||||
for (int i = 0; i < vertexList.vertexCount(); i++) {
|
|
||||||
VertexTransformations.transformPos(vertexList, i, modelMatrix);
|
|
||||||
VertexTransformations.transformNormal(vertexList, i, normalMatrix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public record PlanContext(FrustumIntersection frustum, AtomicInteger vertexCounter, DrawBuffer buffer, ClientLevel level, PoseStack.Pose matrices) {
|
public record PlanContext(FrustumIntersection frustum, AtomicInteger vertexCounter, DrawBuffer buffer, ClientLevel level, PoseStack.Pose matrices) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,9 @@ public abstract class BufferBuilderMixin implements BufferBuilderExtension {
|
||||||
@Shadow
|
@Shadow
|
||||||
private boolean building;
|
private boolean building;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private int nextElementByte;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flywheel$freeBuffer() {
|
public void flywheel$freeBuffer() {
|
||||||
if (buffer != null) {
|
if (buffer != null) {
|
||||||
|
@ -58,5 +61,6 @@ public abstract class BufferBuilderMixin implements BufferBuilderExtension {
|
||||||
|
|
||||||
currentElement = format.getElements().get(0);
|
currentElement = format.getElements().get(0);
|
||||||
elementIndex = 0;
|
elementIndex = 0;
|
||||||
|
nextElementByte = vertexCount * format.getVertexSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package com.jozufozu.flywheel.mixin;
|
package com.jozufozu.flywheel.mixin;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.engine.batching.DrawBufferSet;
|
import com.jozufozu.flywheel.backend.engine.batching.DrawBufferSet;
|
||||||
|
@ -11,6 +13,9 @@ import net.minecraft.client.renderer.RenderType;
|
||||||
|
|
||||||
@Mixin(RenderType.class)
|
@Mixin(RenderType.class)
|
||||||
public class RenderTypeMixin implements RenderTypeExtension {
|
public class RenderTypeMixin implements RenderTypeExtension {
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private boolean sortOnUpload;
|
||||||
@Unique
|
@Unique
|
||||||
private DrawBufferSet flywheel$drawBufferSet;
|
private DrawBufferSet flywheel$drawBufferSet;
|
||||||
|
|
||||||
|
@ -18,7 +23,7 @@ public class RenderTypeMixin implements RenderTypeExtension {
|
||||||
@NotNull
|
@NotNull
|
||||||
public DrawBufferSet flywheel$getDrawBufferSet() {
|
public DrawBufferSet flywheel$getDrawBufferSet() {
|
||||||
if (flywheel$drawBufferSet == null) {
|
if (flywheel$drawBufferSet == null) {
|
||||||
flywheel$drawBufferSet = new DrawBufferSet((RenderType) (Object) this);
|
flywheel$drawBufferSet = new DrawBufferSet((RenderType) (Object) this, sortOnUpload);
|
||||||
}
|
}
|
||||||
return flywheel$drawBufferSet;
|
return flywheel$drawBufferSet;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue