From 83cb735e629b99e742e8dab8b382874a357ce2df Mon Sep 17 00:00:00 2001 From: JozsefA Date: Sat, 23 Jan 2021 12:49:33 -0800 Subject: [PATCH] actors render correctly --- .../components/actors/DrillRenderer.java | 3 +- .../components/actors/HarvesterRenderer.java | 3 +- .../simibubi/create/events/ClientEvents.java | 6 ++++ .../render/FastKineticRenderer.java | 11 ++----- .../render/FastRenderDispatcher.java | 18 +++++----- .../create/foundation/render/GPUBuffer.java | 4 ++- .../ContraptionRenderDispatcher.java | 19 ++++------- .../render/instancing/RenderMaterial.java | 33 ++++++++++++------- .../foundation/render/light/LightVolume.java | 17 ++++++---- .../render/shader/ShaderCallback.java | 7 ++++ .../assets/create/shader/contraption.vert | 10 +++++- .../create/shader/contraption_actor.vert | 22 +++++++++---- .../create/shader/contraption_belt.vert | 11 +++++-- .../create/shader/contraption_rotating.vert | 11 +++++-- 14 files changed, 111 insertions(+), 64 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillRenderer.java index e9e267ad9..d3edadc79 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillRenderer.java @@ -49,10 +49,9 @@ public class DrillRenderer extends KineticTileEntityRenderer { model.setupInstance(data -> { Direction facing = state.get(DrillBlock.FACING); - Vector3f orientation = facing.getOpposite().getUnitVector(); data.setPosition(context.localPos) .setRotationOffset(0) - .setRotationAxis(orientation) + .setRotationAxis(0, 0, 1) .setLocalRotation(AngleHelper.verticalAngle(facing), facing.getHorizontalAngle(), 0); }); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterRenderer.java index c07e61054..29a006d6f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/HarvesterRenderer.java @@ -47,13 +47,12 @@ public class HarvesterRenderer extends SafeTileEntityRenderer { Direction facing = state.get(HORIZONTAL_FACING); - Direction rotationAxis = facing.rotateY(); float originOffset = 1 / 16f; Vector3f rotOffset = new Vector3f(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f); data.setPosition(context.localPos) .setRotationOffset(0) .setRotationCenter(rotOffset) - .setRotationAxis(rotationAxis.getUnitVector()) + .setRotationAxis(-1, 0, 0) .setLocalRotation(0, facing.getHorizontalAngle(), 0); }); } diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index dd58db9cd..39a622a52 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -114,6 +114,12 @@ public class ClientEvents { AnimationTickHolder.ticks = 0; } + @SubscribeEvent + public static void onUnloadWorld(WorldEvent.Unload event) { + CreateClient.invalidateRenderers(); + AnimationTickHolder.ticks = 0; + } + @SubscribeEvent public static void onRenderWorld(RenderWorldLastEvent event) { Vec3d cameraPos = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); diff --git a/src/main/java/com/simibubi/create/foundation/render/FastKineticRenderer.java b/src/main/java/com/simibubi/create/foundation/render/FastKineticRenderer.java index a0634c0ac..85a020d00 100644 --- a/src/main/java/com/simibubi/create/foundation/render/FastKineticRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/FastKineticRenderer.java @@ -94,18 +94,11 @@ public class FastKineticRenderer { public void render(RenderType layer, Matrix4f projection, Matrix4f view, ShaderCallback callback) { prepareFrame(); - layer.startDrawing(); - for (RenderMaterial material : materials.values()) { - material.render(projection, view, callback); + if (material.canRenderInLayer(layer)) + material.render(layer, projection, view, callback); } ShaderHelper.releaseShader(); - - layer.endDrawing(); - } - - public static RenderType getKineticRenderLayer() { - return RenderType.getCutoutMipped(); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java index f79c59c74..8ce6ef538 100644 --- a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java @@ -7,6 +7,7 @@ import com.simibubi.create.foundation.render.contraption.ContraptionRenderDispat import com.simibubi.create.foundation.render.instancing.IInstanceRendered; import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; import com.simibubi.create.foundation.render.instancing.InstanceContext; +import com.simibubi.create.foundation.render.shader.ShaderHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.ClientPlayerEntity; @@ -41,17 +42,18 @@ public class FastRenderDispatcher { view.multiplyBackward(stack.peek().getModel()); Matrix4f projection = getProjectionMatrix(); + type.startDrawing(); - if (type == FastKineticRenderer.getKineticRenderLayer()) { - RenderSystem.enableDepthTest(); - RenderSystem.enableCull(); - GL11.glCullFace(GL11.GL_BACK); - CreateClient.kineticRenderer.render(type, projection, view); - RenderSystem.disableCull(); - //RenderSystem.disableDepthTest(); - } + RenderSystem.enableDepthTest(); + RenderSystem.enableCull(); + GL11.glCullFace(GL11.GL_BACK); + CreateClient.kineticRenderer.render(type, projection, view); + RenderSystem.disableCull(); + //RenderSystem.disableDepthTest(); ContraptionRenderDispatcher.renderLayer(type, projection, view); + ShaderHelper.releaseShader(); + type.endDrawing(); } public static void notifyLightUpdate(ClientChunkProvider world, LightType type, SectionPos pos) { diff --git a/src/main/java/com/simibubi/create/foundation/render/GPUBuffer.java b/src/main/java/com/simibubi/create/foundation/render/GPUBuffer.java index 854b814e8..0f7c3e167 100644 --- a/src/main/java/com/simibubi/create/foundation/render/GPUBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/GPUBuffer.java @@ -13,6 +13,7 @@ import java.nio.ByteBuffer; public abstract class GPUBuffer extends TemplateBuffer { protected int vao, ebo, invariantVBO; + protected boolean removed; public GPUBuffer(BufferBuilder buf) { super(buf); @@ -68,7 +69,7 @@ public abstract class GPUBuffer extends TemplateBuffer { } public void render() { - if (vao == 0) return; + if (vao == 0 || removed) return; GL30.glBindVertexArray(vao); preDrawTask(); @@ -91,6 +92,7 @@ public abstract class GPUBuffer extends TemplateBuffer { } public void delete() { + removed = true; if (vertexCount > 0) { RenderWork.enqueue(this::deleteInternal); } diff --git a/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionRenderDispatcher.java b/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionRenderDispatcher.java index 039c3ed27..5f55119fd 100644 --- a/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/foundation/render/contraption/ContraptionRenderDispatcher.java @@ -43,12 +43,12 @@ public class ContraptionRenderDispatcher { return renderer; } - public static void renderLayer(RenderType renderType, Matrix4f projectionMat, Matrix4f viewMat) { + public static void renderLayer(RenderType layer, Matrix4f projectionMat, Matrix4f viewMat) { removeDeadContraptions(); if (renderers.isEmpty()) return; - renderType.startDrawing(); + layer.startDrawing(); GL11.glEnable(GL13.GL_TEXTURE_3D); GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4 @@ -56,20 +56,15 @@ public class ContraptionRenderDispatcher { int structureShader = ShaderHelper.useShader(Shader.CONTRAPTION_STRUCTURE, callback); for (RenderedContraption renderer : renderers.values()) { - renderer.doRenderLayer(renderType, structureShader); + renderer.doRenderLayer(layer, structureShader); } - if (renderType == FastKineticRenderer.getKineticRenderLayer()) { - for (RenderedContraption renderer : renderers.values()) { - renderer.kinetics.render(renderType, projectionMat, viewMat, renderer::setup); - renderer.teardown(); - } + for (RenderedContraption renderer : renderers.values()) { + renderer.kinetics.render(layer, projectionMat, viewMat, renderer::setup); + renderer.teardown(); } - ShaderHelper.releaseShader(); - - - renderType.endDrawing(); + layer.endDrawing(); GL11.glDisable(GL13.GL_TEXTURE_3D); GL13.glActiveTexture(GL40.GL_TEXTURE0); } diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/RenderMaterial.java b/src/main/java/com/simibubi/create/foundation/render/instancing/RenderMaterial.java index 0679ec855..95cf9aa59 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/RenderMaterial.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/RenderMaterial.java @@ -25,6 +25,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.function.Consumer; +import java.util.function.Predicate; import java.util.function.Supplier; import static com.simibubi.create.foundation.render.Compartment.PARTIAL; @@ -34,33 +35,43 @@ public class RenderMaterial> { protected final Map, Cache> models; protected final ModelFactory factory; protected final Shader shader; + protected final Predicate layerPredicate; + /** + * Creates a material that renders in the default layer (CUTOUT_MIPPED) + */ public RenderMaterial(Shader shader, ModelFactory factory) { + this(shader, factory, type -> type == RenderType.getCutoutMipped()); + } + + public RenderMaterial(Shader shader, ModelFactory factory, Predicate layerPredicate) { this.models = new HashMap<>(); this.factory = factory; this.shader = shader; + this.layerPredicate = layerPredicate; registerCompartment(Compartment.PARTIAL); registerCompartment(Compartment.DIRECTIONAL_PARTIAL); registerCompartment(KineticTileEntityRenderer.KINETIC_TILE); } - public void render(Matrix4f projection, Matrix4f view) { - render(projection, view, null); + public boolean canRenderInLayer(RenderType layer) { + return layerPredicate.test(layer); } - public void render(Matrix4f projection, Matrix4f view, ShaderCallback setup) { - int handle = setupShader(projection, view); - if (setup != null) setup.call(handle); + public void render(RenderType layer, Matrix4f projection, Matrix4f view) { + render(layer, projection, view, null); + } + + public void render(RenderType layer, Matrix4f projection, Matrix4f view, ShaderCallback setup) { + ShaderCallback cb = ShaderHelper.getViewProjectionCallback(projection, view); + + if (setup != null) cb = cb.andThen(setup); + + ShaderHelper.useShader(shader, cb); makeRenderCalls(); teardown(); } - protected int setupShader(Matrix4f projection, Matrix4f view) { - ShaderCallback callback = ShaderHelper.getViewProjectionCallback(projection, view); - - return ShaderHelper.useShader(shader, callback); - } - public void teardown() {} public void delete() { diff --git a/src/main/java/com/simibubi/create/foundation/render/light/LightVolume.java b/src/main/java/com/simibubi/create/foundation/render/light/LightVolume.java index aae5a6b28..ac2c89a3c 100644 --- a/src/main/java/com/simibubi/create/foundation/render/light/LightVolume.java +++ b/src/main/java/com/simibubi/create/foundation/render/light/LightVolume.java @@ -9,6 +9,7 @@ import org.lwjgl.opengl.*; import org.lwjgl.system.MemoryUtil; import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicBoolean; // TODO: Don't immediately destroy light volumes. // There's a high chance that a contraption will stop and soon after start again. @@ -20,7 +21,8 @@ public class LightVolume { private final GridAlignedBB textureVolume; private ByteBuffer lightData; - private boolean bufferDirty; + private final AtomicBoolean bufferDirty = new AtomicBoolean(false); + private boolean removed; private int glTexture; @@ -108,7 +110,7 @@ public class LightVolume { writeLight(x - shiftX, y - shiftY, z - shiftZ, blockLight, skyLight); }); - bufferDirty = true; + bufferDirty.set(true); } /** @@ -130,7 +132,7 @@ public class LightVolume { writeBlock(x - xShift, y - yShift, z - zShift, light); }); - bufferDirty = true; + bufferDirty.set(true); } /** @@ -152,12 +154,12 @@ public class LightVolume { writeSky(x - xShift, y - yShift, z - zShift, light); }); - bufferDirty = true; + bufferDirty.set(true); } public void use() { // just in case something goes wrong or we accidentally call this before this volume is properly disposed of. - if (glTexture == 0 || lightData == null) return; + if (glTexture == 0 || lightData == null || removed) return; GL13.glActiveTexture(GL40.GL_TEXTURE4); GL12.glBindTexture(GL12.GL_TEXTURE_3D, glTexture); @@ -166,9 +168,9 @@ public class LightVolume { GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_S, GL20.GL_MIRRORED_REPEAT); GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_R, GL20.GL_MIRRORED_REPEAT); GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_T, GL20.GL_MIRRORED_REPEAT); - if (bufferDirty) { + if (bufferDirty.get()) { GL12.glTexImage3D(GL12.GL_TEXTURE_3D, 0, GL40.GL_RG8, textureVolume.sizeX(), textureVolume.sizeY(), textureVolume.sizeZ(), 0, GL40.GL_RG, GL40.GL_UNSIGNED_BYTE, lightData); - bufferDirty = false; + bufferDirty.set(false); } } @@ -177,6 +179,7 @@ public class LightVolume { } public void delete() { + removed = true; RenderWork.enqueue(() -> { GL15.glDeleteTextures(glTexture); glTexture = 0; diff --git a/src/main/java/com/simibubi/create/foundation/render/shader/ShaderCallback.java b/src/main/java/com/simibubi/create/foundation/render/shader/ShaderCallback.java index 0474da770..4c950f355 100644 --- a/src/main/java/com/simibubi/create/foundation/render/shader/ShaderCallback.java +++ b/src/main/java/com/simibubi/create/foundation/render/shader/ShaderCallback.java @@ -7,4 +7,11 @@ package com.simibubi.create.foundation.render.shader; public interface ShaderCallback { void call(int shader); + + default ShaderCallback andThen(ShaderCallback other) { + return i -> { + call(i); + other.call(i); + }; + } } diff --git a/src/main/resources/assets/create/shader/contraption.vert b/src/main/resources/assets/create/shader/contraption.vert index e68ed3c54..edd750914 100644 --- a/src/main/resources/assets/create/shader/contraption.vert +++ b/src/main/resources/assets/create/shader/contraption.vert @@ -42,9 +42,17 @@ float diffuse(vec3 normal) { void main() { vec4 worldPos = model * vec4(aPos, 1); + vec3 norm = (model * vec4(aNormal, 0.)).xyz; + BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize; - Diffuse = diffuse((model * vec4(aNormal, 0.)).xyz); + Diffuse = diffuse(norm); Color = aColor / diffuse(aNormal); TexCoords = aTexCoords; gl_Position = projection * view * worldPos; + + if (debug == 2) { + Color = vec4(norm, 1); + } else { + Color = aColor / diffuse(aNormal); + } } diff --git a/src/main/resources/assets/create/shader/contraption_actor.vert b/src/main/resources/assets/create/shader/contraption_actor.vert index 94083048e..be74dba37 100644 --- a/src/main/resources/assets/create/shader/contraption_actor.vert +++ b/src/main/resources/assets/create/shader/contraption_actor.vert @@ -46,7 +46,7 @@ mat4 rotation(vec3 rot) { } mat4 kineticRotation() { - const float speed = 20; + const float speed = -20; float degrees = rotationOffset + time * speed * -3./10.; float angle = fract(degrees / 360.) * PI * 2.; @@ -61,18 +61,26 @@ float diffuse(vec3 normal) { } void main() { + mat4 kineticRotation = kineticRotation(); + vec4 localPos = kineticRotation * vec4(aPos - rotationCenter, 1) + vec4(rotationCenter, 0); + //localPos = vec4(localPos.xyz + instancePos, 1); + vec3 rot = fract(localRotation / 360.) * PI * 2.; mat4 localRot = rotation(rot); - vec4 localPos = localRot * vec4(aPos - 0.5, 1f) + vec4(0.5, 0.5, 0.5, 0); - - mat4 kineticRotation = kineticRotation(); - localPos = kineticRotation * vec4(localPos.xyz - rotationCenter, 1) + vec4(instancePos + rotationCenter, 0); + localPos = localRot * vec4(localPos.xyz - 0.5, 1f) + vec4(instancePos + 0.5, 0); vec4 worldPos = model * localPos; + vec3 norm = normalize(model * localRot * kineticRotation * vec4(aNormal, 0.)).xyz; + BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize; - Diffuse = diffuse(normalize(model * localRot * kineticRotation * vec4(aNormal, 0.)).xyz); - Color = vec4(1.); + Diffuse = diffuse(norm); TexCoords = aTexCoords; gl_Position = projection * view * worldPos; + + if (debug == 2) { + Color = vec4(norm, 1); + } else { + Color = vec4(1.); + } } \ No newline at end of file diff --git a/src/main/resources/assets/create/shader/contraption_belt.vert b/src/main/resources/assets/create/shader/contraption_belt.vert index 1548200d7..edd05364c 100644 --- a/src/main/resources/assets/create/shader/contraption_belt.vert +++ b/src/main/resources/assets/create/shader/contraption_belt.vert @@ -65,9 +65,16 @@ void main() { float scrollSize = scrollTexture.w - scrollTexture.y; float scroll = fract(speed * time / (36 * 16.)) * scrollSize * scrollMult; + vec3 norm = normalize(model * localRotation * vec4(aNormal, 0.)).xyz; + BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize; - Diffuse = diffuse(normalize(model * localRotation * vec4(aNormal, 0.)).xyz); - Color = vec4(1.); + Diffuse = diffuse(norm); TexCoords = aTexCoords - sourceUV + scrollTexture.xy + vec2(0., scroll); gl_Position = projection * view * worldPos; + + if (debug == 2) { + Color = vec4(norm, 1); + } else { + Color = vec4(1.); + } } diff --git a/src/main/resources/assets/create/shader/contraption_rotating.vert b/src/main/resources/assets/create/shader/contraption_rotating.vert index 7c4ff23db..b494b58d6 100644 --- a/src/main/resources/assets/create/shader/contraption_rotating.vert +++ b/src/main/resources/assets/create/shader/contraption_rotating.vert @@ -57,9 +57,16 @@ void main() { vec4 worldPos = model * localPos; + vec3 norm = normalize(model * kineticRotation * vec4(aNormal, 0.)).xyz; + BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize; - Diffuse = diffuse(normalize(model * kineticRotation * vec4(aNormal, 0.)).xyz); - Color = vec4(1.); + Diffuse = diffuse(norm); TexCoords = aTexCoords; gl_Position = projection * view * worldPos; + + if (debug == 2) { + Color = vec4(norm, 1); + } else { + Color = vec4(1.); + } } \ No newline at end of file