begin 2.0 compatibility push, probably not going to be ready for the next release

This commit is contained in:
JozsefA 2021-02-10 17:14:03 -08:00
parent e93562569b
commit 02114b1d9a
21 changed files with 249 additions and 317 deletions

View File

@ -20,7 +20,7 @@ public class RenderInLayerMixin {
* layer-correct custom rendering. RenderWorldLast is not refined enough for rendering world objects. * layer-correct custom rendering. RenderWorldLast is not refined enough for rendering world objects.
* This should probably be a forge event. * 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) { 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); FastRenderDispatcher.renderLayer(type, stack, (float) cameraX, (float) cameraY, (float) cameraZ);
} }

View File

@ -9,6 +9,8 @@ import com.simibubi.create.foundation.render.gl.shader.ProgramSpec;
import com.simibubi.create.foundation.render.gl.shader.ShaderConstants; import com.simibubi.create.foundation.render.gl.shader.ShaderConstants;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import static com.simibubi.create.foundation.render.gl.backend.Backend.register;
public class AllProgramSpecs { public class AllProgramSpecs {
public static final ProgramSpec<BasicProgram> ROTATING = register(new ProgramSpec<>("rotating", Locations.ROTATING, Locations.INSTANCED, BasicProgram::new)); public static final ProgramSpec<BasicProgram> ROTATING = register(new ProgramSpec<>("rotating", Locations.ROTATING, Locations.INSTANCED, BasicProgram::new));
public static final ProgramSpec<BasicProgram> BELT = register(new ProgramSpec<>("belt", Locations.BELT, Locations.INSTANCED, BasicProgram::new)); public static final ProgramSpec<BasicProgram> BELT = register(new ProgramSpec<>("belt", Locations.BELT, Locations.INSTANCED, BasicProgram::new));
@ -17,10 +19,6 @@ public class AllProgramSpecs {
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_BELT = register(new ProgramSpec<>("contraption_belt", Locations.BELT, Locations.CONTRAPTION, ContraptionProgram::new, ShaderConstants.define("CONTRAPTION"))); public static final ProgramSpec<ContraptionProgram> CONTRAPTION_BELT = register(new ProgramSpec<>("contraption_belt", Locations.BELT, Locations.CONTRAPTION, ContraptionProgram::new, ShaderConstants.define("CONTRAPTION")));
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_ACTOR = register(new ProgramSpec<>("contraption_actor", Locations.CONTRAPTION_ACTOR, Locations.CONTRAPTION, ContraptionProgram::new)); public static final ProgramSpec<ContraptionProgram> CONTRAPTION_ACTOR = register(new ProgramSpec<>("contraption_actor", Locations.CONTRAPTION_ACTOR, Locations.CONTRAPTION, ContraptionProgram::new));
private static <P extends GlProgram, S extends ProgramSpec<P>> S register(S spec) {
return Backend.register(spec);
}
public static class Locations { public static class Locations {
public static final ResourceLocation INSTANCED = loc("instanced.frag"); public static final ResourceLocation INSTANCED = loc("instanced.frag");
public static final ResourceLocation CONTRAPTION = loc("contraption.frag"); public static final ResourceLocation CONTRAPTION = loc("contraption.frag");

View File

@ -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);
}

View File

@ -1,46 +1,40 @@
package com.simibubi.create.foundation.render; 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.backend.Backend;
import com.simibubi.create.foundation.render.gl.GlBuffer; 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 com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.HashSet;
public abstract class BufferedModel extends TemplateBuffer { public abstract class BufferedModel extends TemplateBuffer {
protected GlVertexArray vao; protected GlBuffer modelVBO;
protected GlBuffer ebo;
protected GlBuffer invariantVBO;
protected boolean removed; protected boolean removed;
public BufferedModel(BufferBuilder buf) { public BufferedModel(BufferBuilder buf) {
super(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 stride = getModelFormat().getStride();
int invariantSize = vertexCount * stride; 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 // allocate the buffer on the gpu
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, invariantSize, GL15.GL_STATIC_DRAW); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, invariantSize, GL15.GL_STATIC_DRAW);
@ -50,12 +44,6 @@ public abstract class BufferedModel extends TemplateBuffer {
copyVertex(buffer, i); 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); protected abstract void copyVertex(ByteBuffer to, int index);
@ -66,24 +54,46 @@ public abstract class BufferedModel extends TemplateBuffer {
return getModelFormat().getShaderAttributeCount(); return getModelFormat().getShaderAttributeCount();
} }
protected abstract void drawCall(); /**
* Renders this model, checking first if it should actually be rendered.
protected void preDrawTask() { */
public final void render() {
}
public void render() {
if (vertexCount == 0 || removed) return; if (vertexCount == 0 || removed) return;
vao.bind(); doRender();
preDrawTask(); }
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); modelVBO.unbind();
vao.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() { public void delete() {
@ -94,8 +104,6 @@ public abstract class BufferedModel extends TemplateBuffer {
} }
protected void deleteInternal() { protected void deleteInternal() {
invariantVBO.delete(); modelVBO.delete();
ebo.delete();
vao.delete();
} }
} }

View File

@ -33,25 +33,6 @@ public class TemplateBuffer {
((Buffer)template).rewind(); ((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() { public boolean isEmpty() {
return ((Buffer) template).limit() == 0; return ((Buffer) template).limit() == 0;
} }

View File

@ -6,6 +6,7 @@ import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.LightTexture;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL40; import org.lwjgl.opengl.GL40;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -51,9 +52,4 @@ public class ContraptionModel extends BufferedModel {
protected VertexFormat getModelFormat() { protected VertexFormat getModelFormat() {
return FORMAT; return FORMAT;
} }
@Override
protected void drawCall() {
GL40.glDrawElements(GL11.GL_QUADS, vertexCount, GL11.GL_UNSIGNED_SHORT, 0);
}
} }

View File

@ -3,16 +3,20 @@ package com.simibubi.create.foundation.render.gl;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
public class GlBuffer extends GlObject { public class GlBuffer extends GlObject {
public GlBuffer() {
protected final int bufferType;
public GlBuffer(int bufferType) {
setHandle(GL20.glGenBuffers()); setHandle(GL20.glGenBuffers());
this.bufferType = bufferType;
} }
public void bind(int target) { public void bind() {
GL20.glBindBuffer(target, handle()); GL20.glBindBuffer(bufferType, handle());
} }
public void unbind(int target) { public void unbind() {
GL20.glBindBuffer(target, 0); GL20.glBindBuffer(bufferType, 0);
} }
protected void deleteInternal(int handle) { protected void deleteInternal(int handle) {

View File

@ -5,19 +5,19 @@ import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public enum GlPrimitiveType { public enum GlPrimitiveType {
FLOAT(4, "Float", 5126), FLOAT(4, "float", 5126),
UBYTE(1, "Unsigned Byte", 5121), UBYTE(1, "ubyte", 5121),
BYTE(1, "Byte", 5120), BYTE(1, "byte", 5120),
USHORT(2, "Unsigned Short", 5123), USHORT(2, "ushort", 5123),
SHORT(2, "Short", 5122), SHORT(2, "short", 5122),
UINT(4, "Unsigned Int", 5125), UINT(4, "uint", 5125),
INT(4, "Int", 5124); INT(4, "int", 5124);
private final int size; private final int size;
private final String displayName; private final String displayName;
private final int glConstant; 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.size = p_i46095_3_;
this.displayName = p_i46095_4_; this.displayName = p_i46095_4_;
this.glConstant = p_i46095_5_; this.glConstant = p_i46095_5_;

View File

@ -5,14 +5,14 @@ import java.util.ArrayList;
public class AttributeGroup { public class AttributeGroup {
private final int divisor; private final int divisor;
private final ArrayList<VertexAttribute> attributes; private final ArrayList<VertexAttribSpec> attributes;
public AttributeGroup(int divisor) { public AttributeGroup(int divisor) {
this.divisor = divisor; this.divisor = divisor;
this.attributes = new ArrayList<>(); this.attributes = new ArrayList<>();
} }
public AttributeGroup attrib(VertexAttribute attrib) { public AttributeGroup attrib(VertexAttribSpec attrib) {
attributes.add(attrib); attributes.add(attrib);
return this; return this;
} }
@ -21,7 +21,7 @@ public class AttributeGroup {
return divisor; return divisor;
} }
public ArrayList<VertexAttribute> getAttributes() { public ArrayList<VertexAttribSpec> getAttributes() {
return attributes; return attributes;
} }
} }

View File

@ -4,20 +4,20 @@ import com.simibubi.create.foundation.render.gl.GlPrimitiveType;
public class CommonAttributes { public class CommonAttributes {
public static final VertexAttribute MAT4 = new VertexAttribute("aMat4", GlPrimitiveType.FLOAT, 16); public static final VertexAttribSpec MAT4 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 16);
public static final VertexAttribute VEC4 = new VertexAttribute("aVec4", GlPrimitiveType.FLOAT, 4); public static final VertexAttribSpec VEC4 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 4);
public static final VertexAttribute VEC3 = new VertexAttribute("aVec3", GlPrimitiveType.FLOAT, 3); public static final VertexAttribSpec VEC3 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 3);
public static final VertexAttribute VEC2 = new VertexAttribute("aVec2", GlPrimitiveType.FLOAT, 2); public static final VertexAttribSpec VEC2 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 2);
public static final VertexAttribute FLOAT = new VertexAttribute("aFloat", GlPrimitiveType.FLOAT, 1); public static final VertexAttribSpec FLOAT = new VertexAttribSpec(GlPrimitiveType.FLOAT, 1);
public static final VertexAttribute POSITION = VertexAttribute.copy("aPos", VEC3); public static final VertexAttribSpec POSITION = VertexAttribSpec.copy(VEC3);
public static final VertexAttribute NORMAL = new VertexAttribute("aNormal", GlPrimitiveType.BYTE, 3, true); public static final VertexAttribSpec NORMAL = new VertexAttribSpec(GlPrimitiveType.BYTE, 3, true);
public static final VertexAttribute UV = VertexAttribute.copy("aTexCoords", VEC2); public static final VertexAttribSpec UV = VertexAttribSpec.copy(VEC2);
public static final VertexAttribute ROTATION = VertexAttribute.copy("eulerAngles", VEC3); public static final VertexAttribSpec ROTATION = VertexAttribSpec.copy(VEC3);
public static final VertexAttribute INSTANCE_POSITION = VertexAttribute.copy("instancePos", 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 VertexAttribSpec RGBA = new VertexAttribSpec(GlPrimitiveType.UBYTE, 4, true);
public static final VertexAttribute RGB = new VertexAttribute("rgb", GlPrimitiveType.UBYTE, 3, true); public static final VertexAttribSpec RGB = new VertexAttribSpec(GlPrimitiveType.UBYTE, 3, true);
public static final VertexAttribute LIGHT = new VertexAttribute("light", GlPrimitiveType.UBYTE, 2, true); public static final VertexAttribSpec LIGHT = new VertexAttribSpec(GlPrimitiveType.UBYTE, 2, true);
} }

View File

@ -0,0 +1,10 @@
package com.simibubi.create.foundation.render.gl.attrib;
public interface IVertexAttrib {
String attribName();
VertexAttribSpec attribSpec();
int getDivisor();
}

View File

@ -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;
}
}

View File

@ -3,21 +3,19 @@ package com.simibubi.create.foundation.render.gl.attrib;
import com.simibubi.create.foundation.render.gl.GlPrimitiveType; import com.simibubi.create.foundation.render.gl.GlPrimitiveType;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
public class VertexAttribute { public class VertexAttribSpec {
private final String name;
private final GlPrimitiveType type; private final GlPrimitiveType type;
private final int count; private final int count;
private final int size; private final int size;
private final int attributeCount; private final int attributeCount;
private final boolean normalized; private final boolean normalized;
public static VertexAttribute copy(String name, VertexAttribute other) { public static VertexAttribSpec copy(VertexAttribSpec other) {
return new VertexAttribute(name, other); return new VertexAttribSpec(other);
} }
public VertexAttribute(String name, VertexAttribute that) { public VertexAttribSpec(VertexAttribSpec that) {
this.name = name;
this.type = that.type; this.type = that.type;
this.count = that.count; this.count = that.count;
this.size = that.size; this.size = that.size;
@ -25,12 +23,11 @@ public class VertexAttribute {
this.normalized = that.normalized; this.normalized = that.normalized;
} }
public VertexAttribute(String name, GlPrimitiveType type, int count) { public VertexAttribSpec(GlPrimitiveType type, int count) {
this(name, type, count, false); this(type, count, false);
} }
public VertexAttribute(String name, GlPrimitiveType type, int count, boolean normalized) { public VertexAttribSpec(GlPrimitiveType type, int count, boolean normalized) {
this.name = name;
this.type = type; this.type = type;
this.count = count; this.count = count;
this.size = type.getSize() * count; this.size = type.getSize() * count;

View File

@ -2,15 +2,15 @@ package com.simibubi.create.foundation.render.gl.attrib;
public class VertexFormat { public class VertexFormat {
private final VertexAttribute[] elements; private final VertexAttribSpec[] elements;
private final int numAttributes; private final int numAttributes;
private final int stride; private final int stride;
public VertexFormat(VertexAttribute... elements) { public VertexFormat(VertexAttribSpec... elements) {
this.elements = elements; this.elements = elements;
int numAttributes = 0, stride = 0; int numAttributes = 0, stride = 0;
for (VertexAttribute element : elements) { for (VertexAttribSpec element : elements) {
numAttributes += element.getAttributeCount(); numAttributes += element.getAttributeCount();
stride += element.getSize(); stride += element.getSize();
} }
@ -18,15 +18,15 @@ public class VertexFormat {
this.stride = stride; this.stride = stride;
} }
public VertexFormat(VertexFormat start, VertexAttribute... elements) { public VertexFormat(VertexFormat start, VertexAttribSpec... elements) {
int baseLength = start.elements.length; int baseLength = start.elements.length;
int addedLength = 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(start.elements, 0, this.elements, 0, baseLength);
System.arraycopy(elements, 0, this.elements, baseLength, addedLength); System.arraycopy(elements, 0, this.elements, baseLength, addedLength);
int numAttributes = 0, stride = 0; int numAttributes = 0, stride = 0;
for (VertexAttribute element : this.elements) { for (VertexAttribSpec element : this.elements) {
numAttributes += element.getAttributeCount(); numAttributes += element.getAttributeCount();
stride += element.getSize(); stride += element.getSize();
} }
@ -44,7 +44,7 @@ public class VertexFormat {
public void informAttributes(int index) { public void informAttributes(int index) {
int offset = 0; int offset = 0;
for (VertexAttribute element : this.elements) { for (VertexAttribSpec element : this.elements) {
element.registerForBuffer(stride, index, offset); element.registerForBuffer(stride, index, offset);
index += element.getAttributeCount(); index += element.getAttributeCount();
offset += element.getSize(); offset += element.getSize();

View File

@ -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<AttributeGroup> 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<AttributeGroup> 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);
}
}

View File

@ -135,10 +135,13 @@ public class Backend {
refresh(); refresh();
programs.values().forEach(GlProgram::delete); if (isCapable()) {
programs.clear();
for (ProgramSpec<?> shader : registry.values()) { programs.values().forEach(GlProgram::delete);
loadProgram(manager, shader); programs.clear();
for (ProgramSpec<?> shader : registry.values()) {
loadProgram(manager, shader);
}
} }
} }
} }

View File

@ -3,17 +3,17 @@ package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry; import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import com.simibubi.create.foundation.render.gl.GlPrimitiveType; 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.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.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import java.nio.ByteBuffer; 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<BeltData> { public class BeltData extends KineticData<BeltData> {
public static final VertexAttribute TARGET_UV = copy("scrollTexture", CommonAttributes.VEC4); public static final VertexAttribSpec TARGET_UV = copy(CommonAttributes.VEC4);
public static final VertexAttribute SCROLL_MULT = new VertexAttribute("scrollMult", GlPrimitiveType.BYTE, 1, true); 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); public static VertexFormat FORMAT = new VertexFormat(KineticData.FORMAT, CommonAttributes.ROTATION, CommonAttributes.UV, TARGET_UV, SCROLL_MULT);

View File

@ -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.GlBuffer;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat; import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import org.lwjgl.opengl.GL20;
public abstract class DynamicInstancedModel<S extends InstanceData, D extends InstanceData> extends InstancedModel<S> { public abstract class DynamicInstancedModel<S extends InstanceData, D extends InstanceData> extends InstancedModel<S> {
@ -15,9 +16,9 @@ public abstract class DynamicInstancedModel<S extends InstanceData, D extends In
} }
@Override @Override
protected void setup() { protected void init() {
super.setup(); super.init();
dynamicVBO = new GlBuffer(); dynamicVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER);
} }
protected abstract VertexFormat getDynamicFormat(); protected abstract VertexFormat getDynamicFormat();
@ -29,11 +30,6 @@ public abstract class DynamicInstancedModel<S extends InstanceData, D extends In
return super.getTotalShaderAttributeCount() + getDynamicFormat().getShaderAttributeCount(); return super.getTotalShaderAttributeCount() + getDynamicFormat().getShaderAttributeCount();
} }
@Override
protected void preDrawTask() {
super.preDrawTask();
}
@Override @Override
protected void deleteInternal() { protected void deleteInternal() {
super.deleteInternal(); super.deleteInternal();

View File

@ -3,15 +3,13 @@ package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.BufferedModel; import com.simibubi.create.foundation.render.BufferedModel;
import com.simibubi.create.foundation.render.RenderMath; import com.simibubi.create.foundation.render.RenderMath;
import com.simibubi.create.foundation.render.gl.GlVertexArray;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes; import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat; import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.gl.backend.Backend; import com.simibubi.create.foundation.render.gl.backend.Backend;
import com.simibubi.create.foundation.render.gl.GlBuffer; import com.simibubi.create.foundation.render.gl.GlBuffer;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.*;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL31;
import org.lwjgl.opengl.GL33;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
@ -20,6 +18,7 @@ import java.util.function.Consumer;
public abstract class InstancedModel<D extends InstanceData> extends BufferedModel { public abstract class InstancedModel<D extends InstanceData> extends BufferedModel {
public static final VertexFormat FORMAT = new VertexFormat(CommonAttributes.POSITION, CommonAttributes.NORMAL, CommonAttributes.UV); public static final VertexFormat FORMAT = new VertexFormat(CommonAttributes.POSITION, CommonAttributes.NORMAL, CommonAttributes.UV);
protected GlVertexArray vao;
protected GlBuffer instanceVBO; protected GlBuffer instanceVBO;
protected int glBufferSize = -1; protected int glBufferSize = -1;
protected int glInstanceCount = 0; protected int glInstanceCount = 0;
@ -34,32 +33,21 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
} }
@Override @Override
protected void setup() { protected void init() {
super.setup(); vao = new GlVertexArray();
instanceVBO = new GlBuffer(); instanceVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER);
vao.bind();
super.init();
vao.unbind();
} }
@Override @Override
protected VertexFormat getModelFormat() { protected void initModel() {
return FORMAT; 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() { public int instanceCount() {
return data.size(); return data.size();
} }
@ -69,9 +57,11 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
} }
protected void deleteInternal() { protected void deleteInternal() {
super.deleteInternal();
instanceVBO.delete();
keys.forEach(InstanceKey::invalidate); keys.forEach(InstanceKey::invalidate);
super.deleteInternal();
instanceVBO.delete();
vao.delete();
} }
protected abstract D newInstance(); protected abstract D newInstance();
@ -117,40 +107,14 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
return key; return key;
} }
protected void markIndexChanged(int index) { protected void doRender() {
if (minIndexChanged < 0) { vao.bind();
minIndexChanged = index; renderSetup();
} else if (index < minIndexChanged) { GL31.glDrawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount);
minIndexChanged = index; vao.unbind();
}
if (maxIndexChanged < 0) {
maxIndexChanged = index;
} else if (index > maxIndexChanged) {
maxIndexChanged = index;
}
} }
protected final void verifyKey(InstanceKey<D> key) { protected void renderSetup() {
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() {
if (minIndexChanged < 0 || data.isEmpty()) return; if (minIndexChanged < 0 || data.isEmpty()) return;
VertexFormat instanceFormat = getInstanceFormat(); VertexFormat instanceFormat = getInstanceFormat();
@ -159,7 +123,7 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
int newInstanceCount = instanceCount(); int newInstanceCount = instanceCount();
int instanceSize = RenderMath.nextPowerOf2((newInstanceCount + 1) * stride); 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. // this probably changes enough that it's not worth reallocating the entire buffer every time.
if (instanceSize > glBufferSize) { if (instanceSize > glBufferSize) {
@ -197,9 +161,58 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
GL33.glVertexAttribDivisor(i + staticAttributes, 1); GL33.glVertexAttribDivisor(i + staticAttributes, 1);
} }
instanceVBO.unbind(GL15.GL_ARRAY_BUFFER); instanceVBO.unbind();
minIndexChanged = -1; minIndexChanged = -1;
maxIndexChanged = -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<D> 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();
}
} }

View File

@ -117,7 +117,5 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
if (material.canRenderInLayer(layer)) if (material.canRenderInLayer(layer))
material.render(layer, viewProjection, camX, camY, camZ, callback); material.render(layer, viewProjection, camX, camY, camZ, callback);
} }
GL20.glUseProgram(0);
} }
} }

View File

@ -2,7 +2,7 @@ package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; 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.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.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.Vector3f;
@ -10,12 +10,12 @@ import net.minecraft.util.math.BlockPos;
import java.nio.ByteBuffer; 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<D extends KineticData<D>> extends InstanceData { public class KineticData<D extends KineticData<D>> extends InstanceData {
public static final VertexAttribute ROTATION_CENTER = copy("rotationCenter", CommonAttributes.VEC3); public static final VertexAttribSpec ROTATION_CENTER = copy(CommonAttributes.VEC3);
public static final VertexAttribute SPEED = copy("speed", CommonAttributes.FLOAT); public static final VertexAttribSpec SPEED = copy(CommonAttributes.FLOAT);
public static final VertexAttribute OFFSET = copy("offset", 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); public static final VertexFormat FORMAT = new VertexFormat(CommonAttributes.INSTANCE_POSITION, CommonAttributes.LIGHT, CommonAttributes.RGB, SPEED, OFFSET);
private float x; private float x;