maybe lighting is done

starting fast contraption rendering, not safe to use yet
This commit is contained in:
JozsefA 2021-01-07 02:06:40 -08:00
parent 029f56da57
commit 7beeec5e00
21 changed files with 460 additions and 79 deletions

View file

@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.utility.render.FastContraptionRenderer;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.culling.ClippingHelperImpl; 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.client.renderer.entity.EntityRendererManager;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
public abstract class AbstractContraptionEntityRenderer<C extends AbstractContraptionEntity> extends EntityRenderer<C> { public abstract class AbstractContraptionEntityRenderer<C extends AbstractContraptionEntity> extends EntityRenderer<C> {
@ -23,6 +25,9 @@ public abstract class AbstractContraptionEntityRenderer<C extends AbstractContra
protected abstract void transform(C contraptionEntity, float partialTicks, MatrixStack[] matrixStacks); protected abstract void transform(C contraptionEntity, float partialTicks, MatrixStack[] matrixStacks);
public abstract Vec3d getPosition(C contraptionEntity, float partialTicks);
public abstract Vec3d getRotation(C contraptionEntity, float partialTicks);
@Override @Override
public boolean shouldRender(C entity, ClippingHelperImpl p_225626_2_, double p_225626_3_, double p_225626_5_, public boolean shouldRender(C entity, ClippingHelperImpl p_225626_2_, double p_225626_3_, double p_225626_5_,
double p_225626_7_) { double p_225626_7_) {
@ -47,8 +52,10 @@ public abstract class AbstractContraptionEntityRenderer<C extends AbstractContra
ms.push(); ms.push();
transform(entity, partialTicks, matrixStacks); transform(entity, partialTicks, matrixStacks);
Contraption contraption = entity.getContraption(); Contraption contraption = entity.getContraption();
if (contraption != null) if (contraption != null) {
ContraptionRenderer.render(entity.world, contraption, ms, msLocal, buffers); ContraptionRenderer.render(entity.world, contraption, ms, msLocal, buffers);
// not ready yet FastContraptionRenderer.markForRendering(entity.world, contraption, getPosition(entity, partialTicks), getRotation(entity, partialTicks));
}
ms.pop(); ms.pop();
} }

View file

@ -42,11 +42,16 @@ public class ContraptionRenderer {
protected static PlacementSimulationWorld renderWorld; protected static PlacementSimulationWorld renderWorld;
public static void render(World world, Contraption c, MatrixStack ms, MatrixStack msLocal, public static void render(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
IRenderTypeBuffer buffer) { IRenderTypeBuffer buffer) {
renderDynamic(world, c, ms, msLocal, buffer);
renderStructure(world, c, ms, msLocal, buffer);
}
public static void renderDynamic(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
IRenderTypeBuffer buffer) {
renderTileEntities(world, c, ms, msLocal, buffer); renderTileEntities(world, c, ms, msLocal, buffer);
if (buffer instanceof IRenderTypeBuffer.Impl) if (buffer instanceof IRenderTypeBuffer.Impl)
((IRenderTypeBuffer.Impl) buffer).draw(); ((IRenderTypeBuffer.Impl) buffer).draw();
renderStructure(world, c, ms, msLocal, buffer);
renderActors(world, c, ms, msLocal, buffer); renderActors(world, c, ms, msLocal, buffer);
} }
@ -69,12 +74,17 @@ public class ContraptionRenderer {
} }
} }
private static void renderTileEntities(World world, Contraption c, MatrixStack ms, MatrixStack msLocal, protected static void renderTileEntities(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
IRenderTypeBuffer buffer) { IRenderTypeBuffer buffer) {
TileEntityRenderHelper.renderTileEntities(world, c.renderedTileEntities, ms, msLocal, buffer); TileEntityRenderHelper.renderTileEntities(world, c.renderedTileEntities, ms, msLocal, buffer);
} }
private static SuperByteBuffer buildStructureBuffer(Contraption c, RenderType layer) { private static SuperByteBuffer buildStructureBuffer(Contraption c, RenderType layer) {
BufferBuilder builder = buildStructure(c, layer);
return new SuperByteBuffer(builder);
}
protected static BufferBuilder buildStructure(Contraption c, RenderType layer) {
if (renderWorld == null || renderWorld.getWorld() != Minecraft.getInstance().world) if (renderWorld == null || renderWorld.getWorld() != Minecraft.getInstance().world)
renderWorld = new PlacementSimulationWorld(Minecraft.getInstance().world); renderWorld = new PlacementSimulationWorld(Minecraft.getInstance().world);
@ -89,10 +99,10 @@ public class ContraptionRenderer {
renderWorld.setTileEntities(c.presentTileEntities.values()); renderWorld.setTileEntities(c.presentTileEntities.values());
for (BlockInfo info : c.getBlocks() for (BlockInfo info : c.getBlocks()
.values()) .values())
renderWorld.setBlockState(info.pos, info.state); renderWorld.setBlockState(info.pos, info.state);
for (BlockInfo info : c.getBlocks() for (BlockInfo info : c.getBlocks()
.values()) { .values()) {
BlockState state = info.state; BlockState state = info.state;
if (state.getRenderType() == BlockRenderType.ENTITYBLOCK_ANIMATED) if (state.getRenderType() == BlockRenderType.ENTITYBLOCK_ANIMATED)
@ -110,10 +120,10 @@ public class ContraptionRenderer {
builder.finishDrawing(); builder.finishDrawing();
renderWorld.clear(); renderWorld.clear();
return new SuperByteBuffer(builder); return builder;
} }
private static void renderActors(World world, Contraption c, MatrixStack ms, MatrixStack msLocal, protected static void renderActors(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
IRenderTypeBuffer buffer) { IRenderTypeBuffer buffer) {
MatrixStack[] matrixStacks = new MatrixStack[] { ms, msLocal }; MatrixStack[] matrixStacks = new MatrixStack[] { ms, msLocal };
for (Pair<BlockInfo, MovementContext> actor : c.getActors()) { for (Pair<BlockInfo, MovementContext> actor : c.getActors()) {

View file

@ -5,6 +5,8 @@ import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.client.renderer.entity.EntityRendererManager; import net.minecraft.client.renderer.entity.EntityRendererManager;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
public class ControlledContraptionEntityRenderer extends AbstractContraptionEntityRenderer<ControlledContraptionEntity> { public class ControlledContraptionEntityRenderer extends AbstractContraptionEntityRenderer<ControlledContraptionEntity> {
@ -26,4 +28,23 @@ public class ControlledContraptionEntityRenderer extends AbstractContraptionEnti
.unCentre(); .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");
}
} }

View file

@ -56,8 +56,19 @@ public class OrientedContraptionEntityRenderer extends AbstractContraptionEntity
.unCentre(); .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, private void repositionOnContraption(OrientedContraptionEntity entity, float partialTicks,
MatrixStack[] matrixStacks, Entity ridingEntity) { MatrixStack[] matrixStacks, Entity ridingEntity) {
AbstractContraptionEntity parent = (AbstractContraptionEntity) ridingEntity; AbstractContraptionEntity parent = (AbstractContraptionEntity) ridingEntity;
Vec3d passengerPosition = parent.getPassengerPosition(entity, partialTicks); Vec3d passengerPosition = parent.getPassengerPosition(entity, partialTicks);
double x = passengerPosition.x - MathHelper.lerp(partialTicks, entity.lastTickPosX, entity.getX()); 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);
}
} }

View file

@ -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.AnimationTickHolder;
import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.foundation.utility.placement.PlacementHelpers; 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.Minecraft;
import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -111,11 +111,14 @@ public class ClientEvents {
@SubscribeEvent @SubscribeEvent
public static void onLoadWorld(WorldEvent.Load event) { public static void onLoadWorld(WorldEvent.Load event) {
CreateClient.bufferCache.invalidate(); CreateClient.bufferCache.invalidate();
CreateClient.kineticRenderer.invalidate();
FastContraptionRenderer.invalidateAll();
} }
@SubscribeEvent @SubscribeEvent
public static void onRenderWorld(RenderWorldLastEvent event) { public static void onRenderWorld(RenderWorldLastEvent event) {
CreateClient.kineticRenderer.renderInstances(event); CreateClient.kineticRenderer.renderInstances(event);
FastContraptionRenderer.renderAll(event);
MatrixStack ms = event.getMatrixStack(); MatrixStack ms = event.getMatrixStack();
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo(); ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();

View file

@ -3,6 +3,7 @@ package com.simibubi.create.foundation;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.block.render.SpriteShifter; 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.client.resources.ReloadListener;
import net.minecraft.profiler.IProfiler; import net.minecraft.profiler.IProfiler;
import net.minecraft.resources.IResourceManager; import net.minecraft.resources.IResourceManager;
@ -18,6 +19,8 @@ public class ResourceReloadHandler extends ReloadListener<Object> {
protected void apply(Object $, IResourceManager resourceManagerIn, IProfiler profilerIn) { protected void apply(Object $, IResourceManager resourceManagerIn, IProfiler profilerIn) {
SpriteShifter.reloadUVs(); SpriteShifter.reloadUVs();
CreateClient.bufferCache.invalidate(); CreateClient.bufferCache.invalidate();
CreateClient.kineticRenderer.invalidate();
FastContraptionRenderer.invalidateAll();
} }
} }

View file

@ -3,6 +3,7 @@ package com.simibubi.create.foundation.command;
import com.mojang.brigadier.builder.ArgumentBuilder; import com.mojang.brigadier.builder.ArgumentBuilder;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.utility.render.FastContraptionRenderer;
import net.minecraft.command.CommandSource; import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands; import net.minecraft.command.Commands;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
@ -23,5 +24,7 @@ public class ClearBufferCacheCommand {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
private static void execute() { private static void execute() {
CreateClient.bufferCache.invalidate(); CreateClient.bufferCache.invalidate();
CreateClient.kineticRenderer.invalidate();
FastContraptionRenderer.invalidateAll();
} }
} }

View file

@ -8,6 +8,7 @@ import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormatElement; import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraftforge.client.model.pipeline.VertexLighterFlat;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
@ -137,8 +138,8 @@ public class BeltBuffer extends InstancedBuffer<BeltBuffer.BeltData> {
} }
void buffer(ByteBuffer buf) { void buffer(ByteBuffer buf) {
float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF; float blockLightCoordinates = LightUtil.getProperBlockLight(packedLight);
float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF; float skyLightCoordinates = LightUtil.getProperSkyLight(packedLight);
buf.putFloat(x); buf.putFloat(x);
buf.putFloat(y); buf.putFloat(y);

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -69,49 +69,12 @@ public class FastKineticRenderer {
} }
public void renderInstances(RenderWorldLastEvent event) { 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; GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
LightTexture lightManager = gameRenderer.getLightmapTextureManager();
Texture blockAtlasTexture = Minecraft.getInstance().textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE); setup(gameRenderer);
Texture lightTexture = Minecraft.getInstance().textureManager.getTexture(lightManager.resourceLocation);
GL13.glActiveTexture(GL40.GL_TEXTURE0); ShaderCallback callback = ShaderHelper.getViewProjectionCallback(event);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, blockAtlasTexture.getGlTextureId());
blockAtlasTexture.setBlurMipmap(false, true);
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); ShaderHelper.useShader(Shader.ROTATING_INSTANCED, callback);
rotating.values() rotating.values()
@ -123,26 +86,63 @@ public class FastKineticRenderer {
ShaderHelper.useShader(Shader.BELT_INSTANCED, callback); ShaderHelper.useShader(Shader.BELT_INSTANCED, callback);
belts.values() belts.values()
.stream() .stream()
.flatMap(cache -> cache.asMap().values().stream()) .flatMap(cache -> cache.asMap().values().stream())
.filter(type -> !type.isEmpty()) .filter(type -> !type.isEmpty())
.forEach(InstancedBuffer::render); .forEach(InstancedBuffer::render);
ShaderHelper.releaseShader(); 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); GL13.glActiveTexture(GL40.GL_TEXTURE0 + 1);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GL13.glActiveTexture(GL40.GL_TEXTURE0); 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.disableCull();
RenderSystem.disableBlend(); RenderSystem.disableBlend();
RenderSystem.defaultBlendFunc(); RenderSystem.defaultBlendFunc();
RenderSystem.disableDepthTest(); RenderSystem.disableDepthTest();
while (!runs.isEmpty()) {
runs.remove().run();
}
} }
public void registerCompartment(SuperByteBufferCache.Compartment<?> instance) { public void registerCompartment(SuperByteBufferCache.Compartment<?> instance) {

View file

@ -129,7 +129,7 @@ public abstract class InstancedBuffer<T> extends TemplateBuffer {
GL30.glBindVertexArray(vao); GL30.glBindVertexArray(vao);
finishBuffering(); finishBuffering();
for (int i = 0; i <= 10; i++) { for (int i = 0; i <= numAttributes(); i++) {
GL40.glEnableVertexAttribArray(i); GL40.glEnableVertexAttribArray(i);
} }
@ -137,10 +137,11 @@ public abstract class InstancedBuffer<T> extends TemplateBuffer {
GL40.glDrawElementsInstanced(GL11.GL_QUADS, count, GL11.GL_UNSIGNED_SHORT, 0, instanceCount); 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); GL40.glDisableVertexAttribArray(i);
} }
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0); GL30.glBindVertexArray(0);
} }

