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.
* 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);
}

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 net.minecraft.util.ResourceLocation;
import static com.simibubi.create.foundation.render.gl.backend.Backend.register;
public class AllProgramSpecs {
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));
@ -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_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 final ResourceLocation INSTANCED = loc("instanced.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;
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();
}
}

View file

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

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

View file

@ -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) {

View file

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

View file

@ -5,14 +5,14 @@ import java.util.ArrayList;
public class AttributeGroup {
private final int divisor;
private final ArrayList<VertexAttribute> attributes;
private final ArrayList<VertexAttribSpec> 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<VertexAttribute> getAttributes() {
public ArrayList<VertexAttribSpec> getAttributes() {
return attributes;
}
}

View file

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

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

View file

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

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,6 +135,8 @@ public class Backend {
refresh();
if (isCapable()) {
programs.values().forEach(GlProgram::delete);
programs.clear();
for (ProgramSpec<?> shader : registry.values()) {
@ -142,6 +144,7 @@ public class Backend {
}
}
}
}
public static void refresh() {
if (capabilities.OpenGL33) {

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.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<BeltData> {
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);

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.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
import org.lwjgl.opengl.GL20;
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
protected void setup() {
super.setup();
dynamicVBO = new GlBuffer();
protected void init() {
super.init();
dynamicVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER);
}
protected abstract VertexFormat getDynamicFormat();
@ -29,11 +30,6 @@ public abstract class DynamicInstancedModel<S extends InstanceData, D extends In
return super.getTotalShaderAttributeCount() + getDynamicFormat().getShaderAttributeCount();
}
@Override
protected void preDrawTask() {
super.preDrawTask();
}
@Override
protected void 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.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.VertexFormat;
import com.simibubi.create.foundation.render.gl.backend.Backend;
import com.simibubi.create.foundation.render.gl.GlBuffer;
import net.minecraft.client.renderer.BufferBuilder;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL31;
import org.lwjgl.opengl.GL33;
import org.lwjgl.opengl.*;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@ -20,6 +18,7 @@ import java.util.function.Consumer;
public abstract class InstancedModel<D extends InstanceData> 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<D extends InstanceData> 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<D extends InstanceData> 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<D extends InstanceData> extends BufferedMod
return key;
}
protected void markIndexChanged(int index) {
if (minIndexChanged < 0) {
minIndexChanged = index;
} else if (index < minIndexChanged) {
minIndexChanged = index;
protected void doRender() {
vao.bind();
renderSetup();
GL31.glDrawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount);
vao.unbind();
}
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!!");
}
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<D extends InstanceData> 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<D extends InstanceData> 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<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))
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.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<D extends KineticData<D>> 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;