diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java index 8be8937ad..27852a64a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java @@ -101,8 +101,7 @@ public class Backend { materialRegistry.put(name, spec); log.debug("registered material '" + name + "' with vertex size " + spec.getModelFormat() - .getStride() + " and instance size " + spec.getInstanceFormat() - .getStride()); + .getStride() + " and instance size " + spec.getInstanceType().format().getStride()); return spec; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java index 2c8762452..2ddedae40 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java @@ -3,6 +3,7 @@ package com.jozufozu.flywheel.backend.gl.buffer; import java.nio.ByteBuffer; import org.lwjgl.opengl.GL15; +import org.lwjgl.system.MemoryUtil; public abstract class MappedBuffer extends VecBuffer implements AutoCloseable { @@ -13,6 +14,10 @@ public abstract class MappedBuffer extends VecBuffer implements AutoCloseable { this.owner = owner; } + public long addr() { + return MemoryUtil.memAddress(this.internal, internal.position()); + } + protected abstract void checkAndMap(); /** @@ -43,6 +48,11 @@ public abstract class MappedBuffer extends VecBuffer implements AutoCloseable { return this; } + public int position() { + checkAndMap(); + return super.position(); + } + /** * Position this buffer relative to the 0-index in GPU memory. * diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBufferRange.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBufferRange.java index e9df6a807..47c6d764a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBufferRange.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBufferRange.java @@ -17,7 +17,6 @@ public class MappedBufferRange extends MappedBuffer { this.access = access; } - @Override public MappedBuffer position(int p) { if (p < offset || p >= offset + length) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/VecBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/VecBuffer.java index 4ec8b1590..2ece691ee 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/VecBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/VecBuffer.java @@ -48,6 +48,10 @@ public class VecBuffer { return this; } + public int position() { + return internal.position(); + } + /** * Position this buffer relative to the 0-index in GPU memory. * diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/GPUInstancer.java index bc8d05094..1e9d85dcd 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/GPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/GPUInstancer.java @@ -11,33 +11,17 @@ import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.model.IBufferedModel; import com.jozufozu.flywheel.backend.model.ModelAllocator; +import com.jozufozu.flywheel.backend.struct.StructType; +import com.jozufozu.flywheel.backend.struct.StructWriter; import com.jozufozu.flywheel.core.model.IModel; import com.jozufozu.flywheel.util.AttribUtil; -/** - * An instancer is how you interact with an instanced model. - *

- * Instanced models can have many copies, and on most systems it's very fast to draw all of the copies at once. - * There is no limit to how many copies an instanced model can have. - * Each copy is represented by an InstanceData object. - *

- *

- * When you call {@link #createInstance()} you are given an InstanceData object that you can manipulate however - * you want. The changes you make to the InstanceData object are automatically made visible, and persistent. - * Changing the position of your InstanceData object every frame means that that copy of the model will be in a - * different position in the world each frame. Setting the position of your InstanceData once and not touching it - * again means that your model will be in the same position in the world every frame. This persistence is useful - * because it means the properties of your model don't have to be re-evaluated every frame. - *

- * - * @param the data that represents a copy of the instanced model. - */ public class GPUInstancer implements Instancer { private final ModelAllocator modelAllocator; private final IModel modelData; private final VertexFormat instanceFormat; - private final IInstanceFactory factory; + private final StructType type; private IBufferedModel model; private GlVertexArray vao; @@ -52,11 +36,11 @@ public class GPUInstancer implements Instancer { boolean anyToRemove; boolean anyToUpdate; - public GPUInstancer(ModelAllocator modelAllocator, IModel model, IInstanceFactory factory, VertexFormat instanceFormat) { + public GPUInstancer(ModelAllocator modelAllocator, IModel model, StructType type) { this.modelAllocator = modelAllocator; this.modelData = model; - this.factory = factory; - this.instanceFormat = instanceFormat; + this.type = type; + this.instanceFormat = type.format(); } /** @@ -64,7 +48,9 @@ public class GPUInstancer implements Instancer { */ @Override public D createInstance() { - return _add(factory.create(this)); + D data = type.create(); + data.owner = this; + return _add(data); } /** @@ -220,12 +206,12 @@ public class GPUInstancer implements Instancer { if (length > 0) { MappedBuffer mapped = instanceVBO.getBuffer(offset, length); + StructWriter writer = type.getWriter(mapped); + dirtySet.stream() .forEach(i -> { - final D d = data.get(i); - - mapped.position(i * stride); - d.write(mapped); + writer.seek(i); + writer.write(data.get(i)); }); mapped.flush(); } @@ -255,8 +241,9 @@ public class GPUInstancer implements Instancer { instanceVBO.alloc(glBufferSize); MappedBuffer buffer = instanceVBO.getBuffer(0, glBufferSize); + StructWriter writer = type.getWriter(buffer); for (D datum : data) { - datum.write(buffer); + writer.write(datum); } buffer.flush(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/IInstanceFactory.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/IInstanceFactory.java deleted file mode 100644 index f2364392c..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/IInstanceFactory.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.jozufozu.flywheel.backend.instancing; - -public interface IInstanceFactory { - D create(Instancer owner); -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceData.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceData.java index a8c1adfa0..125ddbdeb 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceData.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceData.java @@ -1,6 +1,6 @@ package com.jozufozu.flywheel.backend.instancing; -import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; public abstract class InstanceData { @@ -9,11 +9,7 @@ public abstract class InstanceData { boolean dirty; boolean removed; - protected InstanceData(Instancer owner) { - this.owner = owner; - } - - public abstract void write(MappedBuffer buf); + public abstract void write(VecBuffer buf); public void markDirty() { owner.markDirty(this); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/Instancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/Instancer.java index 28737e143..f83de1e53 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/Instancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/Instancer.java @@ -1,5 +1,23 @@ package com.jozufozu.flywheel.backend.instancing; +/** + * An instancer is how you interact with an instanced model. + *

+ * Instanced models can have many copies, and on most systems it's very fast to draw all of the copies at once. + * There is no limit to how many copies an instanced model can have. + * Each copy is represented by an InstanceData object. + *

+ *

+ * When you call {@link #createInstance()} you are given an InstanceData object that you can manipulate however + * you want. The changes you make to the InstanceData object are automatically made visible, and persistent. + * Changing the position of your InstanceData object every frame means that that copy of the model will be in a + * different position in the world each frame. Setting the position of your InstanceData once and not touching it + * again means that your model will be in the same position in the world every frame. This persistence is useful + * because it means the properties of your model don't have to be re-evaluated every frame. + *

+ * + * @param the data that represents a copy of the instanced model. + */ public interface Instancer { /** * @return a handle to a new copy of this model. diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileEntityInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileEntityInstance.java index eb6e51fa3..957a4565f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileEntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileEntityInstance.java @@ -6,8 +6,8 @@ import com.jozufozu.flywheel.backend.instancing.ITickableInstance; import com.jozufozu.flywheel.backend.material.Material; import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.core.Materials; -import com.jozufozu.flywheel.core.materials.ModelData; -import com.jozufozu.flywheel.core.materials.OrientedData; +import com.jozufozu.flywheel.core.materials.model.ModelData; +import com.jozufozu.flywheel.core.materials.oriented.OrientedData; import com.jozufozu.flywheel.light.GridAlignedBB; import com.jozufozu.flywheel.light.ImmutableBox; diff --git a/src/main/java/com/jozufozu/flywheel/backend/material/MaterialImpl.java b/src/main/java/com/jozufozu/flywheel/backend/material/MaterialImpl.java index ad0bb535c..ce3fa98d0 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/material/MaterialImpl.java +++ b/src/main/java/com/jozufozu/flywheel/backend/material/MaterialImpl.java @@ -44,7 +44,7 @@ public class MaterialImpl implements Material { @Override public Instancer model(Object key, Supplier modelSupplier) { try { - return models.get(key, () -> new GPUInstancer<>(modelPool, modelSupplier.get(), spec.getInstanceFactory(), spec.getInstanceFormat())); + return models.get(key, () -> new GPUInstancer<>(modelPool, modelSupplier.get(), spec.getInstanceType())); } catch (ExecutionException e) { throw new RuntimeException("error creating instancer", e); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/material/MaterialSpec.java b/src/main/java/com/jozufozu/flywheel/backend/material/MaterialSpec.java index 9b3a87b5a..7cc5120ea 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/material/MaterialSpec.java +++ b/src/main/java/com/jozufozu/flywheel/backend/material/MaterialSpec.java @@ -1,8 +1,8 @@ package com.jozufozu.flywheel.backend.material; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; -import com.jozufozu.flywheel.backend.instancing.IInstanceFactory; import com.jozufozu.flywheel.backend.instancing.InstanceData; +import com.jozufozu.flywheel.backend.struct.StructType; import net.minecraft.util.ResourceLocation; @@ -12,15 +12,13 @@ public class MaterialSpec { private final ResourceLocation programSpec; private final VertexFormat modelFormat; - private final VertexFormat instanceFormat; - private final IInstanceFactory instanceFactory; + private final StructType instanceType; - public MaterialSpec(ResourceLocation name, ResourceLocation programSpec, VertexFormat modelFormat, VertexFormat instanceFormat, IInstanceFactory instanceFactory) { + public MaterialSpec(ResourceLocation name, ResourceLocation programSpec, VertexFormat modelFormat, StructType type) { this.name = name; this.programSpec = programSpec; this.modelFormat = modelFormat; - this.instanceFormat = instanceFormat; - this.instanceFactory = instanceFactory; + this.instanceType = type; } public ResourceLocation getProgramName() { @@ -31,12 +29,8 @@ public class MaterialSpec { return modelFormat; } - public VertexFormat getInstanceFormat() { - return instanceFormat; - } - - public IInstanceFactory getInstanceFactory() { - return instanceFactory; + public StructType getInstanceType() { + return instanceType; } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/struct/BasicStructType.java b/src/main/java/com/jozufozu/flywheel/backend/struct/BasicStructType.java new file mode 100644 index 000000000..0562804aa --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/struct/BasicStructType.java @@ -0,0 +1,51 @@ +package com.jozufozu.flywheel.backend.struct; + +import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; +import com.jozufozu.flywheel.backend.instancing.InstanceData; + +import net.minecraftforge.common.util.NonNullSupplier; + +public class BasicStructType implements StructType { + + private final NonNullSupplier factory; + private final VertexFormat format; + + public BasicStructType(NonNullSupplier factory, VertexFormat format) { + this.factory = factory; + this.format = format; + } + + @Override + public S create() { + return factory.get(); + } + + @Override + public VertexFormat format() { + return format; + } + + @Override + public StructWriter getWriter(VecBuffer backing) { + return new BasicWriter(backing); + } + + public class BasicWriter implements StructWriter { + private final VecBuffer buffer; + + public BasicWriter(VecBuffer buffer) { + this.buffer = buffer; + } + + @Override + public void write(S struct) { + struct.write(buffer); + } + + @Override + public void seek(int pos) { + buffer.position(pos * format.getStride()); + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/struct/BufferWriter.java b/src/main/java/com/jozufozu/flywheel/backend/struct/BufferWriter.java new file mode 100644 index 000000000..5d302f5e7 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/struct/BufferWriter.java @@ -0,0 +1,31 @@ +package com.jozufozu.flywheel.backend.struct; + +import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; + +public abstract class BufferWriter implements StructWriter { + protected final VecBuffer backingBuffer; + + protected final VertexFormat format; + protected final int stride; + + protected BufferWriter(VecBuffer backingBuffer, StructType vertexType) { + this.backingBuffer = backingBuffer; + + this.format = vertexType.format(); + this.stride = this.format.getStride(); + } + + /** + * Advances the write pointer forward by the stride of one vertex. This should always be called after a + * vertex is written. Implementations which override this should always call invoke the super implementation. + */ + protected void advance() { + + } + + @Override + public void seek(int pos) { + backingBuffer.position(pos * stride); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/struct/BufferWriterUnsafe.java b/src/main/java/com/jozufozu/flywheel/backend/struct/BufferWriterUnsafe.java new file mode 100644 index 000000000..d7b5a0917 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/struct/BufferWriterUnsafe.java @@ -0,0 +1,42 @@ +package com.jozufozu.flywheel.backend.struct; + +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; + +/** + * An unsafe {@link BufferWriter} implementation which uses direct memory operations to enable fast blitting of + * data into memory buffers. Only available on JVMs which support {@link sun.misc.Unsafe}, but generally produces much + * better optimized code than other implementations. The implementation does not check for invalid memory accesses, + * meaning that errors can corrupt process memory. + */ +public abstract class BufferWriterUnsafe extends BufferWriter { + /** + * The write pointer into the buffer storage. This is advanced by the vertex stride every time + * {@link BufferWriterUnsafe#advance()} is called. + */ + protected long writePointer; + + protected BufferWriterUnsafe(VecBuffer backingBuffer, StructType vertexType) { + super(backingBuffer, vertexType); + + acquireWritePointer(); + } + + @Override + public void seek(int pos) { + super.seek(pos); + acquireWritePointer(); + } + + @Override + protected void advance() { + this.writePointer += this.stride; + + super.advance(); + } + + private void acquireWritePointer() { + this.writePointer = MemoryUtil.memAddress(this.backingBuffer.unwrap(), this.backingBuffer.position()); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/struct/StructType.java b/src/main/java/com/jozufozu/flywheel/backend/struct/StructType.java new file mode 100644 index 000000000..74e374cdd --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/struct/StructType.java @@ -0,0 +1,13 @@ +package com.jozufozu.flywheel.backend.struct; + +import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; + +public interface StructType { + + S create(); + + VertexFormat format(); + + StructWriter getWriter(VecBuffer backing); +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/struct/StructWriter.java b/src/main/java/com/jozufozu/flywheel/backend/struct/StructWriter.java new file mode 100644 index 000000000..adc6c4cba --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/struct/StructWriter.java @@ -0,0 +1,8 @@ +package com.jozufozu.flywheel.backend.struct; + +public interface StructWriter { + + void write(S struct); + + void seek(int pos); +} diff --git a/src/main/java/com/jozufozu/flywheel/core/Materials.java b/src/main/java/com/jozufozu/flywheel/core/Materials.java index 473d9204d..6a41bdcb2 100644 --- a/src/main/java/com/jozufozu/flywheel/core/Materials.java +++ b/src/main/java/com/jozufozu/flywheel/core/Materials.java @@ -1,8 +1,11 @@ package com.jozufozu.flywheel.core; import com.jozufozu.flywheel.backend.material.MaterialSpec; -import com.jozufozu.flywheel.core.materials.ModelData; -import com.jozufozu.flywheel.core.materials.OrientedData; +import com.jozufozu.flywheel.backend.struct.StructType; +import com.jozufozu.flywheel.core.materials.model.ModelData; +import com.jozufozu.flywheel.core.materials.model.ModelType; +import com.jozufozu.flywheel.core.materials.oriented.OrientedData; +import com.jozufozu.flywheel.core.materials.oriented.OrientedType; import com.jozufozu.flywheel.event.GatherContextEvent; import net.minecraft.util.ResourceLocation; @@ -11,8 +14,11 @@ import net.minecraftforge.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) public class Materials { - public static final MaterialSpec ORIENTED = new MaterialSpec<>(Locations.ORIENTED, Programs.ORIENTED, Formats.UNLIT_MODEL, Formats.ORIENTED, OrientedData::new); - public static final MaterialSpec TRANSFORMED = new MaterialSpec<>(Locations.MODEL, Programs.TRANSFORMED, Formats.UNLIT_MODEL, Formats.TRANSFORMED, ModelData::new); + public static final StructType ORIENTED_TYPE = new OrientedType(); + public static final StructType TRANSFORMED_TYPE = new ModelType(); + + public static final MaterialSpec ORIENTED = new MaterialSpec<>(Names.ORIENTED, Programs.ORIENTED, Formats.UNLIT_MODEL, ORIENTED_TYPE); + public static final MaterialSpec TRANSFORMED = new MaterialSpec<>(Names.MODEL, Programs.TRANSFORMED, Formats.UNLIT_MODEL, TRANSFORMED_TYPE); public static void flwInit(GatherContextEvent event) { event.getBackend() @@ -21,7 +27,7 @@ public class Materials { .register(TRANSFORMED); } - public static class Locations { + public static class Names { public static final ResourceLocation MODEL = new ResourceLocation("create", "model"); public static final ResourceLocation ORIENTED = new ResourceLocation("create", "oriented"); } diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/BasicData.java b/src/main/java/com/jozufozu/flywheel/core/materials/BasicData.java index 2fc7fc285..e6e9c537a 100644 --- a/src/main/java/com/jozufozu/flywheel/core/materials/BasicData.java +++ b/src/main/java/com/jozufozu/flywheel/core/materials/BasicData.java @@ -1,22 +1,19 @@ package com.jozufozu.flywheel.core.materials; -import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.backend.instancing.InstanceData; -import com.jozufozu.flywheel.backend.instancing.Instancer; public abstract class BasicData extends InstanceData implements IFlatLight { - protected byte blockLight; - protected byte skyLight; + public byte blockLight; + public byte skyLight; - protected byte r = (byte) 0xFF; - protected byte g = (byte) 0xFF; - protected byte b = (byte) 0xFF; - protected byte a = (byte) 0xFF; - - public BasicData(Instancer owner) { - super(owner); - } + public byte r = (byte) 0xFF; + public byte g = (byte) 0xFF; + public byte b = (byte) 0xFF; + public byte a = (byte) 0xFF; @Override public BasicData setBlockLight(int blockLight) { @@ -71,7 +68,7 @@ public abstract class BasicData extends InstanceData implements IFlatLight owner) { - super(owner); - } + public float[] matrices = empty; public ModelData setTransform(MatrixStack stack) { matrices = RenderUtil.writeMatrixStack(stack); @@ -34,7 +30,7 @@ public class ModelData extends BasicData { } @Override - public void write(MappedBuffer buf) { + public void write(VecBuffer buf) { super.write(buf); buf.putFloatArray(matrices); } diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelType.java b/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelType.java new file mode 100644 index 000000000..1297a07e0 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/materials/model/ModelType.java @@ -0,0 +1,26 @@ +package com.jozufozu.flywheel.core.materials.model; + +import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; +import com.jozufozu.flywheel.backend.struct.StructType; +import com.jozufozu.flywheel.backend.struct.StructWriter; +import com.jozufozu.flywheel.core.Formats; +import com.jozufozu.flywheel.core.materials.model.writer.UnsafeModelWriter; + +public class ModelType implements StructType { + + @Override + public ModelData create() { + return new ModelData(); + } + + @Override + public VertexFormat format() { + return Formats.TRANSFORMED; + } + + @Override + public StructWriter getWriter(VecBuffer backing) { + return new UnsafeModelWriter(backing, this); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/model/writer/UnsafeModelWriter.java b/src/main/java/com/jozufozu/flywheel/core/materials/model/writer/UnsafeModelWriter.java new file mode 100644 index 000000000..ca4f1ee4a --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/materials/model/writer/UnsafeModelWriter.java @@ -0,0 +1,36 @@ +package com.jozufozu.flywheel.core.materials.model.writer; + +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; +import com.jozufozu.flywheel.backend.struct.BufferWriterUnsafe; +import com.jozufozu.flywheel.backend.struct.StructType; +import com.jozufozu.flywheel.backend.struct.BufferWriter; +import com.jozufozu.flywheel.core.materials.model.ModelData; + +public class UnsafeModelWriter extends BufferWriterUnsafe { + + public UnsafeModelWriter(VecBuffer backingBuffer, StructType vertexType) { + super(backingBuffer, vertexType); + } + + @Override + public void write(ModelData d) { + long addr = writePointer; + MemoryUtil.memPutByte(addr, d.blockLight); + MemoryUtil.memPutByte(addr + 1, d.skyLight); + MemoryUtil.memPutByte(addr + 2, d.r); + MemoryUtil.memPutByte(addr + 3, d.g); + MemoryUtil.memPutByte(addr + 4, d.b); + MemoryUtil.memPutByte(addr + 5, d.a); + + addr += 6; + + float[] matrices = d.matrices; + for (int i = 0; i < matrices.length; i++) { + MemoryUtil.memPutFloat(addr + i * 4L, matrices[i]); + } + + advance(); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/OrientedData.java b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedData.java similarity index 72% rename from src/main/java/com/jozufozu/flywheel/core/materials/OrientedData.java rename to src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedData.java index 4a3010abd..fa460e9a9 100644 --- a/src/main/java/com/jozufozu/flywheel/core/materials/OrientedData.java +++ b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedData.java @@ -1,7 +1,7 @@ -package com.jozufozu.flywheel.core.materials; +package com.jozufozu.flywheel.core.materials.oriented; -import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; -import com.jozufozu.flywheel.backend.instancing.Instancer; +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; +import com.jozufozu.flywheel.core.materials.BasicData; import com.jozufozu.flywheel.util.vec.Vec3; import net.minecraft.util.math.BlockPos; @@ -11,20 +11,16 @@ import net.minecraft.util.math.vector.Vector3f; public class OrientedData extends BasicData { - private float posX; - private float posY; - private float posZ; - private float pivotX = 0.5f; - private float pivotY = 0.5f; - private float pivotZ = 0.5f; - private float qX; - private float qY; - private float qZ; - private float qW = 1; - - public OrientedData(Instancer owner) { - super(owner); - } + public float posX; + public float posY; + public float posZ; + public float pivotX = 0.5f; + public float pivotY = 0.5f; + public float pivotZ = 0.5f; + public float qX; + public float qY; + public float qZ; + public float qW = 1; public OrientedData setPosition(BlockPos pos) { return setPosition(pos.getX(), pos.getY(), pos.getZ()); @@ -89,10 +85,19 @@ public class OrientedData extends BasicData { } @Override - public void write(MappedBuffer buf) { + public void write(VecBuffer buf) { super.write(buf); - buf.putFloatArray(new float[]{posX, posY, posZ, pivotX, pivotY, pivotZ, qX, qY, qZ, qW}); + buf.putFloat(posX); + buf.putFloat(posY); + buf.putFloat(posZ); + buf.putFloat(pivotX); + buf.putFloat(pivotY); + buf.putFloat(pivotZ); + buf.putFloat(qX); + buf.putFloat(qY); + buf.putFloat(qZ); + buf.putFloat(qW); } } diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedType.java b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedType.java new file mode 100644 index 000000000..239968079 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/OrientedType.java @@ -0,0 +1,26 @@ +package com.jozufozu.flywheel.core.materials.oriented; + +import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; +import com.jozufozu.flywheel.backend.struct.StructType; +import com.jozufozu.flywheel.backend.struct.StructWriter; +import com.jozufozu.flywheel.core.Formats; +import com.jozufozu.flywheel.core.materials.oriented.writer.UnsafeOrientedWriter; + +public class OrientedType implements StructType { + + @Override + public OrientedData create() { + return new OrientedData(); + } + + @Override + public VertexFormat format() { + return Formats.ORIENTED; + } + + @Override + public StructWriter getWriter(VecBuffer backing) { + return new UnsafeOrientedWriter(backing, this); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/materials/oriented/writer/UnsafeOrientedWriter.java b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/writer/UnsafeOrientedWriter.java new file mode 100644 index 000000000..b67ef7d0b --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/materials/oriented/writer/UnsafeOrientedWriter.java @@ -0,0 +1,38 @@ +package com.jozufozu.flywheel.core.materials.oriented.writer; + +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; +import com.jozufozu.flywheel.backend.struct.BufferWriterUnsafe; +import com.jozufozu.flywheel.backend.struct.StructType; +import com.jozufozu.flywheel.core.materials.oriented.OrientedData; + +public class UnsafeOrientedWriter extends BufferWriterUnsafe { + public UnsafeOrientedWriter(VecBuffer backingBuffer, StructType vertexType) { + super(backingBuffer, vertexType); + } + + @Override + public void write(OrientedData d) { + long addr = writePointer; + MemoryUtil.memPutByte(addr, d.blockLight); + MemoryUtil.memPutByte(addr + 1, d.skyLight); + MemoryUtil.memPutByte(addr + 2, d.r); + MemoryUtil.memPutByte(addr + 3, d.g); + MemoryUtil.memPutByte(addr + 4, d.b); + MemoryUtil.memPutByte(addr + 5, d.a); + + MemoryUtil.memPutFloat(addr + 6, d.posX); + MemoryUtil.memPutFloat(addr + 10, d.posY); + MemoryUtil.memPutFloat(addr + 14, d.posZ); + MemoryUtil.memPutFloat(addr + 18, d.pivotX); + MemoryUtil.memPutFloat(addr + 22, d.pivotY); + MemoryUtil.memPutFloat(addr + 26, d.pivotZ); + MemoryUtil.memPutFloat(addr + 30, d.qX); + MemoryUtil.memPutFloat(addr + 34, d.qY); + MemoryUtil.memPutFloat(addr + 38, d.qZ); + MemoryUtil.memPutFloat(addr + 42, d.qW); + + advance(); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java index a4a83a711..d16b71c95 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java @@ -4,7 +4,7 @@ import com.jozufozu.flywheel.backend.instancing.IDynamicInstance; import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance; import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.core.Materials; -import com.jozufozu.flywheel.core.materials.OrientedData; +import com.jozufozu.flywheel.core.materials.oriented.OrientedData; import com.jozufozu.flywheel.core.model.ModelPart; import com.jozufozu.flywheel.util.AnimationTickHolder; diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java index 7fc97ef03..3c6cb67a6 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java @@ -9,8 +9,8 @@ import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance; import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.backend.state.TextureRenderState; import com.jozufozu.flywheel.core.Materials; -import com.jozufozu.flywheel.core.materials.ModelData; -import com.jozufozu.flywheel.core.materials.OrientedData; +import com.jozufozu.flywheel.core.materials.model.ModelData; +import com.jozufozu.flywheel.core.materials.oriented.OrientedData; import com.jozufozu.flywheel.core.model.ModelPart; import com.jozufozu.flywheel.util.AnimationTickHolder; import com.jozufozu.flywheel.util.transform.MatrixTransformStack; diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java index 3568b4b09..cbc05106e 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java @@ -6,7 +6,7 @@ import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance; import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.backend.state.TextureRenderState; import com.jozufozu.flywheel.core.Materials; -import com.jozufozu.flywheel.core.materials.ModelData; +import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.core.model.IModel; import com.jozufozu.flywheel.core.model.ModelPart; import com.jozufozu.flywheel.util.AnimationTickHolder; diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java index 08c4b62c7..0ff3aaabc 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java @@ -4,7 +4,7 @@ import com.jozufozu.flywheel.backend.instancing.IDynamicInstance; import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance; import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.core.Materials; -import com.jozufozu.flywheel.core.materials.ModelData; +import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.core.model.ModelPart; import com.jozufozu.flywheel.util.AnimationTickHolder; import com.jozufozu.flywheel.util.transform.MatrixTransformStack;