mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-06 04:16:36 +01:00
Hazardous light
- BatchingEngine no longer resets the light matrices - Fix flw_constantAmbientLight always being 0 - Move code from FlwMemoryTracker#*Block methods into MemoryBlockImpl and TrackedMemoryBlockImpl - Convert LightVolume to use MemoryBlock - Add FlwMemoryTracker#callocBuffer - Add javadoc to deprecated FlwMemoryTracker#*Buffer methods - Update Mesh javadoc - Organize imports
This commit is contained in:
parent
a1553b04e7
commit
9b39ba6c32
24 changed files with 288 additions and 296 deletions
|
@ -22,7 +22,7 @@ public interface Material {
|
|||
|
||||
VertexTransformer getVertexTransformer();
|
||||
|
||||
public interface VertexTransformer {
|
||||
interface VertexTransformer {
|
||||
void transform(MutableVertexList vertexList, ClientLevel level);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ public interface StructType<S extends InstancedPart> {
|
|||
|
||||
VertexTransformer<S> getVertexTransformer();
|
||||
|
||||
public interface VertexTransformer<S extends InstancedPart> {
|
||||
interface VertexTransformer<S extends InstancedPart> {
|
||||
void transform(MutableVertexList vertexList, S struct, ClientLevel level);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.jozufozu.flywheel.api.uniform;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||
|
||||
public abstract class UniformProvider {
|
||||
|
|
|
@ -5,8 +5,8 @@ import org.lwjgl.opengl.GL32;
|
|||
|
||||
import com.jozufozu.flywheel.backend.gl.GlObject;
|
||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
package com.jozufozu.flywheel.backend.gl.buffer;
|
||||
|
||||
import static org.lwjgl.opengl.GL32.*;
|
||||
import static org.lwjgl.opengl.GL15.glBufferData;
|
||||
import static org.lwjgl.opengl.GL15.glDeleteBuffers;
|
||||
import static org.lwjgl.opengl.GL15.glGenBuffers;
|
||||
import static org.lwjgl.opengl.GL15.nglBufferData;
|
||||
import static org.lwjgl.opengl.GL30.GL_MAP_WRITE_BIT;
|
||||
import static org.lwjgl.opengl.GL30.nglMapBufferRange;
|
||||
import static org.lwjgl.opengl.GL31.glCopyBufferSubData;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
|
|
|
@ -13,9 +13,7 @@ import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
|||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||
import com.jozufozu.flywheel.core.RenderContext;
|
||||
import com.jozufozu.flywheel.util.FlwUtil;
|
||||
import com.mojang.blaze3d.platform.Lighting;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Matrix4f;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
@ -73,15 +71,6 @@ public class BatchingEngine implements Engine {
|
|||
return;
|
||||
}
|
||||
|
||||
// FIXME: this probably breaks some vanilla stuff but it works much better for flywheel
|
||||
Matrix4f mat = new Matrix4f();
|
||||
mat.setIdentity();
|
||||
if (context.level().effects().constantAmbientLight()) {
|
||||
Lighting.setupNetherLevel(mat);
|
||||
} else {
|
||||
Lighting.setupLevel(mat);
|
||||
}
|
||||
|
||||
batchTracker.endBatch();
|
||||
}
|
||||
|
||||
|
|
|
@ -83,20 +83,15 @@ public class TransformSet<D extends InstancedPart> {
|
|||
vertexList.ptr(anchorPtr);
|
||||
vertexList.setVertexCount(totalVertexCount);
|
||||
material.getVertexTransformer().transform(vertexList, level);
|
||||
applyPoseStack(vertexList, stack, false);
|
||||
applyPoseStack(vertexList, stack);
|
||||
}
|
||||
|
||||
private static void applyPoseStack(MutableVertexList vertexList, PoseStack stack, boolean applyNormalMatrix) {
|
||||
private static void applyPoseStack(MutableVertexList vertexList, PoseStack stack) {
|
||||
Vector4f pos = new Vector4f();
|
||||
Vector3f normal = new Vector3f();
|
||||
|
||||
Matrix4f modelMatrix = stack.last().pose();
|
||||
Matrix3f normalMatrix;
|
||||
if (applyNormalMatrix) {
|
||||
normalMatrix = stack.last().normal();
|
||||
} else {
|
||||
normalMatrix = null;
|
||||
}
|
||||
Matrix3f normalMatrix = stack.last().normal();
|
||||
|
||||
for (int i = 0; i < vertexList.getVertexCount(); i++) {
|
||||
pos.set(
|
||||
|
@ -110,18 +105,16 @@ public class TransformSet<D extends InstancedPart> {
|
|||
vertexList.y(i, pos.y());
|
||||
vertexList.z(i, pos.z());
|
||||
|
||||
if (applyNormalMatrix) {
|
||||
normal.set(
|
||||
vertexList.normalX(i),
|
||||
vertexList.normalY(i),
|
||||
vertexList.normalZ(i)
|
||||
);
|
||||
normal.transform(normalMatrix);
|
||||
normal.normalize();
|
||||
vertexList.normalX(i, normal.x());
|
||||
vertexList.normalY(i, normal.y());
|
||||
vertexList.normalZ(i, normal.z());
|
||||
}
|
||||
normal.set(
|
||||
vertexList.normalX(i),
|
||||
vertexList.normalY(i),
|
||||
vertexList.normalZ(i)
|
||||
);
|
||||
normal.transform(normalMatrix);
|
||||
normal.normalize();
|
||||
vertexList.normalX(i, normal.x());
|
||||
vertexList.normalY(i, normal.y());
|
||||
vertexList.normalZ(i, normal.z());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,10 @@ import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
|||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||
import com.jozufozu.flywheel.backend.gl.array.GlVertexArray;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferUsage;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
|
||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||
|
||||
|
|
|
@ -14,9 +14,9 @@ import com.jozufozu.flywheel.Flywheel;
|
|||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
|
||||
import com.jozufozu.flywheel.backend.gl.array.GlVertexArray;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||
import com.jozufozu.flywheel.core.model.Mesh;
|
||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.nio.ByteBuffer;
|
|||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
public class FlwMemoryTracker {
|
||||
private static final Cleaner CLEANER = Cleaner.create();
|
||||
static final Cleaner CLEANER = Cleaner.create();
|
||||
|
||||
private static long cpuMemory = 0;
|
||||
private static long gpuMemory = 0;
|
||||
|
@ -19,18 +19,11 @@ public class FlwMemoryTracker {
|
|||
return ptr;
|
||||
}
|
||||
|
||||
public static MemoryBlock mallocBlock(long size) {
|
||||
MemoryBlock block = new MemoryBlockImpl(malloc(size), size);
|
||||
_allocCPUMemory(block.size());
|
||||
return block;
|
||||
}
|
||||
|
||||
public static MemoryBlock mallocBlockTracked(long size) {
|
||||
MemoryBlock block = new TrackedMemoryBlockImpl(malloc(size), size, CLEANER);
|
||||
_allocCPUMemory(block.size());
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link MemoryBlock#malloc(long)} or {@link MemoryBlock#mallocTracked(long)} and
|
||||
* {@link MemoryBlock#asBuffer()} instead. This method should only be used if specifically a {@linkplain ByteBuffer} is needed and it is
|
||||
* short-lived.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ByteBuffer mallocBuffer(int size) {
|
||||
ByteBuffer buffer = MemoryUtil.memByteBuffer(malloc(size), size);
|
||||
|
@ -46,16 +39,16 @@ public class FlwMemoryTracker {
|
|||
return ptr;
|
||||
}
|
||||
|
||||
public static MemoryBlock callocBlock(long num, long size) {
|
||||
MemoryBlock block = new MemoryBlockImpl(calloc(num, size), num * size);
|
||||
_allocCPUMemory(block.size());
|
||||
return block;
|
||||
}
|
||||
|
||||
public static MemoryBlock callocBlockTracked(long num, long size) {
|
||||
MemoryBlock block = new TrackedMemoryBlockImpl(calloc(num, size), num * size, CLEANER);
|
||||
_allocCPUMemory(block.size());
|
||||
return block;
|
||||
/**
|
||||
* @deprecated Use {@link MemoryBlock#calloc(long, long)} or {@link MemoryBlock#callocTracked(long, long)} and
|
||||
* {@link MemoryBlock#asBuffer()} instead. This method should only be used if specifically a {@linkplain ByteBuffer} is needed and it is
|
||||
* short-lived.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ByteBuffer callocBuffer(int num, int size) {
|
||||
ByteBuffer buffer = MemoryUtil.memByteBuffer(calloc(num, size), num * size);
|
||||
_allocCPUMemory(buffer.capacity());
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static long realloc(long ptr, long size) {
|
||||
|
@ -66,20 +59,10 @@ public class FlwMemoryTracker {
|
|||
return ptr;
|
||||
}
|
||||
|
||||
public static MemoryBlock reallocBlock(MemoryBlock block, long size) {
|
||||
MemoryBlock newBlock = new MemoryBlockImpl(realloc(block.ptr(), size), size);
|
||||
_freeCPUMemory(block.size());
|
||||
_allocCPUMemory(newBlock.size());
|
||||
return newBlock;
|
||||
}
|
||||
|
||||
public static MemoryBlock reallocBlockTracked(MemoryBlock block, long size) {
|
||||
MemoryBlock newBlock = new TrackedMemoryBlockImpl(realloc(block.ptr(), size), size, CLEANER);
|
||||
_freeCPUMemory(block.size());
|
||||
_allocCPUMemory(newBlock.size());
|
||||
return newBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link MemoryBlock#realloc(long)} or {@link MemoryBlock#reallocTracked(long)} instead. This method
|
||||
* should only be used if specifically a {@linkplain ByteBuffer} is needed and it is short-lived.
|
||||
*/
|
||||
@Deprecated
|
||||
public static ByteBuffer reallocBuffer(ByteBuffer buffer, int size) {
|
||||
ByteBuffer newBuffer = MemoryUtil.memByteBuffer(realloc(MemoryUtil.memAddress(buffer), size), size);
|
||||
|
@ -92,11 +75,10 @@ public class FlwMemoryTracker {
|
|||
MemoryUtil.nmemFree(ptr);
|
||||
}
|
||||
|
||||
public static void freeBlock(MemoryBlock block) {
|
||||
free(block.ptr());
|
||||
_freeCPUMemory(block.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link MemoryBlock#free} instead. This method should only be used if specifically a {@linkplain ByteBuffer} is needed and
|
||||
* it is short-lived.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void freeBuffer(ByteBuffer buffer) {
|
||||
free(MemoryUtil.memAddress(buffer));
|
||||
|
|
|
@ -26,18 +26,18 @@ public sealed interface MemoryBlock permits MemoryBlockImpl {
|
|||
void free();
|
||||
|
||||
static MemoryBlock malloc(long size) {
|
||||
return FlwMemoryTracker.mallocBlock(size);
|
||||
}
|
||||
|
||||
static MemoryBlock calloc(long num, long size) {
|
||||
return FlwMemoryTracker.callocBlock(num, size);
|
||||
return MemoryBlockImpl.mallocBlock(size);
|
||||
}
|
||||
|
||||
static MemoryBlock mallocTracked(long size) {
|
||||
return FlwMemoryTracker.mallocBlockTracked(size);
|
||||
return TrackedMemoryBlockImpl.mallocBlockTracked(size);
|
||||
}
|
||||
|
||||
static MemoryBlock calloc(long num, long size) {
|
||||
return MemoryBlockImpl.callocBlock(num, size);
|
||||
}
|
||||
|
||||
static MemoryBlock callocTracked(long num, long size) {
|
||||
return FlwMemoryTracker.callocBlockTracked(num, size);
|
||||
return TrackedMemoryBlockImpl.callocBlockTracked(num, size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,23 +59,42 @@ sealed class MemoryBlockImpl implements MemoryBlock permits TrackedMemoryBlockIm
|
|||
return MemoryUtil.memByteBuffer(ptr, intSize);
|
||||
}
|
||||
|
||||
void freeInner() {
|
||||
FlwMemoryTracker._freeCPUMemory(size);
|
||||
freed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemoryBlock realloc(long size) {
|
||||
MemoryBlock block = FlwMemoryTracker.reallocBlock(this, size);
|
||||
freed = true;
|
||||
MemoryBlock block = new MemoryBlockImpl(FlwMemoryTracker.realloc(ptr, size), size);
|
||||
FlwMemoryTracker._allocCPUMemory(block.size());
|
||||
freeInner();
|
||||
return block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemoryBlock reallocTracked(long size) {
|
||||
MemoryBlock block = FlwMemoryTracker.reallocBlockTracked(this, size);
|
||||
freed = true;
|
||||
MemoryBlock block = new TrackedMemoryBlockImpl(FlwMemoryTracker.realloc(ptr, size), size, FlwMemoryTracker.CLEANER);
|
||||
FlwMemoryTracker._allocCPUMemory(block.size());
|
||||
freeInner();
|
||||
return block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void free() {
|
||||
FlwMemoryTracker.freeBlock(this);
|
||||
freed = true;
|
||||
FlwMemoryTracker.free(ptr);
|
||||
freeInner();
|
||||
}
|
||||
|
||||
static MemoryBlock mallocBlock(long size) {
|
||||
MemoryBlock block = new MemoryBlockImpl(FlwMemoryTracker.malloc(size), size);
|
||||
FlwMemoryTracker._allocCPUMemory(block.size());
|
||||
return block;
|
||||
}
|
||||
|
||||
static MemoryBlock callocBlock(long num, long size) {
|
||||
MemoryBlock block = new MemoryBlockImpl(FlwMemoryTracker.calloc(num, size), num * size);
|
||||
FlwMemoryTracker._allocCPUMemory(block.size());
|
||||
return block;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,32 +17,25 @@ final class TrackedMemoryBlockImpl extends MemoryBlockImpl {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
void freeInner() {
|
||||
freed = true;
|
||||
super.freeInner();
|
||||
cleaningAction.freed = true;
|
||||
cleanable.clean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemoryBlock realloc(long size) {
|
||||
MemoryBlock block = FlwMemoryTracker.reallocBlock(this, size);
|
||||
freeInner();
|
||||
static MemoryBlock mallocBlockTracked(long size) {
|
||||
MemoryBlock block = new TrackedMemoryBlockImpl(FlwMemoryTracker.malloc(size), size, FlwMemoryTracker.CLEANER);
|
||||
FlwMemoryTracker._allocCPUMemory(block.size());
|
||||
return block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemoryBlock reallocTracked(long size) {
|
||||
MemoryBlock block = FlwMemoryTracker.reallocBlockTracked(this, size);
|
||||
freeInner();
|
||||
static MemoryBlock callocBlockTracked(long num, long size) {
|
||||
MemoryBlock block = new TrackedMemoryBlockImpl(FlwMemoryTracker.calloc(num, size), num * size, FlwMemoryTracker.CLEANER);
|
||||
FlwMemoryTracker._allocCPUMemory(block.size());
|
||||
return block;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void free() {
|
||||
FlwMemoryTracker.freeBlock(this);
|
||||
freeInner();
|
||||
}
|
||||
|
||||
static class CleaningAction implements Runnable {
|
||||
final long ptr;
|
||||
final long size;
|
||||
|
|
|
@ -8,9 +8,9 @@ import org.lwjgl.system.MemoryUtil;
|
|||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||
import com.jozufozu.flywheel.backend.gl.array.GlVertexArray;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||
import com.jozufozu.flywheel.util.Lazy;
|
||||
|
|
|
@ -5,9 +5,9 @@ import org.jetbrains.annotations.Nullable;
|
|||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.backend.gl.GlNumericType;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.backend.instancing.instancing.ElementBuffer;
|
||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||
|
||||
|
|
|
@ -6,24 +6,7 @@ import com.jozufozu.flywheel.backend.instancing.instancing.ElementBuffer;
|
|||
import com.jozufozu.flywheel.core.QuadConverter;
|
||||
|
||||
/**
|
||||
* A mesh that can be rendered by flywheel.
|
||||
*
|
||||
* <p>
|
||||
* It is expected that the following assertion will not fail:
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
* Mesh mesh = ...;
|
||||
* VecBuffer into = ...;
|
||||
*
|
||||
* int initial = VecBuffer.unwrap().position();
|
||||
*
|
||||
* mesh.buffer(into);
|
||||
*
|
||||
* int final = VecBuffer.unwrap().position();
|
||||
*
|
||||
* assert mesh.size() == final - initial;
|
||||
* }</pre>
|
||||
* A holder for arbitrary vertex data that can be written to memory or a vertex list.
|
||||
*/
|
||||
public interface Mesh {
|
||||
|
||||
|
@ -49,8 +32,18 @@ public interface Mesh {
|
|||
return getVertexType().byteOffset(getVertexCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Write this mesh into memory. The written data will use the format defined by {@link #getVertexType()} and the amount of
|
||||
* bytes written will be the same as the return value of {@link #size()}.
|
||||
* @param ptr The address to which data is written to.
|
||||
*/
|
||||
void write(long ptr);
|
||||
|
||||
/**
|
||||
* Write this mesh into a vertex list. Vertices with index {@literal <}0 or {@literal >=}{@link #getVertexCount()} will not be
|
||||
* modified.
|
||||
* @param vertexList The vertex list to which data is written to.
|
||||
*/
|
||||
void write(MutableVertexList vertexList);
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,6 +30,8 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
import net.minecraftforge.client.model.data.IModelData;
|
||||
|
||||
public class BakedModelBuilder {
|
||||
private static final int STARTING_CAPACITY = 64;
|
||||
|
||||
private final BakedModel bakedModel;
|
||||
private boolean shadeSeparated = true;
|
||||
private BlockAndTintGetter renderWorld;
|
||||
|
@ -96,7 +98,7 @@ public class BakedModelBuilder {
|
|||
|
||||
if (shadeSeparated) {
|
||||
ShadeSeparatedBufferFactory<BufferBuilder> bufferFactory = (renderType, shaded) -> {
|
||||
BufferBuilder buffer = new BufferBuilder(64);
|
||||
BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY);
|
||||
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
return buffer;
|
||||
};
|
||||
|
@ -111,7 +113,7 @@ public class BakedModelBuilder {
|
|||
ModelBufferingUtil.bufferSingleShadeSeparated(ModelUtil.VANILLA_RENDERER.getModelRenderer(), renderWorld, bakedModel, blockState, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelData, resultConsumer);
|
||||
} else {
|
||||
BufferFactory<BufferBuilder> bufferFactory = (renderType) -> {
|
||||
BufferBuilder buffer = new BufferBuilder(64);
|
||||
BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY);
|
||||
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
return buffer;
|
||||
};
|
||||
|
|
|
@ -28,6 +28,8 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
import net.minecraftforge.client.model.data.IModelData;
|
||||
|
||||
public class BlockModelBuilder {
|
||||
private static final int STARTING_CAPACITY = 64;
|
||||
|
||||
private final BlockState state;
|
||||
private boolean shadeSeparated = true;
|
||||
private BlockAndTintGetter renderWorld;
|
||||
|
@ -85,7 +87,7 @@ public class BlockModelBuilder {
|
|||
|
||||
if (shadeSeparated) {
|
||||
ShadeSeparatedBufferFactory<BufferBuilder> bufferFactory = (renderType, shaded) -> {
|
||||
BufferBuilder buffer = new BufferBuilder(64);
|
||||
BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY);
|
||||
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
return buffer;
|
||||
};
|
||||
|
@ -100,7 +102,7 @@ public class BlockModelBuilder {
|
|||
ModelBufferingUtil.bufferBlockShadeSeparated(ModelUtil.VANILLA_RENDERER, renderWorld, state, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelData, resultConsumer);
|
||||
} else {
|
||||
BufferFactory<BufferBuilder> bufferFactory = (renderType) -> {
|
||||
BufferBuilder buffer = new BufferBuilder(64);
|
||||
BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY);
|
||||
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
return buffer;
|
||||
};
|
||||
|
|
|
@ -31,6 +31,8 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
|
|||
import net.minecraftforge.client.model.data.IModelData;
|
||||
|
||||
public class MultiBlockModelBuilder {
|
||||
private static final int STARTING_CAPACITY = 1024;
|
||||
|
||||
private final Collection<StructureTemplate.StructureBlockInfo> blocks;
|
||||
private boolean shadeSeparated = true;
|
||||
private VertexFormat vertexFormat;
|
||||
|
@ -92,7 +94,7 @@ public class MultiBlockModelBuilder {
|
|||
|
||||
if (shadeSeparated) {
|
||||
ShadeSeparatedBufferFactory<BufferBuilder> bufferFactory = (renderType, shaded) -> {
|
||||
BufferBuilder buffer = new BufferBuilder(1024);
|
||||
BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY);
|
||||
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
return buffer;
|
||||
};
|
||||
|
@ -107,7 +109,7 @@ public class MultiBlockModelBuilder {
|
|||
ModelBufferingUtil.bufferMultiBlockShadeSeparated(blocks, ModelUtil.VANILLA_RENDERER, renderWorld, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelDataMap, resultConsumer);
|
||||
} else {
|
||||
BufferFactory<BufferBuilder> bufferFactory = (renderType) -> {
|
||||
BufferBuilder buffer = new BufferBuilder(1024);
|
||||
BufferBuilder buffer = new BufferBuilder(STARTING_CAPACITY);
|
||||
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
return buffer;
|
||||
};
|
||||
|
|
|
@ -5,12 +5,11 @@ import java.util.Collection;
|
|||
import java.util.List;
|
||||
|
||||
import org.lwjgl.opengl.GL32;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.jozufozu.flywheel.api.uniform.UniformProvider;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.backend.memory.MemoryBlock;
|
||||
import com.jozufozu.flywheel.core.ComponentRegistry;
|
||||
import com.jozufozu.flywheel.util.RenderMath;
|
||||
|
|
|
@ -56,7 +56,7 @@ public class ViewProvider extends UniformProvider {
|
|||
MemoryUtil.memPutFloat(ptr + 64, camX);
|
||||
MemoryUtil.memPutFloat(ptr + 68, camY);
|
||||
MemoryUtil.memPutFloat(ptr + 72, camZ);
|
||||
MemoryUtil.memPutInt(ptr + 76, constantAmbientLight);
|
||||
MemoryUtil.memPutInt(ptr + 80, constantAmbientLight);
|
||||
|
||||
notifier.signalChanged();
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ public class GPULightVolume extends LightVolume {
|
|||
|
||||
public void bind() {
|
||||
// just in case something goes wrong, or we accidentally call this before this volume is properly disposed of.
|
||||
if (lightData == null || lightData.capacity() == 0) return;
|
||||
if (lightData == null || lightData.size() == 0) return;
|
||||
|
||||
textureUnit.makeActive();
|
||||
glTexture.bind();
|
||||
|
@ -93,7 +93,7 @@ public class GPULightVolume extends LightVolume {
|
|||
int sizeY = box.sizeY();
|
||||
int sizeZ = box.sizeZ();
|
||||
|
||||
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, sizeX, sizeY, sizeZ, GL30.GL_RG, GL_UNSIGNED_BYTE, lightData);
|
||||
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, sizeX, sizeY, sizeZ, GL30.GL_RG, GL_UNSIGNED_BYTE, lightData.ptr());
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4 is the default
|
||||
bufferDirty = false;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.jozufozu.flywheel.light;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.backend.memory.FlwMemoryTracker;
|
||||
import com.jozufozu.flywheel.backend.memory.MemoryBlock;
|
||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
||||
|
||||
|
@ -14,13 +14,53 @@ public class LightVolume implements ImmutableBox, LightListener {
|
|||
|
||||
protected final BlockAndTintGetter level;
|
||||
protected final GridAlignedBB box = new GridAlignedBB();
|
||||
protected ByteBuffer lightData;
|
||||
protected MemoryBlock lightData;
|
||||
|
||||
public LightVolume(BlockAndTintGetter level, ImmutableBox sampleVolume) {
|
||||
this.level = level;
|
||||
this.setBox(sampleVolume);
|
||||
|
||||
this.lightData = FlwMemoryTracker.mallocBuffer(this.box.volume() * 2);
|
||||
this.lightData = MemoryBlock.malloc(this.box.volume() * 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableBox getVolume() {
|
||||
return box;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinX() {
|
||||
return box.getMinX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
return box.getMinY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinZ() {
|
||||
return box.getMinZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxX() {
|
||||
return box.getMaxX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxY() {
|
||||
return box.getMaxY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxZ() {
|
||||
return box.getMaxZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListenerInvalid() {
|
||||
return lightData == null;
|
||||
}
|
||||
|
||||
protected void setBox(ImmutableBox box) {
|
||||
|
@ -29,47 +69,143 @@ public class LightVolume implements ImmutableBox, LightListener {
|
|||
|
||||
public short getPackedLight(int x, int y, int z) {
|
||||
if (box.contains(x, y, z)) {
|
||||
return lightData.getShort(worldPosToBufferIndex(x, y, z));
|
||||
return MemoryUtil.memGetShort(worldPosToPtr(x, y, z));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getMinX() {
|
||||
return box.getMinX();
|
||||
}
|
||||
|
||||
public int getMinY() {
|
||||
return box.getMinY();
|
||||
}
|
||||
|
||||
public int getMinZ() {
|
||||
return box.getMinZ();
|
||||
}
|
||||
|
||||
public int getMaxX() {
|
||||
return box.getMaxX();
|
||||
}
|
||||
|
||||
public int getMaxY() {
|
||||
return box.getMaxY();
|
||||
}
|
||||
|
||||
public int getMaxZ() {
|
||||
return box.getMaxZ();
|
||||
}
|
||||
|
||||
public void move(ImmutableBox newSampleVolume) {
|
||||
if (lightData == null) return;
|
||||
|
||||
setBox(newSampleVolume);
|
||||
int neededCapacity = box.volume() * 2;
|
||||
if (neededCapacity > lightData.capacity()) {
|
||||
lightData = FlwMemoryTracker.reallocBuffer(lightData, neededCapacity);
|
||||
if (neededCapacity > lightData.size()) {
|
||||
lightData = lightData.realloc(neededCapacity);
|
||||
}
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely (re)populate this volume with block and sky lighting data.
|
||||
* This is expensive and should be avoided.
|
||||
*/
|
||||
public void initialize() {
|
||||
if (lightData == null) return;
|
||||
|
||||
copyLight(getVolume());
|
||||
markDirty();
|
||||
}
|
||||
|
||||
protected void markDirty() {
|
||||
// noop
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
lightData.free();
|
||||
lightData = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy all light from the world into this volume.
|
||||
*
|
||||
* @param worldVolume the region in the world to copy data from.
|
||||
*/
|
||||
public void copyLight(ImmutableBox worldVolume) {
|
||||
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
|
||||
|
||||
int xShift = box.getMinX();
|
||||
int yShift = box.getMinY();
|
||||
int zShift = box.getMinZ();
|
||||
|
||||
worldVolume.forEachContained((x, y, z) -> {
|
||||
pos.set(x, y, z);
|
||||
|
||||
int block = this.level.getBrightness(LightLayer.BLOCK, pos);
|
||||
int sky = this.level.getBrightness(LightLayer.SKY, pos);
|
||||
|
||||
writeLight(x - xShift, y - yShift, z - zShift, block, sky);
|
||||
});
|
||||
}
|
||||
|
||||
protected void writeLight(int x, int y, int z, int block, int sky) {
|
||||
byte b = (byte) ((block & 0xF) << 4);
|
||||
byte s = (byte) ((sky & 0xF) << 4);
|
||||
|
||||
long ptr = boxPosToPtr(x, y, z);
|
||||
MemoryUtil.memPutByte(ptr, b);
|
||||
MemoryUtil.memPutByte(ptr + 1, s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy block light from the world into this volume.
|
||||
*
|
||||
* @param worldVolume the region in the world to copy data from.
|
||||
*/
|
||||
public void copyBlock(ImmutableBox worldVolume) {
|
||||
var pos = new BlockPos.MutableBlockPos();
|
||||
|
||||
int xShift = box.getMinX();
|
||||
int yShift = box.getMinY();
|
||||
int zShift = box.getMinZ();
|
||||
|
||||
worldVolume.forEachContained((x, y, z) -> {
|
||||
int light = this.level.getBrightness(LightLayer.BLOCK, pos.set(x, y, z));
|
||||
|
||||
writeBlock(x - xShift, y - yShift, z - zShift, light);
|
||||
});
|
||||
}
|
||||
|
||||
protected void writeBlock(int x, int y, int z, int block) {
|
||||
byte b = (byte) ((block & 0xF) << 4);
|
||||
|
||||
MemoryUtil.memPutByte(boxPosToPtr(x, y, z), b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy sky light from the world into this volume.
|
||||
*
|
||||
* @param worldVolume the region in the world to copy data from.
|
||||
*/
|
||||
public void copySky(ImmutableBox worldVolume) {
|
||||
var pos = new BlockPos.MutableBlockPos();
|
||||
|
||||
int xShift = box.getMinX();
|
||||
int yShift = box.getMinY();
|
||||
int zShift = box.getMinZ();
|
||||
|
||||
worldVolume.forEachContained((x, y, z) -> {
|
||||
int light = this.level.getBrightness(LightLayer.SKY, pos.set(x, y, z));
|
||||
|
||||
writeSky(x - xShift, y - yShift, z - zShift, light);
|
||||
});
|
||||
}
|
||||
|
||||
protected void writeSky(int x, int y, int z, int sky) {
|
||||
byte s = (byte) ((sky & 0xF) << 4);
|
||||
|
||||
MemoryUtil.memPutByte(boxPosToPtr(x, y, z) + 1, s);
|
||||
}
|
||||
|
||||
protected long worldPosToPtr(int x, int y, int z) {
|
||||
return lightData.ptr() + worldPosToPtrOffset(x, y, z);
|
||||
}
|
||||
|
||||
protected long boxPosToPtr(int x, int y, int z) {
|
||||
return lightData.ptr() + boxPosToPtrOffset(x, y, z);
|
||||
}
|
||||
|
||||
protected int worldPosToPtrOffset(int x, int y, int z) {
|
||||
x -= box.getMinX();
|
||||
y -= box.getMinY();
|
||||
z -= box.getMinZ();
|
||||
return boxPosToPtrOffset(x, y, z);
|
||||
}
|
||||
|
||||
protected int boxPosToPtrOffset(int x, int y, int z) {
|
||||
return (x + box.sizeX() * (y + z * box.sizeY())) * 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLightUpdate(LightLayer type, ImmutableBox changedVolume) {
|
||||
if (lightData == null) return;
|
||||
|
@ -95,126 +231,4 @@ public class LightVolume implements ImmutableBox, LightListener {
|
|||
markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely (re)populate this volume with block and sky lighting data.
|
||||
* This is expensive and should be avoided.
|
||||
*/
|
||||
public void initialize() {
|
||||
if (lightData == null) return;
|
||||
|
||||
copyLight(getVolume());
|
||||
markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy block light from the world into this volume.
|
||||
*
|
||||
* @param worldVolume the region in the world to copy data from.
|
||||
*/
|
||||
public void copyBlock(ImmutableBox worldVolume) {
|
||||
var pos = new BlockPos.MutableBlockPos();
|
||||
|
||||
int xShift = box.getMinX();
|
||||
int yShift = box.getMinY();
|
||||
int zShift = box.getMinZ();
|
||||
|
||||
worldVolume.forEachContained((x, y, z) -> {
|
||||
int light = this.level.getBrightness(LightLayer.BLOCK, pos.set(x, y, z));
|
||||
|
||||
writeBlock(x - xShift, y - yShift, z - zShift, light);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy sky light from the world into this volume.
|
||||
*
|
||||
* @param worldVolume the region in the world to copy data from.
|
||||
*/
|
||||
public void copySky(ImmutableBox worldVolume) {
|
||||
var pos = new BlockPos.MutableBlockPos();
|
||||
|
||||
int xShift = box.getMinX();
|
||||
int yShift = box.getMinY();
|
||||
int zShift = box.getMinZ();
|
||||
|
||||
worldVolume.forEachContained((x, y, z) -> {
|
||||
int light = this.level.getBrightness(LightLayer.SKY, pos.set(x, y, z));
|
||||
|
||||
writeSky(x - xShift, y - yShift, z - zShift, light);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy all light from the world into this volume.
|
||||
*
|
||||
* @param worldVolume the region in the world to copy data from.
|
||||
*/
|
||||
public void copyLight(ImmutableBox worldVolume) {
|
||||
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
|
||||
|
||||
int xShift = box.getMinX();
|
||||
int yShift = box.getMinY();
|
||||
int zShift = box.getMinZ();
|
||||
|
||||
worldVolume.forEachContained((x, y, z) -> {
|
||||
pos.set(x, y, z);
|
||||
|
||||
int block = this.level.getBrightness(LightLayer.BLOCK, pos);
|
||||
int sky = this.level.getBrightness(LightLayer.SKY, pos);
|
||||
|
||||
writeLight(x - xShift, y - yShift, z - zShift, block, sky);
|
||||
});
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
FlwMemoryTracker.freeBuffer(lightData);
|
||||
lightData = null;
|
||||
}
|
||||
|
||||
protected void markDirty() {
|
||||
// noop
|
||||
}
|
||||
|
||||
protected void writeLight(int x, int y, int z, int block, int sky) {
|
||||
byte b = (byte) ((block & 0xF) << 4);
|
||||
byte s = (byte) ((sky & 0xF) << 4);
|
||||
|
||||
int i = boxPosToBufferIndex(x, y, z);
|
||||
lightData.put(i, b);
|
||||
lightData.put(i + 1, s);
|
||||
}
|
||||
|
||||
protected void writeBlock(int x, int y, int z, int block) {
|
||||
byte b = (byte) ((block & 0xF) << 4);
|
||||
|
||||
lightData.put(boxPosToBufferIndex(x, y, z), b);
|
||||
}
|
||||
|
||||
protected void writeSky(int x, int y, int z, int sky) {
|
||||
byte b = (byte) ((sky & 0xF) << 4);
|
||||
|
||||
lightData.put(boxPosToBufferIndex(x, y, z) + 1, b);
|
||||
}
|
||||
|
||||
protected int worldPosToBufferIndex(int x, int y, int z) {
|
||||
x -= box.getMinX();
|
||||
y -= box.getMinY();
|
||||
z -= box.getMinZ();
|
||||
return boxPosToBufferIndex(x, y, z);
|
||||
}
|
||||
|
||||
protected int boxPosToBufferIndex(int x, int y, int z) {
|
||||
return (x + box.sizeX() * (y + z * box.sizeY())) * 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableBox getVolume() {
|
||||
return box;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isListenerInvalid() {
|
||||
return lightData == null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,11 +25,11 @@ public class StringUtil {
|
|||
if (bytes < 1024) {
|
||||
return bytes + " B";
|
||||
} else if (bytes < 1024 * 1024) {
|
||||
return THREE_DECIMAL_PLACES.format(bytes / 1024f) + " KB";
|
||||
return THREE_DECIMAL_PLACES.format(bytes / 1024f) + " KiB";
|
||||
} else if (bytes < 1024 * 1024 * 1024) {
|
||||
return THREE_DECIMAL_PLACES.format(bytes / 1024f / 1024f) + " MB";
|
||||
return THREE_DECIMAL_PLACES.format(bytes / 1024f / 1024f) + " MiB";
|
||||
} else {
|
||||
return THREE_DECIMAL_PLACES.format(bytes / 1024f / 1024f / 1024f) + " GB";
|
||||
return THREE_DECIMAL_PLACES.format(bytes / 1024f / 1024f / 1024f) + " GiB";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue