mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 23:47:09 +01:00
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:
parent
42365def02
commit
ede2ba8776
50 changed files with 599 additions and 433 deletions
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||
package com.jozufozu.flywheel.backend.gl.attrib;
|
||||
package com.jozufozu.flywheel.api.vertex;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||
package com.jozufozu.flywheel.core.hardcoded;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -0,0 +1,6 @@
|
|||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||
package com.jozufozu.flywheel.core.layout;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||
package com.jozufozu.flywheel.core.vertex;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
Loading…
Reference in a new issue