Refactor InstancedModel to not rely on inheritance

- Instead, MaterialSpecs store the information
 - RenderMaterials are now generic on InstanceData instead of InstancedModel
 - RenderMaterials are directly constructed with and store a MaterialSpec
This commit is contained in:
JozsefA 2021-05-15 16:41:56 -07:00
parent 79977aee14
commit 9ff193946c
35 changed files with 195 additions and 379 deletions

View file

@ -26,10 +26,9 @@ import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
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;
import com.jozufozu.flywheel.backend.instancing.InstancedModel; import com.jozufozu.flywheel.backend.instancing.InstanceData;
import com.jozufozu.flywheel.backend.instancing.MaterialSpec; import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
import com.jozufozu.flywheel.util.WorldAttached; import com.jozufozu.flywheel.util.WorldAttached;
import com.simibubi.create.content.contraptions.KineticDebugger;
import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.AllConfigs;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
@ -131,7 +130,7 @@ public class Backend {
/** /**
* Register an instancing material. * Register an instancing material.
*/ */
public static <M extends InstancedModel<?>> MaterialSpec<M> register(MaterialSpec<M> spec) { public static <D extends InstanceData> MaterialSpec<D> register(MaterialSpec<D> spec) {
ResourceLocation name = spec.name; ResourceLocation name = spec.name;
if (materialRegistry.containsKey(name)) { if (materialRegistry.containsKey(name)) {
throw new IllegalStateException("Material spec '" + name + "' already registered."); throw new IllegalStateException("Material spec '" + name + "' already registered.");
@ -275,14 +274,6 @@ public class Backend {
return canUseInstancing() && isFlywheelWorld(world); return canUseInstancing() && isFlywheelWorld(world);
} }
/**
* TODO: Remove in favor of separate debug programs specified by the SpecLoader/IMultiProgram
*/
@Deprecated
public static int getDebugMode() {
return KineticDebugger.isActive() ? 1 : 0;
}
public static Collection<MaterialSpec<?>> allMaterials() { public static Collection<MaterialSpec<?>> allMaterials() {
return materialRegistry.values(); return materialRegistry.values();
} }

View file

@ -13,16 +13,45 @@ import net.minecraft.client.renderer.BufferBuilder;
public abstract class BufferedModel extends TemplateBuffer { public abstract class BufferedModel extends TemplateBuffer {
protected final VertexFormat modelFormat;
protected GlBuffer modelVBO; protected GlBuffer modelVBO;
protected boolean removed; private boolean initialized; // lazy init
private boolean removed;
protected BufferedModel(BufferBuilder buf) { protected BufferedModel(VertexFormat modelFormat, BufferBuilder buf) {
super(buf); super(buf);
if (vertexCount > 0) init(); this.modelFormat = modelFormat;
}
/**
* Renders this model, checking first if there is anything to render.
*/
public final void render() {
if (vertexCount == 0 || removed) return;
if (!initialized) {
// Lazily acquire resources in order to get around initialization order, as #getTotalShaderAttributeCount
// might depend on fields in subclasses.
init();
initialized = true;
}
doRender();
}
/**
* Set up any state and make the draw calls.
*/
protected abstract void doRender();
public final void delete() {
removed = true;
if (initialized) {
RenderWork.enqueue(this::deleteInternal);
}
} }
protected void init() { protected void init() {
modelVBO = new GlBuffer(GlBufferType.ARRAY_BUFFER); modelVBO = new GlBuffer(GlBufferType.ARRAY_BUFFER);
modelVBO.bind(); modelVBO.bind();
@ -31,7 +60,7 @@ public abstract class BufferedModel extends TemplateBuffer {
} }
protected void initModel() { protected void initModel() {
int stride = getModelFormat().getStride(); int stride = modelFormat.getStride();
int invariantSize = vertexCount * stride; int invariantSize = vertexCount * stride;
// allocate the buffer on the gpu // allocate the buffer on the gpu
@ -47,40 +76,17 @@ public abstract class BufferedModel extends TemplateBuffer {
protected abstract void copyVertex(MappedBuffer to, int index); protected abstract void copyVertex(MappedBuffer to, int index);
protected abstract VertexFormat getModelFormat();
protected int getTotalShaderAttributeCount() { protected int getTotalShaderAttributeCount() {
return getModelFormat().getShaderAttributeCount(); return modelFormat.getShaderAttributeCount();
} }
/**
* Renders this model, checking first if there is anything to render.
*/
public final void render() {
if (vertexCount == 0 || removed) return;
doRender();
}
/**
* Set up any state and make the draw calls.
*/
protected abstract void doRender();
protected void setupAttributes() { protected void setupAttributes() {
int numAttributes = getTotalShaderAttributeCount(); int numAttributes = getTotalShaderAttributeCount();
for (int i = 0; i <= numAttributes; i++) { for (int i = 0; i <= numAttributes; i++) {
GL20.glEnableVertexAttribArray(i); GL20.glEnableVertexAttribArray(i);
} }
getModelFormat().vertexAttribPointers(0); modelFormat.vertexAttribPointers(0);
}
public final void delete() {
removed = true;
if (vertexCount > 0) {
RenderWork.enqueue(this::deleteInternal);
}
} }
protected void deleteInternal() { protected void deleteInternal() {

View file

@ -1,28 +0,0 @@
package com.jozufozu.flywheel.backend.core.materials;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer;
import net.minecraft.client.renderer.BufferBuilder;
public class OrientedModel extends InstancedModel<OrientedData> {
public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder()
.addAttributes(BasicAttributes.class)
.addAttributes(OrientedAttributes.class)
.build();
public OrientedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(renderer, buf);
}
@Override
protected OrientedData newInstance() {
return new OrientedData(this);
}
@Override
protected VertexFormat getInstanceFormat() {
return INSTANCE_FORMAT;
}
}

View file

@ -1,28 +0,0 @@
package com.jozufozu.flywheel.backend.core.materials;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer;
import net.minecraft.client.renderer.BufferBuilder;
public class TransformedModel extends InstancedModel<ModelData> {
public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder()
.addAttributes(BasicAttributes.class)
.addAttributes(TransformAttributes.class)
.build();
public TransformedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(renderer, buf);
}
@Override
protected ModelData newInstance() {
return new ModelData(this);
}
@Override
protected VertexFormat getInstanceFormat() {
return INSTANCE_FORMAT;
}
}

View file

@ -20,6 +20,9 @@ public abstract class MappedBuffer implements AutoCloseable {
protected abstract void checkAndMap(); protected abstract void checkAndMap();
/**
* Make the changes in client memory available to the GPU.
*/
public void flush() { public void flush() {
if (mapped) { if (mapped) {
GL15.glUnmapBuffer(owner.type.glEnum); GL15.glUnmapBuffer(owner.type.glEnum);
@ -51,7 +54,6 @@ public abstract class MappedBuffer implements AutoCloseable {
/** /**
* Position this buffer relative to the 0-index in GPU memory. * Position this buffer relative to the 0-index in GPU memory.
* *
* @param p
* @return This buffer. * @return This buffer.
*/ */
public MappedBuffer position(int p) { public MappedBuffer position(int p) {

View file

@ -0,0 +1,5 @@
package com.jozufozu.flywheel.backend.instancing;
public interface InstanceFactory<D extends InstanceData> {
D create(InstancedModel<? super D> owner);
}

View file

@ -17,11 +17,13 @@ import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
public abstract class InstancedModel<D extends InstanceData> extends BufferedModel { public class InstancedModel<D extends InstanceData> extends BufferedModel {
public static final VertexFormat FORMAT = VertexFormat.builder().addAttributes(ModelAttributes.class).build(); public static final VertexFormat FORMAT = VertexFormat.builder().addAttributes(ModelAttributes.class).build();
public final InstancedTileRenderer<?> renderer; public final InstancedTileRenderer<?> renderer;
protected final VertexFormat instanceFormat;
protected final InstanceFactory<D> factory;
protected GlVertexArray vao; protected GlVertexArray vao;
protected GlBuffer instanceVBO; protected GlBuffer instanceVBO;
protected int glBufferSize = -1; protected int glBufferSize = -1;
@ -32,11 +34,22 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
boolean anyToRemove; boolean anyToRemove;
boolean anyToUpdate; boolean anyToUpdate;
public InstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) { public InstancedModel(InstancedTileRenderer<?> renderer, VertexFormat instanceFormat, InstanceFactory<D> factory, BufferBuilder buf) {
super(buf); super(FORMAT, buf);
this.factory = factory;
this.instanceFormat = instanceFormat;
this.renderer = renderer; this.renderer = renderer;
} }
public synchronized D createInstance() {
D instanceData = factory.create(this);
instanceData.dirty = true;
anyToUpdate = true;
data.add(instanceData);
return instanceData;
}
@Override @Override
protected void init() { protected void init() {
vao = new GlVertexArray(); vao = new GlVertexArray();
@ -53,14 +66,6 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
setupAttributes(); setupAttributes();
} }
public int instanceCount() {
return data.size();
}
public boolean isEmpty() {
return instanceCount() == 0;
}
protected void deleteInternal() { protected void deleteInternal() {
super.deleteInternal(); super.deleteInternal();
@ -68,23 +73,13 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
vao.delete(); vao.delete();
} }
public synchronized D createInstance() {
D instanceData = newInstance();
instanceData.dirty = true;
anyToUpdate = true;
data.add(instanceData);
return instanceData;
}
protected abstract D newInstance();
protected void doRender() { protected void doRender() {
vao.bind(); vao.bind();
renderSetup(); renderSetup();
if (glInstanceCount > 0) if (glInstanceCount > 0)
Backend.compat.drawInstanced.drawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount); Backend.compat.drawInstanced.drawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount);
vao.unbind(); vao.unbind();
} }
@ -115,22 +110,22 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
} }
private void informAttribDivisors() { private void informAttribDivisors() {
int staticAttributes = getModelFormat().getShaderAttributeCount(); int staticAttributes = modelFormat.getShaderAttributeCount();
getInstanceFormat().vertexAttribPointers(staticAttributes); instanceFormat.vertexAttribPointers(staticAttributes);
for (int i = 0; i < getInstanceFormat().getShaderAttributeCount(); i++) { for (int i = 0; i < instanceFormat.getShaderAttributeCount(); i++) {
Backend.compat.instancedArrays.vertexAttribDivisor(i + staticAttributes, 1); Backend.compat.instancedArrays.vertexAttribDivisor(i + staticAttributes, 1);
} }
} }
private void clearBufferTail() { private void clearBufferTail() {
int size = data.size(); int size = data.size();
final int offset = size * getInstanceFormat().getStride(); final int offset = size * instanceFormat.getStride();
final int length = glBufferSize - offset; final int length = glBufferSize - offset;
if (length > 0) { if (length > 0) {
MappedBuffer buffer = instanceVBO.getBuffer(offset, length); instanceVBO.getBuffer(offset, length)
buffer.putByteArray(new byte[length]); .putByteArray(new byte[length])
buffer.flush(); .flush();
} }
} }
@ -139,7 +134,7 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
if (size <= 0) return; if (size <= 0) return;
final int stride = getInstanceFormat().getStride(); final int stride = instanceFormat.getStride();
final BitSet dirtySet = getDirtyBitSet(); final BitSet dirtySet = getDirtyBitSet();
if (dirtySet.isEmpty()) return; if (dirtySet.isEmpty()) return;
@ -180,7 +175,7 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
private boolean realloc() { private boolean realloc() {
int size = this.data.size(); int size = this.data.size();
int stride = getInstanceFormat().getStride(); int stride = instanceFormat.getStride();
int requiredSize = size * stride; int requiredSize = size * stride;
if (requiredSize > glBufferSize) { if (requiredSize > glBufferSize) {
glBufferSize = requiredSize + stride * 16; glBufferSize = requiredSize + stride * 16;
@ -199,9 +194,7 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
} }
private void removeDeletedInstances() { private void removeDeletedInstances() {
// figure out which elements are to be removed // Figure out which elements are to be removed.
// any exception thrown from the filter predicate at this stage
// will leave the collection unmodified
final int oldSize = this.data.size(); final int oldSize = this.data.size();
int removeCount = 0; int removeCount = 0;
final BitSet removeSet = new BitSet(oldSize); final BitSet removeSet = new BitSet(oldSize);
@ -246,14 +239,7 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
constant.putFloat(getV(template, i)); constant.putFloat(getV(template, i));
} }
@Override
protected VertexFormat getModelFormat() {
return FORMAT;
}
protected abstract VertexFormat getInstanceFormat();
protected int getTotalShaderAttributeCount() { protected int getTotalShaderAttributeCount() {
return getInstanceFormat().getShaderAttributeCount() + super.getTotalShaderAttributeCount(); return instanceFormat.getShaderAttributeCount() + super.getTotalShaderAttributeCount();
} }
} }

View file

@ -46,7 +46,7 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
materials = new HashMap<>(); materials = new HashMap<>();
for (MaterialSpec<?> spec : Backend.allMaterials()) { for (MaterialSpec<?> spec : Backend.allMaterials()) {
materials.put(spec, spec.create(this)); materials.put(spec, new RenderMaterial<>(this, spec));
} }
queuedUpdates = ConcurrentHashMap.newKeySet(64); queuedUpdates = ConcurrentHashMap.newKeySet(64);
@ -137,15 +137,15 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <M extends InstancedModel<?>> RenderMaterial<P, M> getMaterial(MaterialSpec<M> materialType) { public <D extends InstanceData> RenderMaterial<P, D> getMaterial(MaterialSpec<D> materialType) {
return (RenderMaterial<P, M>) materials.get(materialType); return (RenderMaterial<P, D>) materials.get(materialType);
} }
public RenderMaterial<P, InstancedModel<ModelData>> getTransformMaterial() { public RenderMaterial<P, ModelData> getTransformMaterial() {
return getMaterial(AllMaterialSpecs.TRANSFORMED); return getMaterial(AllMaterialSpecs.TRANSFORMED);
} }
public RenderMaterial<P, InstancedModel<OrientedData>> getOrientedMaterial() { public RenderMaterial<P, OrientedData> getOrientedMaterial() {
return getMaterial(AllMaterialSpecs.ORIENTED); return getMaterial(AllMaterialSpecs.ORIENTED);
} }

View file

@ -1,32 +1,35 @@
package com.jozufozu.flywheel.backend.instancing; package com.jozufozu.flywheel.backend.instancing;
import com.jozufozu.flywheel.backend.core.BasicProgram; import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec; import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
public class MaterialSpec<M extends InstancedModel<?>> { public class MaterialSpec<D extends InstanceData> {
public final ResourceLocation name; public final ResourceLocation name;
private final ProgramSpec programSpec; private final ProgramSpec programSpec;
private final ModelFactory<M> modelFactory; private final VertexFormat instanceFormat;
private final InstanceFactory<D> instanceFactory;
public MaterialSpec(ResourceLocation name, ProgramSpec programSpec, ModelFactory<M> modelFactory) { public MaterialSpec(ResourceLocation name, ProgramSpec programSpec, VertexFormat instanceFormat, InstanceFactory<D> instanceFactory) {
this.name = name; this.name = name;
this.programSpec = programSpec; this.programSpec = programSpec;
this.modelFactory = modelFactory; this.instanceFormat = instanceFormat;
this.instanceFactory = instanceFactory;
} }
public ProgramSpec getProgramSpec() { public ProgramSpec getProgramSpec() {
return programSpec; return programSpec;
} }
public ModelFactory<M> getModelFactory() { public VertexFormat getInstanceFormat() {
return modelFactory; return instanceFormat;
} }
public <P extends BasicProgram> RenderMaterial<P, M> create(InstancedTileRenderer<P> renderer) { public InstanceFactory<D> getInstanceFactory() {
return new RenderMaterial<>(renderer, programSpec, modelFactory); return instanceFactory;
} }
} }

View file

@ -1,8 +0,0 @@
package com.jozufozu.flywheel.backend.instancing;
import net.minecraft.client.renderer.BufferBuilder;
@FunctionalInterface
public interface ModelFactory<B extends InstancedModel<?>> {
B makeModel(InstancedTileRenderer<?> renderer, BufferBuilder buf);
}

View file

@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend.instancing;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
@ -13,7 +12,6 @@ import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.jozufozu.flywheel.backend.core.BasicProgram; import com.jozufozu.flywheel.backend.core.BasicProgram;
import com.jozufozu.flywheel.backend.core.PartialModel; import com.jozufozu.flywheel.backend.core.PartialModel;
import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec;
import com.jozufozu.flywheel.backend.gl.shader.ShaderCallback; import com.jozufozu.flywheel.backend.gl.shader.ShaderCallback;
import com.jozufozu.flywheel.util.RenderUtil; import com.jozufozu.flywheel.util.RenderUtil;
import com.jozufozu.flywheel.util.VirtualEmptyModelData; import com.jozufozu.flywheel.util.VirtualEmptyModelData;
@ -32,33 +30,19 @@ import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Matrix4f;
public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel<?>> { public class RenderMaterial<P extends BasicProgram, D extends InstanceData> {
protected final InstancedTileRenderer<P> renderer; protected final InstancedTileRenderer<P> renderer;
protected final Cache<Object, MODEL> models; protected final Cache<Object, InstancedModel<D>> models;
protected final ModelFactory<MODEL> factory; protected final MaterialSpec<D> spec;
protected final ProgramSpec programSpec;
protected final Predicate<RenderType> layerPredicate;
/** public RenderMaterial(InstancedTileRenderer<P> renderer, MaterialSpec<D> spec) {
* Creates a material that renders in the default layer (CUTOUT_MIPPED)
*/
public RenderMaterial(InstancedTileRenderer<P> renderer, ProgramSpec programSpec, ModelFactory<MODEL> factory) {
this(renderer, programSpec, factory, type -> type == RenderType.getCutoutMipped());
}
public RenderMaterial(InstancedTileRenderer<P> renderer, ProgramSpec programSpec, ModelFactory<MODEL> factory, Predicate<RenderType> layerPredicate) {
this.renderer = renderer; this.renderer = renderer;
this.spec = spec;
this.models = CacheBuilder.newBuilder() this.models = CacheBuilder.newBuilder()
.removalListener(notification -> ((InstancedModel<?>) notification.getValue()).delete()) .removalListener(notification -> ((InstancedModel<?>) notification.getValue()).delete())
.build(); .build();
this.factory = factory;
this.programSpec = programSpec;
this.layerPredicate = layerPredicate;
}
public boolean canRenderInLayer(RenderType layer) {
return layerPredicate.test(layer);
} }
public void render(RenderType layer, Matrix4f projection, double camX, double camY, double camZ) { public void render(RenderType layer, Matrix4f projection, double camX, double camY, double camZ) {
@ -66,9 +50,9 @@ 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) {
if (!canRenderInLayer(layer)) return; if (!(layer == RenderType.getCutoutMipped())) return;
P program = renderer.context.getProgram(programSpec); P program = renderer.context.getProgram(this.spec.getProgramSpec());
program.bind(); program.bind();
program.uploadViewProjection(viewProjection); program.uploadViewProjection(viewProjection);
program.uploadCameraPos(camX, camY, camZ); program.uploadCameraPos(camX, camY, camZ);
@ -87,30 +71,30 @@ public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel
runOnAll(InstancedModel::render); runOnAll(InstancedModel::render);
} }
public void runOnAll(Consumer<MODEL> f) { public void runOnAll(Consumer<InstancedModel<D>> f) {
for (MODEL model : models.asMap().values()) { for (InstancedModel<D> model : models.asMap().values()) {
f.accept(model); f.accept(model);
} }
} }
public MODEL getModel(PartialModel partial, BlockState referenceState) { public InstancedModel<D> getModel(PartialModel partial, BlockState referenceState) {
return get(partial, () -> buildModel(partial.get(), referenceState)); return get(partial, () -> buildModel(partial.get(), referenceState));
} }
public MODEL getModel(PartialModel partial, BlockState referenceState, Direction dir) { public InstancedModel<D> getModel(PartialModel partial, BlockState referenceState, Direction dir) {
return getModel(partial, referenceState, dir, RenderUtil.rotateToFace(dir)); return getModel(partial, referenceState, dir, RenderUtil.rotateToFace(dir));
} }
public MODEL getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier<MatrixStack> modelTransform) { public InstancedModel<D> getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier<MatrixStack> modelTransform) {
return get(Pair.of(dir, partial), return get(Pair.of(dir, partial),
() -> buildModel(partial.get(), referenceState, modelTransform.get())); () -> buildModel(partial.get(), referenceState, modelTransform.get()));
} }
public MODEL getModel(BlockState toRender) { public InstancedModel<D> getModel(BlockState toRender) {
return get(toRender, () -> buildModel(toRender)); return get(toRender, () -> buildModel(toRender));
} }
public MODEL get(Object key, Supplier<MODEL> supplier) { public InstancedModel<D> get(Object key, Supplier<InstancedModel<D>> supplier) {
try { try {
return models.get(key, supplier::get); return models.get(key, supplier::get);
} catch (ExecutionException e) { } catch (ExecutionException e) {
@ -119,19 +103,19 @@ public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel
} }
} }
private MODEL buildModel(BlockState renderedState) { private InstancedModel<D> buildModel(BlockState renderedState) {
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher(); BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
return buildModel(dispatcher.getModelForState(renderedState), renderedState); return buildModel(dispatcher.getModelForState(renderedState), renderedState);
} }
private MODEL buildModel(IBakedModel model, BlockState renderedState) { private InstancedModel<D> buildModel(IBakedModel model, BlockState renderedState) {
return buildModel(model, renderedState, new MatrixStack()); return buildModel(model, renderedState, new MatrixStack());
} }
private MODEL buildModel(IBakedModel model, BlockState referenceState, MatrixStack ms) { private InstancedModel<D> buildModel(IBakedModel model, BlockState referenceState, MatrixStack ms) {
BufferBuilder builder = getBufferBuilder(model, referenceState, ms); BufferBuilder builder = getBufferBuilder(model, referenceState, ms);
return factory.makeModel(renderer, builder); return new InstancedModel<>(renderer, spec.getInstanceFormat(), spec.getInstanceFactory(), builder);
} }
private static final Direction[] dirs; private static final Direction[] dirs;

View file

@ -117,11 +117,11 @@ public abstract class TileEntityInstance<T extends TileEntity> implements IInsta
models.forEach(model -> model.setBlockLight(block).setSkyLight(sky)); models.forEach(model -> model.setBlockLight(block).setSkyLight(sky));
} }
protected RenderMaterial<?, InstancedModel<ModelData>> getTransformMaterial() { protected RenderMaterial<?, ModelData> getTransformMaterial() {
return renderer.getTransformMaterial(); return renderer.getTransformMaterial();
} }
protected RenderMaterial<?, InstancedModel<OrientedData>> getOrientedMaterial() { protected RenderMaterial<?, OrientedData> getOrientedMaterial() {
return renderer.getOrientedMaterial(); return renderer.getOrientedMaterial();
} }
} }

View file

@ -1,6 +1,5 @@
package com.simibubi.create.content.contraptions.base; package com.simibubi.create.content.contraptions.base;
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.jozufozu.flywheel.backend.instancing.TileEntityInstance; import com.jozufozu.flywheel.backend.instancing.TileEntityInstance;
@ -85,7 +84,7 @@ public abstract class KineticTileInstance<T extends KineticTileEntity> extends T
return shaft(getRotationAxis()); return shaft(getRotationAxis());
} }
protected final RenderMaterial<?, InstancedModel<RotatingData>> getRotatingMaterial() { protected final RenderMaterial<?, RotatingData> getRotatingMaterial() {
return renderer.getMaterial(AllMaterialSpecs.ROTATING); return renderer.getMaterial(AllMaterialSpecs.ROTATING);
} }

View file

@ -11,7 +11,7 @@ public class RotatingData extends KineticData {
private byte rotationAxisY; private byte rotationAxisY;
private byte rotationAxisZ; private byte rotationAxisZ;
protected RotatingData(InstancedModel<?> owner) { public RotatingData(InstancedModel<?> owner) {
super(owner); super(owner);
} }

View file

@ -1,31 +0,0 @@
package com.simibubi.create.content.contraptions.base;
import com.jozufozu.flywheel.backend.core.materials.BasicAttributes;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer;
import net.minecraft.client.renderer.BufferBuilder;
public class RotatingModel extends InstancedModel<RotatingData> {
public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class)
.addAttributes(RotatingAttributes.class)
.build();
public RotatingModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(renderer, buf);
}
@Override
protected RotatingData newInstance() {
return new RotatingData(this);
}
@Override
protected VertexFormat getInstanceFormat() {
return FORMAT;
}
}

View file

@ -28,7 +28,7 @@ public class ActorData extends InstanceData {
private float speed; private float speed;
protected ActorData(InstancedModel<?> owner) { public ActorData(InstancedModel<?> owner) {
super(owner); super(owner);
} }

View file

@ -1,27 +0,0 @@
package com.simibubi.create.content.contraptions.components.actors;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer;
import net.minecraft.client.renderer.BufferBuilder;
public class ActorModel extends InstancedModel<ActorData> {
public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(ActorVertexAttributes.class)
.build();
public ActorModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(renderer, buf);
}
@Override
protected VertexFormat getInstanceFormat() {
return FORMAT;
}
@Override
protected ActorData newInstance() {
return new ActorData(this);
}
}

View file

@ -1,6 +1,5 @@
package com.simibubi.create.content.contraptions.components.actors; package com.simibubi.create.content.contraptions.components.actors;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.jozufozu.flywheel.backend.instancing.RenderMaterial; import com.jozufozu.flywheel.backend.instancing.RenderMaterial;
import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
@ -21,7 +20,7 @@ public class DrillActorInstance extends ActorInstance {
public DrillActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { public DrillActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
super(modelManager, context); super(modelManager, context);
RenderMaterial<?, InstancedModel<ActorData>> renderMaterial = modelManager.getActorMaterial(); RenderMaterial<?, ActorData> renderMaterial = modelManager.getActorMaterial();
BlockState state = context.state; BlockState state = context.state;

View file

@ -3,7 +3,6 @@ package com.simibubi.create.content.contraptions.components.actors;
import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING; import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING;
import com.jozufozu.flywheel.backend.core.materials.ModelData; import com.jozufozu.flywheel.backend.core.materials.ModelData;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.jozufozu.flywheel.backend.instancing.RenderMaterial; import com.jozufozu.flywheel.backend.instancing.RenderMaterial;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlockPartials;
@ -36,7 +35,7 @@ public class HarvesterActorInstance extends ActorInstance {
public HarvesterActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { public HarvesterActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
super(modelManager, context); super(modelManager, context);
RenderMaterial<?, InstancedModel<ModelData>> renderMaterial = modelManager.getTransformMaterial(); RenderMaterial<?, ModelData> renderMaterial = modelManager.getTransformMaterial();
BlockState state = context.state; BlockState state = context.state;

View file

@ -5,7 +5,6 @@ import static com.simibubi.create.content.contraptions.base.DirectionalKineticBl
import com.jozufozu.flywheel.backend.core.PartialModel; import com.jozufozu.flywheel.backend.core.PartialModel;
import com.jozufozu.flywheel.backend.core.materials.ModelData; import com.jozufozu.flywheel.backend.core.materials.ModelData;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.jozufozu.flywheel.backend.instancing.RenderMaterial; import com.jozufozu.flywheel.backend.instancing.RenderMaterial;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlockPartials;
@ -45,7 +44,7 @@ public class DeployerActorInstance extends ActorInstance {
public DeployerActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) { public DeployerActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
super(modelManager, context); super(modelManager, context);
RenderMaterial<ContraptionProgram, InstancedModel<ModelData>> mat = modelManager.getTransformMaterial(); RenderMaterial<ContraptionProgram, ModelData> mat = modelManager.getTransformMaterial();
BlockState state = context.state; BlockState state = context.state;
DeployerTileEntity.Mode mode = NBTHelper.readEnum(context.tileData, "Mode", DeployerTileEntity.Mode.class); DeployerTileEntity.Mode mode = NBTHelper.readEnum(context.tileData, "Mode", DeployerTileEntity.Mode.class);

View file

@ -63,7 +63,7 @@ public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> im
connectorAngleMult = flipAngle ? -1 : 1; connectorAngleMult = flipAngle ? -1 : 1;
RenderMaterial<?, InstancedModel<ModelData>> mat = getTransformMaterial(); RenderMaterial<?, ModelData> mat = getTransformMaterial();
upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, blockState).createInstance(); upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, blockState).createInstance();
lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, blockState).createInstance(); lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, blockState).createInstance();

View file

@ -7,7 +7,6 @@ import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
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;
@ -65,7 +64,7 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer<Contraptio
return null; return null;
} }
public RenderMaterial<?, InstancedModel<ActorData>> getActorMaterial() { public RenderMaterial<?, ActorData> getActorMaterial() {
return getMaterial(AllMaterialSpecs.ACTORS); return getMaterial(AllMaterialSpecs.ACTORS);
} }

View file

@ -21,7 +21,7 @@ public class ContraptionModel extends BufferedModel {
protected GlBuffer ebo; protected GlBuffer ebo;
public ContraptionModel(BufferBuilder buf) { public ContraptionModel(BufferBuilder buf) {
super(buf); super(FORMAT, buf);
} }
@Override @Override
@ -93,11 +93,6 @@ public class ContraptionModel extends BufferedModel {
to.put(sky); to.put(sky);
} }
@Override
protected VertexFormat getModelFormat() {
return FORMAT;
}
@Override @Override
protected void deleteInternal() { protected void deleteInternal() {
super.deleteInternal(); super.deleteInternal();

View file

@ -21,7 +21,7 @@ public class BeltData extends KineticData {
private float maxV; private float maxV;
private byte scrollMult; private byte scrollMult;
protected BeltData(InstancedModel<?> owner) { public BeltData(InstancedModel<?> owner) {
super(owner); super(owner);
} }

View file

@ -1,32 +0,0 @@
package com.simibubi.create.content.contraptions.relays.belt;
import com.jozufozu.flywheel.backend.core.materials.BasicAttributes;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.content.contraptions.base.KineticAttributes;
import net.minecraft.client.renderer.BufferBuilder;
public class BeltInstancedModel extends InstancedModel<BeltData> {
public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class)
.addAttributes(BeltAttributes.class)
.build();
public BeltInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(renderer, buf);
}
@Override
protected BeltData newInstance() {
return new BeltData(this);
}
@Override
protected VertexFormat getInstanceFormat() {
return FORMAT;
}
}

View file

@ -26,7 +26,7 @@ public class SplitShaftInstance extends KineticTileInstance<SplitShaftTileEntity
float speed = tile.getSpeed(); float speed = tile.getSpeed();
RenderMaterial<?, InstancedModel<RotatingData>> rotatingMaterial = getRotatingMaterial(); RenderMaterial<?, RotatingData> rotatingMaterial = getRotatingMaterial();
for (Direction dir : Iterate.directionsInAxis(getRotationAxis())) { for (Direction dir : Iterate.directionsInAxis(getRotationAxis())) {

View file

@ -33,7 +33,7 @@ public class GearboxInstance extends KineticTileInstance<GearboxTileEntity> {
int skyLight = world.getLightLevel(LightType.SKY, pos); int skyLight = world.getLightLevel(LightType.SKY, pos);
updateSourceFacing(); updateSourceFacing();
RenderMaterial<?, InstancedModel<RotatingData>> rotatingMaterial = getRotatingMaterial(); RenderMaterial<?, RotatingData> rotatingMaterial = getRotatingMaterial();
for (Direction direction : Iterate.directions) { for (Direction direction : Iterate.directions) {
final Direction.Axis axis = direction.getAxis(); final Direction.Axis axis = direction.getAxis();

View file

@ -1,27 +0,0 @@
package com.simibubi.create.content.logistics.block;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer;
import net.minecraft.client.renderer.BufferBuilder;
public class FlapModel extends InstancedModel<FlapData> {
public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(FlapAttributes.class)
.build();
public FlapModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(renderer, buf);
}
@Override
protected FlapData newInstance() {
return new FlapData(this);
}
@Override
protected VertexFormat getInstanceFormat() {
return FORMAT;
}
}

View file

@ -47,7 +47,7 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta
public ArmInstance(InstancedTileRenderer<?> modelManager, ArmTileEntity tile) { public ArmInstance(InstancedTileRenderer<?> modelManager, ArmTileEntity tile) {
super(modelManager, tile); super(modelManager, tile);
RenderMaterial<?, InstancedModel<ModelData>> mat = getTransformMaterial(); RenderMaterial<?, ModelData> mat = getTransformMaterial();
base = mat.getModel(AllBlockPartials.ARM_BASE, blockState).createInstance(); base = mat.getModel(AllBlockPartials.ARM_BASE, blockState).createInstance();
lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, blockState).createInstance(); lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, blockState).createInstance();

View file

@ -2,7 +2,6 @@ package com.simibubi.create.content.logistics.block.redstone;
import com.jozufozu.flywheel.backend.core.materials.ModelData; import com.jozufozu.flywheel.backend.core.materials.ModelData;
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance; import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
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.jozufozu.flywheel.backend.instancing.TileEntityInstance; import com.jozufozu.flywheel.backend.instancing.TileEntityInstance;
@ -27,7 +26,7 @@ public class AnalogLeverInstance extends TileEntityInstance<AnalogLeverTileEntit
public AnalogLeverInstance(InstancedTileRenderer<?> modelManager, AnalogLeverTileEntity tile) { public AnalogLeverInstance(InstancedTileRenderer<?> modelManager, AnalogLeverTileEntity tile) {
super(modelManager, tile); super(modelManager, tile);
RenderMaterial<?, InstancedModel<ModelData>> mat = getTransformMaterial(); RenderMaterial<?, ModelData> mat = getTransformMaterial();
handle = mat.getModel(AllBlockPartials.ANALOG_LEVER_HANDLE, blockState).createInstance(); handle = mat.getModel(AllBlockPartials.ANALOG_LEVER_HANDLE, blockState).createInstance();
indicator = mat.getModel(AllBlockPartials.ANALOG_LEVER_INDICATOR, blockState).createInstance(); indicator = mat.getModel(AllBlockPartials.ANALOG_LEVER_INDICATOR, blockState).createInstance();

View file

@ -2,7 +2,6 @@ package com.simibubi.create.content.schematics.block;
import com.jozufozu.flywheel.backend.core.materials.ModelData; import com.jozufozu.flywheel.backend.core.materials.ModelData;
import com.jozufozu.flywheel.backend.instancing.IDynamicInstance; import com.jozufozu.flywheel.backend.instancing.IDynamicInstance;
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.jozufozu.flywheel.backend.instancing.TileEntityInstance; import com.jozufozu.flywheel.backend.instancing.TileEntityInstance;
@ -21,7 +20,7 @@ public class SchematicannonInstance extends TileEntityInstance<SchematicannonTil
public SchematicannonInstance(InstancedTileRenderer<?> modelManager, SchematicannonTileEntity tile) { public SchematicannonInstance(InstancedTileRenderer<?> modelManager, SchematicannonTileEntity tile) {
super(modelManager, tile); super(modelManager, tile);
RenderMaterial<?, InstancedModel<ModelData>> mat = getTransformMaterial(); RenderMaterial<?, ModelData> mat = getTransformMaterial();
connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, blockState).createInstance(); connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, blockState).createInstance();
pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, blockState).createInstance(); pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, blockState).createInstance();

View file

@ -0,0 +1,39 @@
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.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)
.build();
public static final VertexFormat ORIENTED = VertexFormat.builder()
.addAttributes(BasicAttributes.class)
.addAttributes(OrientedAttributes.class)
.build();
public static VertexFormat ROTATING = VertexFormat.builder()
.addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class)
.addAttributes(RotatingAttributes.class)
.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)
.build();
public static VertexFormat FLAP = VertexFormat.builder()
.addAttributes(FlapAttributes.class)
.build();
}

View file

@ -4,19 +4,12 @@ import static com.jozufozu.flywheel.backend.Backend.register;
import com.jozufozu.flywheel.backend.core.materials.ModelData; import com.jozufozu.flywheel.backend.core.materials.ModelData;
import com.jozufozu.flywheel.backend.core.materials.OrientedData; import com.jozufozu.flywheel.backend.core.materials.OrientedData;
import com.jozufozu.flywheel.backend.core.materials.OrientedModel;
import com.jozufozu.flywheel.backend.core.materials.TransformedModel;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.jozufozu.flywheel.backend.instancing.MaterialSpec; import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.RotatingData;
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.relays.belt.BeltData; import com.simibubi.create.content.contraptions.relays.belt.BeltData;
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
import com.simibubi.create.content.logistics.block.FlapData; import com.simibubi.create.content.logistics.block.FlapData;
import com.simibubi.create.content.logistics.block.FlapModel;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
@ -25,14 +18,13 @@ public class AllMaterialSpecs {
// noop, make sure the static field are loaded. // noop, make sure the static field are loaded.
} }
public static final MaterialSpec<ModelData> TRANSFORMED = register(new MaterialSpec<>(Locations.MODEL, AllProgramSpecs.MODEL, AllInstanceFormats.MODEL, ModelData::new));
public static final MaterialSpec<OrientedData> ORIENTED = register(new MaterialSpec<>(Locations.ORIENTED, AllProgramSpecs.ORIENTED, AllInstanceFormats.ORIENTED, OrientedData::new));
public static final MaterialSpec<InstancedModel<ModelData>> TRANSFORMED = register(new MaterialSpec<>(Locations.MODEL, AllProgramSpecs.MODEL, TransformedModel::new)); public static final MaterialSpec<RotatingData> ROTATING = register(new MaterialSpec<>(Locations.ROTATING, AllProgramSpecs.ROTATING, AllInstanceFormats.ROTATING, RotatingData::new));
public static final MaterialSpec<InstancedModel<OrientedData>> ORIENTED = register(new MaterialSpec<>(Locations.ORIENTED, AllProgramSpecs.ORIENTED, OrientedModel::new)); public static final MaterialSpec<BeltData> BELTS = register(new MaterialSpec<>(Locations.BELTS, AllProgramSpecs.BELT, AllInstanceFormats.BELT, BeltData::new));
public static final MaterialSpec<ActorData> ACTORS = register(new MaterialSpec<>(Locations.ACTORS, AllProgramSpecs.ACTOR, AllInstanceFormats.ACTOR, ActorData::new));
public static final MaterialSpec<InstancedModel<RotatingData>> ROTATING = register(new MaterialSpec<>(Locations.ROTATING, AllProgramSpecs.ROTATING, RotatingModel::new)); public static final MaterialSpec<FlapData> FLAPS = register(new MaterialSpec<>(Locations.FLAPS, AllProgramSpecs.FLAPS, AllInstanceFormats.FLAP, FlapData::new));
public static final MaterialSpec<InstancedModel<BeltData>> BELTS = register(new MaterialSpec<>(Locations.BELTS, AllProgramSpecs.BELT, BeltInstancedModel::new));
public static final MaterialSpec<InstancedModel<ActorData>> ACTORS = register(new MaterialSpec<>(Locations.ACTORS, AllProgramSpecs.ACTOR, ActorModel::new));
public static final MaterialSpec<InstancedModel<FlapData>> FLAPS = register(new MaterialSpec<>(Locations.FLAPS, AllProgramSpecs.FLAPS, FlapModel::new));
public static class Locations { public static class Locations {
public static final ResourceLocation MODEL = new ResourceLocation("create", "model"); public static final ResourceLocation MODEL = new ResourceLocation("create", "model");

View file

@ -13,7 +13,6 @@ import com.jozufozu.flywheel.backend.gl.GlPrimitiveType;
import com.jozufozu.flywheel.backend.gl.GlVertexArray; import com.jozufozu.flywheel.backend.gl.GlVertexArray;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
import com.jozufozu.flywheel.util.RenderUtil; import com.jozufozu.flywheel.util.RenderUtil;
import com.simibubi.create.foundation.render.AllProgramSpecs; import com.simibubi.create.foundation.render.AllProgramSpecs;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -67,9 +66,9 @@ public class EffectsHandler {
private static final int bufferSize = vertices.length * 4; private static final int bufferSize = vertices.length * 4;
private final Framebuffer framebuffer; private final Framebuffer framebuffer;
private final GlVertexArray vao = new GlVertexArray(); private final GlVertexArray vao;
private final GlBuffer vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER); private final GlBuffer vbo;
private final ArrayList<FilterSphere> spheres; private final ArrayList<FilterSphere> spheres;
@ -79,12 +78,14 @@ public class EffectsHandler {
Framebuffer render = Minecraft.getInstance().getFramebuffer(); Framebuffer render = Minecraft.getInstance().getFramebuffer();
framebuffer = new Framebuffer(render.framebufferWidth, render.framebufferHeight, false, Minecraft.IS_RUNNING_ON_MAC); framebuffer = new Framebuffer(render.framebufferWidth, render.framebufferHeight, false, Minecraft.IS_RUNNING_ON_MAC);
vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER);
vbo.bind(); vbo.bind();
vbo.alloc(bufferSize); vbo.alloc(bufferSize);
MappedBuffer buffer = vbo.getBuffer(0, bufferSize); vbo.getBuffer(0, bufferSize)
buffer.putFloatArray(vertices); .putFloatArray(vertices)
buffer.flush(); .flush();
vao = new GlVertexArray();
vao.bind(); vao.bind();
GL20.glEnableVertexAttribArray(0); GL20.glEnableVertexAttribArray(0);

View file

@ -81,8 +81,8 @@ public class SphereFilterProgram extends GlProgram {
public void uploadFilters(ArrayList<FilterSphere> filters) { public void uploadFilters(ArrayList<FilterSphere> filters) {
effectsUBO.bind(GlBufferType.ARRAY_BUFFER); effectsUBO.bind(GlBufferType.ARRAY_BUFFER);
MappedBuffer buffer = effectsUBO.getBuffer(0, BUFFER_SIZE); MappedBuffer buffer = effectsUBO.getBuffer(0, BUFFER_SIZE)
buffer.putInt(filters.size()) .putInt(filters.size())
.position(16); .position(16);
filters.forEach(it -> it.write(buffer)); filters.forEach(it -> it.write(buffer));