mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-29 08:26:37 +01:00
Instanced entities stage 1
This commit is contained in:
parent
285b8f98cf
commit
9cc03a81d7
12 changed files with 237 additions and 82 deletions
|
@ -1,12 +1,18 @@
|
||||||
package com.jozufozu.flywheel.backend;
|
package com.jozufozu.flywheel.backend;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
public interface IShaderContext<P extends GlProgram> {
|
public interface IShaderContext<P extends GlProgram> {
|
||||||
|
|
||||||
P getProgram(ResourceLocation loc);
|
default P getProgram(ResourceLocation loc) {
|
||||||
|
return this.getProgramSupplier(loc).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Supplier<P> getProgramSupplier(ResourceLocation loc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load all programs associated with this context. This might be just one, if the context is very specialized.
|
* Load all programs associated with this context. This might be just one, if the context is very specialized.
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@ -30,8 +31,8 @@ public abstract class ShaderContext<P extends GlProgram> implements IShaderConte
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public P getProgram(ResourceLocation spec) {
|
public Supplier<P> getProgramSupplier(ResourceLocation spec) {
|
||||||
return programs.get(spec).get();
|
return programs.get(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Program loadAndLink(ProgramSpec spec, @Nullable ProgramState state) {
|
public Program loadAndLink(ProgramSpec spec, @Nullable ProgramState state) {
|
||||||
|
|
|
@ -4,20 +4,15 @@ import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL15;
|
import org.lwjgl.opengl.GL15;
|
||||||
|
|
||||||
public abstract class MappedBuffer implements AutoCloseable {
|
public abstract class MappedBuffer extends VecBuffer implements AutoCloseable {
|
||||||
|
|
||||||
protected boolean mapped;
|
protected boolean mapped;
|
||||||
protected final GlBuffer owner;
|
protected final GlBuffer owner;
|
||||||
protected ByteBuffer internal;
|
|
||||||
|
|
||||||
public MappedBuffer(GlBuffer owner) {
|
public MappedBuffer(GlBuffer owner) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInternal(ByteBuffer internal) {
|
|
||||||
this.internal = internal;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void checkAndMap();
|
protected abstract void checkAndMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,20 +33,13 @@ public abstract class MappedBuffer implements AutoCloseable {
|
||||||
|
|
||||||
public MappedBuffer putFloatArray(float[] floats) {
|
public MappedBuffer putFloatArray(float[] floats) {
|
||||||
checkAndMap();
|
checkAndMap();
|
||||||
|
super.putFloatArray(floats);
|
||||||
for (float f : floats) {
|
|
||||||
internal.putFloat(f);
|
|
||||||
}
|
|
||||||
// internal.asFloatBuffer().put(floats);
|
|
||||||
// internal.position(internal.position() + floats.length * 4);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappedBuffer putByteArray(byte[] bytes) {
|
public MappedBuffer putByteArray(byte[] bytes) {
|
||||||
checkAndMap();
|
checkAndMap();
|
||||||
internal.put(bytes);
|
super.putByteArray(bytes);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,75 +50,61 @@ public abstract class MappedBuffer implements AutoCloseable {
|
||||||
*/
|
*/
|
||||||
public MappedBuffer position(int p) {
|
public MappedBuffer position(int p) {
|
||||||
checkAndMap();
|
checkAndMap();
|
||||||
internal.position(p);
|
super.position(p);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappedBuffer putFloat(float f) {
|
public MappedBuffer putFloat(float f) {
|
||||||
checkAndMap();
|
checkAndMap();
|
||||||
internal.putFloat(f);
|
super.putFloat(f);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappedBuffer putInt(int i) {
|
public MappedBuffer putInt(int i) {
|
||||||
checkAndMap();
|
checkAndMap();
|
||||||
internal.putInt(i);
|
super.putInt(i);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappedBuffer put(byte b) {
|
public MappedBuffer put(byte b) {
|
||||||
checkAndMap();
|
checkAndMap();
|
||||||
internal.put(b);
|
super.put(b);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappedBuffer put(ByteBuffer b) {
|
public MappedBuffer put(ByteBuffer b) {
|
||||||
checkAndMap();
|
checkAndMap();
|
||||||
internal.put(b);
|
super.put(b);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappedBuffer putVec4(float x, float y, float z, float w) {
|
public MappedBuffer putVec4(float x, float y, float z, float w) {
|
||||||
checkAndMap();
|
checkAndMap();
|
||||||
internal.putFloat(x);
|
super.putVec4(x, y, z, w);
|
||||||
internal.putFloat(y);
|
|
||||||
internal.putFloat(z);
|
|
||||||
internal.putFloat(w);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappedBuffer putVec3(float x, float y, float z) {
|
public MappedBuffer putVec3(float x, float y, float z) {
|
||||||
checkAndMap();
|
checkAndMap();
|
||||||
internal.putFloat(x);
|
super.putVec3(x, y, z);
|
||||||
internal.putFloat(y);
|
|
||||||
internal.putFloat(z);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappedBuffer putVec2(float x, float y) {
|
public MappedBuffer putVec2(float x, float y) {
|
||||||
checkAndMap();
|
checkAndMap();
|
||||||
internal.putFloat(x);
|
super.putVec2(x, y);
|
||||||
internal.putFloat(y);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappedBuffer putVec3(byte x, byte y, byte z) {
|
public MappedBuffer putVec3(byte x, byte y, byte z) {
|
||||||
checkAndMap();
|
checkAndMap();
|
||||||
internal.put(x);
|
super.putVec3(x, y, z);
|
||||||
internal.put(y);
|
|
||||||
internal.put(z);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappedBuffer putVec2(byte x, byte y) {
|
public MappedBuffer putVec2(byte x, byte y) {
|
||||||
checkAndMap();
|
checkAndMap();
|
||||||
internal.put(x);
|
super.putVec2(x, y);
|
||||||
internal.put(y);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
package com.jozufozu.flywheel.backend.gl.buffer;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
public class VecBuffer {
|
||||||
|
|
||||||
|
protected ByteBuffer internal;
|
||||||
|
|
||||||
|
public VecBuffer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer(ByteBuffer internal) {
|
||||||
|
this.internal = internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VecBuffer allocate(int bytes) {
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(bytes);
|
||||||
|
buffer.order(ByteOrder.nativeOrder());
|
||||||
|
return new VecBuffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setInternal(ByteBuffer internal) {
|
||||||
|
this.internal = internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer unwrap() {
|
||||||
|
return internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer rewind() {
|
||||||
|
internal.rewind();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer putFloatArray(float[] floats) {
|
||||||
|
|
||||||
|
for (float f : floats) {
|
||||||
|
internal.putFloat(f);
|
||||||
|
}
|
||||||
|
// internal.asFloatBuffer().put(floats);
|
||||||
|
// internal.position(internal.position() + floats.length * 4);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer putByteArray(byte[] bytes) {
|
||||||
|
internal.put(bytes);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Position this buffer relative to the 0-index in GPU memory.
|
||||||
|
*
|
||||||
|
* @return This buffer.
|
||||||
|
*/
|
||||||
|
public VecBuffer position(int p) {
|
||||||
|
internal.position(p);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer putFloat(float f) {
|
||||||
|
internal.putFloat(f);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer putInt(int i) {
|
||||||
|
internal.putInt(i);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer put(byte b) {
|
||||||
|
internal.put(b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer put(ByteBuffer b) {
|
||||||
|
internal.put(b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer putVec4(float x, float y, float z, float w) {
|
||||||
|
internal.putFloat(x);
|
||||||
|
internal.putFloat(y);
|
||||||
|
internal.putFloat(z);
|
||||||
|
internal.putFloat(w);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer putVec3(float x, float y, float z) {
|
||||||
|
internal.putFloat(x);
|
||||||
|
internal.putFloat(y);
|
||||||
|
internal.putFloat(z);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer putVec2(float x, float y) {
|
||||||
|
internal.putFloat(x);
|
||||||
|
internal.putFloat(y);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer putVec3(byte x, byte y, byte z) {
|
||||||
|
internal.put(x);
|
||||||
|
internal.put(y);
|
||||||
|
internal.put(z);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VecBuffer putVec2(byte x, byte y) {
|
||||||
|
internal.put(x);
|
||||||
|
internal.put(y);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,6 +54,10 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
modelFormat = this.spec.getModelFormat();
|
modelFormat = this.spec.getModelFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean nothingToRender() {
|
||||||
|
return models.size() > 0 && models.asMap().values().stream().allMatch(Instancer::empty);
|
||||||
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
models.invalidateAll();
|
models.invalidateAll();
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,10 @@ public class Instancer<D extends InstanceData> {
|
||||||
return instanceData;
|
return instanceData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean empty() {
|
||||||
|
return !anyToUpdate && !anyToRemove && glInstanceCount == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all instance data without freeing resources.
|
* Clear all instance data without freeing resources.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -13,6 +13,7 @@ import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
import com.jozufozu.flywheel.util.WeakHashSet;
|
import com.jozufozu.flywheel.util.WeakHashSet;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
@ -25,25 +26,28 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
|
|
||||||
public static int MAX_ORIGIN_DISTANCE = 100;
|
public static int MAX_ORIGIN_DISTANCE = 100;
|
||||||
|
|
||||||
protected final ArrayList<MaterialRenderer<P>> renderers;
|
protected final WorldContext<P> context;
|
||||||
protected final Map<ResourceLocation, InstanceMaterial<?>> materials;
|
|
||||||
|
protected final Map<MaterialSpec<?>, InstanceMaterial<?>> atlasMaterials;
|
||||||
|
protected final ArrayList<MaterialRenderer<P>> atlasRenderers;
|
||||||
|
|
||||||
|
protected final Map<ResourceLocation, ArrayList<MaterialRenderer<P>>> renderers;
|
||||||
|
protected final Map<ResourceLocation, Map<MaterialSpec<?>, InstanceMaterial<?>>> materials;
|
||||||
|
|
||||||
private BlockPos originCoordinate = BlockPos.ZERO;
|
private BlockPos originCoordinate = BlockPos.ZERO;
|
||||||
|
|
||||||
private final WeakHashSet<OriginShiftListener> listeners;
|
private final WeakHashSet<OriginShiftListener> listeners;
|
||||||
|
|
||||||
public MaterialManager(WorldContext<P> context) {
|
public MaterialManager(WorldContext<P> context) {
|
||||||
|
this.context = context;
|
||||||
|
|
||||||
|
this.atlasMaterials = new HashMap<>();
|
||||||
|
this.atlasRenderers = new ArrayList<>(Backend.getInstance().allMaterials().size());
|
||||||
|
|
||||||
this.materials = new HashMap<>();
|
this.materials = new HashMap<>();
|
||||||
this.renderers = new ArrayList<>(Backend.getInstance().allMaterials().size());
|
this.renderers = new HashMap<>();
|
||||||
|
|
||||||
this.listeners = new WeakHashSet<>();
|
this.listeners = new WeakHashSet<>();
|
||||||
|
|
||||||
for (MaterialSpec<?> spec : Backend.getInstance().allMaterials()) {
|
|
||||||
InstanceMaterial<?> material = new InstanceMaterial<>(this::getOriginCoordinate, spec);
|
|
||||||
materials.put(spec.name, material);
|
|
||||||
MaterialRenderer<P> renderer = new MaterialRenderer<>(context.getProgram(spec.getProgramName()), material);
|
|
||||||
renderers.add(renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,20 +76,47 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
|
|
||||||
translate.multiplyBackward(viewProjection);
|
translate.multiplyBackward(viewProjection);
|
||||||
|
|
||||||
for (MaterialRenderer<P> material : renderers) {
|
for (MaterialRenderer<P> material : atlasRenderers) {
|
||||||
material.render(layer, translate, camX, camY, camZ, callback);
|
material.render(layer, translate, camX, camY, camZ, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<ResourceLocation, ArrayList<MaterialRenderer<P>>> entry : renderers.entrySet()) {
|
||||||
|
Minecraft.getInstance().textureManager.bindTexture(entry.getKey());
|
||||||
|
|
||||||
|
for (MaterialRenderer<P> materialRenderer : entry.getValue()) {
|
||||||
|
materialRenderer.render(layer, translate, camX, camY, camZ, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
for (InstanceMaterial<?> material : materials.values()) {
|
atlasMaterials.values().forEach(InstanceMaterial::delete);
|
||||||
material.delete();
|
|
||||||
}
|
materials.values().stream().flatMap(m -> m.values().stream()).forEach(InstanceMaterial::delete);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <D extends InstanceData> InstanceMaterial<D> getMaterial(MaterialSpec<D> materialType) {
|
public <D extends InstanceData> InstanceMaterial<D> getMaterial(MaterialSpec<D> materialType) {
|
||||||
return (InstanceMaterial<D>) materials.get(materialType.name);
|
return (InstanceMaterial<D>) this.atlasMaterials.computeIfAbsent(materialType, type -> {
|
||||||
|
InstanceMaterial<?> material = new InstanceMaterial<>(this::getOriginCoordinate, type);
|
||||||
|
|
||||||
|
this.atlasRenderers.add(new MaterialRenderer<>(context.getProgramSupplier(type.getProgramName()), material));
|
||||||
|
|
||||||
|
return material;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <D extends InstanceData> InstanceMaterial<D> getMaterial(MaterialSpec<D> materialType, ResourceLocation texture) {
|
||||||
|
return (InstanceMaterial<D>) materials.computeIfAbsent(texture, $ -> new HashMap<>())
|
||||||
|
.computeIfAbsent(materialType, type -> {
|
||||||
|
InstanceMaterial<?> material = new InstanceMaterial<>(this::getOriginCoordinate, type);
|
||||||
|
|
||||||
|
this.renderers.computeIfAbsent(texture, $ -> new ArrayList<>())
|
||||||
|
.add(new MaterialRenderer<>(context.getProgramSupplier(type.getProgramName()), material));
|
||||||
|
|
||||||
|
return material;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceMaterial<ModelData> getTransformMaterial() {
|
public InstanceMaterial<ModelData> getTransformMaterial() {
|
||||||
|
@ -117,7 +148,8 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
|
|
||||||
originCoordinate = new BlockPos(cX, cY, cZ);
|
originCoordinate = new BlockPos(cX, cY, cZ);
|
||||||
|
|
||||||
materials.values().forEach(InstanceMaterial::clear);
|
materials.values().stream().flatMap(m -> m.values().stream()).forEach(InstanceMaterial::clear);
|
||||||
|
atlasMaterials.values().forEach(InstanceMaterial::clear);
|
||||||
listeners.forEach(OriginShiftListener::onOriginShift);
|
listeners.forEach(OriginShiftListener::onOriginShift);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing;
|
package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
import com.jozufozu.flywheel.core.shader.IProgramCallback;
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
|
|
||||||
|
@ -8,17 +10,21 @@ import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
|
||||||
public class MaterialRenderer<P extends WorldProgram> {
|
public class MaterialRenderer<P extends WorldProgram> {
|
||||||
|
|
||||||
private final P program;
|
private final Supplier<P> program;
|
||||||
private final InstanceMaterial<?> material;
|
private final InstanceMaterial<?> material;
|
||||||
|
|
||||||
public MaterialRenderer(P program, InstanceMaterial<?> material) {
|
public MaterialRenderer(Supplier<P> programSupplier, InstanceMaterial<?> material) {
|
||||||
this.program = program;
|
this.program = programSupplier;
|
||||||
this.material = material;
|
this.material = material;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<P> setup) {
|
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<P> setup) {
|
||||||
if (!(layer == RenderType.getCutoutMipped())) return;
|
if (!(layer == RenderType.getCutoutMipped())) return;
|
||||||
|
|
||||||
|
if (material.nothingToRender()) return;
|
||||||
|
|
||||||
|
P program = this.program.get();
|
||||||
|
|
||||||
program.bind();
|
program.bind();
|
||||||
program.uploadViewProjection(viewProjection);
|
program.uploadViewProjection(viewProjection);
|
||||||
program.uploadCameraPos(camX, camY, camZ);
|
program.uploadCameraPos(camX, camY, camZ);
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||||
|
|
||||||
|
import net.minecraft.inventory.container.PlayerContainer;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
public class MaterialSpec<D extends InstanceData> {
|
public class MaterialSpec<D extends InstanceData> {
|
||||||
|
@ -12,13 +13,19 @@ public class MaterialSpec<D extends InstanceData> {
|
||||||
private final VertexFormat modelFormat;
|
private final VertexFormat modelFormat;
|
||||||
private final VertexFormat instanceFormat;
|
private final VertexFormat instanceFormat;
|
||||||
private final IInstanceFactory<D> instanceFactory;
|
private final IInstanceFactory<D> instanceFactory;
|
||||||
|
private final ResourceLocation texture;
|
||||||
|
|
||||||
public MaterialSpec(ResourceLocation name, ResourceLocation programSpec, VertexFormat modelFormat, VertexFormat instanceFormat, IInstanceFactory<D> instanceFactory) {
|
public MaterialSpec(ResourceLocation name, ResourceLocation programSpec, VertexFormat modelFormat, VertexFormat instanceFormat, IInstanceFactory<D> instanceFactory) {
|
||||||
|
this(name, programSpec, modelFormat, instanceFormat, PlayerContainer.BLOCK_ATLAS_TEXTURE, instanceFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialSpec(ResourceLocation name, ResourceLocation programSpec, VertexFormat modelFormat, VertexFormat instanceFormat, ResourceLocation texture, IInstanceFactory<D> instanceFactory) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.programSpec = programSpec;
|
this.programSpec = programSpec;
|
||||||
this.modelFormat = modelFormat;
|
this.modelFormat = modelFormat;
|
||||||
this.instanceFormat = instanceFormat;
|
this.instanceFormat = instanceFormat;
|
||||||
this.instanceFactory = instanceFactory;
|
this.instanceFactory = instanceFactory;
|
||||||
|
this.texture = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceLocation getProgramName() {
|
public ResourceLocation getProgramName() {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.jozufozu.flywheel.core.shader;
|
package com.jozufozu.flywheel.core.shader;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,7 +10,7 @@ import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
*
|
*
|
||||||
* @param <P>
|
* @param <P>
|
||||||
*/
|
*/
|
||||||
public interface IMultiProgram<P extends GlProgram> {
|
public interface IMultiProgram<P extends GlProgram> extends Supplier<P> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the shader program most suited for the current game state.
|
* Get the shader program most suited for the current game state.
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package com.simibubi.create.content.contraptions.components.structureMovement.glue;
|
package com.simibubi.create.content.contraptions.components.structureMovement.glue;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
import java.nio.ByteOrder;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.ITickableInstance;
|
import com.jozufozu.flywheel.backend.instancing.ITickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
||||||
|
@ -14,23 +12,28 @@ import com.jozufozu.flywheel.core.Materials;
|
||||||
import com.jozufozu.flywheel.core.instancing.ConditionalInstance;
|
import com.jozufozu.flywheel.core.instancing.ConditionalInstance;
|
||||||
import com.jozufozu.flywheel.core.materials.OrientedData;
|
import com.jozufozu.flywheel.core.materials.OrientedData;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
|
import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.vector.Quaternion;
|
import net.minecraft.util.math.vector.Quaternion;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
|
||||||
public class GlueInstance extends EntityInstance<SuperGlueEntity> implements ITickableInstance {
|
public class GlueInstance extends EntityInstance<SuperGlueEntity> implements ITickableInstance {
|
||||||
|
|
||||||
|
private static final ResourceLocation TEXTURE = new ResourceLocation(Create.ID, "textures/entity/super_glue/slime.png");
|
||||||
|
|
||||||
private final Quaternion rotation;
|
private final Quaternion rotation;
|
||||||
protected ConditionalInstance<OrientedData> model;
|
protected ConditionalInstance<OrientedData> model;
|
||||||
|
|
||||||
public GlueInstance(MaterialManager<?> renderer, SuperGlueEntity entity) {
|
public GlueInstance(MaterialManager<?> materialManager, SuperGlueEntity entity) {
|
||||||
super(renderer, entity);
|
super(materialManager, entity);
|
||||||
Instancer<OrientedData> instancer = renderer.getMaterial(Materials.ORIENTED)
|
|
||||||
|
Instancer<OrientedData> instancer = materialManager.getMaterial(Materials.ORIENTED, TEXTURE)
|
||||||
.get(entity.getType(), GlueInstance::supplyModel);
|
.get(entity.getType(), GlueInstance::supplyModel);
|
||||||
|
|
||||||
Direction face = entity.getFacingDirection();
|
Direction face = entity.getFacingDirection();
|
||||||
|
@ -55,6 +58,7 @@ public class GlueInstance extends EntityInstance<SuperGlueEntity> implements ITi
|
||||||
private void positionModel(OrientedData model) {
|
private void positionModel(OrientedData model) {
|
||||||
|
|
||||||
model.setPosition(getInstancePosition())
|
model.setPosition(getInstancePosition())
|
||||||
|
.setPivot(0, 0, 0)
|
||||||
.setRotation(rotation)
|
.setRotation(rotation)
|
||||||
.setSkyLight(15)
|
.setSkyLight(15)
|
||||||
.setBlockLight(15);
|
.setBlockLight(15);
|
||||||
|
@ -93,24 +97,23 @@ public class GlueInstance extends EntityInstance<SuperGlueEntity> implements ITi
|
||||||
Vector3d a4 = plane.add(start);
|
Vector3d a4 = plane.add(start);
|
||||||
Vector3d b4 = plane.add(end);
|
Vector3d b4 = plane.add(end);
|
||||||
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(Formats.UNLIT_MODEL.getStride() * 8);
|
VecBuffer buffer = VecBuffer.allocate(Formats.UNLIT_MODEL.getStride() * 8);
|
||||||
buffer.order(ByteOrder.nativeOrder());
|
|
||||||
|
|
||||||
// x, y, z,nx, ny,nz, u, v
|
// pos normal uv
|
||||||
// inside quad
|
// inside quad
|
||||||
buffer.putFloat((float) a1.x).putFloat((float) a1.y).putFloat((float) a1.z).put((byte) 0).put((byte) 127).put((byte) 0).putFloat(1f).putFloat(0f);
|
buffer.putVec3((float) a1.x, (float) a1.y, (float) a1.z).putVec3((byte) 0, (byte) 0, (byte) -127).putVec2(1f, 0f);
|
||||||
buffer.putFloat((float) a2.x).putFloat((float) a2.y).putFloat((float) a2.z).put((byte) 0).put((byte) 127).put((byte) 0).putFloat(1f).putFloat(1f);
|
buffer.putVec3((float) a2.x, (float) a2.y, (float) a2.z).putVec3((byte) 0, (byte) 0, (byte) -127).putVec2(1f, 1f);
|
||||||
buffer.putFloat((float) a3.x).putFloat((float) a3.y).putFloat((float) a3.z).put((byte) 0).put((byte) 127).put((byte) 0).putFloat(0f).putFloat(1f);
|
buffer.putVec3((float) a3.x, (float) a3.y, (float) a3.z).putVec3((byte) 0, (byte) 0, (byte) -127).putVec2(0f, 1f);
|
||||||
buffer.putFloat((float) a4.x).putFloat((float) a4.y).putFloat((float) a4.z).put((byte) 0).put((byte) 127).put((byte) 0).putFloat(0f).putFloat(0f);
|
buffer.putVec3((float) a4.x, (float) a4.y, (float) a4.z).putVec3((byte) 0, (byte) 0, (byte) -127).putVec2(0f, 0f);
|
||||||
// outside quad
|
// outside quad
|
||||||
buffer.putFloat((float) b4.x).putFloat((float) b4.y).putFloat((float) b4.z).put((byte) 0).put((byte) -127).put((byte) 0).putFloat(0f).putFloat(0f);
|
buffer.putVec3((float) b4.x, (float) b4.y, (float) b4.z).putVec3((byte) 0, (byte) 0, (byte) 127).putVec2(0f, 0f);
|
||||||
buffer.putFloat((float) b3.x).putFloat((float) b3.y).putFloat((float) b3.z).put((byte) 0).put((byte) -127).put((byte) 0).putFloat(0f).putFloat(1f);
|
buffer.putVec3((float) b3.x, (float) b3.y, (float) b3.z).putVec3((byte) 0, (byte) 0, (byte) 127).putVec2(0f, 1f);
|
||||||
buffer.putFloat((float) b2.x).putFloat((float) b2.y).putFloat((float) b2.z).put((byte) 0).put((byte) -127).put((byte) 0).putFloat(1f).putFloat(1f);
|
buffer.putVec3((float) b2.x, (float) b2.y, (float) b2.z).putVec3((byte) 0, (byte) 0, (byte) 127).putVec2(1f, 1f);
|
||||||
buffer.putFloat((float) b1.x).putFloat((float) b1.y).putFloat((float) b1.z).put((byte) 0).put((byte) -127).put((byte) 0).putFloat(1f).putFloat(0f);
|
buffer.putVec3((float) b1.x, (float) b1.y, (float) b1.z).putVec3((byte) 0, (byte) 0, (byte) 127).putVec2(1f, 0f);
|
||||||
|
|
||||||
buffer.rewind();
|
buffer.rewind();
|
||||||
|
|
||||||
|
|
||||||
return IndexedModel.fromSequentialQuads(Formats.UNLIT_MODEL, buffer, 8);
|
return IndexedModel.fromSequentialQuads(Formats.UNLIT_MODEL, buffer.unwrap(), 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ public class ContraptionMaterialManager extends MaterialManager<ContraptionProgr
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<ContraptionProgram> callback) {
|
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, IProgramCallback<ContraptionProgram> callback) {
|
||||||
for (MaterialRenderer<ContraptionProgram> material : renderers) {
|
for (MaterialRenderer<ContraptionProgram> material : atlasRenderers) {
|
||||||
material.render(layer, viewProjection, camX, camY, camZ, callback);
|
material.render(layer, viewProjection, camX, camY, camZ, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue