diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntityRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntityRenderer.java index d9d22dc20..be0afe739 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntityRenderer.java @@ -25,7 +25,13 @@ public abstract class AbstractContraptionEntityRenderer { + 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); diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/ContraptionLighter.java b/src/main/java/com/simibubi/create/foundation/utility/render/ContraptionLighter.java index 6641f528e..d4907f697 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/ContraptionLighter.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/ContraptionLighter.java @@ -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); diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/FastContraptionRenderer.java b/src/main/java/com/simibubi/create/foundation/utility/render/FastContraptionRenderer.java index fe42d7368..8aeaa533c 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/FastContraptionRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/FastContraptionRenderer.java @@ -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 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(); diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/FastKineticRenderer.java b/src/main/java/com/simibubi/create/foundation/utility/render/FastKineticRenderer.java index 11a0bbf2e..c014d274d 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/FastKineticRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/FastKineticRenderer.java @@ -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, Cache> rotating; Map, Cache> belts; - Queue 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(); }); } diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/RenderWork.java b/src/main/java/com/simibubi/create/foundation/utility/render/RenderWork.java new file mode 100644 index 000000000..d11e11433 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/render/RenderWork.java @@ -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 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); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/TemplateBuffer.java b/src/main/java/com/simibubi/create/foundation/utility/render/TemplateBuffer.java index 109b1f94c..e526fe3b5 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/TemplateBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/TemplateBuffer.java @@ -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); diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/instancing/InstanceBuffer.java b/src/main/java/com/simibubi/create/foundation/utility/render/instancing/InstanceBuffer.java index e849f5dfa..5a4bd4c14 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/instancing/InstanceBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/instancing/InstanceBuffer.java @@ -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 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 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 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