org.spoutcraft.client.gui.MCRenderDelegate.java Source code

Java tutorial

Introduction

Here is the source code for org.spoutcraft.client.gui.MCRenderDelegate.java

Source

/*
 * This file is part of Spoutcraft.
 *
 * Copyright (c) 2011 Spout LLC <http://www.spout.org/>
 * Spoutcraft is licensed under the GNU Lesser General Public License.
 *
 * Spoutcraft is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Spoutcraft 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.spoutcraft.client.gui;

import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.UUID;

import gnu.trove.map.TObjectIntMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.map.hash.TObjectIntHashMap;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.lwjgl.opengl.ContextCapabilities;
import org.lwjgl.opengl.EXTFramebufferObject;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL14;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GLContext;
import org.newdawn.slick.opengl.Texture;

import net.minecraft.client.Minecraft;
import net.minecraft.src.Entity;
import net.minecraft.src.FontRenderer;
import net.minecraft.src.FoodStats;
import net.minecraft.src.GuiButton;
import net.minecraft.src.GuiIngame;
import net.minecraft.src.Material;
import net.minecraft.src.Potion;
import net.minecraft.src.RenderHelper;
import net.minecraft.src.RenderManager;
import net.minecraft.src.ScaledResolution;
import net.minecraft.src.Tessellator;

import org.spoutcraft.api.material.MaterialData;
import org.spoutcraft.api.gui.ArmorBar;
import org.spoutcraft.api.gui.BubbleBar;
import org.spoutcraft.api.gui.Button;
import org.spoutcraft.api.gui.Color;
import org.spoutcraft.api.gui.Control;
import org.spoutcraft.api.gui.ExpBar;
import org.spoutcraft.api.gui.GenericBitmap;
import org.spoutcraft.api.gui.GenericButton;
import org.spoutcraft.api.gui.GenericCheckBox;
import org.spoutcraft.api.gui.GenericComboBox;
import org.spoutcraft.api.gui.GenericEntityWidget;
import org.spoutcraft.api.gui.GenericGradient;
import org.spoutcraft.api.gui.GenericItemWidget;
import org.spoutcraft.api.gui.GenericLabel;
import org.spoutcraft.api.gui.GenericListWidget;
import org.spoutcraft.api.gui.GenericListWidgetItem;
import org.spoutcraft.api.gui.GenericRadioButton;
import org.spoutcraft.api.gui.GenericScrollArea;
import org.spoutcraft.api.gui.GenericScrollable;
import org.spoutcraft.api.gui.GenericSlider;
import org.spoutcraft.api.gui.GenericSlot;
import org.spoutcraft.api.gui.GenericTextField;
import org.spoutcraft.api.gui.GenericTexture;
import org.spoutcraft.api.gui.HealthBar;
import org.spoutcraft.api.gui.HungerBar;
import org.spoutcraft.api.gui.ListWidgetItem;
import org.spoutcraft.api.gui.MinecraftFont;
import org.spoutcraft.api.gui.MinecraftTessellator;
import org.spoutcraft.api.gui.Orientation;
import org.spoutcraft.api.gui.RenderDelegate;
import org.spoutcraft.api.gui.RenderPriority;
import org.spoutcraft.api.gui.RenderUtil;
import org.spoutcraft.api.gui.Widget;
import org.spoutcraft.api.gui.WidgetAnchor;
import org.spoutcraft.api.inventory.ItemStack;
import org.spoutcraft.client.SpoutClient;
import org.spoutcraft.client.io.CustomTextureManager;

public class MCRenderDelegate implements RenderDelegate {
    private Color scrollBarColor = new Color(0.26F, 0.26F, 0.26F, 0.33F);
    private Color scrollBarColor2 = new Color(0.1F, 0.1F, 0.1F, 0.38F);
    public static boolean shouldRenderCursor = false;
    protected final RenderItemCustom renderer;
    protected HashMap<UUID, GuiButton> customFields = new HashMap<UUID, GuiButton>();
    protected TObjectIntMap<GenericBitmap> bitmapId = new TObjectIntHashMap<GenericBitmap>();
    MinecraftFont font = new MinecraftFontWrapper();
    MinecraftTessellator tessellator = new MinecraftTessellatorWrapper();
    TIntObjectHashMap<String> optimalWidth = new TIntObjectHashMap<String>();

    public MCRenderDelegate() {
        renderer = new RenderItemCustom();
        renderer.setRenderManager(RenderManager.instance);
    }

    public void downloadTexture(String plugin, String url) {
        CustomTextureManager.downloadTexture(plugin, url);
    }

    public int getScreenHeight() {
        ScaledResolution resolution = new ScaledResolution(SpoutClient.getHandle().gameSettings,
                SpoutClient.getHandle().displayWidth, SpoutClient.getHandle().displayHeight);
        return resolution.getScaledHeight();
    }

    public int getScreenWidth() {
        ScaledResolution resolution = new ScaledResolution(SpoutClient.getHandle().gameSettings,
                SpoutClient.getHandle().displayWidth, SpoutClient.getHandle().displayHeight);
        return resolution.getScaledWidth();
    }

    public int getTextWidth(String text) {
        return Minecraft.theMinecraft.fontRenderer.getStringWidth(text);
    }

    public void render(ArmorBar bar) {
        float armorPercent = Minecraft.theMinecraft.thePlayer.inventory.getTotalArmorValue() / 0.2f;
        if (bar.isVisible() && bar.getMaxNumShields() > 0) {
            int y = (int) bar.getScreenY();
            float armorPercentPerIcon = 100f / bar.getMaxNumShields();
            for (int icon = 0; icon < bar.getMaxNumShields(); icon++) {
                if (armorPercent > 0 || bar.isAlwaysVisible()) {
                    int x = (int) bar.getScreenX() + icon * bar.getIconOffset();
                    boolean full = (icon + 1) * armorPercentPerIcon <= armorPercent;
                    boolean half = (icon + 1) * armorPercentPerIcon < armorPercent + armorPercentPerIcon;
                    if (full) { // White armor (filled in)
                        RenderUtil.drawTexturedModalRectangle(x, y, 34, 9, 9, 9, 0f);
                    } else if (half) { // Half filled in
                        RenderUtil.drawTexturedModalRectangle(x, y, 25, 9, 9, 9, 0f);
                    } else {
                        RenderUtil.drawTexturedModalRectangle(x, y, 16, 9, 9, 9, 0f);
                    }
                }
            }
        }
    }

    public void render(BubbleBar bar) {
        if (Minecraft.theMinecraft.thePlayer.isInsideOfMaterial(Material.water)) {
            int bubbles = (int) Math
                    .ceil(((double) (Minecraft.theMinecraft.thePlayer.getAir() - 2) * bar.getMaxNumBubbles())
                            / (Minecraft.theMinecraft.thePlayer.maxAir));
            int poppingBubbles = (int) Math
                    .ceil(((double) Minecraft.theMinecraft.thePlayer.getAir() * bar.getMaxNumBubbles())
                            / (Minecraft.theMinecraft.thePlayer.maxAir))
                    - bubbles;
            if (bar.isVisible()) {
                for (int bubble = 0; bubble < bubbles + poppingBubbles; bubble++) {
                    if (bubble < bubbles) {
                        RenderUtil.drawTexturedModalRectangle((int) bar.getScreenX() - bubble * bar.getIconOffset(),
                                (int) bar.getScreenY(), 16, 18, 9, 9, 0f);
                    } else {
                        RenderUtil.drawTexturedModalRectangle((int) bar.getScreenX() - bubble * bar.getIconOffset(),
                                (int) bar.getScreenY(), 25, 18, 9, 9, 0f);
                    }
                }
            }
        }
    }

    public void render(GenericButton button) {
        if (button.isVisible()) {
            FontRenderer font = Minecraft.theMinecraft.fontRenderer;
            SpoutClient.getHandle().renderEngine.bindTexture("/gui/gui.png");
            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
            GL11.glTranslatef((float) Math.floor(button.getScreenX()), (float) Math.floor(button.getScreenY()), 0);
            float width = (float) (button.getWidth() < 200 ? button.getWidth() : 200);
            GL11.glScalef((float) button.getWidth() / width, (float) button.getHeight() / 20f, 1);

            String text = getFittingText(button.getText(), (int) button.getInnerWidth());

            int hoverState = getHoverState(button, isHovering(button));
            RenderUtil.drawTexturedModalRectangle(0, 0, 0, 46 + hoverState * 20, (int) Math.ceil(width / 2), 20,
                    0f);
            RenderUtil.drawTexturedModalRectangle((int) Math.floor(width / 2), 0, 200 - (int) Math.ceil(width / 2),
                    46 + hoverState * 20, (int) Math.ceil(width / 2), 20, 0f);
            Color color = getColor(button);

            int left = 5;
            WidgetAnchor align = button.getAlign();
            if (align == WidgetAnchor.TOP_CENTER || align == WidgetAnchor.CENTER_CENTER
                    || align == WidgetAnchor.BOTTOM_CENTER) {
                left = (int) ((width / 2) - (font.getStringWidth(text) / 2));
            } else if (align == WidgetAnchor.TOP_RIGHT || align == WidgetAnchor.CENTER_RIGHT
                    || align == WidgetAnchor.BOTTOM_RIGHT) {
                left = (int) (width - font.getStringWidth(text)) - 5;
            }

            GL11.glPushMatrix();
            float scale = button.getScale();
            GL11.glScalef(scale, scale, scale);
            font.drawStringWithShadow(text, left, 6, color.toInt());
            GL11.glPopMatrix();
        }
    }

    protected boolean isHovering(Widget widget) {
        double mouseX = widget.getScreen().getMouseX();
        double mouseY = widget.getScreen().getMouseY();

        boolean hovering = mouseX >= widget.getActualX() && mouseY >= widget.getActualY()
                && mouseX < widget.getActualX() + widget.getWidth()
                && mouseY < widget.getActualY() + widget.getHeight();
        return hovering;
    }

    protected int getHoverState(Control control, boolean hover) {
        int state = 1;
        if (!control.isEnabled()) {
            state = 0;
        } else if (hover) {
            state = 2;
        }

        return state;
    }

    public void render(GenericGradient gradient) {
        GL11.glDisable(GL11.GL_TEXTURE_2D);
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glDisable(GL11.GL_ALPHA_TEST);
        GL11.glBlendFunc(770, 771);
        GL11.glShadeModel(GL11.GL_SMOOTH);
        Tessellator tessellator = Tessellator.instance;
        tessellator.startDrawingQuads();
        boolean VERT = gradient.getOrientation() == Orientation.VERTICAL;
        tessellator.setColorRGBA_F(gradient.getTopColor().getRedF(), gradient.getTopColor().getGreenF(),
                gradient.getTopColor().getBlueF(), gradient.getTopColor().getAlphaF());
        tessellator.addVertex((VERT ? gradient.getWidth() : 0) + gradient.getScreenX(),
                (VERT ? 0 : gradient.getHeight()) + gradient.getScreenY(), 0.0D);
        tessellator.addVertex(gradient.getScreenX(), gradient.getScreenY(), 0.0D);
        tessellator.setColorRGBA_F(gradient.getBottomColor().getRedF(), gradient.getBottomColor().getGreenF(),
                gradient.getBottomColor().getBlueF(), gradient.getBottomColor().getAlphaF());
        tessellator.addVertex((VERT ? 0 : gradient.getWidth()) + gradient.getScreenX(),
                (VERT ? gradient.getHeight() : 0) + gradient.getScreenY(), 0.0D);
        tessellator.addVertex(gradient.getWidth() + gradient.getScreenX(),
                gradient.getHeight() + gradient.getScreenY(), 0.0D);
        tessellator.draw();
        GL11.glShadeModel(GL11.GL_FLAT);
        GL11.glDisable(GL11.GL_BLEND);
        GL11.glEnable(GL11.GL_ALPHA_TEST);
        GL11.glEnable(GL11.GL_TEXTURE_2D);
    }

    public void render(GenericItemWidget item) {
        GL11.glDepthFunc(515);
        RenderHelper.enableGUIStandardItemLighting();
        GL11.glDisable(GL11.GL_DEPTH_TEST);
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glEnable(GL11.GL_COLOR_MATERIAL);
        GL11.glPushMatrix();
        GL11.glTranslatef((float) item.getScreenX(), (float) item.getScreenY(), 0);
        if (item.getAnchor() == WidgetAnchor.SCALE) {
            GL11.glScalef((float) (item.getScreen().getWidth() / 427f),
                    (float) (item.getScreen().getHeight() / 240f), 1);
        }
        GL11.glScaled(item.getWidth() / 16D, item.getHeight() / 16D, 1);
        int id = item.getTypeId();
        int data = item.getData();
        if (MaterialData.getCustomItem(id) != null) {
            int temp = id;
            id = 318;
            data = temp;
        }
        GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
        renderer.renderItemIntoGUI(SpoutClient.getHandle().fontRenderer, SpoutClient.getHandle().renderEngine,
                new net.minecraft.src.ItemStack(id, 1, data), 0, 0);
        GL11.glPopMatrix();
        GL11.glScaled(16D / item.getWidth(), 16D / item.getHeight(), 1);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        RenderHelper.disableStandardItemLighting();
    }

    public void render(GenericLabel label) {
        FontRenderer font = SpoutClient.getHandle().fontRenderer;
        String lines[] = label.getLines();

        double swidth = label.getTextWidth();
        double sheight = label.getTextHeight();

        GL11.glPushMatrix();

        double top = label.getScreenY();

        WidgetAnchor align = label.getAlign();
        if (align == WidgetAnchor.CENTER_LEFT || align == WidgetAnchor.CENTER_CENTER
                || align == WidgetAnchor.CENTER_RIGHT) {
            top -= (int) (label.isAuto() ? label.getActualHeight() : label.getHeight()) / 2;
        } else if (align == WidgetAnchor.BOTTOM_LEFT || align == WidgetAnchor.BOTTOM_CENTER
                || align == WidgetAnchor.BOTTOM_RIGHT) {
            top -= (int) (label.isAuto() ? label.getActualHeight() : label.getHeight());
        }

        double aleft = label.getScreenX();
        if (align == WidgetAnchor.TOP_CENTER || align == WidgetAnchor.CENTER_CENTER
                || align == WidgetAnchor.BOTTOM_CENTER) {
            aleft -= (int) (label.isAuto() ? label.getActualWidth() : label.getWidth()) / 2;
        } else if (align == WidgetAnchor.TOP_RIGHT || align == WidgetAnchor.CENTER_RIGHT
                || align == WidgetAnchor.BOTTOM_RIGHT) {
            aleft -= (int) (label.isAuto() ? label.getActualWidth() : label.getWidth());
        }

        GL11.glTranslatef((float) Math.floor(aleft), (float) Math.floor(top), 0);
        if (!label.isAuto()) {
            GL11.glScalef((float) (label.getWidth() / swidth), (float) (label.getHeight() / sheight), 1);
        } else if (label.getAnchor() == WidgetAnchor.SCALE) {
            GL11.glScalef((float) (label.getScreen().getWidth() / 427f),
                    (float) (label.getScreen().getHeight() / 240f), 1);
        }

        for (int i = 0; i < lines.length; i++) {
            double left = 0;

            if (align == WidgetAnchor.TOP_CENTER || align == WidgetAnchor.CENTER_CENTER
                    || align == WidgetAnchor.BOTTOM_CENTER) {
                left = (swidth / 2) - (font.getStringWidth(lines[i]) / 2);
            } else if (align == WidgetAnchor.TOP_RIGHT || align == WidgetAnchor.CENTER_RIGHT
                    || align == WidgetAnchor.BOTTOM_RIGHT) {
                left = swidth - font.getStringWidth(lines[i]);
            }

            float scale = label.getScale();
            float reset = 1 / scale;
            GL11.glScalef(scale, scale, scale);
            if (label.hasShadow()) {
                font.drawStringWithShadow(lines[i], (int) left, i * 10, label.getTextColor().toInt());
            } else {
                font.drawString(lines[i], (int) left, i * 10, label.getTextColor().toInt());
            }
            GL11.glScalef(reset, reset, reset);
        }
        GL11.glPopMatrix();
        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    }

    public void render(GenericSlider slider) {
        if (slider.isVisible()) {
            SpoutClient.getHandle().renderEngine.bindTexture("/gui/gui.png");
            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
            float width = (float) (slider.getWidth() < 200 ? slider.getWidth() : 200);
            GL11.glTranslatef((float) slider.getScreenX(), (float) slider.getScreenY(), 0);
            GL11.glScalef((float) slider.getWidth() / width, (float) slider.getHeight() / 20f, 1);

            double mouseX = slider.getScreen().getMouseX();

            RenderUtil.drawTexturedModalRectangle(0, 0, 0, 46, (int) Math.ceil(width / 2), 20, 0f);
            RenderUtil.drawTexturedModalRectangle((int) Math.floor(width / 2), 0, 200 - (int) Math.ceil(width / 2),
                    46, (int) Math.ceil(width / 2), 20, 0f);

            if (slider.isDragging()) {
                slider.setSliderPosition(
                        (float) (mouseX - (slider.getScreenX() + 4)) / (float) (slider.getWidth() - 8));
            }

            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
            width -= 8;
            RenderUtil.drawTexturedModalRectangle((int) (slider.getSliderPosition() * width), 0, 0, 66, 4, 20, 0f);
            RenderUtil.drawTexturedModalRectangle((int) (slider.getSliderPosition() * width) + 4, 0, 196, 66, 4, 20,
                    0f);

            Color color = slider.getTextColor();
            if (!slider.isEnabled()) {
                color = slider.getDisabledColor();
            }

            int left = 5;
            WidgetAnchor align = slider.getAlign();
            if (align == WidgetAnchor.TOP_CENTER || align == WidgetAnchor.CENTER_CENTER
                    || align == WidgetAnchor.BOTTOM_CENTER) {
                left = (int) ((width / 2) - (font.getTextWidth(slider.getText()) / 2));
            } else if (align == WidgetAnchor.TOP_RIGHT || align == WidgetAnchor.CENTER_RIGHT
                    || align == WidgetAnchor.BOTTOM_RIGHT) {
                left = (int) (width - font.getTextWidth(slider.getText())) - 5;
            }

            GL11.glPushMatrix();
            float scale = slider.getScale();
            GL11.glScalef(scale, scale, scale);
            font.drawString(slider.getText(), left, 6, color.toInt());
            GL11.glPopMatrix();
        }
    }

    public void render(GenericTextField textField) {
        FontRenderer font = SpoutClient.getHandle().fontRenderer;
        RenderUtil.drawRectangle((int) (textField.getScreenX() - 1), (int) (textField.getScreenY() - 1),
                (int) (textField.getScreenX() + textField.getWidth() + 1),
                (int) (textField.getScreenY() + textField.getHeight() + 1), textField.getBorderColor().toInt());
        RenderUtil.drawRectangle((int) textField.getScreenX(), (int) textField.getScreenY(),
                (int) (textField.getScreenX() + textField.getWidth()),
                (int) (textField.getScreenY() + textField.getHeight()), textField.getFieldColor().toInt());

        int x = (int) (textField.getScreenX() + GenericTextField.PADDING);
        int y = (int) (textField.getScreenY() + GenericTextField.PADDING);
        int color = textField.isEnabled() ? textField.getColor().toInt() : textField.getDisabledColor().toInt();
        int[] cursor = textField.getTextProcessor().getCursor2D();
        int lineNum = 0;
        int cursorOffset = 0;
        if (textField.getText().length() != 0) {
            String line;
            Iterator<String> iter = textField.getTextProcessor().iterator();

            while (iter.hasNext()) {
                line = iter.next();
                if (lineNum == cursor[0]) {
                    cursorOffset = font.getStringWidth(line.substring(0, cursor[1]));
                }
                font.drawStringWithShadow(line, x,
                        y + (GenericTextField.LINE_HEIGHT + GenericTextField.LINE_SPACING) * lineNum++, color);
            }
        } else if (!textField.isFocus()) {
            font.drawStringWithShadow(textField.getPlaceholder(), x, y, color);
        }
        boolean showCursor = textField.isEnabled() && textField.isFocus() && shouldRenderCursor;
        if (showCursor) {
            font.drawStringWithShadow("_", x + cursorOffset,
                    y + (GenericTextField.LINE_HEIGHT + GenericTextField.LINE_SPACING) * cursor[0] + 1, color);
        }

    }

    public void render(GenericTexture texture) {
        String addon = texture.getAddon();
        String url = texture.getUrl();
        org.newdawn.slick.opengl.Texture textureBinding;
        if (texture.isLocal()) {
            textureBinding = CustomTextureManager.getTextureFromJar(url);
        } else {
            textureBinding = CustomTextureManager.getTextureFromUrl(addon, url);
        }

        if (textureBinding != null) {
            if (texture.getOriginalHeight() != textureBinding.getImageWidth()
                    || texture.getOriginalWidth() != textureBinding.getImageHeight()) {
                texture.setOriginalWidth(textureBinding.getImageWidth());
                texture.setOriginalHeight(textureBinding.getImageHeight());
            }
            if (texture.getFinishDelegate() != null) {
                texture.getFinishDelegate().run();
                texture.setFinishDelegate(null);
            }

            GL11.glTranslatef((float) texture.getScreenX(), (float) texture.getScreenY(), 0); // moves texture into place
            drawTexture(textureBinding, (int) texture.getWidth(), (int) texture.getHeight(),
                    texture.isDrawingAlphaChannel(), texture.getLeft(), texture.getTop());
        }
    }

    public void render(GenericBitmap bitmap) {
        int textureId;
        if (bitmapId.containsKey(bitmap)) {
            textureId = bitmapId.get(bitmap);
        } else {
            IntBuffer tmp = IntBuffer.allocate(1);
            GL11.glGenTextures(tmp);
            textureId = tmp.get(0);
            bitmapId.put(bitmap, textureId);
        }
        int width = (int) bitmap.getActualWidth();
        int height = (int) bitmap.getActualHeight();
        int left = bitmap.getLeft();
        int top = bitmap.getTop();
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, bitmap.getRawWidth(), bitmap.getRawHeight(), 0,
                GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, bitmap.getBuffer());
        GL11.glTranslatef((float) bitmap.getScreenX(), (float) bitmap.getScreenY(), 0); // moves texture into place
        GL11.glPushMatrix();
        GL11.glDisable(GL11.GL_DEPTH_TEST);
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(770, 771);
        GL11.glDepthMask(false);
        bindColor(new Color(1.0F, 1.0F, 1.0F));
        SpoutClient.getHandle().renderEngine.bindTexture(textureId);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
        double tLeft = 0, tTop = 0, rWidth = bitmap.getWidth(), rHeight = bitmap.getHeight(), tWidth = rWidth,
                tHeight = rHeight;
        if (top >= 0 && left >= 0) {
            tWidth = Math.min(tWidth, width);
            tHeight = Math.min(tHeight, height);
            tLeft = Math.min(Math.max(0, left), rWidth);
            tTop = Math.min(Math.max(0, top), rHeight);
        }
        Tessellator tessellator = Tessellator.instance;
        tessellator.startDrawingQuads();
        tessellator.addVertexWithUV(0.0D, height, -90, tLeft, tTop); // draw corners
        tessellator.addVertexWithUV(width, height, -90, tWidth, tTop);
        tessellator.addVertexWithUV(width, 0.0D, -90, tWidth, tHeight);
        tessellator.addVertexWithUV(0.0D, 0.0D, -90, tLeft, tHeight);
        tessellator.draw();
        GL11.glDepthMask(true);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
        GL11.glPopMatrix();
        GL11.glDisable(GL11.GL_BLEND);
    }

    public void render(HealthBar bar) {
        int health = Minecraft.theMinecraft.thePlayer.health;
        boolean whiteOutlinedHearts = Minecraft.theMinecraft.thePlayer.hurtResistantTime / 3 % 2 == 1;
        if (Minecraft.theMinecraft.thePlayer.hurtResistantTime < 10) {
            whiteOutlinedHearts = false;
        }
        float healthPercent = health / 0.2f;
        int y = (int) bar.getScreenY();
        float healthPercentPerIcon = 100f / bar.getMaxNumHearts();
        if (bar.isVisible() && bar.getMaxNumHearts() > 0) {
            for (int icon = 0; icon < bar.getMaxNumHearts(); ++icon) {
                boolean full = (icon + 1) * healthPercentPerIcon <= healthPercent;
                boolean half = (icon + 1) * healthPercentPerIcon < healthPercent + healthPercentPerIcon;
                int x = (int) bar.getScreenX() + icon * bar.getIconOffset();

                int iconType = 16;

                if (Minecraft.theMinecraft.thePlayer.isPotionActive(Potion.poison)) {
                    iconType += 36;
                }

                byte hardcore = 0;
                if (Minecraft.theMinecraft.theWorld.getWorldInfo().isHardcoreModeEnabled()) {
                    hardcore = 5 * 9;
                }

                int oldY = y;
                if (healthPercent <= bar.getDangerPercent()) {
                    y += GuiIngame.rand.nextInt(2);
                }

                RenderUtil.drawTexturedModalRectangle(x, y, 16 + (whiteOutlinedHearts ? 1 : 0) * 9, hardcore, 9, 9,
                        0f);
                if (whiteOutlinedHearts) {
                    if (full) {
                        RenderUtil.drawTexturedModalRectangle(x, y, iconType + 54, hardcore, 9, 9, 0f);
                    } else if (half) {
                        RenderUtil.drawTexturedModalRectangle(x, y, iconType + 63, hardcore, 9, 9, 0f);
                    }
                }

                if (full) {
                    RenderUtil.drawTexturedModalRectangle(x, y, iconType + 36, hardcore, 9, 9, 0f);
                } else if (half) {
                    RenderUtil.drawTexturedModalRectangle(x, y, iconType + 45, hardcore, 9, 9, 0f);
                }

                y = oldY;
            }
        }
    }

    public void render(GenericEntityWidget entityWidget) {
        Entity entity = SpoutClient.getInstance().getEntityFromId(entityWidget.getEntityId());
        if (entity != null) {
            GL11.glEnable(32826);
            GL11.glEnable(GL11.GL_COLOR_MATERIAL);
            GL11.glPushMatrix();
            GL11.glTranslated(entityWidget.getX() + entityWidget.getWidth() / 2,
                    entityWidget.getY() + entityWidget.getHeight(), 50F);
            RenderHelper.enableStandardItemLighting();
            float f1 = (float) Math.min(entityWidget.getWidth(), entityWidget.getHeight());
            GL11.glScalef(-f1, f1, f1);
            GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
            GL11.glRotatef(entity.prevRotationYaw, 0, 1.0F, 0);
            RenderHelper.enableStandardItemLighting();
            RenderManager.instance.playerViewY = 180F;
            RenderManager.instance.renderEntityWithPosYaw(entity, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F);
            GL11.glPopMatrix();
            RenderHelper.disableStandardItemLighting();
            GL11.glDisable(32826);
        }
    }

    public MinecraftFont getMinecraftFont() {
        return font;
    }

    public MinecraftTessellator getTessellator() {
        return tessellator;
    }

    public void render(HungerBar bar) {
        FoodStats foodStats = Minecraft.theMinecraft.thePlayer.getFoodStats();

        int foodLevel = foodStats.getFoodLevel();
        float foodPercent = foodLevel / 0.2f;
        float foodPercentPerIcon = 100f / bar.getNumOfIcons();

        if (bar.isVisible() && bar.getNumOfIcons() > 0) {
            int foodIcon = 16;
            byte foodOutline = 0;

            if (Minecraft.theMinecraft.thePlayer.isPotionActive(Potion.hunger)) {
                foodIcon += 36;
                foodOutline = 13;
            }

            for (int icon = 0; icon < bar.getNumOfIcons(); icon++) {
                int x = (int) bar.getScreenX() - icon * bar.getIconOffset();
                int y = (int) bar.getScreenY();

                if (Minecraft.theMinecraft.thePlayer.getFoodStats().getSaturationLevel() <= 0.0F
                        && bar.getUpdateCounter() % (foodLevel * 3 + 1) == 0) {
                    y += GuiIngame.rand.nextInt(3) - 1;
                }

                RenderUtil.drawTexturedModalRectangle(x, y, 16 + foodOutline * 9, 27, 9, 9, 0f);

                if ((icon + 1) * foodPercentPerIcon <= foodPercent) {
                    RenderUtil.drawTexturedModalRectangle(x, y, foodIcon + 36, 27, 9, 9, 0f);
                } else if ((icon + 1) * foodPercentPerIcon < foodPercent + foodPercentPerIcon) {
                    RenderUtil.drawTexturedModalRectangle(x, y, foodIcon + 45, 27, 9, 9, 0f);
                }
            }
        }

    }

    public void render(ExpBar bar) {
        if (bar.isVisible()) {
            int expCap = Minecraft.theMinecraft.thePlayer.xpBarCap();
            if (expCap > 0) {
                int x = (int) bar.getScreenX();
                int y = (int) bar.getScreenY();
                int exp = (int) (Minecraft.theMinecraft.thePlayer.experience * 183.0F);
                RenderUtil.drawTexturedModalRectangle(x, y, 0, 64, 182, 5, 0f);
                if (exp > 0) {
                    RenderUtil.drawTexturedModalRectangle(x, y, 0, 69, exp, 5, 0f);
                }
            }

            if (Minecraft.theMinecraft.playerController.func_78763_f()
                    && Minecraft.theMinecraft.thePlayer.experienceLevel > 0) {
                int color = 8453920;
                String level = "" + Minecraft.theMinecraft.thePlayer.experienceLevel;
                FontRenderer font = SpoutClient.getHandle().fontRenderer;
                int x = (int) (bar.getScreenX() + (183 / 2) - (font.getStringWidth(level) / 2));
                int y = (int) bar.getScreenY() - 6;
                font.drawString(level, x + 1, y, 0);
                font.drawString(level, x - 1, y, 0);
                font.drawString(level, x, y + 1, 0);
                font.drawString(level, x, y - 1, 0);
                font.drawString(level, x, y, color);
            }
        }
    }

    public void render(GenericCheckBox checkBox) {
        if (checkBox.isVisible()) {
            GL11.glAlphaFunc(GL11.GL_GREATER, 0.01F);
            Texture checkBoxCross = CustomTextureManager.getTextureFromJar("/res/ui/box_check.png");
            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
            GL11.glTranslatef((float) Math.floor(checkBox.getScreenX()), (float) Math.floor(checkBox.getScreenY()),
                    0);
            renderBaseBox(checkBox, true);
            FontRenderer font = SpoutClient.getHandle().fontRenderer;
            Color color = getColor(checkBox);
            if (!checkBox.isChecked()) {
                color.setAlpha(0.2F);
            } else {
                color.setRed(0).setGreen(1).setBlue(0);
            }
            drawTexture(checkBoxCross, 20, 20, color, true);
            font.drawString(checkBox.getText(), 22, 7, getColor(checkBox).toInt());
        }
    }

    public void render(GenericRadioButton radioButton) {
        if (radioButton.isVisible()) {
            Texture radio = CustomTextureManager.getTextureFromJar("/res/ui/box_radio.png");
            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
            GL11.glTranslatef((float) Math.floor(radioButton.getScreenX()),
                    (float) Math.floor(radioButton.getScreenY()), 0);
            renderBaseBox(radioButton, true);
            FontRenderer font = SpoutClient.getHandle().fontRenderer;
            Color color = getColor(radioButton);
            if (!radioButton.isSelected()) {
                color.setAlpha(0.2F);
            }
            drawTexture(radio, 20, 20, color, true);
            font.drawString(radioButton.getText(), 22, 7, getColor(radioButton).toInt());
        }
    }

    public void renderBaseBox(Control box) {
        renderBaseBox(box, false);
    }

    public void renderBaseBox(Control box, boolean blend) {
        Texture usedTexture = null;
        if (box.isEnabled() && isHovering(box)) {
            usedTexture = CustomTextureManager.getTextureFromJar("/res/ui/box_hover.png");
        } else if (box.isEnabled()) {
            usedTexture = CustomTextureManager.getTextureFromJar("/res/ui/box_normal.png");
        } else {
            usedTexture = CustomTextureManager.getTextureFromJar("/res/ui/box_disabled.png");
        }
        drawTexture(usedTexture, 20, 20, blend);
    }

    private static final Color white = new Color(1.0F, 1.0F, 1.0F);

    public void drawTexture(Texture textureBinding, int width, int height) {
        drawTexture(textureBinding, width, height, white, false, -1, -1, false);
    }

    public void drawTexture(Texture textureBinding, int width, int height, int left, int top) {
        drawTexture(textureBinding, width, height, white, false, left, top, false);
    }

    public void drawTexture(Texture textureBinding, int width, int height, boolean blend) {
        drawTexture(textureBinding, width, height, white, blend, -1, -1, false);
    }

    public void drawTexture(Texture textureBinding, int width, int height, boolean blend, int left, int top) {
        drawTexture(textureBinding, width, height, white, blend, left, top, false);
    }

    public void drawTexture(Texture textureBinding, int width, int height, boolean blend, int left, int top,
            boolean mipmap) {
        drawTexture(textureBinding, width, height, white, blend, left, top, mipmap);
    }

    public void drawTexture(Texture textureBinding, int width, int height, Color color) {
        drawTexture(textureBinding, width, height, color, false, -1, -1, false);
    }

    public void drawTexture(Texture textureBinding, int width, int height, Color color, int left, int top) {
        drawTexture(textureBinding, width, height, color, false, left, top, false);
    }

    public void drawTexture(Texture textureBinding, int width, int height, Color color, boolean blend) {
        drawTexture(textureBinding, width, height, color, blend, -1, -1, false);
    }

    public void drawTexture(Texture textureBinding, int width, int height, Color color, boolean blend, int left,
            int top, boolean mipmap) {
        drawTexture(textureBinding, width, height, color, blend, left, top, mipmap, GL11.GL_NEAREST);
    }

    public void drawTexture(Texture textureBinding, int width, int height, Color color, boolean blend, int left,
            int top, boolean mipmap, int filter) {
        if (textureBinding == null) {
            return;
        }
        GL11.glPushMatrix();
        GL11.glDisable(GL11.GL_DEPTH_TEST);
        boolean wasBlend = GL11.glGetBoolean(GL11.GL_BLEND);
        if (blend) {
            GL11.glEnable(GL11.GL_BLEND);
            GL11.glBlendFunc(770, 771);
        }
        GL11.glDepthMask(false);
        bindColor(color);
        SpoutClient.getHandle().renderEngine.bindTexture(textureBinding.getTextureID());
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, filter);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, filter);
        if (mipmap) {
            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST_MIPMAP_LINEAR);
            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LOD, 8);

            ContextCapabilities capabilities = GLContext.getCapabilities();
            if (capabilities.OpenGL30) {
                GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
            } else if (capabilities.GL_EXT_framebuffer_object) {
                EXTFramebufferObject.glGenerateMipmapEXT(GL11.GL_TEXTURE_2D);
            } else if (capabilities.OpenGL14) {
                GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL14.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
            }
        }

        double tLeft = 0, tTop = 0, rWidth = textureBinding.getWidth(), rHeight = textureBinding.getHeight(),
                tWidth = rWidth, tHeight = rHeight;
        if (top >= 0 && left >= 0) {
            tWidth = Math.min(tWidth,
                    (width / (double) textureBinding.getImageWidth()) * textureBinding.getWidth());
            tHeight = Math.min(tHeight,
                    (height / (double) textureBinding.getImageHeight()) * textureBinding.getHeight());
            tLeft = Math.min(
                    Math.max(0, (left / (double) textureBinding.getImageWidth())) * textureBinding.getWidth(),
                    rWidth);
            tTop = Math.min(
                    Math.max(0, (top / (double) textureBinding.getImageHeight()) * textureBinding.getHeight()),
                    rHeight);
        }
        tHeight = -tHeight;
        tTop = rHeight - tTop;

        Tessellator tessellator = Tessellator.instance;
        tessellator.startDrawingQuads();
        tessellator.addVertexWithUV(0.0D, height, -90, tLeft, tTop + tHeight); // draw corners
        tessellator.addVertexWithUV(width, height, -90, tLeft + tWidth, tTop + tHeight);
        tessellator.addVertexWithUV(width, 0.0D, -90, tLeft + tWidth, tTop);
        tessellator.addVertexWithUV(0.0D, 0.0D, -90, tLeft, tTop);

        tessellator.draw();
        GL11.glDepthMask(true);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
        GL11.glPopMatrix();
        if (blend && !wasBlend) {
            GL11.glDisable(GL11.GL_BLEND);
        }
    }

    public Color getColor(Button c) {
        if (c.isEnabled() && isHovering(c)) {
            return c.getHoverColor().clone();
        } else if (c.isEnabled()) {
            return c.getColor().clone();
        } else {
            return c.getDisabledColor().clone();
        }
    }

    protected void bindColor(Color c) {
        GL11.glColor4f(c.getRedF(), c.getGreenF(), c.getBlueF(), c.getAlphaF());
    }

    public void render(GenericListWidgetItem lwi, int x, int y, int width, int height) {
        if (lwi.getIconUrl() != null && !lwi.getIconUrl().isEmpty()) {
            Texture t = CustomTextureManager.getTextureFromUrl(lwi.getIconUrl());
            if (t != null) {
                int maxHeight = height - 4;
                float f = (float) t.getImageWidth() / (float) t.getImageHeight();
                int w = (int) (maxHeight * f);
                GL11.glTranslated(6, (y + 2), 0);
                drawTexture(t, maxHeight, w);
                GL11.glTranslated(-6, (-(y + 2)), 0);

                x += 2 + w;
            }
        }
        FontRenderer font = SpoutClient.getHandle().fontRenderer;
        font.drawString(lwi.getTitle(), x + 2, y + 2, new Color(1.0F, 1.0F, 1.0F).toInt());
        font.drawString(lwi.getText(), x + 2, y + 2 + 8, new Color(0.8F, 0.8F, 0.8F).toInt());
    }

    private void scissorWidget(Widget widget) {
        double x = widget.getActualX() + widget.getWidth(), y = widget.getActualY() + widget.getHeight(),
                width = widget.getWidth(), height = widget.getHeight();
        double screenHeight;
        screenHeight = getScreenHeight();
        int windowWidth = SpoutClient.getHandle().displayWidth,
                windowHeight = SpoutClient.getHandle().displayHeight;
        ScaledResolution scale = new ScaledResolution(SpoutClient.getHandle().gameSettings, windowWidth,
                windowHeight);
        double scaleFactor = scale.getScaleFactor();
        height = height * scaleFactor;
        width = width * scaleFactor;
        x *= scaleFactor;
        y *= scaleFactor;
        screenHeight *= scaleFactor;
        x = x - width;
        y = screenHeight - y;
        GL11.glScissor((int) x, (int) y, (int) width, (int) height);
    }

    public void render(GenericScrollable gs) {
        int scrollTop = gs.getScrollPosition(Orientation.VERTICAL);
        int scrollLeft = gs.getScrollPosition(Orientation.HORIZONTAL);
        GL11.glTranslated(gs.getScreenX(), gs.getScreenY(), 0);
        GL11.glEnable(GL11.GL_SCISSOR_TEST);
        scissorWidget(gs);
        RenderUtil.drawRectangle(0, 0, (int) gs.getWidth(), (int) gs.getHeight(), gs.getBackgroundColor().toInt());
        GL11.glPushMatrix();
        GL11.glTranslated(-scrollLeft, -scrollTop, 0);
        GL11.glPushMatrix();

        // Render scrollarea contents
        gs.renderContents();

        GL11.glPopMatrix();
        GL11.glPopMatrix();
        GL11.glDisable(GL11.GL_SCISSOR_TEST);
        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);

        GL11.glDisable(2896 /*GL_LIGHTING*/);
        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
        // Draw scrollbars
        if (gs.needsScrollBar(Orientation.HORIZONTAL)) {
            SpoutClient.getHandle().renderEngine.bindTexture("/gui/allitems.png");
            double scrollX = 0;
            double p = (double) scrollLeft / (double) gs.getMaximumScrollPosition(Orientation.HORIZONTAL);
            scrollX = 3 + p * (gs.getViewportSize(Orientation.HORIZONTAL) - 16.0 - 6);
            RenderUtil.drawGradientRectangle(0, (int) gs.getHeight() - 16, (int) gs.getWidth(),
                    (int) gs.getHeight(), scrollBarColor.toInt(), scrollBarColor2.toInt());
            GL11.glColor3f(1.0f, 1.0f, 1.0f);
            RenderUtil.drawTexturedModalRectangle((int) scrollX, (int) (gs.getHeight() - 16), 232, 0, 12, 15, 0f);
        }
        if (gs.needsScrollBar(Orientation.VERTICAL)) {
            SpoutClient.getHandle().renderEngine.bindTexture("/gui/allitems.png");
            double scrollY = 0;
            double p = (double) scrollTop / (double) gs.getMaximumScrollPosition(Orientation.VERTICAL);
            scrollY = 3 + p * (gs.getViewportSize(Orientation.VERTICAL) - 16.0 - 6);
            RenderUtil.drawGradientRectangle((int) gs.getWidth() - 16, 0, (int) gs.getWidth(), (int) gs.getHeight(),
                    scrollBarColor.toInt(), scrollBarColor2.toInt());
            GL11.glColor3f(1.0f, 1.0f, 1.0f);
            RenderUtil.drawTexturedModalRectangle((int) (gs.getWidth() - 16), (int) scrollY, 232, 0, 12, 15, 0f);
            RenderUtil.drawGradientRectangle(0, -1, (int) gs.getWidth(), 5,
                    new Color(0.0F, 0.0F, 0.0F, 1.0F).toInt(), new Color(0.0F, 0.0F, 0.0F, 0.0F).toInt());
            RenderUtil.drawGradientRectangle(0, (int) gs.getHeight() - 5, (int) gs.getWidth() + 1,
                    (int) gs.getHeight(), new Color(0.0F, 0.0F, 0.0F, 0.0F).toInt(),
                    new Color(0.0F, 0.0F, 0.0F, 1.0F).toInt());
        }
    }

    public void renderContents(GenericListWidget lw) {
        int scrollTop = lw.getScrollPosition(Orientation.VERTICAL);
        int scrollBottom = (int) (scrollTop + lw.getHeight() + 5);
        GL11.glTranslated(0, 5, 0);
        int currentHeight = 0;
        for (ListWidgetItem item : lw.getItems()) {
            // Only render visible items
            if (currentHeight >= scrollTop - item.getHeight() && currentHeight <= scrollBottom) {
                // Draw selection border
                if (lw.isSelected(item)) {
                    RenderUtil.drawRectangle(4, currentHeight - 1, lw.getViewportSize(Orientation.HORIZONTAL) - 3,
                            currentHeight - 1 + item.getHeight() + 2, new Color(1.0F, 1.0F, 1.0F).toInt());
                    RenderUtil.drawRectangle(5, currentHeight, lw.getViewportSize(Orientation.HORIZONTAL) - 4,
                            currentHeight + item.getHeight(), new Color(0.0F, 0.0F, 0.0F).toInt());
                }

                // Render actual item
                GL11.glPushMatrix();
                item.render(5, currentHeight, lw.getViewportSize(Orientation.HORIZONTAL) - 9, item.getHeight());
                GL11.glPopMatrix();
            }

            currentHeight += item.getHeight();
        }
    }

    public void renderContents(GenericScrollArea genericScrollArea) {
        for (RenderPriority priority : RenderPriority.values()) {
            for (Widget w : genericScrollArea.getAttachedWidgets()) {
                if (w.getPriority() == priority) {
                    GL11.glPushMatrix();
                    w.render();
                    GL11.glPopMatrix();
                }
            }
        }
    }

    public String getFittingText(String text, int width) {
        if (width <= 1) {
            return text;
        }
        int hash = (new HashCodeBuilder()).append(text).append(width).toHashCode();
        if (optimalWidth.contains(hash)) {
            return optimalWidth.get(hash);
        }
        FontRenderer font = SpoutClient.getHandle().fontRenderer;
        String t = new String(text);
        int remove = 0;
        while (font.getStringWidth(t) > width) {
            remove++;
            t = text.substring(0, Math.max(0, text.length() - 1 - remove)) + "...";
        }
        optimalWidth.put(hash, t);
        return t;
    }

    public void render(GenericComboBox comboBox) {
        if (comboBox.isVisible()) {
            comboBox.setInnerWidth((int) comboBox.getWidth() - 16);
            render((GenericButton) comboBox);
            Texture text;
            if (comboBox.isOpen()) {
                text = CustomTextureManager.getTextureFromJar("/res/ui/box_ascending.png");
            } else {
                text = CustomTextureManager.getTextureFromJar("/res/ui/box_descending.png");
            }
            GL11.glTranslated(comboBox.getWidth() - 16, 3, 0);
            RenderUtil.drawRectangle(0, -3, 16, (int) comboBox.getHeight(), 0x33000000);
            drawTexture(text, 16, 16, getColor(comboBox), true);
        }
    }

    public void render(GenericSlot genericSlot) {
        if (!genericSlot.isVisible()) {
            return;
        }
        ItemStack item = genericSlot.getItem();

        GL11.glDepthFunc(515);
        RenderHelper.enableGUIStandardItemLighting();
        GL11.glDisable(GL11.GL_DEPTH_TEST);
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glEnable(GL11.GL_COLOR_MATERIAL);
        GL11.glPushMatrix();
        GL11.glTranslatef((float) genericSlot.getScreenX(), (float) genericSlot.getScreenY(), 0);
        if (genericSlot.getAnchor() == WidgetAnchor.SCALE) {
            GL11.glScalef((float) (genericSlot.getScreen().getWidth() / 427f),
                    (float) (genericSlot.getScreen().getHeight() / 240f), 1);
        }
        GL11.glScaled(genericSlot.getWidth() / 16D, genericSlot.getHeight() / 16D, 1);

        if (item.getTypeId() != 0) {
            GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
            int id = item.getTypeId();
            int data = item.getDurability();
            if (MaterialData.getCustomItem(id) != null) {
                int temp = id;
                id = 318;
                data = temp;
            }
            renderer.renderItemIntoGUI(SpoutClient.getHandle().fontRenderer, SpoutClient.getHandle().renderEngine,
                    new net.minecraft.src.ItemStack(id, item.getAmount(), data), 0, 0);
            renderer.renderItemOverlayIntoGUI(SpoutClient.getHandle().fontRenderer,
                    SpoutClient.getHandle().renderEngine,
                    new net.minecraft.src.ItemStack(id, item.getAmount(), data), 0, 0);
        }
        GL11.glEnable(GL11.GL_LIGHTING);
        RenderHelper.disableStandardItemLighting();
        if (isHovering(genericSlot))
            RenderUtil.drawRectangle(0, 0, 16, 16, 0x88ffffff);
        GL11.glPopMatrix();
    }

    public boolean bindTexture(String path) {
        Texture tex = CustomTextureManager.getTextureFromPath(path);
        if (tex != null) {
            tex.bind();
        }
        return tex != null;
    }

    public boolean bindTexture(String addon, String path) {
        Texture tex = CustomTextureManager.getTextureFromUrl(addon, path);
        if (tex != null) {
            tex.bind();
        }
        return tex != null;
    }
}