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 super D> 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;