Merge pull request #1597 from PepperCode1/contraption-rendering-fixes

Tweak Contraption Rendering
This commit is contained in:
Jozufozu 2021-05-14 18:02:09 -07:00 committed by GitHub
commit e1de6b5f00
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 43 deletions

View file

@ -87,8 +87,8 @@ public class ContraptionModel extends BufferedModel {
int light = getLight(template, vertex);
byte sky = (byte) (LightTexture.getSkyLightCoordinates(light) << 4);
byte block = (byte) (LightTexture.getBlockLightCoordinates(light) << 4);
byte sky = (byte) (LightTexture.getSkyLightCoordinates(light) << 4);
to.put(block);
to.put(sky);

View file

@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.re
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.lwjgl.opengl.GL11;
@ -22,11 +23,10 @@ import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.BlockModelRenderer;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.BlockModelShapes;
import net.minecraft.client.renderer.BufferBuilder;
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.tileentity.TileEntity;
@ -36,20 +36,19 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template;
import net.minecraft.world.lighting.WorldLightManager;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.model.data.EmptyModelData;
public class RenderedContraption {
private final HashMap<RenderType, ContraptionModel> renderLayers = new HashMap<>();
public final PlacementSimulationWorld renderWorld;
private final ContraptionLighter<?> lighter;
public final ContraptionKineticRenderer kinetics;
private static final BlockModelRenderer MODEL_RENDERER = new BlockModelRenderer(Minecraft.getInstance().getBlockColors());
private static final BlockModelShapes BLOCK_MODELS = Minecraft.getInstance().getModelManager().getBlockModelShapes();
public Contraption contraption;
private final ContraptionLighter<?> lighter;
public final ContraptionKineticRenderer kinetics;
public final PlacementSimulationWorld renderWorld;
private final Map<RenderType, ContraptionModel> renderLayers = new HashMap<>();
private Matrix4f model;
private AxisAlignedBB lightBox;
@ -176,44 +175,42 @@ public class RenderedContraption {
for (Template.BlockInfo info : c.getBlocks()
.values())
renderWorld.setBlockState(info.pos, info.state);
// Skip individual lighting updates to prevent lag with large contraptions
renderWorld.setBlockState(info.pos, info.state, 128);
WorldLightManager lighter = renderWorld.lighter;
renderWorld.chunkProvider.getLightSources().forEach((pos) -> lighter.func_215573_a(pos, renderWorld.getLightValue(pos)));
lighter.tick(Integer.MAX_VALUE, true, false);
renderWorld.updateLightSources();
renderWorld.lighter.tick(Integer.MAX_VALUE, false, false);
return renderWorld;
}
private static BufferBuilder buildStructure(PlacementSimulationWorld renderWorld, Contraption c, RenderType layer) {
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);
ForgeHooksClient.setRenderLayer(layer);
BlockModelRenderer.enableCache();
for (Template.BlockInfo info : c.getBlocks()
.values()) {
BlockState state = info.state;
if (state.getRenderType() == BlockRenderType.ENTITYBLOCK_ANIMATED)
if (state.getRenderType() != BlockRenderType.MODEL)
continue;
if (!RenderTypeLookup.canRenderInLayer(state, layer))
continue;
IBakedModel originalModel = dispatcher.getModelForState(state);
BlockPos pos = info.pos;
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.translate(pos.getX(), pos.getY(), pos.getZ());
MODEL_RENDERER.renderModel(renderWorld, BLOCK_MODELS.getModel(state), state, pos, ms, builder, true,
random, 42, OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE);
ms.pop();
}
BlockModelRenderer.disableCache();
ForgeHooksClient.setRenderLayer(null);
builder.finishDrawing();
return builder;

View file

@ -3,6 +3,8 @@ package com.simibubi.create.foundation.utility.worldWrappers;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import com.jozufozu.flywheel.backend.instancing.IFlywheelWorld;
@ -16,10 +18,10 @@ import net.minecraft.world.World;
import net.minecraft.world.lighting.WorldLightManager;
public class PlacementSimulationWorld extends WrappedWorld implements IFlywheelWorld {
public HashMap<BlockPos, BlockState> blocksAdded;
public HashMap<BlockPos, TileEntity> tesAdded;
public Map<BlockPos, BlockState> blocksAdded;
public Map<BlockPos, TileEntity> tesAdded;
public HashSet<SectionPos> spannedChunks;
public Set<SectionPos> spannedSections;
public WorldLightManager lighter;
public WrappedChunkProvider chunkProvider;
private final BlockPos.Mutable scratch = new BlockPos.Mutable();
@ -31,7 +33,7 @@ public class PlacementSimulationWorld extends WrappedWorld implements IFlywheelW
public PlacementSimulationWorld(World wrapped, WrappedChunkProvider chunkProvider) {
super(wrapped, chunkProvider);
this.chunkProvider = chunkProvider.setWorld(this);
spannedChunks = new HashSet<>();
spannedSections = new HashSet<>();
lighter = new WorldLightManager(chunkProvider, true, false); // blockLight, skyLight
blocksAdded = new HashMap<>();
tesAdded = new HashMap<>();
@ -42,6 +44,17 @@ public class PlacementSimulationWorld extends WrappedWorld implements IFlywheelW
return lighter;
}
public void updateLightSources() {
for (Map.Entry<BlockPos, BlockState> entry : blocksAdded.entrySet()) {
BlockPos pos = entry.getKey();
BlockState state = entry.getValue();
int light = state.getLightValue(this, pos);
if (light > 0) {
lighter.func_215573_a(pos, light);
}
}
}
public void setTileEntities(Collection<TileEntity> tileEntities) {
tesAdded.clear();
tileEntities.forEach(te -> tesAdded.put(te.getPos(), te));
@ -53,16 +66,17 @@ public class PlacementSimulationWorld extends WrappedWorld implements IFlywheelW
@Override
public boolean setBlockState(BlockPos pos, BlockState newState, int flags) {
blocksAdded.put(pos, newState);
SectionPos sectionPos = SectionPos.from(pos);
if (spannedChunks.add(sectionPos)) {
if (spannedSections.add(sectionPos)) {
lighter.updateSectionStatus(sectionPos, false);
}
lighter.checkBlock(pos);
if ((flags & 128) == 0) {
lighter.checkBlock(pos);
}
blocksAdded.put(pos, newState);
return true;
}
@ -100,8 +114,6 @@ public class PlacementSimulationWorld extends WrappedWorld implements IFlywheelW
BlockState state = blocksAdded.get(pos);
if (state != null)
return state;
else
return Blocks.AIR.getDefaultState();
return Blocks.AIR.getDefaultState();
}
}

View file

@ -24,5 +24,5 @@ void FLWFinalizeColor(vec4 color) {
vec4 FLWLight(vec2 lightCoords) {
vec2 lm = max(lightCoords, texture3D(uLightVolume, BoxCoord).rg);
return texture2D(uLightMap, lm * 0.9375 + 0.03125);
return texture2D(uLightMap, lm * 0.99609375 + 0.03125); // * 255/256 + 1/32
}

View file

@ -24,11 +24,11 @@ void main() {
FLWFinalizeNormal(norm);
Diffuse = diffuse(norm);
Color = aColor / diffuse(norm);
TexCoords = aTexCoords;
Light = aModelLight;
if (uDebug == 2) {
Color = vec4(norm, 1.);
} else {
Color = aColor / diffuse(aNormal);
}
TexCoords = aTexCoords;
Light = aModelLight;
}