mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-16 00:03:41 +01:00
Event system, sort of untangle backend
This commit is contained in:
parent
bef6d77a59
commit
9bac709dfd
39 changed files with 541 additions and 414 deletions
|
@ -1,19 +1,10 @@
|
||||||
package com.jozufozu.flywheel.backend;
|
package com.jozufozu.flywheel.backend;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL20.GL_TEXTURE0;
|
|
||||||
import static org.lwjgl.opengl.GL20.GL_TEXTURE4;
|
|
||||||
import static org.lwjgl.opengl.GL20.GL_TEXTURE_2D;
|
|
||||||
import static org.lwjgl.opengl.GL20.glActiveTexture;
|
|
||||||
import static org.lwjgl.opengl.GL20.glBindTexture;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.BitSet;
|
|
||||||
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.Map;
|
||||||
import java.util.SortedSet;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
@ -23,56 +14,27 @@ import org.lwjgl.opengl.GLCapabilities;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
||||||
import com.jozufozu.flywheel.backend.instancing.TileInstanceManager;
|
|
||||||
import com.jozufozu.flywheel.core.CrumblingInstanceManager;
|
|
||||||
import com.jozufozu.flywheel.core.QuadConverter;
|
|
||||||
import com.jozufozu.flywheel.core.WorldContext;
|
import com.jozufozu.flywheel.core.WorldContext;
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
|
||||||
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
|
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
|
||||||
import com.jozufozu.flywheel.util.WorldAttached;
|
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
|
||||||
import net.minecraft.client.renderer.DestroyBlockProgress;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.client.renderer.WorldRenderer;
|
|
||||||
import net.minecraft.client.renderer.model.ModelBakery;
|
|
||||||
import net.minecraft.client.renderer.texture.Texture;
|
|
||||||
import net.minecraft.client.renderer.texture.TextureManager;
|
|
||||||
import net.minecraft.client.world.ClientWorld;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.inventory.container.PlayerContainer;
|
|
||||||
import net.minecraft.resources.IReloadableResourceManager;
|
import net.minecraft.resources.IReloadableResourceManager;
|
||||||
import net.minecraft.resources.IResourceManager;
|
import net.minecraft.resources.IResourceManager;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.util.LazyValue;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class Backend {
|
public class Backend {
|
||||||
public static final Logger log = LogManager.getLogger(Backend.class);
|
public static final Logger log = LogManager.getLogger(Backend.class);
|
||||||
|
|
||||||
public static final ShaderLoader shaderLoader = new ShaderLoader();
|
public static final ShaderSources SHADER_SOURCES = new ShaderSources();
|
||||||
public static final FlywheelListeners listeners = new FlywheelListeners();
|
|
||||||
|
|
||||||
public static GLCapabilities capabilities;
|
public static GLCapabilities capabilities;
|
||||||
public static GlCompat compat;
|
public static GlCompat compat;
|
||||||
|
|
||||||
public static WorldAttached<TileInstanceManager> tileInstanceManager = new WorldAttached<>(world -> new TileInstanceManager(WorldContext.INSTANCE.getMaterialManager(world)));
|
|
||||||
public static LazyValue<Vector<CrumblingInstanceManager>> blockBreaking = new LazyValue<>(() -> {
|
|
||||||
Vector<CrumblingInstanceManager> renderers = new Vector<>(10);
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
renderers.add(new CrumblingInstanceManager());
|
|
||||||
}
|
|
||||||
return renderers;
|
|
||||||
});
|
|
||||||
|
|
||||||
private static Matrix4f projectionMatrix = new Matrix4f();
|
private static Matrix4f projectionMatrix = new Matrix4f();
|
||||||
private static boolean instancedArrays;
|
private static boolean instancedArrays;
|
||||||
private static boolean enabled;
|
private static boolean enabled;
|
||||||
|
@ -84,26 +46,6 @@ public class Backend {
|
||||||
static {
|
static {
|
||||||
register(WorldContext.INSTANCE);
|
register(WorldContext.INSTANCE);
|
||||||
register(WorldContext.CRUMBLING);
|
register(WorldContext.CRUMBLING);
|
||||||
|
|
||||||
listeners.refreshListener(world -> {
|
|
||||||
if (canUseInstancing() && world != null) {
|
|
||||||
TileInstanceManager tileRenderer = Backend.tileInstanceManager.get(world);
|
|
||||||
tileRenderer.invalidate();
|
|
||||||
world.loadedTileEntityList.forEach(tileRenderer::add);
|
|
||||||
}
|
|
||||||
|
|
||||||
QuadConverter quadConverter = QuadConverter.getNullable();
|
|
||||||
if (quadConverter != null) quadConverter.free();
|
|
||||||
});
|
|
||||||
|
|
||||||
listeners.setupFrameListener((world, stack, info, gameRenderer, lightTexture) -> {
|
|
||||||
WorldContext.INSTANCE.materialManager.get(world)
|
|
||||||
.checkAndShiftOrigin(info);
|
|
||||||
Backend.tileInstanceManager.get(world)
|
|
||||||
.beginFrame(info);
|
|
||||||
});
|
|
||||||
|
|
||||||
listeners.renderLayerListener(Backend::renderLayer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Backend() {
|
public Backend() {
|
||||||
|
@ -165,7 +107,7 @@ public class Backend {
|
||||||
/**
|
/**
|
||||||
* Used to avoid calling Flywheel functions on (fake) worlds that don't specifically support it.
|
* Used to avoid calling Flywheel functions on (fake) worlds that don't specifically support it.
|
||||||
*/
|
*/
|
||||||
public static boolean isFlywheelWorld(World world) {
|
public static boolean isFlywheelWorld(IWorld world) {
|
||||||
return (world instanceof IFlywheelWorld && ((IFlywheelWorld) world).supportsFlywheel()) || world == Minecraft.getInstance().world;
|
return (world instanceof IFlywheelWorld && ((IFlywheelWorld) world).supportsFlywheel()) || world == Minecraft.getInstance().world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,8 +139,10 @@ public class Backend {
|
||||||
IResourceManager manager = mc.getResourceManager();
|
IResourceManager manager = mc.getResourceManager();
|
||||||
|
|
||||||
if (manager instanceof IReloadableResourceManager) {
|
if (manager instanceof IReloadableResourceManager) {
|
||||||
((IReloadableResourceManager) manager).addReloadListener(shaderLoader);
|
((IReloadableResourceManager) manager).addReloadListener(SHADER_SOURCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OptifineHandler.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void refresh() {
|
public static void refresh() {
|
||||||
|
@ -213,84 +157,6 @@ public class Backend {
|
||||||
enabled = AllConfigs.CLIENT.experimentalRendering.get() && !OptifineHandler.usingShaders();
|
enabled = AllConfigs.CLIENT.experimentalRendering.get() && !OptifineHandler.usingShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tick() {
|
|
||||||
Minecraft mc = Minecraft.getInstance();
|
|
||||||
ClientWorld world = mc.world;
|
|
||||||
|
|
||||||
TileInstanceManager instancer = tileInstanceManager.get(world);
|
|
||||||
|
|
||||||
Entity renderViewEntity = mc.renderViewEntity;
|
|
||||||
instancer.tick(renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void renderLayer(ClientWorld world, RenderType layer, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
|
||||||
if (!canUseInstancing(world)) return;
|
|
||||||
MaterialManager<WorldProgram> materialManager = WorldContext.INSTANCE.getMaterialManager(world);
|
|
||||||
|
|
||||||
layer.startDrawing();
|
|
||||||
|
|
||||||
materialManager.render(layer, viewProjection, cameraX, cameraY, cameraZ);
|
|
||||||
|
|
||||||
layer.endDrawing();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final RenderType CRUMBLING = ModelBakery.BLOCK_DESTRUCTION_RENDER_LAYERS.get(0);
|
|
||||||
|
|
||||||
public static void renderBreaking(ClientWorld world, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
|
||||||
if (!canUseInstancing(world)) return;
|
|
||||||
|
|
||||||
WorldRenderer worldRenderer = Minecraft.getInstance().worldRenderer;
|
|
||||||
Long2ObjectMap<SortedSet<DestroyBlockProgress>> breakingProgressions = worldRenderer.blockBreakingProgressions;
|
|
||||||
|
|
||||||
if (breakingProgressions.isEmpty()) return;
|
|
||||||
Vector<CrumblingInstanceManager> renderers = blockBreaking.getValue();
|
|
||||||
|
|
||||||
BitSet bitSet = new BitSet(10);
|
|
||||||
|
|
||||||
for (Long2ObjectMap.Entry<SortedSet<DestroyBlockProgress>> entry : breakingProgressions.long2ObjectEntrySet()) {
|
|
||||||
BlockPos breakingPos = BlockPos.fromLong(entry.getLongKey());
|
|
||||||
|
|
||||||
SortedSet<DestroyBlockProgress> progresses = entry.getValue();
|
|
||||||
if (progresses != null && !progresses.isEmpty()) {
|
|
||||||
int blockDamage = progresses.last().getPartialBlockDamage();
|
|
||||||
bitSet.set(blockDamage);
|
|
||||||
renderers.get(blockDamage).add(world.getTileEntity(breakingPos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureManager textureManager = Minecraft.getInstance().textureManager;
|
|
||||||
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE).getGlTextureId());
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE4);
|
|
||||||
|
|
||||||
CRUMBLING.startDrawing();
|
|
||||||
bitSet.stream().forEach(i -> {
|
|
||||||
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(i));
|
|
||||||
CrumblingInstanceManager renderer = renderers.get(i);
|
|
||||||
renderer.beginFrame(info);
|
|
||||||
|
|
||||||
if (breaking != null) {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
|
||||||
renderer.materialManager.render(RenderType.getCutoutMipped(), viewProjection, cameraX, cameraY, cameraZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.invalidate();
|
|
||||||
});
|
|
||||||
CRUMBLING.endDrawing();
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(0));
|
|
||||||
if (breaking != null)
|
|
||||||
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void enqueueUpdate(TileEntity te) {
|
|
||||||
tileInstanceManager.get(te.getWorld()).queueUpdate(te);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void reloadWorldRenderers() {
|
public static void reloadWorldRenderers() {
|
||||||
RenderWork.enqueue(Minecraft.getInstance().worldRenderer::loadRenderers);
|
RenderWork.enqueue(Minecraft.getInstance().worldRenderer::loadRenderers);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.client.world.ClientWorld;
|
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
|
||||||
|
|
||||||
public class FlywheelListeners {
|
|
||||||
|
|
||||||
private final List<SetupFrame> setupFrameListeners = new ArrayList<>();
|
|
||||||
private final List<RenderLayer> renderLayerListeners = new ArrayList<>();
|
|
||||||
private final List<Refresh> refreshListeners = new ArrayList<>();
|
|
||||||
|
|
||||||
public void setupFrameListener(SetupFrame setupFrame) {
|
|
||||||
setupFrameListeners.add(setupFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderLayerListener(RenderLayer renderLayer) {
|
|
||||||
renderLayerListeners.add(renderLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refreshListener(Refresh refresh) {
|
|
||||||
refreshListeners.add(refresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setupFrame(ClientWorld world, MatrixStack stack, ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture) {
|
|
||||||
for (SetupFrame listener : setupFrameListeners) {
|
|
||||||
listener.setupFrame(world, stack, info, gameRenderer, lightTexture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderLayer(ClientWorld world, RenderType type, Matrix4f stack, double camX, double camY, double camZ) {
|
|
||||||
for (RenderLayer listener : renderLayerListeners) {
|
|
||||||
listener.renderLayer(world, type, stack, camX, camY, camZ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refresh(ClientWorld world) {
|
|
||||||
for (Refresh listener : refreshListeners) {
|
|
||||||
listener.refresh(world);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface SetupFrame {
|
|
||||||
void setupFrame(ClientWorld world, MatrixStack stack, ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture);
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface RenderLayer {
|
|
||||||
void renderLayer(ClientWorld world, RenderType type, Matrix4f viewProjection, double camX, double camY, double camZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface Refresh {
|
|
||||||
void refresh(ClientWorld world);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,10 +3,18 @@ package com.jozufozu.flywheel.backend;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
|
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber
|
||||||
public class RenderWork {
|
public class RenderWork {
|
||||||
private static final Queue<Runnable> runs = new ConcurrentLinkedQueue<>();
|
private static final Queue<Runnable> runs = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
public static void runAll() {
|
|
||||||
|
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||||
|
public static void onRenderWorldLast(RenderWorldLastEvent event) {
|
||||||
while (!runs.isEmpty()) {
|
while (!runs.isEmpty()) {
|
||||||
runs.remove().run();
|
runs.remove().run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,18 +20,19 @@ public abstract class ShaderContext<P extends GlProgram> {
|
||||||
|
|
||||||
protected ShaderTransformer transformer = new ShaderTransformer();
|
protected ShaderTransformer transformer = new ShaderTransformer();
|
||||||
|
|
||||||
public ShaderContext() { }
|
public ShaderContext() {
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Untangle the loading functions
|
// TODO: Untangle the loading functions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load all programs associated with this context. This might be just one, if the context is very specialized.
|
* Load all programs associated with this context. This might be just one, if the context is very specialized.
|
||||||
*/
|
*/
|
||||||
public abstract void load(ShaderLoader loader);
|
public abstract void load(ShaderSources loader);
|
||||||
|
|
||||||
protected abstract IMultiProgram<P> loadSpecInternal(ShaderLoader loader, ProgramSpec spec);
|
protected abstract IMultiProgram<P> loadSpecInternal(ShaderSources loader, ProgramSpec spec);
|
||||||
|
|
||||||
public void loadProgramFromSpec(ShaderLoader loader, ProgramSpec programSpec) {
|
public void loadProgramFromSpec(ShaderSources loader, ProgramSpec programSpec) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
programs.put(programSpec.name, loadSpecInternal(loader, programSpec));
|
programs.put(programSpec.name, loadSpecInternal(loader, programSpec));
|
||||||
|
@ -43,7 +44,7 @@ public abstract class ShaderContext<P extends GlProgram> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Program loadProgram(ShaderLoader loader, ProgramSpec spec, Collection<String> defines) {
|
public Program loadProgram(ShaderSources loader, ProgramSpec spec, Collection<String> defines) {
|
||||||
Shader vertexFile = loader.source(spec.vert, ShaderType.VERTEX);
|
Shader vertexFile = loader.source(spec.vert, ShaderType.VERTEX);
|
||||||
Shader fragmentFile = loader.source(spec.frag, ShaderType.FRAGMENT);
|
Shader fragmentFile = loader.source(spec.frag, ShaderType.FRAGMENT);
|
||||||
|
|
||||||
|
|
|
@ -12,14 +12,9 @@ import java.nio.channels.ReadableByteChannel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
@ -52,14 +47,11 @@ import net.minecraftforge.resource.ISelectiveResourceReloadListener;
|
||||||
import net.minecraftforge.resource.VanillaResourceType;
|
import net.minecraftforge.resource.VanillaResourceType;
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public class ShaderLoader implements ISelectiveResourceReloadListener {
|
public class ShaderSources implements ISelectiveResourceReloadListener {
|
||||||
public static final String SHADER_DIR = "flywheel/shaders/";
|
public static final String SHADER_DIR = "flywheel/shaders/";
|
||||||
public static final String PROGRAM_DIR = "flywheel/programs/";
|
public static final String PROGRAM_DIR = "flywheel/programs/";
|
||||||
public static final ArrayList<String> EXTENSIONS = Lists.newArrayList(".vert", ".vsh", ".frag", ".fsh", ".glsl");
|
public static final ArrayList<String> EXTENSIONS = Lists.newArrayList(".vert", ".vsh", ".frag", ".fsh", ".glsl");
|
||||||
|
|
||||||
// #flwinclude <"valid_namespace:valid/path_to_file.glsl">
|
|
||||||
private static final Pattern includePattern = Pattern.compile("#flwinclude <\"([\\w\\d_]+:[\\w\\d_./]+)\">");
|
|
||||||
|
|
||||||
private final Map<ResourceLocation, String> shaderSource = new HashMap<>();
|
private final Map<ResourceLocation, String> shaderSource = new HashMap<>();
|
||||||
|
|
||||||
private boolean shouldCrash;
|
private boolean shouldCrash;
|
||||||
|
@ -161,7 +153,7 @@ public class ShaderLoader implements ISelectiveResourceReloadListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Shader source(ResourceLocation name, ShaderType type) {
|
public Shader source(ResourceLocation name, ShaderType type) {
|
||||||
return new Shader(type, name, getShaderSource(name));
|
return new Shader(this, type, name, getShaderSource(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Program loadProgram(ResourceLocation name, Shader... shaders) {
|
public Program loadProgram(ResourceLocation name, Shader... shaders) {
|
||||||
|
@ -201,38 +193,6 @@ public class ShaderLoader implements ISelectiveResourceReloadListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processIncludes(Shader shader) {
|
|
||||||
HashSet<ResourceLocation> seen = new HashSet<>();
|
|
||||||
seen.add(shader.name);
|
|
||||||
|
|
||||||
String includesInjected = includeRecursive(shader.getSource(), seen).collect(Collectors.joining("\n"));
|
|
||||||
shader.setSource(includesInjected);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Stream<String> includeRecursive(String source, Set<ResourceLocation> seen) {
|
|
||||||
return lines(source).flatMap(line -> {
|
|
||||||
|
|
||||||
Matcher matcher = includePattern.matcher(line);
|
|
||||||
|
|
||||||
if (matcher.find()) {
|
|
||||||
String includeName = matcher.group(1);
|
|
||||||
|
|
||||||
ResourceLocation include = new ResourceLocation(includeName);
|
|
||||||
|
|
||||||
if (seen.add(include)) {
|
|
||||||
try {
|
|
||||||
return includeRecursive(getShaderSource(include), seen);
|
|
||||||
} catch (ShaderLoadingException e) {
|
|
||||||
throw new ShaderLoadingException("could not resolve import: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return Stream.of(line);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Stream<String> lines(String s) {
|
public static Stream<String> lines(String s) {
|
||||||
return new BufferedReader(new StringReader(s)).lines();
|
return new BufferedReader(new StringReader(s)).lines();
|
||||||
}
|
}
|
|
@ -49,8 +49,8 @@ public class InstanceMaterial<D extends InstanceData> {
|
||||||
|
|
||||||
this.models = CacheBuilder.newBuilder()
|
this.models = CacheBuilder.newBuilder()
|
||||||
.removalListener(notification -> {
|
.removalListener(notification -> {
|
||||||
Instancer<?> model = (Instancer<?>) notification.getValue();
|
Instancer<?> instancer = (Instancer<?>) notification.getValue();
|
||||||
RenderWork.enqueue(model::delete);
|
RenderWork.enqueue(instancer::delete);
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
modelFormat = this.spec.getModelFormat();
|
modelFormat = this.spec.getModelFormat();
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||||
|
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||||
|
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;
|
||||||
|
import static org.lwjgl.opengl.GL13.GL_TEXTURE4;
|
||||||
|
import static org.lwjgl.opengl.GL13.glActiveTexture;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
import com.jozufozu.flywheel.core.CrumblingInstanceManager;
|
||||||
|
import com.jozufozu.flywheel.core.WorldContext;
|
||||||
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
|
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||||
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
|
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||||
|
import com.jozufozu.flywheel.util.WorldAttached;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
|
import net.minecraft.client.renderer.DestroyBlockProgress;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.renderer.WorldRenderer;
|
||||||
|
import net.minecraft.client.renderer.model.ModelBakery;
|
||||||
|
import net.minecraft.client.renderer.texture.Texture;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureManager;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.inventory.container.PlayerContainer;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.LazyValue;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
import net.minecraft.world.IWorld;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber
|
||||||
|
public class InstancedRenderDispatcher {
|
||||||
|
|
||||||
|
private static final RenderType CRUMBLING = ModelBakery.BLOCK_DESTRUCTION_RENDER_LAYERS.get(0);
|
||||||
|
|
||||||
|
private static final WorldAttached<TileInstanceManager> tileInstanceManager = new WorldAttached<>(world -> new TileInstanceManager(WorldContext.INSTANCE.getMaterialManager(world)));
|
||||||
|
public static LazyValue<Vector<CrumblingInstanceManager>> blockBreaking = new LazyValue<>(() -> {
|
||||||
|
Vector<CrumblingInstanceManager> renderers = new Vector<>(10);
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
renderers.add(new CrumblingInstanceManager());
|
||||||
|
}
|
||||||
|
return renderers;
|
||||||
|
});
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static TileInstanceManager get(IWorld world) {
|
||||||
|
return tileInstanceManager.get(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void tick() {
|
||||||
|
Minecraft mc = Minecraft.getInstance();
|
||||||
|
ClientWorld world = mc.world;
|
||||||
|
|
||||||
|
TileInstanceManager instancer = get(world);
|
||||||
|
|
||||||
|
Entity renderViewEntity = mc.renderViewEntity;
|
||||||
|
instancer.tick(renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void enqueueUpdate(TileEntity te) {
|
||||||
|
get(te.getWorld()).queueUpdate(te);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onBeginFrame(BeginFrameEvent event) {
|
||||||
|
WorldContext.INSTANCE.getMaterialManager(event.getWorld())
|
||||||
|
.checkAndShiftOrigin(event.getInfo());
|
||||||
|
get(event.getWorld())
|
||||||
|
.beginFrame(event.getInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void renderLayer(RenderLayerEvent event) {
|
||||||
|
ClientWorld world = event.getWorld();
|
||||||
|
if (!Backend.canUseInstancing(world)) return;
|
||||||
|
MaterialManager<WorldProgram> materialManager = WorldContext.INSTANCE.getMaterialManager(world);
|
||||||
|
|
||||||
|
event.type.startDrawing();
|
||||||
|
|
||||||
|
materialManager.render(event.type, event.viewProjection, event.camX, event.camY, event.camZ);
|
||||||
|
|
||||||
|
event.type.endDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
||||||
|
ClientWorld world = event.getWorld();
|
||||||
|
if (Backend.canUseInstancing() && world != null) {
|
||||||
|
WorldContext.INSTANCE.getMaterialManager(world).delete();
|
||||||
|
|
||||||
|
TileInstanceManager tileRenderer = get(world);
|
||||||
|
tileRenderer.invalidate();
|
||||||
|
world.loadedTileEntityList.forEach(tileRenderer::add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void renderBreaking(ClientWorld world, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
||||||
|
if (!Backend.canUseInstancing(world)) return;
|
||||||
|
|
||||||
|
WorldRenderer worldRenderer = Minecraft.getInstance().worldRenderer;
|
||||||
|
Long2ObjectMap<SortedSet<DestroyBlockProgress>> breakingProgressions = worldRenderer.blockBreakingProgressions;
|
||||||
|
|
||||||
|
if (breakingProgressions.isEmpty()) return;
|
||||||
|
Vector<CrumblingInstanceManager> renderers = blockBreaking.getValue();
|
||||||
|
|
||||||
|
BitSet bitSet = new BitSet(10);
|
||||||
|
|
||||||
|
for (Long2ObjectMap.Entry<SortedSet<DestroyBlockProgress>> entry : breakingProgressions.long2ObjectEntrySet()) {
|
||||||
|
BlockPos breakingPos = BlockPos.fromLong(entry.getLongKey());
|
||||||
|
|
||||||
|
SortedSet<DestroyBlockProgress> progresses = entry.getValue();
|
||||||
|
if (progresses != null && !progresses.isEmpty()) {
|
||||||
|
int blockDamage = progresses.last().getPartialBlockDamage();
|
||||||
|
bitSet.set(blockDamage);
|
||||||
|
renderers.get(blockDamage).add(world.getTileEntity(breakingPos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureManager textureManager = Minecraft.getInstance().textureManager;
|
||||||
|
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE).getGlTextureId());
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE4);
|
||||||
|
|
||||||
|
CRUMBLING.startDrawing();
|
||||||
|
bitSet.stream().forEach(i -> {
|
||||||
|
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(i));
|
||||||
|
CrumblingInstanceManager renderer = renderers.get(i);
|
||||||
|
renderer.beginFrame(info);
|
||||||
|
|
||||||
|
if (breaking != null) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
||||||
|
renderer.materialManager.render(RenderType.getCutoutMipped(), viewProjection, cameraX, cameraY, cameraZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.invalidate();
|
||||||
|
});
|
||||||
|
CRUMBLING.endDrawing();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(0));
|
||||||
|
if (breaking != null)
|
||||||
|
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -24,8 +25,8 @@ public class TileInstanceManager implements MaterialManager.OriginShiftListener
|
||||||
protected final ConcurrentHashMap.KeySetView<TileEntity, Boolean> queuedUpdates;
|
protected final ConcurrentHashMap.KeySetView<TileEntity, Boolean> queuedUpdates;
|
||||||
|
|
||||||
protected final Map<TileEntity, TileEntityInstance<?>> instances;
|
protected final Map<TileEntity, TileEntityInstance<?>> instances;
|
||||||
protected final Map<TileEntity, ITickableInstance> tickableInstances;
|
protected final Object2ObjectOpenHashMap<TileEntity, ITickableInstance> tickableInstances;
|
||||||
protected final Map<TileEntity, IDynamicInstance> dynamicInstances;
|
protected final Object2ObjectOpenHashMap<TileEntity, IDynamicInstance> dynamicInstances;
|
||||||
|
|
||||||
protected int frame;
|
protected int frame;
|
||||||
protected int tick;
|
protected int tick;
|
||||||
|
@ -34,10 +35,11 @@ public class TileInstanceManager implements MaterialManager.OriginShiftListener
|
||||||
this.materialManager = materialManager;
|
this.materialManager = materialManager;
|
||||||
this.queuedUpdates = ConcurrentHashMap.newKeySet(64);
|
this.queuedUpdates = ConcurrentHashMap.newKeySet(64);
|
||||||
this.queuedAdditions = new ArrayList<>(64);
|
this.queuedAdditions = new ArrayList<>(64);
|
||||||
this.dynamicInstances = new HashMap<>();
|
|
||||||
this.tickableInstances = new HashMap<>();
|
|
||||||
this.instances = new HashMap<>();
|
this.instances = new HashMap<>();
|
||||||
|
|
||||||
|
this.dynamicInstances = new Object2ObjectOpenHashMap<>();
|
||||||
|
this.tickableInstances = new Object2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
materialManager.onOriginShift(this);
|
materialManager.onOriginShift(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,10 +91,11 @@ public class TileInstanceManager implements MaterialManager.OriginShiftListener
|
||||||
int cZ = (int) info.getProjectedView().z;
|
int cZ = (int) info.getProjectedView().z;
|
||||||
|
|
||||||
if (dynamicInstances.size() > 0) {
|
if (dynamicInstances.size() > 0) {
|
||||||
for (IDynamicInstance dyn : dynamicInstances.values()) {
|
dynamicInstances.object2ObjectEntrySet().fastForEach(e -> {
|
||||||
if (!dyn.decreaseFramerateWithDistance() || shouldTick(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ))
|
IDynamicInstance dyn = e.getValue();
|
||||||
|
if (!dyn.decreaseFramerateWithDistance() || shouldFrameUpdate(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ))
|
||||||
dyn.beginFrame();
|
dyn.beginFrame();
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,14 +187,15 @@ public class TileInstanceManager implements MaterialManager.OriginShiftListener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean shouldTick(BlockPos worldPos, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
|
protected boolean shouldFrameUpdate(BlockPos worldPos, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
|
||||||
int dX = worldPos.getX() - cX;
|
int dX = worldPos.getX() - cX;
|
||||||
int dY = worldPos.getY() - cY;
|
int dY = worldPos.getY() - cY;
|
||||||
int dZ = worldPos.getZ() - cZ;
|
int dZ = worldPos.getZ() - cZ;
|
||||||
|
|
||||||
float dot = (dX + lookX * 2) * lookX + (dY + lookY * 2) * lookY + (dZ + lookZ * 2) * lookZ;
|
// is it more than 2 blocks behind the camera?
|
||||||
|
int dist = 2;
|
||||||
if (dot < 0) return false; // is it more than 2 blocks behind the camera?
|
float dot = (dX + lookX * dist) * lookX + (dY + lookY * dist) * lookY + (dZ + lookZ * dist) * lookZ;
|
||||||
|
if (dot < 0) return false;
|
||||||
|
|
||||||
return (frame % getUpdateDivisor(dX, dY, dZ)) == 0;
|
return (frame % getUpdateDivisor(dX, dY, dZ)) == 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.jozufozu.flywheel.backend.loading;
|
package com.jozufozu.flywheel.backend.loading;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.backend.ShaderLoader;
|
import com.jozufozu.flywheel.backend.ShaderSources;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
@ -22,7 +22,7 @@ public class InstancedArraysTemplate extends ProgramTemplate {
|
||||||
public static final ResourceLocation vert = new ResourceLocation(Flywheel.ID, "template/instanced/instanced.vert");
|
public static final ResourceLocation vert = new ResourceLocation(Flywheel.ID, "template/instanced/instanced.vert");
|
||||||
public static final ResourceLocation frag = new ResourceLocation(Flywheel.ID, "template/instanced/instanced.frag");
|
public static final ResourceLocation frag = new ResourceLocation(Flywheel.ID, "template/instanced/instanced.frag");
|
||||||
|
|
||||||
public InstancedArraysTemplate(ShaderLoader loader) {
|
public InstancedArraysTemplate(ShaderSources loader) {
|
||||||
super(loader);
|
super(loader);
|
||||||
|
|
||||||
templates.put(ShaderType.VERTEX, new ShaderTemplate(requiredVert, loader.getShaderSource(vert)));
|
templates.put(ShaderType.VERTEX, new ShaderTemplate(requiredVert, loader.getShaderSource(vert)));
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.jozufozu.flywheel.backend.loading;
|
package com.jozufozu.flywheel.backend.loading;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.backend.ShaderLoader;
|
import com.jozufozu.flywheel.backend.ShaderSources;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
@ -19,7 +19,7 @@ public class ModelTemplate extends ProgramTemplate {
|
||||||
public static final ResourceLocation vert = new ResourceLocation(Flywheel.ID, "template/model/model.vert");
|
public static final ResourceLocation vert = new ResourceLocation(Flywheel.ID, "template/model/model.vert");
|
||||||
public static final ResourceLocation frag = new ResourceLocation(Flywheel.ID, "template/model/model.frag");
|
public static final ResourceLocation frag = new ResourceLocation(Flywheel.ID, "template/model/model.frag");
|
||||||
|
|
||||||
public ModelTemplate(ShaderLoader loader) {
|
public ModelTemplate(ShaderSources loader) {
|
||||||
super(loader);
|
super(loader);
|
||||||
|
|
||||||
templates.put(ShaderType.VERTEX, new ShaderTemplate(requiredVert, loader.getShaderSource(vert)));
|
templates.put(ShaderType.VERTEX, new ShaderTemplate(requiredVert, loader.getShaderSource(vert)));
|
||||||
|
|
|
@ -3,15 +3,15 @@ package com.jozufozu.flywheel.backend.loading;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.ShaderLoader;
|
import com.jozufozu.flywheel.backend.ShaderSources;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
|
|
||||||
public abstract class ProgramTemplate implements IProcessingStage {
|
public abstract class ProgramTemplate implements IProcessingStage {
|
||||||
|
|
||||||
protected final ShaderLoader loader;
|
protected final ShaderSources loader;
|
||||||
protected Map<ShaderType, ShaderTemplate> templates = new EnumMap<>(ShaderType.class);
|
protected Map<ShaderType, ShaderTemplate> templates = new EnumMap<>(ShaderType.class);
|
||||||
|
|
||||||
public ProgramTemplate(ShaderLoader loader) {
|
public ProgramTemplate(ShaderSources loader) {
|
||||||
this.loader = loader;
|
this.loader = loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,32 +1,43 @@
|
||||||
package com.jozufozu.flywheel.backend.loading;
|
package com.jozufozu.flywheel.backend.loading;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.StringReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.ShaderSources;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
public class Shader {
|
public class Shader {
|
||||||
|
// #flwinclude <"valid_namespace:valid/path_to_file.glsl">
|
||||||
|
private static final Pattern includePattern = Pattern.compile("#flwinclude <\"([\\w\\d_]+:[\\w\\d_./]+)\">");
|
||||||
|
|
||||||
public static final Pattern versionDetector = Pattern.compile("#version[^\\n]*");
|
public static final Pattern versionDetector = Pattern.compile("#version[^\\n]*");
|
||||||
private static final Pattern decorator = Pattern.compile("#\\[([\\w_]*)]");
|
private static final Pattern decorator = Pattern.compile("#\\[([\\w_]*)]");
|
||||||
|
|
||||||
public final ResourceLocation name;
|
public final ResourceLocation name;
|
||||||
public ShaderType type;
|
public ShaderType type;
|
||||||
private String source;
|
private String source;
|
||||||
|
private final ShaderSources loader;
|
||||||
|
|
||||||
private boolean parsed = false;
|
private boolean parsed = false;
|
||||||
final List<TaggedStruct> structs = new ArrayList<>(3);
|
final List<TaggedStruct> structs = new ArrayList<>(3);
|
||||||
final Map<String, TaggedStruct> tag2Struct = new HashMap<>();
|
final Map<String, TaggedStruct> tag2Struct = new HashMap<>();
|
||||||
final Map<String, TaggedStruct> name2Struct = new HashMap<>();
|
final Map<String, TaggedStruct> name2Struct = new HashMap<>();
|
||||||
|
|
||||||
public Shader(ShaderType type, ResourceLocation name, String source) {
|
public Shader(ShaderSources loader, ShaderType type, ResourceLocation name, String source) {
|
||||||
|
this.loader = loader;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.source = source;
|
this.source = source;
|
||||||
|
@ -91,4 +102,39 @@ public class Shader {
|
||||||
|
|
||||||
this.source = strippedSrc.toString();
|
this.source = strippedSrc.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void processIncludes() {
|
||||||
|
HashSet<ResourceLocation> seen = new HashSet<>();
|
||||||
|
seen.add(name);
|
||||||
|
|
||||||
|
source = includeRecursive(source, seen).collect(Collectors.joining("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Stream<String> includeRecursive(String source, Set<ResourceLocation> seen) {
|
||||||
|
return lines(source).flatMap(line -> {
|
||||||
|
|
||||||
|
Matcher matcher = includePattern.matcher(line);
|
||||||
|
|
||||||
|
if (matcher.find()) {
|
||||||
|
String includeName = matcher.group(1);
|
||||||
|
|
||||||
|
ResourceLocation include = new ResourceLocation(includeName);
|
||||||
|
|
||||||
|
if (seen.add(include)) {
|
||||||
|
try {
|
||||||
|
return includeRecursive(loader.getShaderSource(include), seen);
|
||||||
|
} catch (ShaderLoadingException e) {
|
||||||
|
throw new ShaderLoadingException("could not resolve import: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return Stream.of(line);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stream<String> lines(String s) {
|
||||||
|
return new BufferedReader(new StringReader(s)).lines();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class CrumblingInstanceManager extends TileInstanceManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldTick(BlockPos worldPos, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
|
protected boolean shouldFrameUpdate(BlockPos worldPos, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,16 @@ import com.jozufozu.flywheel.backend.gl.GlNumericType;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||||
import com.jozufozu.flywheel.backend.model.ElementBuffer;
|
import com.jozufozu.flywheel.backend.model.ElementBuffer;
|
||||||
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
|
|
||||||
|
import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class to manage EBOs that index quads as triangles.
|
* A class to manage EBOs that index quads as triangles.
|
||||||
*/
|
*/
|
||||||
|
@Mod.EventBusSubscriber
|
||||||
public class QuadConverter {
|
public class QuadConverter {
|
||||||
|
|
||||||
public static final int STARTING_CAPACITY = 42;
|
public static final int STARTING_CAPACITY = 42;
|
||||||
|
@ -158,4 +164,10 @@ public class QuadConverter {
|
||||||
|
|
||||||
return GlNumericType.UINT;
|
return GlNumericType.UINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make sure this gets reset first so it has a chance to repopulate
|
||||||
|
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||||
|
public static void onRendererReload(ReloadRenderersEvent event) {
|
||||||
|
if (INSTANCE != null) INSTANCE.free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.ResourceUtil;
|
import com.jozufozu.flywheel.backend.ResourceUtil;
|
||||||
import com.jozufozu.flywheel.backend.ShaderContext;
|
import com.jozufozu.flywheel.backend.ShaderContext;
|
||||||
import com.jozufozu.flywheel.backend.ShaderLoader;
|
import com.jozufozu.flywheel.backend.ShaderSources;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
import com.jozufozu.flywheel.backend.instancing.MaterialManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
||||||
|
@ -43,7 +43,7 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
||||||
protected Supplier<Stream<ResourceLocation>> specStream;
|
protected Supplier<Stream<ResourceLocation>> specStream;
|
||||||
protected TemplateFactory templateFactory;
|
protected TemplateFactory templateFactory;
|
||||||
|
|
||||||
public final WorldAttached<MaterialManager<P>> materialManager = new WorldAttached<>($ -> new MaterialManager<>(this));
|
private final WorldAttached<MaterialManager<P>> materialManager = new WorldAttached<>($ -> new MaterialManager<>(this));
|
||||||
|
|
||||||
private final Map<ShaderType, ResourceLocation> builtins = new EnumMap<>(ShaderType.class);
|
private final Map<ShaderType, ResourceLocation> builtins = new EnumMap<>(ShaderType.class);
|
||||||
private final Map<ShaderType, String> builtinSources = new EnumMap<>(ShaderType.class);
|
private final Map<ShaderType, String> builtinSources = new EnumMap<>(ShaderType.class);
|
||||||
|
@ -78,13 +78,14 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IMultiProgram<P> loadSpecInternal(ShaderLoader loader, ProgramSpec spec) {
|
protected IMultiProgram<P> loadSpecInternal(ShaderSources loader, ProgramSpec spec) {
|
||||||
return new StateSensitiveMultiProgram<>(loader, factory, this, spec);
|
return new StateSensitiveMultiProgram<>(loader, factory, this, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ProgramTemplate template;
|
protected ProgramTemplate template;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(ShaderLoader loader) {
|
public void load(ShaderSources loader) {
|
||||||
programs.values().forEach(IMultiProgram::delete);
|
programs.values().forEach(IMultiProgram::delete);
|
||||||
programs.clear();
|
programs.clear();
|
||||||
|
|
||||||
|
@ -103,10 +104,10 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
||||||
template = templateFactory.create(loader);
|
template = templateFactory.create(loader);
|
||||||
transformer = new ShaderTransformer()
|
transformer = new ShaderTransformer()
|
||||||
.pushStage(this::injectBuiltins)
|
.pushStage(this::injectBuiltins)
|
||||||
.pushStage(loader::processIncludes)
|
.pushStage(Shader::processIncludes)
|
||||||
.pushStage(Shader::parseStructs)
|
.pushStage(Shader::parseStructs)
|
||||||
.pushStage(template)
|
.pushStage(template)
|
||||||
.pushStage(loader::processIncludes);
|
.pushStage(Shader::processIncludes);
|
||||||
|
|
||||||
specStream.get()
|
specStream.get()
|
||||||
.map(Backend::getSpec)
|
.map(Backend::getSpec)
|
||||||
|
@ -131,6 +132,6 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface TemplateFactory {
|
public interface TemplateFactory {
|
||||||
ProgramTemplate create(ShaderLoader loader);
|
ProgramTemplate create(ShaderSources loader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.ShaderContext;
|
import com.jozufozu.flywheel.backend.ShaderContext;
|
||||||
import com.jozufozu.flywheel.backend.ShaderLoader;
|
import com.jozufozu.flywheel.backend.ShaderSources;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.backend.loading.Program;
|
import com.jozufozu.flywheel.backend.loading.Program;
|
||||||
import com.jozufozu.flywheel.core.shader.spec.IContextCondition;
|
import com.jozufozu.flywheel.core.shader.spec.IContextCondition;
|
||||||
|
@ -18,7 +18,7 @@ public class StateSensitiveMultiProgram<P extends GlProgram> implements IMultiPr
|
||||||
List<Pair<IContextCondition, P>> variants;
|
List<Pair<IContextCondition, P>> variants;
|
||||||
P fallback;
|
P fallback;
|
||||||
|
|
||||||
public StateSensitiveMultiProgram(ShaderLoader loader, ExtensibleGlProgram.Factory<P> factory, ShaderContext<P> context, ProgramSpec p) {
|
public StateSensitiveMultiProgram(ShaderSources loader, ExtensibleGlProgram.Factory<P> factory, ShaderContext<P> context, ProgramSpec p) {
|
||||||
variants = new ArrayList<>(p.states.size());
|
variants = new ArrayList<>(p.states.size());
|
||||||
|
|
||||||
for (ProgramState state : p.states) {
|
for (ProgramState state : p.states) {
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.jozufozu.flywheel.event;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraftforge.eventbus.api.Event;
|
||||||
|
|
||||||
|
public class BeginFrameEvent extends Event {
|
||||||
|
private final ClientWorld world;
|
||||||
|
private final MatrixStack stack;
|
||||||
|
private final ActiveRenderInfo info;
|
||||||
|
private final GameRenderer gameRenderer;
|
||||||
|
private final LightTexture lightTexture;
|
||||||
|
|
||||||
|
public BeginFrameEvent(ClientWorld world, MatrixStack stack, ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture) {
|
||||||
|
this.world = world;
|
||||||
|
this.stack = stack;
|
||||||
|
this.info = info;
|
||||||
|
this.gameRenderer = gameRenderer;
|
||||||
|
this.lightTexture = lightTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientWorld getWorld() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MatrixStack getStack() {
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActiveRenderInfo getInfo() {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameRenderer getGameRenderer() {
|
||||||
|
return gameRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LightTexture getLightTexture() {
|
||||||
|
return lightTexture;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,9 +3,14 @@ package com.jozufozu.flywheel.event;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.TileInstanceManager;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||||
|
import net.minecraftforge.event.world.WorldEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
|
@ -29,4 +34,15 @@ public class ForgeEvents {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onLoadWorld(WorldEvent.Load event) {
|
||||||
|
IWorld world = event.getWorld();
|
||||||
|
|
||||||
|
if (Backend.isFlywheelWorld(world)) {
|
||||||
|
TileInstanceManager renderer = InstancedRenderDispatcher.get(world);
|
||||||
|
renderer.invalidate();
|
||||||
|
((ClientWorld) world).loadedTileEntityList.forEach(renderer::add);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.jozufozu.flywheel.event;
|
||||||
|
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraftforge.eventbus.api.Event;
|
||||||
|
|
||||||
|
public class ReloadRenderersEvent extends Event {
|
||||||
|
private final ClientWorld world;
|
||||||
|
|
||||||
|
public ReloadRenderersEvent(ClientWorld world) {
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientWorld getWorld() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.jozufozu.flywheel.event;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
import net.minecraftforge.eventbus.api.Event;
|
||||||
|
|
||||||
|
public class RenderLayerEvent extends Event {
|
||||||
|
private final ClientWorld world;
|
||||||
|
public final RenderType type;
|
||||||
|
public final Matrix4f viewProjection;
|
||||||
|
public final double camX;
|
||||||
|
public final double camY;
|
||||||
|
public final double camZ;
|
||||||
|
|
||||||
|
public RenderLayerEvent(ClientWorld world, RenderType type, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||||
|
this.world = world;
|
||||||
|
this.type = type;
|
||||||
|
this.viewProjection = viewProjection;
|
||||||
|
this.camX = camX;
|
||||||
|
this.camY = camY;
|
||||||
|
this.camZ = camZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientWorld getWorld() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RenderType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matrix4f getViewProjection() {
|
||||||
|
return viewProjection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCamX() {
|
||||||
|
return camX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCamY() {
|
||||||
|
return camY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCamZ() {
|
||||||
|
return camZ;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,33 @@
|
||||||
package com.jozufozu.flywheel.light;
|
package com.jozufozu.flywheel.light;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_LINEAR;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_MIRRORED_REPEAT;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_TEXTURE0;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_TEXTURE4;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_TEXTURE_3D;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_TEXTURE_MAG_FILTER;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_TEXTURE_MIN_FILTER;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_TEXTURE_WRAP_R;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_TEXTURE_WRAP_S;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_TEXTURE_WRAP_T;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_UNPACK_ALIGNMENT;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_UNPACK_IMAGE_HEIGHT;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_UNPACK_ROW_LENGTH;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_UNPACK_SKIP_IMAGES;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_UNPACK_SKIP_PIXELS;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_UNPACK_SKIP_ROWS;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_UNSIGNED_BYTE;
|
||||||
|
import static org.lwjgl.opengl.GL20.glActiveTexture;
|
||||||
|
import static org.lwjgl.opengl.GL20.glPixelStorei;
|
||||||
|
import static org.lwjgl.opengl.GL20.glTexImage3D;
|
||||||
|
import static org.lwjgl.opengl.GL20.glTexParameteri;
|
||||||
|
import static org.lwjgl.opengl.GL20.glTexSubImage3D;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
import org.lwjgl.opengl.GL12;
|
|
||||||
import org.lwjgl.opengl.GL13;
|
|
||||||
import org.lwjgl.opengl.GL20;
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.RenderWork;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GlTexture;
|
import com.jozufozu.flywheel.backend.gl.GlTexture;
|
||||||
import com.jozufozu.flywheel.backend.gl.versioned.RGPixelFormat;
|
import com.jozufozu.flywheel.backend.gl.versioned.RGPixelFormat;
|
||||||
|
|
||||||
|
@ -35,20 +53,20 @@ public class LightVolume {
|
||||||
|
|
||||||
pixelFormat = Backend.compat.pixelFormat;
|
pixelFormat = Backend.compat.pixelFormat;
|
||||||
|
|
||||||
this.glTexture = new GlTexture(GL20.GL_TEXTURE_3D);
|
this.glTexture = new GlTexture(GL_TEXTURE_3D);
|
||||||
this.lightData = MemoryUtil.memAlloc(this.textureVolume.volume() * pixelFormat.byteCount());
|
this.lightData = MemoryUtil.memAlloc(this.textureVolume.volume() * pixelFormat.byteCount());
|
||||||
|
|
||||||
// allocate space for the texture
|
// allocate space for the texture
|
||||||
GL20.glActiveTexture(GL20.GL_TEXTURE4);
|
glActiveTexture(GL_TEXTURE4);
|
||||||
glTexture.bind();
|
glTexture.bind();
|
||||||
|
|
||||||
int sizeX = textureVolume.sizeX();
|
int sizeX = textureVolume.sizeX();
|
||||||
int sizeY = textureVolume.sizeY();
|
int sizeY = textureVolume.sizeY();
|
||||||
int sizeZ = textureVolume.sizeZ();
|
int sizeZ = textureVolume.sizeZ();
|
||||||
GL12.glTexImage3D(GL12.GL_TEXTURE_3D, 0, pixelFormat.internalFormat(), sizeX, sizeY, sizeZ, 0, pixelFormat.format(), GL20.GL_UNSIGNED_BYTE, 0);
|
glTexImage3D(GL_TEXTURE_3D, 0, pixelFormat.internalFormat(), sizeX, sizeY, sizeZ, 0, pixelFormat.format(), GL_UNSIGNED_BYTE, 0);
|
||||||
|
|
||||||
glTexture.unbind();
|
glTexture.unbind();
|
||||||
GL20.glActiveTexture(GL20.GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSampleVolume(GridAlignedBB sampleVolume) {
|
private void setSampleVolume(GridAlignedBB sampleVolume) {
|
||||||
|
@ -242,32 +260,32 @@ public class LightVolume {
|
||||||
// just in case something goes wrong or we accidentally call this before this volume is properly disposed of.
|
// just in case something goes wrong or we accidentally call this before this volume is properly disposed of.
|
||||||
if (lightData == null || removed) return;
|
if (lightData == null || removed) return;
|
||||||
|
|
||||||
GL13.glActiveTexture(GL20.GL_TEXTURE4);
|
glActiveTexture(GL_TEXTURE4);
|
||||||
glTexture.bind();
|
glTexture.bind();
|
||||||
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_MIN_FILTER, GL13.GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_MAG_FILTER, GL13.GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_S, GL20.GL_MIRRORED_REPEAT);
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
|
||||||
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_R, GL20.GL_MIRRORED_REPEAT);
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_MIRRORED_REPEAT);
|
||||||
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_T, GL20.GL_MIRRORED_REPEAT);
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
|
||||||
|
|
||||||
uploadTexture();
|
uploadTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadTexture() {
|
private void uploadTexture() {
|
||||||
if (bufferDirty) {
|
if (bufferDirty) {
|
||||||
GL20.glPixelStorei(GL20.GL_UNPACK_ROW_LENGTH, 0);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
GL20.glPixelStorei(GL20.GL_UNPACK_SKIP_PIXELS, 0);
|
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||||
GL20.glPixelStorei(GL20.GL_UNPACK_SKIP_ROWS, 0);
|
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||||
GL20.glPixelStorei(GL20.GL_UNPACK_SKIP_IMAGES, 0);
|
glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
|
||||||
GL20.glPixelStorei(GL20.GL_UNPACK_IMAGE_HEIGHT, 0);
|
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
|
||||||
GL20.glPixelStorei(GL20.GL_UNPACK_ALIGNMENT, 2);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
|
||||||
int sizeX = textureVolume.sizeX();
|
int sizeX = textureVolume.sizeX();
|
||||||
int sizeY = textureVolume.sizeY();
|
int sizeY = textureVolume.sizeY();
|
||||||
int sizeZ = textureVolume.sizeZ();
|
int sizeZ = textureVolume.sizeZ();
|
||||||
|
|
||||||
GL12.glTexSubImage3D(GL12.GL_TEXTURE_3D, 0, 0, 0, 0, sizeX, sizeY, sizeZ, pixelFormat.format(), GL20.GL_UNSIGNED_BYTE, lightData);
|
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, sizeX, sizeY, sizeZ, pixelFormat.format(), GL_UNSIGNED_BYTE, lightData);
|
||||||
|
|
||||||
GL20.glPixelStorei(GL20.GL_UNPACK_ALIGNMENT, 4); // 4 is the default
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4 is the default
|
||||||
bufferDirty = false;
|
bufferDirty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,11 +296,9 @@ public class LightVolume {
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
removed = true;
|
removed = true;
|
||||||
RenderWork.enqueue(() -> {
|
glTexture.delete();
|
||||||
glTexture.delete();
|
MemoryUtil.memFree(lightData);
|
||||||
MemoryUtil.memFree(lightData);
|
lightData = null;
|
||||||
lightData = null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeLight(int x, int y, int z, int block, int sky) {
|
private void writeLight(int x, int y, int z, int block, int sky) {
|
||||||
|
|
|
@ -5,11 +5,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.OptifineHandler;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.TileInstanceManager;
|
|
||||||
import com.jozufozu.flywheel.core.PartialModel;
|
import com.jozufozu.flywheel.core.PartialModel;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||||
|
@ -52,7 +48,6 @@ import net.minecraft.util.text.TextComponentUtils;
|
||||||
import net.minecraft.util.text.TextFormatting;
|
import net.minecraft.util.text.TextFormatting;
|
||||||
import net.minecraft.util.text.event.ClickEvent;
|
import net.minecraft.util.text.event.ClickEvent;
|
||||||
import net.minecraft.util.text.event.HoverEvent;
|
import net.minecraft.util.text.event.HoverEvent;
|
||||||
import net.minecraft.world.IWorld;
|
|
||||||
import net.minecraftforge.client.event.ModelBakeEvent;
|
import net.minecraftforge.client.event.ModelBakeEvent;
|
||||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
import net.minecraftforge.client.event.ModelRegistryEvent;
|
||||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
|
@ -86,7 +81,6 @@ public class CreateClient {
|
||||||
|
|
||||||
Backend.init();
|
Backend.init();
|
||||||
CreateFlywheelHandler.init();
|
CreateFlywheelHandler.init();
|
||||||
OptifineHandler.init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clientInit(FMLClientSetupEvent event) {
|
public static void clientInit(FMLClientSetupEvent event) {
|
||||||
|
@ -207,19 +201,8 @@ public class CreateClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void invalidateRenderers() {
|
public static void invalidateRenderers() {
|
||||||
invalidateRenderers(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void invalidateRenderers(@Nullable IWorld world) {
|
|
||||||
BUFFER_CACHE.invalidate();
|
BUFFER_CACHE.invalidate();
|
||||||
|
|
||||||
if (world != null) {
|
|
||||||
Backend.tileInstanceManager.get(world)
|
|
||||||
.invalidate();
|
|
||||||
} else {
|
|
||||||
Backend.tileInstanceManager.forEach(TileInstanceManager::invalidate);
|
|
||||||
}
|
|
||||||
|
|
||||||
ContraptionRenderDispatcher.invalidateAll();
|
ContraptionRenderDispatcher.invalidateAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
|
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.content.contraptions.KineticNetwork;
|
import com.simibubi.create.content.contraptions.KineticNetwork;
|
||||||
import com.simibubi.create.content.contraptions.RotationPropagator;
|
import com.simibubi.create.content.contraptions.RotationPropagator;
|
||||||
|
@ -258,7 +258,7 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
||||||
effects.triggerOverStressedEffect();
|
effects.triggerOverStressedEffect();
|
||||||
|
|
||||||
if (clientPacket)
|
if (clientPacket)
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> Backend.enqueueUpdate(this));
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> InstancedRenderDispatcher.enqueueUpdate(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getGeneratedSpeed() {
|
public float getGeneratedSpeed() {
|
||||||
|
@ -557,7 +557,7 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
||||||
public void requestModelDataUpdate() {
|
public void requestModelDataUpdate() {
|
||||||
super.requestModelDataUpdate();
|
super.requestModelDataUpdate();
|
||||||
if (!this.removed) {
|
if (!this.removed) {
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> Backend.enqueueUpdate(this));
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> InstancedRenderDispatcher.enqueueUpdate(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ package com.simibubi.create.content.contraptions.components.structureMovement.ch
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
|
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllSoundEvents;
|
import com.simibubi.create.AllSoundEvents;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
|
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
|
||||||
|
@ -70,7 +70,7 @@ public class StickerTileEntity extends SmartTileEntity implements IInstanceRende
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> playSound(false));
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> playSound(false));
|
||||||
piston.chase(target, .4f, Chaser.LINEAR);
|
piston.chase(target, .4f, Chaser.LINEAR);
|
||||||
|
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> Backend.enqueueUpdate(this));
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> InstancedRenderDispatcher.enqueueUpdate(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAttachedToBlock() {
|
public boolean isAttachedToBlock() {
|
||||||
|
|
|
@ -40,9 +40,9 @@ public class ContraptionInstanceManager extends TileInstanceManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldTick(BlockPos worldPos, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
|
protected boolean shouldFrameUpdate(BlockPos worldPos, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public ActorInstance createActor(Pair<Template.BlockInfo, MovementContext> actor) {
|
public ActorInstance createActor(Pair<Template.BlockInfo, MovementContext> actor) {
|
||||||
|
|
|
@ -18,6 +18,9 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.loading.ModelTemplate;
|
import com.jozufozu.flywheel.backend.loading.ModelTemplate;
|
||||||
import com.jozufozu.flywheel.core.WorldContext;
|
import com.jozufozu.flywheel.core.WorldContext;
|
||||||
|
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||||
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
|
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.simibubi.create.AllMovementBehaviours;
|
import com.simibubi.create.AllMovementBehaviours;
|
||||||
import com.simibubi.create.CreateClient;
|
import com.simibubi.create.CreateClient;
|
||||||
|
@ -42,7 +45,6 @@ import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||||
import net.minecraft.client.renderer.BlockModelShapes;
|
import net.minecraft.client.renderer.BlockModelShapes;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
@ -50,17 +52,18 @@ import net.minecraft.client.renderer.RenderTypeLookup;
|
||||||
import net.minecraft.client.renderer.WorldRenderer;
|
import net.minecraft.client.renderer.WorldRenderer;
|
||||||
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.client.world.ClientWorld;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
|
||||||
import net.minecraft.world.LightType;
|
import net.minecraft.world.LightType;
|
||||||
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.minecraftforge.client.ForgeHooksClient;
|
import net.minecraftforge.client.ForgeHooksClient;
|
||||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||||
import net.minecraftforge.common.util.Lazy;
|
import net.minecraftforge.common.util.Lazy;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber
|
||||||
public class ContraptionRenderDispatcher {
|
public class ContraptionRenderDispatcher {
|
||||||
private static final Lazy<BlockModelRenderer> MODEL_RENDERER = Lazy.of(() -> new BlockModelRenderer(Minecraft.getInstance().getBlockColors()));
|
private static final Lazy<BlockModelRenderer> MODEL_RENDERER = Lazy.of(() -> new BlockModelRenderer(Minecraft.getInstance().getBlockColors()));
|
||||||
private static final Lazy<BlockModelShapes> BLOCK_MODELS = Lazy.of(() -> Minecraft.getInstance().getModelManager().getBlockModelShapes());
|
private static final Lazy<BlockModelShapes> BLOCK_MODELS = Lazy.of(() -> Minecraft.getInstance().getModelManager().getBlockModelShapes());
|
||||||
|
@ -92,7 +95,9 @@ public class ContraptionRenderDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void beginFrame(ClientWorld world, MatrixStack stack, ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture) {
|
@SubscribeEvent
|
||||||
|
public static void beginFrame(BeginFrameEvent event) {
|
||||||
|
ActiveRenderInfo info = event.getInfo();
|
||||||
double camX = info.getProjectedView().x;
|
double camX = info.getProjectedView().x;
|
||||||
double camY = info.getProjectedView().y;
|
double camY = info.getProjectedView().y;
|
||||||
double camZ = info.getProjectedView().z;
|
double camZ = info.getProjectedView().z;
|
||||||
|
@ -101,10 +106,12 @@ public class ContraptionRenderDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderLayer(ClientWorld world, RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
@SubscribeEvent
|
||||||
|
public static void renderLayer(RenderLayerEvent event) {
|
||||||
removeDeadContraptions();
|
removeDeadContraptions();
|
||||||
|
|
||||||
if (RENDERERS.isEmpty()) return;
|
if (RENDERERS.isEmpty()) return;
|
||||||
|
RenderType layer = event.getType();
|
||||||
|
|
||||||
layer.startDrawing();
|
layer.startDrawing();
|
||||||
glEnable(GL_TEXTURE_3D);
|
glEnable(GL_TEXTURE_3D);
|
||||||
|
@ -114,8 +121,8 @@ public class ContraptionRenderDispatcher {
|
||||||
ContraptionProgram structureShader = STRUCTURE.getProgram(AllProgramSpecs.STRUCTURE);
|
ContraptionProgram structureShader = STRUCTURE.getProgram(AllProgramSpecs.STRUCTURE);
|
||||||
|
|
||||||
structureShader.bind();
|
structureShader.bind();
|
||||||
structureShader.uploadViewProjection(viewProjection);
|
structureShader.uploadViewProjection(event.viewProjection);
|
||||||
structureShader.uploadCameraPos(camX, camY, camZ);
|
structureShader.uploadCameraPos(event.camX, event.camY, event.camZ);
|
||||||
|
|
||||||
for (RenderedContraption renderer : RENDERERS.values()) {
|
for (RenderedContraption renderer : RENDERERS.values()) {
|
||||||
renderer.doRenderLayer(layer, structureShader);
|
renderer.doRenderLayer(layer, structureShader);
|
||||||
|
@ -124,7 +131,7 @@ public class ContraptionRenderDispatcher {
|
||||||
|
|
||||||
if (Backend.canUseInstancing()) {
|
if (Backend.canUseInstancing()) {
|
||||||
for (RenderedContraption renderer : RENDERERS.values()) {
|
for (RenderedContraption renderer : RENDERERS.values()) {
|
||||||
renderer.materialManager.render(layer, viewProjection, camX, camY, camZ, renderer::setup);
|
renderer.materialManager.render(layer, event.viewProjection, event.camX, event.camY, event.camZ, renderer::setup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +141,11 @@ public class ContraptionRenderDispatcher {
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onRendererReload(ReloadRenderersEvent event) {
|
||||||
|
invalidateAll();
|
||||||
|
}
|
||||||
|
|
||||||
public static void render(AbstractContraptionEntity entity, Contraption contraption,
|
public static void render(AbstractContraptionEntity entity, Contraption contraption,
|
||||||
ContraptionMatrices matrices, IRenderTypeBuffer buffers) {
|
ContraptionMatrices matrices, IRenderTypeBuffer buffers) {
|
||||||
World world = entity.world;
|
World world = entity.world;
|
||||||
|
@ -157,7 +169,7 @@ public class ContraptionRenderDispatcher {
|
||||||
|
|
||||||
if (contraption == null) {
|
if (contraption == null) {
|
||||||
PlacementSimulationWorld renderWorld = setupRenderWorld(world, c);
|
PlacementSimulationWorld renderWorld = setupRenderWorld(world, c);
|
||||||
contraption = new RenderedContraption(world, renderWorld, c);
|
contraption = new RenderedContraption(renderWorld, c);
|
||||||
RENDERERS.put(entityId, contraption);
|
RENDERERS.put(entityId, contraption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +195,7 @@ public class ContraptionRenderDispatcher {
|
||||||
renderWorld.setTileEntities(c.presentTileEntities.values());
|
renderWorld.setTileEntities(c.presentTileEntities.values());
|
||||||
|
|
||||||
for (Template.BlockInfo info : c.getBlocks()
|
for (Template.BlockInfo info : c.getBlocks()
|
||||||
.values())
|
.values())
|
||||||
// Skip individual lighting updates to prevent lag with large contraptions
|
// Skip individual lighting updates to prevent lag with large contraptions
|
||||||
renderWorld.setBlockState(info.pos, info.state, 128);
|
renderWorld.setBlockState(info.pos, info.state, 128);
|
||||||
|
|
||||||
|
@ -220,7 +232,7 @@ public class ContraptionRenderDispatcher {
|
||||||
MatrixStack m = matrices.contraptionStack;
|
MatrixStack m = matrices.contraptionStack;
|
||||||
m.push();
|
m.push();
|
||||||
MatrixStacker.of(m)
|
MatrixStacker.of(m)
|
||||||
.translate(blockInfo.pos);
|
.translate(blockInfo.pos);
|
||||||
|
|
||||||
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state);
|
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state);
|
||||||
if (movementBehaviour != null)
|
if (movementBehaviour != null)
|
||||||
|
@ -264,7 +276,7 @@ public class ContraptionRenderDispatcher {
|
||||||
ForgeHooksClient.setRenderLayer(layer);
|
ForgeHooksClient.setRenderLayer(layer);
|
||||||
BlockModelRenderer.enableCache();
|
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.MODEL)
|
if (state.getRenderType() != BlockRenderType.MODEL)
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class RenderedContraption extends ContraptionWorldHolder {
|
||||||
private Matrix4f model;
|
private Matrix4f model;
|
||||||
private AxisAlignedBB lightBox;
|
private AxisAlignedBB lightBox;
|
||||||
|
|
||||||
public RenderedContraption(World world, PlacementSimulationWorld renderWorld, Contraption contraption) {
|
public RenderedContraption(PlacementSimulationWorld renderWorld, Contraption contraption) {
|
||||||
super(contraption, renderWorld);
|
super(contraption, renderWorld);
|
||||||
this.lighter = contraption.makeLighter();
|
this.lighter = contraption.makeLighter();
|
||||||
this.materialManager = new ContraptionMaterialManager(ContraptionRenderDispatcher.TILES);
|
this.materialManager = new ContraptionMaterialManager(ContraptionRenderDispatcher.TILES);
|
||||||
|
@ -119,6 +119,7 @@ public class RenderedContraption extends ContraptionWorldHolder {
|
||||||
|
|
||||||
lighter.lightVolume.delete();
|
lighter.lightVolume.delete();
|
||||||
|
|
||||||
|
materialManager.delete();
|
||||||
kinetics.invalidate();
|
kinetics.invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.light.GridAlignedBB;
|
import com.jozufozu.flywheel.light.GridAlignedBB;
|
||||||
import com.jozufozu.flywheel.light.ILightUpdateListener;
|
import com.jozufozu.flywheel.light.ILightUpdateListener;
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
import com.jozufozu.flywheel.light.LightUpdater;
|
||||||
|
@ -267,7 +267,7 @@ public class BeltTileEntity extends KineticTileEntity implements ILightUpdateLis
|
||||||
belt.color = Optional.ofNullable(colorIn);
|
belt.color = Optional.ofNullable(colorIn);
|
||||||
belt.markDirty();
|
belt.markDirty();
|
||||||
belt.sendData();
|
belt.sendData();
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> Backend.enqueueUpdate(belt));
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> InstancedRenderDispatcher.enqueueUpdate(belt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
|
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock.Shape;
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock.Shape;
|
||||||
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock;
|
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock;
|
||||||
|
@ -103,7 +103,7 @@ public class BeltTunnelTileEntity extends SmartTileEntity implements IInstanceRe
|
||||||
sides.addAll(flaps.keySet());
|
sides.addAll(flaps.keySet());
|
||||||
super.fromTag(state, compound, clientPacket);
|
super.fromTag(state, compound, clientPacket);
|
||||||
if (clientPacket)
|
if (clientPacket)
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> Backend.enqueueUpdate(this));
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> InstancedRenderDispatcher.enqueueUpdate(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateTunnelConnections() {
|
public void updateTunnelConnections() {
|
||||||
|
|
|
@ -3,8 +3,8 @@ package com.simibubi.create.content.logistics.block.funnel;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
|
import com.jozufozu.flywheel.backend.instancing.IInstanceRendered;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllSoundEvents;
|
import com.simibubi.create.AllSoundEvents;
|
||||||
import com.simibubi.create.content.contraptions.goggles.IHaveHoveringInformation;
|
import com.simibubi.create.content.contraptions.goggles.IHaveHoveringInformation;
|
||||||
|
@ -327,7 +327,7 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
|
||||||
extractionCooldown = compound.getInt("TransferCooldown");
|
extractionCooldown = compound.getInt("TransferCooldown");
|
||||||
|
|
||||||
if (clientPacket)
|
if (clientPacket)
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> Backend.enqueueUpdate(this));
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> InstancedRenderDispatcher.enqueueUpdate(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -3,9 +3,7 @@ package com.simibubi.create.events;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.backend.RenderWork;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.TileInstanceManager;
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.simibubi.create.AllFluids;
|
import com.simibubi.create.AllFluids;
|
||||||
|
@ -110,7 +108,7 @@ public class ClientEvents {
|
||||||
|
|
||||||
SoundScapes.tick();
|
SoundScapes.tick();
|
||||||
AnimationTickHolder.tick();
|
AnimationTickHolder.tick();
|
||||||
Backend.tick();
|
InstancedRenderDispatcher.tick();
|
||||||
ScrollValueHandler.tick();
|
ScrollValueHandler.tick();
|
||||||
|
|
||||||
CreateClient.SCHEMATIC_SENDER.tick();
|
CreateClient.SCHEMATIC_SENDER.tick();
|
||||||
|
@ -154,11 +152,8 @@ public class ClientEvents {
|
||||||
public static void onLoadWorld(WorldEvent.Load event) {
|
public static void onLoadWorld(WorldEvent.Load event) {
|
||||||
IWorld world = event.getWorld();
|
IWorld world = event.getWorld();
|
||||||
if (world.isRemote() && world instanceof ClientWorld && !(world instanceof WrappedClientWorld)) {
|
if (world.isRemote() && world instanceof ClientWorld && !(world instanceof WrappedClientWorld)) {
|
||||||
CreateClient.invalidateRenderers(world);
|
CreateClient.invalidateRenderers();
|
||||||
AnimationTickHolder.reset();
|
AnimationTickHolder.reset();
|
||||||
TileInstanceManager renderer = Backend.tileInstanceManager.get(world);
|
|
||||||
renderer.invalidate();
|
|
||||||
((ClientWorld) world).loadedTileEntityList.forEach(renderer::add);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -173,7 +168,7 @@ public class ClientEvents {
|
||||||
public static void onUnloadWorld(WorldEvent.Unload event) {
|
public static void onUnloadWorld(WorldEvent.Unload event) {
|
||||||
if (event.getWorld()
|
if (event.getWorld()
|
||||||
.isRemote()) {
|
.isRemote()) {
|
||||||
CreateClient.invalidateRenderers(event.getWorld());
|
CreateClient.invalidateRenderers();
|
||||||
AnimationTickHolder.reset();
|
AnimationTickHolder.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,8 +194,6 @@ public class ClientEvents {
|
||||||
RenderSystem.enableCull();
|
RenderSystem.enableCull();
|
||||||
|
|
||||||
ms.pop();
|
ms.pop();
|
||||||
|
|
||||||
RenderWork.runAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.foundation.fluid;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack.Entry;
|
import com.mojang.blaze3d.matrix.MatrixStack.Entry;
|
||||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||||
|
@ -15,7 +16,6 @@ import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
|
||||||
import net.minecraft.fluid.Fluid;
|
import net.minecraft.fluid.Fluid;
|
||||||
import net.minecraft.inventory.container.PlayerContainer;
|
import net.minecraft.inventory.container.PlayerContainer;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
@ -23,12 +23,14 @@ import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.Direction.AxisDirection;
|
import net.minecraft.util.Direction.AxisDirection;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
import net.minecraft.util.math.vector.Vector3i;
|
import net.minecraft.util.math.vector.Vector3i;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fluids.FluidAttributes;
|
import net.minecraftforge.fluids.FluidAttributes;
|
||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber
|
||||||
public class FluidRenderer {
|
public class FluidRenderer {
|
||||||
|
|
||||||
// If we draw to BufferBuilder that minecraft provides for RenderType.getTranslucent(), minecraft draws the contents
|
// If we draw to BufferBuilder that minecraft provides for RenderType.getTranslucent(), minecraft draws the contents
|
||||||
|
@ -49,9 +51,10 @@ public class FluidRenderer {
|
||||||
return _builder;
|
return _builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderLayer(ClientWorld world, RenderType type, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
@SubscribeEvent
|
||||||
if (type == RenderType.getTranslucent()) {
|
public static void renderLayer(RenderLayerEvent event) {
|
||||||
type.draw(_builder, 0, 0, 0);
|
if (event.type == RenderType.getTranslucent()) {
|
||||||
|
event.type.draw(_builder, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,9 +79,9 @@ public class FluidRenderer {
|
||||||
|
|
||||||
ms.push();
|
ms.push();
|
||||||
msr.centre()
|
msr.centre()
|
||||||
.rotateY(AngleHelper.horizontalAngle(direction))
|
.rotateY(AngleHelper.horizontalAngle(direction))
|
||||||
.rotateX(direction == Direction.UP ? 0 : direction == Direction.DOWN ? 180 : 90)
|
.rotateX(direction == Direction.UP ? 0 : direction == Direction.DOWN ? 180 : 90)
|
||||||
.unCentre();
|
.unCentre();
|
||||||
ms.translate(.5, 0, .5);
|
ms.translate(.5, 0, .5);
|
||||||
|
|
||||||
float h = (float) (radius);
|
float h = (float) (radius);
|
||||||
|
@ -91,21 +94,21 @@ public class FluidRenderer {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ms.push();
|
ms.push();
|
||||||
renderTiledHorizontalFace(h, Direction.SOUTH, hMin, yMin, hMax, yMax, builder, ms, light, color,
|
renderTiledHorizontalFace(h, Direction.SOUTH, hMin, yMin, hMax, yMax, builder, ms, light, color,
|
||||||
flowTexture);
|
flowTexture);
|
||||||
ms.pop();
|
ms.pop();
|
||||||
msr.rotateY(90);
|
msr.rotateY(90);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progress != 1)
|
if (progress != 1)
|
||||||
renderTiledVerticalFace(yMax, Direction.UP, hMin, hMin, hMax, hMax, builder, ms, light, color,
|
renderTiledVerticalFace(yMax, Direction.UP, hMin, hMin, hMax, hMax, builder, ms, light, color,
|
||||||
stillTexture);
|
stillTexture);
|
||||||
|
|
||||||
ms.pop();
|
ms.pop();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderTiledFluidBB(FluidStack fluidStack, float xMin, float yMin, float zMin, float xMax,
|
public static void renderTiledFluidBB(FluidStack fluidStack, float xMin, float yMin, float zMin, float xMax,
|
||||||
float yMax, float zMax, IRenderTypeBuffer buffer, MatrixStack ms, int light, boolean renderBottom) {
|
float yMax, float zMax, IRenderTypeBuffer buffer, MatrixStack ms, int light, boolean renderBottom) {
|
||||||
Fluid fluid = fluidStack.getFluid();
|
Fluid fluid = fluidStack.getFluid();
|
||||||
FluidAttributes fluidAttributes = fluid.getAttributes();
|
FluidAttributes fluidAttributes = fluid.getAttributes();
|
||||||
TextureAtlasSprite fluidTexture = Minecraft.getInstance()
|
TextureAtlasSprite fluidTexture = Minecraft.getInstance()
|
||||||
|
@ -124,18 +127,18 @@ public class FluidRenderer {
|
||||||
ms.push();
|
ms.push();
|
||||||
if (fluidStack.getFluid()
|
if (fluidStack.getFluid()
|
||||||
.getAttributes()
|
.getAttributes()
|
||||||
.isLighterThanAir())
|
.isLighterThanAir())
|
||||||
MatrixStacker.of(ms)
|
MatrixStacker.of(ms)
|
||||||
.translate(center)
|
.translate(center)
|
||||||
.rotateX(180)
|
.rotateX(180)
|
||||||
.translateBack(center);
|
.translateBack(center);
|
||||||
|
|
||||||
for (Direction side : Iterate.directions) {
|
for (Direction side : Iterate.directions) {
|
||||||
if (side == Direction.DOWN && !renderBottom)
|
if (side == Direction.DOWN && !renderBottom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (side.getAxis()
|
if (side.getAxis()
|
||||||
.isHorizontal()) {
|
.isHorizontal()) {
|
||||||
ms.push();
|
ms.push();
|
||||||
|
|
||||||
if (side.getAxisDirection() == AxisDirection.NEGATIVE)
|
if (side.getAxisDirection() == AxisDirection.NEGATIVE)
|
||||||
|
@ -161,7 +164,7 @@ public class FluidRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void renderTiledVerticalFace(float y, Direction face, float xMin, float zMin, float xMax, float zMax,
|
private static void renderTiledVerticalFace(float y, Direction face, float xMin, float zMin, float xMax, float zMax,
|
||||||
IVertexBuilder builder, MatrixStack ms, int light, int color, TextureAtlasSprite texture) {
|
IVertexBuilder builder, MatrixStack ms, int light, int color, TextureAtlasSprite texture) {
|
||||||
float x2 = 0;
|
float x2 = 0;
|
||||||
float z2 = 0;
|
float z2 = 0;
|
||||||
for (float x1 = xMin; x1 < xMax; x1 = x2) {
|
for (float x1 = xMin; x1 < xMax; x1 = x2) {
|
||||||
|
@ -183,7 +186,7 @@ public class FluidRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void renderTiledHorizontalFace(float h, Direction face, float hMin, float yMin, float hMax,
|
private static void renderTiledHorizontalFace(float h, Direction face, float hMin, float yMin, float hMax,
|
||||||
float yMax, IVertexBuilder builder, MatrixStack ms, int light, int color, TextureAtlasSprite texture) {
|
float yMax, IVertexBuilder builder, MatrixStack ms, int light, int color, TextureAtlasSprite texture) {
|
||||||
boolean X = face.getAxis() == Axis.X;
|
boolean X = face.getAxis() == Axis.X;
|
||||||
|
|
||||||
float h2 = 0;
|
float h2 = 0;
|
||||||
|
@ -220,7 +223,7 @@ public class FluidRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void putVertex(IVertexBuilder builder, MatrixStack ms, float x, float y, float z, int color, float u,
|
private static void putVertex(IVertexBuilder builder, MatrixStack ms, float x, float y, float z, int color, float u,
|
||||||
float v, Direction face, int light) {
|
float v, Direction face, int light) {
|
||||||
|
|
||||||
Vector3i n = face.getDirectionVec();
|
Vector3i n = face.getDirectionVec();
|
||||||
Entry peek = ms.peek();
|
Entry peek = ms.peek();
|
||||||
|
@ -231,11 +234,11 @@ public class FluidRenderer {
|
||||||
int b = color & ff;
|
int b = color & ff;
|
||||||
|
|
||||||
builder.vertex(peek.getModel(), x, y, z)
|
builder.vertex(peek.getModel(), x, y, z)
|
||||||
.color(r, g, b, a)
|
.color(r, g, b, a)
|
||||||
.texture(u, v)
|
.texture(u, v)
|
||||||
.light(light)
|
.light(light)
|
||||||
.normal(n.getX(), n.getY(), n.getZ())
|
.normal(n.getX(), n.getY(), n.getZ())
|
||||||
.endVertex();
|
.endVertex();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.OptifineHandler;
|
import com.jozufozu.flywheel.backend.OptifineHandler;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
|
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||||
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
|
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
@ -23,6 +27,7 @@ import net.minecraft.util.math.vector.Matrix4f;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
@Mixin(WorldRenderer.class)
|
@Mixin(WorldRenderer.class)
|
||||||
|
@ -35,7 +40,7 @@ public class RenderHooksMixin {
|
||||||
private void setupFrame(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_,
|
private void setupFrame(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_,
|
||||||
ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_,
|
ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_,
|
||||||
CallbackInfo ci) {
|
CallbackInfo ci) {
|
||||||
Backend.listeners.setupFrame(world, stack, info, gameRenderer, lightTexture);
|
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(world, stack, info, gameRenderer, lightTexture));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +59,7 @@ public class RenderHooksMixin {
|
||||||
Matrix4f viewProjection = view.copy();
|
Matrix4f viewProjection = view.copy();
|
||||||
viewProjection.multiplyBackward(Backend.getProjectionMatrix());
|
viewProjection.multiplyBackward(Backend.getProjectionMatrix());
|
||||||
|
|
||||||
Backend.listeners.renderLayer(world, type, viewProjection, camX, camY, camZ);
|
MinecraftForge.EVENT_BUS.post(new RenderLayerEvent(world, type, viewProjection, camX, camY, camZ));
|
||||||
GL20.glUseProgram(0);
|
GL20.glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +68,7 @@ public class RenderHooksMixin {
|
||||||
OptifineHandler.refresh();
|
OptifineHandler.refresh();
|
||||||
Backend.refresh();
|
Backend.refresh();
|
||||||
|
|
||||||
Backend.listeners.refresh(world);
|
MinecraftForge.EVENT_BUS.post(new ReloadRenderersEvent(world));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,7 +91,7 @@ public class RenderHooksMixin {
|
||||||
viewProjection.multiplyBackward(Backend.getProjectionMatrix());
|
viewProjection.multiplyBackward(Backend.getProjectionMatrix());
|
||||||
|
|
||||||
Vector3d cameraPos = info.getProjectedView();
|
Vector3d cameraPos = info.getProjectedView();
|
||||||
Backend.renderBreaking(world, viewProjection, cameraPos.x, cameraPos.y, cameraPos.z);
|
InstancedRenderDispatcher.renderBreaking(world, viewProjection, cameraPos.x, cameraPos.y, cameraPos.z);
|
||||||
GL20.glUseProgram(0);
|
GL20.glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +99,7 @@ public class RenderHooksMixin {
|
||||||
|
|
||||||
@Inject(at = @At("TAIL"), method = "scheduleBlockRerenderIfNeeded")
|
@Inject(at = @At("TAIL"), method = "scheduleBlockRerenderIfNeeded")
|
||||||
private void checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) {
|
private void checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) {
|
||||||
Backend.tileInstanceManager.get(world)
|
InstancedRenderDispatcher.get(world)
|
||||||
.update(world.getTileEntity(pos));
|
.update(world.getTileEntity(pos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
|
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
@ -24,7 +24,7 @@ public class TileRemoveMixin {
|
||||||
@Inject(at = @At("TAIL"), method = "remove")
|
@Inject(at = @At("TAIL"), method = "remove")
|
||||||
private void onRemove(CallbackInfo ci) {
|
private void onRemove(CallbackInfo ci) {
|
||||||
if (world instanceof ClientWorld)
|
if (world instanceof ClientWorld)
|
||||||
Backend.tileInstanceManager.get(this.world)
|
InstancedRenderDispatcher.get(this.world)
|
||||||
.remove((TileEntity) (Object) this);
|
.remove((TileEntity) (Object) this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.backend.instancing.TileInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.TileInstanceManager;
|
||||||
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
@ -35,7 +35,7 @@ public class TileWorldHookMixin {
|
||||||
@Inject(at = @At("TAIL"), method = "addTileEntity")
|
@Inject(at = @At("TAIL"), method = "addTileEntity")
|
||||||
private void onAddTile(TileEntity te, CallbackInfoReturnable<Boolean> cir) {
|
private void onAddTile(TileEntity te, CallbackInfoReturnable<Boolean> cir) {
|
||||||
if (isRemote) {
|
if (isRemote) {
|
||||||
Backend.tileInstanceManager.get(self)
|
InstancedRenderDispatcher.get(self)
|
||||||
.queueAdd(te);
|
.queueAdd(te);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public class TileWorldHookMixin {
|
||||||
@Inject(at = @At(value = "INVOKE", target = "Ljava/util/Set;clear()V", ordinal = 0), method = "tickBlockEntities")
|
@Inject(at = @At(value = "INVOKE", target = "Ljava/util/Set;clear()V", ordinal = 0), method = "tickBlockEntities")
|
||||||
private void onChunkUnload(CallbackInfo ci) {
|
private void onChunkUnload(CallbackInfo ci) {
|
||||||
if (isRemote) {
|
if (isRemote) {
|
||||||
TileInstanceManager kineticRenderer = Backend.tileInstanceManager.get(self);
|
TileInstanceManager kineticRenderer = InstancedRenderDispatcher.get(self);
|
||||||
for (TileEntity tile : tileEntitiesToBeRemoved) {
|
for (TileEntity tile : tileEntitiesToBeRemoved) {
|
||||||
kineticRenderer.remove(tile);
|
kineticRenderer.remove(tile);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
import com.jozufozu.flywheel.light.LightUpdater;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientChunkProvider;
|
import net.minecraft.client.multiplayer.ClientChunkProvider;
|
||||||
|
@ -46,7 +46,7 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider {
|
||||||
.getY()) == sectionY)
|
.getY()) == sectionY)
|
||||||
.map(Map.Entry::getValue)
|
.map(Map.Entry::getValue)
|
||||||
.forEach(tile -> {
|
.forEach(tile -> {
|
||||||
Backend.tileInstanceManager.get(world)
|
InstancedRenderDispatcher.get(world)
|
||||||
.onLightUpdate(tile);
|
.onLightUpdate(tile);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
|
||||||
import com.jozufozu.flywheel.backend.RenderWork;
|
import com.jozufozu.flywheel.backend.RenderWork;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
import com.jozufozu.flywheel.light.LightUpdater;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
@ -36,7 +36,7 @@ public class NetworkLightUpdateMixin {
|
||||||
chunk.getTileEntityMap()
|
chunk.getTileEntityMap()
|
||||||
.values()
|
.values()
|
||||||
.forEach(tile -> {
|
.forEach(tile -> {
|
||||||
Backend.tileInstanceManager.get(world)
|
InstancedRenderDispatcher.get(world)
|
||||||
.onLightUpdate(tile);
|
.onLightUpdate(tile);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.foundation.render;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||||
import com.simibubi.create.foundation.fluid.FluidRenderer;
|
|
||||||
import com.simibubi.create.foundation.render.effects.EffectsContext;
|
import com.simibubi.create.foundation.render.effects.EffectsContext;
|
||||||
|
|
||||||
public class CreateFlywheelHandler {
|
public class CreateFlywheelHandler {
|
||||||
|
@ -10,9 +9,5 @@ public class CreateFlywheelHandler {
|
||||||
Backend.register(ContraptionRenderDispatcher.TILES);
|
Backend.register(ContraptionRenderDispatcher.TILES);
|
||||||
Backend.register(ContraptionRenderDispatcher.STRUCTURE);
|
Backend.register(ContraptionRenderDispatcher.STRUCTURE);
|
||||||
Backend.register(EffectsContext.INSTANCE);
|
Backend.register(EffectsContext.INSTANCE);
|
||||||
Backend.listeners.renderLayerListener(ContraptionRenderDispatcher::renderLayer);
|
|
||||||
Backend.listeners.renderLayerListener(FluidRenderer::renderLayer);
|
|
||||||
Backend.listeners.setupFrameListener(ContraptionRenderDispatcher::beginFrame);
|
|
||||||
Backend.listeners.refreshListener($ -> ContraptionRenderDispatcher.invalidateAll());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@ import java.util.Collections;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.ShaderContext;
|
import com.jozufozu.flywheel.backend.ShaderContext;
|
||||||
import com.jozufozu.flywheel.backend.ShaderLoader;
|
import com.jozufozu.flywheel.backend.ShaderSources;
|
||||||
|
import com.jozufozu.flywheel.backend.loading.Shader;
|
||||||
import com.jozufozu.flywheel.backend.loading.ShaderTransformer;
|
import com.jozufozu.flywheel.backend.loading.ShaderTransformer;
|
||||||
import com.jozufozu.flywheel.core.shader.IMultiProgram;
|
import com.jozufozu.flywheel.core.shader.IMultiProgram;
|
||||||
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
|
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
|
||||||
|
@ -19,14 +20,14 @@ public class EffectsContext extends ShaderContext<SphereFilterProgram> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IMultiProgram<SphereFilterProgram> loadSpecInternal(ShaderLoader loader, ProgramSpec spec) {
|
protected IMultiProgram<SphereFilterProgram> loadSpecInternal(ShaderSources loader, ProgramSpec spec) {
|
||||||
return new SphereFilterProgram(loadProgram(loader, spec, Collections.emptyList()));
|
return new SphereFilterProgram(loadProgram(loader, spec, Collections.emptyList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(ShaderLoader loader) {
|
public void load(ShaderSources loader) {
|
||||||
transformer = new ShaderTransformer()
|
transformer = new ShaderTransformer()
|
||||||
.pushStage(loader::processIncludes);
|
.pushStage(Shader::processIncludes);
|
||||||
loadProgramFromSpec(loader, Backend.getSpec(AllProgramSpecs.CHROMATIC));
|
loadProgramFromSpec(loader, Backend.getSpec(AllProgramSpecs.CHROMATIC));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue