diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java index beab8e28e..62a8c0cd7 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java @@ -6,9 +6,11 @@ import static org.lwjgl.opengl.GL20.GL_TEXTURE_2D; import static org.lwjgl.opengl.GL20.glActiveTexture; import static org.lwjgl.opengl.GL20.glBindTexture; +import java.util.ArrayList; import java.util.BitSet; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.SortedSet; import java.util.Vector; @@ -76,7 +78,7 @@ public class Backend { private static boolean enabled; static final Map> materialRegistry = new HashMap<>(); - static final Map> contexts = new HashMap<>(); + static final List> contexts = new ArrayList<>(); static final Map programSpecRegistry = new HashMap<>(); static { @@ -119,11 +121,7 @@ public class Backend { * Register a shader context. */ public static

ShaderContext

register(ShaderContext

spec) { - ResourceLocation name = spec.getRoot(); - if (contexts.containsKey(name)) { - throw new IllegalStateException("Program spec '" + name + "' already registered."); - } - contexts.put(name, spec); + contexts.add(spec); return spec; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/ShaderContext.java b/src/main/java/com/jozufozu/flywheel/backend/ShaderContext.java index b4318d18c..dd4e6a5a3 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/ShaderContext.java +++ b/src/main/java/com/jozufozu/flywheel/backend/ShaderContext.java @@ -6,9 +6,12 @@ import java.util.Map; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.gl.shader.IMultiProgram; import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec; +import com.jozufozu.flywheel.backend.gl.shader.ShaderConstants; import com.jozufozu.flywheel.backend.gl.shader.ShaderSpecLoader; -import com.jozufozu.flywheel.backend.loading.ProcessingStage; +import com.jozufozu.flywheel.backend.gl.shader.ShaderType; +import com.jozufozu.flywheel.backend.loading.Program; import com.jozufozu.flywheel.backend.loading.Shader; +import com.jozufozu.flywheel.backend.loading.ShaderTransformer; import net.minecraft.util.ResourceLocation; @@ -17,27 +20,49 @@ public abstract class ShaderContext

{ public final Map> programs = new HashMap<>(); public final ResourceLocation root; + protected final ShaderSpecLoader

specLoader; + protected ShaderTransformer transformer = new ShaderTransformer(); - public ShaderContext(ResourceLocation root) { + public ShaderContext(ResourceLocation root, ShaderSpecLoader

specLoader) { this.root = root; + this.specLoader = specLoader; } - public abstract ShaderSpecLoader

getLoader(); + // TODO: Untangle the loading functions + /** + * Load all programs associated with this context. This might be just one, if the context is very specialized. + */ public abstract void load(ShaderLoader loader); public void loadProgramFromSpec(ShaderLoader loader, ProgramSpec programSpec) { - programs.put(programSpec, getLoader().create(loader, this, programSpec)); + programs.put(programSpec, specLoader.create(loader, this, programSpec)); Backend.log.debug("Loaded program {}", programSpec.name); } - public void preProcess(ShaderLoader loader, Shader shader) { + public Program loadProgram(ProgramSpec spec, ShaderConstants defines, ShaderLoader loader) { + if (defines != null) + transformer.pushStage(defines); + + Shader vertexFile = loader.source(spec.vert, ShaderType.VERTEX); + Shader fragmentFile = loader.source(spec.frag, ShaderType.FRAGMENT); + + transformer.transformSource(vertexFile); + transformer.transformSource(fragmentFile); + + Program program = loader.loadProgram(spec.name, vertexFile, fragmentFile); + if (defines != null) + transformer.popStage(); + + preLink(program); + + return program.link(); } - public ProcessingStage loadingStage(ShaderLoader loader) { - return shader -> this.preProcess(loader, shader); + protected void preLink(Program program) { + } public P getProgram(ProgramSpec spec) { diff --git a/src/main/java/com/jozufozu/flywheel/backend/ShaderLoader.java b/src/main/java/com/jozufozu/flywheel/backend/ShaderLoader.java index a786efefb..569e2f3f4 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/ShaderLoader.java +++ b/src/main/java/com/jozufozu/flywheel/backend/ShaderLoader.java @@ -27,11 +27,10 @@ import org.lwjgl.system.MemoryUtil; import com.google.common.collect.Lists; import com.jozufozu.flywheel.backend.gl.GlObject; -import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.gl.shader.GlShader; import com.jozufozu.flywheel.backend.gl.shader.ShaderType; +import com.jozufozu.flywheel.backend.loading.Program; import com.jozufozu.flywheel.backend.loading.Shader; -import com.jozufozu.flywheel.backend.loading.ShaderTransformer; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.resources.IResource; @@ -59,26 +58,7 @@ public class ShaderLoader { shaderSource.clear(); loadShaderSources(manager); -// InstancedArraysTemplate template = new InstancedArraysTemplate(this); -// -// ResourceLocation name = new ResourceLocation("create", "test"); -// ResourceLocation vert = new ResourceLocation("create", "model_new.vert"); -// ResourceLocation frag = new ResourceLocation("create", "block_new.frag"); -// -// ShaderTransformer transformer = new ShaderTransformer() -// .pushStage(WorldContext.INSTANCE.loadingStage(this)) -// .pushStage(this::processIncludes) -// .pushStage(template) -// .pushStage(this::processIncludes); -// -// Shader vertexFile = this.source(vert, ShaderType.VERTEX); -// Shader fragmentFile = this.source(frag, ShaderType.FRAGMENT); -// -// GlProgram.Builder builder = loadProgram(name, transformer, vertexFile, fragmentFile); -// -// BasicProgram program = new BasicProgram(builder, GlFogMode.NONE.getFogFactory()); - - for (ShaderContext context : Backend.contexts.values()) { + for (ShaderContext context : Backend.contexts) { context.load(this); } @@ -122,32 +102,30 @@ public class ShaderLoader { return new Shader(type, name, getShaderSource(name)); } - public GlProgram.Builder loadProgram(ResourceLocation name, ShaderTransformer transformer, Shader... shaders) { - return loadProgram(name, transformer, Lists.newArrayList(shaders)); + public Program loadProgram(ResourceLocation name, Shader... shaders) { + return loadProgram(name, Lists.newArrayList(shaders)); } /** * Ingests the given shaders, compiling them and linking them together after applying the transformer to the source. * - * @param name What should we call this program if something goes wrong? - * @param transformer What should we do to the sources before compilation? - * @param shaders What are the different shader stages that should be linked together? - * @return A linked program builder. + * @param name What should we call this program if something goes wrong? + * @param shaders What are the different shader stages that should be linked together? + * @return A program with all provided shaders attached */ - public GlProgram.Builder loadProgram(ResourceLocation name, ShaderTransformer transformer, Collection shaders) { + public Program loadProgram(ResourceLocation name, Collection shaders) { List compiled = new ArrayList<>(shaders.size()); try { - GlProgram.Builder builder = GlProgram.builder(name); + Program builder = new Program(name); for (Shader shader : shaders) { - transformer.transformSource(shader); GlShader sh = new GlShader(shader); compiled.add(sh); - builder.attachShader(sh); + builder.attachShader(shader, sh); } - return builder.link(); + return builder; } finally { compiled.forEach(GlObject::delete); } @@ -180,7 +158,7 @@ public class ShaderLoader { ResourceLocation include = new ResourceLocation(includeName); if (seen.add(include)) { - String includeSource = shaderSource.get(include); + String includeSource = getShaderSource(include); if (includeSource != null) { return includeRecursive(includeSource, seen); diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/BasicProgram.java b/src/main/java/com/jozufozu/flywheel/backend/core/BasicProgram.java index 5d61e5924..80e554f39 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/core/BasicProgram.java +++ b/src/main/java/com/jozufozu/flywheel/backend/core/BasicProgram.java @@ -5,6 +5,7 @@ import static org.lwjgl.opengl.GL20.glUniform3f; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.gl.shader.ProgramFogMode; +import com.jozufozu.flywheel.backend.loading.Program; import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.util.ResourceLocation; @@ -20,7 +21,7 @@ public class BasicProgram extends GlProgram { protected int uBlockAtlas; protected int uLightMap; - public BasicProgram(GlProgram.Builder builder, ProgramFogMode.Factory fogFactory) { + public BasicProgram(Program builder, ProgramFogMode.Factory fogFactory) { this(builder.name, builder.program, fogFactory); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/WorldContext.java b/src/main/java/com/jozufozu/flywheel/backend/core/WorldContext.java index c0ee56f44..c2fbdcdbb 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/core/WorldContext.java +++ b/src/main/java/com/jozufozu/flywheel/backend/core/WorldContext.java @@ -2,8 +2,10 @@ package com.jozufozu.flywheel.backend.core; import java.util.EnumMap; import java.util.Map; +import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Stream; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.ResourceUtil; @@ -11,10 +13,15 @@ import com.jozufozu.flywheel.backend.ShaderContext; import com.jozufozu.flywheel.backend.ShaderLoader; import com.jozufozu.flywheel.backend.gl.shader.FogSensitiveProgram; import com.jozufozu.flywheel.backend.gl.shader.IMultiProgram; +import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec; import com.jozufozu.flywheel.backend.gl.shader.ShaderSpecLoader; import com.jozufozu.flywheel.backend.gl.shader.ShaderType; import com.jozufozu.flywheel.backend.instancing.MaterialSpec; +import com.jozufozu.flywheel.backend.loading.InstancedArraysTemplate; +import com.jozufozu.flywheel.backend.loading.Program; +import com.jozufozu.flywheel.backend.loading.ProgramTemplate; import com.jozufozu.flywheel.backend.loading.Shader; +import com.jozufozu.flywheel.backend.loading.ShaderTransformer; import net.minecraft.util.ResourceLocation; @@ -23,20 +30,30 @@ public class WorldContext

extends ShaderContext

{ private static final String declaration = "#flwbuiltins"; private static final Pattern builtinPattern = Pattern.compile(declaration); - public static final WorldContext INSTANCE = new WorldContext<>(new ResourceLocation("create", "context/std"), new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)); + public static final WorldContext INSTANCE = new WorldContext<>(new ResourceLocation("create", "context/world"), new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)); public static final WorldContext CRUMBLING = new WorldContext<>(new ResourceLocation("create", "context/crumbling"), new FogSensitiveProgram.SpecLoader<>(CrumblingProgram::new)); - private final ShaderSpecLoader

loader; - final Map builtins; + final Map builtinSources; + + protected ProgramTemplate template; + protected final Supplier> specStream; + protected final TemplateFactory templateFactory; public WorldContext(ResourceLocation root, ShaderSpecLoader

loader) { - super(root); + this(root, loader, () -> Backend.allMaterials() + .stream() + .map(MaterialSpec::getProgramSpec), InstancedArraysTemplate::new); + } + + public WorldContext(ResourceLocation root, ShaderSpecLoader

loader, Supplier> specStream, TemplateFactory templateFactory) { + super(root, loader); + this.specStream = specStream; + this.templateFactory = templateFactory; builtins = new EnumMap<>(ShaderType.class); + builtinSources = new EnumMap<>(ShaderType.class); builtins.put(ShaderType.FRAGMENT, ResourceUtil.subPath(root, "/builtin.frag")); builtins.put(ShaderType.VERTEX, ResourceUtil.subPath(root, "/builtin.vert")); - - this.loader = loader; } @Override @@ -44,26 +61,37 @@ public class WorldContext

extends ShaderContext

{ programs.values().forEach(IMultiProgram::delete); programs.clear(); - Backend.allMaterials() - .stream() - .map(MaterialSpec::getProgramSpec) - .forEach(spec -> loadProgramFromSpec(loader, spec)); + builtins.forEach((type, resourceLocation) -> builtinSources.put(type, loader.getShaderSource(resourceLocation))); + + template = templateFactory.create(loader); + transformer = new ShaderTransformer() + .pushStage(this::injectBuiltins) + .pushStage(loader::processIncludes) + .pushStage(Shader::parseStructs) + .pushStage(template) + .pushStage(loader::processIncludes); + + specStream.get().forEach(spec -> loadProgramFromSpec(loader, spec)); } @Override - public void preProcess(ShaderLoader loader, Shader shader) { - String builtinSrc = loader.getShaderSource(builtins.get(shader.type)); + protected void preLink(Program program) { + template.attachAttributes(program); + } + /** + * Replace #flwbuiltins with whatever expansion this context provides for the given shader. + */ + public void injectBuiltins(Shader shader) { Matcher matcher = builtinPattern.matcher(shader.getSource()); if (matcher.find()) - shader.setSource(matcher.replaceFirst(builtinSrc)); + shader.setSource(matcher.replaceFirst(builtinSources.get(shader.type))); else throw new RuntimeException(String.format("%s shader '%s' is missing %s, cannot use in World Context", shader.type.name, shader.name, declaration)); } - @Override - public ShaderSpecLoader

getLoader() { - return loader; + public interface TemplateFactory { + ProgramTemplate create(ShaderLoader loader); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/materials/BasicAttributes.java b/src/main/java/com/jozufozu/flywheel/backend/core/materials/BasicAttributes.java deleted file mode 100644 index 4309c1365..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/core/materials/BasicAttributes.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.jozufozu.flywheel.backend.core.materials; - -import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; -import com.jozufozu.flywheel.backend.gl.attrib.IAttribSpec; -import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; - -public enum BasicAttributes implements IVertexAttrib { - LIGHT("aLight", CommonAttributes.LIGHT), - COLOR("aColor", CommonAttributes.RGBA), - ; - - private final String name; - private final IAttribSpec spec; - - BasicAttributes(String name, IAttribSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - public String attribName() { - return name; - } - - @Override - public IAttribSpec attribSpec() { - return spec; - } - - @Override - public int getDivisor() { - return 0; - } - - @Override - public int getBufferIndex() { - return 0; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/materials/ModelAttributes.java b/src/main/java/com/jozufozu/flywheel/backend/core/materials/ModelAttributes.java deleted file mode 100644 index 16ed122dd..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/core/materials/ModelAttributes.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.jozufozu.flywheel.backend.core.materials; - -import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; -import com.jozufozu.flywheel.backend.gl.attrib.IAttribSpec; -import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; -import com.jozufozu.flywheel.backend.gl.attrib.VertexAttribSpec; - -public enum ModelAttributes implements IVertexAttrib { - VERTEX_POSITION("aPos", CommonAttributes.VEC3), - NORMAL("aNormal", CommonAttributes.NORMAL), - TEXTURE("aTexCoords", CommonAttributes.UV), - ; - - private final String name; - private final VertexAttribSpec spec; - - ModelAttributes(String name, VertexAttribSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - public String attribName() { - return name; - } - - @Override - public IAttribSpec attribSpec() { - return spec; - } - - @Override - public int getDivisor() { - return 0; - } - - @Override - public int getBufferIndex() { - return 0; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/materials/OrientedAttributes.java b/src/main/java/com/jozufozu/flywheel/backend/core/materials/OrientedAttributes.java deleted file mode 100644 index 9d74baef4..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/core/materials/OrientedAttributes.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.jozufozu.flywheel.backend.core.materials; - -import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; -import com.jozufozu.flywheel.backend.gl.attrib.IAttribSpec; -import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; - -public enum OrientedAttributes implements IVertexAttrib { - INSTANCE_POS("aInstancePos", CommonAttributes.VEC3), - PIVOT("aPivot", CommonAttributes.VEC3), - ROTATION("aRotation", CommonAttributes.QUATERNION), - ; - - private final String name; - private final IAttribSpec spec; - - OrientedAttributes(String name, IAttribSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - public String attribName() { - return name; - } - - @Override - public IAttribSpec attribSpec() { - return spec; - } - - @Override - public int getDivisor() { - return 0; - } - - @Override - public int getBufferIndex() { - return 0; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/materials/TransformAttributes.java b/src/main/java/com/jozufozu/flywheel/backend/core/materials/TransformAttributes.java deleted file mode 100644 index 48c85b185..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/core/materials/TransformAttributes.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.jozufozu.flywheel.backend.core.materials; - -import com.jozufozu.flywheel.backend.gl.attrib.IAttribSpec; -import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; -import com.jozufozu.flywheel.backend.gl.attrib.MatrixAttributes; - -public enum TransformAttributes implements IVertexAttrib { - TRANSFORM("aTransform", MatrixAttributes.MAT4), - NORMAL_MAT("aNormalMat", MatrixAttributes.MAT3), - ; - - private final String name; - private final IAttribSpec spec; - - TransformAttributes(String name, IAttribSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - public String attribName() { - return name; - } - - @Override - public IAttribSpec attribSpec() { - return spec; - } - - @Override - public int getDivisor() { - return 0; - } - - @Override - public int getBufferIndex() { - return 0; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlPrimitiveType.java b/src/main/java/com/jozufozu/flywheel/backend/gl/GlPrimitiveType.java index 3a143e3cf..1737c6bd4 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlPrimitiveType.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/GlPrimitiveType.java @@ -1,5 +1,12 @@ package com.jozufozu.flywheel.backend.gl; +import java.util.Arrays; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.annotation.Nullable; + import org.lwjgl.opengl.GL11; import net.minecraftforge.api.distmarker.Dist; @@ -15,6 +22,10 @@ public enum GlPrimitiveType { UINT(4, "uint", GL11.GL_UNSIGNED_INT), INT(4, "int", GL11.GL_INT); + private static final GlPrimitiveType[] VALUES = values(); + private static final Map NAME_LOOKUP = Arrays.stream(VALUES) + .collect(Collectors.toMap(GlPrimitiveType::getDisplayName, type -> type)); + private final int size; private final String displayName; private final int glConstant; @@ -36,4 +47,9 @@ public enum GlPrimitiveType { public int getGlConstant() { return this.glConstant; } + + @Nullable + public static GlPrimitiveType byName(String name) { + return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT)); + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/IVertexAttrib.java b/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/IVertexAttrib.java deleted file mode 100644 index 5775962d8..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/IVertexAttrib.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.jozufozu.flywheel.backend.gl.attrib; - -public interface IVertexAttrib { - - String attribName(); - - IAttribSpec attribSpec(); - - int getDivisor(); - - int getBufferIndex(); -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/VertexFormat.java b/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/VertexFormat.java index 714c7e677..9b325e6ed 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/VertexFormat.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/attrib/VertexFormat.java @@ -1,21 +1,20 @@ package com.jozufozu.flywheel.backend.gl.attrib; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; public class VertexFormat { - private final ArrayList allAttributes; + private final ArrayList allAttributes; private final int numAttributes; private final int stride; - public VertexFormat(ArrayList allAttributes) { + public VertexFormat(ArrayList allAttributes) { this.allAttributes = allAttributes; int numAttributes = 0, stride = 0; - for (IVertexAttrib attrib : allAttributes) { - IAttribSpec spec = attrib.attribSpec(); + for (IAttribSpec spec : allAttributes) { numAttributes += spec.getAttributeCount(); stride += spec.getSize(); } @@ -33,8 +32,7 @@ public class VertexFormat { public void vertexAttribPointers(int index) { int offset = 0; - for (IVertexAttrib attrib : this.allAttributes) { - IAttribSpec spec = attrib.attribSpec(); + for (IAttribSpec spec : this.allAttributes) { spec.vertexAttribPointer(stride, index, offset); index += spec.getAttributeCount(); offset += spec.getSize(); @@ -45,16 +43,14 @@ public class VertexFormat { return new Builder(); } - public static class Builder { - private final ArrayList allAttributes; + private final ArrayList allAttributes = new ArrayList<>(); public Builder() { - allAttributes = new ArrayList<>(); } - public & IVertexAttrib> Builder addAttributes(Class attribEnum) { - allAttributes.addAll(Arrays.asList(attribEnum.getEnumConstants())); + public Builder addAttributes(IAttribSpec... attributes) { + Collections.addAll(allAttributes, attributes); return this; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java index f8ee93fdc..8d6878dd1 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/buffer/MappedBuffer.java @@ -38,8 +38,12 @@ public abstract class MappedBuffer implements AutoCloseable { public MappedBuffer putFloatArray(float[] floats) { checkAndMap(); - internal.asFloatBuffer().put(floats); - internal.position(internal.position() + floats.length * 4); + + for (float f : floats) { + internal.putFloat(f); + } +// internal.asFloatBuffer().put(floats); +// internal.position(internal.position() + floats.length * 4); return this; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/FogSensitiveProgram.java b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/FogSensitiveProgram.java index ac158da54..7aa8ef21d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/FogSensitiveProgram.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/FogSensitiveProgram.java @@ -7,6 +7,7 @@ import com.jozufozu.flywheel.backend.ShaderContext; import com.jozufozu.flywheel.backend.ShaderLoader; import com.jozufozu.flywheel.backend.gl.GlFog; import com.jozufozu.flywheel.backend.gl.GlFogMode; +import com.jozufozu.flywheel.backend.loading.Program; import net.minecraft.util.ResourceLocation; @@ -45,7 +46,7 @@ public class FogSensitiveProgram

implements IMultiProgram

Builder addAttributes(Collection attributes) { - attributes.forEach(this::addAttribute); - return this; - } - - public Builder addAttribute(A attrib) { - glBindAttribLocation(this.program, attributeIndex, attrib.attribName()); - attributeIndex += attrib.attribSpec().getAttributeCount(); - return this; - } - - /** - * Links the attached shaders to this program. - */ - public Builder link() { - glLinkProgram(this.program); - - String log = glGetProgramInfoLog(this.program); - - if (!log.isEmpty()) { - Backend.log.debug("Program link log for " + this.name + ": " + log); - } - - int result = glGetProgrami(this.program, GL_LINK_STATUS); - - if (result != GL_TRUE) { - throw new RuntimeException("Shader program linking failed, see log for details"); - } - - return this; - } - } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/ProgramSpec.java b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/ProgramSpec.java index 4f1cfa0ae..247662d22 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/ProgramSpec.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/ProgramSpec.java @@ -1,15 +1,5 @@ package com.jozufozu.flywheel.backend.gl.shader; -import java.util.ArrayList; -import java.util.Arrays; - -import com.jozufozu.flywheel.backend.ShaderContext; -import com.jozufozu.flywheel.backend.ShaderLoader; -import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; -import com.jozufozu.flywheel.backend.loading.InstancedArraysTemplate; -import com.jozufozu.flywheel.backend.loading.Shader; -import com.jozufozu.flywheel.backend.loading.ShaderTransformer; - import net.minecraft.util.ResourceLocation; public class ProgramSpec { @@ -20,37 +10,15 @@ public class ProgramSpec { public final ShaderConstants defines; - public final ArrayList attributes; - public static Builder builder(ResourceLocation name) { return new Builder(name); } - public ProgramSpec(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, ShaderConstants defines, ArrayList attributes) { + public ProgramSpec(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, ShaderConstants defines) { this.name = name; this.vert = vert; this.frag = frag; this.defines = defines; - - this.attributes = attributes; - } - - public GlProgram.Builder loadProgram(ShaderContext ctx, ShaderConstants defines, ShaderLoader loader) { - InstancedArraysTemplate template = new InstancedArraysTemplate(loader); - - ShaderTransformer transformer = new ShaderTransformer() - .pushStage(ctx.loadingStage(loader)) -// .pushStage(loader::processIncludes) -// .pushStage(template) - .pushStage(loader::processIncludes); - - if (defines != null) - transformer.pushStage(defines); - - Shader vertexFile = loader.source(vert, ShaderType.VERTEX); - Shader fragmentFile = loader.source(frag, ShaderType.FRAGMENT); - return loader.loadProgram(name, transformer, vertexFile, fragmentFile) - .addAttributes(attributes); } public static class Builder { @@ -59,11 +27,9 @@ public class ProgramSpec { private ShaderConstants defines = ShaderConstants.EMPTY; private final ResourceLocation name; - private final ArrayList attributes; public Builder(ResourceLocation name) { this.name = name; - attributes = new ArrayList<>(); } public Builder setVert(ResourceLocation vert) { @@ -81,13 +47,8 @@ public class ProgramSpec { return this; } - public & IVertexAttrib> Builder addAttributes(Class attributeEnum) { - attributes.addAll(Arrays.asList(attributeEnum.getEnumConstants())); - return this; - } - - public ProgramSpec createProgramSpec() { - return new ProgramSpec(name, vert, frag, defines, attributes); + public ProgramSpec build() { + return new ProgramSpec(name, vert, frag, defines); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/ShaderSpecLoader.java b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/ShaderSpecLoader.java index a9d635c8e..f050ac981 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/ShaderSpecLoader.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/ShaderSpecLoader.java @@ -4,5 +4,12 @@ import com.jozufozu.flywheel.backend.ShaderContext; import com.jozufozu.flywheel.backend.ShaderLoader; public interface ShaderSpecLoader

{ + + /** + * @param loader + * @param ctx + * @param spec + * @return + */ IMultiProgram

create(ShaderLoader loader, ShaderContext

ctx, ProgramSpec spec); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/SingleProgram.java b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/SingleProgram.java index 844052880..a957d24b6 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/SingleProgram.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/SingleProgram.java @@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.gl.shader; import com.jozufozu.flywheel.backend.ShaderContext; import com.jozufozu.flywheel.backend.ShaderLoader; +import com.jozufozu.flywheel.backend.loading.Program; import net.minecraft.util.ResourceLocation; @@ -31,7 +32,7 @@ public class SingleProgram

implements IMultiProgram

{ @Override public IMultiProgram

create(ShaderLoader loader, ShaderContext

ctx, ProgramSpec spec) { - GlProgram.Builder builder = spec.loadProgram(ctx, spec.defines, loader); + Program builder = ctx.loadProgram(spec, spec.defines, loader); return new SingleProgram<>(factory.create(builder.name, builder.program)); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/loading/InstancedArraysTemplate.java b/src/main/java/com/jozufozu/flywheel/backend/loading/InstancedArraysTemplate.java index 66135e832..1314e66b9 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/loading/InstancedArraysTemplate.java +++ b/src/main/java/com/jozufozu/flywheel/backend/loading/InstancedArraysTemplate.java @@ -6,8 +6,17 @@ import com.jozufozu.flywheel.backend.gl.shader.ShaderType; import net.minecraft.util.ResourceLocation; public class InstancedArraysTemplate extends ProgramTemplate { - public static final String[] requiredVert = {"FLWInstanceData", "FLWVertexData", "FLWFragment"}; - public static final String[] requiredFrag = {"FLWFragment"}; + + public static final String vertexData = "VertexData"; + public static final String instanceData = "InstanceData"; + public static final String fragment = "Fragment"; + + public static final String vertexPrefix = "a_v_"; + public static final String instancePrefix = "a_i_"; + + public static final String[] requiredVert = new String[]{instanceData, vertexData, fragment}; + + public static final String[] requiredFrag = {fragment}; public static final ResourceLocation vert = new ResourceLocation("create", "template/instanced/instanced.vert"); public static final ResourceLocation frag = new ResourceLocation("create", "template/instanced/instanced.frag"); @@ -18,4 +27,12 @@ public class InstancedArraysTemplate extends ProgramTemplate { templates.put(ShaderType.VERTEX, new ShaderTemplate(requiredVert, loader.getShaderSource(vert))); templates.put(ShaderType.FRAGMENT, new ShaderTemplate(requiredFrag, loader.getShaderSource(frag))); } + + @Override + public void attachAttributes(Program builder) { + Shader shader = builder.attached.get(ShaderType.VERTEX); + + shader.getTag(vertexData).addPrefixedAttributes(builder, vertexPrefix); + shader.getTag(instanceData).addPrefixedAttributes(builder, instancePrefix); + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/loading/LayoutTag.java b/src/main/java/com/jozufozu/flywheel/backend/loading/LayoutTag.java new file mode 100644 index 000000000..ca6ab3445 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/loading/LayoutTag.java @@ -0,0 +1,19 @@ +package com.jozufozu.flywheel.backend.loading; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.jozufozu.flywheel.backend.gl.GlPrimitiveType; + +public class LayoutTag { + + public static final Pattern pattern = Pattern.compile("Layout\\((\\w+)(?:\\s*,\\s*(\\w*))?\\)"); + + final GlPrimitiveType type; + final boolean normalized; + + public LayoutTag(Matcher matcher) { + type = GlPrimitiveType.byName(matcher.group(1)); + normalized = Boolean.parseBoolean(matcher.group(2)); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/loading/ModelTemplate.java b/src/main/java/com/jozufozu/flywheel/backend/loading/ModelTemplate.java new file mode 100644 index 000000000..ffa650c73 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/loading/ModelTemplate.java @@ -0,0 +1,34 @@ +package com.jozufozu.flywheel.backend.loading; + +import com.jozufozu.flywheel.backend.ShaderLoader; +import com.jozufozu.flywheel.backend.gl.shader.ShaderType; + +import net.minecraft.util.ResourceLocation; + +public class ModelTemplate extends ProgramTemplate { + public static final String vertexData = "VertexData"; + public static final String fragment = "Fragment"; + + public static final String vertexPrefix = "a_v_"; + + public static final String[] requiredVert = new String[]{vertexData, fragment}; + + public static final String[] requiredFrag = {fragment}; + + public static final ResourceLocation vert = new ResourceLocation("create", "template/model/model.vert"); + public static final ResourceLocation frag = new ResourceLocation("create", "template/model/model.frag"); + + public ModelTemplate(ShaderLoader loader) { + super(loader); + + templates.put(ShaderType.VERTEX, new ShaderTemplate(requiredVert, loader.getShaderSource(vert))); + templates.put(ShaderType.FRAGMENT, new ShaderTemplate(requiredFrag, loader.getShaderSource(frag))); + } + + @Override + public void attachAttributes(Program builder) { + Shader shader = builder.attached.get(ShaderType.VERTEX); + + shader.getTag(vertexData).addPrefixedAttributes(builder, vertexPrefix); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/loading/ParsedShader.java b/src/main/java/com/jozufozu/flywheel/backend/loading/ParsedShader.java deleted file mode 100644 index a1f050cc5..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/loading/ParsedShader.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.jozufozu.flywheel.backend.loading; - -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import net.minecraft.util.ResourceLocation; - -public class ParsedShader { - private static final Pattern decorator = Pattern.compile("#\\[([\\w_]*)]"); - private static final Pattern taggedStruct = Pattern.compile("#\\[([\\w_]*)]\\s*struct\\s+([\\w\\d_]*)\\s*\\{(\\s*(?:.*;\\s*\\n)+\\s*)}\\s*;"); - - final ResourceLocation loc; - final String src; - - final Map tag2Struct = new HashMap<>(); - final Map name2Struct = new HashMap<>(); - - public ParsedShader(ResourceLocation loc, String src) { - this.loc = loc; - Matcher structs = taggedStruct.matcher(src); - - StringBuffer strippedSrc = new StringBuffer(); - while (structs.find()) { - TaggedStruct struct = new TaggedStruct(structs); - - structs.appendReplacement(strippedSrc, decorator.matcher(struct.source).replaceFirst("")); - - tag2Struct.put(struct.tag, struct); - name2Struct.put(struct.name, struct); - } - structs.appendTail(strippedSrc); - - this.src = strippedSrc.toString(); - } - - public TaggedStruct getTag(String tag) { - return tag2Struct.get(tag); - } - - public TaggedStruct getStruct(String name) { - return name2Struct.get(name); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/loading/Program.java b/src/main/java/com/jozufozu/flywheel/backend/loading/Program.java new file mode 100644 index 000000000..43f6fefe8 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/loading/Program.java @@ -0,0 +1,69 @@ +package com.jozufozu.flywheel.backend.loading; + +import static org.lwjgl.opengl.GL20.GL_LINK_STATUS; +import static org.lwjgl.opengl.GL20.GL_TRUE; +import static org.lwjgl.opengl.GL20.glAttachShader; +import static org.lwjgl.opengl.GL20.glBindAttribLocation; +import static org.lwjgl.opengl.GL20.glCreateProgram; +import static org.lwjgl.opengl.GL20.glGetProgramInfoLog; +import static org.lwjgl.opengl.GL20.glGetProgrami; +import static org.lwjgl.opengl.GL20.glLinkProgram; + +import java.util.EnumMap; +import java.util.Map; + +import com.jozufozu.flywheel.backend.Backend; +import com.jozufozu.flywheel.backend.gl.shader.GlShader; +import com.jozufozu.flywheel.backend.gl.shader.ShaderType; + +import net.minecraft.util.ResourceLocation; + +public class Program { + public final ResourceLocation name; + public final int program; + + private int attributeIndex; + + public final Map attached; + + public Program(ResourceLocation name) { + this.name = name; + this.program = glCreateProgram(); + attached = new EnumMap<>(ShaderType.class); + } + + public Program attachShader(Shader shader, GlShader glShader) { + glAttachShader(this.program, glShader.handle()); + + attached.put(shader.type, shader); + + return this; + } + + public Program addAttribute(String name, int attributeCount) { + glBindAttribLocation(this.program, attributeIndex, name); + attributeIndex += attributeCount; + return this; + } + + /** + * Links the attached shaders to this program. + */ + public Program link() { + glLinkProgram(this.program); + + String log = glGetProgramInfoLog(this.program); + + if (!log.isEmpty()) { + Backend.log.debug("Program link log for " + this.name + ": " + log); + } + + int result = glGetProgrami(this.program, GL_LINK_STATUS); + + if (result != GL_TRUE) { + throw new RuntimeException("Shader program linking failed, see log for details"); + } + + return this; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/loading/ProgramTemplate.java b/src/main/java/com/jozufozu/flywheel/backend/loading/ProgramTemplate.java index ea9378607..df2859cd5 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/loading/ProgramTemplate.java +++ b/src/main/java/com/jozufozu/flywheel/backend/loading/ProgramTemplate.java @@ -6,7 +6,7 @@ import java.util.Map; import com.jozufozu.flywheel.backend.ShaderLoader; import com.jozufozu.flywheel.backend.gl.shader.ShaderType; -public class ProgramTemplate implements ProcessingStage { +public abstract class ProgramTemplate implements ProcessingStage { protected final ShaderLoader loader; protected Map templates = new EnumMap<>(ShaderType.class); @@ -21,8 +21,10 @@ public class ProgramTemplate implements ProcessingStage { if (template == null) return; - ParsedShader parsedShader = new ParsedShader(shader.name, shader.getSource()); + shader.setSource(template.apply(shader)); + } + + public void attachAttributes(Program builder) { - shader.setSource(template.apply(parsedShader)); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/loading/Shader.java b/src/main/java/com/jozufozu/flywheel/backend/loading/Shader.java index 769e1ab5a..aa70847b8 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/loading/Shader.java +++ b/src/main/java/com/jozufozu/flywheel/backend/loading/Shader.java @@ -1,26 +1,32 @@ package com.jozufozu.flywheel.backend.loading; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import com.jozufozu.flywheel.backend.gl.shader.ShaderType; import net.minecraft.util.ResourceLocation; public class Shader { + private static final Pattern decorator = Pattern.compile("#\\[([\\w_]*)]"); + + public final ResourceLocation name; public ShaderType type; - public ResourceLocation name; private String source; + private boolean parsed = false; + final List structs = new ArrayList<>(3); + final Map tag2Struct = new HashMap<>(); + final Map name2Struct = new HashMap<>(); + public Shader(ShaderType type, ResourceLocation name, String source) { this.type = type; this.name = name; - this.setSource(source); - } - - public static Shader vert(ResourceLocation fileLoc, String source) { - return new Shader(ShaderType.VERTEX, fileLoc, source); - } - - public static Shader frag(ResourceLocation fileLoc, String source) { - return new Shader(ShaderType.FRAGMENT, fileLoc, source); + this.source = source; } public String getSource() { @@ -30,4 +36,41 @@ public class Shader { public void setSource(String source) { this.source = source; } + + public TaggedStruct getTag(String tag) { + checkAndParse(); + return tag2Struct.get(tag); + } + + public TaggedStruct getStruct(String name) { + checkAndParse(); + return name2Struct.get(name); + } + + private void checkAndParse() { + if (!parsed) { + parsed = true; + parseStructs(); + } + } + + public void parseStructs() { + Matcher structMatcher = TaggedStruct.taggedStruct.matcher(source); + + StringBuffer strippedSrc = new StringBuffer(); + + while (structMatcher.find()) { + TaggedStruct struct = new TaggedStruct(structMatcher); + + structs.add(struct); + + structMatcher.appendReplacement(strippedSrc, decorator.matcher(struct.source).replaceFirst("")); + + tag2Struct.put(struct.tag, struct); + name2Struct.put(struct.name, struct); + } + structMatcher.appendTail(strippedSrc); + + this.source = strippedSrc.toString(); + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/loading/ShaderTemplate.java b/src/main/java/com/jozufozu/flywheel/backend/loading/ShaderTemplate.java index cee98d09e..d2ed593f4 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/loading/ShaderTemplate.java +++ b/src/main/java/com/jozufozu/flywheel/backend/loading/ShaderTemplate.java @@ -2,7 +2,6 @@ package com.jozufozu.flywheel.backend.loading; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -32,14 +31,14 @@ public class ShaderTemplate { } - public String apply(ParsedShader shader) { + public String apply(Shader shader) { return header + - shader.src + + shader.getSource() + processBody(shader); } - public String processBody(ParsedShader shader) { + public String processBody(Shader shader) { String s = body; List missing = new ArrayList<>(); @@ -55,7 +54,7 @@ public class ShaderTemplate { } if (!missing.isEmpty()) { - String err = shader.loc + " is missing: " + String.join(", ", missing); + String err = shader.name + " is missing: " + String.join(", ", missing); throw new RuntimeException(err); } @@ -65,7 +64,7 @@ public class ShaderTemplate { return s; } - private String fillPrefixes(ParsedShader shader, String s) { + private String fillPrefixes(Shader shader, String s) { Matcher prefixMatches = prefixer.matcher(s); StringBuffer out = new StringBuffer(); @@ -77,13 +76,13 @@ public class ShaderTemplate { TaggedStruct struct = shader.getStruct(structName); StringBuilder builder = new StringBuilder(); - for (Map.Entry field : struct.fields.entrySet()) { + for (TaggedField field : struct.fields) { builder.append(modifier); builder.append(' '); - builder.append(field.getValue()); + builder.append(field.getType()); builder.append(' '); builder.append(prefix); - builder.append(field.getKey()); + builder.append(field.getName()); builder.append(";\n"); } @@ -93,7 +92,7 @@ public class ShaderTemplate { return out.toString(); } - private String fillAssigns(ParsedShader shader, String s) { + private String fillAssigns(Shader shader, String s) { Matcher assignMatches = assigner.matcher(s); StringBuffer out = new StringBuffer(); @@ -105,12 +104,12 @@ public class ShaderTemplate { TaggedStruct struct = shader.getStruct(structName); StringBuilder builder = new StringBuilder(); - for (String field : struct.fields.keySet()) { + for (TaggedField field : struct.fields) { builder.append(lhs); - builder.append(field); + builder.append(field.getName()); builder.append(" = "); builder.append(rhs); - builder.append(field); + builder.append(field.getName()); builder.append(";\n"); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/loading/ShaderTransformer.java b/src/main/java/com/jozufozu/flywheel/backend/loading/ShaderTransformer.java index ddd50c601..1eca0c1b3 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/loading/ShaderTransformer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/loading/ShaderTransformer.java @@ -16,6 +16,11 @@ public class ShaderTransformer { return this; } + public ShaderTransformer popStage() { + stages.removeLast(); + return this; + } + public ShaderTransformer prependStage(ProcessingStage stage) { if (stage != null) { stages.addFirst(stage); diff --git a/src/main/java/com/jozufozu/flywheel/backend/loading/TaggedField.java b/src/main/java/com/jozufozu/flywheel/backend/loading/TaggedField.java new file mode 100644 index 000000000..2d2cfdcdb --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/loading/TaggedField.java @@ -0,0 +1,48 @@ +package com.jozufozu.flywheel.backend.loading; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TaggedField { + public static final Pattern fieldPattern = Pattern.compile("(?:#\\[([^\\n]*)]\\s*)?(\\S+)\\s*(\\S+);"); + + public String annotation; + public String name; + public String type; + public LayoutTag layout; + + public TaggedField(Matcher fieldMatcher) { + annotation = fieldMatcher.group(1); + type = fieldMatcher.group(2); + name = fieldMatcher.group(3); + + if (annotation != null) { + Matcher matcher = LayoutTag.pattern.matcher(annotation); + + if (matcher.find()) { + layout = new LayoutTag(matcher); + } + } + } + + public String getAnnotation() { + return annotation; + } + + public String getName() { + return name; + } + + public String getType() { + return type; + } + + + @Override + public String toString() { + return "TaggedField{" + + "name='" + name + '\'' + + ", type='" + type + '\'' + + '}'; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/loading/TaggedStruct.java b/src/main/java/com/jozufozu/flywheel/backend/loading/TaggedStruct.java index 4249047c9..eac1ee079 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/loading/TaggedStruct.java +++ b/src/main/java/com/jozufozu/flywheel/backend/loading/TaggedStruct.java @@ -1,13 +1,16 @@ package com.jozufozu.flywheel.backend.loading; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class TaggedStruct { - public static final Pattern fieldPattern = Pattern.compile("(\\S+)\\s*(\\S+);"); + // https://regexr.com/5t207 + static final Pattern taggedStruct = Pattern.compile("#\\[(\\w*)]\\s*struct\\s+([\\w\\d]*)\\s*\\{([\\w\\d \\t#\\[\\](),;\\n]*)}\\s*;"); int srcStart, srcEnd; String source; @@ -15,7 +18,8 @@ public class TaggedStruct { String name; String body; - Map fields = new HashMap<>(); + List fields = new ArrayList<>(4); + Map fields2Types = new HashMap<>(); public TaggedStruct(Matcher foundMatcher) { this.source = foundMatcher.group(); @@ -27,10 +31,19 @@ public class TaggedStruct { name = foundMatcher.group(2); body = foundMatcher.group(3); - Matcher fielder = fieldPattern.matcher(body); + Matcher fielder = TaggedField.fieldPattern.matcher(body); while (fielder.find()) { - fields.put(fielder.group(2), fielder.group(1)); + fields.add(new TaggedField(fielder)); + fields2Types.put(fielder.group(2), fielder.group(1)); + } + } + + public void addPrefixedAttributes(Program builder, String prefix) { + for (TaggedField field : fields) { + int attributeCount = TypeHelper.getAttributeCount(field.type); + + builder.addAttribute(prefix + field.name, attributeCount); } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/loading/TypeHelper.java b/src/main/java/com/jozufozu/flywheel/backend/loading/TypeHelper.java new file mode 100644 index 000000000..2d67ff460 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/loading/TypeHelper.java @@ -0,0 +1,37 @@ +package com.jozufozu.flywheel.backend.loading; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TypeHelper { + + public static final Pattern vecType = Pattern.compile("^[biud]?vec([234])$"); + public static final Pattern matType = Pattern.compile("^mat([234])(?:x([234]))?$"); + + public static int getElementCount(String type) { + Matcher vec = vecType.matcher(type); + if (vec.find()) return Integer.parseInt(vec.group(1)); + + Matcher mat = matType.matcher(type); + if (mat.find()) { + int n = Integer.parseInt(mat.group(1)); + + String m = mat.group(2); + + if (m != null) return Integer.parseInt(m) * n; + + return n; + } + + return 1; + } + + public static int getAttributeCount(String type) { + Matcher mat = matType.matcher(type); + if (mat.find()) { + return Integer.parseInt(mat.group(1)); + } + + return 1; + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticAttributes.java deleted file mode 100644 index 3d9f31d5f..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticAttributes.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.simibubi.create.content.contraptions.base; - -import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; -import com.jozufozu.flywheel.backend.gl.attrib.IAttribSpec; -import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; -import com.jozufozu.flywheel.backend.gl.attrib.VertexAttribSpec; - -public enum KineticAttributes implements IVertexAttrib { - INSTANCE_POSITION("aInstancePos", CommonAttributes.VEC3), - SPEED("aSpeed", CommonAttributes.FLOAT), - OFFSET("aOffset", CommonAttributes.FLOAT), - ; - - private final String name; - private final VertexAttribSpec spec; - - KineticAttributes(String name, VertexAttribSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - public String attribName() { - return name; - } - - @Override - public IAttribSpec attribSpec() { - return spec; - } - - @Override - public int getDivisor() { - return 1; - } - - @Override - public int getBufferIndex() { - return 1; - } -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/base/RotatingAttributes.java deleted file mode 100644 index 215027123..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/base/RotatingAttributes.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.simibubi.create.content.contraptions.base; - -import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; -import com.jozufozu.flywheel.backend.gl.attrib.IAttribSpec; -import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; -import com.jozufozu.flywheel.backend.gl.attrib.VertexAttribSpec; - -public enum RotatingAttributes implements IVertexAttrib { - AXIS("aAxis", CommonAttributes.NORMAL), - ; - - private final String name; - private final VertexAttribSpec spec; - - RotatingAttributes(String name, VertexAttribSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - public String attribName() { - return name; - } - - @Override - public IAttribSpec attribSpec() { - return spec; - } - - @Override - public int getDivisor() { - return 1; - } - - @Override - public int getBufferIndex() { - return 1; - } -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorVertexAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorVertexAttributes.java deleted file mode 100644 index 696d9279a..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/ActorVertexAttributes.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.simibubi.create.content.contraptions.components.actors; - -import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; -import com.jozufozu.flywheel.backend.gl.attrib.IAttribSpec; -import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; -import com.jozufozu.flywheel.backend.gl.attrib.VertexAttribSpec; - -public enum ActorVertexAttributes implements IVertexAttrib { - INSTANCE_POSITION("aInstancePos", CommonAttributes.VEC3), - LIGHT("aModelLight", CommonAttributes.LIGHT), - OFFSET("aOffset", CommonAttributes.FLOAT), - AXIS("aAxis", CommonAttributes.NORMAL), - INSTANCE_ROTATION("aInstanceRot", CommonAttributes.QUATERNION), - ROTATION_CENTER("aRotationCenter", CommonAttributes.NORMAL), - SPEED("aSpeed", CommonAttributes.FLOAT), - ; - - private final String name; - private final VertexAttribSpec spec; - - ActorVertexAttributes(String name, VertexAttribSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - public String attribName() { - return name; - } - - @Override - public IAttribSpec attribSpec() { - return spec; - } - - @Override - public int getDivisor() { - return 1; - } - - @Override - public int getBufferIndex() { - return 1; - } -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionAttributes.java deleted file mode 100644 index 649f5e680..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionAttributes.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.simibubi.create.content.contraptions.components.structureMovement.render; - -import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; -import com.jozufozu.flywheel.backend.gl.attrib.IAttribSpec; -import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; -import com.jozufozu.flywheel.backend.gl.attrib.VertexAttribSpec; - -public enum ContraptionAttributes implements IVertexAttrib { - VERTEX_POSITION("aPos", CommonAttributes.VEC3), - NORMAL("aNormal", CommonAttributes.NORMAL), - TEXTURE("aTexCoords", CommonAttributes.UV), - COLOR("aColor", CommonAttributes.RGBA), - MODEL_LIGHT("aModelLight", CommonAttributes.LIGHT), - ; - - private final String name; - private final VertexAttribSpec spec; - - ContraptionAttributes(String name, VertexAttribSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - public String attribName() { - return name; - } - - @Override - public IAttribSpec attribSpec() { - return spec; - } - - @Override - public int getDivisor() { - return 0; - } - - @Override - public int getBufferIndex() { - return 0; - } -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionContext.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionContext.java deleted file mode 100644 index e3bf437dd..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionContext.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.simibubi.create.content.contraptions.components.structureMovement.render; - -import com.jozufozu.flywheel.backend.ShaderLoader; -import com.jozufozu.flywheel.backend.core.WorldContext; -import com.jozufozu.flywheel.backend.gl.shader.FogSensitiveProgram; -import com.simibubi.create.foundation.render.AllProgramSpecs; - -import net.minecraft.util.ResourceLocation; - -public class ContraptionContext extends WorldContext { - - public static final ContraptionContext INSTANCE = new ContraptionContext(); - - public ContraptionContext() { - super(new ResourceLocation("create", "context/contraption"), new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new)); - } - - @Override - public void load(ShaderLoader loader) { - super.load(loader); - - loadProgramFromSpec(loader, AllProgramSpecs.STRUCTURE); - } -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java index a65f178fa..b10f10f2c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionKineticRenderer.java @@ -26,7 +26,7 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer contraption; ContraptionKineticRenderer(RenderedContraption contraption) { - super(ContraptionContext.INSTANCE); + super(ContraptionRenderDispatcher.TILES); this.contraption = new WeakReference<>(contraption); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java index d98369b87..6d0c80d0f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java @@ -10,10 +10,14 @@ import static org.lwjgl.opengl.GL13.glEnable; import java.util.List; import java.util.Random; +import java.util.stream.Stream; import org.apache.commons.lang3.tuple.Pair; import com.jozufozu.flywheel.backend.Backend; +import com.jozufozu.flywheel.backend.core.WorldContext; +import com.jozufozu.flywheel.backend.gl.shader.FogSensitiveProgram; +import com.jozufozu.flywheel.backend.loading.ModelTemplate; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllMovementBehaviours; import com.simibubi.create.CreateClient; @@ -48,6 +52,7 @@ import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.world.ClientWorld; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.world.LightType; @@ -59,6 +64,9 @@ import net.minecraftforge.client.model.data.EmptyModelData; public class ContraptionRenderDispatcher { public static final Int2ObjectMap renderers = new Int2ObjectOpenHashMap<>(); public static final Compartment> CONTRAPTION = new Compartment<>(); + private static final ResourceLocation ctxRoot = new ResourceLocation("create", "context/contraption"); + public static final WorldContext STRUCTURE = new WorldContext<>(ctxRoot, new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new), () -> Stream.of(AllProgramSpecs.STRUCTURE), ModelTemplate::new); + public static final WorldContext TILES = new WorldContext<>(ctxRoot, new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new)); protected static PlacementSimulationWorld renderWorld; public static void tick() { @@ -90,7 +98,7 @@ public class ContraptionRenderDispatcher { glActiveTexture(GL_TEXTURE4); // the shaders expect light volumes to be in texture 4 if (Backend.canUseVBOs()) { - ContraptionProgram structureShader = ContraptionContext.INSTANCE.getProgram(AllProgramSpecs.STRUCTURE); + ContraptionProgram structureShader = STRUCTURE.getProgram(AllProgramSpecs.STRUCTURE); structureShader.bind(); structureShader.uploadViewProjection(viewProjection); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java index 079ae0524..a05c3d5be 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java @@ -14,6 +14,7 @@ import org.lwjgl.opengl.GL11; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.core.IndexedModel; +import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; import com.jozufozu.flywheel.backend.instancing.IInstanceRendered; import com.jozufozu.flywheel.backend.light.GridAlignedBB; @@ -49,7 +50,11 @@ import net.minecraftforge.client.model.data.EmptyModelData; public class RenderedContraption { public static final VertexFormat FORMAT = VertexFormat.builder() - .addAttributes(ContraptionAttributes.class) + .addAttributes(CommonAttributes.VEC3, + CommonAttributes.NORMAL, + CommonAttributes.UV, + CommonAttributes.RGBA, + CommonAttributes.LIGHT) .build(); private static final BlockModelRenderer MODEL_RENDERER = new BlockModelRenderer(Minecraft.getInstance().getBlockColors()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltAttributes.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltAttributes.java deleted file mode 100644 index 6a7b20814..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltAttributes.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.simibubi.create.content.contraptions.relays.belt; - -import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; -import com.jozufozu.flywheel.backend.gl.attrib.IAttribSpec; -import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; -import com.jozufozu.flywheel.backend.gl.attrib.VertexAttribSpec; - -public enum BeltAttributes implements IVertexAttrib { - INSTANCE_ROTATION("aInstanceRot", CommonAttributes.QUATERNION), - SOURCE_TEX("aSourceTexture", CommonAttributes.UV), - SCROLL_TEX("aScrollTexture", CommonAttributes.VEC4), - SCROLL_MULT("aScrollMult", CommonAttributes.NORMALIZED_BYTE), - ; - - private final String name; - private final VertexAttribSpec spec; - - BeltAttributes(String name, VertexAttribSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - public String attribName() { - return name; - } - - @Override - public IAttribSpec attribSpec() { - return spec; - } - - @Override - public int getDivisor() { - return 1; - } - - @Override - public int getBufferIndex() { - return 1; - } -} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/FlapAttributes.java b/src/main/java/com/simibubi/create/content/logistics/block/FlapAttributes.java deleted file mode 100644 index ad6864629..000000000 --- a/src/main/java/com/simibubi/create/content/logistics/block/FlapAttributes.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.simibubi.create.content.logistics.block; - -import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; -import com.jozufozu.flywheel.backend.gl.attrib.IAttribSpec; -import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; -import com.jozufozu.flywheel.backend.gl.attrib.VertexAttribSpec; - -public enum FlapAttributes implements IVertexAttrib { - INSTANCE_POSITION("aInstancePos",CommonAttributes.VEC3), - LIGHT("aLight", CommonAttributes.LIGHT), - SEGMENT_OFFSET("aSegmentOffset", CommonAttributes.VEC3), - PIVOT("aPivot", CommonAttributes.VEC3), - HORIZONTAL_ANGLE("aHorizontalAngle", CommonAttributes.FLOAT), - INTENSITY("aIntensity", CommonAttributes.FLOAT), - FLAP_SCALE("aFlapScale", CommonAttributes.FLOAT), - FLAPNESS("aFlapness", CommonAttributes.FLOAT), - ; - - private final String name; - private final VertexAttribSpec spec; - - FlapAttributes(String name, VertexAttribSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - public String attribName() { - return name; - } - - @Override - public IAttribSpec attribSpec() { - return spec; - } - - @Override - public int getDivisor() { - return 1; - } - - @Override - public int getBufferIndex() { - return 1; - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/AllInstanceFormats.java b/src/main/java/com/simibubi/create/foundation/render/AllInstanceFormats.java index 70c2bf3e6..4fb31d1b8 100644 --- a/src/main/java/com/simibubi/create/foundation/render/AllInstanceFormats.java +++ b/src/main/java/com/simibubi/create/foundation/render/AllInstanceFormats.java @@ -1,39 +1,47 @@ package com.simibubi.create.foundation.render; -import com.jozufozu.flywheel.backend.core.materials.BasicAttributes; -import com.jozufozu.flywheel.backend.core.materials.OrientedAttributes; -import com.jozufozu.flywheel.backend.core.materials.TransformAttributes; +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.simibubi.create.content.contraptions.base.KineticAttributes; -import com.simibubi.create.content.contraptions.base.RotatingAttributes; -import com.simibubi.create.content.contraptions.components.actors.ActorVertexAttributes; -import com.simibubi.create.content.contraptions.relays.belt.BeltAttributes; -import com.simibubi.create.content.logistics.block.FlapAttributes; public class AllInstanceFormats { - public static final VertexFormat MODEL = VertexFormat.builder() - .addAttributes(BasicAttributes.class) - .addAttributes(TransformAttributes.class) + public static final VertexFormat MODEL = litInstance() + .addAttributes(MatrixAttributes.MAT4, + MatrixAttributes.MAT3) .build(); - public static final VertexFormat ORIENTED = VertexFormat.builder() - .addAttributes(BasicAttributes.class) - .addAttributes(OrientedAttributes.class) + + public static final VertexFormat ORIENTED = litInstance() + .addAttributes(CommonAttributes.VEC3, CommonAttributes.VEC3, CommonAttributes.QUATERNION) .build(); - public static VertexFormat ROTATING = VertexFormat.builder() - .addAttributes(BasicAttributes.class) - .addAttributes(KineticAttributes.class) - .addAttributes(RotatingAttributes.class) + + public static VertexFormat ROTATING = kineticInstance() + .addAttributes(CommonAttributes.NORMAL) .build(); + + public static VertexFormat BELT = kineticInstance() + .addAttributes(CommonAttributes.QUATERNION, CommonAttributes.UV, CommonAttributes.VEC4, + CommonAttributes.NORMALIZED_BYTE) + .build(); + public static VertexFormat ACTOR = VertexFormat.builder() - .addAttributes(ActorVertexAttributes.class) - .build(); - public static VertexFormat BELT = VertexFormat.builder() - .addAttributes(BasicAttributes.class) - .addAttributes(KineticAttributes.class) - .addAttributes(BeltAttributes.class) + .addAttributes(CommonAttributes.VEC3, CommonAttributes.LIGHT, CommonAttributes.FLOAT, + CommonAttributes.NORMAL, CommonAttributes.QUATERNION, CommonAttributes.NORMAL, + CommonAttributes.FLOAT) .build(); + public static VertexFormat FLAP = VertexFormat.builder() - .addAttributes(FlapAttributes.class) + .addAttributes(CommonAttributes.VEC3, CommonAttributes.LIGHT, CommonAttributes.VEC3, CommonAttributes.VEC3, + CommonAttributes.FLOAT, CommonAttributes.FLOAT, CommonAttributes.FLOAT, CommonAttributes.FLOAT) .build(); + + private static VertexFormat.Builder litInstance() { + return VertexFormat.builder() + .addAttributes(CommonAttributes.LIGHT, CommonAttributes.RGBA); + } + + private static VertexFormat.Builder kineticInstance() { + return litInstance() + .addAttributes(CommonAttributes.VEC3, CommonAttributes.FLOAT, CommonAttributes.FLOAT); + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/AllMaterialSpecs.java b/src/main/java/com/simibubi/create/foundation/render/AllMaterialSpecs.java index 374bcb368..4a9d1a3da 100644 --- a/src/main/java/com/simibubi/create/foundation/render/AllMaterialSpecs.java +++ b/src/main/java/com/simibubi/create/foundation/render/AllMaterialSpecs.java @@ -2,9 +2,9 @@ package com.simibubi.create.foundation.render; import static com.jozufozu.flywheel.backend.Backend.register; -import com.jozufozu.flywheel.backend.core.materials.ModelAttributes; import com.jozufozu.flywheel.backend.core.materials.ModelData; import com.jozufozu.flywheel.backend.core.materials.OrientedData; +import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat; import com.jozufozu.flywheel.backend.instancing.MaterialSpec; import com.simibubi.create.Create; @@ -20,7 +20,9 @@ public class AllMaterialSpecs { // noop, make sure the static field are loaded. } - public static final VertexFormat UNLIT_MODEL = VertexFormat.builder().addAttributes(ModelAttributes.class).build(); + public static final VertexFormat UNLIT_MODEL = VertexFormat.builder() + .addAttributes(CommonAttributes.VEC3, CommonAttributes.NORMAL, CommonAttributes.UV) + .build(); public static final MaterialSpec TRANSFORMED = register(new MaterialSpec<>(Locations.MODEL, AllProgramSpecs.MODEL, UNLIT_MODEL, AllInstanceFormats.MODEL, ModelData::new)); public static final MaterialSpec ORIENTED = register(new MaterialSpec<>(Locations.ORIENTED, AllProgramSpecs.ORIENTED, UNLIT_MODEL, AllInstanceFormats.ORIENTED, OrientedData::new)); diff --git a/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java b/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java index a4b8fbccb..bf67269e3 100644 --- a/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java +++ b/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java @@ -2,19 +2,9 @@ package com.simibubi.create.foundation.render; import static com.jozufozu.flywheel.backend.Backend.register; -import com.jozufozu.flywheel.backend.core.materials.BasicAttributes; -import com.jozufozu.flywheel.backend.core.materials.ModelAttributes; -import com.jozufozu.flywheel.backend.core.materials.OrientedAttributes; -import com.jozufozu.flywheel.backend.core.materials.TransformAttributes; import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec; import com.jozufozu.flywheel.backend.gl.shader.ShaderConstants; import com.simibubi.create.Create; -import com.simibubi.create.content.contraptions.base.KineticAttributes; -import com.simibubi.create.content.contraptions.base.RotatingAttributes; -import com.simibubi.create.content.contraptions.components.actors.ActorVertexAttributes; -import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionAttributes; -import com.simibubi.create.content.contraptions.relays.belt.BeltAttributes; -import com.simibubi.create.content.logistics.block.FlapAttributes; import net.minecraft.util.ResourceLocation; @@ -24,66 +14,44 @@ public class AllProgramSpecs { } public static final ProgramSpec CHROMATIC = register(builder("chromatic") - .addAttributes(ModelAttributes.class) - .addAttributes(BasicAttributes.class) - .addAttributes(TransformAttributes.class) .setVert(Locations.EFFECT_VERT) .setFrag(Locations.EFFECT_FRAG) - .createProgramSpec()); + .build()); public static final ProgramSpec MODEL = register(builder("model") - .addAttributes(ModelAttributes.class) - .addAttributes(BasicAttributes.class) - .addAttributes(TransformAttributes.class) .setVert(Locations.MODEL_VERT) .setFrag(Locations.BLOCK) - .createProgramSpec()); + .build()); public static final ProgramSpec ORIENTED = register(builder("oriented") - .addAttributes(ModelAttributes.class) - .addAttributes(BasicAttributes.class) - .addAttributes(OrientedAttributes.class) .setVert(Locations.ORIENTED) .setFrag(Locations.BLOCK) - .createProgramSpec()); + .build()); public static final ProgramSpec ROTATING = register(builder("rotating") - .addAttributes(ModelAttributes.class) - .addAttributes(BasicAttributes.class) - .addAttributes(KineticAttributes.class) - .addAttributes(RotatingAttributes.class) .setVert(Locations.ROTATING) .setFrag(Locations.BLOCK) - .createProgramSpec()); + .build()); public static final ProgramSpec BELT = register(builder("belt") - .addAttributes(ModelAttributes.class) - .addAttributes(BasicAttributes.class) - .addAttributes(KineticAttributes.class) - .addAttributes(BeltAttributes.class) .setVert(Locations.BELT) .setFrag(Locations.BLOCK) - .createProgramSpec()); + .build()); public static final ProgramSpec FLAPS = register(builder("flap") - .addAttributes(ModelAttributes.class) - .addAttributes(FlapAttributes.class) .setVert(Locations.FLAP) .setFrag(Locations.BLOCK) - .createProgramSpec()); + .build()); public static final ProgramSpec STRUCTURE = register(builder("contraption_structure") - .addAttributes(ContraptionAttributes.class) .setVert(Locations.CONTRAPTION_STRUCTURE) .setFrag(Locations.BLOCK) .setDefines(ShaderConstants.define("CONTRAPTION")) - .createProgramSpec()); + .build()); public static final ProgramSpec ACTOR = register(builder("contraption_actor") - .addAttributes(ModelAttributes.class) - .addAttributes(ActorVertexAttributes.class) .setVert(Locations.CONTRAPTION_ACTOR) .setFrag(Locations.BLOCK) .setDefines(ShaderConstants.define("CONTRAPTION")) - .createProgramSpec()); + .build()); public static ProgramSpec.Builder builder(String name) { return ProgramSpec.builder(new ResourceLocation(Create.ID, name)); diff --git a/src/main/java/com/simibubi/create/foundation/render/CreateFlywheelHandler.java b/src/main/java/com/simibubi/create/foundation/render/CreateFlywheelHandler.java index 7f3d4a05f..7dc49abdf 100644 --- a/src/main/java/com/simibubi/create/foundation/render/CreateFlywheelHandler.java +++ b/src/main/java/com/simibubi/create/foundation/render/CreateFlywheelHandler.java @@ -1,14 +1,14 @@ package com.simibubi.create.foundation.render; import com.jozufozu.flywheel.backend.Backend; -import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionContext; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; import com.simibubi.create.foundation.fluid.FluidRenderer; import com.simibubi.create.foundation.render.effects.EffectsContext; public class CreateFlywheelHandler { public static void init() { - Backend.register(ContraptionContext.INSTANCE); + Backend.register(ContraptionRenderDispatcher.TILES); + Backend.register(ContraptionRenderDispatcher.STRUCTURE); Backend.register(EffectsContext.INSTANCE); Backend.listeners.renderLayerListener(ContraptionRenderDispatcher::renderLayer); Backend.listeners.renderLayerListener(FluidRenderer::renderLayer); diff --git a/src/main/java/com/simibubi/create/foundation/render/effects/EffectsContext.java b/src/main/java/com/simibubi/create/foundation/render/effects/EffectsContext.java index 00f47c505..f02261b66 100644 --- a/src/main/java/com/simibubi/create/foundation/render/effects/EffectsContext.java +++ b/src/main/java/com/simibubi/create/foundation/render/effects/EffectsContext.java @@ -2,8 +2,8 @@ package com.simibubi.create.foundation.render.effects; import com.jozufozu.flywheel.backend.ShaderContext; import com.jozufozu.flywheel.backend.ShaderLoader; -import com.jozufozu.flywheel.backend.gl.shader.ShaderSpecLoader; import com.jozufozu.flywheel.backend.gl.shader.SingleProgram; +import com.jozufozu.flywheel.backend.loading.ShaderTransformer; import com.simibubi.create.foundation.render.AllProgramSpecs; import net.minecraft.util.ResourceLocation; @@ -12,20 +12,14 @@ public class EffectsContext extends ShaderContext { public static final EffectsContext INSTANCE = new EffectsContext(); - private final SingleProgram.SpecLoader loader; - public EffectsContext() { - super(new ResourceLocation("create", "effects")); - loader = new SingleProgram.SpecLoader<>(SphereFilterProgram::new); + super(new ResourceLocation("create", "effects"), new SingleProgram.SpecLoader<>(SphereFilterProgram::new)); } @Override public void load(ShaderLoader loader) { + transformer = new ShaderTransformer() + .pushStage(loader::processIncludes); loadProgramFromSpec(loader, AllProgramSpecs.CHROMATIC); } - - @Override - public ShaderSpecLoader getLoader() { - return loader; - } } diff --git a/src/main/java/com/simibubi/create/foundation/render/effects/ScreenQuadAttributes.java b/src/main/java/com/simibubi/create/foundation/render/effects/ScreenQuadAttributes.java deleted file mode 100644 index 0c7833527..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/effects/ScreenQuadAttributes.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.simibubi.create.foundation.render.effects; - -import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes; -import com.jozufozu.flywheel.backend.gl.attrib.IAttribSpec; -import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; - -public enum ScreenQuadAttributes implements IVertexAttrib { - INSTANCE_POS("aVertex", CommonAttributes.VEC4), - ; - - private final String name; - private final IAttribSpec spec; - - ScreenQuadAttributes(String name, IAttribSpec spec) { - this.name = name; - this.spec = spec; - } - - @Override - public String attribName() { - return name; - } - - @Override - public IAttribSpec attribSpec() { - return spec; - } - - @Override - public int getDivisor() { - return 0; - } - - @Override - public int getBufferIndex() { - return 0; - } -} diff --git a/src/main/resources/assets/create/flywheel/shaders/belt.vert b/src/main/resources/assets/create/flywheel/shaders/belt.vert index 052520d2d..5d94c0f35 100644 --- a/src/main/resources/assets/create/flywheel/shaders/belt.vert +++ b/src/main/resources/assets/create/flywheel/shaders/belt.vert @@ -1,4 +1,3 @@ -#version 110 #define PI 3.1415926538 #flwbuiltins @@ -6,55 +5,45 @@ #flwinclude <"create:core/matutils.glsl"> #flwinclude <"create:core/diffuse.glsl"> -attribute vec3 aPos; -attribute vec3 aNormal; -attribute vec2 aTexCoords; +#[InstanceData] +struct Belt { + vec2 light; + vec4 color; + vec3 pos; + float speed; + float offset; + vec4 rotation; + vec2 sourceTexture; + vec4 scrollTexture; + float scrollMult; +}; -attribute vec2 aLight; -attribute vec4 aColor; -attribute vec3 aInstancePos; -attribute float aSpeed; -attribute float aOffset; -attribute vec4 aInstanceRot; -attribute vec2 aSourceTexture; -attribute vec4 aScrollTexture; -attribute float aScrollMult; +#flwinclude <"create:data/modelvertex.glsl"> +#flwinclude <"create:data/blockfragment.glsl"> -varying vec2 TexCoords; -varying vec4 Color; -varying float Diffuse; -varying vec2 Light; - -void main() { - vec3 rotated = rotateVertexByQuat(aPos - .5, aInstanceRot) + aInstancePos + .5; +BlockFrag FLWMain(Vertex v, Belt instance) { + vec3 rotated = rotateVertexByQuat(v.pos - .5, instance.rotation) + instance.pos + .5; vec4 worldPos = vec4(rotated, 1.); - vec3 norm = rotateVertexByQuat(aNormal, aInstanceRot); + vec3 norm = rotateVertexByQuat(v.normal, instance.rotation); FLWFinalizeWorldPos(worldPos); FLWFinalizeNormal(norm); - float scrollSize = aScrollTexture.w - aScrollTexture.y; - float scroll = fract(aSpeed * uTime / (31.5 * 16.) + aOffset) * scrollSize * aScrollMult; + float scrollSize = instance.scrollTexture.w - instance.scrollTexture.y; + float scroll = fract(instance.speed * uTime / (31.5 * 16.) + instance.offset) * scrollSize * instance.scrollMult; - Diffuse = diffuse(norm); - TexCoords = aTexCoords - aSourceTexture + aScrollTexture.xy + vec2(0, scroll); - Light = aLight; + BlockFrag b; + b.diffuse = diffuse(norm); + b.texCoords = v.texCoords - instance.sourceTexture + instance.scrollTexture.xy + vec2(0, scroll); + b.light = instance.light; - #ifdef CONTRAPTION - if (uDebug == 2) { - Color = vec4(norm, 1.); - } else { - Color = vec4(1.); - } + #if defined(RAINBOW_DEBUG) + b.color = instance.color; #else - if (uDebug == 1) { - Color = aColor; - } else if (uDebug == 2) { - Color = vec4(norm, 1.); - } else { - Color = vec4(1.); - } + b.color = vec4(1.); #endif + + return b; } diff --git a/src/main/resources/assets/create/flywheel/shaders/block.frag b/src/main/resources/assets/create/flywheel/shaders/block.frag index 2f26044ac..e24666099 100644 --- a/src/main/resources/assets/create/flywheel/shaders/block.frag +++ b/src/main/resources/assets/create/flywheel/shaders/block.frag @@ -1,16 +1,11 @@ -#version 110 - #flwbuiltins -varying vec2 TexCoords; -varying vec2 Light; -varying float Diffuse; -varying vec4 Color; +#flwinclude <"create:data/blockfragment.glsl"> -void main() { - vec4 tex = FLWBlockTexture(TexCoords); +void FLWMain(BlockFrag r) { + vec4 tex = FLWBlockTexture(r.texCoords); - vec4 color = vec4(tex.rgb * FLWLight(Light).rgb * Diffuse, tex.a) * Color; + vec4 color = vec4(tex.rgb * FLWLight(r.light).rgb * r.diffuse, tex.a) * r.color; FLWFinalizeColor(color); } diff --git a/src/main/resources/assets/create/flywheel/shaders/block_new.frag b/src/main/resources/assets/create/flywheel/shaders/block_new.frag deleted file mode 100644 index fe96f0c84..000000000 --- a/src/main/resources/assets/create/flywheel/shaders/block_new.frag +++ /dev/null @@ -1,17 +0,0 @@ -#flwbuiltins - -#[Fragment] -struct Raster { - vec2 texCoords; - vec4 color; - float diffuse; - vec2 light; -}; - -void FLWMain(Raster r) { - vec4 tex = FLWBlockTexture(r.texCoords); - - vec4 color = vec4(tex.rgb * FLWLight(r.light).rgb * r.diffuse, tex.a) * r.color; - - FLWFinalizeColor(color); -} diff --git a/src/main/resources/assets/create/flywheel/shaders/context/contraption/builtin.frag b/src/main/resources/assets/create/flywheel/shaders/context/contraption/builtin.frag index 054697141..6a211bc46 100644 --- a/src/main/resources/assets/create/flywheel/shaders/context/contraption/builtin.frag +++ b/src/main/resources/assets/create/flywheel/shaders/context/contraption/builtin.frag @@ -1,4 +1,4 @@ -#flwinclude <"create:context/std/fog.glsl"> +#flwinclude <"create:context/world/fog.glsl"> #flwinclude <"create:core/lightutil.glsl"> varying vec3 BoxCoord; diff --git a/src/main/resources/assets/create/flywheel/shaders/context/contraption/builtin.vert b/src/main/resources/assets/create/flywheel/shaders/context/contraption/builtin.vert index 2b044c280..3d82348ea 100644 --- a/src/main/resources/assets/create/flywheel/shaders/context/contraption/builtin.vert +++ b/src/main/resources/assets/create/flywheel/shaders/context/contraption/builtin.vert @@ -10,7 +10,6 @@ uniform mat4 uModel; uniform float uTime; uniform mat4 uViewProjection; -uniform int uDebug; uniform vec3 uCameraPos; void FLWFinalizeWorldPos(inout vec4 worldPos) { diff --git a/src/main/resources/assets/create/flywheel/shaders/context/crumbling/builtin.frag b/src/main/resources/assets/create/flywheel/shaders/context/crumbling/builtin.frag index 40bcfbdc4..5bee49af8 100644 --- a/src/main/resources/assets/create/flywheel/shaders/context/crumbling/builtin.frag +++ b/src/main/resources/assets/create/flywheel/shaders/context/crumbling/builtin.frag @@ -1,4 +1,4 @@ -#flwinclude <"create:context/std/fog.glsl"> +#flwinclude <"create:context/world/fog.glsl"> uniform vec2 uTextureScale; uniform sampler2D uBlockAtlas; diff --git a/src/main/resources/assets/create/flywheel/shaders/context/crumbling/builtin.vert b/src/main/resources/assets/create/flywheel/shaders/context/crumbling/builtin.vert index 3ca685f97..8b61a3168 100644 --- a/src/main/resources/assets/create/flywheel/shaders/context/crumbling/builtin.vert +++ b/src/main/resources/assets/create/flywheel/shaders/context/crumbling/builtin.vert @@ -1 +1 @@ -#flwinclude <"create:context/std/builtin.vert"> +#flwinclude <"create:context/world/builtin.vert"> diff --git a/src/main/resources/assets/create/flywheel/shaders/context/std/builtin.frag b/src/main/resources/assets/create/flywheel/shaders/context/world/builtin.frag similarity index 91% rename from src/main/resources/assets/create/flywheel/shaders/context/std/builtin.frag rename to src/main/resources/assets/create/flywheel/shaders/context/world/builtin.frag index 8a30001a6..81e9a2be9 100644 --- a/src/main/resources/assets/create/flywheel/shaders/context/std/builtin.frag +++ b/src/main/resources/assets/create/flywheel/shaders/context/world/builtin.frag @@ -1,4 +1,4 @@ -#flwinclude <"create:context/std/fog.glsl"> +#flwinclude <"create:context/world/fog.glsl"> #flwinclude <"create:core/lightutil.glsl"> uniform sampler2D uBlockAtlas; diff --git a/src/main/resources/assets/create/flywheel/shaders/context/std/builtin.vert b/src/main/resources/assets/create/flywheel/shaders/context/world/builtin.vert similarity index 95% rename from src/main/resources/assets/create/flywheel/shaders/context/std/builtin.vert rename to src/main/resources/assets/create/flywheel/shaders/context/world/builtin.vert index bcf38154a..251267397 100644 --- a/src/main/resources/assets/create/flywheel/shaders/context/std/builtin.vert +++ b/src/main/resources/assets/create/flywheel/shaders/context/world/builtin.vert @@ -1,6 +1,5 @@ uniform float uTime; uniform mat4 uViewProjection; -uniform int uDebug; uniform vec3 uCameraPos; #if defined(USE_FOG) diff --git a/src/main/resources/assets/create/flywheel/shaders/context/std/fog.glsl b/src/main/resources/assets/create/flywheel/shaders/context/world/fog.glsl similarity index 100% rename from src/main/resources/assets/create/flywheel/shaders/context/std/fog.glsl rename to src/main/resources/assets/create/flywheel/shaders/context/world/fog.glsl diff --git a/src/main/resources/assets/create/flywheel/shaders/contraption_actor.vert b/src/main/resources/assets/create/flywheel/shaders/contraption_actor.vert index 96d516359..6fe9b3ac4 100644 --- a/src/main/resources/assets/create/flywheel/shaders/contraption_actor.vert +++ b/src/main/resources/assets/create/flywheel/shaders/contraption_actor.vert @@ -1,4 +1,3 @@ -#version 110 #define PI 3.1415926538 #flwbuiltins @@ -6,45 +5,38 @@ #flwinclude <"create:core/quaternion.glsl"> #flwinclude <"create:core/diffuse.glsl"> -// model data -attribute vec3 aPos; -attribute vec3 aNormal; -attribute vec2 aTexCoords; +#[InstanceData] +struct Actor { + vec3 pos; + vec2 light; + float offset; + vec3 axis; + vec4 rotation; + vec3 rotationCenter; + float speed; +}; -// instance data -attribute vec3 aInstancePos; -attribute vec2 aModelLight; -attribute float aOffset; -attribute vec3 aAxis; -attribute vec4 aInstanceRot; -attribute vec3 aRotationCenter; -attribute float aSpeed; +#flwinclude <"create:data/modelvertex.glsl"> +#flwinclude <"create:data/blockfragment.glsl"> -varying float Diffuse; -varying vec2 TexCoords; -varying vec4 Color; -varying vec2 Light; - -void main() { - float degrees = aOffset + uTime * aSpeed / 20.; +BlockFrag FLWMain(Vertex v, Actor instance) { + float degrees = instance.offset + uTime * instance.speed / 20.; //float angle = fract(degrees / 360.) * PI * 2.; - vec4 kineticRot = quat(aAxis, degrees); - vec3 rotated = rotateVertexByQuat(aPos - aRotationCenter, kineticRot) + aRotationCenter; + vec4 kineticRot = quat(instance.axis, degrees); + vec3 rotated = rotateVertexByQuat(v.pos - instance.rotationCenter, kineticRot) + instance.rotationCenter; - vec4 worldPos = vec4(rotateVertexByQuat(rotated - .5, aInstanceRot) + aInstancePos + .5, 1.); - vec3 norm = rotateVertexByQuat(rotateVertexByQuat(aNormal, kineticRot), aInstanceRot); + vec4 worldPos = vec4(rotateVertexByQuat(rotated - .5, instance.rotation) + instance.pos + .5, 1.); + vec3 norm = rotateVertexByQuat(rotateVertexByQuat(v.normal, kineticRot), instance.rotation); FLWFinalizeWorldPos(worldPos); FLWFinalizeNormal(norm); - Diffuse = diffuse(norm); - TexCoords = aTexCoords; - Light = aModelLight; + BlockFrag b; + b.diffuse = diffuse(norm); + b.texCoords = v.texCoords; + b.light = instance.light; + b.color = vec4(1.); - if (uDebug == 2) { - Color = vec4(norm, 1.); - } else { - Color = vec4(1.); - } + return b; } diff --git a/src/main/resources/assets/create/flywheel/shaders/contraption_structure.vert b/src/main/resources/assets/create/flywheel/shaders/contraption_structure.vert index e3bc37b5a..cac2956a0 100644 --- a/src/main/resources/assets/create/flywheel/shaders/contraption_structure.vert +++ b/src/main/resources/assets/create/flywheel/shaders/contraption_structure.vert @@ -1,34 +1,32 @@ -#version 110 #define PI 3.1415926538 #flwbuiltins #flwinclude <"create:core/matutils.glsl"> #flwinclude <"create:core/diffuse.glsl"> -attribute vec3 aPos; -attribute vec3 aNormal; -attribute vec2 aTexCoords; -attribute vec4 aColor; -attribute vec2 aModelLight; +#[VertexData] +struct Vertex { + vec3 pos; + vec3 normal; + vec2 texCoords; + vec4 color; + vec2 modelLight; +}; -varying float Diffuse; -varying vec2 TexCoords; -varying vec4 Color; -varying vec2 Light; +#flwinclude <"create:data/blockfragment.glsl"> -void main() { - vec4 worldPos = vec4(aPos, 1.); - vec3 norm = aNormal; +BlockFrag FLWMain(Vertex v) { + vec4 worldPos = vec4(v.pos, 1.); + vec3 norm = v.normal; FLWFinalizeWorldPos(worldPos); FLWFinalizeNormal(norm); - Diffuse = diffuse(norm); - if (uDebug == 2) { - Color = vec4(norm, 1.); - } else { - Color = aColor / diffuse(aNormal); - } - TexCoords = aTexCoords; - Light = aModelLight; + BlockFrag b; + b.diffuse = diffuse(norm); + b.color = v.color / diffuse(v.normal); + b.texCoords = v.texCoords; + b.light = v.modelLight; + + return b; } diff --git a/src/main/resources/assets/create/flywheel/shaders/data/blockfragment.glsl b/src/main/resources/assets/create/flywheel/shaders/data/blockfragment.glsl new file mode 100644 index 000000000..e5d09eb16 --- /dev/null +++ b/src/main/resources/assets/create/flywheel/shaders/data/blockfragment.glsl @@ -0,0 +1,7 @@ +#[Fragment] +struct BlockFrag { + vec2 texCoords; + vec4 color; + float diffuse; + vec2 light; +}; diff --git a/src/main/resources/assets/create/flywheel/shaders/data/modelvertex.glsl b/src/main/resources/assets/create/flywheel/shaders/data/modelvertex.glsl new file mode 100644 index 000000000..5e34d2883 --- /dev/null +++ b/src/main/resources/assets/create/flywheel/shaders/data/modelvertex.glsl @@ -0,0 +1,6 @@ +#[VertexData] +struct Vertex { + vec3 pos; + vec3 normal; + vec2 texCoords; +}; diff --git a/src/main/resources/assets/create/flywheel/shaders/flap.vert b/src/main/resources/assets/create/flywheel/shaders/flap.vert index cb4eba652..1f5c973ad 100644 --- a/src/main/resources/assets/create/flywheel/shaders/flap.vert +++ b/src/main/resources/assets/create/flywheel/shaders/flap.vert @@ -1,4 +1,3 @@ -#version 110 #define PI 3.1415926538 #flwbuiltins @@ -6,62 +5,58 @@ #flwinclude <"create:core/quaternion.glsl"> #flwinclude <"create:core/diffuse.glsl"> -attribute vec3 aPos; -attribute vec3 aNormal; -attribute vec2 aTexCoords; +#[InstanceData] +struct Flap { + vec3 instancePos; + vec2 light; + vec3 segmentOffset; + vec3 pivot; + float horizontalAngle; + float intensity; + float flapScale; + float flapness; +}; -attribute vec3 aInstancePos; -attribute vec2 aLight; +#flwinclude <"create:data/modelvertex.glsl"> +#flwinclude <"create:data/blockfragment.glsl"> -attribute vec3 aSegmentOffset; -attribute vec3 aPivot; -attribute float aHorizontalAngle; -attribute float aIntensity; -attribute float aFlapScale; - -attribute float aFlapness; - -// outputs -varying vec2 TexCoords; -varying vec4 Color; -varying float Diffuse; -varying vec2 Light; float toRad(float degrees) { return fract(degrees / 360.) * PI * 2.; } -float getFlapAngle() { - float absFlap = abs(aFlapness); +float getFlapAngle(float flapness, float intensity, float scale) { + float absFlap = abs(flapness); - float angle = sin((1. - absFlap) * PI * aIntensity) * 30. * aFlapness * aFlapScale; + float angle = sin((1. - absFlap) * PI * intensity) * 30. * flapness * scale; float halfAngle = angle * 0.5; - float which = step(0., aFlapness); - float degrees = which * halfAngle + (1. - which) * angle; // branchless conditional multiply + float which = step(0., flapness);// 0 if negative, 1 if positive + float degrees = which * halfAngle + (1. - which) * angle;// branchless conditional multiply return degrees; } -void main() { - float flapAngle = getFlapAngle(); +BlockFrag FLWMain(Vertex v, Flap flap) { + float flapAngle = getFlapAngle(flap.flapness, flap.intensity, flap.flapScale); - vec4 orientation = quat(vec3(0., 1., 0.), -aHorizontalAngle); + vec4 orientation = quat(vec3(0., 1., 0.), -flap.horizontalAngle); vec4 flapRotation = quat(vec3(1., 0., 0.), flapAngle); - vec3 rotated = rotateVertexByQuat(aPos - aPivot, flapRotation) + aPivot + aSegmentOffset; - rotated = rotateVertexByQuat(rotated - .5, orientation) + aInstancePos + .5; + vec3 rotated = rotateVertexByQuat(v.pos - flap.pivot, flapRotation) + flap.pivot + flap.segmentOffset; + rotated = rotateVertexByQuat(rotated - .5, orientation) + flap.instancePos + .5; vec4 worldPos = vec4(rotated, 1.); - vec3 norm = rotateVertexByQuat(rotateVertexByQuat(aNormal, flapRotation), orientation); + vec3 norm = rotateVertexByQuat(rotateVertexByQuat(v.normal, flapRotation), orientation); FLWFinalizeWorldPos(worldPos); FLWFinalizeNormal(norm); - Diffuse = diffuse(norm); - TexCoords = aTexCoords; - Light = aLight; - - Color = vec4(1.); + BlockFrag b; + b.diffuse = diffuse(norm); + b.texCoords = v.texCoords; + b.light = flap.light; + b.color = vec4(1.); + return b; } diff --git a/src/main/resources/assets/create/flywheel/shaders/model.vert b/src/main/resources/assets/create/flywheel/shaders/model.vert index 4e0c76ec5..c9ca3fcea 100644 --- a/src/main/resources/assets/create/flywheel/shaders/model.vert +++ b/src/main/resources/assets/create/flywheel/shaders/model.vert @@ -1,35 +1,31 @@ -#version 110 - #flwbuiltins #flwinclude <"create:core/diffuse.glsl"> -attribute vec3 aPos; -attribute vec3 aNormal; -attribute vec2 aTexCoords; +#[InstanceData] +struct Instance { + vec2 light; + vec4 color; + mat4 transform; + mat3 normalMat; +}; -attribute vec2 aLight; -attribute vec4 aColor; -attribute mat4 aTransform; -attribute mat3 aNormalMat; +#flwinclude <"create:data/modelvertex.glsl"> +#flwinclude <"create:data/blockfragment.glsl"> -varying vec2 TexCoords; -varying vec4 Color; -varying float Diffuse; -varying vec2 Light; +BlockFrag FLWMain(Vertex v, Instance i) { + vec4 worldPos = i.transform * vec4(v.pos, 1.); -void main() { - vec4 worldPos = aTransform * vec4(aPos, 1.); - - vec3 norm = aNormalMat * aNormal; + vec3 norm = i.normalMat * v.normal; FLWFinalizeWorldPos(worldPos); FLWFinalizeNormal(norm); norm = normalize(norm); - Diffuse = diffuse(norm); - TexCoords = aTexCoords; - Light = aLight; - - Color = aColor; + BlockFrag b; + b.diffuse = diffuse(norm); + b.texCoords = v.texCoords; + b.light = i.light; + b.color = i.color; + return b; } diff --git a/src/main/resources/assets/create/flywheel/shaders/model_new.vert b/src/main/resources/assets/create/flywheel/shaders/model_new.vert deleted file mode 100644 index 755d09361..000000000 --- a/src/main/resources/assets/create/flywheel/shaders/model_new.vert +++ /dev/null @@ -1,46 +0,0 @@ -#flwbuiltins -#flwinclude <"create:core/diffuse.glsl"> - -#[VertexData] -struct Vertex { -#[Layout(float)] - vec3 pos; - vec3 normal; - vec2 texCoords; -}; - -#[InstanceData] -struct Instance { -#[Normalized(ushort)] - vec2 light; - #[Normalized(ubyte)] - vec4 color; - mat4 transform; - mat3 normalMat; -}; - -#[Fragment] -struct Raster { - vec2 texCoords; - vec4 color; - float diffuse; - vec2 light; -}; - -Raster FLWMain(Vertex v, Instance i) { - vec4 worldPos = i.transform * vec4(v.pos, 1.); - - vec3 norm = i.normalMat * v.normal; - norm = normalize(norm); - - FLWFinalizeWorldPos(worldPos); - FLWFinalizeNormal(norm); - - Raster r; - r.diffuse = diffuse(norm); - r.texCoords = v.texCoords; - r.light = i.light; - r.color = i.color; - - return r; -} diff --git a/src/main/resources/assets/create/flywheel/shaders/oriented.vert b/src/main/resources/assets/create/flywheel/shaders/oriented.vert index d9f6f5cc5..6b978c08d 100644 --- a/src/main/resources/assets/create/flywheel/shaders/oriented.vert +++ b/src/main/resources/assets/create/flywheel/shaders/oriented.vert @@ -1,36 +1,32 @@ -#version 110 - #flwbuiltins #flwinclude <"create:core/matutils.glsl"> #flwinclude <"create:core/quaternion.glsl"> #flwinclude <"create:core/diffuse.glsl"> -attribute vec3 aPos; -attribute vec3 aNormal; -attribute vec2 aTexCoords; +#[InstanceData] +struct Oriented { + vec2 light; + vec4 color; + vec3 pos; + vec3 pivot; + vec4 rotation; +}; -attribute vec2 aLight; -attribute vec4 aColor; -attribute vec3 aInstancePos; -attribute vec3 aPivot; -attribute vec4 aRotation; +#flwinclude <"create:data/modelvertex.glsl"> +#flwinclude <"create:data/blockfragment.glsl"> -varying vec2 TexCoords; -varying vec4 Color; -varying float Diffuse; -varying vec2 Light; +BlockFrag FLWMain(Vertex v, Oriented o) { + vec4 worldPos = vec4(rotateVertexByQuat(v.pos - o.pivot, o.rotation) + o.pivot + o.pos, 1.); -void main() { - vec4 worldPos = vec4(rotateVertexByQuat(aPos - aPivot, aRotation) + aPivot + aInstancePos, 1.); - - vec3 norm = rotateVertexByQuat(aNormal, aRotation); + vec3 norm = rotateVertexByQuat(v.normal, o.rotation); FLWFinalizeWorldPos(worldPos); FLWFinalizeNormal(norm); - Diffuse = diffuse(norm); - TexCoords = aTexCoords; - Light = aLight; - - Color = aColor; + BlockFrag b; + b.diffuse = diffuse(norm); + b.texCoords = v.texCoords; + b.light = o.light; + b.color = o.color; + return b; } diff --git a/src/main/resources/assets/create/flywheel/shaders/rotating.vert b/src/main/resources/assets/create/flywheel/shaders/rotating.vert index 9d20b6480..2f12cea87 100644 --- a/src/main/resources/assets/create/flywheel/shaders/rotating.vert +++ b/src/main/resources/assets/create/flywheel/shaders/rotating.vert @@ -1,60 +1,51 @@ -#version 110 #define PI 3.1415926538 #flwbuiltins -#flwinclude <"create:core/quaternion.glsl"> #flwinclude <"create:core/matutils.glsl"> #flwinclude <"create:core/diffuse.glsl"> -attribute vec3 aPos; -attribute vec3 aNormal; -attribute vec2 aTexCoords; +#[InstanceData] +struct Rotating { + vec2 light; + vec4 color; + vec3 pos; + float speed; + float offset; + vec3 axis; +}; -attribute vec2 aLight; -attribute vec4 aColor; -attribute vec3 aInstancePos; -attribute float aSpeed; -attribute float aOffset; -attribute vec3 aAxis; +#flwinclude <"create:data/modelvertex.glsl"> +#flwinclude <"create:data/blockfragment.glsl"> -varying vec2 TexCoords; -varying vec4 Color; -varying float Diffuse; -varying vec2 Light; - -mat4 kineticRotation() { - float degrees = aOffset + uTime * aSpeed * 3./10.; +mat4 kineticRotation(float offset, float speed, vec3 axis) { + float degrees = offset + uTime * speed * 3./10.; float angle = fract(degrees / 360.) * PI * 2.; - return rotate(aAxis, angle); + return rotate(axis, angle); } -void main() { - mat4 kineticRotation = kineticRotation(); - vec4 worldPos = kineticRotation * vec4(aPos - .5, 1.) + vec4(aInstancePos + .5, 0.); +BlockFrag FLWMain(Vertex v, Rotating instance) { + mat4 kineticRotation = kineticRotation(instance.offset, instance.speed, instance.axis); - vec3 norm = modelToNormal(kineticRotation) * aNormal; + vec4 worldPos = vec4(v.pos - .5, 1.); + worldPos *= kineticRotation; + worldPos += vec4(instance.pos + .5, 0.); + + vec3 norm = modelToNormal(kineticRotation) * v.normal; FLWFinalizeWorldPos(worldPos); FLWFinalizeNormal(norm); - Diffuse = diffuse(norm); - TexCoords = aTexCoords; - Light = aLight; + BlockFrag b; + b.diffuse = diffuse(norm); + b.texCoords = v.texCoords; + b.light = instance.light; - #ifdef CONTRAPTION - if (uDebug == 2) { - Color = vec4(norm, 1.); - } else { - Color = vec4(1.); - } + #if defined(RAINBOW_DEBUG) + b.color = instance.color; #else - if (uDebug == 1) { - Color = aColor; - } else if (uDebug == 2) { - Color = vec4(norm, 1.); - } else { - Color = vec4(1.); - } + b.color = vec4(1.); #endif + + return b; } diff --git a/src/main/resources/assets/create/flywheel/shaders/template/model/model.frag b/src/main/resources/assets/create/flywheel/shaders/template/model/model.frag new file mode 100644 index 000000000..fb9620d7d --- /dev/null +++ b/src/main/resources/assets/create/flywheel/shaders/template/model/model.frag @@ -0,0 +1,12 @@ +#version 110 + +#flwbeginbody + +#FLWPrefixFields(Fragment, varying, v2f_) + +void main() { + Fragment f; + #FLWAssignFields(Fragment, f., v2f_) + + FLWMain(f); +} diff --git a/src/main/resources/assets/create/flywheel/shaders/template/model/model.vert b/src/main/resources/assets/create/flywheel/shaders/template/model/model.vert new file mode 100644 index 000000000..1a235e153 --- /dev/null +++ b/src/main/resources/assets/create/flywheel/shaders/template/model/model.vert @@ -0,0 +1,15 @@ +#version 110 + +#flwbeginbody +#FLWPrefixFields(VertexData, attribute, a_v_) + +#FLWPrefixFields(Fragment, varying, v2f_) + +void main() { + VertexData v; + #FLWAssignFields(VertexData, v., a_v_) + + Fragment o = FLWMain(v); + + #FLWAssignFields(Fragment, v2f_, o.) +}