mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-16 13:23:42 +01:00
Block breaking animations for arbitrary flywheel tiles.
- Kinda jank so far, but it's great progress. - This is also a really good showcase for how flexible the ShaderContext system is.
This commit is contained in:
parent
9736ba19b5
commit
3171a0b7e5
15 changed files with 224 additions and 43 deletions
|
@ -1,17 +1,29 @@
|
||||||
package com.jozufozu.flywheel.backend;
|
package com.jozufozu.flywheel.backend;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_REPEAT;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T;
|
||||||
|
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||||
|
import static org.lwjgl.opengl.GL11.glTexParameteri;
|
||||||
|
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;
|
||||||
|
import static org.lwjgl.opengl.GL13.glActiveTexture;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.lwjgl.opengl.GL;
|
import org.lwjgl.opengl.GL;
|
||||||
import org.lwjgl.opengl.GLCapabilities;
|
import org.lwjgl.opengl.GLCapabilities;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer;
|
import com.jozufozu.flywheel.backend.core.BasicProgram;
|
||||||
|
import com.jozufozu.flywheel.backend.core.CrumblingProgram;
|
||||||
import com.jozufozu.flywheel.backend.core.EffectsContext;
|
import com.jozufozu.flywheel.backend.core.EffectsContext;
|
||||||
import com.jozufozu.flywheel.backend.core.WorldContext;
|
import com.jozufozu.flywheel.backend.core.WorldContext;
|
||||||
|
import com.jozufozu.flywheel.backend.core.WorldTileRenderer;
|
||||||
import com.jozufozu.flywheel.backend.effects.EffectsHandler;
|
import com.jozufozu.flywheel.backend.effects.EffectsHandler;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec;
|
import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec;
|
||||||
|
@ -19,18 +31,28 @@ import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
||||||
import com.jozufozu.flywheel.backend.instancing.IFlywheelWorld;
|
import com.jozufozu.flywheel.backend.instancing.IFlywheelWorld;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
|
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
|
||||||
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.simibubi.create.content.contraptions.KineticDebugger;
|
import com.simibubi.create.content.contraptions.KineticDebugger;
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
import com.simibubi.create.foundation.utility.WorldAttached;
|
import com.simibubi.create.foundation.utility.WorldAttached;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.DestroyBlockProgress;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
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.client.world.ClientWorld;
|
||||||
import net.minecraft.entity.Entity;
|
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.tileentity.TileEntity;
|
||||||
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.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.resource.ISelectiveResourceReloadListener;
|
import net.minecraftforge.resource.ISelectiveResourceReloadListener;
|
||||||
|
@ -45,7 +67,8 @@ public class Backend {
|
||||||
public static GlCompat compat;
|
public static GlCompat compat;
|
||||||
|
|
||||||
public static EffectsHandler effects;
|
public static EffectsHandler effects;
|
||||||
public static WorldAttached<BasicInstancedTileRenderer> tileRenderer = new WorldAttached<>(BasicInstancedTileRenderer::new);
|
public static WorldAttached<WorldTileRenderer<BasicProgram>> tileRenderer = new WorldAttached<>(() -> new WorldTileRenderer<>(WorldContext.INSTANCE));
|
||||||
|
public static WorldAttached<WorldTileRenderer<CrumblingProgram>> blockBreaking = new WorldAttached<>(() -> new WorldTileRenderer<>(WorldContext.CRUMBLING));
|
||||||
|
|
||||||
private static Matrix4f projectionMatrix = new Matrix4f();
|
private static Matrix4f projectionMatrix = new Matrix4f();
|
||||||
private static boolean instancingAvailable;
|
private static boolean instancingAvailable;
|
||||||
|
@ -57,18 +80,18 @@ public class Backend {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
register(WorldContext.INSTANCE);
|
register(WorldContext.INSTANCE);
|
||||||
|
register(WorldContext.CRUMBLING);
|
||||||
register(EffectsContext.INSTANCE);
|
register(EffectsContext.INSTANCE);
|
||||||
|
|
||||||
listeners.refreshListener(world -> {
|
listeners.refreshListener(world -> {
|
||||||
if (canUseInstancing() && world != null) {
|
if (canUseInstancing() && world != null) {
|
||||||
BasicInstancedTileRenderer tileRenderer = Backend.tileRenderer.get(world);
|
WorldTileRenderer<BasicProgram> tileRenderer = Backend.tileRenderer.get(world);
|
||||||
tileRenderer.invalidate();
|
tileRenderer.invalidate();
|
||||||
world.loadedTileEntityList.forEach(tileRenderer::add);
|
world.loadedTileEntityList.forEach(tileRenderer::add);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
listeners.setupFrameListener((world, stack, info, gameRenderer, lightTexture) -> {
|
listeners.setupFrameListener((world, stack, info, gameRenderer, lightTexture) -> {
|
||||||
|
|
||||||
Backend.tileRenderer.get(world)
|
Backend.tileRenderer.get(world)
|
||||||
.beginFrame(info);
|
.beginFrame(info);
|
||||||
});
|
});
|
||||||
|
@ -174,7 +197,7 @@ public class Backend {
|
||||||
Minecraft mc = Minecraft.getInstance();
|
Minecraft mc = Minecraft.getInstance();
|
||||||
ClientWorld world = mc.world;
|
ClientWorld world = mc.world;
|
||||||
|
|
||||||
BasicInstancedTileRenderer instancer = tileRenderer.get(world);
|
WorldTileRenderer<BasicProgram> instancer = tileRenderer.get(world);
|
||||||
|
|
||||||
Entity renderViewEntity = mc.renderViewEntity;
|
Entity renderViewEntity = mc.renderViewEntity;
|
||||||
instancer.tick(renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ());
|
instancer.tick(renderViewEntity.getX(), renderViewEntity.getY(), renderViewEntity.getZ());
|
||||||
|
@ -182,15 +205,79 @@ public class Backend {
|
||||||
|
|
||||||
public static void renderLayer(ClientWorld world, RenderType layer, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
public static void renderLayer(ClientWorld world, RenderType layer, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
||||||
if (!canUseInstancing(world)) return;
|
if (!canUseInstancing(world)) return;
|
||||||
|
WorldTileRenderer<BasicProgram> renderer = tileRenderer.get(world);
|
||||||
|
if (renderer == null) return;
|
||||||
|
|
||||||
layer.startDrawing();
|
layer.startDrawing();
|
||||||
|
|
||||||
tileRenderer.get(world)
|
renderer.render(layer, viewProjection, cameraX, cameraY, cameraZ);
|
||||||
.render(layer, viewProjection, cameraX, cameraY, cameraZ);
|
|
||||||
|
|
||||||
layer.endDrawing();
|
layer.endDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void renderBreaking(ClientWorld world, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
||||||
|
if (!canUseInstancing(world)) return;
|
||||||
|
WorldTileRenderer<CrumblingProgram> renderer = blockBreaking.get(world);
|
||||||
|
if (renderer == null) return;
|
||||||
|
|
||||||
|
WorldRenderer worldRenderer = Minecraft.getInstance().worldRenderer;
|
||||||
|
Long2ObjectMap<SortedSet<DestroyBlockProgress>> breakingProgressions = worldRenderer.blockBreakingProgressions;
|
||||||
|
|
||||||
|
if (breakingProgressions.isEmpty()) return;
|
||||||
|
|
||||||
|
for (Long2ObjectMap.Entry<SortedSet<DestroyBlockProgress>> entry : breakingProgressions.long2ObjectEntrySet()) {
|
||||||
|
BlockPos breakingPos = BlockPos.fromLong(entry.getLongKey());
|
||||||
|
|
||||||
|
SortedSet<DestroyBlockProgress> sortedset1 = entry.getValue();
|
||||||
|
if (sortedset1 != null && !sortedset1.isEmpty()) {
|
||||||
|
renderer.add(world.getTileEntity(breakingPos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.beginFrame(Minecraft.getInstance().gameRenderer.getActiveRenderInfo());
|
||||||
|
|
||||||
|
RenderType layer = RenderType.getCutoutMipped();
|
||||||
|
|
||||||
|
layer.startDrawing();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
TextureManager textureManager = Minecraft.getInstance().textureManager;
|
||||||
|
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(5));
|
||||||
|
|
||||||
|
if (breaking != null) {
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.DST_COLOR, GlStateManager.DestFactor.SRC_COLOR, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||||
|
|
||||||
|
RenderSystem.enableAlphaTest();
|
||||||
|
RenderSystem.alphaFunc(516, 0.003921569F);
|
||||||
|
|
||||||
|
RenderSystem.polygonOffset(-1.0F, -10.0F);
|
||||||
|
RenderSystem.enablePolygonOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.render(layer, viewProjection, cameraX, cameraY, cameraZ, program -> program.setTextureScale(64, 64));
|
||||||
|
|
||||||
|
if (breaking != null) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE).getGlTextureId());
|
||||||
|
|
||||||
|
RenderSystem.disableBlend();
|
||||||
|
RenderSystem.defaultBlendFunc();
|
||||||
|
|
||||||
|
RenderSystem.polygonOffset(0.0F, 0.0F);
|
||||||
|
RenderSystem.disablePolygonOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.endDrawing();
|
||||||
|
|
||||||
|
renderer.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
public static void enqueueUpdate(TileEntity te) {
|
public static void enqueueUpdate(TileEntity te) {
|
||||||
tileRenderer.get(te.getWorld()).queueUpdate(te);
|
tileRenderer.get(te.getWorld()).queueUpdate(te);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.jozufozu.flywheel.backend.core;
|
package com.jozufozu.flywheel.backend.core;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL20;
|
import static org.lwjgl.opengl.GL20.glUniform1f;
|
||||||
|
import static org.lwjgl.opengl.GL20.glUniform1i;
|
||||||
|
import static org.lwjgl.opengl.GL20.glUniform3f;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ProgramFogMode;
|
import com.jozufozu.flywheel.backend.gl.shader.ProgramFogMode;
|
||||||
|
@ -42,11 +44,11 @@ public class BasicProgram extends GlProgram {
|
||||||
public void bind(Matrix4f viewProjection, double camX, double camY, double camZ, int debugMode) {
|
public void bind(Matrix4f viewProjection, double camX, double camY, double camZ, int debugMode) {
|
||||||
super.bind();
|
super.bind();
|
||||||
|
|
||||||
GL20.glUniform1i(uDebug, debugMode);
|
glUniform1i(uDebug, debugMode);
|
||||||
GL20.glUniform1f(uTime, AnimationTickHolder.getRenderTime());
|
glUniform1f(uTime, AnimationTickHolder.getRenderTime());
|
||||||
|
|
||||||
uploadMatrixUniform(uViewProjection, viewProjection);
|
uploadMatrixUniform(uViewProjection, viewProjection);
|
||||||
GL20.glUniform3f(uCameraPos, (float) camX, (float) camY, (float) camZ);
|
glUniform3f(uCameraPos, (float) camX, (float) camY, (float) camZ);
|
||||||
|
|
||||||
fogMode.bind();
|
fogMode.bind();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.jozufozu.flywheel.backend.core;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL20.glUniform2f;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.gl.shader.ProgramFogMode;
|
||||||
|
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
public class CrumblingProgram extends BasicProgram {
|
||||||
|
protected final int uTextureScale;
|
||||||
|
|
||||||
|
public CrumblingProgram(ResourceLocation name, int handle, ProgramFogMode.Factory fogFactory) {
|
||||||
|
super(name, handle, fogFactory);
|
||||||
|
|
||||||
|
uTextureScale = getUniformLocation("uTextureScale");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextureScale(float x, float y) {
|
||||||
|
glUniform2f(uTextureScale, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ public class WorldContext<P extends BasicProgram> extends ShaderContext<P> {
|
||||||
private static final Pattern builtinPattern = Pattern.compile("#flwbuiltins");
|
private static final Pattern builtinPattern = Pattern.compile("#flwbuiltins");
|
||||||
|
|
||||||
public static final WorldContext<BasicProgram> INSTANCE = new WorldContext<>(new ResourceLocation("create", "std"), new FogSensitiveProgram.SpecLoader<>(BasicProgram::new));
|
public static final WorldContext<BasicProgram> INSTANCE = new WorldContext<>(new ResourceLocation("create", "std"), new FogSensitiveProgram.SpecLoader<>(BasicProgram::new));
|
||||||
|
public static final WorldContext<CrumblingProgram> CRUMBLING = new WorldContext<>(new ResourceLocation("create", "crumbling"), new FogSensitiveProgram.SpecLoader<>(CrumblingProgram::new));
|
||||||
|
|
||||||
private final ShaderSpecLoader<P> loader;
|
private final ShaderSpecLoader<P> loader;
|
||||||
|
|
||||||
|
|
|
@ -12,13 +12,13 @@ import net.minecraft.util.math.BlockPos;
|
||||||
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.Matrix4f;
|
||||||
|
|
||||||
public class BasicInstancedTileRenderer extends InstancedTileRenderer<BasicProgram> {
|
public class WorldTileRenderer<P extends BasicProgram> extends InstancedTileRenderer<P> {
|
||||||
public static int MAX_ORIGIN_DISTANCE = 100;
|
public static int MAX_ORIGIN_DISTANCE = 100;
|
||||||
|
|
||||||
public BlockPos originCoordinate = BlockPos.ZERO;
|
public BlockPos originCoordinate = BlockPos.ZERO;
|
||||||
|
|
||||||
public BasicInstancedTileRenderer() {
|
public WorldTileRenderer(WorldContext<P> context) {
|
||||||
super(WorldContext.INSTANCE);
|
super(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -50,7 +50,7 @@ public class BasicInstancedTileRenderer extends InstancedTileRenderer<BasicProgr
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ,
|
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ,
|
||||||
ShaderCallback<BasicProgram> callback) {
|
ShaderCallback<P> callback) {
|
||||||
BlockPos originCoordinate = getOriginCoordinate();
|
BlockPos originCoordinate = getOriginCoordinate();
|
||||||
|
|
||||||
camX -= originCoordinate.getX();
|
camX -= originCoordinate.getX();
|
|
@ -1,8 +1,20 @@
|
||||||
package com.jozufozu.flywheel.backend.gl.shader;
|
package com.jozufozu.flywheel.backend.gl.shader;
|
||||||
|
|
||||||
import java.util.Collection;
|
import static org.lwjgl.opengl.GL20.GL_LINK_STATUS;
|
||||||
|
import static org.lwjgl.opengl.GL20.GL_TRUE;
|
||||||
|
import static org.lwjgl.opengl.GL20.glAttachShader;
|
||||||
|
import static org.lwjgl.opengl.GL20.glBindAttribLocation;
|
||||||
|
import static org.lwjgl.opengl.GL20.glCreateProgram;
|
||||||
|
import static org.lwjgl.opengl.GL20.glDeleteProgram;
|
||||||
|
import static org.lwjgl.opengl.GL20.glGetProgramInfoLog;
|
||||||
|
import static org.lwjgl.opengl.GL20.glGetProgrami;
|
||||||
|
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
||||||
|
import static org.lwjgl.opengl.GL20.glLinkProgram;
|
||||||
|
import static org.lwjgl.opengl.GL20.glUniform1i;
|
||||||
|
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
|
||||||
|
import static org.lwjgl.opengl.GL20.glUseProgram;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL20;
|
import java.util.Collection;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.RenderUtil;
|
import com.jozufozu.flywheel.backend.RenderUtil;
|
||||||
|
@ -26,11 +38,11 @@ public abstract class GlProgram extends GlObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind() {
|
public void bind() {
|
||||||
GL20.glUseProgram(handle());
|
glUseProgram(handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unbind() {
|
public void unbind() {
|
||||||
GL20.glUseProgram(0);
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,7 +52,7 @@ public abstract class GlProgram extends GlObject {
|
||||||
* @return The uniform's index
|
* @return The uniform's index
|
||||||
*/
|
*/
|
||||||
public int getUniformLocation(String uniform) {
|
public int getUniformLocation(String uniform) {
|
||||||
int index = GL20.glGetUniformLocation(this.handle(), uniform);
|
int index = glGetUniformLocation(this.handle(), uniform);
|
||||||
|
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
Backend.log.debug("No active uniform '{}' exists in program '{}'. Could be unused.", uniform, this.name);
|
Backend.log.debug("No active uniform '{}' exists in program '{}'. Could be unused.", uniform, this.name);
|
||||||
|
@ -61,19 +73,19 @@ public abstract class GlProgram extends GlObject {
|
||||||
int samplerUniform = getUniformLocation(name);
|
int samplerUniform = getUniformLocation(name);
|
||||||
|
|
||||||
if (samplerUniform >= 0) {
|
if (samplerUniform >= 0) {
|
||||||
GL20.glUniform1i(samplerUniform, binding);
|
glUniform1i(samplerUniform, binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
return samplerUniform;
|
return samplerUniform;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void uploadMatrixUniform(int uniform, Matrix4f mat) {
|
protected static void uploadMatrixUniform(int uniform, Matrix4f mat) {
|
||||||
GL20.glUniformMatrix4fv(uniform, false, RenderUtil.writeMatrix(mat));
|
glUniformMatrix4fv(uniform, false, RenderUtil.writeMatrix(mat));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void deleteInternal(int handle) {
|
protected void deleteInternal(int handle) {
|
||||||
GL20.glDeleteProgram(handle);
|
glDeleteProgram(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
@ -84,11 +96,11 @@ public abstract class GlProgram extends GlObject {
|
||||||
|
|
||||||
public Builder(ResourceLocation name) {
|
public Builder(ResourceLocation name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.program = GL20.glCreateProgram();
|
this.program = glCreateProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder attachShader(GlShader shader) {
|
public Builder attachShader(GlShader shader) {
|
||||||
GL20.glAttachShader(this.program, shader.handle());
|
glAttachShader(this.program, shader.handle());
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +111,7 @@ public abstract class GlProgram extends GlObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public <A extends IVertexAttrib> Builder addAttribute(A attrib) {
|
public <A extends IVertexAttrib> Builder addAttribute(A attrib) {
|
||||||
GL20.glBindAttribLocation(this.program, attributeIndex, attrib.attribName());
|
glBindAttribLocation(this.program, attributeIndex, attrib.attribName());
|
||||||
attributeIndex += attrib.attribSpec().getAttributeCount();
|
attributeIndex += attrib.attribSpec().getAttributeCount();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -108,17 +120,17 @@ public abstract class GlProgram extends GlObject {
|
||||||
* Links the attached shaders to this program.
|
* Links the attached shaders to this program.
|
||||||
*/
|
*/
|
||||||
public Builder link() {
|
public Builder link() {
|
||||||
GL20.glLinkProgram(this.program);
|
glLinkProgram(this.program);
|
||||||
|
|
||||||
String log = GL20.glGetProgramInfoLog(this.program);
|
String log = glGetProgramInfoLog(this.program);
|
||||||
|
|
||||||
if (!log.isEmpty()) {
|
if (!log.isEmpty()) {
|
||||||
Backend.log.debug("Program link log for " + this.name + ": " + log);
|
Backend.log.debug("Program link log for " + this.name + ": " + log);
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = GL20.glGetProgrami(this.program, GL20.GL_LINK_STATUS);
|
int result = glGetProgrami(this.program, GL_LINK_STATUS);
|
||||||
|
|
||||||
if (result != GL20.GL_TRUE) {
|
if (result != GL_TRUE) {
|
||||||
throw new RuntimeException("Shader program linking failed, see log for details");
|
throw new RuntimeException("Shader program linking failed, see log for details");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.RenderWork;
|
import com.jozufozu.flywheel.backend.RenderWork;
|
||||||
import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer;
|
import com.jozufozu.flywheel.backend.core.BasicProgram;
|
||||||
|
import com.jozufozu.flywheel.backend.core.WorldTileRenderer;
|
||||||
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;
|
||||||
|
@ -144,7 +145,7 @@ public class ClientEvents {
|
||||||
if (world.isRemote() && world instanceof ClientWorld && !(world instanceof WrappedClientWorld)) {
|
if (world.isRemote() && world instanceof ClientWorld && !(world instanceof WrappedClientWorld)) {
|
||||||
CreateClient.invalidateRenderers(world);
|
CreateClient.invalidateRenderers(world);
|
||||||
AnimationTickHolder.reset();
|
AnimationTickHolder.reset();
|
||||||
BasicInstancedTileRenderer renderer = Backend.tileRenderer.get(world);
|
WorldTileRenderer<BasicProgram> renderer = Backend.tileRenderer.get(world);
|
||||||
renderer.invalidate();
|
renderer.invalidate();
|
||||||
((ClientWorld) world).loadedTileEntityList.forEach(renderer::add);
|
((ClientWorld) world).loadedTileEntityList.forEach(renderer::add);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import net.minecraft.client.renderer.WorldRenderer;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@ -66,6 +67,23 @@ public class RenderHooksMixin {
|
||||||
Backend.listeners.refresh(world);
|
Backend.listeners.refresh(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject(at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/longs/Long2ObjectMap;long2ObjectEntrySet()Lit/unimi/dsi/fastutil/objects/ObjectSet;"), method = "render")
|
||||||
|
private void renderBlockBreaking(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_,
|
||||||
|
ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_,
|
||||||
|
CallbackInfo ci) {
|
||||||
|
if (!Backend.available())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Matrix4f view = stack.peek()
|
||||||
|
.getModel();
|
||||||
|
Matrix4f viewProjection = view.copy();
|
||||||
|
viewProjection.multiplyBackward(Backend.getProjectionMatrix());
|
||||||
|
|
||||||
|
Vector3d cameraPos = info.getProjectedView();
|
||||||
|
Backend.renderBreaking(world, viewProjection, cameraPos.x, cameraPos.y, cameraPos.z);
|
||||||
|
GL20.glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Effects system
|
// Effects system
|
||||||
|
|
||||||
@Inject(method = "render", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/client/shader/ShaderGroup;render(F)V"))
|
@Inject(method = "render", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/client/shader/ShaderGroup;render(F)V"))
|
||||||
|
|
|
@ -11,7 +11,8 @@ 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.Backend;
|
||||||
import com.jozufozu.flywheel.backend.core.BasicInstancedTileRenderer;
|
import com.jozufozu.flywheel.backend.core.BasicProgram;
|
||||||
|
import com.jozufozu.flywheel.backend.core.WorldTileRenderer;
|
||||||
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
@ -46,7 +47,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) {
|
||||||
BasicInstancedTileRenderer kineticRenderer = Backend.tileRenderer.get(self);
|
WorldTileRenderer<BasicProgram> kineticRenderer = Backend.tileRenderer.get(self);
|
||||||
for (TileEntity tile : tileEntitiesToBeRemoved) {
|
for (TileEntity tile : tileEntitiesToBeRemoved) {
|
||||||
kineticRenderer.remove(tile);
|
kineticRenderer.remove(tile);
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,3 +89,5 @@ public net.minecraft.util.math.vector.Matrix4f field_226587_m_ #a30
|
||||||
public net.minecraft.util.math.vector.Matrix4f field_226588_n_ #a31
|
public net.minecraft.util.math.vector.Matrix4f field_226588_n_ #a31
|
||||||
public net.minecraft.util.math.vector.Matrix4f field_226589_o_ #a32
|
public net.minecraft.util.math.vector.Matrix4f field_226589_o_ #a32
|
||||||
public net.minecraft.util.math.vector.Matrix4f field_226590_p_ #a33
|
public net.minecraft.util.math.vector.Matrix4f field_226590_p_ #a33
|
||||||
|
|
||||||
|
public net.minecraft.client.renderer.WorldRenderer field_228407_B_ #blockBreakingProgressions
|
||||||
|
|
|
@ -7,13 +7,10 @@ varying vec2 Light;
|
||||||
varying float Diffuse;
|
varying float Diffuse;
|
||||||
varying vec4 Color;
|
varying vec4 Color;
|
||||||
|
|
||||||
uniform sampler2D uBlockAtlas;
|
|
||||||
uniform sampler2D uLightMap;
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 tex = texture2D(uBlockAtlas, TexCoords);
|
vec4 tex = FLWBlockTexture(TexCoords);
|
||||||
|
|
||||||
vec4 color = vec4(tex.rgb * FLWLight(Light, uLightMap).rgb * Diffuse, tex.a) * Color;
|
vec4 color = vec4(tex.rgb * FLWLight(Light).rgb * Diffuse, tex.a) * Color;
|
||||||
|
|
||||||
FLWFinalizeColor(color);
|
FLWFinalizeColor(color);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,13 @@
|
||||||
varying vec3 BoxCoord;
|
varying vec3 BoxCoord;
|
||||||
uniform sampler3D uLightVolume;
|
uniform sampler3D uLightVolume;
|
||||||
|
|
||||||
|
uniform sampler2D uBlockAtlas;
|
||||||
|
uniform sampler2D uLightMap;
|
||||||
|
|
||||||
|
vec4 FLWBlockTexture(vec2 texCoords) {
|
||||||
|
return texture2D(uBlockAtlas, texCoords);
|
||||||
|
}
|
||||||
|
|
||||||
void FLWFinalizeColor(inout vec4 color) {
|
void FLWFinalizeColor(inout vec4 color) {
|
||||||
#if defined(USE_FOG)
|
#if defined(USE_FOG)
|
||||||
float a = color.a;
|
float a = color.a;
|
||||||
|
@ -13,7 +20,7 @@ void FLWFinalizeColor(inout vec4 color) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 FLWLight(vec2 lightCoords, sampler2D lightMap) {
|
vec4 FLWLight(vec2 lightCoords) {
|
||||||
vec2 lm = max(lightCoords, texture3D(uLightVolume, BoxCoord).rg);
|
vec2 lm = max(lightCoords, texture3D(uLightVolume, BoxCoord).rg);
|
||||||
return texture2D(lightMap, lm * 0.9375 + 0.03125);
|
return texture2D(uLightMap, lm * 0.9375 + 0.03125);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#flwinclude <"create:std/fog.glsl">
|
||||||
|
|
||||||
|
uniform vec2 uTextureScale;
|
||||||
|
uniform sampler2D uBlockAtlas;
|
||||||
|
uniform sampler2D uLightMap;
|
||||||
|
|
||||||
|
vec4 FLWBlockTexture(vec2 texCoords) {
|
||||||
|
return texture2D(uBlockAtlas, texCoords * uTextureScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FLWFinalizeColor(inout vec4 color) {
|
||||||
|
#if defined(USE_FOG)
|
||||||
|
float a = color.a;
|
||||||
|
float fog = clamp(FLWFogFactor(), 0., 1.);
|
||||||
|
|
||||||
|
color = mix(uFogColor, color, fog);
|
||||||
|
color.a = a;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 FLWLight(vec2 lightCoords) {
|
||||||
|
return vec4(1.);
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
#flwinclude <"create:std/builtin.vert">
|
|
@ -1,5 +1,12 @@
|
||||||
#flwinclude <"create:std/fog.glsl">
|
#flwinclude <"create:std/fog.glsl">
|
||||||
|
|
||||||
|
uniform sampler2D uBlockAtlas;
|
||||||
|
uniform sampler2D uLightMap;
|
||||||
|
|
||||||
|
vec4 FLWBlockTexture(vec2 texCoords) {
|
||||||
|
return texture2D(uBlockAtlas, texCoords);
|
||||||
|
}
|
||||||
|
|
||||||
void FLWFinalizeColor(inout vec4 color) {
|
void FLWFinalizeColor(inout vec4 color) {
|
||||||
#if defined(USE_FOG)
|
#if defined(USE_FOG)
|
||||||
float a = color.a;
|
float a = color.a;
|
||||||
|
@ -10,7 +17,7 @@ void FLWFinalizeColor(inout vec4 color) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 FLWLight(vec2 lightCoords, sampler2D lightMap) {
|
vec4 FLWLight(vec2 lightCoords) {
|
||||||
vec2 lm = lightCoords * 0.9375 + 0.03125;
|
vec2 lm = lightCoords * 0.9375 + 0.03125;
|
||||||
return texture2D(lightMap, lm);
|
return texture2D(uLightMap, lm);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue