Only contraptions use EBOs now.

Tight light bounds for bearing contraptions.
This commit is contained in:
JozsefA 2021-02-27 21:35:45 -08:00
parent 884f19d518
commit 55f1b538b5
4 changed files with 110 additions and 69 deletions

View file

@ -19,25 +19,13 @@ public class BearingLighter extends ContraptionLighter<BearingContraption> {
Set<BlockPos> blocks = contraption.getBlocks().keySet();
Direction orientation = contraption.facing;
float maxDistanceSq = -1;
for (BlockPos pos : blocks) {
float x = pos.getX();
float y = pos.getY();
float z = pos.getZ();
float distSq = x * x + y * y + z * z;
if (distSq > maxDistanceSq) maxDistanceSq = distSq;
}
int radius = (int) (Math.ceil(Math.sqrt(maxDistanceSq)));
GridAlignedBB betterBounds = GridAlignedBB.ofRadius(radius);
GridAlignedBB contraptionBounds = GridAlignedBB.fromAABB(contraption.bounds);
Direction.Axis axis = orientation.getAxis();
int radius = (int) (Math.ceil(Math.sqrt(getRadius(blocks, axis))));
GridAlignedBB betterBounds = GridAlignedBB.ofRadius(radius);
GridAlignedBB contraptionBounds = GridAlignedBB.fromAABB(contraption.bounds);
if (axis == Direction.Axis.X) {
betterBounds.maxX = contraptionBounds.maxX;
betterBounds.minX = contraptionBounds.minX;
@ -52,4 +40,36 @@ public class BearingLighter extends ContraptionLighter<BearingContraption> {
betterBounds.translate(contraption.anchor);
return betterBounds;
}
private static float getRadius(Set<BlockPos> blocks, Direction.Axis axis) {
switch (axis) {
case X:
return getMaxDistSqr(blocks, BlockPos::getY, BlockPos::getZ);
case Y:
return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getZ);
case Z:
return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getY);
}
throw new IllegalStateException("Impossible axis");
}
private static float getMaxDistSqr(Set<BlockPos> blocks, Coordinate one, Coordinate other) {
float maxDistSq = -1;
for (BlockPos pos : blocks) {
float a = one.get(pos);
float b = other.get(pos);
float distSq = a * a + b * b;
if (distSq > maxDistSq) maxDistSq = distSq;
}
return maxDistSq;
}
private interface Coordinate {
float get(BlockPos from);
}
}

View file

