From 7beeec5e00481ce6bb02d4d3fe6b1b47dd2dc2ca Mon Sep 17 00:00:00 2001 From: JozsefA Date: Thu, 7 Jan 2021 02:06:40 -0800 Subject: [PATCH] maybe lighting is done starting fast contraption rendering, not safe to use yet --- .../AbstractContraptionEntityRenderer.java | 9 +- .../ContraptionRenderer.java | 24 ++-- .../ControlledContraptionEntityRenderer.java | 21 ++++ .../OrientedContraptionEntityRenderer.java | 36 +++++- .../simibubi/create/events/ClientEvents.java | 5 +- .../foundation/ResourceReloadHandler.java | 3 + .../command/ClearBufferCacheCommand.java | 3 + .../foundation/utility/render/BeltBuffer.java | 5 +- .../utility/render/ContraptionBuffer.java | 109 ++++++++++++++++++ .../utility/render/ContraptionLighter.java | 86 ++++++++++++++ .../utility/render/FastKineticRenderer.java | 96 +++++++-------- .../utility/render/InstancedBuffer.java | 5 +- .../foundation/utility/render/LightUtil.java | 13 +++ .../utility/render/RotatingBuffer.java | 4 +- .../utility/render/SuperByteBufferCache.java | 1 - .../utility/render/shader/Shader.java | 4 +- .../utility/render/shader/ShaderHelper.java | 30 +++++ .../resources/assets/create/shader/belt.vert | 8 +- .../create/shader/contraption_static.vert | 51 ++++++++ .../assets/create/shader/instanced.frag | 14 ++- .../assets/create/shader/rotating.vert | 12 +- 21 files changed, 460 insertions(+), 79 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/utility/render/ContraptionBuffer.java create mode 100644 src/main/java/com/simibubi/create/foundation/utility/render/ContraptionLighter.java create mode 100644 src/main/java/com/simibubi/create/foundation/utility/render/LightUtil.java create mode 100644 src/main/resources/assets/create/shader/contraption_static.vert 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 f6b9ad44d..8ca710438 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 @@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement; import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.utility.render.FastContraptionRenderer; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.culling.ClippingHelperImpl; @@ -9,6 +10,7 @@ import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRendererManager; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; public abstract class AbstractContraptionEntityRenderer extends EntityRenderer { @@ -23,6 +25,9 @@ public abstract class AbstractContraptionEntityRenderer actor : c.getActors()) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntityRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntityRenderer.java index 6567b0419..65c2b0d15 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntityRenderer.java @@ -5,6 +5,8 @@ import com.simibubi.create.foundation.utility.MatrixStacker; import net.minecraft.client.renderer.entity.EntityRendererManager; import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; public class ControlledContraptionEntityRenderer extends AbstractContraptionEntityRenderer { @@ -26,4 +28,23 @@ 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; + + float angle = entity.getAngle(partialTicks); + + if (axis == Axis.X) return new Vec3d(angle, 0, 0); + if (axis == Axis.Y) return new Vec3d(0, angle, 0); + if (axis == Axis.Z) return new Vec3d(0, 0, angle); + + throw new IllegalStateException("impossible axis"); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/OrientedContraptionEntityRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/OrientedContraptionEntityRenderer.java index 78604cfb8..8f60343af 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/OrientedContraptionEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/OrientedContraptionEntityRenderer.java @@ -56,8 +56,19 @@ public class OrientedContraptionEntityRenderer extends AbstractContraptionEntity .unCentre(); } + @Override + public Vec3d getPosition(OrientedContraptionEntity entity, float partialTicks) { + + return Vec3d.ZERO; + } + + @Override + public Vec3d getRotation(OrientedContraptionEntity contraptionEntity, float partialTicks) { + return Vec3d.ZERO; + } + private void repositionOnContraption(OrientedContraptionEntity entity, float partialTicks, - MatrixStack[] matrixStacks, Entity ridingEntity) { + 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()); @@ -93,4 +104,27 @@ public class OrientedContraptionEntityRenderer extends AbstractContraptionEntity } } + private Vec3d getCartPosition(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()); + double cartZ = MathHelper.lerp(partialTicks, cart.lastTickPosZ, cart.getZ()); + Vec3d cartPos = cart.getPos(cartX, cartY, cartZ); + + 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; + } + + return new Vec3d(cartX, cartY, cartZ); + } + } diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index 056043cdf..5340cbce7 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -32,7 +32,7 @@ import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollVal 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.FastKineticRenderer; +import com.simibubi.create.foundation.utility.render.FastContraptionRenderer; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.IRenderTypeBuffer; @@ -111,11 +111,14 @@ public class ClientEvents { @SubscribeEvent public static void onLoadWorld(WorldEvent.Load event) { CreateClient.bufferCache.invalidate(); + CreateClient.kineticRenderer.invalidate(); + FastContraptionRenderer.invalidateAll(); } @SubscribeEvent public static void onRenderWorld(RenderWorldLastEvent event) { CreateClient.kineticRenderer.renderInstances(event); + FastContraptionRenderer.renderAll(event); MatrixStack ms = event.getMatrixStack(); ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo(); diff --git a/src/main/java/com/simibubi/create/foundation/ResourceReloadHandler.java b/src/main/java/com/simibubi/create/foundation/ResourceReloadHandler.java index 9206a88c4..7809c8bc5 100644 --- a/src/main/java/com/simibubi/create/foundation/ResourceReloadHandler.java +++ b/src/main/java/com/simibubi/create/foundation/ResourceReloadHandler.java @@ -3,6 +3,7 @@ package com.simibubi.create.foundation; import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.block.render.SpriteShifter; +import com.simibubi.create.foundation.utility.render.FastContraptionRenderer; import net.minecraft.client.resources.ReloadListener; import net.minecraft.profiler.IProfiler; import net.minecraft.resources.IResourceManager; @@ -18,6 +19,8 @@ public class ResourceReloadHandler extends ReloadListener { protected void apply(Object $, IResourceManager resourceManagerIn, IProfiler profilerIn) { SpriteShifter.reloadUVs(); CreateClient.bufferCache.invalidate(); + CreateClient.kineticRenderer.invalidate(); + FastContraptionRenderer.invalidateAll(); } } diff --git a/src/main/java/com/simibubi/create/foundation/command/ClearBufferCacheCommand.java b/src/main/java/com/simibubi/create/foundation/command/ClearBufferCacheCommand.java index 2398d9406..159f96861 100644 --- a/src/main/java/com/simibubi/create/foundation/command/ClearBufferCacheCommand.java +++ b/src/main/java/com/simibubi/create/foundation/command/ClearBufferCacheCommand.java @@ -3,6 +3,7 @@ package com.simibubi.create.foundation.command; import com.mojang.brigadier.builder.ArgumentBuilder; import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.utility.render.FastContraptionRenderer; import net.minecraft.command.CommandSource; import net.minecraft.command.Commands; import net.minecraft.util.text.StringTextComponent; @@ -23,5 +24,7 @@ public class ClearBufferCacheCommand { @OnlyIn(Dist.CLIENT) private static void execute() { CreateClient.bufferCache.invalidate(); + CreateClient.kineticRenderer.invalidate(); + FastContraptionRenderer.invalidateAll(); } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/BeltBuffer.java b/src/main/java/com/simibubi/create/foundation/utility/render/BeltBuffer.java index f28797586..e17b33623 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/BeltBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/BeltBuffer.java @@ -8,6 +8,7 @@ import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.VertexFormatElement; import net.minecraft.util.math.BlockPos; +import net.minecraftforge.client.model.pipeline.VertexLighterFlat; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; @@ -137,8 +138,8 @@ public class BeltBuffer extends InstancedBuffer { } void buffer(ByteBuffer buf) { - float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF; - float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF; + float blockLightCoordinates = LightUtil.getProperBlockLight(packedLight); + float skyLightCoordinates = LightUtil.getProperSkyLight(packedLight); buf.putFloat(x); buf.putFloat(y); diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/ContraptionBuffer.java b/src/main/java/com/simibubi/create/foundation/utility/render/ContraptionBuffer.java new file mode 100644 index 000000000..d667788ca --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/render/ContraptionBuffer.java @@ -0,0 +1,109 @@ +package com.simibubi.create.foundation.utility.render; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.CreateClient; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.vertex.VertexFormatElement; +import org.lwjgl.opengl.*; + +import java.nio.Buffer; +import java.nio.ByteBuffer; + +public class ContraptionBuffer extends TemplateBuffer { + + protected int vao, ebo, vbo; + + public ContraptionBuffer(BufferBuilder buf) { + super(buf); + setup(); + } + + public void invalidate() { + CreateClient.kineticRenderer.enqueue(() -> { + GL15.glDeleteBuffers(vbo); + GL15.glDeleteBuffers(ebo); + GL30.glDeleteVertexArrays(vao); + }); + } + + public void render() { + + GL30.glBindVertexArray(vao); + + for (int i = 0; i <= 3; i++) { + GL40.glEnableVertexAttribArray(i); + } + + GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo); + + GL40.glDrawElements(GL11.GL_QUADS, count, GL11.GL_UNSIGNED_SHORT, 0); + + for (int i = 0; i <= 3; i++) { + GL40.glDisableVertexAttribArray(i); + } + + GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); + GL30.glBindVertexArray(0); + } + + private void setup() { + int floatSize = VertexFormatElement.Type.FLOAT.getSize(); + + int stride = floatSize * 8; + int invariantSize = count * stride; + + ByteBuffer constant = GLAllocation.createDirectByteBuffer(invariantSize); + constant.order(template.order()); + ((Buffer) constant).limit(invariantSize); + + int indicesSize = count * VertexFormatElement.Type.USHORT.getSize(); + ByteBuffer indices = GLAllocation.createDirectByteBuffer(indicesSize); + indices.order(template.order()); + ((Buffer) indices).limit(indicesSize); + + int vertexCount = vertexCount(template); + for (int i = 0; i < vertexCount; i++) { + constant.putFloat(getX(template, i)); + constant.putFloat(getY(template, i)); + constant.putFloat(getZ(template, i)); + + constant.putFloat(getNX(template, i)); + constant.putFloat(getNY(template, i)); + constant.putFloat(getNZ(template, i)); + + constant.putFloat(getU(template, i)); + constant.putFloat(getV(template, i)); + + indices.putShort((short) i); + } + constant.rewind(); + indices.rewind(); + + vao = GL30.glGenVertexArrays(); + GL30.glBindVertexArray(vao); + + ebo = GlStateManager.genBuffers(); + vbo = GlStateManager.genBuffers(); + + GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, vbo); + GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, constant, GL15.GL_STATIC_DRAW); + + GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo); + GlStateManager.bufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW); + + // vertex positions + GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, stride, 0); + + // vertex normals + GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, stride, floatSize * 3L); + + // uv position + GL20.glVertexAttribPointer(2, 2, GL11.GL_FLOAT, false, stride, floatSize * 6L); + + GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, 0); + GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); + // Deselect (bind to 0) the VAO + GL30.glBindVertexArray(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 new file mode 100644 index 000000000..3e2dd318b --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/render/ContraptionLighter.java @@ -0,0 +1,86 @@ +package com.simibubi.create.foundation.utility.render; + +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.world.LightType; +import net.minecraft.world.World; +import net.minecraft.world.lighting.WorldLightManager; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import org.lwjgl.opengl.GL40; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.util.Set; + +public class ContraptionLighter { + + int minX; + int minY; + int minZ; + + int sizeX; + int sizeY; + int sizeZ; + + ByteBuffer lightVolume; + + int texture; + + public ContraptionLighter(Contraption contraption) { + texture = GL11.glGenTextures(); + + AxisAlignedBB bounds = contraption.bounds; + + int minX = (int) Math.floor(bounds.minX); + int minY = (int) Math.floor(bounds.minY); + int minZ = (int) Math.floor(bounds.minZ); + int maxX = (int) Math.ceil(bounds.maxX); + int maxY = (int) Math.ceil(bounds.maxY); + int maxZ = (int) Math.ceil(bounds.maxZ); + + sizeX = maxX - minX; + sizeY = maxY - minY; + sizeZ = maxZ - minZ; + + lightVolume = GLAllocation.createDirectByteBuffer(sizeX * sizeY * sizeZ * 2); + } + + public void delete() { + GL11.glDeleteTextures(texture); + } + + public void tick() { + + } + + public void addLightData(World world, BlockPos pos) { + + int contraptionX = pos.getX() - minX; + int contraptionY = pos.getY() - minY; + int contraptionZ = pos.getZ() - minZ; + + if (contraptionX < 0 || contraptionX >= sizeX || contraptionY < 0 || contraptionY >= sizeY || contraptionZ < 0 || contraptionZ >= sizeZ) + return; + + int blockLight = world.getLightLevel(LightType.BLOCK, pos); + int skyLight = world.getLightLevel(LightType.SKY, pos); + + writeLight(contraptionX, contraptionY, contraptionZ, blockLight, skyLight); + } + + private void writeLight(int x, int y, int z, int block, int sky) { + int i = (x + y * sizeX + z * sizeX * sizeY) * 2; + + lightVolume.put(i, (byte) (block * 16)); + lightVolume.put(i + 1, (byte) (sky * 16)); + } + + public void use() { + GL12.glBindTexture(GL12.GL_TEXTURE_3D, texture); + lightVolume.rewind(); + GL12.glTexImage3D(GL12.GL_TEXTURE_3D, 0, GL40.GL_RG, sizeX, sizeY, sizeZ, 0, GL40.GL_RG, GL40.GL_UNSIGNED_BYTE, lightVolume); + } +} 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 1ee9e3f35..1ee76a574 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 @@ -69,49 +69,12 @@ public class FastKineticRenderer { } public void renderInstances(RenderWorldLastEvent event) { - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); - - RenderSystem.enableLighting(); - RenderSystem.enableDepthTest(); - GL11.glCullFace(GL11.GL_BACK); - GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer; - LightTexture lightManager = gameRenderer.getLightmapTextureManager(); - Texture blockAtlasTexture = Minecraft.getInstance().textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE); - Texture lightTexture = Minecraft.getInstance().textureManager.getTexture(lightManager.resourceLocation); + setup(gameRenderer); - GL13.glActiveTexture(GL40.GL_TEXTURE0); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, blockAtlasTexture.getGlTextureId()); - blockAtlasTexture.setBlurMipmap(false, true); + ShaderCallback callback = ShaderHelper.getViewProjectionCallback(event); - GL13.glActiveTexture(GL40.GL_TEXTURE0 + 1); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, lightTexture.getGlTextureId()); - RenderSystem.texParameter(3553, 10241, 9729); - RenderSystem.texParameter(3553, 10240, 9729); - RenderSystem.texParameter(3553, 10242, 10496); - RenderSystem.texParameter(3553, 10243, 10496); - RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.enableTexture(); - - ShaderCallback callback = shader -> { - ShaderHelper.MATRIX_BUFFER.position(0); - event.getProjectionMatrix().write(ShaderHelper.MATRIX_BUFFER); - - int projection = GlStateManager.getUniformLocation(shader, "projection"); - GlStateManager.uniformMatrix4(projection, false, ShaderHelper.MATRIX_BUFFER); - - // view matrix - Vec3d pos = gameRenderer.getActiveRenderInfo().getProjectedView(); - Matrix4f translate = Matrix4f.translate((float) -pos.x, (float) -pos.y, (float) -pos.z); - translate.multiplyBackward(event.getMatrixStack().peek().getModel()); - - ShaderHelper.MATRIX_BUFFER.position(0); - translate.write(ShaderHelper.MATRIX_BUFFER); - int view = GlStateManager.getUniformLocation(shader, "view"); - GlStateManager.uniformMatrix4(view, false, ShaderHelper.MATRIX_BUFFER); - }; ShaderHelper.useShader(Shader.ROTATING_INSTANCED, callback); rotating.values() @@ -123,26 +86,63 @@ public class FastKineticRenderer { ShaderHelper.useShader(Shader.BELT_INSTANCED, callback); belts.values() - .stream() - .flatMap(cache -> cache.asMap().values().stream()) - .filter(type -> !type.isEmpty()) - .forEach(InstancedBuffer::render); + .stream() + .flatMap(cache -> cache.asMap().values().stream()) + .filter(type -> !type.isEmpty()) + .forEach(InstancedBuffer::render); ShaderHelper.releaseShader(); + teardown(); + + while (!runs.isEmpty()) { + runs.remove().run(); + } + } + + public void setup(GameRenderer gameRenderer) { + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + + RenderSystem.enableLighting(); + RenderSystem.enableDepthTest(); + GL11.glCullFace(GL11.GL_BACK); + + LightTexture lightManager = gameRenderer.getLightmapTextureManager(); + + Texture blockAtlasTexture = Minecraft.getInstance().textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE); + Texture lightTexture = Minecraft.getInstance().textureManager.getTexture(lightManager.resourceLocation); + + // bind the block atlas texture to 0 + GL13.glActiveTexture(GL40.GL_TEXTURE0); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, blockAtlasTexture.getGlTextureId()); + GL40.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST_MIPMAP_LINEAR); + GL40.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); + + // bind the light texture to 1 and setup the mysterious filtering options + GL13.glActiveTexture(GL40.GL_TEXTURE1); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, lightTexture.getGlTextureId()); + RenderSystem.texParameter(GL11.GL_TEXTURE_2D, 10241, 9729); + RenderSystem.texParameter(GL11.GL_TEXTURE_2D, 10240, 9729); + RenderSystem.texParameter(GL11.GL_TEXTURE_2D, 10242, 10496); + RenderSystem.texParameter(GL11.GL_TEXTURE_2D, 10243, 10496); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.enableTexture(); + } + + public void teardown() { + GL13.glActiveTexture(GL40.GL_TEXTURE0 + 1); GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); + GL13.glActiveTexture(GL40.GL_TEXTURE0); - blockAtlasTexture.restoreLastBlurMipmap(); + GL40.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST_MIPMAP_LINEAR); + GL40.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); RenderSystem.disableCull(); RenderSystem.disableBlend(); RenderSystem.defaultBlendFunc(); RenderSystem.disableDepthTest(); - - while (!runs.isEmpty()) { - runs.remove().run(); - } } public void registerCompartment(SuperByteBufferCache.Compartment instance) { diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/InstancedBuffer.java b/src/main/java/com/simibubi/create/foundation/utility/render/InstancedBuffer.java index ad77c60a7..bd7be51c8 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/InstancedBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/InstancedBuffer.java @@ -129,7 +129,7 @@ public abstract class InstancedBuffer extends TemplateBuffer { GL30.glBindVertexArray(vao); finishBuffering(); - for (int i = 0; i <= 10; i++) { + for (int i = 0; i <= numAttributes(); i++) { GL40.glEnableVertexAttribArray(i); } @@ -137,10 +137,11 @@ public abstract class InstancedBuffer extends TemplateBuffer { GL40.glDrawElementsInstanced(GL11.GL_QUADS, count, GL11.GL_UNSIGNED_SHORT, 0, instanceCount); - for (int i = 0; i <= 10; i++) { + for (int i = 0; i <= numAttributes(); i++) { GL40.glDisableVertexAttribArray(i); } + GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); GL30.glBindVertexArray(0); } diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/LightUtil.java b/src/main/java/com/simibubi/create/foundation/utility/render/LightUtil.java new file mode 100644 index 000000000..278ae2c1b --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/render/LightUtil.java @@ -0,0 +1,13 @@ +package com.simibubi.create.foundation.utility.render; + +import net.minecraft.client.renderer.LightTexture; + +public class LightUtil { + public static float getProperBlockLight(int packedLight) { + return ((LightTexture.getBlockLightCoordinates(packedLight) + 1) / (float) 0xF); + } + + public static float getProperSkyLight(int packedLight) { + return ((LightTexture.getSkyLightCoordinates(packedLight) + 1) / (float) 0xF); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/RotatingBuffer.java b/src/main/java/com/simibubi/create/foundation/utility/render/RotatingBuffer.java index e154baf8e..6d80607f0 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/RotatingBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/RotatingBuffer.java @@ -122,8 +122,8 @@ public class RotatingBuffer extends InstancedBuffer } void buffer(ByteBuffer buf) { - float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF; - float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF; + float blockLightCoordinates = LightUtil.getProperBlockLight(packedLight); + float skyLightCoordinates = LightUtil.getProperSkyLight(packedLight); buf.putFloat(x); buf.putFloat(y); diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/SuperByteBufferCache.java b/src/main/java/com/simibubi/create/foundation/utility/render/SuperByteBufferCache.java index 296fbf3de..fbb52d014 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/SuperByteBufferCache.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/SuperByteBufferCache.java @@ -128,7 +128,6 @@ public class SuperByteBufferCache { public void invalidate() { cache.forEach((comp, cache) -> cache.invalidateAll()); - CreateClient.kineticRenderer.invalidate(); } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/shader/Shader.java b/src/main/java/com/simibubi/create/foundation/utility/render/shader/Shader.java index e0b2d11ff..0820adff9 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/shader/Shader.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/shader/Shader.java @@ -2,7 +2,9 @@ package com.simibubi.create.foundation.utility.render.shader; public enum Shader { ROTATING_INSTANCED("shader/rotating.vert", "shader/instanced.frag"), - BELT_INSTANCED("shader/belt.vert", "shader/instanced.frag"),; + BELT_INSTANCED("shader/belt.vert", "shader/instanced.frag"), + CONTRAPTION_STRUCTURE("shader/contraption_static.vert", "shader/instanced.frag"), + ; public final String vert; public final String frag; diff --git a/src/main/java/com/simibubi/create/foundation/utility/render/shader/ShaderHelper.java b/src/main/java/com/simibubi/create/foundation/utility/render/shader/ShaderHelper.java index 9bd8df36d..ae5d1d957 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/render/shader/ShaderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/render/shader/ShaderHelper.java @@ -4,6 +4,7 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.Create; import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.Matrix4f; import net.minecraft.client.shader.IShaderManager; import net.minecraft.client.shader.ShaderLinkHelper; import net.minecraft.client.shader.ShaderLoader; @@ -11,6 +12,8 @@ import net.minecraft.resources.IReloadableResourceManager; import net.minecraft.resources.IResourceManager; import net.minecraft.resources.IResourceManagerReloadListener; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.client.event.RenderWorldLastEvent; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.lwjgl.system.MemoryUtil; @@ -28,6 +31,7 @@ public class ShaderHelper { public static final Logger log = LogManager.getLogger("shader"); public static final FloatBuffer FLOAT_BUFFER = MemoryUtil.memAllocFloat(1); + public static final FloatBuffer VEC3_BUFFER = MemoryUtil.memAllocFloat(3); public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16); private static final Map PROGRAMS = new EnumMap<>(Shader.class); @@ -48,6 +52,32 @@ public class ShaderHelper { } } + public static int getShaderHandle(Shader shader) { + ShaderProgram shaderProgram = PROGRAMS.get(shader); + + return shaderProgram.getProgram(); + } + + public static ShaderCallback getViewProjectionCallback(RenderWorldLastEvent event) { + return shader -> { + ShaderHelper.MATRIX_BUFFER.position(0); + event.getProjectionMatrix().write(ShaderHelper.MATRIX_BUFFER); + + int projection = GlStateManager.getUniformLocation(shader, "projection"); + GlStateManager.uniformMatrix4(projection, false, ShaderHelper.MATRIX_BUFFER); + + // view matrix + Vec3d pos = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); + Matrix4f translate = Matrix4f.translate((float) -pos.x, (float) -pos.y, (float) -pos.z); + translate.multiplyBackward(event.getMatrixStack().peek().getModel()); + + ShaderHelper.MATRIX_BUFFER.position(0); + translate.write(ShaderHelper.MATRIX_BUFFER); + int view = GlStateManager.getUniformLocation(shader, "view"); + GlStateManager.uniformMatrix4(view, false, ShaderHelper.MATRIX_BUFFER); + }; + } + public static void useShader(Shader shader) { useShader(shader, null); } diff --git a/src/main/resources/assets/create/shader/belt.vert b/src/main/resources/assets/create/shader/belt.vert index 76abae150..afe714db0 100644 --- a/src/main/resources/assets/create/shader/belt.vert +++ b/src/main/resources/assets/create/shader/belt.vert @@ -13,6 +13,7 @@ layout (location = 7) in vec2 sourceUV; layout (location = 8) in vec4 scrollTexture; layout (location = 9) in float scrollMult; +out vec3 Normal; out vec2 TexCoords; out vec2 Light; @@ -21,8 +22,7 @@ uniform int ticks; uniform mat4 projection; uniform mat4 view; -mat4 rotate(vec3 axis, float angle) -{ +mat4 rotate(vec3 axis, float angle) { float s = sin(angle); float c = cos(angle); float oc = 1.0 - c; @@ -33,8 +33,7 @@ mat4 rotate(vec3 axis, float angle) 0., 0., 0., 1.); } -void main() -{ +void main() { vec3 rot = fract(rotationDegrees / 360.) * PI * 2.; mat4 rotation = rotate(vec3(0, 1, 0), rot.y) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(1, 0, 0), rot.x); @@ -46,6 +45,7 @@ void main() float scroll = fract(speed * time / (36 * 16.)) * scrollSize * scrollMult; + Normal = normalize((rotation * vec4(aNormal, 0.)).xyz); Light = light; TexCoords = aTexCoords - sourceUV + scrollTexture.xy + vec2(0., scroll); gl_Position = projection * view * renderPos; diff --git a/src/main/resources/assets/create/shader/contraption_static.vert b/src/main/resources/assets/create/shader/contraption_static.vert new file mode 100644 index 000000000..3f758039b --- /dev/null +++ b/src/main/resources/assets/create/shader/contraption_static.vert @@ -0,0 +1,51 @@ +#version 440 core +#define PI 3.1415926538 + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; +layout (location = 2) in vec2 aTexCoords; + +out vec3 Normal; +out vec2 TexCoords; +out vec2 Light; + +layout (binding = 2) uniform sampler3D lightVolume; + +uniform vec3 cSize; +uniform vec3 cPos; +uniform vec3 cRot; + +uniform float time; +uniform int ticks; +uniform mat4 projection; +uniform mat4 view; + +mat4 rotate(vec3 axis, float angle) +{ + float s = sin(angle); + float c = cos(angle); + float oc = 1.0 - c; + + return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0., + oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0., + oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0., + 0., 0., 0., 1.); +} + +mat4 contraptionRotation() { + vec3 rot = -fract(cRot / 360) * PI * 2; + return rotate(vec3(0, 1, 0), rot.y) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(1, 0, 0), rot.x); +} + +void main() { + vec4 rotatedPos = contraptionRotation() * vec4(aPos - vec3(0.5), 1); + + vec4 worldPos = rotatedPos + vec4(cPos + vec3(0.5), 0); + + vec3 boxCoord = (worldPos.xyz - cPos - cSize * 0.5) / cSize; + + //Light = texture(lightVolume, boxCoord).rg; + Normal = aNormal; + TexCoords = aTexCoords; + gl_Position = projection * view * worldPos; +} diff --git a/src/main/resources/assets/create/shader/instanced.frag b/src/main/resources/assets/create/shader/instanced.frag index 81596480c..215f1178a 100644 --- a/src/main/resources/assets/create/shader/instanced.frag +++ b/src/main/resources/assets/create/shader/instanced.frag @@ -1,4 +1,6 @@ #version 440 core + +in vec3 Normal; in vec2 TexCoords; in vec2 Light; @@ -19,11 +21,17 @@ vec3 blendDarken(vec3 base, vec3 blend, float opacity) { return (blendDarken(base, blend) * opacity + base * (1.0 - opacity)); } -void main() -{ +float diffuse() { + float x = Normal.x; + float y = Normal.y; + float z = Normal.z; + return min(x * x * 0.6f + y * y * ((3f + y) / 4f) + z * z * 0.8f, 1f); +} + +void main() { vec4 tex = texture2D(BlockAtlas, TexCoords); vec4 light = texture2D(LightMap, Light); - fragColor = vec4(blendDarken(tex.rgb, light.rgb, light.a), tex.a); + fragColor = vec4(blendDarken(tex.rgb, light.rgb, light.a) * diffuse(), tex.a); } \ No newline at end of file diff --git a/src/main/resources/assets/create/shader/rotating.vert b/src/main/resources/assets/create/shader/rotating.vert index 2643566f2..9c1efea5d 100644 --- a/src/main/resources/assets/create/shader/rotating.vert +++ b/src/main/resources/assets/create/shader/rotating.vert @@ -10,6 +10,7 @@ layout (location = 5) in float speed; layout (location = 6) in float rotationOffset; layout (location = 7) in vec3 rotationAxis; +out vec3 Normal; out vec2 TexCoords; out vec2 Light; @@ -18,8 +19,7 @@ uniform int ticks; uniform mat4 projection; uniform mat4 view; -mat4 kineticRotation() -{ +mat4 kineticRotation() { float degrees = rotationOffset + time * speed * -3./10.; float angle = fract(degrees / 360.) * PI * 2.; @@ -34,14 +34,14 @@ mat4 kineticRotation() 0., 0., 0., 1.); } -void main() -{ - vec4 renderPos = kineticRotation() * vec4(aPos - vec3(0.5), 1); +void main() { + mat4 rotation = kineticRotation(); + vec4 renderPos = rotation * vec4(aPos - vec3(0.5), 1); renderPos += vec4(instancePos + vec3(0.5), 0); TexCoords = aTexCoords; - + Normal = normalize((rotation * vec4(aNormal, 0.)).xyz); gl_Position = projection * view * renderPos; Light = light; } \ No newline at end of file