Mostly untangle the loading functions, enforce triangles

This commit is contained in:
JozsefA 2021-06-04 17:55:05 -07:00
parent 9bac709dfd
commit 457fff78f3
14 changed files with 184 additions and 139 deletions

View file

@ -14,6 +14,7 @@ import org.lwjgl.opengl.GLCapabilities;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
import com.jozufozu.flywheel.backend.instancing.InstanceData;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
import com.jozufozu.flywheel.core.WorldContext;
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
@ -45,7 +46,7 @@ public class Backend {
static {
register(WorldContext.INSTANCE);
register(WorldContext.CRUMBLING);
register(InstancedRenderDispatcher.CRUMBLING);
}
public Backend() {

View file

@ -1,16 +1,23 @@
package com.jozufozu.flywheel.backend;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
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.jozufozu.flywheel.core.shader.IMultiProgram;
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
import com.jozufozu.flywheel.core.shader.spec.ProgramState;
import net.minecraft.util.ResourceLocation;
@ -18,57 +25,69 @@ public abstract class ShaderContext<P extends GlProgram> {
protected final Map<ResourceLocation, IMultiProgram<P>> programs = new HashMap<>();
protected ShaderTransformer transformer = new ShaderTransformer();
public ShaderContext() {
}
// TODO: Untangle the loading functions
protected ShaderSources sourceRepo;
/**
* Load all programs associated with this context. This might be just one, if the context is very specialized.
*/
public abstract void load(ShaderSources loader);
protected abstract IMultiProgram<P> loadSpecInternal(ShaderSources loader, ProgramSpec spec);
public void loadProgramFromSpec(ShaderSources loader, ProgramSpec programSpec) {
try {
programs.put(programSpec.name, loadSpecInternal(loader, programSpec));
Backend.log.debug("Loaded program {}", programSpec.name);
} catch (Exception e) {
Backend.log.error("Program '{}': {}", programSpec.name, e);
loader.notifyError();
}
public final void load(ShaderSources loader) {
this.sourceRepo = loader;
load();
}
public Program loadProgram(ShaderSources loader, ProgramSpec spec, Collection<String> defines) {
Shader vertexFile = loader.source(spec.vert, ShaderType.VERTEX);
Shader fragmentFile = loader.source(spec.frag, ShaderType.FRAGMENT);
protected abstract void load();
transformer.transformSource(vertexFile);
transformer.transformSource(fragmentFile);
public Program loadAndLink(ProgramSpec spec, @Nullable ProgramState state) {
Shader vertexFile = getSource(ShaderType.VERTEX, spec.vert);
Shader fragmentFile = getSource(ShaderType.FRAGMENT, spec.frag);
if (defines != null) {
vertexFile.defineAll(defines);
fragmentFile.defineAll(defines);
if (state != null) {
vertexFile.defineAll(state.getDefines());
fragmentFile.defineAll(state.getDefines());
}
Program program = loader.loadProgram(spec.name, vertexFile, fragmentFile);
return link(loadProgram(spec.name, vertexFile, fragmentFile));
}
preLink(program);
protected Shader getSource(ShaderType type, ResourceLocation name) {
return sourceRepo.source(name, type);
}
protected Program link(Program program) {
return program.link();
}
protected void preLink(Program program) {
}
public P getProgram(ResourceLocation spec) {
return programs.get(spec).get();
}
protected 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 shaders What are the different shader stages that should be linked together?
* @return A program with all provided shaders attached
*/
protected Program loadProgram(ResourceLocation name, Collection<Shader> shaders) {
List<GlShader> compiled = new ArrayList<>(shaders.size());
try {
Program builder = new Program(name);
for (Shader shader : shaders) {
GlShader sh = new GlShader(shader);
compiled.add(sh);
builder.attachShader(shader, sh);
}
return builder;
} finally {
compiled.forEach(GlObject::delete);
}
}
}

View file

@ -12,7 +12,6 @@ import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Stream;
@ -26,10 +25,7 @@ import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.jozufozu.flywheel.backend.gl.GlObject;
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.ShaderLoadingException;
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
@ -156,43 +152,6 @@ public class ShaderSources implements ISelectiveResourceReloadListener {
return new Shader(this, type, name, getShaderSource(name));
}
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 shaders What are the different shader stages that should be linked together?
* @return A program with all provided shaders attached
*/
public Program loadProgram(ResourceLocation name, Collection<Shader> shaders) {
List<GlShader> compiled = new ArrayList<>(shaders.size());
try {
Program builder = new Program(name);
for (Shader shader : shaders) {
GlShader sh = new GlShader(shader);
compiled.add(sh);
builder.attachShader(shader, sh);
}
return builder;
} finally {
compiled.forEach(GlObject::delete);
}
}
private void printSource(ResourceLocation name, String source) {
Backend.log.debug("Finished processing '" + name + "':");
int i = 1;
for (String s : source.split("\n")) {
Backend.log.debug(String.format("%1$4s: ", i++) + s);
}
}
public static Stream<String> lines(String s) {
return new BufferedReader(new StringReader(s)).lines();
}

View file

@ -13,12 +13,10 @@ import org.lwjgl.opengl.GL11;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.jozufozu.flywheel.backend.RenderWork;
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.model.BufferedModel;
import com.jozufozu.flywheel.backend.model.IndexedModel;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.core.QuadConverter;
import com.jozufozu.flywheel.util.BufferBuilderReader;
import com.jozufozu.flywheel.util.RenderUtil;
import com.jozufozu.flywheel.util.VirtualEmptyModelData;
@ -133,9 +131,10 @@ public class InstanceMaterial<D extends InstanceData> {
// return new BufferedModel(GlPrimitive.QUADS, format, vertices, vertexCount);
return new IndexedModel(GlPrimitive.TRIANGLES, modelFormat, vertices, vertexCount, QuadConverter.getInstance().quads2Tris(vertexCount / 4));
return IndexedModel.fromSequentialQuads(modelFormat, vertices, vertexCount);
}
// DOWN, UP, NORTH, SOUTH, WEST, EAST, null
private static final Direction[] dirs;
static {

View file

@ -12,8 +12,11 @@ import java.util.Vector;
import javax.annotation.Nonnull;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
import com.jozufozu.flywheel.core.CrumblingInstanceManager;
import com.jozufozu.flywheel.core.CrumblingProgram;
import com.jozufozu.flywheel.core.WorldContext;
import com.jozufozu.flywheel.core.shader.WorldProgram;
import com.jozufozu.flywheel.event.BeginFrameEvent;
@ -35,6 +38,7 @@ import net.minecraft.entity.Entity;
import net.minecraft.inventory.container.PlayerContainer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.LazyValue;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.world.IWorld;
@ -44,10 +48,16 @@ import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber
public class InstancedRenderDispatcher {
private static final RenderType CRUMBLING = ModelBakery.BLOCK_DESTRUCTION_RENDER_LAYERS.get(0);
public static final ResourceLocation CRUMBLING_CONTEXT = new ResourceLocation(Flywheel.ID, "context/crumbling");
public static final WorldContext<CrumblingProgram> CRUMBLING = new WorldContext<>(CrumblingProgram::new)
.withName(CRUMBLING_CONTEXT)
.withBuiltin(ShaderType.FRAGMENT, CRUMBLING_CONTEXT, "/builtin.frag")
.withBuiltin(ShaderType.VERTEX, CRUMBLING_CONTEXT, "/builtin.vert");
private static final RenderType crumblingLayer = ModelBakery.BLOCK_DESTRUCTION_RENDER_LAYERS.get(0);
private static final WorldAttached<TileInstanceManager> tileInstanceManager = new WorldAttached<>(world -> new TileInstanceManager(WorldContext.INSTANCE.getMaterialManager(world)));
public static LazyValue<Vector<CrumblingInstanceManager>> blockBreaking = new LazyValue<>(() -> {
private static final LazyValue<Vector<CrumblingInstanceManager>> blockBreaking = new LazyValue<>(() -> {
Vector<CrumblingInstanceManager> renderers = new Vector<>(10);
for (int i = 0; i < 10; i++) {
renderers.add(new CrumblingInstanceManager());
@ -137,7 +147,7 @@ public class InstancedRenderDispatcher {
glActiveTexture(GL_TEXTURE4);
CRUMBLING.startDrawing();
crumblingLayer.startDrawing();
bitSet.stream().forEach(i -> {
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(i));
CrumblingInstanceManager renderer = renderers.get(i);
@ -150,7 +160,7 @@ public class InstancedRenderDispatcher {
renderer.invalidate();
});
CRUMBLING.endDrawing();
crumblingLayer.endDrawing();
glActiveTexture(GL_TEXTURE0);
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(0));

View file

@ -14,6 +14,7 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.ShaderSources;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
@ -134,6 +135,14 @@ public class Shader {
});
}
public void printSource() {
Backend.log.debug("Source for shader '" + name + "':");
int i = 1;
for (String s : source.split("\n")) {
Backend.log.debug(String.format("%1$4s: ", i++) + s);
}
}
public static Stream<String> lines(String s) {
return new BufferedReader(new StringReader(s)).lines();
}

View file

@ -7,17 +7,27 @@ import org.lwjgl.opengl.GL20;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.core.QuadConverter;
/**
* An indexed triangle model. Just what the driver ordered.
*
* <br><em>This should be favored over a normal BufferedModel.</em>
*/
public class IndexedModel extends BufferedModel {
protected ElementBuffer ebo;
public IndexedModel(GlPrimitive primitiveMode, VertexFormat modelFormat, ByteBuffer buf, int vertices, ElementBuffer ebo) {
super(primitiveMode, modelFormat, buf, vertices);
public IndexedModel(VertexFormat modelFormat, ByteBuffer buf, int vertices, ElementBuffer ebo) {
super(GlPrimitive.TRIANGLES, modelFormat, buf, vertices);
this.ebo = ebo;
}
public static IndexedModel fromSequentialQuads(VertexFormat modelFormat, ByteBuffer quads, int vertices) {
return new IndexedModel(modelFormat, quads, vertices, QuadConverter.getInstance().quads2Tris(vertices / 4));
}
@Override
public void setupState() {
super.setupState();

View file

@ -1,5 +1,6 @@
package com.jozufozu.flywheel.core;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
import com.jozufozu.flywheel.backend.instancing.TileInstanceManager;
@ -7,7 +8,7 @@ import net.minecraft.util.math.BlockPos;
public class CrumblingInstanceManager extends TileInstanceManager {
public CrumblingInstanceManager() {
super(new MaterialManager<>(WorldContext.CRUMBLING));
super(new MaterialManager<>(InstancedRenderDispatcher.CRUMBLING));
}
@Override

View file

@ -25,7 +25,6 @@ import com.jozufozu.flywheel.core.shader.ExtensibleGlProgram;
import com.jozufozu.flywheel.core.shader.IMultiProgram;
import com.jozufozu.flywheel.core.shader.StateSensitiveMultiProgram;
import com.jozufozu.flywheel.core.shader.WorldProgram;
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
import com.jozufozu.flywheel.util.WorldAttached;
import net.minecraft.util.ResourceLocation;
@ -36,10 +35,14 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
private static final String declaration = "#flwbuiltins";
private static final Pattern builtinPattern = Pattern.compile(declaration);
public static final WorldContext<WorldProgram> INSTANCE = new WorldContext<>(new ResourceLocation(Flywheel.ID, "context/world"), WorldProgram::new);
public static final WorldContext<CrumblingProgram> CRUMBLING = new WorldContext<>(new ResourceLocation(Flywheel.ID, "context/crumbling"), CrumblingProgram::new);
public static final ResourceLocation WORLD_CONTEXT = new ResourceLocation(Flywheel.ID, "context/world");
protected final ResourceLocation name;
public static final WorldContext<WorldProgram> INSTANCE = new WorldContext<>(WorldProgram::new)
.withName(WORLD_CONTEXT)
.withBuiltin(ShaderType.FRAGMENT, WORLD_CONTEXT, "/builtin.frag")
.withBuiltin(ShaderType.VERTEX, WORLD_CONTEXT, "/builtin.vert");
protected ResourceLocation name;
protected Supplier<Stream<ResourceLocation>> specStream;
protected TemplateFactory templateFactory;
@ -50,11 +53,8 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
private final ExtensibleGlProgram.Factory<P> factory;
public WorldContext(ResourceLocation root, ExtensibleGlProgram.Factory<P> factory) {
public WorldContext(ExtensibleGlProgram.Factory<P> factory) {
this.factory = factory;
this.name = root;
builtins.put(ShaderType.FRAGMENT, ResourceUtil.subPath(root, "/builtin.frag"));
builtins.put(ShaderType.VERTEX, ResourceUtil.subPath(root, "/builtin.vert"));
specStream = () -> Backend.allMaterials()
.stream()
@ -63,60 +63,88 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
templateFactory = InstancedArraysTemplate::new;
}
public WorldContext<P> withName(ResourceLocation name) {
this.name = name;
return this;
}
public WorldContext<P> withBuiltin(ShaderType shaderType, ResourceLocation folder, String file) {
return withBuiltin(shaderType, ResourceUtil.subPath(folder, file));
}
public WorldContext<P> withBuiltin(ShaderType shaderType, ResourceLocation file) {
builtins.put(shaderType, file);
return this;
}
public MaterialManager<P> getMaterialManager(IWorld world) {
return materialManager.get(world);
}
public WorldContext<P> setSpecStream(Supplier<Stream<ResourceLocation>> specStream) {
public WorldContext<P> withSpecStream(Supplier<Stream<ResourceLocation>> specStream) {
this.specStream = specStream;
return this;
}
public WorldContext<P> setTemplateFactory(TemplateFactory templateFactory) {
public WorldContext<P> withTemplateFactory(TemplateFactory templateFactory) {
this.templateFactory = templateFactory;
return this;
}
@Override
protected IMultiProgram<P> loadSpecInternal(ShaderSources loader, ProgramSpec spec) {
return new StateSensitiveMultiProgram<>(loader, factory, this, spec);
}
protected ShaderTransformer transformer;
protected ProgramTemplate template;
@Override
public void load(ShaderSources loader) {
public void load() {
programs.values().forEach(IMultiProgram::delete);
programs.clear();
Backend.log.info("Loading context '{}'", name);
try {
builtins.forEach((type, resourceLocation) -> builtinSources.put(type, loader.getShaderSource(resourceLocation)));
builtins.forEach((type, resourceLocation) -> builtinSources.put(type, sourceRepo.getShaderSource(resourceLocation)));
} catch (ShaderLoadingException e) {
loader.notifyError();
sourceRepo.notifyError();
Backend.log.error(String.format("Could not find builtin: %s", e.getMessage()));
return;
}
template = templateFactory.create(loader);
template = templateFactory.create(sourceRepo);
transformer = new ShaderTransformer()
.pushStage(this::injectBuiltins)
.pushStage(Shader::processIncludes)
.pushStage(Shader::parseStructs)
.pushStage(template)
.pushStage(Shader::processIncludes);
specStream.get()
.map(Backend::getSpec)
.forEach(spec -> loadProgramFromSpec(loader, spec));
.forEach(spec -> {
try {
programs.put(spec.name, new StateSensitiveMultiProgram<>(factory, this, spec));
Backend.log.debug("Loaded program {}", spec.name);
} catch (Exception e) {
Backend.log.error("Program '{}': {}", spec.name, e);
sourceRepo.notifyError();
}
});
}
@Override
protected void preLink(Program program) {
protected Shader getSource(ShaderType type, ResourceLocation name) {
Shader source = super.getSource(type, name);
transformer.transformSource(source);
return source;
}
@Override
protected Program link(Program program) {
template.attachAttributes(program);
return super.link(program);
}
/**

View file

@ -1,11 +1,9 @@
package com.jozufozu.flywheel.core.shader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.jozufozu.flywheel.backend.ShaderContext;
import com.jozufozu.flywheel.backend.ShaderSources;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.backend.loading.Program;
import com.jozufozu.flywheel.core.shader.spec.IContextCondition;
@ -18,19 +16,19 @@ public class StateSensitiveMultiProgram<P extends GlProgram> implements IMultiPr
List<Pair<IContextCondition, P>> variants;
P fallback;
public StateSensitiveMultiProgram(ShaderSources loader, ExtensibleGlProgram.Factory<P> factory, ShaderContext<P> context, ProgramSpec p) {
public StateSensitiveMultiProgram(ExtensibleGlProgram.Factory<P> factory, ShaderContext<P> context, ProgramSpec p) {
variants = new ArrayList<>(p.states.size());
for (ProgramState state : p.states) {
Program variant = context.loadProgram(loader, p, state.getDefines());
Program variant = context.loadAndLink(p, state);
Pair<IContextCondition, P> pair = Pair.of(state.getContext(), factory.create(variant, state.getExtensions()));
variants.add(pair);
}
fallback = factory.create(context.loadProgram(loader, p, Collections.emptyList()));
fallback = factory.create(context.loadAndLink(p, null));
}
@Override

View file

@ -2,14 +2,12 @@ package com.simibubi.create.content.contraptions.components.structureMovement.gl
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
import com.jozufozu.flywheel.backend.instancing.ITickableInstance;
import com.jozufozu.flywheel.backend.instancing.Instancer;
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
import com.jozufozu.flywheel.backend.model.BufferedModel;
import com.jozufozu.flywheel.backend.model.IndexedModel;
import com.jozufozu.flywheel.core.QuadConverter;
import com.jozufozu.flywheel.core.instancing.ConditionalInstance;
import com.jozufozu.flywheel.core.materials.OrientedData;
import com.simibubi.create.AllItems;
@ -102,15 +100,15 @@ public class GlueInstance extends EntityInstance<SuperGlueEntity> implements ITi
(float) a3.x, (float) a3.y, (float) a3.z, 0, -1, 0, 0, 1,
(float) a4.x, (float) a4.y, (float) a4.z, 0, -1, 0, 0, 0,
// outside quad
(float) b4.x, (float) b4.y, (float) b4.z, 0, 1, 0, 0, 0,
(float) b3.x, (float) b3.y, (float) b3.z, 0, 1, 0, 0, 1,
(float) b2.x, (float) b2.y, (float) b2.z, 0, 1, 0, 1, 1,
(float) b1.x, (float) b1.y, (float) b1.z, 0, 1, 0, 1, 0,
(float) b4.x, (float) b4.y, (float) b4.z, 0, 1, 0, 0, 0,
(float) b3.x, (float) b3.y, (float) b3.z, 0, 1, 0, 0, 1,
(float) b2.x, (float) b2.y, (float) b2.z, 0, 1, 0, 1, 1,
(float) b1.x, (float) b1.y, (float) b1.z, 0, 1, 0, 1, 0,
};
ByteBuffer buffer = ByteBuffer.allocate(quads.length * 4);
buffer.asFloatBuffer().put(quads);
return new IndexedModel(GlPrimitive.TRIANGLES, AllMaterialSpecs.UNLIT_MODEL, buffer, 8, QuadConverter.getInstance().quads2Tris(2));
return IndexedModel.fromSequentialQuads(AllMaterialSpecs.UNLIT_MODEL, buffer, 8);
}
}

View file

@ -16,6 +16,7 @@ import java.util.stream.Stream;
import org.apache.commons.lang3.tuple.Pair;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
import com.jozufozu.flywheel.backend.loading.ModelTemplate;
import com.jozufozu.flywheel.core.WorldContext;
import com.jozufozu.flywheel.event.BeginFrameEvent;
@ -74,10 +75,10 @@ public class ContraptionRenderDispatcher {
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, ContraptionProgram::new)
.setSpecStream(() -> Stream.of(AllProgramSpecs.STRUCTURE))
.setTemplateFactory(ModelTemplate::new);
public static final WorldContext<ContraptionProgram> TILES = new WorldContext<>(ctxRoot, ContraptionProgram::new);
public static final WorldContext<ContraptionProgram> TILES = contraptionContext();
public static final WorldContext<ContraptionProgram> STRUCTURE = contraptionContext()
.withSpecStream(() -> Stream.of(AllProgramSpecs.STRUCTURE))
.withTemplateFactory(ModelTemplate::new);
public static void tick() {
if (Minecraft.getInstance().isGamePaused()) return;
@ -341,4 +342,11 @@ public class ContraptionRenderDispatcher {
public static void removeDeadHolders() {
WORLD_HOLDERS.values().removeIf(ContraptionWorldHolder::isDead);
}
private static WorldContext<ContraptionProgram> contraptionContext() {
return new WorldContext<>(ContraptionProgram::new)
.withName(ctxRoot)
.withBuiltin(ShaderType.FRAGMENT, ctxRoot, "/builtin.frag")
.withBuiltin(ShaderType.VERTEX, ctxRoot, "/builtin.vert");
}
}

View file

@ -10,7 +10,6 @@ import java.util.Map;
import javax.annotation.Nullable;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
import com.jozufozu.flywheel.backend.gl.attrib.CommonAttributes;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
@ -19,7 +18,6 @@ import com.jozufozu.flywheel.backend.model.ArrayModelRenderer;
import com.jozufozu.flywheel.backend.model.BufferedModel;
import com.jozufozu.flywheel.backend.model.IndexedModel;
import com.jozufozu.flywheel.backend.model.ModelRenderer;
import com.jozufozu.flywheel.core.QuadConverter;
import com.jozufozu.flywheel.light.GridAlignedBB;
import com.jozufozu.flywheel.util.BufferBuilderReader;
import com.mojang.blaze3d.matrix.MatrixStack;
@ -203,6 +201,6 @@ public class RenderedContraption extends ContraptionWorldHolder {
vertices.rewind();
return new IndexedModel(GlPrimitive.TRIANGLES, format, vertices, vertexCount, QuadConverter.getInstance().quads2Tris(vertexCount / 4));
return IndexedModel.fromSequentialQuads(format, vertices, vertexCount);
}
}

View file

@ -1,16 +1,14 @@
package com.simibubi.create.foundation.render.effects;
import java.util.Collections;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.ShaderContext;
import com.jozufozu.flywheel.backend.ShaderSources;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
import com.jozufozu.flywheel.backend.loading.Shader;
import com.jozufozu.flywheel.backend.loading.ShaderTransformer;
import com.jozufozu.flywheel.core.shader.IMultiProgram;
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
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();
@ -20,14 +18,23 @@ public class EffectsContext extends ShaderContext<SphereFilterProgram> {
}
@Override
protected IMultiProgram<SphereFilterProgram> loadSpecInternal(ShaderSources loader, ProgramSpec spec) {
return new SphereFilterProgram(loadProgram(loader, spec, Collections.emptyList()));
public void load() {
ProgramSpec programSpec = Backend.getSpec(AllProgramSpecs.CHROMATIC);
try {
programs.put(programSpec.name, new SphereFilterProgram(loadAndLink(programSpec, null)));
Backend.log.debug("Loaded program {}", programSpec.name);
} catch (Exception e) {
Backend.log.error("Program '{}': {}", programSpec.name, e);
sourceRepo.notifyError();
}
}
@Override
public void load(ShaderSources loader) {
transformer = new ShaderTransformer()
.pushStage(Shader::processIncludes);
loadProgramFromSpec(loader, Backend.getSpec(AllProgramSpecs.CHROMATIC));
protected Shader getSource(ShaderType type, ResourceLocation name) {
Shader source = super.getSource(type, name);
source.processIncludes();
return source;
}
}