Moved dissolve shader to Minecraft's new custom shader rendertype.

This commit is contained in:
Christian Knaapen
2021-09-26 19:38:02 +02:00
parent 4b1997e44f
commit 43d0a02faf
10 changed files with 151 additions and 329 deletions

View File

@@ -1,7 +1,6 @@
buildscript { buildscript {
repositories { repositories {
maven { url = 'https://files.minecraftforge.net/maven' } maven { url = 'https://files.minecraftforge.net/maven' }
jcenter()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
@@ -12,9 +11,8 @@ apply plugin: 'net.minecraftforge.gradle'
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. // Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
apply from: 'https://raw.githubusercontent.com/SizableShrimp/Forge-Class-Remapper/main/classremapper.gradle'
version = '1.16.3-2.24' version = '1.17.1-2.24'
group = 'nl.requios.effortlessbuilding' // http://maven.apache.org/guides/mini/guide-naming-conventions.html group = 'nl.requios.effortlessbuilding' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'effortlessbuilding' archivesBaseName = 'effortlessbuilding'

View File

@@ -37,7 +37,6 @@ import nl.requios.effortlessbuilding.proxy.ServerProxy;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
// The value here should match an entry in the META-INF/mods.toml file
@Mod(EffortlessBuilding.MODID) @Mod(EffortlessBuilding.MODID)
public class EffortlessBuilding { public class EffortlessBuilding {

View File

@@ -1,16 +1,21 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RegisterShadersEvent;
import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.render.BuildRenderTypes;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, value = {Dist.CLIENT}) @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, value = {Dist.CLIENT})
@@ -43,4 +48,12 @@ public class ModClientEventHandler {
public static TextureAtlasSprite getModeOptionIcon(ModeOptions.ActionEnum action) { public static TextureAtlasSprite getModeOptionIcon(ModeOptions.ActionEnum action) {
return Minecraft.getInstance().getModelManager().getAtlas(TextureAtlas.LOCATION_BLOCKS).getSprite(modeOptionIcons.get(action)); return Minecraft.getInstance().getModelManager().getAtlas(TextureAtlas.LOCATION_BLOCKS).getSprite(modeOptionIcons.get(action));
} }
@SubscribeEvent
public static void registerShaders(RegisterShadersEvent event) throws IOException {
event.registerShader(new ShaderInstance(event.getResourceManager(),
new ResourceLocation(EffortlessBuilding.MODID, "dissolve"),
DefaultVertexFormat.BLOCK),
shaderInstance -> BuildRenderTypes.dissolveShaderInstance = shaderInstance);
}
} }

View File

@@ -5,7 +5,6 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.SoundType;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.gui.screens.MenuScreens;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.resources.language.I18n; import net.minecraft.client.resources.language.I18n;
import net.minecraft.client.KeyMapping; import net.minecraft.client.KeyMapping;
@@ -29,28 +28,23 @@ import net.minecraftforge.client.settings.KeyConflictContext;
import net.minecraftforge.client.settings.KeyModifier; import net.minecraftforge.client.settings.KeyModifier;
import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.DeferredWorkQueue;
import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fmlclient.registry.ClientRegistry; import net.minecraftforge.fmlclient.registry.ClientRegistry;
import net.minecraftforge.fmllegacy.network.NetworkEvent; import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.gui.RandomizerBagScreen;
import nl.requios.effortlessbuilding.gui.buildmode.PlayerSettingsGui; import nl.requios.effortlessbuilding.gui.buildmode.PlayerSettingsGui;
import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu;
import nl.requios.effortlessbuilding.gui.buildmodifier.ModifierSettingsGui; import nl.requios.effortlessbuilding.gui.buildmodifier.ModifierSettingsGui;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.network.*; import nl.requios.effortlessbuilding.network.*;
import nl.requios.effortlessbuilding.render.ShaderHandler;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
@@ -66,7 +60,6 @@ public class ClientProxy implements IProxy {
public static int ticksInGame = 0; public static int ticksInGame = 0;
private static int placeCooldown = 0; private static int placeCooldown = 0;
private static int breakCooldown = 0; private static int breakCooldown = 0;
private static boolean shadersInitialized = false;
@SubscribeEvent @SubscribeEvent
public static void onClientTick(TickEvent.ClientTickEvent event) { public static void onClientTick(TickEvent.ClientTickEvent event) {
@@ -102,12 +95,6 @@ public class ClientProxy implements IProxy {
if (gui == null || !gui.isPauseScreen()) { if (gui == null || !gui.isPauseScreen()) {
ticksInGame++; ticksInGame++;
} }
//Init shaders in the first tick. Doing it anywhere before this seems to crash the game.
if (!shadersInitialized) {
ShaderHandler.init();
shadersInitialized = true;
}
} }
} }
@@ -276,12 +263,6 @@ public class ClientProxy implements IProxy {
} }
} }
//For shader development
if (keyBindings.length >= 8 && keyBindings[7].consumeClick()) {
ShaderHandler.init();
EffortlessBuilding.log(player, "Reloaded shaders");
}
} }
public static void openModifierSettings() { public static void openModifierSettings() {
@@ -367,7 +348,6 @@ public class ClientProxy implements IProxy {
keyBindings[4] = new KeyMapping("key.effortlessbuilding.undo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputConstants.getKey(GLFW.GLFW_KEY_Z, 0), "key.effortlessbuilding.category"); keyBindings[4] = new KeyMapping("key.effortlessbuilding.undo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputConstants.getKey(GLFW.GLFW_KEY_Z, 0), "key.effortlessbuilding.category");
keyBindings[5] = new KeyMapping("key.effortlessbuilding.redo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputConstants.getKey(GLFW.GLFW_KEY_Y, 0), "key.effortlessbuilding.category"); keyBindings[5] = new KeyMapping("key.effortlessbuilding.redo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputConstants.getKey(GLFW.GLFW_KEY_Y, 0), "key.effortlessbuilding.category");
keyBindings[6] = new KeyMapping("key.effortlessbuilding.altplacement.desc", KeyConflictContext.IN_GAME, InputConstants.getKey(GLFW.GLFW_KEY_LEFT_CONTROL, 0), "key.effortlessbuilding.category"); keyBindings[6] = new KeyMapping("key.effortlessbuilding.altplacement.desc", KeyConflictContext.IN_GAME, InputConstants.getKey(GLFW.GLFW_KEY_LEFT_CONTROL, 0), "key.effortlessbuilding.category");
//keyBindings[7] = new KeyBinding("Reload shaders", KeyConflictContext.UNIVERSAL, InputMappings.getInputByCode(GLFW.GLFW_KEY_TAB, 0), "key.effortlessbuilding.category");
// register all the key bindings // register all the key bindings
for (KeyMapping keyBinding : keyBindings) { for (KeyMapping keyBinding : keyBindings) {

View File

@@ -1,26 +1,38 @@
package nl.requios.effortlessbuilding.render; package nl.requios.effortlessbuilding.render;
import com.mojang.blaze3d.shaders.Uniform;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.Util; import net.minecraft.Util;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderStateShard; import net.minecraft.client.renderer.RenderStateShard;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlas;
import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import org.lwjgl.opengl.*; import org.lwjgl.opengl.*;
import java.util.OptionalDouble; import java.util.OptionalDouble;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function;
public class BuildRenderTypes extends RenderType { public class BuildRenderTypes extends RenderType {
public static ResourceLocation shaderMaskTextureLocation = new ResourceLocation(EffortlessBuilding.MODID, "textures/shader_mask.png");
public static final RenderType LINES; public static final RenderType LINES;
public static final RenderType PLANES; public static final RenderType PLANES;
private static final int primaryTextureUnit = 0; public static ShaderInstance dissolveShaderInstance;
private static final int secondaryTextureUnit = 2; private static final ShaderStateShard RENDERTYPE_DISSOLVE_SHADER = new ShaderStateShard(() -> dissolveShaderInstance);
//Between 0 and 7, but dont override vanilla textures
//Also update dissolve.fsh SamplerX
private static final int maskTextureIndex = 7;
static { static {
final LineStateShard LINE = new LineStateShard(OptionalDouble.of(2.0)); final LineStateShard LINE = new LineStateShard(OptionalDouble.of(2.0));
@@ -58,39 +70,27 @@ public class BuildRenderTypes extends RenderType {
DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.TRIANGLE_STRIP, INITIAL_BUFFER_SIZE, false, false, renderState); DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.TRIANGLE_STRIP, INITIAL_BUFFER_SIZE, false, false, renderState);
} }
// Dummy constructor needed to make java happy
public BuildRenderTypes(String p_173178_, VertexFormat p_173179_, VertexFormat.Mode p_173180_, int p_173181_, boolean p_173182_, boolean p_173183_, Runnable p_173184_, Runnable p_173185_) { public BuildRenderTypes(String p_173178_, VertexFormat p_173179_, VertexFormat.Mode p_173180_, int p_173181_, boolean p_173182_, boolean p_173183_, Runnable p_173184_, Runnable p_173185_) {
super(p_173178_, p_173179_, p_173180_, p_173181_, p_173182_, p_173183_, p_173184_, p_173185_); super(p_173178_, p_173179_, p_173180_, p_173181_, p_173182_, p_173183_, p_173184_, p_173185_);
} }
public static RenderType getBlockPreviewRenderType(float dissolve, BlockPos blockPos, BlockPos firstPos, public static RenderType getBlockPreviewRenderType(float dissolve, BlockPos blockPos, BlockPos firstPos, BlockPos secondPos, boolean red) {
BlockPos secondPos, boolean red) {
// RenderSystem.pushLightingAttributes();
// RenderSystem.pushTextureAttributes();
// RenderSystem.enableCull();
// RenderSystem.enableTexture();
// Minecraft.getInstance().textureManager.bindTexture(ShaderHandler.shaderMaskTextureLocation);
//
// RenderSystem.enableBlend();
// RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
// RenderSystem.blendColor(1f, 1f, 1f, 0.8f);
//end
// ShaderHandler.releaseShader();
//highjacking texturing state (which does nothing by default) to do my own things Boolean useShaders = BuildConfig.visuals.useShaders.get();
//TODO 1.17 don't use shaders if config says no
String stateName = "eb_texturing_" + dissolve + "_" + blockPos + "_" + firstPos + "_" + secondPos + "_" + red; String stateName = "eb_texturing_" + dissolve + "_" + blockPos + "_" + firstPos + "_" + secondPos + "_" + red;
RenderStateShard.TexturingStateShard MY_TEXTURING = new RenderStateShard.TexturingStateShard(stateName, () -> { TexturingStateShard MY_TEXTURING = new TexturingStateShard(stateName, () -> {
// RenderSystem.pushLightingAttributes(); setShaderParameters(dissolveShaderInstance, dissolve, Vec3.atLowerCornerOf(blockPos), Vec3.atLowerCornerOf(firstPos), Vec3.atLowerCornerOf(secondPos), blockPos == secondPos, red);
// RenderSystem.pushTextureAttributes();
ShaderHandler.useShader(ShaderHandler.dissolve, generateShaderCallback(dissolve, Vec3.atLowerCornerOf(blockPos), Vec3.atLowerCornerOf(firstPos), Vec3.atLowerCornerOf(secondPos), blockPos == secondPos, red));
RenderSystem.setShaderColor(1f, 1f, 1f, 0.8f); RenderSystem.setShaderColor(1f, 1f, 1f, 0.8f);
}, ShaderHandler::releaseShader); }, () -> {});
RenderType.CompositeState renderState = RenderType.CompositeState.builder() RenderType.CompositeState renderState = RenderType.CompositeState.builder()
.setShaderState(RenderStateShard.RENDERTYPE_TRANSLUCENT_SHADER) .setShaderState(RENDERTYPE_DISSOLVE_SHADER)
.setTextureState(new RenderStateShard.TextureStateShard(ShaderHandler.shaderMaskTextureLocation, false, false))
.setTexturingState(MY_TEXTURING) .setTexturingState(MY_TEXTURING)
.setTextureState(new RenderStateShard.TextureStateShard(shaderMaskTextureLocation, false, false))
.setTransparencyState(TRANSLUCENT_TRANSPARENCY) .setTransparencyState(TRANSLUCENT_TRANSPARENCY)
//TODO 1.17 //TODO 1.17
// .setDiffuseLightingState(DIFFUSE_LIGHTING_DISABLED) // .setDiffuseLightingState(DIFFUSE_LIGHTING_DISABLED)
@@ -105,49 +105,26 @@ public class BuildRenderTypes extends RenderType {
DefaultVertexFormat.BLOCK, VertexFormat.Mode.QUADS, 256, true, true, renderState); DefaultVertexFormat.BLOCK, VertexFormat.Mode.QUADS, 256, true, true, renderState);
} }
private static Consumer<Integer> generateShaderCallback(final float dissolve, final Vec3 blockpos, private static void setShaderParameters(ShaderInstance shader, final float dissolve, final Vec3 blockpos,
final Vec3 firstpos, final Vec3 secondpos, final Vec3 firstpos, final Vec3 secondpos,
final boolean highlight, final boolean red) { final boolean highlight, final boolean red) {
Minecraft mc = Minecraft.getInstance(); Uniform percentileUniform = shader.getUniform("dissolve");
return (Integer shader) -> { Uniform highlightUniform = shader.getUniform("highlight");
int percentileUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "dissolve"); Uniform redUniform = shader.getUniform("red");
int highlightUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "highlight"); Uniform blockposUniform = shader.getUniform("blockpos");
int redUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "red"); Uniform firstposUniform = shader.getUniform("firstpos");
int blockposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "blockpos"); Uniform secondposUniform = shader.getUniform("secondpos");
int firstposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "firstpos");
int secondposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "secondpos");
int imageUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "image");
int maskUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "mask");
RenderSystem.enableTexture(); RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_BLOCKS);
GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D); RenderSystem.setShaderTexture(maskTextureIndex, shaderMaskTextureLocation);
//mask percentileUniform.set(dissolve);
ARBShaderObjects.glUniform1iARB(maskUniform, secondaryTextureUnit); highlightUniform.set(highlight ? 1 : 0);
glActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + secondaryTextureUnit); redUniform.set(red ? 1 : 0);
RenderSystem.setShaderTexture(0, ShaderHandler.shaderMaskTextureLocation);
//mc.getTextureManager().bindForSetup(ShaderHandler.shaderMaskTextureLocation);//getTexture(ShaderHandler.shaderMaskTextureLocation).bindTexture();
//GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.getTextureManager().getTexture(ShaderHandler.shaderMaskTextureLocation).getGlTextureId());
//image blockposUniform.set((float) blockpos.x, (float) blockpos.y, (float) blockpos.z);
ARBShaderObjects.glUniform1iARB(imageUniform, primaryTextureUnit); firstposUniform.set((float) firstpos.x, (float) firstpos.y, (float) firstpos.z);
glActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + primaryTextureUnit); secondposUniform.set((float) secondpos.x, (float) secondpos.y, (float) secondpos.z);
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_BLOCKS);
//mc.getTextureManager().bindForSetup(TextureAtlas.LOCATION_BLOCKS);//.getTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE).bindTexture();
//GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.getTextureManager().getTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE).getGlTextureId());
//blockpos
ARBShaderObjects.glUniform3fARB(blockposUniform, (float) blockpos.x, (float) blockpos.y, (float) blockpos.z);
ARBShaderObjects.glUniform3fARB(firstposUniform, (float) firstpos.x, (float) firstpos.y, (float) firstpos.z);
ARBShaderObjects.glUniform3fARB(secondposUniform, (float) secondpos.x, (float) secondpos.y, (float) secondpos.z);
//dissolve
ARBShaderObjects.glUniform1fARB(percentileUniform, dissolve);
//highlight
ARBShaderObjects.glUniform1iARB(highlightUniform, highlight ? 1 : 0);
//red
ARBShaderObjects.glUniform1iARB(redUniform, red ? 1 : 0);
};
} }
public static void glActiveTexture(int texture) { public static void glActiveTexture(int texture) {

View File

@@ -1,201 +0,0 @@
/**
* This class was created by <Vazkii>. It's distributed as
* part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania
* <p>
* Modified by Requios
* <p>
* Botania is Open Source and distributed under the
* Botania License: http://botaniamod.net/license.php
* <p>
* File Created @ [Apr 9, 2014, 11:20:26 PM (GMT)]
*/
package nl.requios.effortlessbuilding.render;
import net.minecraft.resources.ResourceLocation;
import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.proxy.ClientProxy;
import org.apache.logging.log4j.Level;
import org.lwjgl.opengl.*;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.function.Consumer;
public final class ShaderHandler {
private static final int VERT_ST = ARBVertexShader.GL_VERTEX_SHADER_ARB;
private static final int FRAG_ST = ARBFragmentShader.GL_FRAGMENT_SHADER_ARB;
private static final int VERT = 1;
private static final int FRAG = 2;
private static final String VERT_EXTENSION = ".vert";
private static final String FRAG_EXTENSION = ".frag";
public static int rawColor;
public static int dissolve;
public static ResourceLocation shaderMaskTextureLocation = new ResourceLocation(EffortlessBuilding.MODID, "textures/shader_mask.png");
public static void init() {
if (!doUseShaders())
return;
// rawColor = createProgram("/assets/effortlessbuilding/shaders/raw_color", FRAG);
dissolve = createProgram("/assets/effortlessbuilding/shaders/dissolve", VERT + FRAG);
}
public static void useShader(int shader, Consumer<Integer> callback) {
if (!doUseShaders())
return;
ARBShaderObjects.glUseProgramObjectARB(shader);
if (shader != 0) {
int time = ARBShaderObjects.glGetUniformLocationARB(shader, "time");
ARBShaderObjects.glUniform1iARB(time, ClientProxy.ticksInGame);
if (callback != null)
callback.accept(shader);
}
}
public static void useShader(int shader) {
useShader(shader, null);
}
public static void releaseShader() {
useShader(0);
}
public static boolean doUseShaders() {
//Extracted from OpenGLHelper in 1.13 and earlier
//Can probably be simplified
GLCapabilities glcapabilities = GL.getCapabilities();
boolean openGL14 = glcapabilities.OpenGL14 || glcapabilities.GL_EXT_blend_func_separate;
boolean openGL21 = glcapabilities.OpenGL21;
boolean framebufferSupported = openGL14 && (glcapabilities.GL_ARB_framebuffer_object || glcapabilities.GL_EXT_framebuffer_object || glcapabilities.OpenGL30);
boolean shadersAvailable = openGL21 || glcapabilities.GL_ARB_vertex_shader && glcapabilities.GL_ARB_fragment_shader && glcapabilities.GL_ARB_shader_objects;
boolean shadersSupported = framebufferSupported && shadersAvailable;
return BuildConfig.visuals.useShaders.get() && shadersSupported;
}
private static int createProgram(String s, int sides) {
boolean vert = (sides & VERT) != 0;
boolean frag = (sides & FRAG) != 0;
return createProgram(vert ? s + VERT_EXTENSION : null, frag ? s + FRAG_EXTENSION : null);
}
// Most of the code taken from the LWJGL wiki
// http://lwjgl.org/wiki/index.php?title=GLSL_Shaders_with_LWJGL
private static int createProgram(String vert, String frag) {
int vertId = 0, fragId = 0, program;
if (vert != null)
vertId = createShader(vert, VERT_ST);
if (frag != null)
fragId = createShader(frag, FRAG_ST);
program = ARBShaderObjects.glCreateProgramObjectARB();
if (program == 0)
return 0;
if (vert != null)
ARBShaderObjects.glAttachObjectARB(program, vertId);
if (frag != null)
ARBShaderObjects.glAttachObjectARB(program, fragId);
ARBShaderObjects.glLinkProgramARB(program);
if (ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE) {
EffortlessBuilding.logger.log(Level.ERROR, getLogInfo(program));
return 0;
}
ARBShaderObjects.glValidateProgramARB(program);
if (ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_VALIDATE_STATUS_ARB) == GL11.GL_FALSE) {
EffortlessBuilding.logger.log(Level.ERROR, getLogInfo(program));
return 0;
}
return program;
}
private static int createShader(String filename, int shaderType) {
int shader = 0;
try {
shader = ARBShaderObjects.glCreateShaderObjectARB(shaderType);
if (shader == 0)
return 0;
ARBShaderObjects.glShaderSourceARB(shader, readFileAsString(filename));
ARBShaderObjects.glCompileShaderARB(shader);
if (ARBShaderObjects.glGetObjectParameteriARB(shader, ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB) == GL11.GL_FALSE)
throw new RuntimeException("Error creating shader: " + getLogInfo(shader));
return shader;
} catch (Exception e) {
ARBShaderObjects.glDeleteObjectARB(shader);
e.printStackTrace();
return -1;
}
}
private static String getLogInfo(int obj) {
return ARBShaderObjects.glGetInfoLogARB(obj, ARBShaderObjects.glGetObjectParameteriARB(obj, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB));
}
private static String readFileAsString(String filename) throws Exception {
StringBuilder source = new StringBuilder();
InputStream in = ShaderHandler.class.getResourceAsStream(filename);
Exception exception = null;
BufferedReader reader;
if (in == null)
return "";
try {
reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
Exception innerExc = null;
try {
String line;
while ((line = reader.readLine()) != null)
source.append(line).append('\n');
} catch (Exception exc) {
exception = exc;
} finally {
try {
reader.close();
} catch (Exception exc) {
innerExc = exc;
}
}
if (innerExc != null)
throw innerExc;
} catch (Exception exc) {
exception = exc;
} finally {
try {
in.close();
} catch (Exception exc) {
if (exception == null)
exception = exc;
else exc.printStackTrace();
}
if (exception != null)
throw exception;
}
return source.toString();
}
}

View File

@@ -1,6 +1,15 @@
#version 120 #version 150
uniform int time; // Passed in, see ShaderHelper.java #moj_import <fog.glsl>
uniform sampler2D Sampler0;
uniform sampler2D Sampler7;
uniform float GameTime;
uniform vec4 ColorModulator;
uniform float FogStart;
uniform float FogEnd;
uniform vec4 FogColor;
uniform float dissolve; // Passed in via Callback uniform float dissolve; // Passed in via Callback
uniform int highlight; uniform int highlight;
@@ -8,18 +17,23 @@ uniform int red;
uniform vec3 blockpos; uniform vec3 blockpos;
uniform vec3 firstpos; uniform vec3 firstpos;
uniform vec3 secondpos; uniform vec3 secondpos;
uniform sampler2D image;
uniform sampler2D mask;
varying vec4 position; in vec3 vertexPosition;
varying vec3 normal; in float vertexDistance;
in vec4 vertexColor;
in vec2 texCoord0;
in vec4 normal;
out vec4 fragColor;
void main() { void main() {
vec3 pixelposition = floor(position.xyz * 8.0) / 8.0; //convert gametime to seconds (roughly)
float time = GameTime * 1200;
vec3 pixelposition = floor(vertexPosition * 8.0) / 8.0;
vec3 worldpos = blockpos + pixelposition.xyz; vec3 worldpos = blockpos + pixelposition.xyz;
vec2 texcoord = vec2(gl_TexCoord[0]); vec4 texcolor = texture2D(Sampler0, texCoord0) * vertexColor * ColorModulator;
vec4 texcolor = texture2D(image, texcoord);
vec4 color = texcolor; vec4 color = texcolor;
vec3 firstposc = firstpos + 0.51; //center in block vec3 firstposc = firstpos + 0.51; //center in block
vec3 secondposc = secondpos + 0.5; vec3 secondposc = secondpos + 0.5;
@@ -41,10 +55,10 @@ void main() {
maskcoord = vec2(worldpos.x, worldpos.y); maskcoord = vec2(worldpos.x, worldpos.y);
maskcoord /= 20.0; maskcoord /= 20.0;
vec4 maskColor = texture2D(mask, maskcoord); vec4 maskColor = texture2D(Sampler7, maskcoord);
float maskgs = maskColor.r; float maskgs = maskColor.r;
color.rgb *= gl_Color.rgb; color.rgb *= vertexColor.rgb;
//desaturate //desaturate
color.rgb *= vec3(0.8); color.rgb *= vec3(0.8);
@@ -53,30 +67,18 @@ void main() {
color.rgb += vec3(-0.1, 0.0, 0.2); color.rgb += vec3(-0.1, 0.0, 0.2);
//add pulsing blue //add pulsing blue
float pulse = (sin(time / 5.0) + 1.0) / 2.0; float pulse = (sin(time * 4.0) + 1.0) / 2.0;
color.rgb += 0.4 * vec3(-0.5, 0.2, 0.6) * pulse; color.rgb += 0.4 * vec3(-0.5, 0.2, 0.6) * pulse;
//add diagonal highlights //add diagonal highlights
float diagTime = mod(time / 40.0, 1.4) - 0.2; float diagTime = mod(time / 2.0, 1.4) - 0.2;
float diag = smoothstep(diagTime - 0.2, diagTime, place) - smoothstep(diagTime, diagTime + 0.2, place); float diag = smoothstep(diagTime - 0.2, diagTime, place) - smoothstep(diagTime, diagTime + 0.2, place);
color.rgb += 0.2 * diag * vec3(0.0, 0.2, 0.4); color.rgb += 0.2 * diag * vec3(0.0, 0.2, 0.4);
float diagTime2 = mod(time / 70.0, 1.4) - 0.2; float diagTime2 = mod(time / 3.5, 1.4) - 0.2;
float diag2 = smoothstep(diagTime2 - 0.2, diagTime2, place) - smoothstep(diagTime2, diagTime2 + 0.2, place); float diag2 = smoothstep(diagTime2 - 0.2, diagTime2, place) - smoothstep(diagTime2, diagTime2 + 0.2, place);
color.rgb += 0.2 * diag2 * vec3(0.0, 0.4, 0.8); color.rgb += 0.2 * diag2 * vec3(0.0, 0.4, 0.8);
//add edge shading
// vec3 p1;
// //if (firstpos.x < secondpos.x)
//
// vec3 wmf = worldpos - firstposc;
// vec3 wms = worldpos - (secondposc + vec3(0.0, 1.0, 1.0));
// float distToEdge1 = min(length(wmf.xy), length(wmf.xz));
// float distToEdge2 = min(length(wmf.yz), length(wms.xy));
// float distToEdge3 = min(length(wms.xz), length(wms.yz));
// float distToEdge = min(min(distToEdge1, distToEdge2), distToEdge3);
// color.rgb += vec3(0.5 - smoothstep(0, 0.5, distToEdge)) * 0.5;
//add flat shading //add flat shading
// if (abs(normal.x) > 0.5) // if (abs(normal.x) > 0.5)
// color.rgb -= 0.0; // color.rgb -= 0.0;
@@ -99,6 +101,6 @@ void main() {
color.b = max(0, min(1, color.b)); color.b = max(0, min(1, color.b));
if (maskgs * 0.3 + place * 0.7 <= dissolve) if (maskgs * 0.3 + place * 0.7 <= dissolve)
gl_FragColor = vec4(texcolor.rgb, 0.0); fragColor = vec4(texcolor.rgb, 0.0);
else gl_FragColor = color; else fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor);
} }

View File

@@ -0,0 +1,37 @@
{
"blend": {
"func": "add",
"srcrgb": "srcalpha",
"dstrgb": "1-srcalpha"
},
"vertex": "effortlessbuilding:dissolve",
"fragment": "effortlessbuilding:dissolve",
"attributes": [
"Position",
"Color",
"UV0",
"UV2",
"Normal"
],
"samplers": [
{ "name": "Sampler0" },
{ "name": "Sampler2" }
],
"uniforms": [
{ "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
{ "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
{ "name": "ChunkOffset", "type": "float", "count": 3, "values": [ 0.0, 0.0, 0.0 ] },
{ "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] },
{ "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] },
{ "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] },
{ "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "GameTime", "type": "float", "count": 1, "values": [ 0.0 ] },
{ "name": "dissolve", "type": "float", "count": 1, "values": [0.0] },
{ "name": "highlight", "type": "int", "count": 1, "values": [0] },
{ "name": "red", "type": "int", "count": 1, "values": [0] },
{ "name": "blockpos", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] },
{ "name": "firstpos", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] },
{ "name": "secondpos", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] }
]
}

View File

@@ -0,0 +1,31 @@
#version 150
#moj_import <light.glsl>
in vec3 Position;
in vec4 Color;
in vec2 UV0;
in ivec2 UV2;
in vec3 Normal;
uniform sampler2D Sampler2;
uniform mat4 ModelViewMat;
uniform mat4 ProjMat;
uniform vec3 ChunkOffset;
out vec3 vertexPosition;
out float vertexDistance;
out vec4 vertexColor;
out vec2 texCoord0;
out vec4 normal;
void main() {
gl_Position = ProjMat * ModelViewMat * vec4(Position + ChunkOffset, 1.0);
vertexPosition = gl_Position.xyz;
vertexDistance = length((ModelViewMat * vec4(Position + ChunkOffset, 1.0)).xyz);
vertexColor = Color * minecraft_sample_lightmap(Sampler2, UV2);
texCoord0 = UV0;
normal = ProjMat * ModelViewMat * vec4(Normal, 0.0);
}

View File

@@ -1,14 +0,0 @@
#version 120
varying vec4 position;
varying vec3 normal;
void main() {
gl_Position = ftransform();//gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
//gl_BackColor = gl_Color;
position = gl_Vertex;
normal = gl_Normal;
}