Shader with dissolve and blue pulse on block previews.
Floor mode. Block preview sorting based on player distance.
This commit is contained in:
@@ -57,5 +57,8 @@ public class BuildConfig {
|
||||
public static class Visuals {
|
||||
@Comment({"Show a block preview if you have a block in hand on build mode Normal"})
|
||||
public boolean alwaysShowBlockPreview = false;
|
||||
|
||||
@Comment({"Use fancy shaders while placing blocks"})
|
||||
public boolean useShaders = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,34 +3,136 @@ package nl.requios.effortlessbuilding.buildmode;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import nl.requios.effortlessbuilding.helper.ReachHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class Floor implements IBuildMode {
|
||||
Dictionary<UUID, Integer> rightClickNrTable = new Hashtable<>();
|
||||
Dictionary<UUID, BlockPos> firstPosTable = new Hashtable<>();
|
||||
Dictionary<UUID, EnumFacing> sideHitTable = new Hashtable<>();
|
||||
Dictionary<UUID, Vec3d> hitVecTable = new Hashtable<>();
|
||||
|
||||
@Override
|
||||
public void initialize(EntityPlayer player) {
|
||||
|
||||
rightClickNrTable.put(player.getUniqueID(), 0);
|
||||
firstPosTable.put(player.getUniqueID(), BlockPos.ORIGIN);
|
||||
sideHitTable.put(player.getUniqueID(), EnumFacing.UP);
|
||||
hitVecTable.put(player.getUniqueID(), Vec3d.ZERO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPos> onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec) {
|
||||
return new ArrayList<>();
|
||||
List<BlockPos> list = new ArrayList<>();
|
||||
|
||||
int rightClickNr = rightClickNrTable.get(player.getUniqueID());
|
||||
rightClickNr++;
|
||||
rightClickNrTable.put(player.getUniqueID(), rightClickNr);
|
||||
|
||||
if (rightClickNr == 1) {
|
||||
//If clicking in air, reset and try again
|
||||
if (blockPos == null) {
|
||||
rightClickNrTable.put(player.getUniqueID(), 0);
|
||||
return list;
|
||||
}
|
||||
|
||||
//First click, remember starting position
|
||||
firstPosTable.put(player.getUniqueID(), blockPos);
|
||||
sideHitTable.put(player.getUniqueID(), sideHit);
|
||||
hitVecTable.put(player.getUniqueID(), hitVec);
|
||||
//Keep list empty, dont place any blocks yet
|
||||
} else {
|
||||
//Second click, place wall
|
||||
|
||||
list = findCoordinates(player, blockPos);
|
||||
rightClickNrTable.put(player.getUniqueID(), 0);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPos> findCoordinates(EntityPlayer player, BlockPos blockPos) {
|
||||
return new ArrayList<>();
|
||||
List<BlockPos> list = new ArrayList<>();
|
||||
int rightClickNr = rightClickNrTable.get(player.getUniqueID());
|
||||
BlockPos firstPos = firstPosTable.get(player.getUniqueID());
|
||||
|
||||
if (rightClickNr == 0) {
|
||||
if (blockPos != null)
|
||||
list.add(blockPos);
|
||||
} else {
|
||||
Vec3d look = player.getLookVec();
|
||||
Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ);
|
||||
|
||||
//try on z axis
|
||||
double y = firstPos.getY();
|
||||
|
||||
//then x and z are
|
||||
double x = (y - start.y) / look.y * look.x + start.x;
|
||||
double z = (y - start.y) / look.y * look.z + start.z;
|
||||
|
||||
Vec3d yBound = new Vec3d(x, y, z);
|
||||
|
||||
//distance to player
|
||||
double yDistSquared = yBound.subtract(start).lengthSquared();
|
||||
|
||||
|
||||
int reach = ReachHelper.getMaxReach(player); //4 times as much as normal placement reach
|
||||
|
||||
//check if its not behind the player and its not too close and not too far
|
||||
boolean yValid = yBound.subtract(start).dotProduct(look) > 0 &&
|
||||
yDistSquared > 4 && yDistSquared < reach * reach;
|
||||
|
||||
//select the one that is closest to the player and is valid
|
||||
Vec3d selected = null;
|
||||
if (yValid) selected = yBound;
|
||||
|
||||
if (selected == null) return list;
|
||||
|
||||
//check if it doesnt go through blocks
|
||||
RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, selected, false, false, false);
|
||||
if (rayTraceResult != null && rayTraceResult.typeOfHit != RayTraceResult.Type.BLOCK) {
|
||||
//return empty list
|
||||
return list;
|
||||
}
|
||||
|
||||
BlockPos secondPos = new BlockPos(selected);
|
||||
|
||||
//Add whole wall
|
||||
//Limit amount of blocks you can place per row
|
||||
int limit = ReachHelper.getMaxBlocksPlacedAtOnce(player);
|
||||
|
||||
int x1 = firstPos.getX(), x2 = secondPos.getX();
|
||||
int y1 = firstPos.getY(), y2 = secondPos.getY();
|
||||
int z1 = firstPos.getZ(), z2 = secondPos.getZ();
|
||||
|
||||
for (int l = x1; x1 < x2 ? l <= x2 : l >= x2; l += x1 < x2 ? 1 : -1) {
|
||||
|
||||
for (int n = z1; z1 < z2 ? n <= z2 : n >= z2; n += z1 < z2 ? 1 : -1) {
|
||||
|
||||
//check if whole row fits within limit
|
||||
if (Math.abs(y1 - y2) < limit - list.size()) {
|
||||
|
||||
for (int m = y1; y1 < y2 ? m <= y2 : m >= y2; m += y1 < y2 ? 1 : -1) {
|
||||
list.add(new BlockPos(l, m, n));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumFacing getSideHit(EntityPlayer player) {
|
||||
return null;
|
||||
return sideHitTable.get(player.getUniqueID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3d getHitVec(EntityPlayer player) {
|
||||
return null;
|
||||
return hitVecTable.get(player.getUniqueID());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import nl.requios.effortlessbuilding.EffortlessBuilding;
|
||||
import nl.requios.effortlessbuilding.helper.ReachHelper;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -12,7 +12,7 @@ import nl.requios.effortlessbuilding.EffortlessBuilding;
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RandomizerBagGuiContainer extends GuiContainer {
|
||||
private static final ResourceLocation guiTextures =
|
||||
new ResourceLocation(EffortlessBuilding.MODID + ":textures/gui/container/randomizerbag.png");
|
||||
new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/randomizerbag.png");
|
||||
private final InventoryPlayer inventoryPlayer;
|
||||
private final IItemHandler inventoryBag;
|
||||
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
package nl.requios.effortlessbuilding.helper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockDirt;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.renderer.*;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
@@ -35,13 +39,18 @@ import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
|
||||
import nl.requios.effortlessbuilding.buildmodifier.RadialMirror;
|
||||
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
|
||||
import nl.requios.effortlessbuilding.proxy.ClientProxy;
|
||||
import org.lwjgl.opengl.ARBMultitexture;
|
||||
import org.lwjgl.opengl.ARBShaderObjects;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL14;
|
||||
import org.lwjgl.util.Color;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||
public class RenderHelper implements IWorldEventListener {
|
||||
@@ -56,6 +65,8 @@ public class RenderHelper implements IWorldEventListener {
|
||||
|
||||
private static List<BlockPos> previousCoordinates;
|
||||
|
||||
private static final int secondaryTextureUnit = 7;
|
||||
|
||||
private static void begin(float partialTicks) {
|
||||
EntityPlayer player = Minecraft.getMinecraft().player;
|
||||
double playerX = player.prevPosX + (player.posX - player.prevPosX) * partialTicks;
|
||||
@@ -89,14 +100,17 @@ public class RenderHelper implements IWorldEventListener {
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
|
||||
GL11.glEnable(GL11.GL_CULL_FACE);
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation(EffortlessBuilding.MODID, "textures/shader_color.png"));
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation(EffortlessBuilding.MODID, "textures/shader_mask.png"));
|
||||
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL11.GL_CONSTANT_ALPHA, GL11.GL_ONE_MINUS_CONSTANT_ALPHA);
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GL14.glBlendColor(1F, 1F, 1F, 0.8f);
|
||||
}
|
||||
|
||||
private static void endBlockPreviews() {
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
ShaderHelper.releaseShader();
|
||||
GlStateManager.disableBlend();
|
||||
GL11.glPopAttrib();
|
||||
}
|
||||
@@ -241,6 +255,9 @@ public class RenderHelper implements IWorldEventListener {
|
||||
|
||||
if (sideHit != null) {
|
||||
BlockRendererDispatcher dispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
|
||||
float percentile = ClientProxy.ticksInGame / 100f % 1f;
|
||||
//TODO test
|
||||
percentile = 1f;
|
||||
|
||||
//get coordinates
|
||||
List<BlockPos> startCoordinates = BuildModes.findCoordinates(player, startPos);
|
||||
@@ -253,6 +270,13 @@ public class RenderHelper implements IWorldEventListener {
|
||||
|
||||
List<BlockPos> newCoordinates = BuildModifiers.findCoordinates(player, startCoordinates);
|
||||
|
||||
Collections.sort(newCoordinates, (lhs, rhs) -> {
|
||||
// -1 - less than, 1 - greater than, 0 - equal
|
||||
double lhsDistanceToPlayer = new Vec3d(lhs).subtract(player.getPositionEyes(1f)).lengthSquared();
|
||||
double rhsDistanceToPlayer = new Vec3d(rhs).subtract(player.getPositionEyes(1f)).lengthSquared();
|
||||
return (int) Math.signum(lhsDistanceToPlayer - rhsDistanceToPlayer);
|
||||
});
|
||||
|
||||
//check if they are different from previous
|
||||
if (!BuildModifiers.compareCoordinates(previousCoordinates, newCoordinates)) {
|
||||
previousCoordinates = newCoordinates;
|
||||
@@ -275,6 +299,8 @@ public class RenderHelper implements IWorldEventListener {
|
||||
if (!itemstack.isEmpty() && SurvivalHelper.canPlayerEdit(player, player.world, blockPos, itemstack) &&
|
||||
SurvivalHelper.mayPlace(player.world, Block.getBlockFromItem(itemstack.getItem()), blockState, blockPos, true, EnumFacing.UP, player) &&
|
||||
SurvivalHelper.canReplace(player.world, player, blockPos)) {
|
||||
|
||||
ShaderHelper.useShader(ShaderHelper.psiBar, generateCallback(percentile, new Vec3d(blockPos), i == 0 || i == newCoordinates.size() - 1));
|
||||
renderBlockPreview(dispatcher, blockPos, blockState);
|
||||
}
|
||||
}
|
||||
@@ -395,6 +421,40 @@ public class RenderHelper implements IWorldEventListener {
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
private static Consumer<Integer> generateCallback(final float percentile, final Vec3d blockpos, final boolean highlight) {
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
return (Integer shader) -> {
|
||||
int percentileUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "percentile");
|
||||
int highlightUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "highlight");
|
||||
int blockposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "blockpos");
|
||||
int imageUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "image");
|
||||
int maskUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "mask");
|
||||
|
||||
//image
|
||||
OpenGlHelper.setActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB);
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.renderEngine.getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE/*new ResourceLocation(EffortlessBuilding.MODID, "textures/shader_color.png")*/).getGlTextureId());
|
||||
ARBShaderObjects.glUniform1iARB(imageUniform, 0);
|
||||
|
||||
OpenGlHelper.setActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + secondaryTextureUnit);
|
||||
|
||||
GlStateManager.enableTexture2D();
|
||||
GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
|
||||
|
||||
//mask
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D,
|
||||
mc.renderEngine.getTexture(new ResourceLocation(EffortlessBuilding.MODID, "textures/shader_mask.png")).getGlTextureId());
|
||||
ARBShaderObjects.glUniform1iARB(maskUniform, secondaryTextureUnit);
|
||||
|
||||
//blockpos
|
||||
ARBShaderObjects.glUniform3fARB(blockposUniform, (float) blockpos.x, (float) blockpos.y, (float) blockpos.z);
|
||||
|
||||
//percentile
|
||||
ARBShaderObjects.glUniform1fARB(percentileUniform, percentile);
|
||||
//highlight
|
||||
ARBShaderObjects.glUniform1iARB(highlightUniform, highlight ? 1 : 0);
|
||||
};
|
||||
}
|
||||
|
||||
//IWORLDEVENTLISTENER IMPLEMENTATION
|
||||
@Override
|
||||
public void notifyBlockUpdate(World worldIn, BlockPos pos, IBlockState oldState, IBlockState newState, int flags) {
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* Modified by Requios
|
||||
*
|
||||
* Botania is Open Source and distributed under the
|
||||
* Botania License: http://botaniamod.net/license.php
|
||||
*
|
||||
* File Created @ [Apr 9, 2014, 11:20:26 PM (GMT)]
|
||||
*/
|
||||
package nl.requios.effortlessbuilding.helper;
|
||||
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
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.ARBFragmentShader;
|
||||
import org.lwjgl.opengl.ARBShaderObjects;
|
||||
import org.lwjgl.opengl.ARBVertexShader;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
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 ShaderHelper {
|
||||
|
||||
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 psiBar;
|
||||
|
||||
public static void init() {
|
||||
if(!doUseShaders())
|
||||
return;
|
||||
|
||||
rawColor = createProgram("/assets/effortlessbuilding/shaders/raw_color", FRAG);
|
||||
psiBar = createProgram("/assets/effortlessbuilding/shaders/dissolve", 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() {
|
||||
return BuildConfig.visuals.useShaders && OpenGlHelper.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 = ShaderHelper.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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.audio.PositionedSoundRecord;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.ScaledResolution;
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
@@ -51,6 +52,7 @@ import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu;
|
||||
import nl.requios.effortlessbuilding.gui.buildmodifier.ModifierSettingsGui;
|
||||
import nl.requios.effortlessbuilding.helper.ReachHelper;
|
||||
import nl.requios.effortlessbuilding.helper.RenderHelper;
|
||||
import nl.requios.effortlessbuilding.helper.ShaderHelper;
|
||||
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
|
||||
import nl.requios.effortlessbuilding.network.BlockBrokenMessage;
|
||||
import nl.requios.effortlessbuilding.network.BlockPlacedMessage;
|
||||
@@ -70,10 +72,13 @@ public class ClientProxy implements IProxy {
|
||||
public static RayTraceResult currentLookAt;
|
||||
private static int breakCooldown = 0;
|
||||
|
||||
public static int ticksInGame = 0;
|
||||
|
||||
private static final HashMap<BuildModes.BuildModeEnum, RadialMenu.SpriteIconPositioning> buildModeIcons = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void preInit(FMLPreInitializationEvent event) {
|
||||
ShaderHelper.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,6 +147,10 @@ public class ClientProxy implements IProxy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* From Chisels and Bits by AlgorithmX2
|
||||
* https://github.com/AlgorithmX2/Chisels-and-Bits/blob/1.12/src/main/java/mod/chiselsandbits/core/ClientSide.java
|
||||
*/
|
||||
private static void loadIcon(final TextureMap map, final BuildModes.BuildModeEnum mode) {
|
||||
final RadialMenu.SpriteIconPositioning sip = new RadialMenu.SpriteIconPositioning();
|
||||
|
||||
@@ -284,6 +293,11 @@ public class ClientProxy implements IProxy {
|
||||
|
||||
//QuickReplace toggle
|
||||
if (keyBindings[1].isPressed()) {
|
||||
//TODO testing
|
||||
EffortlessBuilding.log(player, "ShaderHelper init");
|
||||
ShaderHelper.init();
|
||||
|
||||
|
||||
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
|
||||
modifierSettings.setQuickReplace(!modifierSettings.doQuickReplace());
|
||||
EffortlessBuilding.log(player, "Set "+ TextFormatting.GOLD + "Quick Replace " + TextFormatting.RESET + (
|
||||
@@ -304,29 +318,35 @@ public class ClientProxy implements IProxy {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase != TickEvent.Phase.START) return;
|
||||
if (event.phase == TickEvent.Phase.START) {
|
||||
RayTraceResult objectMouseOver = Minecraft.getMinecraft().objectMouseOver;
|
||||
//Checking for null is necessary! Even in vanilla when looking down ladders it is occasionally null (instead of Type MISS)
|
||||
if (objectMouseOver == null) return;
|
||||
|
||||
RayTraceResult objectMouseOver = Minecraft.getMinecraft().objectMouseOver;
|
||||
//Checking for null is necessary! Even in vanilla when looking down ladders it is occasionally null (instead of Type MISS)
|
||||
if (objectMouseOver == null) return;
|
||||
|
||||
if (currentLookAt == null) {
|
||||
currentLookAt = objectMouseOver;
|
||||
previousLookAt = objectMouseOver;
|
||||
return;
|
||||
}
|
||||
|
||||
if (objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
if (currentLookAt.typeOfHit != RayTraceResult.Type.BLOCK) {
|
||||
if (currentLookAt == null) {
|
||||
currentLookAt = objectMouseOver;
|
||||
previousLookAt = objectMouseOver;
|
||||
} else {
|
||||
if (currentLookAt.getBlockPos() != objectMouseOver.getBlockPos()){
|
||||
previousLookAt = currentLookAt;
|
||||
return;
|
||||
}
|
||||
|
||||
if (objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
if (currentLookAt.typeOfHit != RayTraceResult.Type.BLOCK) {
|
||||
currentLookAt = objectMouseOver;
|
||||
previousLookAt = objectMouseOver;
|
||||
} else {
|
||||
if (currentLookAt.getBlockPos() != objectMouseOver.getBlockPos()) {
|
||||
previousLookAt = currentLookAt;
|
||||
currentLookAt = objectMouseOver;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (event.phase == TickEvent.Phase.END){
|
||||
GuiScreen gui = Minecraft.getMinecraft().currentScreen;
|
||||
if(gui == null || !gui.doesGuiPauseGame()) {
|
||||
ticksInGame++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
#version 120
|
||||
|
||||
uniform int time; // Passed in, see ShaderHelper.java
|
||||
|
||||
uniform float percentile; // Passed in via Callback
|
||||
uniform int highlight;
|
||||
uniform vec3 blockpos;
|
||||
uniform sampler2D image;
|
||||
uniform sampler2D mask;
|
||||
// Simplex 3D Noise
|
||||
// by Ian McEwan, Ashima Arts
|
||||
//
|
||||
vec4 permute(vec4 x) {return mod(((x*34.0)+1.0)*x, 289.0);}
|
||||
vec4 taylorInvSqrt(vec4 r) {return 1.79284291400159 - 0.85373472095314 * r;}
|
||||
|
||||
float snoise(vec3 v){
|
||||
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
|
||||
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
|
||||
|
||||
// First corner
|
||||
vec3 i = floor(v + dot(v, C.yyy) );
|
||||
vec3 x0 = v - i + dot(i, C.xxx) ;
|
||||
|
||||
// Other corners
|
||||
vec3 g = step(x0.yzx, x0.xyz);
|
||||
vec3 l = 1.0 - g;
|
||||
vec3 i1 = min( g.xyz, l.zxy );
|
||||
vec3 i2 = max( g.xyz, l.zxy );
|
||||
|
||||
// x0 = x0 - 0. + 0.0 * C
|
||||
vec3 x1 = x0 - i1 + 1.0 * C.xxx;
|
||||
vec3 x2 = x0 - i2 + 2.0 * C.xxx;
|
||||
vec3 x3 = x0 - 1. + 3.0 * C.xxx;
|
||||
|
||||
// Permutations
|
||||
i = mod(i, 289.0 );
|
||||
vec4 p = permute( permute( permute(
|
||||
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
|
||||
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
|
||||
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
|
||||
|
||||
// Gradients
|
||||
// ( N*N points uniformly over a square, mapped onto an octahedron.)
|
||||
float n_ = 1.0/7.0; // N=7
|
||||
vec3 ns = n_ * D.wyz - D.xzx;
|
||||
|
||||
vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N)
|
||||
|
||||
vec4 x_ = floor(j * ns.z);
|
||||
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
|
||||
|
||||
vec4 x = x_ *ns.x + ns.yyyy;
|
||||
vec4 y = y_ *ns.x + ns.yyyy;
|
||||
vec4 h = 1.0 - abs(x) - abs(y);
|
||||
|
||||
vec4 b0 = vec4( x.xy, y.xy );
|
||||
vec4 b1 = vec4( x.zw, y.zw );
|
||||
|
||||
vec4 s0 = floor(b0)*2.0 + 1.0;
|
||||
vec4 s1 = floor(b1)*2.0 + 1.0;
|
||||
vec4 sh = -step(h, vec4(0.0));
|
||||
|
||||
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
|
||||
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
|
||||
|
||||
vec3 p0 = vec3(a0.xy,h.x);
|
||||
vec3 p1 = vec3(a0.zw,h.y);
|
||||
vec3 p2 = vec3(a1.xy,h.z);
|
||||
vec3 p3 = vec3(a1.zw,h.w);
|
||||
|
||||
//Normalise gradients
|
||||
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
|
||||
p0 *= norm.x;
|
||||
p1 *= norm.y;
|
||||
p2 *= norm.z;
|
||||
p3 *= norm.w;
|
||||
|
||||
// Mix final noise value
|
||||
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
|
||||
m = m * m;
|
||||
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
|
||||
dot(p2,x2), dot(p3,x3) ) );
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 texcoord = vec2(gl_TexCoord[0]);
|
||||
vec4 color = texture2D(image, texcoord);
|
||||
|
||||
vec3 relBlockPos = mod(blockpos, 32.0) / 32.0;
|
||||
vec2 maskcoord = texcoord + vec2(relBlockPos.x + relBlockPos.y, relBlockPos.z + relBlockPos.y);
|
||||
vec4 maskColor = texture2D(mask, maskcoord);
|
||||
float maskgs = maskColor.r;
|
||||
//maskgs = snoise(blockpos / 32.0 + );
|
||||
|
||||
float r = color.r * gl_Color.r;
|
||||
float g = color.g * gl_Color.g;
|
||||
float b = color.b * gl_Color.b;
|
||||
float a = color.a; // Ignore gl_Color.a as we don't want to make use of that for the dissolve effect
|
||||
|
||||
float pulse = (sin(time / 10.0) + 1.0) / 2.0;
|
||||
vec4 pulseColor = texture2D(mask, maskcoord + time / 1000.0);
|
||||
vec4 pulseColor2 = texture2D(mask, vec2(maskcoord.x - time / 1300.0, maskcoord.y - time / 1300.0));
|
||||
float pulseGreyScale = pulseColor.r + pulseColor2.r / 2.0;
|
||||
g += (1.0 - g) * pulseGreyScale * pulse * 0.2;
|
||||
b += (1.0 - b) * pulseGreyScale * pulse;
|
||||
|
||||
// float exr1 = sin(texcoord.x * 2 + texcoord.y * 10 + time * 0.035);
|
||||
// float exr2 = sin(texcoord.x * 20 + texcoord.y * 2 + time * 0.15);
|
||||
// float exr3 = sin(texcoord.x * 1 + texcoord.y * 90 + time * 0.75);
|
||||
|
||||
// float w1 = (cos(time * 0.1) + 1) * 0.5;
|
||||
// float w2 = (sin(time * 0.08) + 1) * 0.5;
|
||||
// float w3 = (cos(time * 0.001) + 1) * 0.5;
|
||||
|
||||
// float w = w1 + w2 + w3;
|
||||
// float exr = (exr1 * w1 + exr2 * w2 + exr3 * w3) / w * 0.1;
|
||||
|
||||
// r += exr;
|
||||
// g -= exr;
|
||||
|
||||
if(highlight == 1) {
|
||||
r -= 0.2;
|
||||
b -= 0.2;
|
||||
g -= 0.2;
|
||||
}
|
||||
|
||||
r = max(0, min(1, r));
|
||||
g = max(0, min(1, g));
|
||||
b = max(0, min(1, b));
|
||||
|
||||
if(maskgs <= percentile)
|
||||
gl_FragColor = vec4(r, g, b, a);
|
||||
else gl_FragColor = vec4(r, g, b, 0);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#version 120
|
||||
|
||||
uniform sampler2D bgl_RenderedTexture;
|
||||
|
||||
void main() {
|
||||
vec2 texcoord = vec2(gl_TexCoord[0]);
|
||||
vec4 color = texture2D(bgl_RenderedTexture, texcoord);
|
||||
|
||||
float r = color.b * gl_Color.r;
|
||||
float g = color.g * gl_Color.g;
|
||||
float b = color.r * gl_Color.b;
|
||||
float a = color.a * gl_Color.a;
|
||||
|
||||
gl_FragColor = vec4(r, g, b, a);
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 266 B |
Binary file not shown.
|
After Width: | Height: | Size: 174 KiB |
Reference in New Issue
Block a user