@ -3,20 +3,69 @@ package com.simibubi.create.content.contraptions.components.structureMovement.re
import java.nio.ByteBuffer;
import com.simibubi.create.foundation.render.backend.BufferedModel;
import com.simibubi.create.foundation.render.backend.gl.GlBuffer;
import com.simibubi.create.foundation.render.backend.gl.GlPrimitiveType;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.LightTexture;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
public class ContraptionModel extends BufferedModel {
public static final VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(ContraptionVertexAttributes.class)
.build();
protected GlPrimitiveType eboIndexType;
protected GlBuffer ebo;
public ContraptionModel(BufferBuilder buf) {
super(buf);
}
@Override
protected void init() {
super.init();
createEBO();
}
@Override
protected void doRender() {
modelVBO.bind();
ebo.bind();
setupAttributes();
GL20.glDrawElements(GL20.GL_QUADS, vertexCount, eboIndexType.getGlConstant(), 0);
int numAttributes = getTotalShaderAttributeCount();
for (int i = 0; i <= numAttributes; i++) {
GL20.glDisableVertexAttribArray(i);
}
ebo.unbind();
modelVBO.unbind();
}
protected final void createEBO() {
ebo = new GlBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER);
eboIndexType = GlPrimitiveType.UINT; // TODO: choose this based on the number of vertices
int indicesSize = vertexCount * eboIndexType.getSize();
ebo.bind();
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, GL15.GL_STATIC_DRAW);
ebo.map(indicesSize, indices -> {
for (int i = 0; i < vertexCount; i++) {
indices.putInt(i);
}
});
ebo.unbind();
}
@Override
protected void copyVertex(ByteBuffer to, int vertex) {
to.putFloat(getX(template, vertex));
@ -48,4 +97,10 @@ public class ContraptionModel extends BufferedModel {
protected VertexFormat getModelFormat() {
return FORMAT;
}
@Override
protected void deleteInternal() {
super.deleteInternal();
ebo.delete();
}
}

View file

@ -14,11 +14,10 @@ import net.minecraft.client.renderer.BufferBuilder;
public abstract class BufferedModel extends TemplateBuffer {
protected GlBuffer ebo;
protected GlBuffer modelVBO;
protected boolean removed;
public BufferedModel(BufferBuilder buf) {
protected BufferedModel(BufferBuilder buf) {
super(buf);
if (vertexCount > 0) init();
}
@ -28,8 +27,6 @@ public abstract class BufferedModel extends TemplateBuffer {
modelVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER);
modelVBO.with(vbo -> initModel());
ebo = createEBO();
}
protected void initModel() {
@ -47,25 +44,6 @@ public abstract class BufferedModel extends TemplateBuffer {
});
}
protected final GlBuffer createEBO() {
GlBuffer ebo = new GlBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER);
int indicesSize = vertexCount * GlPrimitiveType.UINT.getSize();
ebo.bind();
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, GL15.GL_STATIC_DRAW);
ebo.map(indicesSize, indices -> {
for (int i = 0; i < vertexCount; i++) {
indices.putInt(i);
}
});
ebo.unbind();
return ebo;
}
protected abstract void copyVertex(ByteBuffer to, int index);
protected abstract VertexFormat getModelFormat();
@ -75,7 +53,7 @@ public abstract class BufferedModel extends TemplateBuffer {
}
/**
* Renders this model, checking first if it should actually be rendered.
* Renders this model, checking first if there is anything to render.
*/
public final void render() {
if (vertexCount == 0 || removed) return;
@ -84,23 +62,9 @@ public abstract class BufferedModel extends TemplateBuffer {
}
/**
* Override this.
* Set up any state and make the draw calls.
*/
protected void doRender() {
modelVBO.bind();
ebo.bind();
setupAttributes();
GL20.glDrawElements(GL20.GL_QUADS, vertexCount, GlPrimitiveType.UINT.getGlConstant(), 0);
int numAttributes = getTotalShaderAttributeCount();
for (int i = 0; i <= numAttributes; i++) {
GL20.glDisableVertexAttribArray(i);
}
ebo.unbind();
modelVBO.unbind();
}
protected abstract void doRender();
protected void setupAttributes() {
int numAttributes = getTotalShaderAttributeCount();
@ -111,7 +75,7 @@ public abstract class BufferedModel extends TemplateBuffer {
getModelFormat().vertexAttribPointers(0);
}
public void delete() {
public final void delete() {
removed = true;
if (vertexCount > 0) {
RenderWork.enqueue(this::deleteInternal);

View file

@ -2,25 +2,27 @@ package com.simibubi.create.foundation.render.backend.gl;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
@OnlyIn(Dist.CLIENT)
public enum GlPrimitiveType {
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);
FLOAT(4, "float", GL11.GL_FLOAT),
UBYTE(1, "ubyte", GL11.GL_UNSIGNED_BYTE),
BYTE(1, "byte", GL11.GL_BYTE),
USHORT(2, "ushort", GL11.GL_UNSIGNED_SHORT),
SHORT(2, "short", GL11.GL_SHORT),
UINT(4, "uint", GL11.GL_UNSIGNED_INT),
INT(4, "int", GL11.GL_INT);
private final int size;
private final String displayName;
private final int glConstant;
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_;
GlPrimitiveType(int bytes, String name, int glEnum) {
this.size = bytes;
this.displayName = name;
this.glConstant = glEnum;
}
public int getSize() {