ShaderContexts

- A huge step towards more arbitrary shader usage
 - Need to work on registration of the different parts
 - Things are unorganized
This commit is contained in:
JozsefA 2021-05-03 21:46:33 -07:00
parent fcbab5b820
commit bc5630e593
28 changed files with 349 additions and 230 deletions

View file

@ -8,9 +8,10 @@ import org.apache.logging.log4j.Logger;
import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GLCapabilities; import org.lwjgl.opengl.GLCapabilities;
import com.jozufozu.flywheel.backend.core.ContraptionContext;
import com.jozufozu.flywheel.backend.core.EffectsContext;
import com.jozufozu.flywheel.backend.core.WorldContext;
import com.jozufozu.flywheel.backend.effects.EffectsHandler; import com.jozufozu.flywheel.backend.effects.EffectsHandler;
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.ProgramSpec;
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat; import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
import com.jozufozu.flywheel.backend.instancing.IFlywheelWorld; import com.jozufozu.flywheel.backend.instancing.IFlywheelWorld;
@ -38,28 +39,41 @@ public class Backend {
private static boolean instancingAvailable; private static boolean instancingAvailable;
private static boolean enabled; private static boolean enabled;
static final Map<ResourceLocation, ProgramSpec<?>> registry = new HashMap<>(); static final Map<ResourceLocation, ShaderContext<?>> contexts = new HashMap<>();
static final Map<ProgramSpec<?>, IMultiProgram<?>> programs = new HashMap<>(); static final Map<ResourceLocation, ProgramSpec> specRegistry = new HashMap<>();
static {
register(WorldContext.INSTANCE);
register(ContraptionContext.INSTANCE);
register(EffectsContext.INSTANCE);
}
public Backend() { public Backend() {
throw new IllegalStateException(); throw new IllegalStateException();
} }
/** /**
* Register a shader program. TODO: replace with forge registry? * Register a shader program.
*/ */
public static <P extends GlProgram, S extends ProgramSpec<P>> S register(S spec) { public static ProgramSpec register(ProgramSpec spec) {
ResourceLocation name = spec.name; ResourceLocation name = spec.name;
if (registry.containsKey(name)) { if (specRegistry.containsKey(name)) {
throw new IllegalStateException("Program spec '" + name + "' already registered."); throw new IllegalStateException("Program spec '" + name + "' already registered.");
} }
registry.put(name, spec); specRegistry.put(name, spec);
return spec; return spec;
} }
@SuppressWarnings("unchecked") /**
public static <P extends GlProgram, S extends ProgramSpec<P>> P getProgram(S spec) { * Register a shader context.
return (P) programs.get(spec).get(); */
public static ShaderContext<?> register(ShaderContext<?> spec) {
ResourceLocation name = spec.getRoot();
if (contexts.containsKey(name)) {
throw new IllegalStateException("Program spec '" + name + "' already registered.");
}
contexts.put(name, spec);
return spec;
} }
public static boolean isFlywheelWorld(World world) { public static boolean isFlywheelWorld(World world) {

View file

@ -1,10 +1,21 @@
package com.jozufozu.flywheel.backend; package com.jozufozu.flywheel.backend;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer;
import com.jozufozu.flywheel.backend.core.OrientedModel;
import com.jozufozu.flywheel.backend.core.TransformedModel;
import com.jozufozu.flywheel.backend.instancing.MaterialFactory;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.KineticDebugger; import com.simibubi.create.content.contraptions.KineticDebugger;
import com.simibubi.create.foundation.render.KineticRenderer; import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
import com.simibubi.create.content.contraptions.base.RotatingModel;
import com.simibubi.create.content.contraptions.components.actors.ActorModel;
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
import com.simibubi.create.content.logistics.block.FlapModel;
import com.simibubi.create.foundation.render.AllProgramSpecs;
import com.simibubi.create.foundation.utility.WorldAttached; import com.simibubi.create.foundation.utility.WorldAttached;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -17,8 +28,23 @@ import net.minecraft.world.World;
public class FastRenderDispatcher { public class FastRenderDispatcher {
public static Map<MaterialType<?>, MaterialFactory> materials = new HashMap<>();
static {
registerMaterials();
}
public static WorldAttached<ConcurrentHashMap.KeySetView<TileEntity, Boolean>> queuedUpdates = new WorldAttached<>(ConcurrentHashMap::newKeySet); public static WorldAttached<ConcurrentHashMap.KeySetView<TileEntity, Boolean>> queuedUpdates = new WorldAttached<>(ConcurrentHashMap::newKeySet);
public static void registerMaterials() {
materials.put(MaterialTypes.TRANSFORMED, new MaterialFactory(AllProgramSpecs.MODEL, TransformedModel::new));
materials.put(MaterialTypes.ORIENTED, new MaterialFactory(AllProgramSpecs.ORIENTED, OrientedModel::new));
materials.put(KineticRenderMaterials.BELTS, new MaterialFactory(AllProgramSpecs.BELT, BeltInstancedModel::new));
materials.put(KineticRenderMaterials.ROTATING, new MaterialFactory(AllProgramSpecs.ROTATING, RotatingModel::new));
materials.put(KineticRenderMaterials.FLAPS, new MaterialFactory(AllProgramSpecs.FLAPS, FlapModel::new));
materials.put(KineticRenderMaterials.ACTORS, new MaterialFactory(AllProgramSpecs.C_ACTOR, ActorModel::new));
}
public static void enqueueUpdate(TileEntity te) { public static void enqueueUpdate(TileEntity te) {
queuedUpdates.get(te.getWorld()).add(te); queuedUpdates.get(te.getWorld()).add(te);
} }
@ -27,7 +53,7 @@ public class FastRenderDispatcher {
Minecraft mc = Minecraft.getInstance(); Minecraft mc = Minecraft.getInstance();
ClientWorld world = mc.world; ClientWorld world = mc.world;
KineticRenderer kineticRenderer = CreateClient.kineticRenderer.get(world); BasicInstancedTileRenderer kineticRenderer = CreateClient.kineticRenderer.get(world);
Entity renderViewEntity = mc.renderViewEntity; Entity renderViewEntity = mc.renderViewEntity;
kineticRenderer.tick(renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ()); kineticRenderer.tick(renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ());
@ -61,7 +87,7 @@ public class FastRenderDispatcher {
if (!Backend.canUseInstancing()) return; if (!Backend.canUseInstancing()) return;
ClientWorld world = Minecraft.getInstance().world; ClientWorld world = Minecraft.getInstance().world;
KineticRenderer kineticRenderer = CreateClient.kineticRenderer.get(world); BasicInstancedTileRenderer kineticRenderer = CreateClient.kineticRenderer.get(world);
layer.startDrawing(); layer.startDrawing();

View file

@ -0,0 +1,10 @@
package com.jozufozu.flywheel.backend;
import net.minecraft.util.ResourceLocation;
public class ResourceUtil {
public static ResourceLocation subPath(ResourceLocation root, String subPath) {
return new ResourceLocation(root.getNamespace(), root.getPath() + subPath);
}
}

View file

@ -0,0 +1,54 @@
package com.jozufozu.flywheel.backend;
import java.util.HashMap;
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.ShaderSpecLoader;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
import net.minecraft.util.ResourceLocation;
public abstract class ShaderContext<P extends GlProgram> {
public final Map<ProgramSpec, IMultiProgram<P>> programs = new HashMap<>();
public final ResourceLocation root;
public ShaderContext(ResourceLocation root) {
this.root = root;
}
public abstract ShaderSpecLoader<P> getLoader();
public void load(ShaderLoader loader) {
programs.values().forEach(IMultiProgram::delete);
programs.clear();
for (ProgramSpec programSpec : Backend.specRegistry.values()) {
loadProgramFromSpec(loader, programSpec);
}
}
public void loadProgramFromSpec(ShaderLoader loader, ProgramSpec programSpec) {
programs.put(programSpec, getLoader().create(loader, this, programSpec));
Backend.log.debug("Loaded program {}", programSpec.name);
}
public String preProcess(ShaderLoader loader, String shaderSrc, ShaderType type) {
return shaderSrc;
}
public P getProgram(ProgramSpec spec) {
return programs.get(spec).get();
}
public ResourceLocation getRoot() {
return root;
}
}

View file

@ -28,7 +28,6 @@ import com.google.common.collect.Lists;
import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram; import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.backend.gl.shader.GlShader; import com.jozufozu.flywheel.backend.gl.shader.GlShader;
import com.jozufozu.flywheel.backend.gl.shader.IMultiProgram;
import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec; import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec;
import com.jozufozu.flywheel.backend.gl.shader.ShaderConstants; import com.jozufozu.flywheel.backend.gl.shader.ShaderConstants;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType; import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
@ -46,10 +45,9 @@ public class ShaderLoader {
// #flwinclude <"valid_namespace:valid/path_to_file.glsl"> // #flwinclude <"valid_namespace:valid/path_to_file.glsl">
private static final Pattern includePattern = Pattern.compile("#flwinclude <\"([\\w\\d_]+:[\\w\\d_./]+)\">"); private static final Pattern includePattern = Pattern.compile("#flwinclude <\"([\\w\\d_]+:[\\w\\d_./]+)\">");
private static final Pattern builtinPattern = Pattern.compile("#flwbuiltins");
private static boolean debugDumpFile = true; private static boolean debugDumpFile = true;
final Map<ResourceLocation, String> shaderSource = new HashMap<>(); private final Map<ResourceLocation, String> shaderSource = new HashMap<>();
void onResourceManagerReload(IResourceManager manager, Predicate<IResourceType> predicate) { void onResourceManagerReload(IResourceManager manager, Predicate<IResourceType> predicate) {
if (predicate.test(VanillaResourceType.SHADERS)) { if (predicate.test(VanillaResourceType.SHADERS)) {
@ -60,9 +58,9 @@ public class ShaderLoader {
shaderSource.clear(); shaderSource.clear();
loadShaderSources(manager); loadShaderSources(manager);
Backend.programs.values().forEach(IMultiProgram::delete); for (ShaderContext<?> context : Backend.contexts.values()) {
Backend.programs.clear(); context.load(this);
Backend.registry.values().forEach(this::loadProgramFromSpec); }
Backend.log.info("Loaded all shader programs."); Backend.log.info("Loaded all shader programs.");
@ -72,6 +70,10 @@ public class ShaderLoader {
} }
} }
public String getShaderSource(ResourceLocation loc) {
return shaderSource.get(loc);
}
private void loadShaderSources(IResourceManager manager) { private void loadShaderSources(IResourceManager manager) {
Collection<ResourceLocation> allShaders = manager.getAllResourceLocations(SHADER_DIR, s -> { Collection<ResourceLocation> allShaders = manager.getAllResourceLocations(SHADER_DIR, s -> {
for (String ext : EXTENSIONS) { for (String ext : EXTENSIONS) {
@ -96,27 +98,20 @@ public class ShaderLoader {
} }
} }
private <P extends GlProgram, S extends ProgramSpec<P>> void loadProgramFromSpec(S programSpec) { public GlProgram.Builder loadProgram(ShaderContext<?> ctx, ProgramSpec programSpec) {
return loadProgram(ctx, programSpec, programSpec.defines);
Backend.programs.put(programSpec, programSpec.finalizer.create(this, programSpec));
Backend.log.debug("Loaded program {}", programSpec.name);
} }
public GlProgram.Builder loadProgram(ProgramSpec<?> programSpec) { public GlProgram.Builder loadProgram(ShaderContext<?> ctx, ProgramSpec programSpec, ShaderConstants defines) {
return loadProgram(programSpec, programSpec.defines); return loadProgram(ctx, programSpec.name, programSpec.vert, programSpec.frag, programSpec.attributes, defines);
} }
public GlProgram.Builder loadProgram(ProgramSpec<?> programSpec, ShaderConstants defines) { public GlProgram.Builder loadProgram(ShaderContext<?> ctx, ResourceLocation name, ResourceLocation vert, ResourceLocation frag, Collection<IVertexAttrib> attribs, ShaderConstants defines) {
return loadProgram(programSpec.name, programSpec.vert, programSpec.frag, programSpec.attributes, defines);
}
public GlProgram.Builder loadProgram(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, Collection<IVertexAttrib> attribs, ShaderConstants defines) {
GlShader vsh = null; GlShader vsh = null;
GlShader fsh = null; GlShader fsh = null;
try { try {
vsh = loadShader(vert, ShaderType.VERTEX, defines); vsh = loadShader(ctx, vert, ShaderType.VERTEX, defines);
fsh = loadShader(frag, ShaderType.FRAGMENT, defines); fsh = loadShader(ctx, frag, ShaderType.FRAGMENT, defines);
return GlProgram.builder(name) return GlProgram.builder(name)
.attachShader(vsh) .attachShader(vsh)
@ -129,10 +124,10 @@ public class ShaderLoader {
} }
} }
public GlShader loadShader(ResourceLocation name, ShaderType type, ShaderConstants defines) { public GlShader loadShader(ShaderContext<?> ctx, ResourceLocation name, ShaderType type, ShaderConstants defines) {
String source = shaderSource.get(name); String source = shaderSource.get(name);
source = expandBuiltins(source, type); source = ctx.preProcess(this, source, type);
source = processIncludes(source, name); source = processIncludes(source, name);
if (defines != null) if (defines != null)
@ -149,33 +144,6 @@ public class ShaderLoader {
return new GlShader(type, name, source); return new GlShader(type, name, source);
} }
private String expandBuiltins(String source, ShaderType type) {
return lines(source).flatMap(line -> {
Matcher matcher = builtinPattern.matcher(line);
if (matcher.find()) {
ResourceLocation builtins;
switch (type) {
case FRAGMENT:
builtins = new ResourceLocation("create", "std/builtin.frag");
break;
case VERTEX:
builtins = new ResourceLocation("create", "std/builtin.vert");
break;
default:
builtins = null;
}
String includeSource = shaderSource.get(builtins);
return lines(includeSource);
}
return Stream.of(line);
}).collect(Collectors.joining("\n"));
}
private String processIncludes(String source, ResourceLocation baseName) { private String processIncludes(String source, ResourceLocation baseName) {
HashSet<ResourceLocation> seen = new HashSet<>(); HashSet<ResourceLocation> seen = new HashSet<>();
seen.add(baseName); seen.add(baseName);

View file

@ -2,11 +2,8 @@ package com.jozufozu.flywheel.backend.core;
import java.util.ArrayList; import java.util.ArrayList;
import com.jozufozu.flywheel.backend.MaterialTypes;
import com.jozufozu.flywheel.backend.gl.shader.ShaderCallback; import com.jozufozu.flywheel.backend.gl.shader.ShaderCallback;
import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer;
import com.jozufozu.flywheel.backend.instancing.RenderMaterial;
import com.simibubi.create.foundation.render.AllProgramSpecs;
import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
@ -20,11 +17,8 @@ public class BasicInstancedTileRenderer extends InstancedTileRenderer<BasicProgr
public BlockPos originCoordinate = BlockPos.ZERO; public BlockPos originCoordinate = BlockPos.ZERO;
@Override public BasicInstancedTileRenderer() {
public void registerMaterials() { super(WorldContext.INSTANCE);
materials.put(MaterialTypes.TRANSFORMED,
new RenderMaterial<>(this, AllProgramSpecs.MODEL, TransformedModel::new));
materials.put(MaterialTypes.ORIENTED, new RenderMaterial<>(this, AllProgramSpecs.ORIENTED, OrientedModel::new));
} }
@Override @Override

View file

@ -0,0 +1,17 @@
package com.jozufozu.flywheel.backend.core;
import com.jozufozu.flywheel.backend.gl.shader.FogSensitiveProgram;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionProgram;
import net.minecraft.util.ResourceLocation;
public class ContraptionContext extends WorldContext<ContraptionProgram> {
public static final ContraptionContext INSTANCE = new ContraptionContext();
public ContraptionContext() {
super(new ResourceLocation("create", "contraption"), new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new));
}
}

View file

@ -0,0 +1,32 @@
package com.jozufozu.flywheel.backend.core;
import com.jozufozu.flywheel.backend.ShaderContext;
import com.jozufozu.flywheel.backend.ShaderLoader;
import com.jozufozu.flywheel.backend.effects.SphereFilterProgram;
import com.jozufozu.flywheel.backend.gl.shader.ShaderSpecLoader;
import com.jozufozu.flywheel.backend.gl.shader.SingleProgram;
import com.simibubi.create.foundation.render.AllProgramSpecs;
import net.minecraft.util.ResourceLocation;
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);
}
@Override
public void load(ShaderLoader loader) {
loadProgramFromSpec(loader, AllProgramSpecs.CHROMATIC);
}
@Override
public ShaderSpecLoader<SphereFilterProgram> getLoader() {
return loader;
}
}

View file

@ -0,0 +1,76 @@
package com.jozufozu.flywheel.backend.core;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.jozufozu.flywheel.backend.ResourceUtil;
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.ShaderSpecLoader;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
import net.minecraft.util.ResourceLocation;
public class WorldContext<P extends BasicProgram> extends ShaderContext<P> {
private static final Pattern builtinPattern = Pattern.compile("#flwbuiltins");
public static final WorldContext<BasicProgram> INSTANCE = new WorldContext<>(new ResourceLocation("create", "std"), new FogSensitiveProgram.SpecLoader<>(BasicProgram::new));
private final ShaderSpecLoader<P> loader;
public final ResourceLocation frag;
public final ResourceLocation vert;
public WorldContext(ResourceLocation root, ShaderSpecLoader<P> loader) {
super(root);
this.frag = ResourceUtil.subPath(root, "/builtin.frag");
this.vert = ResourceUtil.subPath(root, "/builtin.vert");
this.loader = loader;
}
@Override
public String preProcess(ShaderLoader loader, String shaderSrc, ShaderType type) {
return ShaderLoader.lines(shaderSrc).flatMap(line -> {
Matcher matcher = builtinPattern.matcher(line);
if (matcher.find()) {
ResourceLocation builtins;
switch (type) {
case FRAGMENT:
builtins = frag;
break;
case VERTEX:
builtins = vert;
break;
default:
builtins = null;
}
String includeSource = loader.getShaderSource(builtins);
return ShaderLoader.lines(includeSource);
}
return Stream.of(line);
}).collect(Collectors.joining("\n"));
}
public ResourceLocation getFrag() {
return frag;
}
public ResourceLocation getVert() {
return vert;
}
@Override
public ShaderSpecLoader<P> getLoader() {
return loader;
}
}

View file

@ -9,6 +9,7 @@ import org.lwjgl.opengl.GL30;
import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.RenderUtil; import com.jozufozu.flywheel.backend.RenderUtil;
import com.jozufozu.flywheel.backend.core.EffectsContext;
import com.jozufozu.flywheel.backend.gl.GlBuffer; import com.jozufozu.flywheel.backend.gl.GlBuffer;
import com.jozufozu.flywheel.backend.gl.GlPrimitiveType; import com.jozufozu.flywheel.backend.gl.GlPrimitiveType;
import com.jozufozu.flywheel.backend.gl.GlVertexArray; import com.jozufozu.flywheel.backend.gl.GlVertexArray;
@ -95,7 +96,7 @@ public class EffectsHandler {
Backend.compat.fbo.bindFramebuffer(FramebufferConstants.FRAME_BUFFER, framebuffer.framebufferObject); Backend.compat.fbo.bindFramebuffer(FramebufferConstants.FRAME_BUFFER, framebuffer.framebufferObject);
GL11.glClear(GL30.GL_COLOR_BUFFER_BIT); GL11.glClear(GL30.GL_COLOR_BUFFER_BIT);
SphereFilterProgram program = Backend.getProgram(AllProgramSpecs.CHROMATIC); SphereFilterProgram program = EffectsContext.INSTANCE.getProgram(AllProgramSpecs.CHROMATIC);
program.bind(); program.bind();
program.bindColorTexture(mainBuffer.getColorAttachment()); program.bindColorTexture(mainBuffer.getColorAttachment());

View file

@ -3,6 +3,7 @@ package com.jozufozu.flywheel.backend.gl.shader;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import com.jozufozu.flywheel.backend.ShaderContext;
import com.jozufozu.flywheel.backend.ShaderLoader; import com.jozufozu.flywheel.backend.ShaderLoader;
import com.jozufozu.flywheel.backend.gl.GlFog; import com.jozufozu.flywheel.backend.gl.GlFog;
import com.jozufozu.flywheel.backend.gl.GlFogMode; import com.jozufozu.flywheel.backend.gl.GlFogMode;
@ -36,7 +37,7 @@ public class FogSensitiveProgram<P extends GlProgram> implements IMultiProgram<P
} }
@Override @Override
public IMultiProgram<P> create(ShaderLoader loader, ProgramSpec<P> spec) { public IMultiProgram<P> create(ShaderLoader loader, ShaderContext<P> ctx, ProgramSpec spec) {
Map<GlFogMode, P> programs = new EnumMap<>(GlFogMode.class); Map<GlFogMode, P> programs = new EnumMap<>(GlFogMode.class);
for (GlFogMode fogMode : GlFogMode.values()) { for (GlFogMode fogMode : GlFogMode.values()) {
@ -44,7 +45,7 @@ public class FogSensitiveProgram<P extends GlProgram> implements IMultiProgram<P
defines.defineAll(fogMode.getDefines()); defines.defineAll(fogMode.getDefines());
GlProgram.Builder builder = loader.loadProgram(spec, defines); GlProgram.Builder builder = loader.loadProgram(ctx, spec, defines);
programs.put(fogMode, fogProgramLoader.create(builder.name, builder.program, fogMode.getFogFactory())); programs.put(fogMode, fogProgramLoader.create(builder.name, builder.program, fogMode.getFogFactory()));
} }

View file

@ -4,11 +4,10 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib; import com.jozufozu.flywheel.backend.gl.attrib.IVertexAttrib;
import com.simibubi.create.Create;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
public class ProgramSpec<P extends GlProgram> { public class ProgramSpec {
public final ResourceLocation name; public final ResourceLocation name;
public final ResourceLocation vert; public final ResourceLocation vert;
@ -18,63 +17,54 @@ public class ProgramSpec<P extends GlProgram> {
public final ArrayList<IVertexAttrib> attributes; public final ArrayList<IVertexAttrib> attributes;
public final ShaderSpecLoader<P> finalizer; public static Builder builder(ResourceLocation name) {
return new Builder(name);
public static <P extends GlProgram> Builder<P> builder(String name, ShaderSpecLoader<P> factory) {
return builder(new ResourceLocation(Create.ID, name), factory);
} }
public static <P extends GlProgram> Builder<P> builder(ResourceLocation name, ShaderSpecLoader<P> factory) { public ProgramSpec(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, ShaderConstants defines, ArrayList<IVertexAttrib> attributes) {
return new Builder<>(name, factory);
}
public ProgramSpec(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, ShaderConstants defines, ArrayList<IVertexAttrib> attributes, ShaderSpecLoader<P> finalizer) {
this.name = name; this.name = name;
this.vert = vert; this.vert = vert;
this.frag = frag; this.frag = frag;
this.defines = defines; this.defines = defines;
this.attributes = attributes; this.attributes = attributes;
this.finalizer = finalizer;
} }
public static class Builder<P extends GlProgram> { public static class Builder {
private ResourceLocation vert; private ResourceLocation vert;
private ResourceLocation frag; private ResourceLocation frag;
private ShaderConstants defines = ShaderConstants.EMPTY; private ShaderConstants defines = ShaderConstants.EMPTY;
private final ShaderSpecLoader<P> loader;
private final ResourceLocation name; private final ResourceLocation name;
private final ArrayList<IVertexAttrib> attributes; private final ArrayList<IVertexAttrib> attributes;
public Builder(ResourceLocation name, ShaderSpecLoader<P> factory) { public Builder(ResourceLocation name) {
this.name = name; this.name = name;
this.loader = factory;
attributes = new ArrayList<>(); attributes = new ArrayList<>();
} }
public Builder<P> setVert(ResourceLocation vert) { public Builder setVert(ResourceLocation vert) {
this.vert = vert; this.vert = vert;
return this; return this;
} }
public Builder<P> setFrag(ResourceLocation frag) { public Builder setFrag(ResourceLocation frag) {
this.frag = frag; this.frag = frag;
return this; return this;
} }
public Builder<P> setDefines(ShaderConstants defines) { public Builder setDefines(ShaderConstants defines) {
this.defines = defines; this.defines = defines;
return this; return this;
} }
public <A extends Enum<A> & IVertexAttrib> Builder<P> addAttributes(Class<A> attributeEnum) { public <A extends Enum<A> & IVertexAttrib> Builder addAttributes(Class<A> attributeEnum) {
attributes.addAll(Arrays.asList(attributeEnum.getEnumConstants())); attributes.addAll(Arrays.asList(attributeEnum.getEnumConstants()));
return this; return this;
} }
public ProgramSpec<P> createProgramSpec() { public ProgramSpec createProgramSpec() {
return new ProgramSpec<>(name, vert, frag, defines, attributes, loader); return new ProgramSpec(name, vert, frag, defines, attributes);
} }
} }

View file

@ -1,7 +1,8 @@
package com.jozufozu.flywheel.backend.gl.shader; package com.jozufozu.flywheel.backend.gl.shader;
import com.jozufozu.flywheel.backend.ShaderContext;
import com.jozufozu.flywheel.backend.ShaderLoader; import com.jozufozu.flywheel.backend.ShaderLoader;
public interface ShaderSpecLoader<P extends GlProgram> { public interface ShaderSpecLoader<P extends GlProgram> {
IMultiProgram<P> create(ShaderLoader loader, ProgramSpec<P> spec); IMultiProgram<P> create(ShaderLoader loader, ShaderContext<P> ctx, ProgramSpec spec);
} }

View file

@ -1,5 +1,6 @@
package com.jozufozu.flywheel.backend.gl.shader; package com.jozufozu.flywheel.backend.gl.shader;
import com.jozufozu.flywheel.backend.ShaderContext;
import com.jozufozu.flywheel.backend.ShaderLoader; import com.jozufozu.flywheel.backend.ShaderLoader;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
@ -29,8 +30,8 @@ public class SingleProgram<P extends GlProgram> implements IMultiProgram<P> {
} }
@Override @Override
public IMultiProgram<P> create(ShaderLoader loader, ProgramSpec<P> spec) { public IMultiProgram<P> create(ShaderLoader loader, ShaderContext<P> ctx, ProgramSpec spec) {
GlProgram.Builder builder = loader.loadProgram(spec); GlProgram.Builder builder = loader.loadProgram(ctx, spec);
return new SingleProgram<>(factory.create(builder.name, builder.program)); return new SingleProgram<>(factory.create(builder.name, builder.program));
} }

View file

@ -7,8 +7,10 @@ import java.util.Map;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.FastRenderDispatcher;
import com.jozufozu.flywheel.backend.MaterialType; import com.jozufozu.flywheel.backend.MaterialType;
import com.jozufozu.flywheel.backend.MaterialTypes; import com.jozufozu.flywheel.backend.MaterialTypes;
import com.jozufozu.flywheel.backend.ShaderContext;
import com.jozufozu.flywheel.backend.core.BasicProgram; import com.jozufozu.flywheel.backend.core.BasicProgram;
import com.jozufozu.flywheel.backend.core.ModelData; import com.jozufozu.flywheel.backend.core.ModelData;
import com.jozufozu.flywheel.backend.core.OrientedData; import com.jozufozu.flywheel.backend.core.OrientedData;
@ -32,19 +34,21 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
protected Map<TileEntity, ITickableInstance> tickableInstances = new HashMap<>(); protected Map<TileEntity, ITickableInstance> tickableInstances = new HashMap<>();
protected Map<TileEntity, IDynamicInstance> dynamicInstances = new HashMap<>(); protected Map<TileEntity, IDynamicInstance> dynamicInstances = new HashMap<>();
public final ShaderContext<P> context;
protected Map<MaterialType<?>, RenderMaterial<P, ?>> materials = new HashMap<>(); protected Map<MaterialType<?>, RenderMaterial<P, ?>> materials = new HashMap<>();
protected int frame; protected int frame;
protected int tick; protected int tick;
protected InstancedTileRenderer() { protected InstancedTileRenderer(ShaderContext<P> context) {
registerMaterials(); this.context = context;
FastRenderDispatcher.materials.forEach((key, value) -> materials.put(key, value.create(this)));
} }
public abstract BlockPos getOriginCoordinate(); public abstract BlockPos getOriginCoordinate();
public abstract void registerMaterials();
public void tick(double cameraX, double cameraY, double cameraZ) { public void tick(double cameraX, double cameraY, double cameraZ) {
tick++; tick++;

View file

@ -0,0 +1,19 @@
package com.jozufozu.flywheel.backend.instancing;
import com.jozufozu.flywheel.backend.core.BasicProgram;
import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec;
public class MaterialFactory {
ProgramSpec programSpec;
ModelFactory<?> modelFactory;
public MaterialFactory(ProgramSpec programSpec, ModelFactory<?> modelFactory) {
this.programSpec = programSpec;
this.modelFactory = modelFactory;
}
public <P extends BasicProgram> RenderMaterial<P, ?> create(InstancedTileRenderer<P> renderer) {
return new RenderMaterial<>(renderer, programSpec, modelFactory);
}
}

View file

@ -9,7 +9,6 @@ import org.apache.commons.lang3.tuple.Pair;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.FastRenderDispatcher; import com.jozufozu.flywheel.backend.FastRenderDispatcher;
import com.jozufozu.flywheel.backend.RenderUtil; import com.jozufozu.flywheel.backend.RenderUtil;
import com.jozufozu.flywheel.backend.core.BasicProgram; import com.jozufozu.flywheel.backend.core.BasicProgram;
@ -30,20 +29,20 @@ import net.minecraft.util.math.vector.Matrix4f;
public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel<?>> { public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel<?>> {
protected final InstancedTileRenderer<?> renderer; protected final InstancedTileRenderer<P> renderer;
protected final Cache<Object, MODEL> models; protected final Cache<Object, MODEL> models;
protected final ModelFactory<MODEL> factory; protected final ModelFactory<MODEL> factory;
protected final ProgramSpec<P> programSpec; protected final ProgramSpec programSpec;
protected final Predicate<RenderType> layerPredicate; protected final Predicate<RenderType> layerPredicate;
/** /**
* Creates a material that renders in the default layer (CUTOUT_MIPPED) * Creates a material that renders in the default layer (CUTOUT_MIPPED)
*/ */
public RenderMaterial(InstancedTileRenderer<?> renderer, ProgramSpec<P> programSpec, ModelFactory<MODEL> factory) { public RenderMaterial(InstancedTileRenderer<P> renderer, ProgramSpec programSpec, ModelFactory<MODEL> factory) {
this(renderer, programSpec, factory, type -> type == RenderType.getCutoutMipped()); this(renderer, programSpec, factory, type -> type == RenderType.getCutoutMipped());
} }
public RenderMaterial(InstancedTileRenderer<?> renderer, ProgramSpec<P> programSpec, ModelFactory<MODEL> factory, Predicate<RenderType> layerPredicate) { public RenderMaterial(InstancedTileRenderer<P> renderer, ProgramSpec programSpec, ModelFactory<MODEL> factory, Predicate<RenderType> layerPredicate) {
this.renderer = renderer; this.renderer = renderer;
this.models = CacheBuilder.newBuilder() this.models = CacheBuilder.newBuilder()
.removalListener(notification -> ((InstancedModel<?>) notification.getValue()).delete()) .removalListener(notification -> ((InstancedModel<?>) notification.getValue()).delete())
@ -62,7 +61,7 @@ public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel
} }
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, ShaderCallback<P> setup) { public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, ShaderCallback<P> setup) {
P program = Backend.getProgram(programSpec); P program = renderer.context.getProgram(programSpec);
program.bind(viewProjection, camX, camY, camZ, FastRenderDispatcher.getDebugMode()); program.bind(viewProjection, camX, camY, camZ, FastRenderDispatcher.getDebugMode());
if (setup != null) setup.call(program); if (setup != null) setup.call(program);

View file

@ -9,6 +9,7 @@ import javax.annotation.Nullable;
import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.OptifineHandler; import com.jozufozu.flywheel.backend.OptifineHandler;
import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer;
import com.jozufozu.flywheel.backend.core.PartialModel; import com.jozufozu.flywheel.backend.core.PartialModel;
import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
@ -27,7 +28,6 @@ import com.simibubi.create.foundation.item.CustomRenderedItems;
import com.simibubi.create.foundation.ponder.content.PonderIndex; import com.simibubi.create.foundation.ponder.content.PonderIndex;
import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; import com.simibubi.create.foundation.ponder.elements.WorldSectionElement;
import com.simibubi.create.foundation.render.AllProgramSpecs; import com.simibubi.create.foundation.render.AllProgramSpecs;
import com.simibubi.create.foundation.render.KineticRenderer;
import com.simibubi.create.foundation.render.SuperByteBufferCache; import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.utility.WorldAttached; import com.simibubi.create.foundation.utility.WorldAttached;
import com.simibubi.create.foundation.utility.ghost.GhostBlocks; import com.simibubi.create.foundation.utility.ghost.GhostBlocks;
@ -65,7 +65,7 @@ public class CreateClient {
public static SchematicHandler schematicHandler; public static SchematicHandler schematicHandler;
public static SchematicAndQuillHandler schematicAndQuillHandler; public static SchematicAndQuillHandler schematicAndQuillHandler;
public static SuperByteBufferCache bufferCache; public static SuperByteBufferCache bufferCache;
public static WorldAttached<KineticRenderer> kineticRenderer; public static WorldAttached<BasicInstancedTileRenderer> kineticRenderer;
public static final Outliner outliner = new Outliner(); public static final Outliner outliner = new Outliner();
public static GhostBlocks ghostBlocks; public static GhostBlocks ghostBlocks;
@ -88,7 +88,7 @@ public class CreateClient {
public static void clientInit(FMLClientSetupEvent event) { public static void clientInit(FMLClientSetupEvent event) {
AllProgramSpecs.init(); AllProgramSpecs.init();
kineticRenderer = new WorldAttached<>(KineticRenderer::new); kineticRenderer = new WorldAttached<>(BasicInstancedTileRenderer::new);
schematicSender = new ClientSchematicLoader(); schematicSender = new ClientSchematicLoader();
schematicHandler = new SchematicHandler(); schematicHandler = new SchematicHandler();

View file

@ -7,22 +7,15 @@ import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import com.jozufozu.flywheel.backend.MaterialTypes; import com.jozufozu.flywheel.backend.core.ContraptionContext;
import com.jozufozu.flywheel.backend.core.OrientedModel;
import com.jozufozu.flywheel.backend.core.TransformedModel;
import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer;
import com.jozufozu.flywheel.backend.instancing.RenderMaterial; import com.jozufozu.flywheel.backend.instancing.RenderMaterial;
import com.simibubi.create.AllMovementBehaviours; import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
import com.simibubi.create.content.contraptions.base.RotatingModel;
import com.simibubi.create.content.contraptions.components.actors.ActorData; import com.simibubi.create.content.contraptions.components.actors.ActorData;
import com.simibubi.create.content.contraptions.components.actors.ActorModel;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
import com.simibubi.create.content.logistics.block.FlapModel;
import com.simibubi.create.foundation.render.AllProgramSpecs;
import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -35,19 +28,9 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer<Contraptio
private final WeakReference<RenderedContraption> contraption; private final WeakReference<RenderedContraption> contraption;
ContraptionKineticRenderer(RenderedContraption contraption) { ContraptionKineticRenderer(RenderedContraption contraption) {
this.contraption = new WeakReference<>(contraption); super(ContraptionContext.INSTANCE);
} this.contraption = new WeakReference<>(contraption);
}
@Override
public void registerMaterials() {
materials.put(MaterialTypes.TRANSFORMED, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, TransformedModel::new));
materials.put(MaterialTypes.ORIENTED, new RenderMaterial<>(this, AllProgramSpecs.C_ORIENTED, OrientedModel::new));
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.C_BELT, BeltInstancedModel::new));
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.C_ROTATING, RotatingModel::new));
materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.C_FLAPS, FlapModel::new));
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.C_ACTOR, ActorModel::new));
}
public void tick() { public void tick() {
actors.forEach(ActorInstance::tick); actors.forEach(ActorInstance::tick);

View file

@ -10,6 +10,7 @@ import org.lwjgl.opengl.GL40;
import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.FastRenderDispatcher; import com.jozufozu.flywheel.backend.FastRenderDispatcher;
import com.jozufozu.flywheel.backend.core.ContraptionContext;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllMovementBehaviours; import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
@ -81,12 +82,12 @@ public class ContraptionRenderDispatcher {
GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4 GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4
if (Backend.canUseVBOs()) { if (Backend.canUseVBOs()) {
ContraptionProgram structureShader = Backend.getProgram(AllProgramSpecs.C_STRUCTURE); ContraptionProgram structureShader = ContraptionContext.INSTANCE.getProgram(AllProgramSpecs.C_STRUCTURE);
structureShader.bind(viewProjection, camX, camY, camZ, FastRenderDispatcher.getDebugMode()); structureShader.bind(viewProjection, camX, camY, camZ, FastRenderDispatcher.getDebugMode());
for (RenderedContraption renderer : renderers.values()) { for (RenderedContraption renderer : renderers.values()) {
renderer.doRenderLayer(layer, structureShader); renderer.doRenderLayer(layer, structureShader);
} }
} }
if (Backend.canUseInstancing()) { if (Backend.canUseInstancing()) {
for (RenderedContraption renderer : renderers.values()) { for (RenderedContraption renderer : renderers.values()) {

View file

@ -5,6 +5,7 @@ import java.util.List;
import com.jozufozu.flywheel.backend.FastRenderDispatcher; import com.jozufozu.flywheel.backend.FastRenderDispatcher;
import com.jozufozu.flywheel.backend.RenderWork; import com.jozufozu.flywheel.backend.RenderWork;
import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllFluids; import com.simibubi.create.AllFluids;
@ -36,7 +37,6 @@ import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.networking.LeftClickPacket; import com.simibubi.create.foundation.networking.LeftClickPacket;
import com.simibubi.create.foundation.ponder.PonderTooltipHandler; import com.simibubi.create.foundation.ponder.PonderTooltipHandler;
import com.simibubi.create.foundation.render.KineticRenderer;
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
import com.simibubi.create.foundation.sound.SoundScapes; import com.simibubi.create.foundation.sound.SoundScapes;
import com.simibubi.create.foundation.tileEntity.behaviour.edgeInteraction.EdgeInteractionRenderer; import com.simibubi.create.foundation.tileEntity.behaviour.edgeInteraction.EdgeInteractionRenderer;
@ -144,7 +144,7 @@ public class ClientEvents {
if (world.isRemote() && world instanceof ClientWorld && !(world instanceof WrappedClientWorld)) { if (world.isRemote() && world instanceof ClientWorld && !(world instanceof WrappedClientWorld)) {
CreateClient.invalidateRenderers(world); CreateClient.invalidateRenderers(world);
AnimationTickHolder.reset(); AnimationTickHolder.reset();
KineticRenderer renderer = CreateClient.kineticRenderer.get(world); BasicInstancedTileRenderer renderer = CreateClient.kineticRenderer.get(world);
renderer.invalidate(); renderer.invalidate();
((ClientWorld) world).loadedTileEntityList.forEach(renderer::add); ((ClientWorld) world).loadedTileEntityList.forEach(renderer::add);
} }

View file

@ -10,11 +10,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.FastRenderDispatcher; import com.jozufozu.flywheel.backend.FastRenderDispatcher;
import com.jozufozu.flywheel.backend.OptifineHandler; import com.jozufozu.flywheel.backend.OptifineHandler;
import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.render.KineticRenderer;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.ActiveRenderInfo;
@ -96,7 +96,7 @@ public class RenderHooksMixin {
Backend.refresh(); Backend.refresh();
if (Backend.canUseInstancing() && world != null) { if (Backend.canUseInstancing() && world != null) {
KineticRenderer kineticRenderer = CreateClient.kineticRenderer.get(world); BasicInstancedTileRenderer kineticRenderer = CreateClient.kineticRenderer.get(world);
kineticRenderer.invalidate(); kineticRenderer.invalidate();
world.loadedTileEntityList.forEach(kineticRenderer::add); world.loadedTileEntityList.forEach(kineticRenderer::add);
} }

View file

@ -10,8 +10,8 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.render.KineticRenderer;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -46,7 +46,7 @@ public class TileWorldHookMixin {
@Inject(at = @At(value = "INVOKE", target = "Ljava/util/Set;clear()V", ordinal = 0), method = "tickBlockEntities") @Inject(at = @At(value = "INVOKE", target = "Ljava/util/Set;clear()V", ordinal = 0), method = "tickBlockEntities")
private void onChunkUnload(CallbackInfo ci) { private void onChunkUnload(CallbackInfo ci) {
if (isRemote) { if (isRemote) {
KineticRenderer kineticRenderer = CreateClient.kineticRenderer.get(self); BasicInstancedTileRenderer kineticRenderer = CreateClient.kineticRenderer.get(self);
for (TileEntity tile : tileEntitiesToBeRemoved) { for (TileEntity tile : tileEntitiesToBeRemoved) {
kineticRenderer.remove(tile); kineticRenderer.remove(tile);
} }

View file

@ -3,21 +3,16 @@ package com.simibubi.create.foundation.render;
import static com.jozufozu.flywheel.backend.Backend.register; import static com.jozufozu.flywheel.backend.Backend.register;
import com.jozufozu.flywheel.backend.core.BasicAttributes; import com.jozufozu.flywheel.backend.core.BasicAttributes;
import com.jozufozu.flywheel.backend.core.BasicProgram;
import com.jozufozu.flywheel.backend.core.ModelAttributes; import com.jozufozu.flywheel.backend.core.ModelAttributes;
import com.jozufozu.flywheel.backend.core.OrientedAttributes; import com.jozufozu.flywheel.backend.core.OrientedAttributes;
import com.jozufozu.flywheel.backend.core.TransformAttributes; import com.jozufozu.flywheel.backend.core.TransformAttributes;
import com.jozufozu.flywheel.backend.effects.SphereFilterProgram;
import com.jozufozu.flywheel.backend.gl.shader.FogSensitiveProgram;
import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec; import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec;
import com.jozufozu.flywheel.backend.gl.shader.ShaderConstants; import com.jozufozu.flywheel.backend.gl.shader.ShaderConstants;
import com.jozufozu.flywheel.backend.gl.shader.SingleProgram;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.base.KineticAttributes; import com.simibubi.create.content.contraptions.base.KineticAttributes;
import com.simibubi.create.content.contraptions.base.RotatingAttributes; import com.simibubi.create.content.contraptions.base.RotatingAttributes;
import com.simibubi.create.content.contraptions.components.actors.ActorVertexAttributes; 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.components.structureMovement.render.ContraptionAttributes;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionProgram;
import com.simibubi.create.content.contraptions.relays.belt.BeltAttributes; import com.simibubi.create.content.contraptions.relays.belt.BeltAttributes;
import com.simibubi.create.content.logistics.block.FlapAttributes; import com.simibubi.create.content.logistics.block.FlapAttributes;
@ -28,7 +23,7 @@ public class AllProgramSpecs {
// noop, make sure the static field are loaded. // noop, make sure the static field are loaded.
} }
public static final ProgramSpec<SphereFilterProgram> CHROMATIC = register(ProgramSpec.builder("chromatic", new SingleProgram.SpecLoader<>(SphereFilterProgram::new)) public static final ProgramSpec CHROMATIC = register(builder("chromatic")
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(TransformAttributes.class) .addAttributes(TransformAttributes.class)
@ -36,7 +31,7 @@ public class AllProgramSpecs {
.setFrag(Locations.EFFECT_FRAG) .setFrag(Locations.EFFECT_FRAG)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<BasicProgram> MODEL = register(ProgramSpec.builder("model", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)) public static final ProgramSpec MODEL = register(builder("model")
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(TransformAttributes.class) .addAttributes(TransformAttributes.class)
@ -44,7 +39,7 @@ public class AllProgramSpecs {
.setFrag(Locations.BLOCK) .setFrag(Locations.BLOCK)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<BasicProgram> ORIENTED = register(ProgramSpec.builder("oriented", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)) public static final ProgramSpec ORIENTED = register(builder("oriented")
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(OrientedAttributes.class) .addAttributes(OrientedAttributes.class)
@ -52,7 +47,7 @@ public class AllProgramSpecs {
.setFrag(Locations.BLOCK) .setFrag(Locations.BLOCK)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<BasicProgram> ROTATING = register(ProgramSpec.builder("rotating", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)) public static final ProgramSpec ROTATING = register(builder("rotating")
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class) .addAttributes(KineticAttributes.class)
@ -61,7 +56,7 @@ public class AllProgramSpecs {
.setFrag(Locations.BLOCK) .setFrag(Locations.BLOCK)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<BasicProgram> BELT = register(ProgramSpec.builder("belt", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)) public static final ProgramSpec BELT = register(builder("belt")
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class) .addAttributes(KineticAttributes.class)
@ -70,60 +65,19 @@ public class AllProgramSpecs {
.setFrag(Locations.BLOCK) .setFrag(Locations.BLOCK)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<BasicProgram> FLAPS = register(ProgramSpec.builder("flap", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new)) public static final ProgramSpec FLAPS = register(builder("flap")
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(FlapAttributes.class) .addAttributes(FlapAttributes.class)
.setVert(Locations.FLAP) .setVert(Locations.FLAP)
.setFrag(Locations.BLOCK) .setFrag(Locations.BLOCK)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_STRUCTURE = register(ProgramSpec.builder("contraption_structure", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new)) public static final ProgramSpec C_STRUCTURE = register(builder("contraption_structure")
.addAttributes(ContraptionAttributes.class) .addAttributes(ContraptionAttributes.class)
.setVert(Locations.CONTRAPTION_STRUCTURE) .setVert(Locations.CONTRAPTION_STRUCTURE)
.setFrag(Locations.BLOCK) .setFrag(Locations.BLOCK)
.setDefines(ShaderConstants.define("CONTRAPTION")) .setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_MODEL = register(ProgramSpec.builder("contraption_model", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new)) public static final ProgramSpec C_ACTOR = register(builder("contraption_actor")
.addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class)
.addAttributes(TransformAttributes.class)
.setVert(Locations.MODEL_VERT)
.setFrag(Locations.BLOCK)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_ORIENTED = register(ProgramSpec.builder("contraption_oriented", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new))
.addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class)
.addAttributes(OrientedAttributes.class)
.setVert(Locations.ORIENTED)
.setFrag(Locations.BLOCK)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_ROTATING = register(ProgramSpec.builder("contraption_rotating", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new))
.addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class)
.addAttributes(RotatingAttributes.class)
.setVert(Locations.ROTATING)
.setFrag(Locations.BLOCK)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_BELT = register(ProgramSpec.builder("contraption_belt", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new))
.addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class)
.addAttributes(BeltAttributes.class)
.setVert(Locations.BELT)
.setFrag(Locations.BLOCK)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_FLAPS = register(ProgramSpec.builder("contraption_flap", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new))
.addAttributes(ModelAttributes.class)
.addAttributes(FlapAttributes.class)
.setVert(Locations.FLAP)
.setFrag(Locations.BLOCK)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_ACTOR = register(ProgramSpec.builder("contraption_actor", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new))
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(ActorVertexAttributes.class) .addAttributes(ActorVertexAttributes.class)
.setVert(Locations.CONTRAPTION_ACTOR) .setVert(Locations.CONTRAPTION_ACTOR)
@ -131,6 +85,9 @@ public class AllProgramSpecs {
.setDefines(ShaderConstants.define("CONTRAPTION")) .setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec()); .createProgramSpec());
public static ProgramSpec.Builder builder(String name) {
return ProgramSpec.builder(new ResourceLocation(Create.ID, name));
}
public static class Locations { public static class Locations {
public static final ResourceLocation BLOCK = loc("block.frag"); public static final ResourceLocation BLOCK = loc("block.frag");

View file

@ -1,22 +0,0 @@
package com.simibubi.create.foundation.render;
import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer;
import com.jozufozu.flywheel.backend.instancing.RenderMaterial;
import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
import com.simibubi.create.content.contraptions.base.RotatingModel;
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
import com.simibubi.create.content.logistics.block.FlapModel;
public class KineticRenderer extends BasicInstancedTileRenderer {
@Override
public void registerMaterials() {
super.registerMaterials();
materials.put(KineticRenderMaterials.BELTS,
new RenderMaterial<>(this, AllProgramSpecs.BELT, BeltInstancedModel::new));
materials.put(KineticRenderMaterials.ROTATING,
new RenderMaterial<>(this, AllProgramSpecs.ROTATING, RotatingModel::new));
materials.put(KineticRenderMaterials.FLAPS, new RenderMaterial<>(this, AllProgramSpecs.FLAPS, FlapModel::new));
}
}

View file

@ -1,3 +1,5 @@
#flwinclude <"create:std/fog.glsl">
varying vec3 BoxCoord; varying vec3 BoxCoord;
uniform sampler3D uLightVolume; uniform sampler3D uLightVolume;

View file

@ -1,9 +1,5 @@
#flwinclude <"create:std/fog.glsl"> #flwinclude <"create:std/fog.glsl">
#if defined(CONTRAPTION)
#flwinclude <"create:contraption/builtin.frag">
#else
void FLWFinalizeColor(vec4 color) { void FLWFinalizeColor(vec4 color) {
#if defined(USE_FOG) #if defined(USE_FOG)
float a = color.a; float a = color.a;
@ -18,4 +14,3 @@ vec4 FLWLight(vec2 lightCoords, sampler2D lightMap) {
vec2 lm = lightCoords * 0.9375 + 0.03125; vec2 lm = lightCoords * 0.9375 + 0.03125;
return texture2D(lightMap, lm); return texture2D(lightMap, lm);
} }
#endif

View file

@ -1,6 +1,3 @@
#if defined(CONTRAPTION)
#flwinclude <"create:contraption/builtin.vert">
#else
#if defined(USE_FOG) #if defined(USE_FOG)
varying float FragDistance; varying float FragDistance;
@ -15,4 +12,3 @@ void FLWFinalizeWorldPos(inout vec4 worldPos, vec3 cameraPos) {
void FLWFinalizeNormal(inout vec3 normal) { void FLWFinalizeNormal(inout vec3 normal) {
// noop // noop
} }
#endif