/* * This file is part of Matter Overdrive * Copyright (c) 2015., Simeon Radivoev, All rights reserved. * * Matter Overdrive is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Matter Overdrive is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Matter Overdrive. If not, see <http://www.gnu.org/licenses>. */ package matteroverdrive.client.render.tileentity; import matteroverdrive.MatterOverdrive; import matteroverdrive.Reference; import matteroverdrive.client.data.Color; import matteroverdrive.handler.ConfigurationHandler; import matteroverdrive.machines.MOTileEntityMachine; import matteroverdrive.util.IConfigSubscriber; import matteroverdrive.util.MOLog; import matteroverdrive.util.MOStringHelper; import matteroverdrive.util.RenderUtils; import matteroverdrive.util.math.MOMathHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import org.apache.commons.io.IOUtils; import org.lwjgl.opengl.GLContext; import java.io.IOException; import java.io.InputStream; import java.util.Random; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL20.*; /** * Created by Simeon on 5/27/2015. */ public abstract class TileEntityRendererStation<T extends MOTileEntityMachine> extends TileEntitySpecialRenderer implements IConfigSubscriber { public static ResourceLocation glowTexture = new ResourceLocation(Reference.PATH_FX + "hologram_beam.png"); ResourceLocation holo_shader_vert_loc = new ResourceLocation(Reference.PATH_SHADERS + "holo_shader.vert"); ResourceLocation holo_shader_frag_loc = new ResourceLocation(Reference.PATH_SHADERS + "holo_shader.frag"); String holo_shader_vert; String holo_shader_frag; protected int shaderProgram; protected boolean validShader = true; private boolean enableHoloShader = true; int vertexShader; int fragmentShader; Random fliker; protected Color holoColor; protected Color red_holoColor; public TileEntityRendererStation() { holoColor = Reference.COLOR_HOLO.multiplyWithoutAlpha(0.25f); red_holoColor = Reference.COLOR_HOLO_RED.multiplyWithoutAlpha(0.25f); fliker = new Random(); if (GLContext.getCapabilities().OpenGL20) { loadShader(); }else { validShader = false; MatterOverdrive.log.warn("Your machine does not support OpenGL 2.0. The holographic shader will be disabled."); } } private void loadShader() { shaderProgram = glCreateProgram(); vertexShader = glCreateShader(GL_VERTEX_SHADER); fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); try { InputStream descriptionStream = Minecraft.getMinecraft().getResourceManager().getResource(holo_shader_vert_loc).getInputStream(); holo_shader_vert = IOUtils.toString(descriptionStream); } catch (IOException e) { e.printStackTrace(); } try { InputStream descriptionStream = Minecraft.getMinecraft().getResourceManager().getResource(holo_shader_frag_loc).getInputStream(); holo_shader_frag = IOUtils.toString(descriptionStream); } catch (IOException e) { e.printStackTrace(); } try { glShaderSource(vertexShader, holo_shader_vert); glCompileShader(vertexShader); glShaderSource(fragmentShader, holo_shader_frag); glCompileShader(fragmentShader); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); if (glGetProgrami(vertexShader, GL_LINK_STATUS) == GL_FALSE) { System.out.println("Could not link shader"); System.out.println(glGetProgramInfoLog(vertexShader, glGetProgrami(vertexShader, GL_INFO_LOG_LENGTH))); validShader = false; } glValidateProgram(shaderProgram); if (glGetProgrami(vertexShader, GL_VALIDATE_STATUS) == GL_FALSE) { System.out.println("Could not validate shader"); System.out.println(glGetProgramInfoLog(vertexShader, glGetProgrami(vertexShader, GL_INFO_LOG_LENGTH))); validShader = false; } if (glGetShaderi(vertexShader, GL_COMPILE_STATUS) == GL_FALSE) { System.out.println("Could not compile shader"); validShader = false; } } catch (Exception e) { e.printStackTrace(); validShader = false; } } private void drawHoloLights(TileEntity entity,World world, double x, double y, double z,double t) { glEnable(GL_BLEND); glDisable(GL_LIGHTING); glBlendFunc(GL_ONE, GL_ONE); glDepthMask(false); RenderUtils.disableLightmap(); glDisable(GL_CULL_FACE); Minecraft.getMinecraft().renderEngine.bindTexture(glowTexture); double height = 9f * (1f / 16f); double hologramHeight = getLightHeight(); double topSize = getLightsSize() - 1; glPushMatrix(); glTranslated(x,y + height,z); Tessellator.instance.startDrawingQuads(); Tessellator.instance.setColorRGBA_F(getHoloColor(entity).getFloatR(), getHoloColor(entity).getFloatG(), getHoloColor(entity).getFloatB(), 1); Tessellator.instance.addVertexWithUV(0, 0, 0, 1, 1); Tessellator.instance.addVertexWithUV(-topSize, hologramHeight, -topSize, 1, 0); Tessellator.instance.addVertexWithUV(1 + topSize, hologramHeight, -topSize, 0, 0); Tessellator.instance.addVertexWithUV(1, 0, 0, 0, 1); Tessellator.instance.addVertexWithUV(1, 0, 0, 1, 1); Tessellator.instance.addVertexWithUV(1 + topSize, hologramHeight, -topSize, 1, 0); Tessellator.instance.addVertexWithUV(1 + topSize, hologramHeight, 1 + topSize, 0, 0); Tessellator.instance.addVertexWithUV(1, 0, 1, 0, 1); Tessellator.instance.addVertexWithUV(1, 0, 1, 1, 1); Tessellator.instance.addVertexWithUV(1 + topSize, hologramHeight, 1 + topSize, 1, 0); Tessellator.instance.addVertexWithUV(-topSize, hologramHeight, 1 + topSize, 0, 0); Tessellator.instance.addVertexWithUV(0, 0, 1, 0, 1); Tessellator.instance.addVertexWithUV(0, 0, 1, 1, 1); Tessellator.instance.addVertexWithUV(-topSize, hologramHeight, 1 + topSize, 1, 0); Tessellator.instance.addVertexWithUV(-topSize, hologramHeight, -topSize, 0, 0); Tessellator.instance.addVertexWithUV(0, 0, 0, 0, 1); Tessellator.instance.draw(); glPopMatrix(); glDisable(GL_BLEND); glEnable(GL_LIGHTING); glEnable(GL_CULL_FACE); RenderUtils.enableLightmap(); } protected double getLightHeight() { return 1; } protected double getLightsSize() { return 1.3; } protected Color getHoloColor(TileEntity entity) { if (((MOTileEntityMachine)entity).isUseableByPlayer(Minecraft.getMinecraft().thePlayer)) { return holoColor; } return red_holoColor; } @Override public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float ticks) { double t = MOMathHelper.noise(tileEntity.xCoord * 0.3, tileEntity.yCoord * 0.3, tileEntity.zCoord * 0.3); try { glPushMatrix(); glPushAttrib(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); try { renderHologram((T) tileEntity, x, y, z, ticks, t); } catch (ClassCastException e) { MOLog.warn("Could not cast to desired station class", e); } glPopAttrib(); glPopMatrix(); } catch (Exception e) { MOLog.warn("Error while render a station", e); } if (drawHoloLights()) drawHoloLights(tileEntity,tileEntity.getWorldObj(), x, y, z,ticks); } protected boolean drawHoloLights() { return true; } protected void beginHolo(T tileEntity) { if (validShader && enableHoloShader) { glUseProgram(shaderProgram); glUniform4f(0, getHoloColor(tileEntity).getFloatR(), getHoloColor(tileEntity).getFloatG(), getHoloColor(tileEntity).getFloatB(), 0); }else { glEnable(GL_ALPHA_TEST); glEnable(GL_DEPTH_TEST); glDepthMask(true); } } protected void endHolo() { if (validShader) { glUseProgram(0); } } protected void rotate(T station,double noise) { glRotated((Minecraft.getMinecraft().theWorld.getWorldTime() * 0.5) + (1800 * noise), 0, -1, 0); } protected boolean isUsable(T station) { return (station).isUseableByPlayer(Minecraft.getMinecraft().thePlayer); } protected void renderHologram(T station, double x, double y, double z, float partialTicks, double noise) { if (!isUsable(station)) { glPushMatrix(); glTranslated(x + 0.5, y + 0.8, z + 0.5); rotate(station, noise); glDisable(GL_CULL_FACE); glDisable(GL_LIGHTING); glScaled(0.02, 0.02, 0.02); glRotated(180, 1, 0, 0); Color color = Reference.COLOR_HOLO_RED.multiplyWithoutAlpha(0.33f); String info[] = MOStringHelper.translateToLocal("gui.hologram.access_denied").split(" "); for (int i = 0; i < info.length; i++) { int width = Minecraft.getMinecraft().fontRenderer.getStringWidth(info[i]); glPushMatrix(); glTranslated(-width / 2, -32, 0); Minecraft.getMinecraft().fontRenderer.drawString(info[i], 0, i * 10, color.getColor()); glPopMatrix(); } glPopMatrix(); } } @Override public void onConfigChanged(ConfigurationHandler config) { enableHoloShader = config.getBool("use holo shader",ConfigurationHandler.CATEGORY_CLIENT,true,"Use the custom holo shader for holographic items"); } }