reorganize some stuff

cart contraptions should at least be positioned correctly
maybe fix a bunch of memory leaks
This commit is contained in:
JozsefA 2021-01-09 21:59:11 -08:00
parent d2173614dc
commit 092a92f095
11 changed files with 119 additions and 91 deletions

View file

@ -25,7 +25,13 @@ public abstract class AbstractContraptionEntityRenderer<C extends AbstractContra
protected abstract void transform(C contraptionEntity, float partialTicks, MatrixStack[] matrixStacks);
public abstract Vec3d getPosition(C contraptionEntity, float partialTicks);
public Vec3d getPosition(C entity, float partialTicks) {
double x = MathHelper.lerp(partialTicks, entity.lastTickPosX, entity.getX());
double y = MathHelper.lerp(partialTicks, entity.lastTickPosY, entity.getY());
double z = MathHelper.lerp(partialTicks, entity.lastTickPosZ, entity.getZ());
return new Vec3d(x, y, z);
}
public abstract Vec3d getRotation(C contraptionEntity, float partialTicks);
@Override

View file

@ -28,13 +28,6 @@ public class ControlledContraptionEntityRenderer extends AbstractContraptionEnti
.unCentre();
}
public Vec3d getPosition(ControlledContraptionEntity entity, float partialTicks) {
double x = MathHelper.lerp(partialTicks, entity.lastTickPosX, entity.getX());
double y = MathHelper.lerp(partialTicks, entity.lastTickPosY, entity.getY());
double z = MathHelper.lerp(partialTicks, entity.lastTickPosZ, entity.getZ());
return new Vec3d(x, y, z);
}
public Vec3d getRotation(ControlledContraptionEntity entity, float partialTicks) {
Axis axis = entity.getRotationAxis();
if (axis == null) return Vec3d.ZERO;

View file

@ -7,6 +7,7 @@ import net.minecraft.client.renderer.culling.ClippingHelperImpl;
import net.minecraft.client.renderer.entity.EntityRendererManager;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
@ -39,7 +40,7 @@ public class OrientedContraptionEntityRenderer extends AbstractContraptionEntity
Entity ridingEntity = entity.getRidingEntity();
if (ridingEntity instanceof AbstractMinecartEntity)
repositionOnCart(partialTicks, matrixStacks, ridingEntity);
if (ridingEntity instanceof AbstractContraptionEntity) {
else if (ridingEntity instanceof AbstractContraptionEntity) {
if (ridingEntity.getRidingEntity() instanceof AbstractMinecartEntity)
repositionOnCart(partialTicks, matrixStacks, ridingEntity.getRidingEntity());
else
@ -58,53 +59,59 @@ public class OrientedContraptionEntityRenderer extends AbstractContraptionEntity
@Override
public Vec3d getPosition(OrientedContraptionEntity entity, float partialTicks) {
Vec3d offset = Vec3d.ZERO;
return Vec3d.ZERO;
Entity ridingEntity = entity.getRidingEntity();
if (ridingEntity instanceof AbstractMinecartEntity)
offset = getCartOffset(partialTicks, ridingEntity);
else if (ridingEntity instanceof AbstractContraptionEntity) {
if (ridingEntity.getRidingEntity() instanceof AbstractMinecartEntity)
offset = getCartOffset(partialTicks, ridingEntity.getRidingEntity());
else
offset = getContraptionOffset(entity, partialTicks, ridingEntity);
}
@Override
public Vec3d getRotation(OrientedContraptionEntity contraptionEntity, float partialTicks) {
return Vec3d.ZERO;
Vec3d pos = super.getPosition(entity, partialTicks);
return new Vec3d(pos.x + offset.x - 0.5, pos.y + offset.y, pos.z + offset.z - 0.5);
}
public Vec3d getRotation(OrientedContraptionEntity entity, float partialTicks) {
float angleInitialYaw = entity.getInitialYaw();
float angleYaw = entity.getYaw(partialTicks);
float anglePitch = entity.getPitch(partialTicks);
return new Vec3d(0, angleInitialYaw + angleYaw, anglePitch);
}
private void repositionOnContraption(OrientedContraptionEntity entity, float partialTicks,
MatrixStack[] matrixStacks, Entity ridingEntity) {
AbstractContraptionEntity parent = (AbstractContraptionEntity) ridingEntity;
Vec3d passengerPosition = parent.getPassengerPosition(entity, partialTicks);
double x = passengerPosition.x - MathHelper.lerp(partialTicks, entity.lastTickPosX, entity.getX());
double y = passengerPosition.y - MathHelper.lerp(partialTicks, entity.lastTickPosY, entity.getY());
double z = passengerPosition.z - MathHelper.lerp(partialTicks, entity.lastTickPosZ, entity.getZ());
Vec3d pos = getContraptionOffset(entity, partialTicks, ridingEntity);
for (MatrixStack stack : matrixStacks)
stack.translate(x, y, z);
stack.translate(pos.x, pos.y, pos.z);
}
// Minecarts do not always render at their exact location, so the contraption
// has to adjust aswell
private void repositionOnCart(float partialTicks, MatrixStack[] matrixStacks, Entity ridingEntity) {
AbstractMinecartEntity cart = (AbstractMinecartEntity) ridingEntity;
double cartX = MathHelper.lerp(partialTicks, cart.lastTickPosX, cart.getX());
double cartY = MathHelper.lerp(partialTicks, cart.lastTickPosY, cart.getY());
double cartZ = MathHelper.lerp(partialTicks, cart.lastTickPosZ, cart.getZ());
Vec3d cartPos = cart.getPos(cartX, cartY, cartZ);
Vec3d cartPos = getCartOffset(partialTicks, ridingEntity);
if (cartPos != null) {
Vec3d cartPosFront = cart.getPosOffset(cartX, cartY, cartZ, (double) 0.3F);
Vec3d cartPosBack = cart.getPosOffset(cartX, cartY, cartZ, (double) -0.3F);
if (cartPosFront == null)
cartPosFront = cartPos;
if (cartPosBack == null)
cartPosBack = cartPos;
cartX = cartPos.x - cartX;
cartY = (cartPosFront.y + cartPosBack.y) / 2.0D - cartY;
cartZ = cartPos.z - cartZ;
if (cartPos == Vec3d.ZERO) return;
for (MatrixStack stack : matrixStacks)
stack.translate(cartX, cartY, cartZ);
}
stack.translate(cartPos.x, cartPos.y, cartPos.z);
}
private Vec3d getCartPosition(float partialTicks, Entity ridingEntity) {
private Vec3d getContraptionOffset(OrientedContraptionEntity entity, float partialTicks, Entity ridingEntity) {
AbstractContraptionEntity parent = (AbstractContraptionEntity) ridingEntity;
Vec3d passengerPosition = parent.getPassengerPosition(entity, partialTicks);
double x = passengerPosition.x - MathHelper.lerp(partialTicks, entity.lastTickPosX, entity.getX());
double y = passengerPosition.y - MathHelper.lerp(partialTicks, entity.lastTickPosY, entity.getY());
double z = passengerPosition.z - MathHelper.lerp(partialTicks, entity.lastTickPosZ, entity.getZ());
return new Vec3d(x, y, z);
}
private Vec3d getCartOffset(float partialTicks, Entity ridingEntity) {
AbstractMinecartEntity cart = (AbstractMinecartEntity) ridingEntity;
double cartX = MathHelper.lerp(partialTicks, cart.lastTickPosX, cart.getX());
double cartY = MathHelper.lerp(partialTicks, cart.lastTickPosY, cart.getY());
@ -122,9 +129,11 @@ public class OrientedContraptionEntityRenderer extends AbstractContraptionEntity
cartX = cartPos.x - cartX;
cartY = (cartPosFront.y + cartPosBack.y) / 2.0D - cartY;
cartZ = cartPos.z - cartZ;
}
return new Vec3d(cartX, cartY, cartZ);
}
return Vec3d.ZERO;
}
}

View file

@ -33,6 +33,7 @@ import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
import com.simibubi.create.foundation.utility.render.FastContraptionRenderer;
import com.simibubi.create.foundation.utility.render.RenderWork;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -135,6 +136,8 @@ public class ClientEvents {
buffer.draw();
ms.pop();
RenderWork.runAll();
}
@SubscribeEvent

View file

@ -8,6 +8,8 @@ import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import org.lwjgl.opengl.*;
import org.lwjgl.system.MemoryUtil;
import static com.simibubi.create.foundation.utility.render.instancing.VertexAttribute.*;
import java.nio.Buffer;
@ -23,8 +25,8 @@ public class ContraptionBuffer extends TemplateBuffer {
setup();
}
public void invalidate() {
CreateClient.kineticRenderer.enqueue(() -> {
public void delete() {
RenderWork.enqueue(() -> {
GL15.glDeleteBuffers(vbo);
GL15.glDeleteBuffers(ebo);
GL30.glDeleteVertexArrays(vao);
@ -95,9 +97,11 @@ public class ContraptionBuffer extends TemplateBuffer {
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, vbo);
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, constant, GL15.GL_STATIC_DRAW);
MemoryUtil.memFree(constant);
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
GlStateManager.bufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);
MemoryUtil.memFree(indices);
FORMAT.informAttributes(0);

View file

@ -1,36 +1,32 @@
package com.simibubi.create.foundation.utility.render;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.LightType;
import net.minecraft.world.World;
import net.minecraft.world.lighting.WorldLightManager;
import org.lwjgl.opengl.*;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.util.Set;
public class ContraptionLighter {
int minX;
int minY;
int minZ;
private int minX;
private int minY;
private int minZ;
int sizeX;
int sizeY;
int sizeZ;
private final int sizeX;
private final int sizeY;
private final int sizeZ;
ByteBuffer lightVolume;
private ByteBuffer lightVolume;
boolean dirty;
private boolean dirty;
int texture;
private int texture;
public ContraptionLighter(Contraption contraption) {
texture = GL11.glGenTextures();
@ -50,7 +46,7 @@ public class ContraptionLighter {
lightVolume = GLAllocation.createDirectByteBuffer(sizeX * sizeY * sizeZ * 2);
tick(contraption);
update(contraption);
}
public static int nextPowerOf2(int a) {
@ -83,8 +79,11 @@ public class ContraptionLighter {
}
public void delete() {
CreateClient.kineticRenderer.enqueue(() -> {
RenderWork.enqueue(() -> {
GL15.glDeleteTextures(texture);
texture = 0;
MemoryUtil.memFree(lightVolume);
lightVolume = null;
});
}
@ -95,7 +94,9 @@ public class ContraptionLighter {
minZ = (int) (Math.floor(positionVec.z) - sizeZ / 2);
}
public void tick(Contraption c) {
public void update(Contraption c) {
if (lightVolume == null) return;
setupPosition(c);
World world = c.entity.world;
@ -129,6 +130,8 @@ public class ContraptionLighter {
}
public void use() {
if (texture == 0 || lightVolume == null) return;
GL13.glEnable(GL31.GL_TEXTURE_3D);
GL13.glActiveTexture(GL40.GL_TEXTURE0 + 4);
GL12.glBindTexture(GL12.GL_TEXTURE_3D, texture);

View file

@ -1,7 +1,5 @@
package com.simibubi.create.foundation.utility.render;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
@ -10,20 +8,14 @@ import com.simibubi.create.foundation.utility.render.shader.Shader;
import com.simibubi.create.foundation.utility.render.shader.ShaderHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.color.BlockColors;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL40;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
public class FastContraptionRenderer extends ContraptionRenderer {
@ -48,9 +40,9 @@ public class FastContraptionRenderer extends ContraptionRenderer {
public static void tick() {
if (Minecraft.getInstance().isGamePaused()) return;
CreateClient.kineticRenderer.enqueue(() -> {
RenderWork.enqueue(() -> {
for (FastContraptionRenderer renderer : renderers.values()) {
renderer.lighter.tick(renderer.c);
renderer.lighter.update(renderer.c);
}
});
}
@ -101,7 +93,11 @@ public class FastContraptionRenderer extends ContraptionRenderer {
}
private void buildLayers() {
invalidate();
for (ContraptionBuffer buffer : renderLayers) {
buffer.delete();
}
renderLayers.clear();
List<RenderType> blockLayers = RenderType.getBlockLayers();
@ -112,8 +108,9 @@ public class FastContraptionRenderer extends ContraptionRenderer {
private void invalidate() {
for (ContraptionBuffer buffer : renderLayers) {
buffer.invalidate();
buffer.delete();
}
lighter.delete();
renderLayers.clear();

View file

@ -12,7 +12,6 @@ import com.simibubi.create.foundation.utility.render.shader.ShaderCallback;
import com.simibubi.create.foundation.utility.render.shader.ShaderHelper;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientChunkProvider;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.texture.Texture;
@ -29,7 +28,6 @@ import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL40;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
@ -40,14 +38,11 @@ public class FastKineticRenderer {
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, RotatingBuffer>> rotating;
Map<SuperByteBufferCache.Compartment<?>, Cache<Object, BeltBuffer>> belts;
Queue<Runnable> runs;
boolean rebuild;
public FastKineticRenderer() {
rotating = new HashMap<>();
belts = new HashMap<>();
runs = new ConcurrentLinkedQueue<>();
registerCompartment(SuperByteBufferCache.GENERIC_TILE);
registerCompartment(SuperByteBufferCache.PARTIAL);
registerCompartment(SuperByteBufferCache.DIRECTIONAL_PARTIAL);
@ -91,10 +86,6 @@ public class FastKineticRenderer {
// rebuild = true;
}
public void enqueue(Runnable run) {
runs.add(run);
}
public void renderInstances(RenderWorldLastEvent event) {
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
//
@ -126,10 +117,6 @@ public class FastKineticRenderer {
ShaderHelper.releaseShader();
teardown();
while (!runs.isEmpty()) {
runs.remove().run();
}
}
public void setup(GameRenderer gameRenderer) {
@ -254,12 +241,12 @@ public class FastKineticRenderer {
public void invalidate() {
rotating.values().forEach(cache -> {
cache.asMap().values().forEach(InstanceBuffer::invalidate);
cache.asMap().values().forEach(InstanceBuffer::delete);
cache.invalidateAll();
});
belts.values().forEach(cache -> {
cache.asMap().values().forEach(InstanceBuffer::invalidate);
cache.asMap().values().forEach(InstanceBuffer::delete);
cache.invalidateAll();
});
}

View file

@ -0,0 +1,21 @@
package com.simibubi.create.foundation.utility.render;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
public class RenderWork {
private static final Queue<Runnable> runs = new ConcurrentLinkedQueue<>();
public static void runAll() {
while (!runs.isEmpty()) {
runs.remove().run();
}
}
/**
* Queue work to be executed at the end of a frame
*/
public static void enqueue(Runnable run) {
runs.add(run);
}
}

View file

@ -23,7 +23,7 @@ public class TemplateBuffer {
count = state.getFirst().getCount();
int size = count * formatSize;
template = GLAllocation.createDirectByteBuffer(size);
template = ByteBuffer.allocate(size);
template.order(rendered.order());
((Buffer)template).limit(((Buffer)rendered).limit());
template.put(rendered);

View file

@ -3,11 +3,13 @@ package com.simibubi.create.foundation.utility.render.instancing;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.utility.render.RenderWork;
import com.simibubi.create.foundation.utility.render.TemplateBuffer;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import org.lwjgl.opengl.*;
import org.lwjgl.system.MemoryUtil;
import java.nio.Buffer;
import java.nio.ByteBuffer;
@ -69,9 +71,11 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, invariantVBO);
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, constant, GL15.GL_STATIC_DRAW);
MemoryUtil.memFree(constant);
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
GlStateManager.bufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);
MemoryUtil.memFree(indices);
FORMAT.informAttributes(0);
@ -96,8 +100,8 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
shouldBuild = true;
}
public void invalidate() {
CreateClient.kineticRenderer.enqueue(() -> {
public void delete() {
RenderWork.enqueue(() -> {
GL15.glDeleteBuffers(invariantVBO);
GL15.glDeleteBuffers(instanceVBO);
GL15.glDeleteBuffers(ebo);
@ -158,10 +162,11 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, instanceVBO);
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
instanceFormat.informAttributes(3);
int staticAttributes = FORMAT.getNumAttributes();
instanceFormat.informAttributes(staticAttributes);
for (int i = 0; i < instanceFormat.getNumAttributes(); i++) {
GL40.glVertexAttribDivisor(i + 3, 1);
GL40.glVertexAttribDivisor(i + staticAttributes, 1);
}
// Deselect (bind to 0) the VBO