diff --git a/src/main/java/electroblob/wizardry/client/DrawingUtils.java b/src/main/java/electroblob/wizardry/client/DrawingUtils.java new file mode 100644 index 00000000..382fba75 --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/DrawingUtils.java @@ -0,0 +1,228 @@ +package electroblob.wizardry.client; + +import org.lwjgl.opengl.GL11; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.RenderItem; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +/** + * Utility class containing some useful static methods for drawing GUIs. Previously these were spread across the main + * {@code WizardryUtilities} class and various individual GUI classes. + * + * @author Electroblob + * @since Wizardry 4.2 + * @see MixedFontRenderer + */ +@SideOnly(Side.CLIENT) +public final class DrawingUtils { + + /** + * The integer colour for black passed into the font renderer methods. This used to be 0 but that's now white for + * some reason, so I've made a it a constant in case it changes again. + */ + // I think this is actually ever-so-slightly lighter than pure black, but the difference is unnoticeable. + public static final int BLACK = 1; + + /** + * Shorthand for {@link DrawingUtils#drawTexturedRect(int, int, int, int, int, int, int, int)} which draws the + * entire texture (u and v are set to 0 and textureWidth and textureHeight are the same as width and height). + */ + public static void drawTexturedRect(int x, int y, int width, int height){ + drawTexturedRect(x, y, 0, 0, width, height, width, height); + } + + /** + * Draws a textured rectangle, taking the size of the image and the bit needed into + * account, unlike {@link net.minecraft.client.gui.Gui#drawTexturedModalRect(int, int, int, int, int, int) + * Gui.drawTexturedModalRect(int, int, int, int, int, int)}, which is harcoded for only 256x256 textures. Also handy + * for custom potion icons. + * + * @param x The x position of the rectangle + * @param y The y position of the rectangle + * @param u The x position of the top left corner of the section of the image wanted + * @param v The y position of the top left corner of the section of the image wanted + * @param width The width of the section + * @param height The height of the section + * @param textureWidth The width of the actual image. + * @param textureHeight The height of the actual image. + */ + public static void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight){ + DrawingUtils.drawTexturedFlippedRect(x, y, u, v, width, height, textureWidth, textureHeight, false, false); + } + + /** + * Draws a textured rectangle, taking the size of the image and the bit needed into + * account, unlike {@link net.minecraft.client.gui.Gui#drawTexturedModalRect(int, int, int, int, int, int) + * Gui.drawTexturedModalRect(int, int, int, int, int, int)}, which is harcoded for only 256x256 textures. Also handy + * for custom potion icons. This version allows the texture to additionally be flipped in x and/or y. + * + * @param x The x position of the rectangle + * @param y The y position of the rectangle + * @param u The x position of the top left corner of the section of the image wanted + * @param v The y position of the top left corner of the section of the image wanted + * @param width The width of the section + * @param height The height of the section + * @param textureWidth The width of the actual image. + * @param textureHeight The height of the actual image. + * @param flipX Whether to flip the texture in the x direction. + * @param flipY Whether to flip the texture in the y direction. + */ + public static void drawTexturedFlippedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight, boolean flipX, boolean flipY){ + + float f = 1F / (float)textureWidth; + float f1 = 1F / (float)textureHeight; + + int u1 = flipX ? u + width : u; + int u2 = flipX ? u : u + width; + int v1 = flipY ? v + height : v; + int v2 = flipY ? v : v + height; + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + + buffer.begin(org.lwjgl.opengl.GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); + + buffer.pos((double)(x), (double)(y + height), 0).tex((double)((float)(u1) * f), (double)((float)(v2) * f1)).endVertex(); + buffer.pos((double)(x + width), (double)(y + height), 0).tex((double)((float)(u2) * f), (double)((float)(v2) * f1)).endVertex(); + buffer.pos((double)(x + width), (double)(y), 0).tex((double)((float)(u2) * f), (double)((float)(v1) * f1)).endVertex(); + buffer.pos((double)(x), (double)(y), 0).tex((double)((float)(u1) * f), (double)((float)(v1) * f1)).endVertex(); + + tessellator.draw(); + } + + /** + * Draws a textured rectangle, stretching the section of the image to fit the size given. + * + * @param x The x position of the rectangle + * @param y The y position of the rectangle + * @param u The x position of the top left corner of the section of the image wanted, expressed as a fraction of the + * image width + * @param v The y position of the top left corner of the section of the image wanted, expressed as a fraction of the + * image width + * @param finalWidth The width as rendered + * @param finalHeight The height as rendered + * @param width The width of the section, expressed as a fraction of the image width + * @param height The height of the section, expressed as a fraction of the image width + */ + public static void drawTexturedStretchedRect(int x, int y, int u, int v, int finalWidth, int finalHeight, int width, + int height){ + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + + buffer.pos((x), y + finalHeight, 0).tex(u, v + height).endVertex(); + buffer.pos(x + finalWidth, y + finalHeight, 0).tex(u + width, v + height).endVertex(); + buffer.pos(x + finalWidth, (y), 0).tex(u + width, v).endVertex(); + buffer.pos((x), (y), 0).tex(u, v).endVertex(); + + tessellator.draw(); + } + + /** + * Makes the given opaque colour translucent with the given opacity. + * @param colour An integer colour code, should be a 6-digit hexadecimal (i.e. opaque). + * @param opacity The opacity to apply to the given colour, as a fraction between 0 and 1. + * @return The resulting integer colour code, which will be an 8-digit hexadecimal. + */ + public static int makeTranslucent(int colour, float opacity){ + return colour + ((int)(0xff * opacity * 0x01000000)); + } + + /** + * Draws the given string at the given position, scaling it if it does not fit within the given width. + * @param font A {@code FontRenderer} object. + * @param text The text to display. + * @param x The x position of the top-left corner of the text. + * @param y The y position of the top-left corner of the text. + * @param scale The scale that the text should normally be if it does not exceed the maximum width. + * @param colour The colour to render the text in, supports translucency. + * @param width The maximum width of the text. This is not scaled; you should pass in the width of the actual + * area of the screen in which the text needs to fit, regardless of the scale parameter. + * @param centre Whether to adjust the y position such that the centre of the text lines up with where its centre + * would be if it was not scaled (automatically or manually). + * @param alignR True to right-align the text, false for normal left alignment. + */ + public static void drawScaledStringToWidth(FontRenderer font, String text, float x, float y, float scale, int colour, float width, boolean centre, boolean alignR){ + + float textWidth = font.getStringWidth(text) * scale; + float textHeight = font.FONT_HEIGHT * scale; + + if(textWidth > width){ + scale *= width/textWidth; + }else if(alignR){ // Alignment makes no difference if the string fills the entire width + x += width - textWidth; + } + + if(centre) y += (font.FONT_HEIGHT - textHeight)/2; + + DrawingUtils.drawScaledTranslucentString(font, text, x, y, scale, colour); + } + + /** Draws the given string at the given position, scaling the text by the specified factor. Also enables blending to + * render text in semitransparent colours (e.g. 0x88ffffff). */ + public static void drawScaledTranslucentString(FontRenderer font, String text, float x, float y, float scale, int colour){ + + GlStateManager.pushMatrix(); + GlStateManager.enableBlend(); + GlStateManager.scale(scale, scale, scale); + // Because we scaled the entire rendering space, the coordinates have to be scaled inversely + x /= scale; + y /= scale; + font.drawStringWithShadow(text, x, y, colour); + GlStateManager.disableBlend(); + GlStateManager.popMatrix(); + } + + /** + * Draws an itemstack and (optionally) its tooltip, directly. Mainly intended for use outside of GUI classes, since + * most of the GL state changes done in this method (which are the main reason it exists at all) are already done + * when drawing a GUI. + * + * @param gui An instance of a GUI class. + * @param stack The itemstack to draw. + * @param x The x position of the left-hand edge of the itemstack. + * @param y The y position of the top edge of the itemstack. + * @param mouseX The x position of the mouse, used for tooltip positioning. + * @param mouseY The y position of the mouse, used for tooltip positioning. + * @param tooltip Whether to draw the tooltip. + */ + public static void drawItemAndTooltip(GuiContainer gui, ItemStack stack, int x, int y, int mouseX, int mouseY, boolean tooltip){ + + RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); + GlStateManager.pushMatrix(); + RenderHelper.enableGUIStandardItemLighting(); + GlStateManager.disableLighting(); + GlStateManager.enableRescaleNormal(); + GlStateManager.enableColorMaterial(); + GlStateManager.enableLighting(); + renderItem.zLevel = 100.0F; + + if(!stack.isEmpty()){ + renderItem.renderItemAndEffectIntoGUI(stack, x, y); + renderItem.renderItemOverlays(Minecraft.getMinecraft().fontRenderer, stack, x, y); + + if(tooltip){ + gui.drawHoveringText(gui.getItemToolTip(stack), mouseX + gui.getXSize()/2 - gui.width/2, + mouseY + gui.getYSize()/2 - gui.height/2); + } + } + + GlStateManager.popMatrix(); + GlStateManager.enableLighting(); + GlStateManager.enableDepth(); + RenderHelper.enableStandardItemLighting(); + } + +} diff --git a/src/main/java/electroblob/wizardry/client/gui/GuiArcaneWorkbench.java b/src/main/java/electroblob/wizardry/client/gui/GuiArcaneWorkbench.java index a560abd5..349ffa36 100644 --- a/src/main/java/electroblob/wizardry/client/gui/GuiArcaneWorkbench.java +++ b/src/main/java/electroblob/wizardry/client/gui/GuiArcaneWorkbench.java @@ -84,7 +84,7 @@ public class GuiArcaneWorkbench extends GuiContainer { Minecraft.getMinecraft().renderEngine.bindTexture(texture); // Main inventory - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSizeNoTip, ySize); + DrawingUtils.drawTexturedRect(guiLeft, guiTop, 0, 0, MAIN_GUI_WIDTH, ySize, TEXTURE_WIDTH, TEXTURE_HEIGHT); // Changing slots for(int i = 0; i < ContainerArcaneWorkbench.CRYSTAL_SLOT; i++){ @@ -122,7 +122,7 @@ public class GuiArcaneWorkbench extends GuiContainer { .bindTexture(discovered ? spell.element.getIcon() : Element.MAGIC.getIcon()); // Renders the little element icon - WizardryUtilities.drawTexturedRect(guiLeft + xSizeNoTip + 5, guiTop + 34 + 10 * i++, 8, 8); + DrawingUtils.drawTexturedRect(guiLeft + MAIN_GUI_WIDTH + 5, guiTop + 34 + 10 * i++, 8, 8); } int x = 0; diff --git a/src/main/java/electroblob/wizardry/client/gui/GuiSpellBook.java b/src/main/java/electroblob/wizardry/client/gui/GuiSpellBook.java index 2d78b219..fccc7c25 100644 --- a/src/main/java/electroblob/wizardry/client/gui/GuiSpellBook.java +++ b/src/main/java/electroblob/wizardry/client/gui/GuiSpellBook.java @@ -46,10 +46,10 @@ public class GuiSpellBook extends GuiScreen { // Draws spell illustration on opposite page, underneath the book so it shows through the hole. Minecraft.getMinecraft().renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon()); - WizardryUtilities.drawTexturedRect(xPos + 145, yPos + 20, 0, 0, 128, 128, 128, 128); - Minecraft.getMinecraft().renderEngine.bindTexture(texture); - WizardryUtilities.drawTexturedRect(xPos, yPos, 0, 0, xSize, ySize, xSize, 256); + DrawingUtils.drawTexturedRect(xPos + 146, yPos + 20, 0, 0, 128, 128, 128, 128); + + DrawingUtils.drawTexturedRect(xPos, yPos, 0, 0, xSize, ySize, xSize, 256); super.drawScreen(par1, par2, par3); diff --git a/src/main/java/electroblob/wizardry/client/gui/GuiSpellDisplay.java b/src/main/java/electroblob/wizardry/client/gui/GuiSpellDisplay.java index fff4d965..6d2a0c6d 100644 --- a/src/main/java/electroblob/wizardry/client/gui/GuiSpellDisplay.java +++ b/src/main/java/electroblob/wizardry/client/gui/GuiSpellDisplay.java @@ -19,6 +19,7 @@ import electroblob.wizardry.SpellGlyphData; import electroblob.wizardry.WizardData; import electroblob.wizardry.Wizardry; import electroblob.wizardry.client.ClientProxy; +import electroblob.wizardry.client.DrawingUtils; import electroblob.wizardry.client.MixedFontRenderer; import electroblob.wizardry.constants.Constants; import electroblob.wizardry.item.ItemWand; @@ -27,7 +28,6 @@ import electroblob.wizardry.registry.WizardryItems; import electroblob.wizardry.registry.WizardryPotions; import electroblob.wizardry.spell.Spell; import electroblob.wizardry.util.WandHelper; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.renderer.GlStateManager; @@ -219,51 +219,6 @@ public class GuiSpellDisplay { return name; } - /** - * Draws the given string at the given position, scaling it if it does not fit within the given width. - * @param font A {@code FontRenderer} object. - * @param text The text to display. - * @param x The x position of the top-left corner of the text. - * @param y The y position of the top-left corner of the text. - * @param scale The scale that the text should be if it does not exceed the maximum width. - * @param colour The colour to render the text in, supports translucency. - * @param width The maximum width of the text. This is not scaled; you should pass in the width of the actual - * area of the screen in which the text needs to fit. - * @param centre Whether to adjust the y position such that the centre of the text lines up with where its centre - * would be if it was not scaled (automatically or manually). - * @param alignR True to right-align the text, false for normal left alignment. - */ - private static void drawScaledStringToWidth(FontRenderer font, String text, float x, float y, float scale, int colour, float width, boolean centre, boolean alignR){ - - float textWidth = font.getStringWidth(text) * scale; - float textHeight = font.FONT_HEIGHT * scale; - - if(textWidth > width){ - scale *= width/textWidth; - }else if(alignR){ // Alignment makes no difference if the string fills the entire width - x += width - textWidth; - } - - if(centre) y += (font.FONT_HEIGHT - textHeight)/2; - - drawScaledTranslucentString(font, text, x, y, scale, colour); - } - - /** Draws the given string at the given position, scaling the text by the specified factor. Also enables blending to - * render text in semitransparent colours (e.g. 0x88ffffff). */ - private static void drawScaledTranslucentString(FontRenderer font, String text, float x, float y, float scale, int colour){ - - GlStateManager.pushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.scale(scale, scale, scale); - // Because we scaled it, the coordinates have to be scaled inversely - x /= scale; - y /= scale; - font.drawStringWithShadow(text, x, y, colour); - GlStateManager.disableBlend(); - GlStateManager.popMatrix(); - } - @SubscribeEvent public static void onLivingUpdateEvent(LivingUpdateEvent event){ if(event.getEntity() == Minecraft.getMinecraft().player){ // Makes sure this only gets called once each tick. @@ -501,7 +456,7 @@ public class GuiSpellDisplay { // y is upside-down so this is the other way round int y1 = flipY && mirrorY ? y + spellIconInsetY : y - spellIconInsetY - SPELL_ICON_SIZE; - WizardryUtilities.drawTexturedRect(x1, y1, 0, 0, SPELL_ICON_SIZE, SPELL_ICON_SIZE, SPELL_ICON_SIZE, SPELL_ICON_SIZE); + DrawingUtils.drawTexturedRect(x1, y1, 0, 0, SPELL_ICON_SIZE, SPELL_ICON_SIZE, SPELL_ICON_SIZE, SPELL_ICON_SIZE); // Background of spell hud mc.renderEngine.bindTexture(texture); @@ -510,7 +465,7 @@ public class GuiSpellDisplay { y1 = flipY && mirrorY ? y : y - height; // The 128 here is a uv value, not a dimension, and hence is left as a hardcoded number. // TODO: Since the HUD is wider than it is tall, perhaps the creative mode texture should be in the bottom half instead of the right half? - WizardryUtilities.drawTexturedFlippedRect(x1, y1, creativeMode ? 128 : 0, 0, width, height, 256, 256, flipX && mirrorX, flipY && mirrorY); + DrawingUtils.drawTexturedFlippedRect(x1, y1, creativeMode ? 128 : 0, 0, width, height, 256, 256, flipX && mirrorX, flipY && mirrorY); // Cooldown bar if(!creativeMode && cooldownBarProgress > 0 && (showCooldownWhenFull || cooldownBarProgress < 1)){ @@ -523,7 +478,7 @@ public class GuiSpellDisplay { int u = cooldownBarX; // This doesn't change, even when cooldownBarMirrorX is true, because it should int v = height; // always start with the left-hand in the actual texture file - WizardryUtilities.drawTexturedFlippedRect(x1, y1, u, v, l, cooldownBarHeight, 256, 256, flipX && cooldownBarMirrorX, flipY && cooldownBarMirrorY); + DrawingUtils.drawTexturedFlippedRect(x1, y1, u, v, l, cooldownBarHeight, 256, 256, flipX && cooldownBarMirrorX, flipY && cooldownBarMirrorY); } GlStateManager.popMatrix(); @@ -574,11 +529,11 @@ public class GuiSpellDisplay { float yNext = y1 + cascadeOffsetY; // No need to account for flipY because next is always below. float maxWidthPrev = maxWidth + (flipY ? -1 : 1) * cascadeOffsetX; float maxWidthNext = maxWidth - (flipY ? -1 : 1) * cascadeOffsetX; - int nextPrevClr = makeTranslucent(0xffffff, SPELL_NAME_OPACITY); + int nextPrevClr = DrawingUtils.makeTranslucent(0xffffff, SPELL_NAME_OPACITY); - drawScaledStringToWidth(font, prevSpellName, xPrev, yPrev, SPELL_NAME_SCALE, nextPrevClr, maxWidthPrev, true, flipX && mirrorX); - drawScaledStringToWidth(font, spellName, x1, y1, 1, 0xffffffff, maxWidth, true, flipX && mirrorX); - drawScaledStringToWidth(font, nextSpellName, xNext, yNext, SPELL_NAME_SCALE, nextPrevClr, maxWidthNext, true, flipX && mirrorX); + DrawingUtils.drawScaledStringToWidth(font, prevSpellName, xPrev, yPrev, SPELL_NAME_SCALE, nextPrevClr, maxWidthPrev, true, flipX && mirrorX); + DrawingUtils.drawScaledStringToWidth(font, spellName, x1, y1, 1, 0xffffffff, maxWidth, true, flipX && mirrorX); + DrawingUtils.drawScaledStringToWidth(font, nextSpellName, xNext, yNext, SPELL_NAME_SCALE, nextPrevClr, maxWidthNext, true, flipX && mirrorX); }else{ // Switching spells @@ -593,20 +548,20 @@ public class GuiSpellDisplay { float maxWidthNext = maxWidth - (flipY ? -1 : 1) * cascadeOffsetX * (1 - animationProgress); float scalePrev = SPELL_NAME_SCALE + (1 - SPELL_NAME_SCALE) * (1 - animationProgress); float scaleNext = SPELL_NAME_SCALE + (1 - SPELL_NAME_SCALE) * (animationProgress); - int clrPrev = makeTranslucent(0xffffff, SPELL_NAME_OPACITY + (1 - SPELL_NAME_OPACITY) * (1 - animationProgress)); - int clrNext = makeTranslucent(0xffffff, SPELL_NAME_OPACITY + (1 - SPELL_NAME_OPACITY) * animationProgress); + int clrPrev = DrawingUtils.makeTranslucent(0xffffff, SPELL_NAME_OPACITY + (1 - SPELL_NAME_OPACITY) * (1 - animationProgress)); + int clrNext = DrawingUtils.makeTranslucent(0xffffff, SPELL_NAME_OPACITY + (1 - SPELL_NAME_OPACITY) * animationProgress); if(reverse){ // Switching to previous spell // Only renders the next spell and the current one - drawScaledStringToWidth(font, spellName, xPrev, yPrev, scalePrev, clrPrev, maxWidthPrev, true, flipX && mirrorX); - drawScaledStringToWidth(font, nextSpellName, xNext, yNext, scaleNext, clrNext, maxWidthNext, true, flipX && mirrorX); + DrawingUtils.drawScaledStringToWidth(font, spellName, xPrev, yPrev, scalePrev, clrPrev, maxWidthPrev, true, flipX && mirrorX); + DrawingUtils.drawScaledStringToWidth(font, nextSpellName, xNext, yNext, scaleNext, clrNext, maxWidthNext, true, flipX && mirrorX); }else{ // Switching to next spell // Only renders the previous spell and the current one - drawScaledStringToWidth(font, prevSpellName, xPrev, yPrev, scalePrev, clrPrev, maxWidthPrev, true, flipX && mirrorX); - drawScaledStringToWidth(font, spellName, xNext, yNext, scaleNext, clrNext, maxWidthNext, true, flipX && mirrorX); + DrawingUtils.drawScaledStringToWidth(font, prevSpellName, xPrev, yPrev, scalePrev, clrPrev, maxWidthPrev, true, flipX && mirrorX); + DrawingUtils.drawScaledStringToWidth(font, spellName, xNext, yNext, scaleNext, clrNext, maxWidthNext, true, flipX && mirrorX); } } diff --git a/src/main/java/electroblob/wizardry/util/WizardryUtilities.java b/src/main/java/electroblob/wizardry/util/WizardryUtilities.java index a00bfbc3..bcd9872c 100644 --- a/src/main/java/electroblob/wizardry/util/WizardryUtilities.java +++ b/src/main/java/electroblob/wizardry/util/WizardryUtilities.java @@ -27,7 +27,6 @@ import electroblob.wizardry.registry.WizardryPotions; import electroblob.wizardry.spell.MindControl; import electroblob.wizardry.spell.Spell; import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; @@ -68,7 +67,6 @@ import net.minecraftforge.fml.relauncher.SideOnly; *

* - In-world utilities (position calculating, retrieving entities, etc.)
* - Raytracing
- * - Drawing utilities (client-only)
* - NBT and data storage utilities
* - Interaction with the ally designation system
* - Loot and weighting utilities @@ -684,82 +682,6 @@ public final class WizardryUtilities { return result; } - // SECTION Rendering and GUIs - // =============================================================================================================== - - // Doesn't seem right to put this in the proxies since it should only ever be called from client-side code, and I'm - // not about to make a whole separate utilities class just for one method. Fully qualified names it is! - /** - * [Client-side only] Draws a textured rectangle, taking the size of the image and the bit needed into - * account, unlike {@link net.minecraft.client.gui.Gui#drawTexturedModalRect(int, int, int, int, int, int) - * Gui.drawTexturedModalRect(int, int, int, int, int, int)}, which is harcoded for only 256x256 textures. Also handy - * for custom potion icons. - * - * @param x The x position of the rectangle - * @param y The y position of the rectangle - * @param u The x position of the top left corner of the section of the image wanted - * @param v The y position of the top left corner of the section of the image wanted - * @param width The width of the section - * @param height The height of the section - * @param textureWidth The width of the actual image. - * @param textureHeight The height of the actual image. - */ - @SideOnly(Side.CLIENT) - public static void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight){ - drawTexturedFlippedRect(x, y, u, v, width, height, textureWidth, textureHeight, false, false); - } - - /** - * [Client-side only] Draws a textured rectangle, taking the size of the image and the bit needed into - * account, unlike {@link net.minecraft.client.gui.Gui#drawTexturedModalRect(int, int, int, int, int, int) - * Gui.drawTexturedModalRect(int, int, int, int, int, int)}, which is harcoded for only 256x256 textures. Also handy - * for custom potion icons. This version allows the texture to be flipped in x and/or y. - * - * @param x The x position of the rectangle - * @param y The y position of the rectangle - * @param u The x position of the top left corner of the section of the image wanted - * @param v The y position of the top left corner of the section of the image wanted - * @param width The width of the section - * @param height The height of the section - * @param textureWidth The width of the actual image. - * @param textureHeight The height of the actual image. - * @param flipX Whether to flip the texture in the x direction. - * @param flipY Whether to flip the texture in the y direction. - */ - @SideOnly(Side.CLIENT) - public static void drawTexturedFlippedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight, boolean flipX, boolean flipY){ - - float f = 1F / (float)textureWidth; - float f1 = 1F / (float)textureHeight; - - int u1 = flipX ? u + width : u; - int u2 = flipX ? u : u + width; - int v1 = flipY ? v + height : v; - int v2 = flipY ? v : v + height; - - // Essentially the same as getting the tessellator. For most code, you'll want the tessellator AND the - // vertexbuffer stored in local variables. - BufferBuilder buffer = net.minecraft.client.renderer.Tessellator.getInstance().getBuffer(); - // Equivalent of tessellator.startDrawingQuads() - buffer.begin(org.lwjgl.opengl.GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); - // Equivalent of tessellator.addVertex() - buffer.pos((double)(x), (double)(y + height), 0).tex((double)((float)(u1) * f), (double)((float)(v2) * f1)).endVertex(); - buffer.pos((double)(x + width), (double)(y + height), 0).tex((double)((float)(u2) * f), (double)((float)(v2) * f1)).endVertex(); - buffer.pos((double)(x + width), (double)(y), 0).tex((double)((float)(u2) * f), (double)((float)(v1) * f1)).endVertex(); - buffer.pos((double)(x), (double)(y), 0).tex((double)((float)(u1) * f), (double)((float)(v1) * f1)).endVertex(); - // Exactly the same as before. - net.minecraft.client.renderer.Tessellator.getInstance().draw(); - } - - /** - * Shorthand for {@link WizardryUtilities#drawTexturedRect(int, int, int, int, int, int, int, int)} which draws the - * entire texture (u and v are set to 0 and textureWidth and textureHeight are the same as width and height). - */ - @SideOnly(Side.CLIENT) - public static void drawTexturedRect(int x, int y, int width, int height){ - drawTexturedRect(x, y, 0, 0, width, height, width, height); - } - // SECTION NBT and Data Storage // ===============================================================================================================