begin 2.0 compatibility push, probably not going to be ready for the next release
This commit is contained in:
parent
e93562569b
commit
02114b1d9a
21 changed files with 249 additions and 317 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package com.simibubi.create.foundation.render.gl.attrib;
|
||||
|
||||
public interface IVertexAttrib {
|
||||
|
||||
String attribName();
|
||||
|
||||
VertexAttribSpec attribSpec();
|
||||
|
||||
int getDivisor();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue