mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-10 20:11:35 +01:00
contraption actors take into account self lighting
This commit is contained in:
parent
0ad6db4bf7
commit
951a0c4769
12 changed files with 258 additions and 218 deletions
|
@ -1,7 +1,6 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionRenderer;
|
||||
import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivity;
|
||||
import com.simibubi.create.content.schematics.ClientSchematicLoader;
|
||||
import com.simibubi.create.content.schematics.client.SchematicAndQuillHandler;
|
||||
|
@ -74,7 +73,7 @@ public class CreateClient {
|
|||
|
||||
bufferCache = new SuperByteBufferCache();
|
||||
bufferCache.registerCompartment(KineticTileEntityRenderer.KINETIC_TILE);
|
||||
bufferCache.registerCompartment(ContraptionRenderer.CONTRAPTION, 20);
|
||||
bufferCache.registerCompartment(ContraptionRenderDispatcher.CONTRAPTION, 20);
|
||||
|
||||
AllKeys.register();
|
||||
AllContainerTypes.registerScreenFactories();
|
||||
|
|
|
@ -5,6 +5,7 @@ import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FAC
|
|||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.RenderedContraption;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
|
||||
|
@ -79,7 +80,7 @@ public class HarvesterRenderer extends SafeTileEntityRenderer<HarvesterTileEntit
|
|||
.rotate(Direction.WEST, AngleHelper.rad(angle))
|
||||
.translate(-rotOffset.x, -rotOffset.y, -rotOffset.z)
|
||||
.light(msLocal.peek()
|
||||
.getModel())
|
||||
.getModel(), ContraptionRenderDispatcher.getLightOnContraption(context))
|
||||
.renderInto(ms, buffers.getBuffer(RenderType.getCutoutMipped()));
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.mojang.blaze3d.vertex.IVertexBuilder;
|
|||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
|
@ -52,7 +53,7 @@ public class PortableStorageInterfaceRenderer extends SafeTileEntityRenderer<Por
|
|||
}
|
||||
|
||||
render(blockState, progress, lit, sbb -> sbb.light(msLocal.peek()
|
||||
.getModel())
|
||||
.getModel(), ContraptionRenderDispatcher.getLightOnContraption(context))
|
||||
.renderInto(ms, vb), ms, msLocal);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
|||
import com.simibubi.create.content.contraptions.components.deployer.DeployerTileEntity.Mode;
|
||||
import com.simibubi.create.content.contraptions.components.deployer.DeployerTileEntity.State;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringRenderer;
|
||||
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
||||
|
@ -191,9 +192,9 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
|
|||
.getModel();
|
||||
for (MatrixStack m : matrixStacks)
|
||||
m.translate(offset.x, offset.y, offset.z);
|
||||
pole.light(lighting)
|
||||
pole.light(lighting, ContraptionRenderDispatcher.getLightOnContraption(context))
|
||||
.renderInto(ms, builder);
|
||||
hand.light(lighting)
|
||||
hand.light(lighting, ContraptionRenderDispatcher.getLightOnContraption(context))
|
||||
.renderInto(ms, builder);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.simibubi.create.CreateClient;
|
|||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringRenderer;
|
||||
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
||||
|
@ -183,7 +184,7 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> {
|
|||
|
||||
superBuffer
|
||||
.light(msLocal.peek()
|
||||
.getModel())
|
||||
.getModel(), ContraptionRenderDispatcher.getLightOnContraption(context))
|
||||
.renderInto(ms, buffer.getBuffer(RenderType.getCutoutMipped()));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.culling.ClippingHelperImpl;
|
||||
|
@ -57,12 +56,7 @@ public abstract class AbstractContraptionEntityRenderer<C extends AbstractContra
|
|||
transform(entity, partialTicks, matrixStacks);
|
||||
Contraption contraption = entity.getContraption();
|
||||
if (contraption != null) {
|
||||
if (Backend.canUseVBOs()) {
|
||||
ContraptionRenderer.renderDynamic(entity.world, contraption, ms, msLocal, buffers);
|
||||
}
|
||||
else {
|
||||
ContraptionRenderer.render(entity.world, contraption, ms, msLocal, buffers);
|
||||
}
|
||||
ContraptionRenderDispatcher.render(entity, ms, buffers, msLocal, contraption);
|
||||
}
|
||||
ms.pop();
|
||||
|
||||
|
|
|
@ -1,173 +0,0 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.*;
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllMovementBehaviours;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld;
|
||||
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.Matrix4f;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.RenderTypeLookup;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
||||
public class ContraptionRenderer {
|
||||
|
||||
public static final Compartment<Pair<Contraption, Integer>> CONTRAPTION = new Compartment<>();
|
||||
protected static PlacementSimulationWorld renderWorld;
|
||||
|
||||
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();
|
||||
renderActors(world, c, ms, msLocal, buffer);
|
||||
}
|
||||
|
||||
protected static void renderStructure(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
|
||||
IRenderTypeBuffer buffer) {
|
||||
SuperByteBufferCache bufferCache = CreateClient.bufferCache;
|
||||
List<RenderType> blockLayers = RenderType.getBlockLayers();
|
||||
|
||||
buffer.getBuffer(RenderType.getSolid());
|
||||
for (int i = 0; i < blockLayers.size(); i++) {
|
||||
RenderType layer = blockLayers.get(i);
|
||||
Pair<Contraption, Integer> key = Pair.of(c, i);
|
||||
SuperByteBuffer contraptionBuffer = bufferCache.get(CONTRAPTION, key, () -> buildStructureBuffer(c, layer));
|
||||
if (contraptionBuffer.isEmpty())
|
||||
continue;
|
||||
Matrix4f model = msLocal.peek()
|
||||
.getModel();
|
||||
contraptionBuffer.light(model)
|
||||
.renderInto(ms, buffer.getBuffer(layer));
|
||||
}
|
||||
}
|
||||
|
||||
protected static void renderTileEntities(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
|
||||
IRenderTypeBuffer buffer) {
|
||||
if (Backend.canUseVBOs()) {
|
||||
ContraptionRenderDispatcher.renderTileEntities(world, c, ms, msLocal, buffer);
|
||||
} else {
|
||||
TileEntityRenderHelper.renderTileEntities(world, c.maybeInstancedTileEntities, ms, msLocal, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private static SuperByteBuffer buildStructureBuffer(Contraption c, RenderType layer) {
|
||||
BufferBuilder builder = buildStructure(c, layer);
|
||||
return new SuperByteBuffer(builder);
|
||||
}
|
||||
|
||||
public static BufferBuilder buildStructure(Contraption c, RenderType layer) {
|
||||
if (renderWorld == null || renderWorld.getWorld() != Minecraft.getInstance().world)
|
||||
renderWorld = new PlacementSimulationWorld(Minecraft.getInstance().world);
|
||||
|
||||
ForgeHooksClient.setRenderLayer(layer);
|
||||
MatrixStack ms = new MatrixStack();
|
||||
BlockRendererDispatcher dispatcher = Minecraft.getInstance()
|
||||
.getBlockRendererDispatcher();
|
||||
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
||||
Random random = new Random();
|
||||
BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize());
|
||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
renderWorld.setTileEntities(c.presentTileEntities.values());
|
||||
|
||||
for (BlockInfo info : c.getBlocks()
|
||||
.values())
|
||||
renderWorld.setBlockState(info.pos, info.state);
|
||||
|
||||
for (BlockInfo info : c.getBlocks()
|
||||
.values()) {
|
||||
BlockState state = info.state;
|
||||
|
||||
if (state.getRenderType() == BlockRenderType.ENTITYBLOCK_ANIMATED)
|
||||
continue;
|
||||
if (!RenderTypeLookup.canRenderInLayer(state, layer))
|
||||
continue;
|
||||
|
||||
IBakedModel originalModel = dispatcher.getModelForState(state);
|
||||
ms.push();
|
||||
ms.translate(info.pos.getX(), info.pos.getY(), info.pos.getZ());
|
||||
blockRenderer.renderModel(renderWorld, originalModel, state, info.pos, ms, builder, true, random, 42,
|
||||
OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE);
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
builder.finishDrawing();
|
||||
renderWorld.clear();
|
||||
renderWorld = null;
|
||||
return builder;
|
||||
}
|
||||
|
||||
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()) {
|
||||
MovementContext context = actor.getRight();
|
||||
if (context == null)
|
||||
continue;
|
||||
if (context.world == null)
|
||||
context.world = world;
|
||||
BlockInfo blockInfo = actor.getLeft();
|
||||
for (MatrixStack m : matrixStacks) {
|
||||
m.push();
|
||||
MatrixStacker.of(m)
|
||||
.translate(blockInfo.pos);
|
||||
}
|
||||
|
||||
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state);
|
||||
if (movementBehaviour != null)
|
||||
movementBehaviour.renderInContraption(context, ms, msLocal, buffer);
|
||||
|
||||
for (MatrixStack m : matrixStacks)
|
||||
m.pop();
|
||||
}
|
||||
}
|
||||
|
||||
public static int getLight(World world, float lx, float ly, float lz) {
|
||||
BlockPos.Mutable pos = new BlockPos.Mutable();
|
||||
float sky = 0, block = 0;
|
||||
float offset = 1 / 8f;
|
||||
|
||||
for (float zOffset = offset; zOffset >= -offset; zOffset -= 2 * offset)
|
||||
for (float yOffset = offset; yOffset >= -offset; yOffset -= 2 * offset)
|
||||
for (float xOffset = offset; xOffset >= -offset; xOffset -= 2 * offset) {
|
||||
pos.setPos(lx + xOffset, ly + yOffset, lz + zOffset);
|
||||
sky += world.getLightLevel(LightType.SKY, pos) / 8f;
|
||||
block += world.getLightLevel(LightType.BLOCK, pos) / 8f;
|
||||
}
|
||||
|
||||
return ((int) sky) << 20 | ((int) block) << 4;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.be
|
|||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.*;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
|
@ -57,7 +58,7 @@ public class StabilizedBearingMovementBehaviour extends MovementBehaviour {
|
|||
|
||||
// render
|
||||
superBuffer.light(msLocal.peek()
|
||||
.getModel());
|
||||
.getModel(), ContraptionRenderDispatcher.getLightOnContraption(context));
|
||||
superBuffer.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,45 +1,51 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.render;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntityRenderer;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandler;
|
||||
import com.simibubi.create.foundation.render.AllProgramSpecs;
|
||||
import com.simibubi.create.foundation.render.TileEntityRenderHelper;
|
||||
import com.simibubi.create.AllMovementBehaviours;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.*;
|
||||
import com.simibubi.create.foundation.render.*;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.Pair;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.Matrix4f;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.*;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.SectionPos;
|
||||
import net.minecraft.world.ILightReader;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.template.Template;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL13;
|
||||
import org.lwjgl.opengl.GL40;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
public class ContraptionRenderDispatcher {
|
||||
public static final Int2ObjectMap<RenderedContraption> renderers = new Int2ObjectOpenHashMap<>();
|
||||
public static final Compartment<Pair<Contraption, Integer>> CONTRAPTION = new Compartment<>();
|
||||
protected static PlacementSimulationWorld renderWorld;
|
||||
|
||||
public static void notifyLightUpdate(ILightReader world, LightType type, SectionPos pos) {
|
||||
for (RenderedContraption renderer : renderers.values()) {
|
||||
|
@ -48,6 +54,8 @@ public class ContraptionRenderDispatcher {
|
|||
}
|
||||
|
||||
public static void renderTick(TickEvent.RenderTickEvent event) {
|
||||
if (!Backend.canUseVBOs()) return;
|
||||
|
||||
ClientWorld world = Minecraft.getInstance().world;
|
||||
if (event.phase == TickEvent.Phase.START && world != null) {
|
||||
Map<Integer, WeakReference<AbstractContraptionEntity>> map = ContraptionHandler.loadedContraptions.get(world);
|
||||
|
@ -69,10 +77,14 @@ public class ContraptionRenderDispatcher {
|
|||
}
|
||||
|
||||
public static void renderTileEntities(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
|
||||
IRenderTypeBuffer buffer) {
|
||||
RenderedContraption renderer = getRenderer(world, c);
|
||||
IRenderTypeBuffer buffer) {
|
||||
if (Backend.canUseInstancing()) {
|
||||
RenderedContraption renderer = getRenderer(world, c);
|
||||
|
||||
TileEntityRenderHelper.renderTileEntities(world, renderer.renderWorld, c.specialRenderedTileEntities, ms, msLocal, buffer);
|
||||
TileEntityRenderHelper.renderTileEntities(world, renderer.renderWorld, c.specialRenderedTileEntities, ms, msLocal, buffer);
|
||||
} else {
|
||||
TileEntityRenderHelper.renderTileEntities(world, c.specialRenderedTileEntities, ms, msLocal, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private static <C extends AbstractContraptionEntity> void updateTransform(C c, AbstractContraptionEntityRenderer<C> entityRenderer) {
|
||||
|
@ -152,4 +164,158 @@ public class ContraptionRenderDispatcher {
|
|||
|
||||
renderers.clear();
|
||||
}
|
||||
|
||||
public static void render(AbstractContraptionEntity entity, MatrixStack ms, IRenderTypeBuffer buffers,
|
||||
MatrixStack msLocal, Contraption contraption) {
|
||||
if (Backend.canUseVBOs()) {
|
||||
ContraptionRenderDispatcher.renderDynamic(entity.world, contraption, ms, msLocal, buffers);
|
||||
} else {
|
||||
ContraptionRenderDispatcher.renderDynamic(entity.world, contraption, ms, msLocal, buffers);
|
||||
ContraptionRenderDispatcher.renderStructure(entity.world, contraption, ms, msLocal, buffers);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
renderActors(world, c, ms, msLocal, buffer);
|
||||
}
|
||||
|
||||
public static void renderStructure(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
|
||||
IRenderTypeBuffer buffer) {
|
||||
SuperByteBufferCache bufferCache = CreateClient.bufferCache;
|
||||
List<RenderType> blockLayers = RenderType.getBlockLayers();
|
||||
|
||||
buffer.getBuffer(RenderType.getSolid());
|
||||
for (int i = 0; i < blockLayers.size(); i++) {
|
||||
RenderType layer = blockLayers.get(i);
|
||||
Pair<Contraption, Integer> key = Pair.of(c, i);
|
||||
SuperByteBuffer contraptionBuffer = bufferCache.get(CONTRAPTION, key, () -> buildStructureBuffer(c, layer));
|
||||
if (contraptionBuffer.isEmpty())
|
||||
continue;
|
||||
Matrix4f model = msLocal.peek()
|
||||
.getModel();
|
||||
contraptionBuffer.light(model)
|
||||
.renderInto(ms, buffer.getBuffer(layer));
|
||||
}
|
||||
}
|
||||
|
||||
private static SuperByteBuffer buildStructureBuffer(Contraption c, RenderType layer) {
|
||||
BufferBuilder builder = buildStructure(c, layer);
|
||||
return new SuperByteBuffer(builder);
|
||||
}
|
||||
|
||||
public static BufferBuilder buildStructure(Contraption c, RenderType layer) {
|
||||
if (renderWorld == null || renderWorld.getWorld() != Minecraft.getInstance().world)
|
||||
renderWorld = new PlacementSimulationWorld(Minecraft.getInstance().world);
|
||||
|
||||
ForgeHooksClient.setRenderLayer(layer);
|
||||
MatrixStack ms = new MatrixStack();
|
||||
BlockRendererDispatcher dispatcher = Minecraft.getInstance()
|
||||
.getBlockRendererDispatcher();
|
||||
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
||||
Random random = new Random();
|
||||
BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize());
|
||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
renderWorld.setTileEntities(c.presentTileEntities.values());
|
||||
|
||||
for (Template.BlockInfo info : c.getBlocks()
|
||||
.values())
|
||||
renderWorld.setBlockState(info.pos, info.state);
|
||||
|
||||
for (Template.BlockInfo info : c.getBlocks()
|
||||
.values()) {
|
||||
BlockState state = info.state;
|
||||
|
||||
if (state.getRenderType() == BlockRenderType.ENTITYBLOCK_ANIMATED)
|
||||
continue;
|
||||
if (!RenderTypeLookup.canRenderInLayer(state, layer))
|
||||
continue;
|
||||
|
||||
IBakedModel originalModel = dispatcher.getModelForState(state);
|
||||
ms.push();
|
||||
ms.translate(info.pos.getX(), info.pos.getY(), info.pos.getZ());
|
||||
blockRenderer.renderModel(renderWorld, originalModel, state, info.pos, ms, builder, true, random, 42,
|
||||
OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE);
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
builder.finishDrawing();
|
||||
renderWorld.clear();
|
||||
renderWorld = null;
|
||||
return builder;
|
||||
}
|
||||
|
||||
protected static void renderActors(World world, Contraption c, MatrixStack ms, MatrixStack msLocal,
|
||||
IRenderTypeBuffer buffer) {
|
||||
MatrixStack[] matrixStacks = new MatrixStack[] { ms, msLocal };
|
||||
for (Pair<Template.BlockInfo, MovementContext> actor : c.getActors()) {
|
||||
MovementContext context = actor.getRight();
|
||||
if (context == null)
|
||||
continue;
|
||||
if (context.world == null)
|
||||
context.world = world;
|
||||
Template.BlockInfo blockInfo = actor.getLeft();
|
||||
for (MatrixStack m : matrixStacks) {
|
||||
m.push();
|
||||
MatrixStacker.of(m)
|
||||
.translate(blockInfo.pos);
|
||||
}
|
||||
|
||||
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state);
|
||||
if (movementBehaviour != null)
|
||||
movementBehaviour.renderInContraption(context, ms, msLocal, buffer);
|
||||
|
||||
for (MatrixStack m : matrixStacks)
|
||||
m.pop();
|
||||
}
|
||||
}
|
||||
|
||||
public static int getLight(World world, float lx, float ly, float lz) {
|
||||
BlockPos.Mutable pos = new BlockPos.Mutable();
|
||||
float sky = 0, block = 0;
|
||||
float offset = 1 / 8f;
|
||||
|
||||
for (float zOffset = offset; zOffset >= -offset; zOffset -= 2 * offset)
|
||||
for (float yOffset = offset; yOffset >= -offset; yOffset -= 2 * offset)
|
||||
for (float xOffset = offset; xOffset >= -offset; xOffset -= 2 * offset) {
|
||||
pos.setPos(lx + xOffset, ly + yOffset, lz + zOffset);
|
||||
sky += world.getLightLevel(LightType.SKY, pos) / 8f;
|
||||
block += world.getLightLevel(LightType.BLOCK, pos) / 8f;
|
||||
}
|
||||
|
||||
return ((int) sky) << 20 | ((int) block) << 4;
|
||||
}
|
||||
|
||||
public static int getLightOnContraption(World world, PlacementSimulationWorld renderWorld, BlockPos pos, BlockPos lightPos) {
|
||||
int worldLight = WorldRenderer.getLightmapCoordinates(world, lightPos);
|
||||
|
||||
if (renderWorld != null)
|
||||
return getMaxBlockLight(worldLight, renderWorld.getLightLevel(LightType.BLOCK, pos));
|
||||
|
||||
return worldLight;
|
||||
}
|
||||
|
||||
public static int getMaxBlockLight(int packedLight, int blockLightValue) {
|
||||
int unpackedBlockLight = LightTexture.getBlockLightCoordinates(packedLight);
|
||||
|
||||
if (blockLightValue > unpackedBlockLight) {
|
||||
packedLight = (packedLight & 0xFFFF0000) | (blockLightValue << 4);
|
||||
}
|
||||
|
||||
return packedLight;
|
||||
}
|
||||
|
||||
public static int getLightOnContraption(MovementContext context) {
|
||||
int entityId = context.contraption.entity.getEntityId();
|
||||
|
||||
RenderedContraption renderedContraption = renderers.get(entityId);
|
||||
if (renderedContraption != null) {
|
||||
return renderedContraption.renderWorld.getLightLevel(LightType.BLOCK, context.localPos);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.render;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.render.*;
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllMovementBehaviours;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld;
|
||||
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.Matrix4f;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.RenderTypeLookup;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
||||
public class ContraptionRenderer {
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.foundation.render;
|
|||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
||||
import it.unimi.dsi.fastutil.longs.Long2DoubleMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
|
||||
|
@ -32,6 +33,7 @@ public class SuperByteBuffer extends TemplateBuffer {
|
|||
// Vertex Lighting
|
||||
private boolean shouldLight;
|
||||
private int packedLightCoords;
|
||||
private int otherBlockLight;
|
||||
private Matrix4f lightTransform;
|
||||
|
||||
// Vertex Coloring
|
||||
|
@ -136,7 +138,11 @@ public class SuperByteBuffer extends TemplateBuffer {
|
|||
lightPos.set(((x - f) * 15 / 16f) + f, (y - f) * 15 / 16f + f, (z - f) * 15 / 16f + f, 1F);
|
||||
lightPos.transform(localTransforms);
|
||||
lightPos.transform(lightTransform);
|
||||
|
||||
light = getLight(Minecraft.getInstance().world, lightPos);
|
||||
if (otherBlockLight >= 0) {
|
||||
light = ContraptionRenderDispatcher.getMaxBlockLight(light, otherBlockLight);
|
||||
}
|
||||
}
|
||||
builder.light(light);
|
||||
} else
|
||||
|
@ -150,6 +156,7 @@ public class SuperByteBuffer extends TemplateBuffer {
|
|||
spriteShiftFunc = null;
|
||||
shouldColor = false;
|
||||
shouldLight = false;
|
||||
otherBlockLight = -1;
|
||||
}
|
||||
|
||||
public SuperByteBuffer translate(double x, double y, double z) {
|
||||
|
@ -214,6 +221,13 @@ public class SuperByteBuffer extends TemplateBuffer {
|
|||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer light(Matrix4f lightTransform, int otherBlockLight) {
|
||||
shouldLight = true;
|
||||
this.lightTransform = lightTransform;
|
||||
this.otherBlockLight = otherBlockLight;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer color(int color) {
|
||||
shouldColor = true;
|
||||
r = ((color >> 16) & 0xFF);
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.foundation.render;
|
|||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
|
@ -12,9 +13,7 @@ import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
|||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.model.pipeline.LightUtil;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
|
@ -51,17 +50,7 @@ public class TileEntityRenderHelper {
|
|||
Vector4f vec = new Vector4f(pos.getX() + .5f, pos.getY() + .5f, pos.getZ() + .5f, 1);
|
||||
vec.transform(matrix);
|
||||
BlockPos lightPos = new BlockPos(vec.getX(), vec.getY(), vec.getZ());
|
||||
int worldLight = WorldRenderer.getLightmapCoordinates(world, lightPos);
|
||||
|
||||
if (renderWorld != null) {
|
||||
int contraptionBlockLight = renderWorld.getLightLevel(LightType.BLOCK, pos);
|
||||
|
||||
int worldBlockLight = LightTexture.getBlockLightCoordinates(worldLight);
|
||||
|
||||
if (contraptionBlockLight > worldBlockLight) {
|
||||
worldLight = (worldLight & 0xFFFF0000) | (contraptionBlockLight << 4);
|
||||
}
|
||||
}
|
||||
int worldLight = ContraptionRenderDispatcher.getLightOnContraption(world, renderWorld, pos, lightPos);
|
||||
|
||||
renderer.render(tileEntity, pt, ms, buffer, worldLight,
|
||||
OverlayTexture.DEFAULT_UV);
|
||||
|
|
Loading…
Reference in a new issue