diff --git a/src/main/java/WayofTime/bloodmagic/client/helper/ShaderHelper.java b/src/main/java/WayofTime/bloodmagic/client/helper/ShaderHelper.java new file mode 100644 index 00000000..f6c68e74 --- /dev/null +++ b/src/main/java/WayofTime/bloodmagic/client/helper/ShaderHelper.java @@ -0,0 +1,209 @@ +/** + * This class was created by . It's distributed as + * part of the Botania Mod. Get the Source Code in github: + * https://github.com/Vazkii/Botania + * + * Botania is Open Source and distributed under a + * Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License + * (http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_GB) + * + * File Created @ [Apr 9, 2014, 11:20:26 PM (GMT)] + */ +package WayofTime.bloodmagic.client.helper; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; + +import net.minecraftforge.fml.common.FMLLog; + +import org.lwjgl.opengl.ARBFragmentShader; +import org.lwjgl.opengl.ARBShaderObjects; +import org.lwjgl.opengl.ARBVertexShader; +import org.lwjgl.opengl.GL11; + +public final class ShaderHelper +{ + + private static final int VERT = ARBVertexShader.GL_VERTEX_SHADER_ARB; + private static final int FRAG = ARBFragmentShader.GL_FRAGMENT_SHADER_ARB; + + public static int beam = 0; + + public static void initShaders() + { +// if(!useShaders()) +// return; + + beam = createProgram(null, "/assets/bloodmagic/shaders/beam.frag"); + } + + public static void useShaderWithProps(int shader, Object... props) + { +// if(!useShaders()) +// return; + + ARBShaderObjects.glUseProgramObjectARB(shader); + + if (shader != 0 && props.length % 2 == 0) + { + int propCount = props.length / 2; + for (int i = 0; i < propCount; i++) + { + String propName = (String) props[i * 2]; + Object propVal = props[i * 2 + 1]; + + int uniform = ARBShaderObjects.glGetUniformLocationARB(shader, propName); + if (propVal instanceof Integer) + ARBShaderObjects.glUniform1iARB(uniform, (Integer) propVal); + if (propVal instanceof Float) + ARBShaderObjects.glUniform1fARB(uniform, (Float) propVal); + // Possible Vector2, Vector3 and Vector4, no need yet. + } + } + } + + public static void useShader(int shader) + { + useShaderWithProps(shader); + } + + public static void releaseShader() + { + useShader(0); + } + + public static boolean useShaders() + { + return true;//ConfigHandler.useShaders && OpenGlHelper.shadersSupported; + } + + // 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 = 0; + if (vert != null) + vertId = createShader(vert, VERT); + if (frag != null) + fragId = createShader(frag, FRAG); + + 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) + { + FMLLog.warning(getLogInfo(program)); + return 0; + } + + ARBShaderObjects.glValidateProgramARB(program); + if (ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_VALIDATE_STATUS_ARB) == GL11.GL_FALSE) + { + FMLLog.warning(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, "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) + { + if (innerExc == null) + innerExc = exc; + else + exc.printStackTrace(); + } + } + + 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(); + } +} diff --git a/src/main/java/WayofTime/bloodmagic/client/render/RenderItemRoutingNode.java b/src/main/java/WayofTime/bloodmagic/client/render/RenderItemRoutingNode.java new file mode 100644 index 00000000..d212eb4d --- /dev/null +++ b/src/main/java/WayofTime/bloodmagic/client/render/RenderItemRoutingNode.java @@ -0,0 +1,116 @@ +package WayofTime.bloodmagic.client.render; + +import java.util.List; + +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.BlockPos; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; + +import org.lwjgl.opengl.GL11; + +import WayofTime.bloodmagic.client.helper.ShaderHelper; +import WayofTime.bloodmagic.tile.routing.TileRoutingNode; + +public class RenderItemRoutingNode extends TileEntitySpecialRenderer +{ + private static final ResourceLocation field_110629_a = new ResourceLocation("textures/entity/beacon_beam.png"); + +// private static final ResourceLocation test = new ResourceLocation("luminescence:textures/models/InputMirror.png"); + + @Override + public void renderTileEntityAt(TileRoutingNode tileNode, double x, double y, double z, float partialTicks, int destroyStage) + { + List connectionList = tileNode.getConnected(); + for (BlockPos wantedPos : connectionList) + { + BlockPos offsetPos = wantedPos.subtract(tileNode.getPos()); + + //The beam renders towards the east by default. + + int xd = offsetPos.getX(); + int yd = offsetPos.getY(); + int zd = offsetPos.getZ(); + double distance = Math.sqrt(xd * xd + yd * yd + zd * zd); + double subLength = MathHelper.sqrt_double(xd * xd + zd * zd); + float rotYaw = -((float) (Math.atan2(zd, xd) * 180.0D / Math.PI)); + float rotPitch = ((float) (Math.atan2(yd, subLength) * 180.0D / Math.PI)); + + GL11.glPushMatrix(); + float f1 = 1.0f; + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer wr = tessellator.getWorldRenderer(); + this.bindTexture(field_110629_a); + GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, 10497.0F); + GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, 10497.0F); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_CULL_FACE); + float f2 = 0; + float f3 = -f2 * 0.2F - (float) MathHelper.floor_float(-f2 * 0.1F); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + GL11.glDepthMask(false); + + double width = 0.1; + + float test = (tileNode.getWorld().getTotalWorldTime() + partialTicks) / 5f; + + double d18 = -width / 2; + double d19 = -width / 2; + double d20 = width / 2; + double d21 = -width / 2; + double d22 = -width / 2; + double d23 = width / 2; + double d24 = width / 2; + double d25 = width / 2; + double d26 = (double) (distance * f1); + double d27 = 0.0D; + double d28 = 1.0D; + double d29 = (double) (f3) + test; + double d30 = (double) (distance * f1) + d29; + + GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5); + + GL11.glRotatef(rotYaw, 0.0F, 1, 0); + GL11.glRotatef(rotPitch, 0, 0.0F, 1); + +// tessellator.setBrightness(240); +// float s = 1F / 16F; +// GL11.glTranslatef(0F, s, s); +// GL11.glScalef(1F, s * 14F, s * 14F); + wr.begin(7, DefaultVertexFormats.POSITION_TEX); +// tessellator.setColorRGBA(255, 255, 255, 100); + wr.pos(d26, d18, d19).tex(d28, d30).endVertex(); + wr.pos(0, d18, d19).tex(d28, d29).endVertex(); + wr.pos(0, d20, d21).tex(d27, d29).endVertex(); + wr.pos(d26, d20, d21).tex(d27, d30).endVertex(); + wr.pos(d26, d24, d25).tex(d28, d30).endVertex(); + wr.pos(0, d24, d25).tex(d28, d29).endVertex(); + wr.pos(0, d22, d23).tex(d27, d29).endVertex(); + wr.pos(d26, d22, d23).tex(d27, d30).endVertex(); + wr.pos(d26, d20, d21).tex(d28, d30).endVertex(); + wr.pos(0, d20, d21).tex(d28, d29).endVertex(); + wr.pos(0, d24, d25).tex(d27, d29).endVertex(); + wr.pos(d26, d24, d25).tex(d27, d30).endVertex(); + wr.pos(d26, d22, d23).tex(d28, d30).endVertex(); + wr.pos(0, d22, d23).tex(d28, d29).endVertex(); + wr.pos(0, d18, d19).tex(d27, d29).endVertex(); + wr.pos(d26, d18, d19).tex(d27, d30).endVertex(); + + ShaderHelper.useShaderWithProps(ShaderHelper.beam, "time", (int) tileNode.getWorld().getTotalWorldTime()); + tessellator.draw(); + ShaderHelper.releaseShader(); + + GL11.glDepthMask(true); + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_TEXTURE_2D); + GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F); + GL11.glPopMatrix(); + } + } +} diff --git a/src/main/java/WayofTime/bloodmagic/proxy/ClientProxy.java b/src/main/java/WayofTime/bloodmagic/proxy/ClientProxy.java index 5872893f..8bbb901e 100644 --- a/src/main/java/WayofTime/bloodmagic/proxy/ClientProxy.java +++ b/src/main/java/WayofTime/bloodmagic/proxy/ClientProxy.java @@ -6,9 +6,11 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.client.registry.RenderingRegistry; import WayofTime.bloodmagic.api.Constants; +import WayofTime.bloodmagic.client.helper.ShaderHelper; import WayofTime.bloodmagic.client.mesh.ItemSentientSwordMeshDefinition; import WayofTime.bloodmagic.client.render.RenderAlchemyArray; import WayofTime.bloodmagic.client.render.RenderAltar; +import WayofTime.bloodmagic.client.render.RenderItemRoutingNode; import WayofTime.bloodmagic.client.render.entity.SentientArrowRenderFactory; import WayofTime.bloodmagic.client.render.entity.SoulSnareRenderFactory; import WayofTime.bloodmagic.entity.projectile.EntitySentientArrow; @@ -17,6 +19,7 @@ import WayofTime.bloodmagic.registry.ModBlocks; import WayofTime.bloodmagic.registry.ModItems; import WayofTime.bloodmagic.tile.TileAlchemyArray; import WayofTime.bloodmagic.tile.TileAltar; +import WayofTime.bloodmagic.tile.routing.TileRoutingNode; import WayofTime.bloodmagic.util.handler.ClientEventHandler; import WayofTime.bloodmagic.util.helper.InventoryRenderHelper; @@ -45,6 +48,7 @@ public class ClientProxy extends CommonProxy ClientRegistry.bindTileEntitySpecialRenderer(TileAlchemyArray.class, new RenderAlchemyArray()); ClientRegistry.bindTileEntitySpecialRenderer(TileAltar.class, new RenderAltar()); + ClientRegistry.bindTileEntitySpecialRenderer(TileRoutingNode.class, new RenderItemRoutingNode()); ModelLoader.setCustomMeshDefinition(ModItems.sentientSword, new ItemSentientSwordMeshDefinition()); } @@ -54,6 +58,7 @@ public class ClientProxy extends CommonProxy { RenderingRegistry.registerEntityRenderingHandler(EntitySoulSnare.class, new SoulSnareRenderFactory()); RenderingRegistry.registerEntityRenderingHandler(EntitySentientArrow.class, new SentientArrowRenderFactory()); + ShaderHelper.initShaders(); } @Override diff --git a/src/main/java/WayofTime/bloodmagic/proxy/CommonProxy.java b/src/main/java/WayofTime/bloodmagic/proxy/CommonProxy.java index 9c16bbb8..d32d5303 100644 --- a/src/main/java/WayofTime/bloodmagic/proxy/CommonProxy.java +++ b/src/main/java/WayofTime/bloodmagic/proxy/CommonProxy.java @@ -1,7 +1,7 @@ package WayofTime.bloodmagic.proxy; +import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.common.FMLCommonHandler; import WayofTime.bloodmagic.util.handler.EventHandler; import WayofTime.bloodmagic.util.helper.InventoryRenderHelper; @@ -32,4 +32,10 @@ public class CommonProxy { } + + public Object beamCont(World worldObj, double xi, double yi, double zi, double tx, double ty, double tz, int type, int color, boolean reverse, float endmod, Object input, int impact) + { + // TODO Auto-generated method stub + return null; + } } diff --git a/src/main/java/WayofTime/bloodmagic/tile/routing/TileRoutingNode.java b/src/main/java/WayofTime/bloodmagic/tile/routing/TileRoutingNode.java index 6d3e9e59..ab9dda98 100644 --- a/src/main/java/WayofTime/bloodmagic/tile/routing/TileRoutingNode.java +++ b/src/main/java/WayofTime/bloodmagic/tile/routing/TileRoutingNode.java @@ -9,6 +9,8 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import WayofTime.bloodmagic.api.Constants; import WayofTime.bloodmagic.routing.IItemRoutingNode; import WayofTime.bloodmagic.routing.IMasterRoutingNode; @@ -151,6 +153,7 @@ public class TileRoutingNode extends TileInventory implements IRoutingNode, IIte { if (!connectionList.contains(pos1)) { + worldObj.markBlockForUpdate(this.pos); connectionList.add(pos1); } } @@ -160,6 +163,7 @@ public class TileRoutingNode extends TileInventory implements IRoutingNode, IIte { if (connectionList.contains(pos1)) { + worldObj.markBlockForUpdate(this.pos); connectionList.remove(pos1); } } @@ -175,4 +179,11 @@ public class TileRoutingNode extends TileInventory implements IRoutingNode, IIte { return 0; } + + @Override + @SideOnly(Side.CLIENT) + public double getMaxRenderDistanceSquared() + { + return 10000; + } } diff --git a/src/main/resources/assets/bloodmagic/textures/misc/beam2.png b/src/main/resources/assets/bloodmagic/textures/misc/beam2.png new file mode 100644 index 00000000..aa338d92 Binary files /dev/null and b/src/main/resources/assets/bloodmagic/textures/misc/beam2.png differ