Initial data/struct format refactor

- Inspired by jellysquid3's vertex sinks
 - More robust/extensible solution for data writes
This commit is contained in:
Jozufozu 2021-09-12 14:49:00 -07:00
parent c68b2bbf91
commit fbcc1f0a10
28 changed files with 385 additions and 108 deletions

View file

@ -101,8 +101,7 @@ public class Backend {
materialRegistry.put(name, spec); materialRegistry.put(name, spec);
log.debug("registered material '" + name + "' with vertex size " + spec.getModelFormat() log.debug("registered material '" + name + "' with vertex size " + spec.getModelFormat()
.getStride() + " and instance size " + spec.getInstanceFormat() .getStride() + " and instance size " + spec.getInstanceType().format().getStride());
.getStride());
return spec; return spec;
} }

View file

@ -3,6 +3,7 @@ package com.jozufozu.flywheel.backend.gl.buffer;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL15;
import org.lwjgl.system.MemoryUtil;
public abstract class MappedBuffer extends VecBuffer implements AutoCloseable { public abstract class MappedBuffer extends VecBuffer implements AutoCloseable {
@ -13,6 +14,10 @@ public abstract class MappedBuffer extends VecBuffer implements AutoCloseable {
this.owner = owner; this.owner = owner;
} }
public long addr() {
return MemoryUtil.memAddress(this.internal, internal.position());
}
protected abstract void checkAndMap(); protected abstract void checkAndMap();
/** /**
@ -43,6 +48,11 @@ public abstract class MappedBuffer extends VecBuffer implements AutoCloseable {
return this; return this;
} }
public int position() {
checkAndMap();
return super.position();
}
/** /**
* Position this buffer relative to the 0-index in GPU memory. * Position this buffer relative to the 0-index in GPU memory.
* *

View file

@ -17,7 +17,6 @@ public class MappedBufferRange extends MappedBuffer {
this.access = access; this.access = access;
} }
@Override @Override
public MappedBuffer position(int p) { public MappedBuffer position(int p) {
if (p < offset || p >= offset + length) { if (p < offset || p >= offset + length) {

View file

@ -48,6 +48,10 @@ public class VecBuffer {
return this; return this;
} }
public int position() {
return internal.position();
}
/** /**
* Position this buffer relative to the 0-index in GPU memory. * Position this buffer relative to the 0-index in GPU memory.
* *

View file

@ -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.gl.buffer.MappedBuffer;
import com.jozufozu.flywheel.backend.model.IBufferedModel; import com.jozufozu.flywheel.backend.model.IBufferedModel;
import com.jozufozu.flywheel.backend.model.ModelAllocator; 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.core.model.IModel;
import com.jozufozu.flywheel.util.AttribUtil; import com.jozufozu.flywheel.util.AttribUtil;
/**
* An instancer is how you interact with an instanced model.
* <p>
* 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.
* </p>
* <p>
* 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.
* </p>
*
* @param <D> the data that represents a copy of the instanced model.
*/
public class GPUInstancer<D extends InstanceData> implements Instancer<D> { public class GPUInstancer<D extends InstanceData> implements Instancer<D> {
private final ModelAllocator modelAllocator; private final ModelAllocator modelAllocator;
private final IModel modelData; private final IModel modelData;
private final VertexFormat instanceFormat; private final VertexFormat instanceFormat;
private final IInstanceFactory<D> factory; private final StructType<D> type;
private IBufferedModel model; private IBufferedModel model;
private GlVertexArray vao; private GlVertexArray vao;
@ -52,11 +36,11 @@ public class GPUInstancer<D extends InstanceData> implements Instancer<D> {
boolean anyToRemove; boolean anyToRemove;
boolean anyToUpdate; boolean anyToUpdate;
public GPUInstancer(ModelAllocator modelAllocator, IModel model, IInstanceFactory<D> factory, VertexFormat instanceFormat) { public GPUInstancer(ModelAllocator modelAllocator, IModel model, StructType<D> type) {
this.modelAllocator = modelAllocator; this.modelAllocator = modelAllocator;
this.modelData = model; this.modelData = model;
this.factory = factory; this.type = type;
this.instanceFormat = instanceFormat; this.instanceFormat = type.format();
} }
/** /**
@ -64,7 +48,9 @@ public class GPUInstancer<D extends InstanceData> implements Instancer<D> {
*/ */
@Override @Override
public D createInstance() { 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<D extends InstanceData> implements Instancer<D> {
if (length > 0) { if (length > 0) {
MappedBuffer mapped = instanceVBO.getBuffer(offset, length); MappedBuffer mapped = instanceVBO.getBuffer(offset, length);
StructWriter<D> writer = type.getWriter(mapped);
dirtySet.stream() dirtySet.stream()
.forEach(i -> { .forEach(i -> {
final D d = data.get(i); writer.seek(i);
writer.write(data.get(i));
mapped.position(i * stride);
d.write(mapped);
}); });
mapped.flush(); mapped.flush();
} }
@ -255,8 +241,9 @@ public class GPUInstancer<D extends InstanceData> implements Instancer<D> {
instanceVBO.alloc(glBufferSize); instanceVBO.alloc(glBufferSize);
MappedBuffer buffer = instanceVBO.getBuffer(0, glBufferSize); MappedBuffer buffer = instanceVBO.getBuffer(0, glBufferSize);
StructWriter<D> writer = type.getWriter(buffer);
for (D datum : data) { for (D datum : data) {
datum.write(buffer); writer.write(datum);
} }
buffer.flush(); buffer.flush();

View file

@ -1,5 +0,0 @@
package com.jozufozu.flywheel.backend.instancing;
public interface IInstanceFactory<D extends InstanceData> {
D create(Instancer<? super D> owner);
}

View file

@ -1,6 +1,6 @@
package com.jozufozu.flywheel.backend.instancing; 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 { public abstract class InstanceData {
@ -9,11 +9,7 @@ public abstract class InstanceData {
boolean dirty; boolean dirty;
boolean removed; boolean removed;
protected InstanceData(Instancer<?> owner) { public abstract void write(VecBuffer buf);
this.owner = owner;
}
public abstract void write(MappedBuffer buf);
public void markDirty() { public void markDirty() {
owner.markDirty(this); owner.markDirty(this);

View file

@ -1,5 +1,23 @@
package com.jozufozu.flywheel.backend.instancing; package com.jozufozu.flywheel.backend.instancing;
/**
* An instancer is how you interact with an instanced model.
* <p>
* 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.
* </p>
* <p>
* 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.
* </p>
*
* @param <D> the data that represents a copy of the instanced model.
*/
public interface Instancer<D extends InstanceData> { public interface Instancer<D extends InstanceData> {
/** /**
* @return a handle to a new copy of this model. * @return a handle to a new copy of this model.

View file

@ -6,8 +6,8 @@ import com.jozufozu.flywheel.backend.instancing.ITickableInstance;
import com.jozufozu.flywheel.backend.material.Material; import com.jozufozu.flywheel.backend.material.Material;
import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.backend.material.MaterialManager;
import com.jozufozu.flywheel.core.Materials; 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.materials.OrientedData; import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
import com.jozufozu.flywheel.light.GridAlignedBB; import com.jozufozu.flywheel.light.GridAlignedBB;
import com.jozufozu.flywheel.light.ImmutableBox; import com.jozufozu.flywheel.light.ImmutableBox;

View file

@ -44,7 +44,7 @@ public class MaterialImpl<D extends InstanceData> implements Material<D> {
@Override @Override
public Instancer<D> model(Object key, Supplier<IModel> modelSupplier) { public Instancer<D> model(Object key, Supplier<IModel> modelSupplier) {
try { 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) { } catch (ExecutionException e) {
throw new RuntimeException("error creating instancer", e); throw new RuntimeException("error creating instancer", e);
} }

View file

@ -1,8 +1,8 @@
package com.jozufozu.flywheel.backend.material; package com.jozufozu.flywheel.backend.material;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; 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.instancing.InstanceData;
import com.jozufozu.flywheel.backend.struct.StructType;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
@ -12,15 +12,13 @@ public class MaterialSpec<D extends InstanceData> {
private final ResourceLocation programSpec; private final ResourceLocation programSpec;
private final VertexFormat modelFormat; private final VertexFormat modelFormat;
private final VertexFormat instanceFormat; private final StructType<D> instanceType;
private final IInstanceFactory<D> instanceFactory;
public MaterialSpec(ResourceLocation name, ResourceLocation programSpec, VertexFormat modelFormat, VertexFormat instanceFormat, IInstanceFactory<D> instanceFactory) { public MaterialSpec(ResourceLocation name, ResourceLocation programSpec, VertexFormat modelFormat, StructType<D> type) {
this.name = name; this.name = name;
this.programSpec = programSpec; this.programSpec = programSpec;
this.modelFormat = modelFormat; this.modelFormat = modelFormat;
this.instanceFormat = instanceFormat; this.instanceType = type;
this.instanceFactory = instanceFactory;
} }
public ResourceLocation getProgramName() { public ResourceLocation getProgramName() {
@ -31,12 +29,8 @@ public class MaterialSpec<D extends InstanceData> {
return modelFormat; return modelFormat;
} }
public VertexFormat getInstanceFormat() { public StructType<D> getInstanceType() {
return instanceFormat; return instanceType;
}
public IInstanceFactory<D> getInstanceFactory() {
return instanceFactory;
} }
} }

View file

@ -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<S extends InstanceData> implements StructType<S> {
private final NonNullSupplier<S> factory;
private final VertexFormat format;
public BasicStructType(NonNullSupplier<S> 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<S> getWriter(VecBuffer backing) {
return new BasicWriter(backing);
}
public class BasicWriter implements StructWriter<S> {
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());
}
}
}

View file

@ -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<S> implements StructWriter<S> {
protected final VecBuffer backingBuffer;
protected final VertexFormat format;
protected final int stride;
protected BufferWriter(VecBuffer backingBuffer, StructType<S> 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);
}
}

View file

@ -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<S> extends BufferWriter<S> {
/**
* 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<S> 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());
}
}

View file

@ -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> {
S create();
VertexFormat format();
StructWriter<S> getWriter(VecBuffer backing);
}

View file

@ -0,0 +1,8 @@
package com.jozufozu.flywheel.backend.struct;
public interface StructWriter<S> {
void write(S struct);
void seek(int pos);
}

View file

@ -1,8 +1,11 @@
package com.jozufozu.flywheel.core; package com.jozufozu.flywheel.core;
import com.jozufozu.flywheel.backend.material.MaterialSpec; import com.jozufozu.flywheel.backend.material.MaterialSpec;
import com.jozufozu.flywheel.core.materials.ModelData; import com.jozufozu.flywheel.backend.struct.StructType;
import com.jozufozu.flywheel.core.materials.OrientedData; 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 com.jozufozu.flywheel.event.GatherContextEvent;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
@ -11,8 +14,11 @@ import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public class Materials { public class Materials {
public static final MaterialSpec<OrientedData> ORIENTED = new MaterialSpec<>(Locations.ORIENTED, Programs.ORIENTED, Formats.UNLIT_MODEL, Formats.ORIENTED, OrientedData::new); public static final StructType<OrientedData> ORIENTED_TYPE = new OrientedType();
public static final MaterialSpec<ModelData> TRANSFORMED = new MaterialSpec<>(Locations.MODEL, Programs.TRANSFORMED, Formats.UNLIT_MODEL, Formats.TRANSFORMED, ModelData::new); public static final StructType<ModelData> TRANSFORMED_TYPE = new ModelType();
public static final MaterialSpec<OrientedData> ORIENTED = new MaterialSpec<>(Names.ORIENTED, Programs.ORIENTED, Formats.UNLIT_MODEL, ORIENTED_TYPE);
public static final MaterialSpec<ModelData> TRANSFORMED = new MaterialSpec<>(Names.MODEL, Programs.TRANSFORMED, Formats.UNLIT_MODEL, TRANSFORMED_TYPE);
public static void flwInit(GatherContextEvent event) { public static void flwInit(GatherContextEvent event) {
event.getBackend() event.getBackend()
@ -21,7 +27,7 @@ public class Materials {
.register(TRANSFORMED); .register(TRANSFORMED);
} }
public static class Locations { public static class Names {
public static final ResourceLocation MODEL = new ResourceLocation("create", "model"); public static final ResourceLocation MODEL = new ResourceLocation("create", "model");
public static final ResourceLocation ORIENTED = new ResourceLocation("create", "oriented"); public static final ResourceLocation ORIENTED = new ResourceLocation("create", "oriented");
} }

View file

@ -1,22 +1,19 @@
package com.jozufozu.flywheel.core.materials; 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.InstanceData;
import com.jozufozu.flywheel.backend.instancing.Instancer;
public abstract class BasicData extends InstanceData implements IFlatLight<BasicData> { public abstract class BasicData extends InstanceData implements IFlatLight<BasicData> {
protected byte blockLight; public byte blockLight;
protected byte skyLight; public byte skyLight;
protected byte r = (byte) 0xFF; public byte r = (byte) 0xFF;
protected byte g = (byte) 0xFF; public byte g = (byte) 0xFF;
protected byte b = (byte) 0xFF; public byte b = (byte) 0xFF;
protected byte a = (byte) 0xFF; public byte a = (byte) 0xFF;
public BasicData(Instancer<?> owner) {
super(owner);
}
@Override @Override
public BasicData setBlockLight(int blockLight) { public BasicData setBlockLight(int blockLight) {
@ -71,7 +68,7 @@ public abstract class BasicData extends InstanceData implements IFlatLight<Basic
} }
@Override @Override
public void write(MappedBuffer buf) { public void write(VecBuffer buf) {
buf.putByteArray(new byte[]{blockLight, skyLight, r, g, b, a}); buf.putByteArray(new byte[]{blockLight, skyLight, r, g, b, a});
} }
} }

View file

@ -1,18 +1,14 @@
package com.jozufozu.flywheel.core.materials; package com.jozufozu.flywheel.core.materials.model;
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
import com.jozufozu.flywheel.backend.instancing.Instancer; import com.jozufozu.flywheel.core.materials.BasicData;
import com.jozufozu.flywheel.util.RenderUtil; import com.jozufozu.flywheel.util.RenderUtil;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
public class ModelData extends BasicData { public class ModelData extends BasicData {
private static final float[] empty = new float[25]; private static final float[] empty = new float[25];
private float[] matrices = empty; public float[] matrices = empty;
public ModelData(Instancer<?> owner) {
super(owner);
}
public ModelData setTransform(MatrixStack stack) { public ModelData setTransform(MatrixStack stack) {
matrices = RenderUtil.writeMatrixStack(stack); matrices = RenderUtil.writeMatrixStack(stack);
@ -34,7 +30,7 @@ public class ModelData extends BasicData {
} }
@Override @Override
public void write(MappedBuffer buf) { public void write(VecBuffer buf) {
super.write(buf); super.write(buf);
buf.putFloatArray(matrices); buf.putFloatArray(matrices);
} }

View file

@ -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<ModelData> {
@Override
public ModelData create() {
return new ModelData();
}
@Override
public VertexFormat format() {
return Formats.TRANSFORMED;
}
@Override
public StructWriter<ModelData> getWriter(VecBuffer backing) {
return new UnsafeModelWriter(backing, this);
}
}

View file

@ -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<ModelData> {
public UnsafeModelWriter(VecBuffer backingBuffer, StructType<ModelData> 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();
}
}

View file

@ -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.gl.buffer.VecBuffer;
import com.jozufozu.flywheel.backend.instancing.Instancer; import com.jozufozu.flywheel.core.materials.BasicData;
import com.jozufozu.flywheel.util.vec.Vec3; import com.jozufozu.flywheel.util.vec.Vec3;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -11,20 +11,16 @@ import net.minecraft.util.math.vector.Vector3f;
public class OrientedData extends BasicData { public class OrientedData extends BasicData {
private float posX; public float posX;
private float posY; public float posY;
private float posZ; public float posZ;
private float pivotX = 0.5f; public float pivotX = 0.5f;
private float pivotY = 0.5f; public float pivotY = 0.5f;
private float pivotZ = 0.5f; public float pivotZ = 0.5f;
private float qX; public float qX;
private float qY; public float qY;
private float qZ; public float qZ;
private float qW = 1; public float qW = 1;
public OrientedData(Instancer<?> owner) {
super(owner);
}
public OrientedData setPosition(BlockPos pos) { public OrientedData setPosition(BlockPos pos) {
return setPosition(pos.getX(), pos.getY(), pos.getZ()); return setPosition(pos.getX(), pos.getY(), pos.getZ());
@ -89,10 +85,19 @@ public class OrientedData extends BasicData {
} }
@Override @Override
public void write(MappedBuffer buf) { public void write(VecBuffer buf) {
super.write(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);
} }
} }

View file

@ -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<OrientedData> {
@Override
public OrientedData create() {
return new OrientedData();
}
@Override
public VertexFormat format() {
return Formats.ORIENTED;
}
@Override
public StructWriter<OrientedData> getWriter(VecBuffer backing) {
return new UnsafeOrientedWriter(backing, this);
}
}

View file

@ -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<OrientedData> {
public UnsafeOrientedWriter(VecBuffer backingBuffer, StructType<OrientedData> 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();
}
}

View file

@ -4,7 +4,7 @@ import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance; import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.backend.material.MaterialManager;
import com.jozufozu.flywheel.core.Materials; 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.core.model.ModelPart;
import com.jozufozu.flywheel.util.AnimationTickHolder; import com.jozufozu.flywheel.util.AnimationTickHolder;

View file

@ -9,8 +9,8 @@ import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.backend.material.MaterialManager;
import com.jozufozu.flywheel.backend.state.TextureRenderState; import com.jozufozu.flywheel.backend.state.TextureRenderState;
import com.jozufozu.flywheel.core.Materials; 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.materials.OrientedData; import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
import com.jozufozu.flywheel.core.model.ModelPart; import com.jozufozu.flywheel.core.model.ModelPart;
import com.jozufozu.flywheel.util.AnimationTickHolder; import com.jozufozu.flywheel.util.AnimationTickHolder;
import com.jozufozu.flywheel.util.transform.MatrixTransformStack; import com.jozufozu.flywheel.util.transform.MatrixTransformStack;

View file

@ -6,7 +6,7 @@ import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.backend.material.MaterialManager;
import com.jozufozu.flywheel.backend.state.TextureRenderState; import com.jozufozu.flywheel.backend.state.TextureRenderState;
import com.jozufozu.flywheel.core.Materials; 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.IModel;
import com.jozufozu.flywheel.core.model.ModelPart; import com.jozufozu.flywheel.core.model.ModelPart;
import com.jozufozu.flywheel.util.AnimationTickHolder; import com.jozufozu.flywheel.util.AnimationTickHolder;

View file

@ -4,7 +4,7 @@ import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance; import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.backend.material.MaterialManager;
import com.jozufozu.flywheel.core.Materials; 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.core.model.ModelPart;
import com.jozufozu.flywheel.util.AnimationTickHolder; import com.jozufozu.flywheel.util.AnimationTickHolder;
import com.jozufozu.flywheel.util.transform.MatrixTransformStack; import com.jozufozu.flywheel.util.transform.MatrixTransformStack;