mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-10 12:34:11 +01:00
Layout down to rest
- Remove BufferLayout and associated classes. - Replace InternalVertex with new Layout. - Calculate InternalVertex stuff as static final fields. - Elements track their own byte size. - The byte size of an element type is unchanged. - The byte size of an element is 4-aligned. - Layout byte size now accounts for alignment. - Generated packed fields are now always prefixed with an underscore.
This commit is contained in:
parent
5276a4456c
commit
0deac32fde
@ -24,5 +24,7 @@ public interface Layout {
|
||||
ElementType type();
|
||||
|
||||
int offset();
|
||||
|
||||
int byteSize();
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,33 @@
|
||||
package com.jozufozu.flywheel.backend;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.layout.FloatRepr;
|
||||
import com.jozufozu.flywheel.api.layout.Layout;
|
||||
import com.jozufozu.flywheel.api.layout.LayoutBuilder;
|
||||
import com.jozufozu.flywheel.api.layout.UnsignedIntegerRepr;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexView;
|
||||
import com.jozufozu.flywheel.backend.gl.layout.BufferLayout;
|
||||
import com.jozufozu.flywheel.backend.gl.layout.CommonItems;
|
||||
import com.jozufozu.flywheel.backend.engine.LayoutAttributes;
|
||||
import com.jozufozu.flywheel.backend.gl.array.VertexAttribute;
|
||||
import com.jozufozu.flywheel.lib.vertex.FullVertexView;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public final class InternalVertex {
|
||||
public static final BufferLayout LAYOUT = BufferLayout.builder()
|
||||
.addItem(CommonItems.VEC3, "position")
|
||||
.addItem(CommonItems.UNORM_4x8, "color")
|
||||
.addItem(CommonItems.VEC2, "tex")
|
||||
.addItem(CommonItems.LIGHT_COORD, "overlay")
|
||||
.addItem(CommonItems.LIGHT_COORD, "light")
|
||||
.addItem(CommonItems.NORM_3x8, "normal")
|
||||
.withPadding(1)
|
||||
public static final Layout LAYOUT = LayoutBuilder.create()
|
||||
.vector("position", FloatRepr.FLOAT, 3)
|
||||
.vector("color", FloatRepr.NORMALIZED_UNSIGNED_BYTE, 4)
|
||||
.vector("tex", FloatRepr.FLOAT, 2)
|
||||
.vector("overlay", UnsignedIntegerRepr.UNSIGNED_SHORT, 2)
|
||||
.vector("light", UnsignedIntegerRepr.UNSIGNED_SHORT, 2)
|
||||
.vector("normal", FloatRepr.NORMALIZED_BYTE, 3)
|
||||
.build();
|
||||
|
||||
public static final List<VertexAttribute> ATTRIBUTES = LayoutAttributes.attributes(LAYOUT);
|
||||
public static final int ATTRIBUTE_COUNT = ATTRIBUTES.size();
|
||||
public static final int STRIDE = LAYOUT.byteSize();
|
||||
|
||||
public static final ResourceLocation LAYOUT_SHADER = Flywheel.rl("internal/vertex_input.vert");
|
||||
|
||||
private InternalVertex() {
|
||||
|
@ -21,7 +21,7 @@ public class PipelineCompiler {
|
||||
.withResource(pipeline.vertexApiImpl())
|
||||
.withResource(InternalVertex.LAYOUT_SHADER)
|
||||
.withComponent(key -> pipeline.assembler()
|
||||
.assemble(new Pipeline.InstanceAssemblerContext(InternalVertex.LAYOUT.getAttributeCount(), key.instanceType())))
|
||||
.assemble(new Pipeline.InstanceAssemblerContext(InternalVertex.ATTRIBUTE_COUNT, key.instanceType())))
|
||||
.withComponents(vertexComponents)
|
||||
.withResource(key -> key.instanceType()
|
||||
.vertexShader())
|
||||
|
@ -113,13 +113,14 @@ public class IndirectComponent implements SourceComponent {
|
||||
// FIXME: I don't think we're unpacking signed byte/short values correctly
|
||||
// FIXME: we definitely don't consider endianness. this all assumes little endian which works on my machine.
|
||||
var type = element.type();
|
||||
var name = "_" + element.name();
|
||||
|
||||
if (type instanceof ScalarElementType scalar) {
|
||||
return unpackScalar(element.name(), packed, scalar);
|
||||
return unpackScalar(name, packed, scalar);
|
||||
} else if (type instanceof VectorElementType vector) {
|
||||
return unpackVector(element.name(), packed, vector);
|
||||
return unpackVector(name, packed, vector);
|
||||
} else if (type instanceof MatrixElementType matrix) {
|
||||
return unpackMatrix(element.name(), packed, matrix);
|
||||
return unpackMatrix(name, packed, matrix);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown type " + type);
|
||||
@ -217,7 +218,7 @@ public class IndirectComponent implements SourceComponent {
|
||||
private static GlslExpr unpack(String fieldName, GlslStruct packed, int size, String backingType, String outType, Function<GlslExpr, GlslExpr> perElement) {
|
||||
List<GlslExpr> args = new ArrayList<>();
|
||||
for (int i = 0; i < size; i++) {
|
||||
var name = "_" + fieldName + "_" + i;
|
||||
var name = fieldName + "_" + i;
|
||||
packed.addField(backingType, name);
|
||||
args.add(UNPACKING_VARIABLE.access(name)
|
||||
.transform(perElement));
|
||||
@ -258,7 +259,7 @@ public class IndirectComponent implements SourceComponent {
|
||||
for (int i = 0; i < size; i++) {
|
||||
int unpackField = i / 2;
|
||||
int bitPos = (i % 2) * 16;
|
||||
var name = "_" + fieldName + "_" + unpackField;
|
||||
var name = fieldName + "_" + unpackField;
|
||||
if (bitPos == 0) {
|
||||
// First time we're seeing this field, add it to the struct.
|
||||
packed.addField("uint", name);
|
||||
|
@ -37,8 +37,8 @@ public class IndirectMeshPool {
|
||||
vertexArray = GlVertexArray.create();
|
||||
|
||||
vertexArray.setElementBuffer(ebo.handle());
|
||||
vertexArray.bindVertexBuffer(0, vbo.handle(), 0, InternalVertex.LAYOUT.getStride());
|
||||
vertexArray.bindAttributes(0, 0, InternalVertex.LAYOUT.attributes());
|
||||
vertexArray.bindVertexBuffer(0, vbo.handle(), 0, InternalVertex.STRIDE);
|
||||
vertexArray.bindAttributes(0, 0, InternalVertex.ATTRIBUTES);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,7 +151,7 @@ public class IndirectMeshPool {
|
||||
private BufferedMesh(Mesh mesh) {
|
||||
this.mesh = mesh;
|
||||
vertexCount = mesh.vertexCount();
|
||||
byteSize = vertexCount * InternalVertex.LAYOUT.getStride();
|
||||
byteSize = vertexCount * InternalVertex.STRIDE;
|
||||
}
|
||||
|
||||
public int vertexCount() {
|
||||
|
@ -36,7 +36,7 @@ public class DrawCall {
|
||||
return;
|
||||
}
|
||||
|
||||
instancer.bindIfNeeded(vao, InternalVertex.LAYOUT.getAttributeCount());
|
||||
instancer.bindIfNeeded(vao, InternalVertex.ATTRIBUTE_COUNT);
|
||||
mesh.setup(vao);
|
||||
|
||||
vao.bindForDraw();
|
||||
@ -58,7 +58,7 @@ public class DrawCall {
|
||||
|
||||
var vao = lazyScratchVao();
|
||||
|
||||
instancer.bindRaw(vao, InternalVertex.LAYOUT.getAttributeCount(), impl.index);
|
||||
instancer.bindRaw(vao, InternalVertex.ATTRIBUTE_COUNT, impl.index);
|
||||
mesh.setup(vao);
|
||||
|
||||
vao.bindForDraw();
|
||||
|
@ -36,7 +36,7 @@ public class InstancedMeshPool {
|
||||
*/
|
||||
public InstancedMeshPool() {
|
||||
vertexView = InternalVertex.createVertexView();
|
||||
int stride = InternalVertex.LAYOUT.getStride();
|
||||
int stride = InternalVertex.STRIDE;
|
||||
vbo = new GlBuffer();
|
||||
vbo.growthFunction(l -> Math.max(l + stride * 128L, (long) (l * 1.6)));
|
||||
}
|
||||
@ -149,7 +149,7 @@ public class InstancedMeshPool {
|
||||
private BufferedMesh(Mesh mesh, long byteIndex, EboCache eboCache) {
|
||||
this.mesh = mesh;
|
||||
vertexCount = mesh.vertexCount();
|
||||
byteSize = vertexCount * InternalVertex.LAYOUT.getStride();
|
||||
byteSize = vertexCount * InternalVertex.STRIDE;
|
||||
this.byteIndex = byteIndex;
|
||||
this.ebo = eboCache.get(mesh.indexSequence(), mesh.indexCount());
|
||||
}
|
||||
@ -182,8 +182,8 @@ public class InstancedMeshPool {
|
||||
|
||||
public void setup(GlVertexArray vao) {
|
||||
if (boundTo.add(vao)) {
|
||||
vao.bindVertexBuffer(0, InstancedMeshPool.this.vbo.handle(), byteIndex, InternalVertex.LAYOUT.getStride());
|
||||
vao.bindAttributes(0, 0, InternalVertex.LAYOUT.attributes());
|
||||
vao.bindVertexBuffer(0, InstancedMeshPool.this.vbo.handle(), byteIndex, InternalVertex.STRIDE);
|
||||
vao.bindAttributes(0, 0, InternalVertex.ATTRIBUTES);
|
||||
vao.setElementBuffer(ebo);
|
||||
}
|
||||
}
|
||||
|
@ -1,85 +0,0 @@
|
||||
package com.jozufozu.flywheel.backend.gl.layout;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.jozufozu.flywheel.backend.gl.array.VertexAttribute;
|
||||
|
||||
/**
|
||||
* Classic Vertex Format with a clever name.
|
||||
*
|
||||
* <p>
|
||||
* Used for vertices and instances. Describes the layout of a datatype in a buffer object.
|
||||
* </p>
|
||||
*
|
||||
* @see com.jozufozu.flywheel.api.instance.InstanceType
|
||||
*/
|
||||
public class BufferLayout {
|
||||
|
||||
public final List<LayoutItem> layoutItems;
|
||||
public final List<VertexAttribute> attributes;
|
||||
|
||||
private final int stride;
|
||||
|
||||
public BufferLayout(List<LayoutItem> layoutItems, int padding) {
|
||||
this.layoutItems = ImmutableList.copyOf(layoutItems);
|
||||
|
||||
ImmutableList.Builder<VertexAttribute> attributes = ImmutableList.builder();
|
||||
|
||||
for (var item : this.layoutItems) {
|
||||
item.type()
|
||||
.provideAttributes(attributes::add);
|
||||
}
|
||||
|
||||
this.attributes = attributes.build();
|
||||
this.stride = calculateStride(this.attributes) + padding;
|
||||
}
|
||||
|
||||
public List<VertexAttribute> attributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public int getAttributeCount() {
|
||||
return attributes.size();
|
||||
}
|
||||
|
||||
public int getStride() {
|
||||
return stride;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
private static int calculateStride(List<VertexAttribute> layoutItems) {
|
||||
int stride = 0;
|
||||
for (var spec : layoutItems) {
|
||||
stride += spec.byteWidth();
|
||||
}
|
||||
return stride;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final ImmutableList.Builder<LayoutItem> allItems;
|
||||
private int padding;
|
||||
|
||||
public Builder() {
|
||||
allItems = ImmutableList.builder();
|
||||
}
|
||||
|
||||
public Builder addItem(InputType type, String name) {
|
||||
allItems.add(new LayoutItem(type, name));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withPadding(int padding) {
|
||||
this.padding = padding;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BufferLayout build() {
|
||||
return new BufferLayout(allItems.build(), padding);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
package com.jozufozu.flywheel.backend.gl.layout;
|
||||
|
||||
import com.jozufozu.flywheel.backend.gl.GlNumericType;
|
||||
import com.jozufozu.flywheel.backend.gl.array.VertexAttribute;
|
||||
import com.jozufozu.flywheel.backend.glsl.generate.FnSignature;
|
||||
import com.jozufozu.flywheel.backend.glsl.generate.GlslExpr;
|
||||
|
||||
public final class CommonItems {
|
||||
private static final String VEC2_TYPE = "vec2";
|
||||
private static final String VEC3_TYPE = "vec3";
|
||||
private static final String VEC4_TYPE = "vec4";
|
||||
private static final String VEC2F_TYPE = "Vec2F";
|
||||
private static final String VEC3F_TYPE = "Vec3F";
|
||||
private static final String VEC4F_TYPE = "Vec4F";
|
||||
private static final String IVEC2_TYPE = "ivec2";
|
||||
private static final String FLOAT_TYPE = "float";
|
||||
private static final String UINT_TYPE = "uint";
|
||||
private static final String LIGHT_COORD_TYPE = "uint";
|
||||
|
||||
public static final VecInput LIGHT_COORD = VecInput.builder()
|
||||
.vertexAttribute(new VertexAttribute.Int(GlNumericType.USHORT, 2))
|
||||
.typeName(IVEC2_TYPE)
|
||||
.packedTypeName(LIGHT_COORD_TYPE)
|
||||
.unpackingFunction(expr -> expr.callFunction("unpackLightCoord"))
|
||||
.declaration(builder -> builder.function()
|
||||
.signature(FnSignature.create()
|
||||
.name("unpackLightCoord")
|
||||
.returnType(IVEC2_TYPE)
|
||||
.arg("uint", "light")
|
||||
.build())
|
||||
.body(block -> block.raw("return ivec2(light & 0xFFFFu, (light >> 16) & 0xFFFFu);")))
|
||||
.build();
|
||||
|
||||
public static final VecInput FLOAT = VecInput.builder()
|
||||
.vertexAttribute(new VertexAttribute.Float(GlNumericType.FLOAT, 1, false))
|
||||
.typeName(FLOAT_TYPE)
|
||||
.packedTypeName(FLOAT_TYPE)
|
||||
.build();
|
||||
public static final VecInput NORM_3x8 = VecInput.builder()
|
||||
.vertexAttribute(new VertexAttribute.Float(GlNumericType.BYTE, 3, true))
|
||||
.typeName(VEC3_TYPE)
|
||||
.packedTypeName(UINT_TYPE)
|
||||
.unpackingFunction(expr -> expr.callFunction("unpackSnorm4x8")
|
||||
.swizzle("xyz"))
|
||||
.build();
|
||||
public static final VecInput UNORM_4x8 = VecInput.builder()
|
||||
.vertexAttribute(new VertexAttribute.Float(GlNumericType.UBYTE, 4, true))
|
||||
.typeName(VEC4_TYPE)
|
||||
.packedTypeName(UINT_TYPE)
|
||||
.unpackingFunction(expr -> expr.callFunction("unpackUnorm4x8"))
|
||||
.build();
|
||||
public static final VecInput UNORM_3x8 = VecInput.builder()
|
||||
.vertexAttribute(new VertexAttribute.Float(GlNumericType.UBYTE, 3, true))
|
||||
.typeName(VEC3_TYPE)
|
||||
.packedTypeName(UINT_TYPE)
|
||||
.unpackingFunction(expr -> expr.callFunction("unpackUnorm4x8")
|
||||
.swizzle("xyz"))
|
||||
.build();
|
||||
public static final VecInput VEC4 = VecInput.builder()
|
||||
.vertexAttribute(new VertexAttribute.Float(GlNumericType.FLOAT, 4, false))
|
||||
.typeName(VEC4_TYPE)
|
||||
.packedTypeName(VEC4F_TYPE)
|
||||
.unpackingFunction(expr -> expr.callFunction("unpackVec4F"))
|
||||
.declaration(builder -> {
|
||||
builder.struct()
|
||||
.setName(VEC4F_TYPE)
|
||||
.addField(FLOAT_TYPE, "x")
|
||||
.addField(FLOAT_TYPE, "y")
|
||||
.addField(FLOAT_TYPE, "z")
|
||||
.addField(FLOAT_TYPE, "w");
|
||||
builder.function()
|
||||
.signature(FnSignature.create()
|
||||
.name("unpackVec4F")
|
||||
.returnType(VEC4_TYPE)
|
||||
.arg(VEC4F_TYPE, "v")
|
||||
.build())
|
||||
.body(block -> {
|
||||
var v = GlslExpr.variable("v");
|
||||
block.ret(GlslExpr.call("vec4", v.access("x"), v.access("y"), v.access("z"), v.access("w")));
|
||||
});
|
||||
})
|
||||
.build();
|
||||
public static final VecInput VEC3 = VecInput.builder()
|
||||
.vertexAttribute(new VertexAttribute.Float(GlNumericType.FLOAT, 3, false))
|
||||
.typeName(VEC3_TYPE)
|
||||
.packedTypeName(VEC3F_TYPE)
|
||||
.unpackingFunction(expr -> expr.callFunction("unpackVec3F"))
|
||||
.declaration(builder -> {
|
||||
builder.struct()
|
||||
.setName(VEC3F_TYPE)
|
||||
.addField(FLOAT_TYPE, "x")
|
||||
.addField(FLOAT_TYPE, "y")
|
||||
.addField(FLOAT_TYPE, "z");
|
||||
builder.function()
|
||||
.signature(FnSignature.create()
|
||||
.name("unpackVec3F")
|
||||
.returnType(VEC3_TYPE)
|
||||
.arg(VEC3F_TYPE, "v")
|
||||
.build())
|
||||
.body(block -> {
|
||||
var v = GlslExpr.variable("v");
|
||||
block.ret(GlslExpr.call("vec3", v.access("x"), v.access("y"), v.access("z")));
|
||||
});
|
||||
})
|
||||
.build();
|
||||
public static final VecInput VEC2 = VecInput.builder()
|
||||
.vertexAttribute(new VertexAttribute.Float(GlNumericType.FLOAT, 2, false))
|
||||
.typeName(VEC2_TYPE)
|
||||
.packedTypeName(VEC2F_TYPE)
|
||||
.unpackingFunction(expr -> expr.callFunction("unpackVec2F"))
|
||||
.declaration(builder -> {
|
||||
builder.struct()
|
||||
.setName(VEC2F_TYPE)
|
||||
.addField(FLOAT_TYPE, "x")
|
||||
.addField(FLOAT_TYPE, "y");
|
||||
builder.function()
|
||||
.signature(FnSignature.create()
|
||||
.name("unpackVec2F")
|
||||
.returnType(VEC2_TYPE)
|
||||
.arg(VEC2F_TYPE, "v")
|
||||
.build())
|
||||
.body(block -> {
|
||||
var v = GlslExpr.variable("v");
|
||||
block.ret(GlslExpr.call("vec2", v.access("x"), v.access("y")));
|
||||
});
|
||||
})
|
||||
.build();
|
||||
|
||||
public static final MatInput MAT3 = new MatInput(3, 3, "mat3", "Mat3F", "unpackMat3F");
|
||||
public static final MatInput MAT4 = new MatInput(4, 4, "mat4", "Mat4F", "unpackMat4F");
|
||||
|
||||
private CommonItems() {
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.jozufozu.flywheel.backend.gl.layout;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.jozufozu.flywheel.backend.gl.array.VertexAttribute;
|
||||
import com.jozufozu.flywheel.backend.glsl.generate.GlslBuilder;
|
||||
import com.jozufozu.flywheel.backend.glsl.generate.GlslExpr;
|
||||
|
||||
public interface InputType {
|
||||
|
||||
void provideAttributes(Consumer<VertexAttribute> consumer);
|
||||
|
||||
String typeName();
|
||||
|
||||
String packedTypeName();
|
||||
|
||||
int attributeCount();
|
||||
|
||||
GlslExpr unpack(GlslExpr packed);
|
||||
|
||||
void declare(GlslBuilder builder);
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.jozufozu.flywheel.backend.gl.layout;
|
||||
|
||||
public record LayoutItem(InputType type, String name) {
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package com.jozufozu.flywheel.backend.gl.layout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.jozufozu.flywheel.backend.gl.GlNumericType;
|
||||
import com.jozufozu.flywheel.backend.gl.array.VertexAttribute;
|
||||
import com.jozufozu.flywheel.backend.glsl.generate.FnSignature;
|
||||
import com.jozufozu.flywheel.backend.glsl.generate.GlslBuilder;
|
||||
import com.jozufozu.flywheel.backend.glsl.generate.GlslExpr;
|
||||
|
||||
public record MatInput(int rows, int cols, String typeName, String packedTypeName,
|
||||
String unpackingFunction) implements InputType {
|
||||
|
||||
@Override
|
||||
public void provideAttributes(Consumer<VertexAttribute> consumer) {
|
||||
for (int i = 0; i < rows; i++) {
|
||||
consumer.accept(new VertexAttribute.Float(GlNumericType.FLOAT, cols, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attributeCount() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlslExpr unpack(GlslExpr packed) {
|
||||
return packed.callFunction(unpackingFunction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void declare(GlslBuilder builder) {
|
||||
|
||||
var s = builder.struct();
|
||||
s.setName(packedTypeName);
|
||||
|
||||
for (int c = 0; c < cols; c++) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
s.addField("float", "m" + c + r);
|
||||
}
|
||||
}
|
||||
|
||||
builder.function()
|
||||
.signature(FnSignature.create()
|
||||
.name(unpackingFunction)
|
||||
.returnType(typeName)
|
||||
.arg(packedTypeName, "p")
|
||||
.build())
|
||||
.body(block -> {
|
||||
List<GlslExpr> args = new ArrayList<>();
|
||||
var p = GlslExpr.variable("p");
|
||||
|
||||
for (int c = 0; c < cols; c++) {
|
||||
for (int r = 0; r < rows; r++) {
|
||||
args.add(p.access("m" + c + r));
|
||||
}
|
||||
}
|
||||
|
||||
block.ret(GlslExpr.call(typeName, args));
|
||||
});
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package com.jozufozu.flywheel.backend.gl.layout;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.jozufozu.flywheel.backend.gl.array.VertexAttribute;
|
||||
import com.jozufozu.flywheel.backend.glsl.generate.GlslBuilder;
|
||||
import com.jozufozu.flywheel.backend.glsl.generate.GlslExpr;
|
||||
|
||||
public class VecInput implements InputType {
|
||||
private final VertexAttribute attribute;
|
||||
private final String typeName;
|
||||
private final String packedTypeName;
|
||||
private final Function<GlslExpr, GlslExpr> unpackingFunction;
|
||||
private final Consumer<GlslBuilder> declaration;
|
||||
|
||||
public VecInput(VertexAttribute attribute, String typeName, String packedTypeName, Function<GlslExpr, GlslExpr> unpackingFunction, Consumer<GlslBuilder> declaration) {
|
||||
this.attribute = attribute;
|
||||
this.typeName = typeName;
|
||||
this.packedTypeName = packedTypeName;
|
||||
this.unpackingFunction = unpackingFunction;
|
||||
this.declaration = declaration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void provideAttributes(Consumer<VertexAttribute> consumer) {
|
||||
consumer.accept(attribute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String typeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String packedTypeName() {
|
||||
return packedTypeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int attributeCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlslExpr unpack(GlslExpr packed) {
|
||||
return unpackingFunction.apply(packed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void declare(GlslBuilder builder) {
|
||||
declaration.accept(builder);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private VertexAttribute attribute;
|
||||
private String typeName;
|
||||
private String packedTypeName;
|
||||
private Function<GlslExpr, GlslExpr> unpackingFunction = Function.identity();
|
||||
private Consumer<GlslBuilder> declaration = $ -> {
|
||||
};
|
||||
|
||||
public Builder vertexAttribute(VertexAttribute attribute) {
|
||||
this.attribute = attribute;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder typeName(String typeName) {
|
||||
this.typeName = typeName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder packedTypeName(String packedTypeName) {
|
||||
this.packedTypeName = packedTypeName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder unpackingFunction(Function<GlslExpr, GlslExpr> f) {
|
||||
this.unpackingFunction = f;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder declaration(Consumer<GlslBuilder> declaration) {
|
||||
this.declaration = declaration;
|
||||
return this;
|
||||
}
|
||||
|
||||
public VecInput build() {
|
||||
return new VecInput(attribute, typeName, packedTypeName, unpackingFunction, declaration);
|
||||
}
|
||||
}
|
||||
}
|
@ -126,7 +126,7 @@ public class LayoutBuilderImpl implements LayoutBuilder {
|
||||
}
|
||||
|
||||
private LayoutBuilder element(String name, ElementType type) {
|
||||
elements.add(new ElementImpl(name, type, offset));
|
||||
elements.add(new ElementImpl(name, type, offset, MoreMath.align4(type.byteSize())));
|
||||
offset += type.byteSize();
|
||||
offset = MoreMath.align4(offset);
|
||||
return this;
|
||||
@ -173,7 +173,7 @@ public class LayoutBuilderImpl implements LayoutBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
return new LayoutImpl(List.copyOf(elements));
|
||||
return new LayoutImpl(List.copyOf(elements), offset);
|
||||
}
|
||||
|
||||
private static boolean isValidNameCharacter(char c) {
|
||||
|
@ -18,14 +18,12 @@ final class LayoutImpl implements Layout {
|
||||
private final Map<String, Element> map;
|
||||
private final int byteSize;
|
||||
|
||||
LayoutImpl(@Unmodifiable List<Element> elements) {
|
||||
LayoutImpl(@Unmodifiable List<Element> elements, int byteSize) {
|
||||
this.elements = elements;
|
||||
|
||||
Object2ObjectOpenHashMap<String, Element> map = new Object2ObjectOpenHashMap<>();
|
||||
int byteSize = 0;
|
||||
for (Element element : this.elements) {
|
||||
map.put(element.name(), element);
|
||||
byteSize += element.type().byteSize();
|
||||
}
|
||||
map.trim();
|
||||
|
||||
@ -73,6 +71,6 @@ final class LayoutImpl implements Layout {
|
||||
return elements.equals(other.elements);
|
||||
}
|
||||
|
||||
record ElementImpl(String name, ElementType type, int offset) implements Element {
|
||||
record ElementImpl(String name, ElementType type, int offset, int byteSize) implements Element {
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user