Finally safe vertex formats

- true to false for Pepper
 - IBufferedModel -> BufferedModel
 - VertexFormat -> BufferLayout
 - Use ImmutableList in BufferLayout
 - LayoutItem naming consistency
 - Try to reduce usage of raw BufferLayouts
 - Move vertex interfaces to api package
 - #createWriter and #createReader in VertexType
 - Some documentation
This commit is contained in:
Jozufozu 2021-12-22 02:45:45 -08:00
parent 42365def02
commit ede2ba8776
50 changed files with 599 additions and 433 deletions

View file

@ -1,6 +1,6 @@
package com.jozufozu.flywheel.api.struct;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.core.layout.BufferLayout;
/**
* A StructType contains metadata for a specific instance struct that Flywheel can interface with.
@ -9,13 +9,13 @@ import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
public interface StructType<S> {
/**
* @return A new, zeroed instance of the struct.
* @return A new, zeroed instance of S.
*/
S create();
/**
* @return The format descriptor of the struct type.
* @return The layout of S when buffered.
*/
VertexFormat format();
BufferLayout getLayout();
}

View file

@ -1,5 +1,14 @@
package com.jozufozu.flywheel.core.vertex;
package com.jozufozu.flywheel.api.vertex;
/**
* A read only view of a vertex buffer.
*
* <p>
* VertexList assumes nothing about the layout of the vertices. Implementations should feel free to return constants
* for values that are unused in their layout.
* </p>
* TODO: more flexible elements?
*/
public interface VertexList {
float getX(int index);

View file

@ -0,0 +1,42 @@
package com.jozufozu.flywheel.api.vertex;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.core.layout.BufferLayout;
/**
* A vertex type containing metadata about a specific vertex layout.
*/
public interface VertexType {
/**
* The layout of this type of vertex when buffered.
*/
BufferLayout getLayout();
/**
* Create a writer backed by the given ByteBuffer.
*
* <p>
* Implementors are encouraged to override the return type for ergonomics.
* </p>
*/
VertexWriter createWriter(ByteBuffer buffer);
/**
* Create a view of the given ByteBuffer as if it were already filled with vertices.
*
* <p>
* Implementors are encouraged to override the return type for ergonomics.
* </p>
*/
VertexList createReader(ByteBuffer buffer, int vertexCount);
default int getStride() {
return getLayout().getStride();
}
default int byteOffset(int vertexIndex) {
return getStride() * vertexIndex;
}
}

View file

@ -0,0 +1,15 @@
package com.jozufozu.flywheel.api.vertex;
public interface VertexWriter {
void writeVertex(VertexList list, int index);
void seekToVertex(int vertex);
VertexList intoReader();
default void writeVertexList(VertexList list) {
for (int i = 0; i < list.getVertexCount(); i++) {
this.writeVertex(list, i);
}
}
}

View file

@ -1,5 +1,5 @@
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
package com.jozufozu.flywheel.backend.gl.attrib;
package com.jozufozu.flywheel.api.vertex;
import javax.annotation.ParametersAreNonnullByDefault;

View file

@ -102,7 +102,7 @@ public class Backend {
}
materialRegistry.put(name, spec);
log.debug("registered material '" + name + "' with instance size " + spec.format().getStride());
log.debug("registered material '" + name + "' with instance size " + spec.getLayout().getStride());
return spec;
}

View file

@ -1,21 +0,0 @@
package com.jozufozu.flywheel.backend.gl.attrib;
import com.jozufozu.flywheel.backend.gl.GlNumericType;
public class CommonAttributes {
public static final VertexAttribSpec VEC4 = new VertexAttribSpec(GlNumericType.FLOAT, 4);
public static final VertexAttribSpec VEC3 = new VertexAttribSpec(GlNumericType.FLOAT, 3);
public static final VertexAttribSpec VEC2 = new VertexAttribSpec(GlNumericType.FLOAT, 2);
public static final VertexAttribSpec FLOAT = new VertexAttribSpec(GlNumericType.FLOAT, 1);
public static final VertexAttribSpec QUATERNION = new VertexAttribSpec(GlNumericType.FLOAT, 4);
public static final VertexAttribSpec NORMAL = new VertexAttribSpec(GlNumericType.BYTE, 3, true);
public static final VertexAttribSpec UV = new VertexAttribSpec(GlNumericType.FLOAT, 2);
public static final VertexAttribSpec RGBA = new VertexAttribSpec(GlNumericType.UBYTE, 4, true);
public static final VertexAttribSpec RGB = new VertexAttribSpec(GlNumericType.UBYTE, 3, true);
public static final VertexAttribSpec LIGHT = new VertexAttribSpec(GlNumericType.UBYTE, 2, true);
public static final VertexAttribSpec NORMALIZED_BYTE = new VertexAttribSpec(GlNumericType.BYTE, 1, true);
}

View file

@ -1,61 +0,0 @@
package com.jozufozu.flywheel.backend.gl.attrib;
import java.util.ArrayList;
import java.util.Collections;
public class VertexFormat {
private final ArrayList<IAttribSpec> allAttributes;
private final int numAttributes;
private final int stride;
public VertexFormat(ArrayList<IAttribSpec> allAttributes) {
this.allAttributes = allAttributes;
int numAttributes = 0, stride = 0;
for (IAttribSpec spec : allAttributes) {
numAttributes += spec.getAttributeCount();
stride += spec.getSize();
}
this.numAttributes = numAttributes;
this.stride = stride;
}
public int getAttributeCount() {
return numAttributes;
}
public int getStride() {
return stride;
}
public void vertexAttribPointers(int index) {
int offset = 0;
for (IAttribSpec spec : this.allAttributes) {
spec.vertexAttribPointer(stride, index, offset);
index += spec.getAttributeCount();
offset += spec.getSize();
}
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private final ArrayList<IAttribSpec> allAttributes = new ArrayList<>();
public Builder() {
}
public Builder addAttributes(IAttribSpec... attributes) {
Collections.addAll(allAttributes, attributes);
return this;
}
public VertexFormat build() {
return new VertexFormat(allAttributes);
}
}
}

