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); int light = getLight(template, vertex);
byte sky = (byte) (LightTexture.getSkyLightCoordinates(light) << 4);
byte block = (byte) (LightTexture.getBlockLightCoordinates(light) << 4); byte block = (byte) (LightTexture.getBlockLightCoordinates(light) << 4);
byte sky = (byte) (LightTexture.getSkyLightCoordinates(light) << 4);
to.put(block); to.put(block);
to.put(sky); 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.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Random; import java.util.Random;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
@ -22,11 +23,10 @@ import net.minecraft.block.BlockState;
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.BlockModelRenderer; 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.BufferBuilder;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderTypeLookup; 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.texture.OverlayTexture;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.tileentity.TileEntity; 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.util.math.vector.Matrix4f;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template; import net.minecraft.world.gen.feature.template.Template;
import net.minecraft.world.lighting.WorldLightManager;
import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.model.data.EmptyModelData; import net.minecraftforge.client.model.data.EmptyModelData;
public class RenderedContraption { public class RenderedContraption {
private final HashMap<RenderType, ContraptionModel> renderLayers = new HashMap<>(); private static final BlockModelRenderer MODEL_RENDERER = new BlockModelRenderer(Minecraft.getInstance().getBlockColors());
private static final BlockModelShapes BLOCK_MODELS = Minecraft.getInstance().getModelManager().getBlockModelShapes();
public final PlacementSimulationWorld renderWorld;
private final ContraptionLighter<?> lighter;
public final ContraptionKineticRenderer kinetics;
public Contraption contraption; 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 Matrix4f model;
private AxisAlignedBB lightBox; private AxisAlignedBB lightBox;
@ -176,44 +175,42 @@ public class RenderedContraption {
for (Template.BlockInfo info : c.getBlocks() for (Template.BlockInfo info : c.getBlocks()
.values()) .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.updateLightSources();
renderWorld.lighter.tick(Integer.MAX_VALUE, false, false);
renderWorld.chunkProvider.getLightSources().forEach((pos) -> lighter.func_215573_a(pos, renderWorld.getLightValue(pos)));
lighter.tick(Integer.MAX_VALUE, true, false);
return renderWorld; return renderWorld;
} }
private static BufferBuilder buildStructure(PlacementSimulationWorld renderWorld, Contraption c, RenderType layer) { private static BufferBuilder buildStructure(PlacementSimulationWorld renderWorld, Contraption c, RenderType layer) {
ForgeHooksClient.setRenderLayer(layer);
MatrixStack ms = new MatrixStack(); MatrixStack ms = new MatrixStack();
BlockRendererDispatcher dispatcher = Minecraft.getInstance()
.getBlockRendererDispatcher();
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
Random random = new Random(); Random random = new Random();
BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize()); BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize());
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
ForgeHooksClient.setRenderLayer(layer);
BlockModelRenderer.enableCache();
for (Template.BlockInfo info : c.getBlocks() for (Template.BlockInfo info : c.getBlocks()
.values()) { .values()) {
BlockState state = info.state; BlockState state = info.state;
if (state.getRenderType() == BlockRenderType.ENTITYBLOCK_ANIMATED) if (state.getRenderType() != BlockRenderType.MODEL)
continue; continue;
if (!RenderTypeLookup.canRenderInLayer(state, layer)) if (!RenderTypeLookup.canRenderInLayer(state, layer))
continue; continue;
IBakedModel originalModel = dispatcher.getModelForState(state); BlockPos pos = info.pos;
ms.push(); ms.push();
ms.translate(info.pos.getX(), info.pos.getY(), info.pos.getZ()); ms.translate(pos.getX(), pos.getY(), pos.getZ());
blockRenderer.renderModel(renderWorld, originalModel, state, info.pos, ms, builder, true, random, 42, MODEL_RENDERER.renderModel(renderWorld, BLOCK_MODELS.getModel(state), state, pos, ms, builder, true,
OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE); random, 42, OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE);
ms.pop(); ms.pop();
} }
BlockModelRenderer.disableCache();
ForgeHooksClient.setRenderLayer(null);
builder.finishDrawing(); builder.finishDrawing();
return builder; return builder;

View file

@ -3,6 +3,8 @@ package com.simibubi.create.foundation.utility.worldWrappers;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;
import com.jozufozu.flywheel.backend.instancing.IFlywheelWorld; import com.jozufozu.flywheel.backend.instancing.IFlywheelWorld;
@ -16,10 +18,10 @@ import net.minecraft.world.World;
import net.minecraft.world.lighting.WorldLightManager; import net.minecraft.world.lighting.WorldLightManager;
public class PlacementSimulationWorld extends WrappedWorld implements IFlywheelWorld { public class PlacementSimulationWorld extends WrappedWorld implements IFlywheelWorld {
public HashMap<BlockPos, BlockState> blocksAdded; public Map<BlockPos, BlockState> blocksAdded;
public HashMap<BlockPos, TileEntity> tesAdded; public Map<BlockPos, TileEntity> tesAdded;
public HashSet<SectionPos> spannedChunks; public Set<SectionPos> spannedSections;
public WorldLightManager lighter; public WorldLightManager lighter;
public WrappedChunkProvider chunkProvider; public WrappedChunkProvider chunkProvider;
private final BlockPos.Mutable scratch = new BlockPos.Mutable(); 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) { public PlacementSimulationWorld(World wrapped, WrappedChunkProvider chunkProvider) {
super(wrapped, chunkProvider); super(wrapped, chunkProvider);
this.chunkProvider = chunkProvider.setWorld(this); this.chunkProvider = chunkProvider.setWorld(this);
spannedChunks = new HashSet<>(); spannedSections = new HashSet<>();
lighter = new WorldLightManager(chunkProvider, true, false); // blockLight, skyLight lighter = new WorldLightManager(chunkProvider, true, false); // blockLight, skyLight
blocksAdded = new HashMap<>(); blocksAdded = new HashMap<>();
tesAdded = new HashMap<>(); tesAdded = new HashMap<>();
@ -42,6 +44,17 @@ public class PlacementSimulationWorld extends WrappedWorld implements IFlywheelW
return lighter; 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) { public void setTileEntities(Collection<TileEntity> tileEntities) {
tesAdded.clear(); tesAdded.clear();
tileEntities.forEach(te -> tesAdded.put(te.getPos(), te)); tileEntities.forEach(te -> tesAdded.put(te.getPos(), te));
@ -53,16 +66,17 @@ public class PlacementSimulationWorld extends WrappedWorld implements IFlywheelW
@Override @Override
public boolean setBlockState(BlockPos pos, BlockState newState, int flags) { public boolean setBlockState(BlockPos pos, BlockState newState, int flags) {
blocksAdded.put(pos, newState);
SectionPos sectionPos = SectionPos.from(pos); SectionPos sectionPos = SectionPos.from(pos);
if (spannedSections.add(sectionPos)) {
if (spannedChunks.add(sectionPos)) {
lighter.updateSectionStatus(sectionPos, false); lighter.updateSectionStatus(sectionPos, false);
} }
lighter.checkBlock(pos); if ((flags & 128) == 0) {
lighter.checkBlock(pos);
}
blocksAdded.put(pos, newState);
return true; return true;
} }
@ -100,8 +114,6 @@ public class PlacementSimulationWorld extends WrappedWorld implements IFlywheelW
BlockState state = blocksAdded.get(pos); BlockState state = blocksAdded.get(pos);
if (state != null) if (state != null)
return state; 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) { vec4 FLWLight(vec2 lightCoords) {
vec2 lm = max(lightCoords, texture3D(uLightVolume, BoxCoord).rg); 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); FLWFinalizeNormal(norm);
Diffuse = diffuse(norm); Diffuse = diffuse(norm);
Color = aColor / diffuse(norm);
TexCoords = aTexCoords;
Light = aModelLight;
if (uDebug == 2) { if (uDebug == 2) {
Color = vec4(norm, 1.); Color = vec4(norm, 1.);
} else {
Color = aColor / diffuse(aNormal);
} }
TexCoords = aTexCoords;
Light = aModelLight;
} }