View file

@ -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);
}
}

View file

@ -122,8 +122,8 @@ public class RotatingBuffer extends InstancedBuffer<RotatingBuffer.InstanceData>
} }
void buffer(ByteBuffer buf) { void buffer(ByteBuffer buf) {
float blockLightCoordinates = LightTexture.getBlockLightCoordinates(packedLight) / (float) 0xF; float blockLightCoordinates = LightUtil.getProperBlockLight(packedLight);
float skyLightCoordinates = LightTexture.getSkyLightCoordinates(packedLight) / (float) 0xF; float skyLightCoordinates = LightUtil.getProperSkyLight(packedLight);
buf.putFloat(x); buf.putFloat(x);
buf.putFloat(y); buf.putFloat(y);

View file

@ -128,7 +128,6 @@ public class SuperByteBufferCache {
public void invalidate() { public void invalidate() {
cache.forEach((comp, cache) -> cache.invalidateAll()); cache.forEach((comp, cache) -> cache.invalidateAll());
CreateClient.kineticRenderer.invalidate();
} }
} }

View file

@ -2,7 +2,9 @@ package com.simibubi.create.foundation.utility.render.shader;
public enum Shader { public enum Shader {
ROTATING_INSTANCED("shader/rotating.vert", "shader/instanced.frag"), 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 vert;
public final String frag; public final String frag;

View file

@ -4,6 +4,7 @@ import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.shader.IShaderManager; import net.minecraft.client.shader.IShaderManager;
import net.minecraft.client.shader.ShaderLinkHelper; import net.minecraft.client.shader.ShaderLinkHelper;
import net.minecraft.client.shader.ShaderLoader; import net.minecraft.client.shader.ShaderLoader;
@ -11,6 +12,8 @@ import net.minecraft.resources.IReloadableResourceManager;
import net.minecraft.resources.IResourceManager; import net.minecraft.resources.IResourceManager;
import net.minecraft.resources.IResourceManagerReloadListener; import net.minecraft.resources.IResourceManagerReloadListener;
import net.minecraft.util.ResourceLocation; 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.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
@ -28,6 +31,7 @@ public class ShaderHelper {
public static final Logger log = LogManager.getLogger("shader"); public static final Logger log = LogManager.getLogger("shader");
public static final FloatBuffer FLOAT_BUFFER = MemoryUtil.memAllocFloat(1); 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); public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16);
private static final Map<Shader, ShaderProgram> PROGRAMS = new EnumMap<>(Shader.class); private static final Map<Shader, ShaderProgram> 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) { public static void useShader(Shader shader) {
useShader(shader, null); useShader(shader, null);
} }

View file

@ -13,6 +13,7 @@ layout (location = 7) in vec2 sourceUV;
layout (location = 8) in vec4 scrollTexture; layout (location = 8) in vec4 scrollTexture;
layout (location = 9) in float scrollMult; layout (location = 9) in float scrollMult;
out vec3 Normal;
out vec2 TexCoords; out vec2 TexCoords;
out vec2 Light; out vec2 Light;
@ -21,8 +22,7 @@ uniform int ticks;
uniform mat4 projection; uniform mat4 projection;
uniform mat4 view; uniform mat4 view;
mat4 rotate(vec3 axis, float angle) mat4 rotate(vec3 axis, float angle) {
{
float s = sin(angle); float s = sin(angle);
float c = cos(angle); float c = cos(angle);
float oc = 1.0 - c; float oc = 1.0 - c;
@ -33,8 +33,7 @@ mat4 rotate(vec3 axis, float angle)
0., 0., 0., 1.); 0., 0., 0., 1.);
} }
void main() void main() {
{
vec3 rot = fract(rotationDegrees / 360.) * PI * 2.; 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); 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; float scroll = fract(speed * time / (36 * 16.)) * scrollSize * scrollMult;
Normal = normalize((rotation * vec4(aNormal, 0.)).xyz);
Light = light; Light = light;
TexCoords = aTexCoords - sourceUV + scrollTexture.xy + vec2(0., scroll); TexCoords = aTexCoords - sourceUV + scrollTexture.xy + vec2(0., scroll);
gl_Position = projection * view * renderPos; gl_Position = projection * view * renderPos;

View file

@ -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;
}