View file

@ -11,14 +11,14 @@ import com.jozufozu.flywheel.core.model.Model;
public abstract class AbstractInstancer<D extends InstanceData> implements Instancer<D> {
protected final Supplier<D> type;
protected final Supplier<D> factory;
protected final Model modelData;
protected final ArrayList<D> data = new ArrayList<>();
protected boolean anyToRemove;
protected AbstractInstancer(Supplier<D> type, Model modelData) {
this.type = type;
protected AbstractInstancer(Supplier<D> factory, Model modelData) {
this.factory = factory;
this.modelData = modelData;
}
@ -27,7 +27,7 @@ public abstract class AbstractInstancer<D extends InstanceData> implements Insta
*/
@Override
public D createInstance() {
return _add(type.get());
return _add(factory.get());
}
/**

View file

@ -1,21 +1,18 @@
package com.jozufozu.flywheel.backend.instancing.instancing;
import java.util.BitSet;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.InstanceData;
import com.jozufozu.flywheel.api.struct.Instanced;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.struct.StructWriter;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.core.layout.BufferLayout;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
import com.jozufozu.flywheel.backend.gl.error.GlError;
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
import com.jozufozu.flywheel.backend.model.IBufferedModel;
import com.jozufozu.flywheel.backend.model.BufferedModel;
import com.jozufozu.flywheel.backend.model.ModelAllocator;
import com.jozufozu.flywheel.core.model.Model;
import com.jozufozu.flywheel.util.AttribUtil;
@ -23,10 +20,10 @@ import com.jozufozu.flywheel.util.AttribUtil;
public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
private final ModelAllocator modelAllocator;
private final VertexFormat instanceFormat;
private final BufferLayout instanceFormat;
private final Instanced<D> instancedType;
private IBufferedModel model;
private BufferedModel model;
private GlVertexArray vao;
private GlBuffer instanceVBO;
private int glBufferSize = -1;
@ -39,7 +36,7 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
public GPUInstancer(Instanced<D> type, Model model, ModelAllocator modelAllocator) {
super(type::create, model);
this.modelAllocator = modelAllocator;
this.instanceFormat = type.format();
this.instanceFormat = type.getLayout();
instancedType = type;
}

View file

@ -1,90 +1,41 @@
package com.jozufozu.flywheel.backend.model;
import static org.lwjgl.opengl.GL11.glDrawArrays;
import com.jozufozu.flywheel.core.layout.BufferLayout;
import com.jozufozu.flywheel.api.vertex.VertexType;
import org.lwjgl.opengl.GL31;
public interface BufferedModel {
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
import com.jozufozu.flywheel.core.model.Model;
import com.jozufozu.flywheel.util.AttribUtil;
VertexType getType();
public class BufferedModel implements IBufferedModel {
protected final Model model;
protected final GlPrimitive primitiveMode;
protected GlBuffer vbo;
protected boolean deleted;
public BufferedModel(GlPrimitive primitiveMode, Model model) {
this.model = model;
this.primitiveMode = primitiveMode;
vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER);
vbo.bind();
// allocate the buffer on the gpu
vbo.alloc(model.size());
// mirror it in system memory so we can write to it, and upload our model.
try (MappedBuffer buffer = vbo.getBuffer(0, model.size())) {
model.getType().copyInto(buffer.unwrap(), model.getReader());
} catch (Exception e) {
Flywheel.log.error(String.format("Error uploading model '%s':", model.name()), e);
}
vbo.unbind();
}
public boolean isDeleted() {
return deleted;
}
public VertexFormat getFormat() {
return model.format();
}
public int getVertexCount() {
return model.vertexCount();
}
int getVertexCount();
/**
* The VBO/VAO should be bound externally.
*/
public void setupState() {
vbo.bind();
AttribUtil.enableArrays(getAttributeCount());
getFormat().vertexAttribPointers(0);
}
void setupState();
public void clearState() {
AttribUtil.disableArrays(getAttributeCount());
vbo.unbind();
}
void clearState();
public void drawCall() {
glDrawArrays(primitiveMode.glEnum, 0, getVertexCount());
}
void drawCall();
/**
* Draws many instances of this model, assuming the appropriate state is already bound.
*/
public void drawInstances(int instanceCount) {
if (!valid()) return;
void drawInstances(int instanceCount);
GL31.glDrawArraysInstanced(primitiveMode.glEnum, 0, getVertexCount(), instanceCount);
boolean isDeleted();
void delete();
default BufferLayout getFormat() {
return getType().getLayout();
}
public void delete() {
if (deleted) return;
default boolean valid() {
return getVertexCount() > 0 && !isDeleted();
}
deleted = true;
vbo.delete();
default int getAttributeCount() {
return getFormat().getAttributeCount();
}
}

View file

@ -1,36 +0,0 @@
package com.jozufozu.flywheel.backend.model;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
public interface IBufferedModel {
VertexFormat getFormat();
int getVertexCount();
/**
* The VBO/VAO should be bound externally.
*/
void setupState();
void clearState();
void drawCall();
/**
* Draws many instances of this model, assuming the appropriate state is already bound.
*/
void drawInstances(int instanceCount);
boolean isDeleted();
void delete();
default boolean valid() {
return getVertexCount() > 0 && !isDeleted();
}
default int getAttributeCount() {
return getFormat().getAttributeCount();
}
}

View file

@ -7,7 +7,7 @@ public class ImmediateAllocator implements ModelAllocator {
public static final ImmediateAllocator INSTANCE = new ImmediateAllocator();
@Override
public IBufferedModel alloc(Model model, Callback allocationCallback) {
public BufferedModel alloc(Model model, Callback allocationCallback) {
IndexedModel out = new IndexedModel(model);
allocationCallback.onAlloc(out);
return out;

View file

@ -11,7 +11,7 @@ import com.jozufozu.flywheel.core.model.Model;
*
* <br><em>This should be favored over a normal BufferedModel.</em>
*/
public class IndexedModel extends BufferedModel {
public class IndexedModel extends VBOModel {
protected ElementBuffer ebo;

View file

@ -9,10 +9,10 @@ public interface ModelAllocator {
* @param model The model to allocate.
* @return A handle to the allocated model.
*/
IBufferedModel alloc(Model model, Callback allocationCallback);
BufferedModel alloc(Model model, Callback allocationCallback);
@FunctionalInterface
interface Callback {
void onAlloc(IBufferedModel arenaModel);
void onAlloc(BufferedModel arenaModel);
}
}

View file

@ -1,6 +1,5 @@
package com.jozufozu.flywheel.backend.model;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
@ -8,13 +7,13 @@ import org.lwjgl.opengl.GL32;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
import com.jozufozu.flywheel.core.model.Model;
import com.jozufozu.flywheel.core.vertex.VertexType;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.api.vertex.VertexWriter;
import com.jozufozu.flywheel.util.AttribUtil;
public class ModelPool implements ModelAllocator {
@ -118,13 +117,13 @@ public class ModelPool implements ModelAllocator {
private void uploadAll() {
try (MappedBuffer buffer = vbo.getBuffer(0, bufferSize)) {
ByteBuffer buf = buffer.unwrap();
VertexWriter writer = vertexType.createWriter(buffer.unwrap());
int vertices = 0;
for (PooledModel model : models) {
model.first = vertices;
buffer(buf, model);
buffer(writer, model);
vertices += model.getVertexCount();
}
@ -136,9 +135,9 @@ public class ModelPool implements ModelAllocator {
private void uploadPending() {
try (MappedBuffer buffer = vbo.getBuffer(0, bufferSize)) {
ByteBuffer buf = buffer.unwrap();
VertexWriter writer = vertexType.createWriter(buffer.unwrap());
for (PooledModel model : pendingUpload) {
buffer(buf, model);
buffer(writer, model);
}
pendingUpload.clear();
} catch (Exception e) {
@ -146,10 +145,9 @@ public class ModelPool implements ModelAllocator {
}
}
private void buffer(ByteBuffer buf, PooledModel model) {
int pos = model.first * vertexType.getStride();
buf.position(pos);
vertexType.copyInto(buf, model.model.getReader());
private void buffer(VertexWriter writer, PooledModel model) {
writer.seekToVertex(model.first);
writer.writeVertexList(model.model.getReader());
if (model.callback != null) model.callback.onAlloc(model);
}
@ -161,7 +159,7 @@ public class ModelPool implements ModelAllocator {
vbo.delete();
}
public class PooledModel implements IBufferedModel {
public class PooledModel implements BufferedModel {
private final ElementBuffer ebo;
private Callback callback;
@ -178,8 +176,8 @@ public class ModelPool implements ModelAllocator {
}
@Override
public VertexFormat getFormat() {
return model.format();
public VertexType getType() {
return ModelPool.this.vertexType;
}
@Override
@ -192,7 +190,7 @@ public class ModelPool implements ModelAllocator {
vbo.bind();
ebo.bind();
AttribUtil.enableArrays(getAttributeCount());
getFormat().vertexAttribPointers(0);
ModelPool.this.vertexType.getLayout().vertexAttribPointers(0);
}
@Override

View file

@ -7,7 +7,7 @@ import com.jozufozu.flywheel.core.model.Model;
public class ModelRenderer {
protected Supplier<Model> modelSupplier;
protected IBufferedModel model;
protected BufferedModel model;
protected boolean initialized;

View file

@ -0,0 +1,91 @@
package com.jozufozu.flywheel.backend.model;
import static org.lwjgl.opengl.GL11.glDrawArrays;
import org.lwjgl.opengl.GL31;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
import com.jozufozu.flywheel.core.model.Model;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.util.AttribUtil;
public class VBOModel implements BufferedModel {
protected final Model model;
protected final GlPrimitive primitiveMode;
protected GlBuffer vbo;
protected boolean deleted;
public VBOModel(GlPrimitive primitiveMode, Model model) {
this.model = model;
this.primitiveMode = primitiveMode;
vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER);
vbo.bind();
// allocate the buffer on the gpu
vbo.alloc(model.size());
// mirror it in system memory so we can write to it, and upload our model.
try (MappedBuffer buffer = vbo.getBuffer(0, model.size())) {
model.writeInto(buffer.unwrap());
} catch (Exception e) {
Flywheel.log.error(String.format("Error uploading model '%s':", model.name()), e);
}
vbo.unbind();
}
public boolean isDeleted() {
return deleted;
}
@Override
public VertexType getType() {
return model.getType();
}
public int getVertexCount() {
return model.vertexCount();
}
/**
* The VBO/VAO should be bound externally.
*/
public void setupState() {
vbo.bind();
AttribUtil.enableArrays(getAttributeCount());
getFormat().vertexAttribPointers(0);
}
public void clearState() {
AttribUtil.disableArrays(getAttributeCount());
vbo.unbind();
}
public void drawCall() {
glDrawArrays(primitiveMode.glEnum, 0, getVertexCount());
}
/**
* Draws many instances of this model, assuming the appropriate state is already bound.
*/
public void drawInstances(int instanceCount) {
if (!valid()) return;
GL31.glDrawArraysInstanced(primitiveMode.glEnum, 0, getVertexCount(), instanceCount);
}
public void delete() {
if (deleted) return;
deleted = true;
vbo.delete();
}
}

View file

@ -2,20 +2,17 @@ package com.jozufozu.flywheel.backend.struct;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.struct.StructWriter;
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();
this.stride = vertexType.getLayout().getStride();
}
@Override
@ -36,6 +33,6 @@ public abstract class BufferWriter<S> implements StructWriter<S> {
@Override
public void seek(int pos) {
backingBuffer.position(pos * stride);
backingBuffer.position(pos * stride);
}
}

View file

@ -2,17 +2,17 @@ package com.jozufozu.flywheel.core.hardcoded;
import java.util.List;
import com.jozufozu.flywheel.core.Formats;
import com.jozufozu.flywheel.core.model.Model;
import com.jozufozu.flywheel.core.vertex.VertexList;
import com.jozufozu.flywheel.core.vertex.PosTexNormalVertexListUnsafe;
import com.jozufozu.flywheel.core.vertex.PosTexNormalWriter;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe;
import com.mojang.blaze3d.platform.MemoryTracker;
public class ModelPart implements Model {
private final int vertices;
private final String name;
private final PosTexNormalVertexListUnsafe reader;
private final VertexList reader;
public ModelPart(List<PartBuilder.CuboidBuilder> cuboids, String name) {
this.name = name;
@ -25,7 +25,7 @@ public class ModelPart implements Model {
this.vertices = vertices;
}
PosTexNormalWriter writer = new PosTexNormalWriter(MemoryTracker.create(size()));
PosTexNormalWriterUnsafe writer = Formats.POS_TEX_NORMAL.createWriter(MemoryTracker.create(size()));
for (PartBuilder.CuboidBuilder cuboid : cuboids) {
cuboid.buffer(writer);
}

View file

@ -5,7 +5,7 @@ import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import com.jozufozu.flywheel.core.vertex.PosTexNormalWriter;
import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe;
import com.mojang.math.Matrix3f;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
@ -160,7 +160,7 @@ public class PartBuilder {
return visibleFaces.size() * 4;
}
public void buffer(PosTexNormalWriter buffer) {
public void buffer(PosTexNormalWriterUnsafe buffer) {
float sizeX = posX2 - posX1;
float sizeY = posY2 - posY1;
@ -235,7 +235,7 @@ public class PartBuilder {
}
}
public void quad(PosTexNormalWriter buffer, Vector3f[] vertices, float minU, float minV, float maxU, float maxV, Vector3f normal) {
public void quad(PosTexNormalWriterUnsafe buffer, Vector3f[] vertices, float minU, float minV, float maxU, float maxV, Vector3f normal) {
buffer.putVertex(vertices[0].x(), vertices[0].y(), vertices[0].z(), normal.x(), normal.y(), normal.z(), maxU, minV);
buffer.putVertex(vertices[1].x(), vertices[1].y(), vertices[1].z(), normal.x(), normal.y(), normal.z(), minU, minV);
buffer.putVertex(vertices[2].x(), vertices[2].y(), vertices[2].z(), normal.x(), normal.y(), normal.z(), minU, maxV);

View file

@ -0,0 +1,6 @@
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
package com.jozufozu.flywheel.core.hardcoded;
import javax.annotation.ParametersAreNonnullByDefault;
import net.minecraft.MethodsReturnNonnullByDefault;

View file

@ -0,0 +1,74 @@
package com.jozufozu.flywheel.core.layout;
import java.util.List;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.api.vertex.VertexType;
/**
* Classic Vertex Format struct with a clever name.
*
* <p>
* Used for vertices and instance. Describes the layout of a datatype in a buffer object.
* </p>
*
* @see com.jozufozu.flywheel.api.struct.StructType
* @see VertexType
*/
public class BufferLayout {
private final List<LayoutItem> allAttributes;
private final int numAttributes;
private final int stride;
public BufferLayout(List<LayoutItem> allAttributes) {
this.allAttributes = allAttributes;
int numAttributes = 0, stride = 0;
for (LayoutItem spec : allAttributes) {
numAttributes += spec.getAttributeCount();
stride += spec.getSize();
}
this.numAttributes = numAttributes;
this.stride = stride;
}
public int getAttributeCount() {
return numAttributes;
}
public int getStride() {
return stride;
}
public void vertexAttribPointers(int index) {
int offset = 0;
for (LayoutItem spec : this.allAttributes) {
spec.vertexAttribPointer(stride, index, offset);
index += spec.getAttributeCount();
offset += spec.getSize();
}
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private final ImmutableList.Builder<LayoutItem> allItems;
public Builder() {
allItems = ImmutableList.builder();
}
public Builder addItems(LayoutItem... attributes) {
allItems.add(attributes);
return this;
}
public BufferLayout build() {
return new BufferLayout(allItems.build());
}
}
}

View file

@ -0,0 +1,24 @@
package com.jozufozu.flywheel.core.layout;
import com.jozufozu.flywheel.backend.gl.GlNumericType;
public class CommonItems {
public static final PrimitiveItem VEC4 = new PrimitiveItem(GlNumericType.FLOAT, 4);
public static final PrimitiveItem VEC3 = new PrimitiveItem(GlNumericType.FLOAT, 3);
public static final PrimitiveItem VEC2 = new PrimitiveItem(GlNumericType.FLOAT, 2);
public static final PrimitiveItem FLOAT = new PrimitiveItem(GlNumericType.FLOAT, 1);
public static final PrimitiveItem QUATERNION = new PrimitiveItem(GlNumericType.FLOAT, 4);
public static final PrimitiveItem NORMAL = new PrimitiveItem(GlNumericType.BYTE, 3, true);
public static final PrimitiveItem UV = new PrimitiveItem(GlNumericType.FLOAT, 2);
public static final PrimitiveItem RGBA = new PrimitiveItem(GlNumericType.UBYTE, 4, true);
public static final PrimitiveItem RGB = new PrimitiveItem(GlNumericType.UBYTE, 3, true);
public static final PrimitiveItem LIGHT = new PrimitiveItem(GlNumericType.UBYTE, 2, true);
public static final PrimitiveItem LIGHT_SHORT = new PrimitiveItem(GlNumericType.USHORT, 2, true);
public static final PrimitiveItem NORMALIZED_BYTE = new PrimitiveItem(GlNumericType.BYTE, 1, true);
public static final LayoutItem PADDING_BYTE = new PaddingItem(1);
}

View file

@ -1,6 +1,6 @@
package com.jozufozu.flywheel.backend.gl.attrib;
package com.jozufozu.flywheel.core.layout;
public interface IAttribSpec {
public interface LayoutItem {
void vertexAttribPointer(int stride, int index, int offset);

View file

@ -1,10 +1,10 @@
package com.jozufozu.flywheel.backend.gl.attrib;
package com.jozufozu.flywheel.core.layout;
import org.lwjgl.opengl.GL20;
import com.jozufozu.flywheel.backend.gl.GlNumericType;
public enum MatrixAttributes implements IAttribSpec {
public enum MatrixItems implements LayoutItem {
MAT3(3, 3),
MAT4(4, 4),
;
@ -12,7 +12,7 @@ public enum MatrixAttributes implements IAttribSpec {
private final int rows;
private final int cols;
MatrixAttributes(int rows, int cols) {
MatrixItems(int rows, int cols) {
this.rows = rows;
this.cols = cols;
}

View file

@ -0,0 +1,19 @@
package com.jozufozu.flywheel.core.layout;
record PaddingItem(int bytes) implements LayoutItem {
@Override
public void vertexAttribPointer(int stride, int index, int offset) {
}
@Override
public int getSize() {
return bytes;
}
@Override
public int getAttributeCount() {
return 0;
}
}

View file

@ -1,10 +1,10 @@
package com.jozufozu.flywheel.backend.gl.attrib;
package com.jozufozu.flywheel.core.layout;
import org.lwjgl.opengl.GL20;
import com.jozufozu.flywheel.backend.gl.GlNumericType;
public class VertexAttribSpec implements IAttribSpec {
public class PrimitiveItem implements LayoutItem {
private final GlNumericType type;
private final int count;
@ -12,11 +12,11 @@ public class VertexAttribSpec implements IAttribSpec {
private final int attributeCount;
private final boolean normalized;
public VertexAttribSpec(GlNumericType type, int count) {
public PrimitiveItem(GlNumericType type, int count) {
this(type, count, false);
}
public VertexAttribSpec(GlNumericType type, int count, boolean normalized) {
public PrimitiveItem(GlNumericType type, int count, boolean normalized) {
this.type = type;
this.count = count;
this.size = type.getByteWidth() * count;

View file

@ -0,0 +1,6 @@
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
package com.jozufozu.flywheel.core.layout;
import javax.annotation.ParametersAreNonnullByDefault;
import net.minecraft.MethodsReturnNonnullByDefault;

View file

@ -6,9 +6,9 @@ import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
import com.jozufozu.flywheel.backend.struct.UnsafeBufferWriter;
public abstract class UnsafeBasicWriter<D extends BasicData> extends UnsafeBufferWriter<D> {
public abstract class BasicWriterUnsafe<D extends BasicData> extends UnsafeBufferWriter<D> {
public UnsafeBasicWriter(VecBuffer backingBuffer, StructType<D> vertexType) {
public BasicWriterUnsafe(VecBuffer backingBuffer, StructType<D> vertexType) {
super(backingBuffer, vertexType);
}

View file

@ -3,9 +3,9 @@ package com.jozufozu.flywheel.core.materials.model;
import com.jozufozu.flywheel.api.struct.Batched;
import com.jozufozu.flywheel.api.struct.Instanced;
import com.jozufozu.flywheel.api.struct.StructWriter;
import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes;
import com.jozufozu.flywheel.backend.gl.attrib.MatrixAttributes;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.core.layout.CommonItems;
import com.jozufozu.flywheel.core.layout.MatrixItems;
import com.jozufozu.flywheel.core.layout.BufferLayout;
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
import com.jozufozu.flywheel.core.Programs;
import com.jozufozu.flywheel.core.model.ModelTransformer;
@ -14,9 +14,9 @@ import net.minecraft.resources.ResourceLocation;
public class ModelType implements Instanced<ModelData>, Batched<ModelData> {
public static final VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(CommonAttributes.LIGHT, CommonAttributes.RGBA)
.addAttributes(MatrixAttributes.MAT4, MatrixAttributes.MAT3)
public static final BufferLayout FORMAT = BufferLayout.builder()
.addItems(CommonItems.LIGHT, CommonItems.RGBA)
.addItems(MatrixItems.MAT4, MatrixItems.MAT3)
.build();
@Override
@ -25,13 +25,13 @@ public class ModelType implements Instanced<ModelData>, Batched<ModelData> {
}
@Override
public VertexFormat format() {
public BufferLayout getLayout() {
return FORMAT;
}
@Override
public StructWriter<ModelData> getWriter(VecBuffer backing) {
return new UnsafeModelWriter(backing, this);
return new ModelWriterUnsafe(backing, this);
}
@Override

View file

@ -2,12 +2,12 @@ package com.jozufozu.flywheel.core.materials.model;
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.core.materials.UnsafeBasicWriter;
import com.jozufozu.flywheel.core.materials.BasicWriterUnsafe;
import com.jozufozu.flywheel.util.WriteUnsafe;
public class UnsafeModelWriter extends UnsafeBasicWriter<ModelData> {
public class ModelWriterUnsafe extends BasicWriterUnsafe<ModelData> {
public UnsafeModelWriter(VecBuffer backingBuffer, StructType<ModelData> vertexType) {
public ModelWriterUnsafe(VecBuffer backingBuffer, StructType<ModelData> vertexType) {
super(backingBuffer, vertexType);
}

View file

@ -3,8 +3,8 @@ package com.jozufozu.flywheel.core.materials.oriented;
import com.jozufozu.flywheel.api.struct.Batched;
import com.jozufozu.flywheel.api.struct.Instanced;
import com.jozufozu.flywheel.api.struct.StructWriter;
import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.core.layout.CommonItems;
import com.jozufozu.flywheel.core.layout.BufferLayout;
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
import com.jozufozu.flywheel.core.Programs;
import com.jozufozu.flywheel.core.model.ModelTransformer;
@ -14,9 +14,9 @@ import net.minecraft.resources.ResourceLocation;
public class OrientedType implements Instanced<OrientedData>, Batched<OrientedData> {
public static final VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(CommonAttributes.LIGHT, CommonAttributes.RGBA)
.addAttributes(CommonAttributes.VEC3, CommonAttributes.VEC3, CommonAttributes.QUATERNION)
public static final BufferLayout FORMAT = BufferLayout.builder()
.addItems(CommonItems.LIGHT, CommonItems.RGBA)
.addItems(CommonItems.VEC3, CommonItems.VEC3, CommonItems.QUATERNION)
.build();
@Override
@ -25,13 +25,13 @@ public class OrientedType implements Instanced<OrientedData>, Batched<OrientedDa
}
@Override
public VertexFormat format() {
public BufferLayout getLayout() {
return FORMAT;
}
@Override
public StructWriter<OrientedData> getWriter(VecBuffer backing) {
return new UnsafeOrientedWriter(backing, this);
return new OrientedWriterUnsafe(backing, this);
}
@Override

View file

@ -4,10 +4,10 @@ import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.core.materials.UnsafeBasicWriter;
import com.jozufozu.flywheel.core.materials.BasicWriterUnsafe;
public class UnsafeOrientedWriter extends UnsafeBasicWriter<OrientedData> {
public UnsafeOrientedWriter(VecBuffer backingBuffer, StructType<OrientedData> vertexType) {
public class OrientedWriterUnsafe extends BasicWriterUnsafe<OrientedData> {
public OrientedWriterUnsafe(VecBuffer backingBuffer, StructType<OrientedData> vertexType) {
super(backingBuffer, vertexType);
}

View file

@ -1,7 +1,7 @@
package com.jozufozu.flywheel.core.model;
import com.jozufozu.flywheel.core.vertex.VertexList;
import com.jozufozu.flywheel.core.vertex.BlockVertexListUnsafe;
import com.jozufozu.flywheel.core.Formats;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
@ -29,7 +29,7 @@ public class BlockModel implements Model {
}
public BlockModel(BakedModel model, BlockState referenceState, PoseStack ms) {
reader = new BlockVertexListUnsafe(ModelUtil.getBufferBuilder(model, referenceState, ms));
reader = Formats.BLOCK.createReader(ModelUtil.getBufferBuilder(model, referenceState, ms));
name = referenceState.toString();
}

View file

@ -1,11 +1,12 @@
package com.jozufozu.flywheel.core.model;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.model.ElementBuffer;
import com.jozufozu.flywheel.core.Formats;
import com.jozufozu.flywheel.core.QuadConverter;
import com.jozufozu.flywheel.core.vertex.VertexList;
import com.jozufozu.flywheel.core.vertex.VertexType;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.api.vertex.VertexType;
/**
* A model that can be rendered by flywheel.
@ -49,13 +50,6 @@ public interface Model {
return Formats.POS_TEX_NORMAL;
}
/**
* @return The format of this model's vertices
*/
default VertexFormat format() {
return getType().getFormat();
}
/**
* Create an element buffer object that indexes the vertices of this model.
*
@ -75,7 +69,7 @@ public interface Model {
* The size in bytes that this model's data takes up.
*/
default int size() {
return vertexCount() * format().getStride();
return getType().byteOffset(vertexCount());
}
/**
@ -85,4 +79,8 @@ public interface Model {
default boolean empty() {
return vertexCount() == 0;
}
default void writeInto(ByteBuffer buffer) {
getType().createWriter(buffer).writeVertexList(getReader());
}
}

View file

@ -1,6 +1,6 @@
package com.jozufozu.flywheel.core.model;
import com.jozufozu.flywheel.core.vertex.VertexList;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.util.RenderMath;
import com.jozufozu.flywheel.util.transform.Transform;
import com.mojang.blaze3d.vertex.PoseStack;

View file

@ -55,7 +55,7 @@ public class ModelUtil {
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
blockRenderer.tesselateBlock(VirtualEmptyBlockGetter.INSTANCE, model, referenceState, BlockPos.ZERO, ms, builder,
true, new Random(), 42, OverlayTexture.NO_OVERLAY, VirtualEmptyModelData.INSTANCE);
false, new Random(), 42, OverlayTexture.NO_OVERLAY, VirtualEmptyModelData.INSTANCE);
builder.end();
return builder;
}

View file

@ -3,9 +3,8 @@ package com.jozufozu.flywheel.core.model;
import java.util.Collection;
import com.jozufozu.flywheel.core.Formats;
import com.jozufozu.flywheel.core.vertex.VertexList;
import com.jozufozu.flywheel.core.vertex.VertexType;
import com.jozufozu.flywheel.core.vertex.BlockVertexListUnsafe;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.api.vertex.VertexType;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.level.BlockAndTintGetter;
@ -17,7 +16,7 @@ public class WorldModel implements Model {
private final String name;
public WorldModel(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks, String name) {
reader = new BlockVertexListUnsafe(ModelUtil.getBufferBuilderFromTemplate(renderWorld, layer, blocks));
reader = Formats.BLOCK.createReader(ModelUtil.getBufferBuilderFromTemplate(renderWorld, layer, blocks));
this.name = name;
}

View file

@ -2,70 +2,49 @@ package com.jozufozu.flywheel.core.vertex;
import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.util.RenderMath;
import net.minecraft.client.renderer.LightTexture;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.core.layout.CommonItems;
import com.jozufozu.flywheel.core.layout.BufferLayout;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.datafixers.util.Pair;
public class BlockVertex implements VertexType {
public static final VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(CommonAttributes.VEC3,
CommonAttributes.UV,
CommonAttributes.RGBA,
CommonAttributes.LIGHT,
CommonAttributes.NORMAL)
public static final BufferLayout FORMAT = BufferLayout.builder()
.addItems(CommonItems.VEC3,
CommonItems.RGBA,
CommonItems.UV,
CommonItems.LIGHT_SHORT,
CommonItems.NORMAL,
CommonItems.PADDING_BYTE)
.build();
@Override
public VertexFormat getFormat() {
public BufferLayout getLayout() {
return FORMAT;
}
@Override
public void copyInto(ByteBuffer buffer, VertexList reader) {
int stride = getStride();
long addr = MemoryUtil.memAddress(buffer);
public BlockWriterUnsafe createWriter(ByteBuffer buffer) {
return new BlockWriterUnsafe(this, buffer);
}
int vertexCount = reader.getVertexCount();
for (int i = 0; i < vertexCount; i++) {
float x = reader.getX(i);
float y = reader.getY(i);
float z = reader.getZ(i);
@Override
public BlockVertexListUnsafe createReader(ByteBuffer buffer, int vertexCount) {
return new BlockVertexListUnsafe(buffer, vertexCount);
}
float xN = reader.getNX(i);
float yN = reader.getNY(i);
float zN = reader.getNZ(i);
public VertexList createReader(BufferBuilder bufferBuilder) {
// TODO: try to avoid virtual model rendering
Pair<BufferBuilder.DrawState, ByteBuffer> pair = bufferBuilder.popNextBuffer();
BufferBuilder.DrawState drawState = pair.getFirst();
float u = reader.getU(i);
float v = reader.getV(i);
byte r = reader.getR(i);
byte g = reader.getG(i);
byte b = reader.getB(i);
byte a = reader.getA(i);
int light = reader.getLight(i);
MemoryUtil.memPutFloat(addr, x);
MemoryUtil.memPutFloat(addr + 4, y);
MemoryUtil.memPutFloat(addr + 8, z);
MemoryUtil.memPutFloat(addr + 12, u);
MemoryUtil.memPutFloat(addr + 16, v);
MemoryUtil.memPutByte(addr + 20, r);
MemoryUtil.memPutByte(addr + 21, g);
MemoryUtil.memPutByte(addr + 22, b);
MemoryUtil.memPutByte(addr + 23, a);
MemoryUtil.memPutByte(addr + 24, (byte) (LightTexture.block(light) << 4));
MemoryUtil.memPutByte(addr + 25, (byte) (LightTexture.sky(light) << 4));
MemoryUtil.memPutByte(addr + 26, RenderMath.nb(xN));
MemoryUtil.memPutByte(addr + 27, RenderMath.nb(yN));
MemoryUtil.memPutByte(addr + 28, RenderMath.nb(zN));
addr += stride;
if (drawState.format() != DefaultVertexFormat.BLOCK) {
throw new RuntimeException("Cannot use BufferBuilder with " + drawState.format());
}
return new BlockVertexListUnsafe(pair.getSecond(), drawState.vertexCount());
}
}

View file

@ -2,6 +2,7 @@ package com.jozufozu.flywheel.core.vertex;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.util.RenderMath;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.datafixers.util.Pair;

View file

@ -4,27 +4,23 @@ import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.util.RenderMath;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.datafixers.util.Pair;
public class BlockVertexListUnsafe implements VertexList {
private final ByteBuffer buffer;
private final int vertexCount;
private final int stride;
private final long base;
public BlockVertexListUnsafe(BufferBuilder builder) {
VertexFormat vertexFormat = builder.getVertexFormat();
Pair<BufferBuilder.DrawState, ByteBuffer> data = builder.popNextBuffer();
this.base = MemoryUtil.memAddress(data.getSecond());
this.vertexCount = data.getFirst().vertexCount();
this.stride = vertexFormat.getVertexSize();
public BlockVertexListUnsafe(ByteBuffer buffer, int vertexCount) {
this.buffer = buffer;
this.base = MemoryUtil.memAddress(buffer);
this.vertexCount = vertexCount;
}
private long ptr(long index) {
return base + index * stride;
return base + index * 32;
}
@Override

View file

@ -0,0 +1,57 @@
package com.jozufozu.flywheel.core.vertex;
import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.util.RenderMath;
public class BlockWriterUnsafe extends VertexWriterUnsafe<BlockVertex> {
public BlockWriterUnsafe(BlockVertex type, ByteBuffer buffer) {
super(type, buffer);
}
@Override
public void writeVertex(VertexList list, int i) {
float x = list.getX(i);
float y = list.getY(i);
float z = list.getZ(i);
float xN = list.getNX(i);
float yN = list.getNY(i);
float zN = list.getNZ(i);
float u = list.getU(i);
float v = list.getV(i);
byte r = list.getR(i);
byte g = list.getG(i);
byte b = list.getB(i);
byte a = list.getA(i);
int light = list.getLight(i);
putVertex(x, y, z, u, v, r, g, b, a, light, xN, yN, zN);
}
public void putVertex(float x, float y, float z, float u, float v, byte r, byte g, byte b, byte a, int light, float nX, float nY, float nZ) {
MemoryUtil.memPutFloat(ptr, x);
MemoryUtil.memPutFloat(ptr + 4, y);
MemoryUtil.memPutFloat(ptr + 8, z);
MemoryUtil.memPutByte(ptr + 12, r);
MemoryUtil.memPutByte(ptr + 13, g);
MemoryUtil.memPutByte(ptr + 14, b);
MemoryUtil.memPutByte(ptr + 15, a);
MemoryUtil.memPutFloat(ptr + 16, u);
MemoryUtil.memPutFloat(ptr + 20, v);
MemoryUtil.memPutInt(ptr + 24, light);
MemoryUtil.memPutByte(ptr + 28, RenderMath.nb(nX));
MemoryUtil.memPutByte(ptr + 29, RenderMath.nb(nY));
MemoryUtil.memPutByte(ptr + 30, RenderMath.nb(nZ));
ptr += 32;
advance();
}
}

View file

@ -2,38 +2,28 @@ package com.jozufozu.flywheel.core.vertex;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.core.layout.CommonItems;
import com.jozufozu.flywheel.core.layout.BufferLayout;
public class PosTexNormalVertex implements VertexType {
public static final VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(CommonAttributes.VEC3, CommonAttributes.UV, CommonAttributes.NORMAL)
public static final BufferLayout FORMAT = BufferLayout.builder()
.addItems(CommonItems.VEC3, CommonItems.UV, CommonItems.NORMAL)
.build();
@Override
public VertexFormat getFormat() {
public BufferLayout getLayout() {
return FORMAT;
}
@Override
public void copyInto(ByteBuffer buffer, VertexList reader) {
PosTexNormalWriter writer = new PosTexNormalWriter(buffer);
public PosTexNormalWriterUnsafe createWriter(ByteBuffer buffer) {
return new PosTexNormalWriterUnsafe(this, buffer);
}
int vertexCount = reader.getVertexCount();
for (int i = 0; i < vertexCount; i++) {
float x = reader.getX(i);
float y = reader.getY(i);
float z = reader.getZ(i);
float u = reader.getU(i);
float v = reader.getV(i);
float xN = reader.getNX(i);
float yN = reader.getNY(i);
float zN = reader.getNZ(i);
writer.putVertex(x, y, z, xN, yN, zN, u, v);
}
@Override
public PosTexNormalVertexListUnsafe createReader(ByteBuffer buffer, int vertexCount) {
return new PosTexNormalVertexListUnsafe(buffer, vertexCount);
}
}

View file

@ -4,6 +4,7 @@ import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.util.RenderMath;
public class PosTexNormalVertexListUnsafe implements VertexList {

View file

@ -1,42 +0,0 @@
package com.jozufozu.flywheel.core.vertex;
import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.util.RenderMath;
public class PosTexNormalWriter {
private final ByteBuffer buffer;
private long addr;
private int vertexCount;
public PosTexNormalWriter(ByteBuffer buffer) {
this.buffer = buffer;
addr = MemoryUtil.memAddress(buffer);
}
public void putVertex(float x, float y, float z, float nX, float nY, float nZ, float u, float v) {
MemoryUtil.memPutFloat(addr, x);
MemoryUtil.memPutFloat(addr + 4, y);
MemoryUtil.memPutFloat(addr + 8, z);
MemoryUtil.memPutFloat(addr + 12, u);
MemoryUtil.memPutFloat(addr + 16, v);
MemoryUtil.memPutByte(addr + 20, RenderMath.nb(nX));
MemoryUtil.memPutByte(addr + 21, RenderMath.nb(nY));
MemoryUtil.memPutByte(addr + 22, RenderMath.nb(nZ));
addr += 23;
vertexCount++;
}
public int getVertexCount() {
return vertexCount;
}
public PosTexNormalVertexListUnsafe intoReader() {
return new PosTexNormalVertexListUnsafe(buffer, vertexCount);
}
}

View file

@ -0,0 +1,45 @@
package com.jozufozu.flywheel.core.vertex;
import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.util.RenderMath;
public class PosTexNormalWriterUnsafe extends VertexWriterUnsafe<PosTexNormalVertex> {
public PosTexNormalWriterUnsafe(PosTexNormalVertex type, ByteBuffer buffer) {
super(type, buffer);
}
@Override
public void writeVertex(VertexList list, int i) {
float x = list.getX(i);
float y = list.getY(i);
float z = list.getZ(i);
float u = list.getU(i);
float v = list.getV(i);
float xN = list.getNX(i);
float yN = list.getNY(i);
float zN = list.getNZ(i);
putVertex(x, y, z, xN, yN, zN, u, v);
}
public void putVertex(float x, float y, float z, float nX, float nY, float nZ, float u, float v) {
MemoryUtil.memPutFloat(ptr, x);
MemoryUtil.memPutFloat(ptr + 4, y);
MemoryUtil.memPutFloat(ptr + 8, z);
MemoryUtil.memPutFloat(ptr + 12, u);
MemoryUtil.memPutFloat(ptr + 16, v);
MemoryUtil.memPutByte(ptr + 20, RenderMath.nb(nX));
MemoryUtil.memPutByte(ptr + 21, RenderMath.nb(nY));
MemoryUtil.memPutByte(ptr + 22, RenderMath.nb(nZ));
ptr += 23;
advance();
}
}

View file

@ -1,16 +0,0 @@
package com.jozufozu.flywheel.core.vertex;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
public interface VertexType {
VertexFormat getFormat();
void copyInto(ByteBuffer buffer, VertexList reader);
default int getStride() {
return getFormat().getStride();
}
}

View file

@ -0,0 +1,41 @@
package com.jozufozu.flywheel.core.vertex;
import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.api.vertex.VertexWriter;
public abstract class VertexWriterUnsafe<V extends VertexType> implements VertexWriter {
public final V type;
protected final ByteBuffer buffer;
private int totalVertices;
private int writeVertex;
protected long ptr;
protected VertexWriterUnsafe(V type, ByteBuffer buffer) {
this.type = type;
this.buffer = buffer;
this.ptr = MemoryUtil.memAddress(buffer);
}
protected void advance() {
writeVertex++;
if (writeVertex > totalVertices) totalVertices = writeVertex;
}
@Override
public void seekToVertex(int vertex) {
buffer.position(type.byteOffset(vertex));
writeVertex = vertex;
ptr = MemoryUtil.memAddress(buffer);
}
@Override
public VertexList intoReader() {
return type.createReader(buffer, totalVertices);
}
}

View file

@ -0,0 +1,6 @@
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
package com.jozufozu.flywheel.core.vertex;
import javax.annotation.ParametersAreNonnullByDefault;
import net.minecraft.MethodsReturnNonnullByDefault;