Reorganize/rename

- No more set in builders
 - Move generated components to backend packages
 - Fix code organization
This commit is contained in:
Jozufozu 2022-09-15 12:37:18 -07:00
parent 03c2df4664
commit cab922f187
15 changed files with 329 additions and 312 deletions

View file

@ -72,40 +72,40 @@ public class SimpleBackendType implements BackendType {
private Component engineMessage;
private Supplier<Engine> engineSupplier;
private Supplier<BackendType> fallback;
private BooleanSupplier booleanSupplier;
private BooleanSupplier isSupported;
public Builder setProperName(String properName) {
public Builder properName(String properName) {
this.properName = properName;
return this;
}
public Builder setShortName(String shortName) {
public Builder shortName(String shortName) {
this.shortName = shortName;
return this;
}
public Builder setEngineMessage(Component engineMessage) {
public Builder engineMessage(Component engineMessage) {
this.engineMessage = engineMessage;
return this;
}
public Builder setEngineSupplier(Supplier<Engine> engineSupplier) {
public Builder engineSupplier(Supplier<Engine> engineSupplier) {
this.engineSupplier = engineSupplier;
return this;
}
public Builder setFallback(Supplier<BackendType> fallback) {
public Builder fallback(Supplier<BackendType> fallback) {
this.fallback = fallback;
return this;
}
public Builder supported(BooleanSupplier booleanSupplier) {
this.booleanSupplier = booleanSupplier;
public Builder supported(BooleanSupplier isSupported) {
this.isSupported = isSupported;
return this;
}
public BackendType register() {
return BackendTypes.register(new SimpleBackendType(properName, shortName, engineMessage, engineSupplier, fallback, booleanSupplier));
return BackendTypes.register(new SimpleBackendType(properName, shortName, engineMessage, engineSupplier, fallback, isSupported));
}
}
}

View file

@ -33,8 +33,7 @@ public class ComputeCullerCompiler extends Memoizer<StructType<?>, GlProgram> {
var finalSource = new StringBuilder();
CompilationContext context = new CompilationContext();
var components = List.of(structType.getLayout()
.getIndirectComponent(), location.getFile(), Components.Pipeline.INDIRECT_CULL.getFile());
var components = List.of(new IndirectComponent(structType.getLayout().layoutItems), location.getFile(), Components.Pipeline.INDIRECT_CULL.getFile());
var names = ImmutableList.<ResourceLocation>builder();
var included = new LinkedHashSet<SourceComponent>(); // linked to preserve order

View file

@ -0,0 +1,77 @@
package com.jozufozu.flywheel.backend.instancing.indirect;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.core.Components;
import com.jozufozu.flywheel.core.SourceComponent;
import com.jozufozu.flywheel.core.layout.LayoutItem;
import com.jozufozu.flywheel.core.source.CompilationContext;
import com.jozufozu.flywheel.core.source.generate.GlslBuilder;
import com.jozufozu.flywheel.core.source.generate.GlslExpr;
import net.minecraft.resources.ResourceLocation;
public class IndirectComponent implements SourceComponent {
private static final String UNPACK_ARG = "p";
private static final GlslExpr.Variable UNPACKING_VARIABLE = GlslExpr.variable(UNPACK_ARG);
private final List<LayoutItem> layoutItems;
public IndirectComponent(List<LayoutItem> layoutItems) {
this.layoutItems = layoutItems;
}
@Override
public Collection<? extends SourceComponent> included() {
return List.of(Components.UTIL_TYPES.getFile());
}
@Override
public ResourceLocation name() {
return Flywheel.rl("generated_indirect");
}
@Override
public String source(CompilationContext ctx) {
var generated = generateIndirect("IndirectStruct");
return ctx.generatedHeader(generated, name().toString()) + generated;
}
public String generateIndirect(String structName) {
var builder = new GlslBuilder();
final var packedStructName = structName + "_packed";
builder.define("FlwInstance", structName);
builder.define("FlwPackedInstance", packedStructName);
var packed = builder.struct();
builder.blankLine();
var instance = builder.struct();
packed.setName(packedStructName);
instance.setName(structName);
for (var field : layoutItems) {
field.addPackedToStruct(packed);
field.addToStruct(instance);
}
builder.blankLine();
var func = builder.function()
.returnType(structName)
.name("flw_unpackInstance")
.argumentIn(packedStructName, UNPACK_ARG);
var args = layoutItems.stream()
.map(layoutItem -> layoutItem.unpackField(UNPACKING_VARIABLE))
.map(GlslExpr::minPrint)
.collect(Collectors.joining(", "));
func.statement("return " + structName + "(" + args + ");");
return builder.build();
}
}

View file

@ -0,0 +1,85 @@
package com.jozufozu.flywheel.backend.instancing.instancing;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.core.SourceComponent;
import com.jozufozu.flywheel.core.layout.LayoutItem;
import com.jozufozu.flywheel.core.source.CompilationContext;
import com.jozufozu.flywheel.core.source.generate.GlslBuilder;
import com.jozufozu.flywheel.core.source.generate.GlslExpr;
import net.minecraft.resources.ResourceLocation;
public class InstancedArraysComponent implements SourceComponent {
private static final String ATTRIBUTE_SUFFIX = "_vertex_in";
private final List<LayoutItem> layoutItems;
private final int baseIndex;
public InstancedArraysComponent(List<LayoutItem> layoutItems, int baseIndex) {
this.layoutItems = layoutItems;
this.baseIndex = baseIndex;
}
@Override
public Collection<? extends SourceComponent> included() {
return Collections.emptyList();
}
@Override
public String source(CompilationContext ctx) {
var generated = generateInstancedArrays("Instance");
return ctx.generatedHeader(generated, name().toString()) + generated;
}
@Override
public ResourceLocation name() {
return Flywheel.rl("generated_instanced_arrays");
}
public String generateInstancedArrays(String structName) {
var builder = new GlslBuilder();
builder.define("FlwInstance", structName);
int i = baseIndex;
for (var field : layoutItems) {
builder.vertexInput()
.binding(i)
.type(field.type()
.typeName())
.name(field.name() + ATTRIBUTE_SUFFIX);
i += field.type()
.attributeCount();
}
builder.blankLine();
var structBuilder = builder.struct();
structBuilder.setName(structName);
for (var field : layoutItems) {
field.addToStruct(structBuilder);
}
builder.blankLine();
var func = builder.function()
.returnType(structName)
.name("flw_unpackInstance");
var args = layoutItems.stream()
.map(it -> new GlslExpr.Variable(it.name() + ATTRIBUTE_SUFFIX))
.map(GlslExpr::minPrint)
.collect(Collectors.joining(", "));
func.statement("return " + structName + "(" + args + ");");
return builder.build();
}
}

View file

@ -21,74 +21,74 @@ import net.minecraft.network.chat.TextComponent;
public class BackendTypes {
public static final Map<String, BackendType> BACKEND_TYPES = new HashMap<>();
public static final BackendType OFF = SimpleBackendType.builder()
.properName("Off")
.shortName("off")
.engineMessage(new TextComponent("Disabled Flywheel").withStyle(ChatFormatting.RED))
.engineSupplier(() -> {
throw new IllegalStateException("Cannot create engine when backend is off.");
})
.fallback(() -> BackendTypes.OFF)
.supported(() -> true)
.register();
/**
* Use a thread pool to buffer instances in parallel on the CPU.
*/
public static final BackendType BATCHING = SimpleBackendType.builder()
.properName("Parallel Batching")
.shortName("batching")
.engineMessage(new TextComponent("Using Batching Engine").withStyle(ChatFormatting.GREEN))
.engineSupplier(BatchingEngine::new)
.fallback(() -> BackendTypes.OFF)
.supported(() -> !ShadersModHandler.isShaderPackInUse())
.register();
/**
* Use GPU instancing to render everything.
*/
public static final BackendType INSTANCING = SimpleBackendType.builder()
.properName("GL33 Instanced Arrays")
.shortName("instancing")
.engineMessage(new TextComponent("Using Instancing Engine").withStyle(ChatFormatting.GREEN))
.engineSupplier(() -> new InstancingEngine(Components.WORLD, 100 * 100))
.fallback(() -> BackendTypes.BATCHING)
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance()
.instancedArraysSupported())
.register();
/**
* Use Compute shaders to cull instances.
*/
public static final BackendType INDIRECT = SimpleBackendType.builder()
.properName("GL46 Compute Culling")
.shortName("indirect")
.engineMessage(new TextComponent("Using Indirect Engine").withStyle(ChatFormatting.GREEN))
.engineSupplier(() -> new IndirectEngine(Components.WORLD))
.fallback(() -> BackendTypes.INSTANCING)
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance()
.supportsIndirect())
.register();
public static BackendType register(BackendType type) {
BACKEND_TYPES.put(type.getShortName(), type);
return type;
}
public static final BackendType OFF = SimpleBackendType.builder()
.setProperName("Off")
.setShortName("off")
.setEngineMessage(new TextComponent("Disabled Flywheel").withStyle(ChatFormatting.RED))
.setEngineSupplier(() -> {
throw new IllegalStateException("Cannot create engine when backend is off.");
})
.setFallback(() -> BackendTypes.OFF)
.supported(() -> true)
.register();
public static BackendType defaultForCurrentPC() {
// TODO: Automatically select the best default config based on the user's driver
return INDIRECT;
}
/**
* Use a thread pool to buffer instances in parallel on the CPU.
*/
public static final BackendType BATCHING = SimpleBackendType.builder()
.setProperName("Parallel Batching")
.setShortName("batching")
.setEngineMessage(new TextComponent("Using Batching Engine").withStyle(ChatFormatting.GREEN))
.setEngineSupplier(BatchingEngine::new)
.setFallback(() -> BackendTypes.OFF)
.supported(() -> !ShadersModHandler.isShaderPackInUse())
.register();
@Nullable
public static BackendType getBackendType(String name) {
return BACKEND_TYPES.get(name.toLowerCase(Locale.ROOT));
}
/**
* Use GPU instancing to render everything.
*/
public static final BackendType INSTANCING = SimpleBackendType.builder()
.setProperName("GL33 Instanced Arrays")
.setShortName("instancing")
.setEngineMessage(new TextComponent("Using Instancing Engine").withStyle(ChatFormatting.GREEN))
.setEngineSupplier(() -> new InstancingEngine(Components.WORLD, 100 * 100))
.setFallback(() -> BackendTypes.BATCHING)
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance()
.instancedArraysSupported())
.register();
public static Collection<String> validNames() {
return BACKEND_TYPES.keySet();
}
/**
* Use Compute shaders to cull instances.
*/
public static final BackendType INDIRECT = SimpleBackendType.builder()
.setProperName("GL46 Compute Culling")
.setShortName("indirect")
.setEngineMessage(new TextComponent("Using Indirect Engine").withStyle(ChatFormatting.GREEN))
.setEngineSupplier(() -> new IndirectEngine(Components.WORLD))
.setFallback(() -> BackendTypes.INSTANCING)
.supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance()
.supportsIndirect())
.register();
public static void init() {
// noop
}

View file

@ -6,6 +6,8 @@ import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.context.ContextShader;
import com.jozufozu.flywheel.api.pipeline.PipelineShader;
import com.jozufozu.flywheel.backend.gl.GLSLVersion;
import com.jozufozu.flywheel.backend.instancing.indirect.IndirectComponent;
import com.jozufozu.flywheel.backend.instancing.instancing.InstancedArraysComponent;
import com.jozufozu.flywheel.core.crumbling.CrumblingProgram;
import com.jozufozu.flywheel.core.source.FileResolution;
import com.jozufozu.flywheel.core.source.SourceChecks;
@ -29,11 +31,9 @@ public class Components {
public static final ContextShader WORLD = ComponentRegistry.register(new ContextShader(WorldProgram::new, Files.WORLD_VERTEX, Files.WORLD_FRAGMENT));
public static final ContextShader CRUMBLING = ComponentRegistry.register(new ContextShader(CrumblingProgram::new, Files.WORLD_VERTEX, Files.CRUMBLING_FRAGMENT));
public static final PipelineShader INSTANCED_ARRAYS = new PipelineShader(GLSLVersion.V420, Pipeline.INSTANCED_ARRAYS_DRAW, Pipeline.DRAW_FRAGMENT, (vertexType, structType) -> structType.getLayout()
.getInstancedArraysComponent(vertexType.getLayout()
.getAttributeCount()));
public static final PipelineShader INDIRECT = new PipelineShader(GLSLVersion.V460, Pipeline.INDIRECT_DRAW, Pipeline.DRAW_FRAGMENT, (vertexType, structType) -> structType.getLayout()
.getIndirectComponent());
public static final PipelineShader INSTANCED_ARRAYS = new PipelineShader(GLSLVersion.V420, Pipeline.INSTANCED_ARRAYS_DRAW, Pipeline.DRAW_FRAGMENT, (vertexType, structType) -> new InstancedArraysComponent(structType.getLayout().layoutItems, vertexType.getLayout()
.getAttributeCount()));
public static final PipelineShader INDIRECT = new PipelineShader(GLSLVersion.V460, Pipeline.INDIRECT_DRAW, Pipeline.DRAW_FRAGMENT, (vertexType, structType) -> new IndirectComponent(structType.getLayout().layoutItems));
public static final FileResolution UTIL_TYPES = FileResolution.get(Flywheel.rl("util/types.glsl"));
public static void init() {
@ -117,14 +117,13 @@ public class Components {
public static class Checks {
public static final BiConsumer<ErrorReporter, SourceFile> LAYOUT_VERTEX = SourceChecks.checkFunctionArity("flw_layoutVertex", 0)
.andThen(SourceChecks.checkDefine("FLW_INSTANCE_BASE_INDEX"));
public static final BiConsumer<ErrorReporter, SourceFile> INSTANCE_VERTEX = SourceChecks.checkFunctionParameterTypeExists("flw_instanceVertex", 1, 0)
.andThen(SourceChecks.checkDefine("FLW_INSTANCE_STRUCT"));
public static final BiConsumer<ErrorReporter, SourceFile> LAYOUT_VERTEX = SourceChecks.checkFunctionArity("flw_layoutVertex", 0);
public static final BiConsumer<ErrorReporter, SourceFile> INSTANCE_VERTEX = SourceChecks.checkFunctionParameterTypeExists("flw_instanceVertex", 1, 0);
public static final BiConsumer<ErrorReporter, SourceFile> MATERIAL_VERTEX = SourceChecks.checkFunctionArity("flw_materialVertex", 0);
public static final BiConsumer<ErrorReporter, SourceFile> MATERIAL_FRAGMENT = SourceChecks.checkFunctionArity("flw_materialFragment", 0);
public static final BiConsumer<ErrorReporter, SourceFile> CONTEXT_VERTEX = SourceChecks.checkFunctionArity("flw_contextVertex", 0);
public static final BiConsumer<ErrorReporter, SourceFile> CONTEXT_FRAGMENT = SourceChecks.checkFunctionArity("flw_contextFragment", 0).andThen(SourceChecks.checkFunctionArity("flw_initFragment", 0));
public static final BiConsumer<ErrorReporter, SourceFile> CONTEXT_FRAGMENT = SourceChecks.checkFunctionArity("flw_contextFragment", 0)
.andThen(SourceChecks.checkFunctionArity("flw_initFragment", 0));
public static final BiConsumer<ErrorReporter, SourceFile> PIPELINE = SourceChecks.checkFunctionArity("main", 0);
}

View file

@ -1,21 +1,10 @@
package com.jozufozu.flywheel.core.layout;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.gl.array.VertexAttribute;
import com.jozufozu.flywheel.core.Components;
import com.jozufozu.flywheel.core.SourceComponent;
import com.jozufozu.flywheel.core.source.CompilationContext;
import com.jozufozu.flywheel.core.source.generate.GlslBuilder;
import com.jozufozu.flywheel.core.source.generate.GlslExpr;
import net.minecraft.resources.ResourceLocation;
/**
* Classic Vertex Format struct with a clever name.
@ -39,8 +28,9 @@ public class BufferLayout {
ImmutableList.Builder<VertexAttribute> attributes = ImmutableList.builder();
for (var item : layoutItems) {
item.type.provideAttributes(attributes::add);
for (var item : this.layoutItems) {
item.type()
.provideAttributes(attributes::add);
}
this.attributes = attributes.build();
@ -59,14 +49,6 @@ public class BufferLayout {
return stride;
}
public InstancedArraysComponent getInstancedArraysComponent(int baseIndex) {
return new InstancedArraysComponent(baseIndex);
}
public IndirectComponent getIndirectComponent() {
return new IndirectComponent();
}
public static Builder builder() {
return new Builder();
}
@ -102,136 +84,4 @@ public class BufferLayout {
}
}
public record LayoutItem(InputType type, String name) {
public String unpack(String argName) {
return argName + '.' + name;
}
}
public class InstancedArraysComponent implements SourceComponent {
private static final String ATTRIBUTE_SUFFIX = "_vertex_in";
private final int baseIndex;
public InstancedArraysComponent(int baseIndex) {
this.baseIndex = baseIndex;
}
@Override
public Collection<? extends SourceComponent> included() {
return Collections.emptyList();
}
@Override
public String source(CompilationContext ctx) {
var generated = generateInstancedArrays("Instance");
return ctx.generatedHeader(generated, name().toString()) + generated;
}
@Override
public ResourceLocation name() {
return Flywheel.rl("generated_instanced_arrays");
}
public String generateInstancedArrays(String structName) {
var builder = new GlslBuilder();
builder.define("FlwInstance", structName);
int i = baseIndex;
for (var field : layoutItems) {
builder.vertexInput()
.binding(i)
.type(field.type.typeName())
.name(field.name + ATTRIBUTE_SUFFIX);
i += field.type.attributeCount();
}
builder.blankLine();
var structBuilder = builder.struct();
structBuilder.setName(structName);
for (var field : layoutItems) {
structBuilder.addField(field.type.typeName(), field.name);
}
builder.blankLine();
var func = builder.function()
.returnType(structName)
.name("flw_unpackInstance");
var args = layoutItems.stream()
.map(it -> new GlslExpr.Variable(it.name + ATTRIBUTE_SUFFIX))
.map(GlslExpr::minPrint)
.collect(Collectors.joining(", "));
func.statement("return " + structName + "(" + args + ");");
return builder.build();
}
}
public class IndirectComponent implements SourceComponent {
private static final String UNPACK_ARG = "p";
private static GlslExpr genGlslForLayoutItem(LayoutItem layoutItem) {
return GlslExpr.variable(UNPACK_ARG)
.access(layoutItem.name)
.transform(layoutItem.type::unpack);
}
@Override
public Collection<? extends SourceComponent> included() {
return List.of(Components.UTIL_TYPES.getFile());
}
@Override
public ResourceLocation name() {
return Flywheel.rl("generated_indirect");
}
@Override
public String source(CompilationContext ctx) {
var generated = generateIndirect("IndirectStruct");
return ctx.generatedHeader(generated, name().toString()) + generated;
}
public String generateIndirect(String structName) {
var builder = new GlslBuilder();
final var packedStructName = structName + "_packed";
builder.define("FlwInstance", structName);
builder.define("FlwPackedInstance", packedStructName);
var packed = builder.struct();
builder.blankLine();
var instance = builder.struct();
packed.setName(packedStructName);
instance.setName(structName);
for (var field : layoutItems) {
packed.addField(field.type.packedTypeName(), field.name);
instance.addField(field.type.typeName(), field.name);
}
builder.blankLine();
var func = builder.function()
.returnType(structName)
.name("flw_unpackInstance")
.argumentIn(packedStructName, UNPACK_ARG);
var args = layoutItems.stream()
.map(IndirectComponent::genGlslForLayoutItem)
.map(GlslExpr::minPrint)
.collect(Collectors.joining(", "));
func.statement("return " + structName + "(" + args + ");");
return builder.build();
}
}
}

View file

@ -6,70 +6,69 @@ import com.jozufozu.flywheel.backend.gl.array.VertexAttributeI;
public 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 VEC2_TYPE = "vec2";
private static final String FLOAT_TYPE = "float";
private static final String IVEC2_TYPE = "ivec2";
private static final String UINT_TYPE = "uint";
private static final String VEC4F_TYPE = "Vec4F";
private static final String VEC3F_TYPE = "Vec3F";
private static final String LIGHT_COORD_TYPE = "LightCoord";
public static final PrimitiveItem LIGHT_COORD = PrimitiveItem.builder()
.setAttribute(new VertexAttributeI(GlNumericType.USHORT, 2))
.setTypeName(IVEC2_TYPE)
.setPackedTypeName(LIGHT_COORD_TYPE)
.unpack(expr -> expr.callFunction("unpackLightCoord"))
.createPrimitiveItem();
public static final PrimitiveItem FLOAT = PrimitiveItem.builder()
.setAttribute(new VertexAttributeF(GlNumericType.FLOAT, 1, false))
.setTypeName(FLOAT_TYPE)
.setPackedTypeName(FLOAT_TYPE)
.createPrimitiveItem();
public static final PrimitiveItem NORM_3x8 = PrimitiveItem.builder()
.setAttribute(new VertexAttributeF(GlNumericType.BYTE, 3, true))
.setTypeName(VEC3_TYPE)
.setPackedTypeName(UINT_TYPE)
.unpack(expr -> expr.callFunction("unpackSnorm4x8")
.swizzle("xyz"))
.createPrimitiveItem();
public static final PrimitiveItem UNORM_4x8 = PrimitiveItem.builder()
.setAttribute(new VertexAttributeF(GlNumericType.UBYTE, 4, true))
.setTypeName(VEC4_TYPE)
.setPackedTypeName(UINT_TYPE)
.unpack(expr -> expr.callFunction("unpackUnorm4x8"))
.createPrimitiveItem();
public static final PrimitiveItem UNORM_3x8 = PrimitiveItem.builder()
.setAttribute(new VertexAttributeF(GlNumericType.UBYTE, 3, true))
.setTypeName(VEC3_TYPE)
.setPackedTypeName(UINT_TYPE)
.unpack(expr -> expr.callFunction("unpackUnorm4x8")
.swizzle("xyz"))
.createPrimitiveItem();
public static final PrimitiveItem VEC4 = PrimitiveItem.builder()
.setAttribute(new VertexAttributeF(GlNumericType.FLOAT, 4, false))
.setTypeName(VEC4_TYPE)
.setPackedTypeName(VEC4F_TYPE)
.unpack(expr -> expr.callFunction("unpackVec4F"))
.createPrimitiveItem();
public static final PrimitiveItem VEC3 = PrimitiveItem.builder()
.setAttribute(new VertexAttributeF(GlNumericType.FLOAT, 3, false))
.setTypeName(VEC3_TYPE)
.setPackedTypeName(VEC3F_TYPE)
.unpack(expr -> expr.callFunction("unpackVec3F"))
.createPrimitiveItem();
public static final PrimitiveItem VEC2 = PrimitiveItem.builder()
.setAttribute(new VertexAttributeF(GlNumericType.FLOAT, 2, false))
.setTypeName(VEC2_TYPE)
.setPackedTypeName(VEC2F_TYPE)
.unpack(expr -> expr.callFunction("unpackVec2F"))
.createPrimitiveItem();
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 = "LightCoord";
public static final VecInput LIGHT_COORD = VecInput.builder()
.vertexAttribute(new VertexAttributeI(GlNumericType.USHORT, 2))
.typeName(IVEC2_TYPE)
.packedTypeName(LIGHT_COORD_TYPE)
.unpackingFunction(expr -> expr.callFunction("unpackLightCoord"))
.build();
public static final VecInput FLOAT = VecInput.builder()
.vertexAttribute(new VertexAttributeF(GlNumericType.FLOAT, 1, false))
.typeName(FLOAT_TYPE)
.packedTypeName(FLOAT_TYPE)
.build();
public static final VecInput NORM_3x8 = VecInput.builder()
.vertexAttribute(new VertexAttributeF(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 VertexAttributeF(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 VertexAttributeF(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 VertexAttributeF(GlNumericType.FLOAT, 4, false))
.typeName(VEC4_TYPE)
.packedTypeName(VEC4F_TYPE)
.unpackingFunction(expr -> expr.callFunction("unpackVec4F"))
.build();
public static final VecInput VEC3 = VecInput.builder()
.vertexAttribute(new VertexAttributeF(GlNumericType.FLOAT, 3, false))
.typeName(VEC3_TYPE)
.packedTypeName(VEC3F_TYPE)
.unpackingFunction(expr -> expr.callFunction("unpackVec3F"))
.build();
public static final VecInput VEC2 = VecInput.builder()
.vertexAttribute(new VertexAttributeF(GlNumericType.FLOAT, 2, false))
.typeName(VEC2_TYPE)
.packedTypeName(VEC2F_TYPE)
.unpackingFunction(expr -> expr.callFunction("unpackVec2F"))
.build();
public static final MatrixItem MAT3 = new MatrixItem(3, 3, "mat3", "Mat3F", "unpackMat3F");
public static final MatrixItem MAT4 = new MatrixItem(4, 4, "mat4", "Mat4F", "unpackMat4F");
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 static class Unpacking {

View file

@ -0,0 +1,19 @@
package com.jozufozu.flywheel.core.layout;
import com.jozufozu.flywheel.core.source.generate.GlslBuilder;
import com.jozufozu.flywheel.core.source.generate.GlslExpr;
public record LayoutItem(InputType type, String name) {
public GlslExpr unpackField(GlslExpr.Variable struct) {
return struct.access(name())
.transform(type()::unpack);
}
public void addToStruct(GlslBuilder.StructBuilder structBuilder) {
structBuilder.addField(type().typeName(), name());
}
public void addPackedToStruct(GlslBuilder.StructBuilder packed) {
packed.addField(type().packedTypeName(), name());
}
}

View file

@ -7,8 +7,8 @@ import com.jozufozu.flywheel.backend.gl.array.VertexAttribute;
import com.jozufozu.flywheel.backend.gl.array.VertexAttributeF;
import com.jozufozu.flywheel.core.source.generate.GlslExpr;
public record MatrixItem(int rows, int cols, String typeName, String packedTypeName,
String unpackingFunction) implements InputType {
public record MatInput(int rows, int cols, String typeName, String packedTypeName,
String unpackingFunction) implements InputType {
@Override
public void provideAttributes(Consumer<VertexAttribute> consumer) {

View file

@ -6,14 +6,14 @@ import java.util.function.Function;
import com.jozufozu.flywheel.backend.gl.array.VertexAttribute;
import com.jozufozu.flywheel.core.source.generate.GlslExpr;
public class PrimitiveItem implements InputType {
public class VecInput implements InputType {
private final VertexAttribute attribute;
private final String typeName;
private final String packedTypeName;
private final Function<GlslExpr, GlslExpr> unpackingFunction;
public PrimitiveItem(VertexAttribute attribute, String typeName, String packedTypeName, Function<GlslExpr, GlslExpr> unpackingFunction) {
public VecInput(VertexAttribute attribute, String typeName, String packedTypeName, Function<GlslExpr, GlslExpr> unpackingFunction) {
this.attribute = attribute;
this.typeName = typeName;
this.packedTypeName = packedTypeName;
@ -40,8 +40,8 @@ public class PrimitiveItem implements InputType {
return 1;
}
public static PrimitiveItemBuilder builder() {
return new PrimitiveItemBuilder();
public static Builder builder() {
return new Builder();
}
@Override
@ -49,34 +49,34 @@ public class PrimitiveItem implements InputType {
return unpackingFunction.apply(packed);
}
public static class PrimitiveItemBuilder {
public static class Builder {
private VertexAttribute attribute;
private String typeName;
private String packedTypeName;
private Function<GlslExpr, GlslExpr> unpackingFunction = Function.identity();
public PrimitiveItemBuilder setAttribute(VertexAttribute attribute) {
public Builder vertexAttribute(VertexAttribute attribute) {
this.attribute = attribute;
return this;
}
public PrimitiveItemBuilder setTypeName(String typeName) {
public Builder typeName(String typeName) {
this.typeName = typeName;
return this;
}
public PrimitiveItemBuilder setPackedTypeName(String packedTypeName) {
public Builder packedTypeName(String packedTypeName) {
this.packedTypeName = packedTypeName;
return this;
}
public PrimitiveItemBuilder unpack(Function<GlslExpr, GlslExpr> f) {
public Builder unpackingFunction(Function<GlslExpr, GlslExpr> f) {
this.unpackingFunction = f;
return this;
}
public PrimitiveItem createPrimitiveItem() {
return new PrimitiveItem(attribute, typeName, packedTypeName, unpackingFunction);
public VecInput build() {
return new VecInput(attribute, typeName, packedTypeName, unpackingFunction);
}
}
}

View file

@ -54,12 +54,4 @@ public class SourceChecks {
return func;
}
public static BiConsumer<? super ErrorReporter, ? super SourceFile> checkDefine(String define) {
return (errorReporter, file) -> {
// if (!file.hasDefine(define)) {
// errorReporter.generateMissingDefine(file, define, "\"" + define + "\" define not defined");
// }
};
}
}

View file

@ -11,7 +11,7 @@ public class GlslBuilder {
private final List<SourceElement> elements = new ArrayList<>();
public void define(String name, String value) {
elements.add(new Define(name, value));
add(new Define(name, value));
}
public StructBuilder struct() {
@ -31,6 +31,9 @@ public class GlslBuilder {
return element;
}
public void blankLine() {
elements.add(Separators.BLANK_LINE);
}
public String build() {
return elements.stream()
@ -38,8 +41,8 @@ public class GlslBuilder {
.collect(Collectors.joining("\n"));
}
public void blankLine() {
elements.add(Separators.BLANK_LINE);
public interface SourceElement {
String build();
}
public enum Separators implements SourceElement {
@ -51,15 +54,11 @@ public class GlslBuilder {
Separators(String separator) {
this.separator = separator;
}
@Override
public String build() {
return separator;
}
}
public interface SourceElement {
String build();
}
public record Define(String name, String value) implements SourceElement {

View file

@ -1,6 +1,5 @@
#use "flywheel:api/vertex.glsl"
#use "flywheel:util/quaternion.glsl"
#use "flywheel:util/types.glsl"
void flw_transformBoundingSphere(in FlwInstance i, inout vec3 center, inout float radius) {
vec4 rotation = i.rotation;

View file

@ -1,5 +1,4 @@
#use "flywheel:api/vertex.glsl"
#use "flywheel:util/types.glsl"
void flw_transformBoundingSphere(in FlwInstance i, inout vec3 center, inout float radius) {
mat4 pose = i.pose;