mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-28 16:06:28 +01:00
A tribute from layouts
- Add utility to convert a Layout to a list of VertexAttributes.
This commit is contained in:
parent
0b59067701
commit
bd00bdff97
5 changed files with 116 additions and 14 deletions
|
@ -6,6 +6,7 @@ import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
|
import com.jozufozu.flywheel.api.layout.Layout;
|
||||||
import com.jozufozu.flywheel.backend.compile.Pipeline;
|
import com.jozufozu.flywheel.backend.compile.Pipeline;
|
||||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||||
import com.jozufozu.flywheel.glsl.generate.FnSignature;
|
import com.jozufozu.flywheel.glsl.generate.FnSignature;
|
||||||
|
@ -23,10 +24,12 @@ public class IndirectComponent implements SourceComponent {
|
||||||
private static final String PACKED_STRUCT_NAME = "FlwPackedInstance";
|
private static final String PACKED_STRUCT_NAME = "FlwPackedInstance";
|
||||||
private static final String UNPACK_FN_NAME = "_flw_unpackInstance";
|
private static final String UNPACK_FN_NAME = "_flw_unpackInstance";
|
||||||
|
|
||||||
|
private final Layout layout;
|
||||||
private final List<LayoutItem> layoutItems;
|
private final List<LayoutItem> layoutItems;
|
||||||
|
|
||||||
public IndirectComponent(List<LayoutItem> layoutItems) {
|
public IndirectComponent(InstanceType<?> type) {
|
||||||
this.layoutItems = layoutItems;
|
this.layoutItems = type.oldLayout().layoutItems;
|
||||||
|
this.layout = type.layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IndirectComponent create(Pipeline.InstanceAssemblerContext ctx) {
|
public static IndirectComponent create(Pipeline.InstanceAssemblerContext ctx) {
|
||||||
|
@ -34,7 +37,7 @@ public class IndirectComponent implements SourceComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IndirectComponent create(InstanceType<?> instanceType) {
|
public static IndirectComponent create(InstanceType<?> instanceType) {
|
||||||
return new IndirectComponent(instanceType.oldLayout().layoutItems);
|
return new IndirectComponent(instanceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
package com.jozufozu.flywheel.backend.engine;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.layout.FloatRepr;
|
||||||
|
import com.jozufozu.flywheel.api.layout.IntegerRepr;
|
||||||
|
import com.jozufozu.flywheel.api.layout.Layout;
|
||||||
|
import com.jozufozu.flywheel.api.layout.MatrixElementType;
|
||||||
|
import com.jozufozu.flywheel.api.layout.ScalarElementType;
|
||||||
|
import com.jozufozu.flywheel.api.layout.UnsignedIntegerRepr;
|
||||||
|
import com.jozufozu.flywheel.api.layout.ValueRepr;
|
||||||
|
import com.jozufozu.flywheel.api.layout.VectorElementType;
|
||||||
|
import com.jozufozu.flywheel.gl.GlNumericType;
|
||||||
|
import com.jozufozu.flywheel.gl.array.VertexAttribute;
|
||||||
|
|
||||||
|
public class LayoutAttributes {
|
||||||
|
/**
|
||||||
|
* Collects the vertex attributes required from the given layout.
|
||||||
|
*
|
||||||
|
* @param layout The abstract layout definition.
|
||||||
|
* @return A concrete list of vertex attributes.
|
||||||
|
*/
|
||||||
|
public static List<VertexAttribute> attributes(Layout layout) {
|
||||||
|
List<VertexAttribute> out = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Layout.Element element : layout.elements()) {
|
||||||
|
var type = element.type();
|
||||||
|
|
||||||
|
if (type instanceof ScalarElementType scalar) {
|
||||||
|
vector(out, scalar.repr(), 1);
|
||||||
|
} else if (type instanceof VectorElementType vector) {
|
||||||
|
vector(out, vector.repr(), vector.size());
|
||||||
|
} else if (type instanceof MatrixElementType matrix) {
|
||||||
|
matrix(out, matrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void matrix(List<VertexAttribute> out, MatrixElementType matrix) {
|
||||||
|
int size = matrix.columns();
|
||||||
|
var repr = matrix.repr();
|
||||||
|
var glType = toGlType(repr);
|
||||||
|
boolean normalized = normalized(repr);
|
||||||
|
|
||||||
|
for (int i = 0; i < matrix.rows(); i++) {
|
||||||
|
out.add(new VertexAttribute.Float(glType, size, normalized));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void vector(List<VertexAttribute> out, ValueRepr repr, int size) {
|
||||||
|
if (repr instanceof IntegerRepr integer) {
|
||||||
|
out.add(new VertexAttribute.Int(toGlType(integer), size));
|
||||||
|
} else if (repr instanceof UnsignedIntegerRepr integer) {
|
||||||
|
out.add(new VertexAttribute.Int(toGlType(integer), size));
|
||||||
|
} else if (repr instanceof FloatRepr floatRepr) {
|
||||||
|
out.add(new VertexAttribute.Float(toGlType(floatRepr), size, normalized(floatRepr)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GlNumericType toGlType(IntegerRepr repr) {
|
||||||
|
return switch (repr) {
|
||||||
|
case BYTE -> GlNumericType.BYTE;
|
||||||
|
case SHORT -> GlNumericType.SHORT;
|
||||||
|
case INT -> GlNumericType.INT;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GlNumericType toGlType(UnsignedIntegerRepr repr) {
|
||||||
|
return switch (repr) {
|
||||||
|
case UNSIGNED_BYTE -> GlNumericType.UBYTE;
|
||||||
|
case UNSIGNED_SHORT -> GlNumericType.USHORT;
|
||||||
|
case UNSIGNED_INT -> GlNumericType.UINT;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GlNumericType toGlType(FloatRepr repr) {
|
||||||
|
return switch (repr) {
|
||||||
|
case BYTE, NORMALIZED_BYTE -> GlNumericType.BYTE;
|
||||||
|
case UNSIGNED_BYTE, NORMALIZED_UNSIGNED_BYTE -> GlNumericType.UBYTE;
|
||||||
|
case SHORT, NORMALIZED_SHORT -> GlNumericType.SHORT;
|
||||||
|
case UNSIGNED_SHORT, NORMALIZED_UNSIGNED_SHORT -> GlNumericType.USHORT;
|
||||||
|
case INT, NORMALIZED_INT -> GlNumericType.INT;
|
||||||
|
case UNSIGNED_INT, NORMALIZED_UNSIGNED_INT -> GlNumericType.UINT;
|
||||||
|
case FLOAT -> GlNumericType.FLOAT;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean normalized(FloatRepr repr) {
|
||||||
|
return switch (repr) {
|
||||||
|
case NORMALIZED_BYTE, NORMALIZED_UNSIGNED_BYTE, NORMALIZED_SHORT, NORMALIZED_UNSIGNED_SHORT, NORMALIZED_INT, NORMALIZED_UNSIGNED_INT ->
|
||||||
|
true;
|
||||||
|
default -> false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -58,8 +58,8 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
applyProgram = programs.getApplyProgram();
|
applyProgram = programs.getApplyProgram();
|
||||||
drawProgram = programs.getIndirectProgram(instanceType, Contexts.DEFAULT);
|
drawProgram = programs.getIndirectProgram(instanceType, Contexts.DEFAULT);
|
||||||
|
|
||||||
objectStride = instanceType.oldLayout()
|
objectStride = instanceType.layout()
|
||||||
.getStride() + IndirectBuffers.INT_SIZE;
|
.byteSize() + IndirectBuffers.INT_SIZE;
|
||||||
|
|
||||||
buffers = new IndirectBuffers(objectStride);
|
buffers = new IndirectBuffers(objectStride);
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,8 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
|
|
||||||
public IndirectInstancer(InstanceType<I> type) {
|
public IndirectInstancer(InstanceType<I> type) {
|
||||||
super(type);
|
super(type);
|
||||||
long instanceStride = type.oldLayout()
|
this.objectStride = type.layout()
|
||||||
.getStride();
|
.byteSize() + IndirectBuffers.INT_SIZE;
|
||||||
this.objectStride = instanceStride + IndirectBuffers.INT_SIZE;
|
|
||||||
writer = this.type.writer();
|
writer = this.type.writer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,15 @@ import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceWriter;
|
import com.jozufozu.flywheel.api.instance.InstanceWriter;
|
||||||
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
||||||
|
import com.jozufozu.flywheel.backend.engine.LayoutAttributes;
|
||||||
import com.jozufozu.flywheel.gl.array.GlVertexArray;
|
import com.jozufozu.flywheel.gl.array.GlVertexArray;
|
||||||
|
import com.jozufozu.flywheel.gl.array.VertexAttribute;
|
||||||
import com.jozufozu.flywheel.gl.buffer.GlBuffer;
|
import com.jozufozu.flywheel.gl.buffer.GlBuffer;
|
||||||
import com.jozufozu.flywheel.gl.buffer.GlBufferUsage;
|
import com.jozufozu.flywheel.gl.buffer.GlBufferUsage;
|
||||||
import com.jozufozu.flywheel.gl.buffer.MappedBuffer;
|
import com.jozufozu.flywheel.gl.buffer.MappedBuffer;
|
||||||
import com.jozufozu.flywheel.lib.layout.BufferLayout;
|
|
||||||
|
|
||||||
public class InstancedInstancer<I extends Instance> extends AbstractInstancer<I> {
|
public class InstancedInstancer<I extends Instance> extends AbstractInstancer<I> {
|
||||||
private final BufferLayout instanceFormat;
|
private final List<VertexAttribute> instanceAttributes;
|
||||||
private final int instanceStride;
|
private final int instanceStride;
|
||||||
|
|
||||||
private final Set<GlVertexArray> boundTo = new HashSet<>();
|
private final Set<GlVertexArray> boundTo = new HashSet<>();
|
||||||
|
@ -28,13 +29,14 @@ public class InstancedInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
|
|
||||||
public InstancedInstancer(InstanceType<I> type) {
|
public InstancedInstancer(InstanceType<I> type) {
|
||||||
super(type);
|
super(type);
|
||||||
instanceFormat = type.oldLayout();
|
var layout = type.layout();
|
||||||
instanceStride = instanceFormat.getStride();
|
instanceAttributes = LayoutAttributes.attributes(layout);
|
||||||
|
instanceStride = layout.byteSize();
|
||||||
writer = type.writer();
|
writer = type.writer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAttributeCount() {
|
public int getAttributeCount() {
|
||||||
return instanceFormat.getAttributeCount();
|
return instanceAttributes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInvalid() {
|
public boolean isInvalid() {
|
||||||
|
@ -114,7 +116,7 @@ public class InstancedInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
long offset = (long) baseInstance * instanceStride;
|
long offset = (long) baseInstance * instanceStride;
|
||||||
vao.bindVertexBuffer(1, vbo.handle(), offset, instanceStride);
|
vao.bindVertexBuffer(1, vbo.handle(), offset, instanceStride);
|
||||||
vao.setBindingDivisor(1, 1);
|
vao.setBindingDivisor(1, 1);
|
||||||
vao.bindAttributes(1, startAttrib, instanceFormat.attributes());
|
vao.bindAttributes(1, startAttrib, instanceAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue