mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-15 20:53:41 +01:00
Move to the template system and overhaul instance attributes
- All material shaders now use the template system. - Because of the template system, we can know what attributes a material has, along with how they're formatted. - All of the *Attribute enums are effectively inlined, as the context they used to provide is no longer needed.
This commit is contained in:
parent
695fe98d28
commit
55703d8838
67 changed files with 739 additions and 1123 deletions
|
@ -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<ResourceLocation, MaterialSpec<?>> materialRegistry = new HashMap<>();
|
||||
static final Map<ResourceLocation, ShaderContext<?>> contexts = new HashMap<>();
|
||||
static final List<ShaderContext<?>> contexts = new ArrayList<>();
|
||||
static final Map<ResourceLocation, ProgramSpec> programSpecRegistry = new HashMap<>();
|
||||
|
||||
static {
|
||||
|
@ -119,11 +121,7 @@ public class Backend {
|
|||
* Register a shader context.
|
||||
*/
|
||||
public static <P extends GlProgram> ShaderContext<P> register(ShaderContext<P> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<P extends GlProgram> {
|
|||
public final Map<ProgramSpec, IMultiProgram<P>> programs = new HashMap<>();
|
||||
|
||||
public final ResourceLocation root;
|
||||
protected final ShaderSpecLoader<P> specLoader;
|
||||
protected ShaderTransformer transformer = new ShaderTransformer();
|
||||
|
||||
public ShaderContext(ResourceLocation root) {
|
||||
public ShaderContext(ResourceLocation root, ShaderSpecLoader<P> specLoader) {
|
||||
this.root = root;
|
||||
this.specLoader = specLoader;
|
||||
}
|
||||
|
||||
public abstract ShaderSpecLoader<P> 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) {
|
||||
|
|
|
@ -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<Shader> shaders) {
|
||||
public Program loadProgram(ResourceLocation name, Collection<Shader> shaders) {
|
||||
List<GlShader> 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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<P extends BasicProgram> extends ShaderContext<P> {
|
|||
private static final String declaration = "#flwbuiltins";
|
||||
private static final Pattern builtinPattern = Pattern.compile(declaration);
|
||||
|
||||
public static final WorldContext<BasicProgram> INSTANCE = new WorldContext<>(new ResourceLocation("create", "context/std"), new FogSensitiveProgram.SpecLoader<>(BasicProgram::new));
|
||||
public static final WorldContext<BasicProgram> INSTANCE = new WorldContext<>(new ResourceLocation("create", "context/world"), new FogSensitiveProgram.SpecLoader<>(BasicProgram::new));
|
||||
public static final WorldContext<CrumblingProgram> CRUMBLING = new WorldContext<>(new ResourceLocation("create", "context/crumbling"), new FogSensitiveProgram.SpecLoader<>(CrumblingProgram::new));
|
||||
|
||||
private final ShaderSpecLoader<P> loader;
|
||||
|
||||
final Map<ShaderType, ResourceLocation> builtins;
|
||||
final Map<ShaderType, String> builtinSources;
|
||||
|
||||
protected ProgramTemplate template;
|
||||
protected final Supplier<Stream<ProgramSpec>> specStream;
|
||||
protected final TemplateFactory templateFactory;
|
||||
|
||||
public WorldContext(ResourceLocation root, ShaderSpecLoader<P> loader) {
|
||||
super(root);
|
||||
this(root, loader, () -> Backend.allMaterials()
|
||||
.stream()
|
||||
.map(MaterialSpec::getProgramSpec), InstancedArraysTemplate::new);
|
||||
}
|
||||
|
||||
public WorldContext(ResourceLocation root, ShaderSpecLoader<P> loader, Supplier<Stream<ProgramSpec>> 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<P extends BasicProgram> extends ShaderContext<P> {
|
|||
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<P> getLoader() {
|
||||
return loader;
|
||||
public interface TemplateFactory {
|
||||
ProgramTemplate create(ShaderLoader loader);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<String, GlPrimitiveType> 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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package com.jozufozu.flywheel.backend.gl.attrib;
|
||||
|
||||
public interface IVertexAttrib {
|
||||
|
||||
String attribName();
|
||||
|
||||
IAttribSpec attribSpec();
|
||||
|
||||
int getDivisor();
|
||||
|
||||
int getBufferIndex();
|
||||
}
|
|
@ -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<IVertexAttrib> allAttributes;
|
||||
private final ArrayList<IAttribSpec> allAttributes;
|
||||
|
||||
private final int numAttributes;
|
||||
private final int stride;
|
||||
|
||||
public VertexFormat(ArrayList<IVertexAttrib> allAttributes) {
|
||||
public VertexFormat(ArrayList<IAttribSpec> 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<IVertexAttrib> allAttributes;
|
||||
private final ArrayList<IAttribSpec> allAttributes = new ArrayList<>();
|
||||
|
||||
public Builder() {
|
||||
allAttributes = new ArrayList<>();
|
||||
}
|
||||
|
||||
public <A extends Enum<A> & IVertexAttrib> Builder addAttributes(Class<A> attribEnum) {
|
||||
allAttributes.addAll(Arrays.asList(attribEnum.getEnumConstants()));
|
||||
public Builder addAttributes(IAttribSpec... attributes) {
|
||||
Collections.addAll(allAttributes, attributes);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<P extends GlProgram> implements IMultiProgram<P
|
|||
|
||||
defines.defineAll(fogMode.getDefines());
|
||||
|
||||
GlProgram.Builder builder = spec.loadProgram(ctx, defines, loader);
|
||||
Program builder = ctx.loadProgram(spec, defines, loader);
|
||||
|
||||
programs.put(fogMode, fogProgramLoader.create(builder.name, builder.program, fogMode.getFogFactory()));
|
||||
}
|
||||
|
|
|
@ -1,24 +1,13 @@
|
|||
package com.jozufozu.flywheel.backend.gl.shader;
|
||||
|
||||
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.glDeleteProgram;
|
||||
import static org.lwjgl.opengl.GL20.glGetProgramInfoLog;
|
||||
import static org.lwjgl.opengl.GL20.glGetProgrami;
|
||||
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
||||
import static org.lwjgl.opengl.GL20.glLinkProgram;
|
||||
import static org.lwjgl.opengl.GL20.glUniform1i;
|
||||
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
|
||||
import static org.lwjgl.opengl.GL20.glUseProgram;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.gl.GlObject;
|
||||
import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib;
|
||||
import com.jozufozu.flywheel.util.RenderUtil;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
@ -33,10 +22,6 @@ public abstract class GlProgram extends GlObject {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
public static Builder builder(ResourceLocation name) {
|
||||
return new Builder(name);
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
glUseProgram(handle());
|
||||
}
|
||||
|
@ -88,53 +73,4 @@ public abstract class GlProgram extends GlObject {
|
|||
glDeleteProgram(handle);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
public final ResourceLocation name;
|
||||
public final int program;
|
||||
|
||||
private int attributeIndex;
|
||||
|
||||
public Builder(ResourceLocation name) {
|
||||
this.name = name;
|
||||
this.program = glCreateProgram();
|
||||
}
|
||||
|
||||
public Builder attachShader(GlShader shader) {
|
||||
glAttachShader(this.program, shader.handle());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public <A extends IVertexAttrib> Builder addAttributes(Collection<A> attributes) {
|
||||
attributes.forEach(this::addAttribute);
|
||||
return this;
|
||||
}
|
||||
|
||||
public <A extends IVertexAttrib> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<IVertexAttrib> attributes;
|
||||
|
||||
public static Builder builder(ResourceLocation name) {
|
||||
return new Builder(name);
|
||||
}
|
||||
|
||||
public ProgramSpec(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, ShaderConstants defines, ArrayList<IVertexAttrib> 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<IVertexAttrib> 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 <A extends Enum<A> & IVertexAttrib> Builder addAttributes(Class<A> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,5 +4,12 @@ import com.jozufozu.flywheel.backend.ShaderContext;
|
|||
import com.jozufozu.flywheel.backend.ShaderLoader;
|
||||
|
||||
public interface ShaderSpecLoader<P extends GlProgram> {
|
||||
|
||||
/**
|
||||
* @param loader
|
||||
* @param ctx
|
||||
* @param spec
|
||||
* @return
|
||||
*/
|
||||
IMultiProgram<P> create(ShaderLoader loader, ShaderContext<P> ctx, ProgramSpec spec);
|
||||
}
|
||||
|
|
|
@ -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<P extends GlProgram> implements IMultiProgram<P> {
|
|||
|
||||
@Override
|
||||
public IMultiProgram<P> create(ShaderLoader loader, ShaderContext<P> 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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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<String, TaggedStruct> tag2Struct = new HashMap<>();
|
||||
final Map<String, TaggedStruct> 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);
|
||||
}
|
||||
}
|
|
@ -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<ShaderType, Shader> 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;
|
||||
}
|
||||
}
|
|
@ -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<ShaderType, ShaderTemplate> 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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<TaggedStruct> structs = new ArrayList<>(3);
|
||||
final Map<String, TaggedStruct> tag2Struct = new HashMap<>();
|
||||
final Map<String, TaggedStruct> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String> 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<String, String> 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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -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<String, String> fields = new HashMap<>();
|
||||
List<TaggedField> fields = new ArrayList<>(4);
|
||||
Map<String, String> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<ContraptionProgram> {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer<Contraptio
|
|||
private final WeakReference<RenderedContraption> contraption;
|
||||
|
||||
ContraptionKineticRenderer(RenderedContraption contraption) {
|
||||
super(ContraptionContext.INSTANCE);
|
||||
super(ContraptionRenderDispatcher.TILES);
|
||||
this.contraption = new WeakReference<>(contraption);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<RenderedContraption> renderers = new Int2ObjectOpenHashMap<>();
|
||||
public static final Compartment<Pair<Contraption, Integer>> CONTRAPTION = new Compartment<>();
|
||||
private static final ResourceLocation ctxRoot = new ResourceLocation("create", "context/contraption");
|
||||
public static final WorldContext<ContraptionProgram> STRUCTURE = new WorldContext<>(ctxRoot, new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new), () -> Stream.of(AllProgramSpecs.STRUCTURE), ModelTemplate::new);
|
||||
public static final WorldContext<ContraptionProgram> 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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<ModelData> TRANSFORMED = register(new MaterialSpec<>(Locations.MODEL, AllProgramSpecs.MODEL, UNLIT_MODEL, AllInstanceFormats.MODEL, ModelData::new));
|
||||
public static final MaterialSpec<OrientedData> ORIENTED = register(new MaterialSpec<>(Locations.ORIENTED, AllProgramSpecs.ORIENTED, UNLIT_MODEL, AllInstanceFormats.ORIENTED, OrientedData::new));
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<SphereFilterProgram> {
|
|||
|
||||
public static final EffectsContext INSTANCE = new EffectsContext();
|
||||
|
||||
private final SingleProgram.SpecLoader<SphereFilterProgram> 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<SphereFilterProgram> getLoader() {
|
||||
return loader;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#flwinclude <"create:context/std/fog.glsl">
|
||||
#flwinclude <"create:context/world/fog.glsl">
|
||||
#flwinclude <"create:core/lightutil.glsl">
|
||||
|
||||
varying vec3 BoxCoord;
|
||||
|
|
|
@ -10,7 +10,6 @@ uniform mat4 uModel;
|
|||
|
||||
uniform float uTime;
|
||||
uniform mat4 uViewProjection;
|
||||
uniform int uDebug;
|
||||
uniform vec3 uCameraPos;
|
||||
|
||||
void FLWFinalizeWorldPos(inout vec4 worldPos) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#flwinclude <"create:context/std/fog.glsl">
|
||||
#flwinclude <"create:context/world/fog.glsl">
|
||||
|
||||
uniform vec2 uTextureScale;
|
||||
uniform sampler2D uBlockAtlas;
|
||||
|
|
|
@ -1 +1 @@
|
|||
#flwinclude <"create:context/std/builtin.vert">
|
||||
#flwinclude <"create:context/world/builtin.vert">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#flwinclude <"create:context/std/fog.glsl">
|
||||
#flwinclude <"create:context/world/fog.glsl">
|
||||
#flwinclude <"create:core/lightutil.glsl">
|
||||
|
||||
uniform sampler2D uBlockAtlas;
|
|
@ -1,6 +1,5 @@
|
|||
uniform float uTime;
|
||||
uniform mat4 uViewProjection;
|
||||
uniform int uDebug;
|
||||
uniform vec3 uCameraPos;
|
||||
|
||||
#if defined(USE_FOG)
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#[Fragment]
|
||||
struct BlockFrag {
|
||||
vec2 texCoords;
|
||||
vec4 color;
|
||||
float diffuse;
|
||||
vec2 light;
|
||||
};
|
|
@ -0,0 +1,6 @@
|
|||
#[VertexData]
|
||||
struct Vertex {
|
||||
vec3 pos;
|
||||
vec3 normal;
|
||||
vec2 texCoords;
|
||||
};
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
#version 110
|
||||
|
||||
#flwbeginbody
|
||||
|
||||
#FLWPrefixFields(Fragment, varying, v2f_)
|
||||
|
||||
void main() {
|
||||
Fragment f;
|
||||
#FLWAssignFields(Fragment, f., v2f_)
|
||||
|
||||
FLWMain(f);
|
||||
}
|
|
@ -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.)
|
||||
}
|
Loading…
Reference in a new issue