View file

@ -1,4 +1,6 @@
#version 440 core #version 440 core
in vec3 Normal;
in vec2 TexCoords; in vec2 TexCoords;
in vec2 Light; in vec2 Light;
@ -19,11 +21,17 @@ vec3 blendDarken(vec3 base, vec3 blend, float opacity) {
return (blendDarken(base, blend) * opacity + base * (1.0 - 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 tex = texture2D(BlockAtlas, TexCoords);
vec4 light = texture2D(LightMap, Light); 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);
} }

View file

@ -10,6 +10,7 @@ layout (location = 5) in float speed;
layout (location = 6) in float rotationOffset; layout (location = 6) in float rotationOffset;
layout (location = 7) in vec3 rotationAxis; layout (location = 7) in vec3 rotationAxis;
out vec3 Normal;
out vec2 TexCoords; out vec2 TexCoords;
out vec2 Light; out vec2 Light;
@ -18,8 +19,7 @@ uniform int ticks;
uniform mat4 projection; uniform mat4 projection;
uniform mat4 view; uniform mat4 view;
mat4 kineticRotation() mat4 kineticRotation() {
{
float degrees = rotationOffset + time * speed * -3./10.; float degrees = rotationOffset + time * speed * -3./10.;
float angle = fract(degrees / 360.) * PI * 2.; float angle = fract(degrees / 360.) * PI * 2.;
@ -34,14 +34,14 @@ mat4 kineticRotation()
0., 0., 0., 1.); 0., 0., 0., 1.);
} }
void main() void main() {
{ mat4 rotation = kineticRotation();
vec4 renderPos = kineticRotation() * vec4(aPos - vec3(0.5), 1); vec4 renderPos = rotation * vec4(aPos - vec3(0.5), 1);
renderPos += vec4(instancePos + vec3(0.5), 0); renderPos += vec4(instancePos + vec3(0.5), 0);
TexCoords = aTexCoords; TexCoords = aTexCoords;
Normal = normalize((rotation * vec4(aNormal, 0.)).xyz);
gl_Position = projection * view * renderPos; gl_Position = projection * view * renderPos;
Light = light; Light = light;
} }