mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-15 22:53:42 +01:00
contraptions self light but man it is slow
optimization in PlacementSimulationWorld.getBlockState
This commit is contained in:
parent
751fc7192d
commit
16b8e1175e
11 changed files with 438 additions and 10 deletions
|
@ -217,6 +217,8 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
|||
@Override
|
||||
protected void read(CompoundNBT compound, boolean clientPacket) {
|
||||
boolean overStressedBefore = overStressed;
|
||||
Long networkBefore = network;
|
||||
float speedBefore = speed;
|
||||
clearKineticInformation();
|
||||
|
||||
// DO NOT READ kinetic information when placed after movement
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement;
|
|||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.world.lighting.WorldLightManager;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
|
@ -101,6 +102,15 @@ public class ContraptionRenderer {
|
|||
for (BlockInfo info : c.getBlocks()
|
||||
.values())
|
||||
renderWorld.setBlockState(info.pos, info.state);
|
||||
|
||||
WorldLightManager lighter = renderWorld.lighter;
|
||||
|
||||
renderWorld.chunkProvider.getLightSources().forEach((pos) -> {
|
||||
lighter.func_215573_a(pos, renderWorld.getLightValue(pos));
|
||||
});
|
||||
|
||||
lighter.tick(Integer.MAX_VALUE, true, false);
|
||||
|
||||
for (BlockInfo info : c.getBlocks()
|
||||
.values()) {
|
||||
BlockState state = info.state;
|
||||
|
@ -120,6 +130,7 @@ public class ContraptionRenderer {
|
|||
|
||||
builder.finishDrawing();
|
||||
renderWorld.clear();
|
||||
renderWorld = null;
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,15 +4,17 @@ import com.simibubi.create.foundation.render.BufferedModel;
|
|||
import com.simibubi.create.foundation.render.instancing.InstancedModel;
|
||||
import com.simibubi.create.foundation.render.instancing.VertexFormat;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL40;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.LIGHT;
|
||||
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.RGBA;
|
||||
|
||||
public class ContraptionModel extends BufferedModel {
|
||||
public static final VertexFormat FORMAT = new VertexFormat(InstancedModel.FORMAT, RGBA);
|
||||
public static final VertexFormat FORMAT = new VertexFormat(InstancedModel.FORMAT, RGBA, LIGHT);
|
||||
|
||||
public ContraptionModel(BufferBuilder buf) {
|
||||
super(buf);
|
||||
|
@ -35,6 +37,14 @@ public class ContraptionModel extends BufferedModel {
|
|||
to.put(getG(template, vertex));
|
||||
to.put(getB(template, vertex));
|
||||
to.put(getA(template, vertex));
|
||||
|
||||
int light = getLight(template, vertex);
|
||||
|
||||
byte sky = (byte) (LightTexture.getSkyLightCoordinates(light) << 4);
|
||||
byte block = (byte) (LightTexture.getBlockLightCoordinates(light) << 4);
|
||||
|
||||
to.put(block);
|
||||
to.put(sky);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,10 +7,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Con
|
|||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
|
||||
import com.simibubi.create.foundation.render.instancing.IInstanceRendered;
|
||||
import com.simibubi.create.foundation.render.instancing.InstancedModel;
|
||||
import com.simibubi.create.foundation.render.instancing.KineticRenderMaterials;
|
||||
import com.simibubi.create.foundation.render.instancing.RenderMaterial;
|
||||
import com.simibubi.create.foundation.render.instancing.*;
|
||||
import com.simibubi.create.foundation.render.instancing.actors.StaticRotatingActorData;
|
||||
import com.simibubi.create.foundation.render.light.ContraptionLighter;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.simibubi.create.foundation.render.gl.shader;
|
|||
public enum Shader {
|
||||
ROTATING("shader/rotating.vert", "shader/instanced.frag"),
|
||||
BELT("shader/belt.vert", "shader/instanced.frag"),
|
||||
CONTRAPTION_STRUCTURE("shader/contraption.vert", "shader/contraption.frag"),
|
||||
CONTRAPTION_STRUCTURE("shader/contraption_structure.vert", "shader/contraption_structure.frag"),
|
||||
CONTRAPTION_ROTATING("shader/contraption_rotating.vert", "shader/contraption.frag"),
|
||||
CONTRAPTION_BELT("shader/contraption_belt.vert", "shader/contraption.frag"),
|
||||
CONTRAPTION_ACTOR("shader/contraption_actor.vert", "shader/contraption.frag"),
|
||||
|
|
|
@ -2,24 +2,50 @@ package com.simibubi.create.foundation.utility.worldWrappers;
|
|||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.simibubi.create.foundation.render.light.GridAlignedBB;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.SectionPos;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.NibbleArray;
|
||||
import net.minecraft.world.lighting.WorldLightManager;
|
||||
|
||||
public class PlacementSimulationWorld extends WrappedWorld {
|
||||
public HashMap<BlockPos, BlockState> blocksAdded;
|
||||
public HashMap<BlockPos, TileEntity> tesAdded;
|
||||
|
||||
public HashSet<SectionPos> spannedChunks;
|
||||
public WorldLightManager lighter;
|
||||
public WrappedChunkProvider chunkProvider;
|
||||
private final BlockPos.Mutable scratch = new BlockPos.Mutable();
|
||||
|
||||
public PlacementSimulationWorld(World wrapped) {
|
||||
super(wrapped);
|
||||
this(wrapped, new WrappedChunkProvider());
|
||||
}
|
||||
|
||||
public PlacementSimulationWorld(World wrapped, WrappedChunkProvider chunkProvider) {
|
||||
super(wrapped, chunkProvider);
|
||||
this.chunkProvider = chunkProvider.setWorld(this);
|
||||
spannedChunks = new HashSet<>();
|
||||
lighter = new WorldLightManager(chunkProvider, true, false); // blockLight, skyLight
|
||||
blocksAdded = new HashMap<>();
|
||||
tesAdded = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldLightManager getLightingProvider() {
|
||||
return lighter;
|
||||
}
|
||||
|
||||
public void setTileEntities(Collection<TileEntity> tileEntities) {
|
||||
tesAdded.clear();
|
||||
tileEntities.forEach(te -> tesAdded.put(te.getPos(), te));
|
||||
|
@ -31,6 +57,15 @@ public class PlacementSimulationWorld extends WrappedWorld {
|
|||
|
||||
@Override
|
||||
public boolean setBlockState(BlockPos pos, BlockState newState, int flags) {
|
||||
|
||||
SectionPos sectionPos = SectionPos.from(pos);
|
||||
|
||||
if (spannedChunks.add(sectionPos)) {
|
||||
lighter.updateSectionStatus(sectionPos, false);
|
||||
}
|
||||
|
||||
lighter.checkBlock(pos);
|
||||
|
||||
blocksAdded.put(pos, newState);
|
||||
return true;
|
||||
}
|
||||
|
@ -62,8 +97,10 @@ public class PlacementSimulationWorld extends WrappedWorld {
|
|||
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
if (blocksAdded.containsKey(pos))
|
||||
return blocksAdded.get(pos);
|
||||
BlockState state = blocksAdded.get(pos);
|
||||
if (state != null)
|
||||
return state;
|
||||
else
|
||||
return Blocks.AIR.getDefaultState();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
package com.simibubi.create.foundation.utility.worldWrappers;
|
||||
|
||||
import com.simibubi.create.foundation.utility.worldWrappers.chunk.WrappedChunk;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.chunk.AbstractChunkProvider;
|
||||
import net.minecraft.world.chunk.ChunkStatus;
|
||||
import net.minecraft.world.chunk.IChunk;
|
||||
import net.minecraft.world.chunk.IChunkLightProvider;
|
||||
import net.minecraft.world.lighting.WorldLightManager;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class WrappedChunkProvider extends AbstractChunkProvider {
|
||||
private PlacementSimulationWorld world;
|
||||
|
||||
public HashMap<Long, WrappedChunk> chunks;
|
||||
|
||||
public WrappedChunkProvider setWorld(PlacementSimulationWorld world) {
|
||||
this.world = world;
|
||||
this.chunks = new HashMap<>();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Stream<BlockPos> getLightSources() {
|
||||
return world.blocksAdded
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(it -> it.getValue().getLightValue(world, it.getKey()) != 0)
|
||||
.map(Map.Entry::getKey);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBlockReader getChunkForLight(int x, int z) {
|
||||
return getChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockReader getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IChunk getChunk(int x, int z, ChunkStatus status, boolean p_212849_4_) {
|
||||
return getChunk(x, z);
|
||||
}
|
||||
|
||||
public WrappedChunk getChunk(int x, int z) {
|
||||
long pos = ChunkPos.asLong(x, z);
|
||||
|
||||
WrappedChunk chunk = chunks.get(pos);
|
||||
|
||||
if (chunk == null) {
|
||||
chunk = new WrappedChunk(world, x, z);
|
||||
chunks.put(pos, chunk);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(BooleanSupplier p_217207_1_) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String makeString() {
|
||||
return "WrappedChunkProvider";
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldLightManager getLightManager() {
|
||||
return world.getLightingProvider();
|
||||
}
|
||||
}
|
|
@ -19,18 +19,30 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.world.ITickList;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.lighting.WorldLightManager;
|
||||
import net.minecraft.world.storage.MapData;
|
||||
|
||||
public class WrappedWorld extends World {
|
||||
|
||||
protected World world;
|
||||
|
||||
public WrappedWorld(World world, WrappedChunkProvider provider) {
|
||||
super(world.getWorldInfo(), world.getDimension().getType(), (w, d) -> provider,
|
||||
world.getProfiler(), world.isRemote);
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public WrappedWorld(World world) {
|
||||
super(world.getWorldInfo(), world.getDimension().getType(), (w, d) -> world.getChunkProvider(),
|
||||
world.getProfiler(), world.isRemote);
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldLightManager getLightingProvider() {
|
||||
return super.getLightingProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return world;
|
||||
|
|
|
@ -0,0 +1,250 @@
|
|||
package com.simibubi.create.foundation.utility.worldWrappers.chunk;
|
||||
|
||||
import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld;
|
||||
import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld;
|
||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import it.unimi.dsi.fastutil.shorts.ShortList;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.palette.UpgradeData;
|
||||
import net.minecraft.world.ITickList;
|
||||
import net.minecraft.world.biome.BiomeContainer;
|
||||
import net.minecraft.world.chunk.ChunkSection;
|
||||
import net.minecraft.world.chunk.ChunkStatus;
|
||||
import net.minecraft.world.chunk.IChunk;
|
||||
import net.minecraft.world.gen.Heightmap;
|
||||
import net.minecraft.world.gen.feature.structure.StructureStart;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class WrappedChunk implements IChunk {
|
||||
|
||||
private final PlacementSimulationWorld world;
|
||||
private boolean needsLight;
|
||||
private final int x;
|
||||
private final int z;
|
||||
private final ChunkPos pos;
|
||||
|
||||
public WrappedChunk(PlacementSimulationWorld world, int x, int z) {
|
||||
this.world = world;
|
||||
this.needsLight = true;
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
this.pos = new ChunkPos(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<BlockPos> getLightSources() {
|
||||
return world.blocksAdded
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(it -> {
|
||||
BlockPos blockPos = it.getKey();
|
||||
boolean chunkContains = blockPos.getX() >> 4 == x && blockPos.getZ() >> 4 == z;
|
||||
return chunkContains && it.getValue().getLightValue(world, blockPos) != 0;
|
||||
})
|
||||
.map(Map.Entry::getKey);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockState setBlockState(BlockPos p_177436_1_, BlockState p_177436_2_, boolean p_177436_3_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTileEntity(BlockPos p_177426_1_, TileEntity p_177426_2_) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntity(Entity p_76612_1_) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<BlockPos> getTileEntitiesPos() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getSections() {
|
||||
return new ChunkSection[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Map.Entry<Heightmap.Type, Heightmap>> func_217311_f() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeightmap(Heightmap.Type p_201607_1_, long[] p_201607_2_) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Heightmap getHeightmap(Heightmap.Type p_217303_1_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTopBlockY(Heightmap.Type p_201576_1_, int p_201576_2_, int p_201576_3_) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkPos getPos() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastSaveTime(long p_177432_1_) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, StructureStart> getStructureStarts() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStructureStarts(Map<String, StructureStart> p_201612_1_) {
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BiomeContainer getBiomeArray() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setModified(boolean p_177427_1_) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkStatus getStatus() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTileEntity(BlockPos p_177425_1_) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShortList[] getPackedPositions() {
|
||||
return new ShortList[0];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CompoundNBT getDeferredTileEntity(BlockPos p_201579_1_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CompoundNBT func_223134_j(BlockPos p_223134_1_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITickList<Block> getBlocksToBeTicked() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITickList<Fluid> getFluidsToBeTicked() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpgradeData getUpgradeData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInhabitedTime(long p_177415_1_) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getInhabitedTime() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLight() {
|
||||
return needsLight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLight(boolean needsLight) {
|
||||
this.needsLight = needsLight;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TileEntity getTileEntity(BlockPos pos) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
return world.getBlockState(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidState getFluidState(BlockPos pos) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public StructureStart getStructureStart(String p_201585_1_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStructureStart(String p_201584_1_, StructureStart p_201584_2_) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongSet getStructureReferences(String p_201578_1_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addStructureReference(String p_201583_1_, long p_201583_2_) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, LongSet> getStructureReferences() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStructureReferences(Map<String, LongSet> p_201606_1_) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#version 440 core
|
||||
|
||||
in vec2 TexCoords;
|
||||
in vec4 Color;
|
||||
in float Diffuse;
|
||||
in vec3 BoxCoord;
|
||||
in vec2 ModelLight;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
layout(binding=0) uniform sampler2D BlockAtlas;
|
||||
layout(binding=2) uniform sampler2D LightMap;
|
||||
layout(binding=4) uniform sampler3D LightVolume;
|
||||
|
||||
vec4 light() {
|
||||
vec2 lm = texture(LightVolume, BoxCoord).rg * 0.9375 + 0.03125;
|
||||
return texture2D(LightMap, max(lm, ModelLight));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 tex = texture2D(BlockAtlas, TexCoords);
|
||||
|
||||
fragColor = vec4(tex.rgb * light().rgb * Diffuse * Color.rgb, tex.a);
|
||||
}
|
|
@ -5,11 +5,13 @@ layout (location = 0) in vec3 aPos;
|
|||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 2) in vec2 aTexCoords;
|
||||
layout (location = 3) in vec4 aColor;
|
||||
layout (location = 4) in vec2 modelLight;
|
||||
|
||||
out float Diffuse;
|
||||
out vec2 TexCoords;
|
||||
out vec4 Color;
|
||||
out vec3 BoxCoord;
|
||||
out vec2 ModelLight;
|
||||
|
||||
uniform vec3 lightBoxSize;
|
||||
uniform vec3 lightBoxMin;
|
||||
|
@ -48,6 +50,7 @@ void main() {
|
|||
Diffuse = diffuse(norm);
|
||||
Color = aColor / diffuse(aNormal);
|
||||
TexCoords = aTexCoords;
|
||||
ModelLight = modelLight;
|
||||
gl_Position = projection * view * worldPos;
|
||||
|
||||
if (debug == 2) {
|
Loading…
Reference in a new issue