diff --git a/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java index ba05ba4e1..9073923dc 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java @@ -20,7 +20,7 @@ public class RenderInLayerMixin { * layer-correct custom rendering. RenderWorldLast is not refined enough for rendering world objects. * This should probably be a forge event. */ - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/IProfiler;endSection()V", ordinal = 1), method = "renderLayer") + @Inject(at = @At(value = "TAIL"), method = "renderLayer") private void renderLayer(RenderType type, MatrixStack stack, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) { FastRenderDispatcher.renderLayer(type, stack, (float) cameraX, (float) cameraY, (float) cameraZ); } diff --git a/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java b/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java index c571f6ee8..344d41429 100644 --- a/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java +++ b/src/main/java/com/simibubi/create/foundation/render/AllProgramSpecs.java @@ -9,6 +9,8 @@ import com.simibubi.create.foundation.render.gl.shader.ProgramSpec; import com.simibubi.create.foundation.render.gl.shader.ShaderConstants; import net.minecraft.util.ResourceLocation; +import static com.simibubi.create.foundation.render.gl.backend.Backend.register; + public class AllProgramSpecs { public static final ProgramSpec ROTATING = register(new ProgramSpec<>("rotating", Locations.ROTATING, Locations.INSTANCED, BasicProgram::new)); public static final ProgramSpec BELT = register(new ProgramSpec<>("belt", Locations.BELT, Locations.INSTANCED, BasicProgram::new)); @@ -17,10 +19,6 @@ public class AllProgramSpecs { public static final ProgramSpec CONTRAPTION_BELT = register(new ProgramSpec<>("contraption_belt", Locations.BELT, Locations.CONTRAPTION, ContraptionProgram::new, ShaderConstants.define("CONTRAPTION"))); public static final ProgramSpec CONTRAPTION_ACTOR = register(new ProgramSpec<>("contraption_actor", Locations.CONTRAPTION_ACTOR, Locations.CONTRAPTION, ContraptionProgram::new)); - private static

> S register(S spec) { - return Backend.register(spec); - } - public static class Locations { public static final ResourceLocation INSTANCED = loc("instanced.frag"); public static final ResourceLocation CONTRAPTION = loc("contraption.frag"); diff --git a/src/main/java/com/simibubi/create/foundation/render/AllVertexSpecs.java b/src/main/java/com/simibubi/create/foundation/render/AllVertexSpecs.java deleted file mode 100644 index 4e860fefe..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/AllVertexSpecs.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.simibubi.create.foundation.render; - -import com.simibubi.create.foundation.render.gl.GlPrimitiveType; -import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes; -import com.simibubi.create.foundation.render.gl.attrib.VertexSpec; -import com.simibubi.create.foundation.render.gl.attrib.VertexAttribute; -import com.simibubi.create.foundation.render.gl.attrib.VertexFormat; - -import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribute.copy; -import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.*; - -public class AllVertexSpecs { - - public static final VertexAttribute ROTATION_CENTER = copy("rotationCenter", CommonAttributes.VEC3); - public static final VertexAttribute SPEED = copy("speed", CommonAttributes.FLOAT); - public static final VertexAttribute OFFSET = copy("offset", CommonAttributes.FLOAT); - public static final VertexAttribute TARGET_UV = copy("scrollTexture", CommonAttributes.VEC4); - public static final VertexAttribute SCROLL_MULT = new VertexAttribute("scrollMult", GlPrimitiveType.BYTE, 1, true); - - - public static final VertexFormat FORMAT = new VertexFormat(CommonAttributes.INSTANCE_POSITION, CommonAttributes.LIGHT, CommonAttributes.RGB, SPEED, OFFSET); - - public static final VertexSpec KINETIC = new VertexSpec() - .attrib(POSITION) - .attrib(NORMAL) - .attrib(UV) - .pushGroup(1) // instance data - .attrib(INSTANCE_POSITION) - .attrib(LIGHT) - .attrib(RGB) - .attrib(SPEED) - .attrib(OFFSET); - - public static final VertexSpec BELT = new VertexSpec(KINETIC) - .attrib(ROTATION) - .attrib("uv", UV) - .attrib(TARGET_UV) - .attrib(SCROLL_MULT); - - public static final VertexSpec ROTATING = new VertexSpec(KINETIC) - .attrib("rotationAxis", NORMAL); - - public static final VertexSpec ACTOR = new VertexSpec() - .attrib(POSITION) - .attrib(NORMAL) - .attrib(UV) - .pushGroup(1) // instance data - .attrib(INSTANCE_POSITION) - .attrib(LIGHT) - .attrib(OFFSET) - .attrib("localRotationAxis", NORMAL) - .attrib("localRotation", ROTATION) - .attrib(ROTATION_CENTER); -} diff --git a/src/main/java/com/simibubi/create/foundation/render/BufferedModel.java b/src/main/java/com/simibubi/create/foundation/render/BufferedModel.java index 37348904d..2df3d68ae 100644 --- a/src/main/java/com/simibubi/create/foundation/render/BufferedModel.java +++ b/src/main/java/com/simibubi/create/foundation/render/BufferedModel.java @@ -1,46 +1,40 @@ package com.simibubi.create.foundation.render; +import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.foundation.render.gl.backend.Backend; import com.simibubi.create.foundation.render.gl.GlBuffer; -import com.simibubi.create.foundation.render.gl.GlVertexArray; import com.simibubi.create.foundation.render.gl.attrib.VertexFormat; import net.minecraft.client.renderer.BufferBuilder; +import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; import java.nio.ByteBuffer; +import java.util.HashSet; public abstract class BufferedModel extends TemplateBuffer { - protected GlVertexArray vao; - - protected GlBuffer ebo; - protected GlBuffer invariantVBO; + protected GlBuffer modelVBO; protected boolean removed; public BufferedModel(BufferBuilder buf) { super(buf); - if (vertexCount > 0) setup(); + if (vertexCount > 0) init(); } - protected void setup() { + protected void init() { + + modelVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER); + + modelVBO.bind(); + initModel(); + modelVBO.unbind(); + } + + protected void initModel() { int stride = getModelFormat().getStride(); - int invariantSize = vertexCount * stride; - vao = new GlVertexArray(); - invariantVBO = new GlBuffer(); - ebo = createEBO(); - - vao.bind(); - - int numAttributes = getTotalShaderAttributeCount(); - for (int i = 0; i <= numAttributes; i++) { - GL20.glEnableVertexAttribArray(i); - } - - invariantVBO.bind(GL15.GL_ARRAY_BUFFER); - // allocate the buffer on the gpu GL15.glBufferData(GL15.GL_ARRAY_BUFFER, invariantSize, GL15.GL_STATIC_DRAW); @@ -50,12 +44,6 @@ public abstract class BufferedModel extends TemplateBuffer { copyVertex(buffer, i); } }); - - getModelFormat().informAttributes(0); - - invariantVBO.unbind(GL15.GL_ARRAY_BUFFER); - // Deselect (bind to 0) the VAO - vao.unbind(); } protected abstract void copyVertex(ByteBuffer to, int index); @@ -66,24 +54,46 @@ public abstract class BufferedModel extends TemplateBuffer { return getModelFormat().getShaderAttributeCount(); } - protected abstract void drawCall(); - - protected void preDrawTask() { - - } - - public void render() { + /** + * Renders this model, checking first if it should actually be rendered. + */ + public final void render() { if (vertexCount == 0 || removed) return; - vao.bind(); - preDrawTask(); + doRender(); + } - ebo.bind(GL15.GL_ELEMENT_ARRAY_BUFFER); + /** + * Override this + */ + protected void doRender() { + GL20.glDisableClientState(32884); + GL20.glDisableClientState(32885); + GL20.glDisableClientState(32886); + GL20.glDisableClientState(32888); + GL20.glEnable(GL20.GL_VERTEX_ARRAY); + modelVBO.bind(); - drawCall(); + setupAttributes(); + GL20.glDrawArrays(GL11.GL_QUADS, 0, vertexCount); - ebo.unbind(GL15.GL_ELEMENT_ARRAY_BUFFER); - vao.unbind(); + modelVBO.unbind(); + + int numAttributes = getTotalShaderAttributeCount(); + for (int i = 0; i <= numAttributes; i++) { + GL20.glDisableVertexAttribArray(i); + } + + GL20.glDisable(GL20.GL_VERTEX_ARRAY); + } + + protected void setupAttributes() { + getModelFormat().informAttributes(0); + + int numAttributes = getTotalShaderAttributeCount(); + for (int i = 0; i <= numAttributes; i++) { + GL20.glEnableVertexAttribArray(i); + } } public void delete() { @@ -94,8 +104,6 @@ public abstract class BufferedModel extends TemplateBuffer { } protected void deleteInternal() { - invariantVBO.delete(); - ebo.delete(); - vao.delete(); + modelVBO.delete(); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/TemplateBuffer.java b/src/main/java/com/simibubi/create/foundation/render/TemplateBuffer.java index 1d81fe2dc..3b31227b3 100644 --- a/src/main/java/com/simibubi/create/foundation/render/TemplateBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/TemplateBuffer.java @@ -33,25 +33,6 @@ public class TemplateBuffer { ((Buffer)template).rewind(); } - protected final GlBuffer createEBO(){ - GlBuffer ebo = new GlBuffer(); - - int indicesSize = vertexCount * VertexFormatElement.Type.USHORT.getSize(); - - ebo.bind(GL15.GL_ELEMENT_ARRAY_BUFFER); - - GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, GL15.GL_STATIC_DRAW); - Backend.mapBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, indices -> { - for (int i = 0; i < vertexCount; i++) { - indices.putShort((short) i); - } - }); - - ebo.unbind(GL15.GL_ELEMENT_ARRAY_BUFFER); - - return ebo; - } - public boolean isEmpty() { return ((Buffer) template).limit() == 0; } diff --git a/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionModel.java b/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionModel.java index 2fa63f9a0..e917c4234 100644 --- a/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionModel.java +++ b/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionModel.java @@ -6,6 +6,7 @@ import com.simibubi.create.foundation.render.gl.attrib.VertexFormat; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.LightTexture; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL40; import java.nio.ByteBuffer; @@ -51,9 +52,4 @@ public class ContraptionModel extends BufferedModel { protected VertexFormat getModelFormat() { return FORMAT; } - - @Override - protected void drawCall() { - GL40.glDrawElements(GL11.GL_QUADS, vertexCount, GL11.GL_UNSIGNED_SHORT, 0); - } } diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/GlBuffer.java b/src/main/java/com/simibubi/create/foundation/render/gl/GlBuffer.java index 59d30067f..287ba6057 100644 --- a/src/main/java/com/simibubi/create/foundation/render/gl/GlBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/GlBuffer.java @@ -3,16 +3,20 @@ package com.simibubi.create.foundation.render.gl; import org.lwjgl.opengl.GL20; public class GlBuffer extends GlObject { - public GlBuffer() { + + protected final int bufferType; + + public GlBuffer(int bufferType) { setHandle(GL20.glGenBuffers()); + this.bufferType = bufferType; } - public void bind(int target) { - GL20.glBindBuffer(target, handle()); + public void bind() { + GL20.glBindBuffer(bufferType, handle()); } - public void unbind(int target) { - GL20.glBindBuffer(target, 0); + public void unbind() { + GL20.glBindBuffer(bufferType, 0); } protected void deleteInternal(int handle) { diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/GlPrimitiveType.java b/src/main/java/com/simibubi/create/foundation/render/gl/GlPrimitiveType.java index cec97b41f..623164c08 100644 --- a/src/main/java/com/simibubi/create/foundation/render/gl/GlPrimitiveType.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/GlPrimitiveType.java @@ -5,19 +5,19 @@ import net.minecraftforge.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) public enum GlPrimitiveType { - FLOAT(4, "Float", 5126), - UBYTE(1, "Unsigned Byte", 5121), - BYTE(1, "Byte", 5120), - USHORT(2, "Unsigned Short", 5123), - SHORT(2, "Short", 5122), - UINT(4, "Unsigned Int", 5125), - INT(4, "Int", 5124); + FLOAT(4, "float", 5126), + UBYTE(1, "ubyte", 5121), + BYTE(1, "byte", 5120), + USHORT(2, "ushort", 5123), + SHORT(2, "short", 5122), + UINT(4, "uint", 5125), + INT(4, "int", 5124); private final int size; private final String displayName; private final int glConstant; - private GlPrimitiveType(int p_i46095_3_, String p_i46095_4_, int p_i46095_5_) { + GlPrimitiveType(int p_i46095_3_, String p_i46095_4_, int p_i46095_5_) { this.size = p_i46095_3_; this.displayName = p_i46095_4_; this.glConstant = p_i46095_5_; diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/attrib/AttributeGroup.java b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/AttributeGroup.java index 3546e3552..8a48ccb3c 100644 --- a/src/main/java/com/simibubi/create/foundation/render/gl/attrib/AttributeGroup.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/AttributeGroup.java @@ -5,14 +5,14 @@ import java.util.ArrayList; public class AttributeGroup { private final int divisor; - private final ArrayList attributes; + private final ArrayList attributes; public AttributeGroup(int divisor) { this.divisor = divisor; this.attributes = new ArrayList<>(); } - public AttributeGroup attrib(VertexAttribute attrib) { + public AttributeGroup attrib(VertexAttribSpec attrib) { attributes.add(attrib); return this; } @@ -21,7 +21,7 @@ public class AttributeGroup { return divisor; } - public ArrayList getAttributes() { + public ArrayList getAttributes() { return attributes; } } diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/attrib/CommonAttributes.java b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/CommonAttributes.java index d690334da..6b4f3fa57 100644 --- a/src/main/java/com/simibubi/create/foundation/render/gl/attrib/CommonAttributes.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/CommonAttributes.java @@ -4,20 +4,20 @@ import com.simibubi.create.foundation.render.gl.GlPrimitiveType; public class CommonAttributes { - public static final VertexAttribute MAT4 = new VertexAttribute("aMat4", GlPrimitiveType.FLOAT, 16); - public static final VertexAttribute VEC4 = new VertexAttribute("aVec4", GlPrimitiveType.FLOAT, 4); - public static final VertexAttribute VEC3 = new VertexAttribute("aVec3", GlPrimitiveType.FLOAT, 3); - public static final VertexAttribute VEC2 = new VertexAttribute("aVec2", GlPrimitiveType.FLOAT, 2); - public static final VertexAttribute FLOAT = new VertexAttribute("aFloat", GlPrimitiveType.FLOAT, 1); + public static final VertexAttribSpec MAT4 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 16); + public static final VertexAttribSpec VEC4 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 4); + public static final VertexAttribSpec VEC3 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 3); + public static final VertexAttribSpec VEC2 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 2); + public static final VertexAttribSpec FLOAT = new VertexAttribSpec(GlPrimitiveType.FLOAT, 1); - public static final VertexAttribute POSITION = VertexAttribute.copy("aPos", VEC3); - public static final VertexAttribute NORMAL = new VertexAttribute("aNormal", GlPrimitiveType.BYTE, 3, true); - public static final VertexAttribute UV = VertexAttribute.copy("aTexCoords", VEC2); + public static final VertexAttribSpec POSITION = VertexAttribSpec.copy(VEC3); + public static final VertexAttribSpec NORMAL = new VertexAttribSpec(GlPrimitiveType.BYTE, 3, true); + public static final VertexAttribSpec UV = VertexAttribSpec.copy(VEC2); - public static final VertexAttribute ROTATION = VertexAttribute.copy("eulerAngles", VEC3); - public static final VertexAttribute INSTANCE_POSITION = VertexAttribute.copy("instancePos", VEC3); + public static final VertexAttribSpec ROTATION = VertexAttribSpec.copy(VEC3); + public static final VertexAttribSpec INSTANCE_POSITION = VertexAttribSpec.copy(VEC3); - public static final VertexAttribute RGBA = new VertexAttribute("rgba", GlPrimitiveType.UBYTE, 4, true); - public static final VertexAttribute RGB = new VertexAttribute("rgb", GlPrimitiveType.UBYTE, 3, true); - public static final VertexAttribute LIGHT = new VertexAttribute("light", GlPrimitiveType.UBYTE, 2, true); + public static final VertexAttribSpec RGBA = new VertexAttribSpec(GlPrimitiveType.UBYTE, 4, true); + public static final VertexAttribSpec RGB = new VertexAttribSpec(GlPrimitiveType.UBYTE, 3, true); + public static final VertexAttribSpec LIGHT = new VertexAttribSpec(GlPrimitiveType.UBYTE, 2, true); } diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/attrib/IVertexAttrib.java b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/IVertexAttrib.java new file mode 100644 index 000000000..30ef9ad45 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/IVertexAttrib.java @@ -0,0 +1,10 @@ +package com.simibubi.create.foundation.render.gl.attrib; + +public interface IVertexAttrib { + + String attribName(); + + VertexAttribSpec attribSpec(); + + int getDivisor(); +} diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/attrib/RotatingVertexAttributes.java b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/RotatingVertexAttributes.java new file mode 100644 index 000000000..efd958688 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/RotatingVertexAttributes.java @@ -0,0 +1,43 @@ +package com.simibubi.create.foundation.render.gl.attrib; + +public enum RotatingVertexAttributes implements IVertexAttrib { + VERTEX_POSITION("aPos", CommonAttributes.VEC3), + NORMAL("aNormal", CommonAttributes.VEC3), + TEXTURE("aInstancePos", CommonAttributes.VEC3), + INSTANCE_POSITION("aInstancePos", CommonAttributes.VEC3, 1), + LIGHT("aLight", CommonAttributes.LIGHT, 1), + NETWORK_COLOR("aNetworkTint", CommonAttributes.RGB, 1), + SPEED("aSpeed", CommonAttributes.FLOAT, 1), + OFFSET("aOffset", CommonAttributes.FLOAT, 1), + AXIS("aAxis", CommonAttributes.NORMAL, 1), + ; + + private final String name; + private final VertexAttribSpec spec; + private final int divisor; + + RotatingVertexAttributes(String name, VertexAttribSpec spec) { + this(name, spec, 0); + } + + RotatingVertexAttributes(String name, VertexAttribSpec spec, int divisor) { + this.name = name; + this.spec = spec; + this.divisor = divisor; + } + + @Override + public String attribName() { + return name; + } + + @Override + public VertexAttribSpec attribSpec() { + return spec; + } + + @Override + public int getDivisor() { + return divisor; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexAttribute.java b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexAttribSpec.java similarity index 68% rename from src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexAttribute.java rename to src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexAttribSpec.java index 94386821b..eb90102ee 100644 --- a/src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexAttribute.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexAttribSpec.java @@ -3,21 +3,19 @@ package com.simibubi.create.foundation.render.gl.attrib; import com.simibubi.create.foundation.render.gl.GlPrimitiveType; import org.lwjgl.opengl.GL20; -public class VertexAttribute { +public class VertexAttribSpec { - private final String name; private final GlPrimitiveType type; private final int count; private final int size; private final int attributeCount; private final boolean normalized; - public static VertexAttribute copy(String name, VertexAttribute other) { - return new VertexAttribute(name, other); + public static VertexAttribSpec copy(VertexAttribSpec other) { + return new VertexAttribSpec(other); } - public VertexAttribute(String name, VertexAttribute that) { - this.name = name; + public VertexAttribSpec(VertexAttribSpec that) { this.type = that.type; this.count = that.count; this.size = that.size; @@ -25,12 +23,11 @@ public class VertexAttribute { this.normalized = that.normalized; } - public VertexAttribute(String name, GlPrimitiveType type, int count) { - this(name, type, count, false); + public VertexAttribSpec(GlPrimitiveType type, int count) { + this(type, count, false); } - public VertexAttribute(String name, GlPrimitiveType type, int count, boolean normalized) { - this.name = name; + public VertexAttribSpec(GlPrimitiveType type, int count, boolean normalized) { this.type = type; this.count = count; this.size = type.getSize() * count; diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexFormat.java b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexFormat.java index aa4de2447..f205826f3 100644 --- a/src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexFormat.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexFormat.java @@ -2,15 +2,15 @@ package com.simibubi.create.foundation.render.gl.attrib; public class VertexFormat { - private final VertexAttribute[] elements; + private final VertexAttribSpec[] elements; private final int numAttributes; private final int stride; - public VertexFormat(VertexAttribute... elements) { + public VertexFormat(VertexAttribSpec... elements) { this.elements = elements; int numAttributes = 0, stride = 0; - for (VertexAttribute element : elements) { + for (VertexAttribSpec element : elements) { numAttributes += element.getAttributeCount(); stride += element.getSize(); } @@ -18,15 +18,15 @@ public class VertexFormat { this.stride = stride; } - public VertexFormat(VertexFormat start, VertexAttribute... elements) { + public VertexFormat(VertexFormat start, VertexAttribSpec... elements) { int baseLength = start.elements.length; int addedLength = elements.length; - this.elements = new VertexAttribute[baseLength + addedLength]; + this.elements = new VertexAttribSpec[baseLength + addedLength]; System.arraycopy(start.elements, 0, this.elements, 0, baseLength); System.arraycopy(elements, 0, this.elements, baseLength, addedLength); int numAttributes = 0, stride = 0; - for (VertexAttribute element : this.elements) { + for (VertexAttribSpec element : this.elements) { numAttributes += element.getAttributeCount(); stride += element.getSize(); } @@ -44,7 +44,7 @@ public class VertexFormat { public void informAttributes(int index) { int offset = 0; - for (VertexAttribute element : this.elements) { + for (VertexAttribSpec element : this.elements) { element.registerForBuffer(stride, index, offset); index += element.getAttributeCount(); offset += element.getSize(); diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexSpec.java b/src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexSpec.java deleted file mode 100644 index 0b56596fb..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/gl/attrib/VertexSpec.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.simibubi.create.foundation.render.gl.attrib; - -import com.google.common.collect.Lists; - -import java.util.ArrayList; -import java.util.function.Consumer; - -public class VertexSpec { - - private final ArrayList groups; - - public VertexSpec() { - groups = Lists.newArrayList(new AttributeGroup(0)); - } - - public VertexSpec(VertexSpec that) { - groups = new ArrayList<>(); - for (AttributeGroup group : that.groups) { - AttributeGroup copy = new AttributeGroup(group.getDivisor()); - - for (VertexAttribute attribute : group.getAttributes()) { - copy.attrib(attribute); - } - - groups.add(copy); - } - } - - public VertexSpec pushGroup() { - return pushGroup(0); - } - - public VertexSpec group(int divisor, Consumer builder) { - AttributeGroup group = new AttributeGroup(divisor); - builder.accept(group); - return group(group); - } - - public VertexSpec pushGroup(int divisor) { - return group(new AttributeGroup(divisor)); - } - - public VertexSpec group(AttributeGroup group) { - groups.add(group); - return this; - } - - public VertexSpec attrib(String name, VertexAttribute attrib) { - return attrib(VertexAttribute.copy(name, attrib)); - } - - public VertexSpec attrib(VertexAttribute attrib) { - last().attrib(attrib); - return this; - } - - - private AttributeGroup last() { - return groups.get(groups.size() - 1); - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java b/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java index 36b198ad6..0912e9407 100644 --- a/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java @@ -135,10 +135,13 @@ public class Backend { refresh(); - programs.values().forEach(GlProgram::delete); - programs.clear(); - for (ProgramSpec shader : registry.values()) { - loadProgram(manager, shader); + if (isCapable()) { + + programs.values().forEach(GlProgram::delete); + programs.clear(); + for (ProgramSpec shader : registry.values()) { + loadProgram(manager, shader); + } } } } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/BeltData.java b/src/main/java/com/simibubi/create/foundation/render/instancing/BeltData.java index 75ef968ad..bbb302e72 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/BeltData.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/BeltData.java @@ -3,17 +3,17 @@ package com.simibubi.create.foundation.render.instancing; import com.simibubi.create.foundation.block.render.SpriteShiftEntry; import com.simibubi.create.foundation.render.gl.GlPrimitiveType; import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes; -import com.simibubi.create.foundation.render.gl.attrib.VertexAttribute; +import com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec; import com.simibubi.create.foundation.render.gl.attrib.VertexFormat; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import java.nio.ByteBuffer; -import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribute.*; +import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec.*; public class BeltData extends KineticData { - public static final VertexAttribute TARGET_UV = copy("scrollTexture", CommonAttributes.VEC4); - public static final VertexAttribute SCROLL_MULT = new VertexAttribute("scrollMult", GlPrimitiveType.BYTE, 1, true); + public static final VertexAttribSpec TARGET_UV = copy(CommonAttributes.VEC4); + public static final VertexAttribSpec SCROLL_MULT = new VertexAttribSpec(GlPrimitiveType.BYTE, 1, true); public static VertexFormat FORMAT = new VertexFormat(KineticData.FORMAT, CommonAttributes.ROTATION, CommonAttributes.UV, TARGET_UV, SCROLL_MULT); diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/DynamicInstancedModel.java b/src/main/java/com/simibubi/create/foundation/render/instancing/DynamicInstancedModel.java index 0b40e50af..4e6bec405 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/DynamicInstancedModel.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/DynamicInstancedModel.java @@ -3,6 +3,7 @@ package com.simibubi.create.foundation.render.instancing; import com.simibubi.create.foundation.render.gl.GlBuffer; import com.simibubi.create.foundation.render.gl.attrib.VertexFormat; import net.minecraft.client.renderer.BufferBuilder; +import org.lwjgl.opengl.GL20; public abstract class DynamicInstancedModel extends InstancedModel { @@ -15,9 +16,9 @@ public abstract class DynamicInstancedModel extends BufferedModel { public static final VertexFormat FORMAT = new VertexFormat(CommonAttributes.POSITION, CommonAttributes.NORMAL, CommonAttributes.UV); + protected GlVertexArray vao; protected GlBuffer instanceVBO; protected int glBufferSize = -1; protected int glInstanceCount = 0; @@ -34,32 +33,21 @@ public abstract class InstancedModel extends BufferedMod } @Override - protected void setup() { - super.setup(); - instanceVBO = new GlBuffer(); + protected void init() { + vao = new GlVertexArray(); + instanceVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER); + + vao.bind(); + super.init(); + vao.unbind(); } @Override - protected VertexFormat getModelFormat() { - return FORMAT; + protected void initModel() { + super.initModel(); + setupAttributes(); } - @Override - protected void copyVertex(ByteBuffer constant, int i) { - constant.putFloat(getX(template, i)); - constant.putFloat(getY(template, i)); - constant.putFloat(getZ(template, i)); - - constant.put(getNX(template, i)); - constant.put(getNY(template, i)); - constant.put(getNZ(template, i)); - - constant.putFloat(getU(template, i)); - constant.putFloat(getV(template, i)); - } - - protected abstract VertexFormat getInstanceFormat(); - public int instanceCount() { return data.size(); } @@ -69,9 +57,11 @@ public abstract class InstancedModel extends BufferedMod } protected void deleteInternal() { - super.deleteInternal(); - instanceVBO.delete(); keys.forEach(InstanceKey::invalidate); + super.deleteInternal(); + + instanceVBO.delete(); + vao.delete(); } protected abstract D newInstance(); @@ -117,40 +107,14 @@ public abstract class InstancedModel extends BufferedMod return key; } - protected void markIndexChanged(int index) { - if (minIndexChanged < 0) { - minIndexChanged = index; - } else if (index < minIndexChanged) { - minIndexChanged = index; - } - - if (maxIndexChanged < 0) { - maxIndexChanged = index; - } else if (index > maxIndexChanged) { - maxIndexChanged = index; - } + protected void doRender() { + vao.bind(); + renderSetup(); + GL31.glDrawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount); + vao.unbind(); } - protected final void verifyKey(InstanceKey key) { - if (key.model != this) throw new IllegalStateException("Provided key does not belong to model."); - - if (!key.isValid()) throw new IllegalStateException("Provided key has been invalidated."); - - if (key.index >= data.size()) throw new IndexOutOfBoundsException("Key points out of bounds. (" + key.index + " > " + (data.size() - 1) + ")"); - - if (keys.get(key.index) != key) throw new IllegalStateException("Key desync!!"); - } - - protected int getTotalShaderAttributeCount() { - return getInstanceFormat().getShaderAttributeCount() + super.getTotalShaderAttributeCount(); - } - - @Override - protected void drawCall() { - GL31.glDrawElementsInstanced(GL11.GL_QUADS, vertexCount, GL11.GL_UNSIGNED_SHORT, 0, glInstanceCount); - } - - protected void preDrawTask() { + protected void renderSetup() { if (minIndexChanged < 0 || data.isEmpty()) return; VertexFormat instanceFormat = getInstanceFormat(); @@ -159,7 +123,7 @@ public abstract class InstancedModel extends BufferedMod int newInstanceCount = instanceCount(); int instanceSize = RenderMath.nextPowerOf2((newInstanceCount + 1) * stride); - instanceVBO.bind(GL15.GL_ARRAY_BUFFER); + instanceVBO.bind(); // this probably changes enough that it's not worth reallocating the entire buffer every time. if (instanceSize > glBufferSize) { @@ -197,9 +161,58 @@ public abstract class InstancedModel extends BufferedMod GL33.glVertexAttribDivisor(i + staticAttributes, 1); } - instanceVBO.unbind(GL15.GL_ARRAY_BUFFER); + instanceVBO.unbind(); minIndexChanged = -1; maxIndexChanged = -1; } + + protected void markIndexChanged(int index) { + if (minIndexChanged < 0) { + minIndexChanged = index; + } else if (index < minIndexChanged) { + minIndexChanged = index; + } + + if (maxIndexChanged < 0) { + maxIndexChanged = index; + } else if (index > maxIndexChanged) { + maxIndexChanged = index; + } + } + + protected final void verifyKey(InstanceKey key) { + if (key.model != this) throw new IllegalStateException("Provided key does not belong to model."); + + if (!key.isValid()) throw new IllegalStateException("Provided key has been invalidated."); + + if (key.index >= data.size()) throw new IndexOutOfBoundsException("Key points out of bounds. (" + key.index + " > " + (data.size() - 1) + ")"); + + if (keys.get(key.index) != key) throw new IllegalStateException("Key desync!!"); + } + + @Override + protected void copyVertex(ByteBuffer constant, int i) { + constant.putFloat(getX(template, i)); + constant.putFloat(getY(template, i)); + constant.putFloat(getZ(template, i)); + + constant.put(getNX(template, i)); + constant.put(getNY(template, i)); + constant.put(getNZ(template, i)); + + constant.putFloat(getU(template, i)); + constant.putFloat(getV(template, i)); + } + + @Override + protected VertexFormat getModelFormat() { + return FORMAT; + } + + protected abstract VertexFormat getInstanceFormat(); + + protected int getTotalShaderAttributeCount() { + return getInstanceFormat().getShaderAttributeCount() + super.getTotalShaderAttributeCount(); + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderer.java b/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderer.java index bce27b736..a5e84af0c 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderer.java @@ -117,7 +117,5 @@ public abstract class InstancedTileRenderer

{ if (material.canRenderInLayer(layer)) material.render(layer, viewProjection, camX, camY, camZ, callback); } - - GL20.glUseProgram(0); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/KineticData.java b/src/main/java/com/simibubi/create/foundation/render/instancing/KineticData.java index b205596ac..2367b2f51 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/KineticData.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/KineticData.java @@ -2,7 +2,7 @@ package com.simibubi.create.foundation.render.instancing; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes; -import com.simibubi.create.foundation.render.gl.attrib.VertexAttribute; +import com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec; import com.simibubi.create.foundation.render.gl.attrib.VertexFormat; import com.simibubi.create.foundation.utility.ColorHelper; import net.minecraft.client.renderer.Vector3f; @@ -10,12 +10,12 @@ import net.minecraft.util.math.BlockPos; import java.nio.ByteBuffer; -import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribute.*; +import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec.*; public class KineticData> extends InstanceData { - public static final VertexAttribute ROTATION_CENTER = copy("rotationCenter", CommonAttributes.VEC3); - public static final VertexAttribute SPEED = copy("speed", CommonAttributes.FLOAT); - public static final VertexAttribute OFFSET = copy("offset", CommonAttributes.FLOAT); + public static final VertexAttribSpec ROTATION_CENTER = copy(CommonAttributes.VEC3); + public static final VertexAttribSpec SPEED = copy(CommonAttributes.FLOAT); + public static final VertexAttribSpec OFFSET = copy(CommonAttributes.FLOAT); public static final VertexFormat FORMAT = new VertexFormat(CommonAttributes.INSTANCE_POSITION, CommonAttributes.LIGHT, CommonAttributes.RGB, SPEED, OFFSET); private float x;