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.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<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);
public abstract Vec3d getPosition(C contraptionEntity, float partialTicks);
public abstract Vec3d getRotation(C contraptionEntity, float partialTicks);
@Override
public boolean shouldRender(C entity, ClippingHelperImpl p_225626_2_, double p_225626_3_, double p_225626_5_,
double p_225626_7_) {
@ -47,8 +52,10 @@ public abstract class AbstractContraptionEntityRenderer<C extends AbstractContra
ms.push();
transform(entity, partialTicks, matrixStacks);
Contraption contraption = entity.getContraption();
if (contraption != null)
if (contraption != null) {
ContraptionRenderer.render(entity.world, contraption, ms, msLocal, buffers);
// not ready yet FastContraptionRenderer.markForRendering(entity.world, contraption, getPosition(entity, partialTicks), getRotation(entity, partialTicks));
}
ms.pop();
}

View file

@ -43,10 +43,15 @@ public class ContraptionRenderer {
public static void render(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
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);
if (buffer instanceof IRenderTypeBuffer.Impl)
((IRenderTypeBuffer.Impl) buffer).draw();
renderStructure(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) {
TileEntityRenderHelper.renderTileEntities(world, c.renderedTileEntities, ms, msLocal, buffer);
}
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)
renderWorld = new PlacementSimulationWorld(Minecraft.getInstance().world);
@ -110,10 +120,10 @@ public class ContraptionRenderer {
builder.finishDrawing();
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) {
MatrixStack[] matrixStacks = new MatrixStack[] { ms, msLocal };
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.util.Direction.Axis;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
public class ControlledContraptionEntityRenderer extends AbstractContraptionEntityRenderer<ControlledContraptionEntity> {
@ -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");
}
}

View file

@ -56,6 +56,17 @@ 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) {
AbstractContraptionEntity parent = (AbstractContraptionEntity) ridingEntity;
@ -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.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();

View file

@ -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<Object> {
protected void apply(Object $, IResourceManager resourceManagerIn, IProfiler profilerIn) {
SpriteShifter.reloadUVs();
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.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();
}
}

View file

@ -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<BeltBuffer.BeltData> {
}
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);

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) {
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()
@ -130,19 +93,56 @@ public class FastKineticRenderer {
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) {

View file

@ -129,7 +129,7 @@ public abstract class InstancedBuffer<T> 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<T> 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);
}

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) {
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);

View file

@ -128,7 +128,6 @@ public class SuperByteBufferCache {
public void invalidate() {
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 {
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;

View file

@ -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<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) {
useShader(shader, null);
}

View file

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

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

View file

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