package game.renderer; import game.Game; import game.color.TextColor; import game.gui.Font; import game.gui.FontChar; import game.log.Log; public abstract class Drawing { public static class Vec2i { public final int xpos; public final int ypos; private Vec2i(int x, int y) { this.xpos = x; this.ypos = y; } } public static class Offset extends Vec2i { public final int offset; private Offset(int off, int x, int y) { super(x, y); this.offset = off; } } // private static final int FLAG_ULINE = 0x01; // private static final int FLAG_CLINE = 0x02; // private static final int FLAG_BLINK = 0x04; // private static final int FLAG_FADE = 0x08; // public static void drawTexturedModalRect(int tw, int th, int x, int y, int textureX, int textureY, int width, int height) // { // float xs = 1.0f / (float)tw; // 0.00390625F; // float ys = 1.0f / (float)th; // 0.00390625F; // RenderBuffer rb = Tessellator.getBuffer(); // rb.begin(7, DefaultVertexFormats.POSITION_TEX); // rb.pos((double)(x + 0), (double)(y + height), 0.0).tex((double)((float)(textureX + 0) * xs), (double)((float)(textureY + height) * ys)).endVertex(); // rb.pos((double)(x + width), (double)(y + height), 0.0).tex((double)((float)(textureX + width) * xs), (double)((float)(textureY + height) * ys)).endVertex(); // rb.pos((double)(x + width), (double)(y + 0), 0.0).tex((double)((float)(textureX + width) * xs), (double)((float)(textureY + 0) * ys)).endVertex(); // rb.pos((double)(x + 0), (double)(y + 0), 0.0).tex((double)((float)(textureX + 0) * xs), (double)((float)(textureY + 0) * ys)).endVertex(); // Tessellator.draw(); // } public static void drawTexturedModalRect(RenderBuffer rb, int tw, int th, int x, int y, int textureX, int textureY, int width, int height, int color) { float xs = 1.0f / (float)tw; // 0.00390625F; float ys = 1.0f / (float)th; // 0.00390625F; rb.pos((double)(x + 0), (double)(y + height), 0.0).tex((double)((float)(textureX + 0) * xs), (double)((float)(textureY + height) * ys)).color(color).endVertex(); rb.pos((double)(x + width), (double)(y + height), 0.0).tex((double)((float)(textureX + width) * xs), (double)((float)(textureY + height) * ys)).color(color).endVertex(); rb.pos((double)(x + width), (double)(y + 0), 0.0).tex((double)((float)(textureX + width) * xs), (double)((float)(textureY + 0) * ys)).color(color).endVertex(); rb.pos((double)(x + 0), (double)(y + 0), 0.0).tex((double)((float)(textureX + 0) * xs), (double)((float)(textureY + 0) * ys)).color(color).endVertex(); } private static void color(int c) { float a = (float)(c >> 24 & 255) / 255.0F; float r = (float)(c >> 16 & 255) / 255.0F; float g = (float)(c >> 8 & 255) / 255.0F; float b = (float)(c & 255) / 255.0F; GlState.color(r, g, b, a); } // private static void trect(int left, int top, int right, int bottom) // { // RenderBuffer worldrenderer = Tessellator.getBuffer(); // worldrenderer.begin(7, DefaultVertexFormats.POSITION); // worldrenderer.pos((double)left, (double)bottom, 0.0D).endVertex(); // worldrenderer.pos((double)right, (double)bottom, 0.0D).endVertex(); // worldrenderer.pos((double)right, (double)top, 0.0D).endVertex(); // worldrenderer.pos((double)left, (double)top, 0.0D).endVertex(); // Tessellator.draw(); // } public static void txt_draw(int x, int y, int x1, int y1, int x2, int y2, int color, String str) { GlState.enableTexture2D(); GlState.enableBlend(); GlState.disableAlpha(); GlState.tryBlendFuncSeparate(770, 771, 1, 0); GlState.shadeModel(7425); GlState.color(1.0f, 1.0f, 1.0f, 1.0f); Font.bindTexture(); RenderBuffer rb = Tessellator.getBuffer(); rb.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); int h = Font.YGLYPH; int tx, ty, u, v; FontChar glyph; char ch; int ncolor = color; // color(color); for(int z = 0; z < str.length(); z++) { ch = str.charAt(z); if(ch == Log.CHR_NLN) { x = x1; y += h; continue; } // else if(ch >= Log.CHR_ULINE && ch <= Log.CHR_FADE) { // continue; // } else if((ch >= Log.CHR_COLORS1 && ch <= Log.CHR_COLORE1) || (ch >= Log.CHR_COLORS2 && ch <= Log.CHR_COLORE2)) { // color(TextColor.getColor(ch) | (color & 0xff000000)); ncolor = TextColor.getColor(ch) | (color & 0xff000000); continue; } // else if(ch == Log.CHR_FRESET) { // continue; // } else if(ch == Log.CHR_CRESET) { // color(color); ncolor = color; continue; } if(ch >= 256) ch = Log.CHR_UNK; glyph = Font.SIZES[ch]; if(glyph.u == 0 && glyph.v != 0) continue; else if(glyph.u == 0) glyph = Font.SIZES[Log.CHR_UNK]; u = glyph.u + 3 - glyph.s; v = h; tx = ((x + u) > x2) ? x1 : x; ty = ((x + u) > x2) ? y + h : y; x = tx; y = ty; if(x < x1 || y < y1 || x > x2 || y > y2) { break; } drawTexturedModalRect(rb, Font.XGLYPH * 16, Font.YGLYPH * 16, x, y, (ch & 0x0f) * Font.XGLYPH + glyph.s, ((ch & 0xf0) >> 4) * Font.YGLYPH, glyph.u, h, ncolor); x += u; } Tessellator.draw(); GlState.shadeModel(7424); GlState.disableBlend(); GlState.enableAlpha(); GlState.enableTexture2D(); } public static void txt_draw_range(int start, int end, int x, int y, int x1, int y1, int x2, int y2, int back, String str) { int h = Font.YGLYPH; int tx, ty, u, v; FontChar glyph; char ch; int pos = 0; int lpos = 0; // ShaderContext shd = Shader.TEXT.use(); // shd.setVec2("font_size", (float)font.xglyph, (float)font.yglyph); // shd.setInt("flags", 0); // shd.setColor("color", 0x00000000); // shd.setColor("back", back); // shd.setInt("ch_index", Log.CHR_SPC & 0xff); // GlState.bindTexture(font.textures[Log.CHR_SPC >> 8]); while(true) { pos = lpos; if(lpos >= str.length()) break; ch = str.charAt(lpos++); if(ch == Log.CHR_NLN) { x = x1; y += h; continue; } else if(ch < Log.CHR_SPC) { continue; } if(ch >= 256) ch = Log.CHR_UNK; glyph = Font.SIZES[ch]; if(glyph.u == 0 && glyph.v != 0) continue; else if(glyph.u == 0) glyph = Font.SIZES[Log.CHR_UNK]; u = glyph.u + 3 - glyph.s; v = h; tx = ((x + u) > x2) ? x1 : x; ty = ((x + u) > x2) ? y + h : y; x = tx; y = ty; if(x < x1 || y < y1 || x > x2 || y > y2) { break; } if(pos >= start && pos < end) { // shd.setVec2("offset", (float)x, (float)y); // shd.setVec2("size", (float)u, (float)v); // shd.setVec4("glyph", (float)glyph.s, 0.0f, (float)glyph.u, (float)h); // shd.draw(); drawRect(x, y, x + u, y + v, back); } x += u; } // shd.discard(); } public static Vec2i txt_size(int x, int y, int x1, int y1, int x2, int y2, String str) { int h = Font.YGLYPH; int ix = x; int iy = y; int tx, ty, u, v; FontChar glyph; char ch; for(int z = 0; z < str.length(); z++) { ch = str.charAt(z); if(ch == Log.CHR_NLN) { x = x1; y += h; continue; } else if(ch < Log.CHR_SPC) { continue; } if(ch >= 256) ch = Log.CHR_UNK; glyph = Font.SIZES[ch]; if(glyph.u == 0 && glyph.v != 0) continue; else if(glyph.u == 0) glyph = Font.SIZES[Log.CHR_UNK]; u = glyph.u + 3 - glyph.s; v = h; tx = ((x + u) > x2) ? x1 : x; ty = ((x + u) > x2) ? y + h : y; x = tx; y = ty; if(x < x1 || y < y1 || x > x2 || y > y2) { break; } x += u; } return new Vec2i(x - ix, y - iy); } public static Vec2i txt_box(int x, int y, int x1, int y1, int x2, int y2, String str) { int h = Font.YGLYPH; int ix = x; // int iy = y; int tx, ty, u, v; FontChar glyph; char ch; for(int z = 0; z < str.length(); z++) { ch = str.charAt(z); if(ch == Log.CHR_NLN) { x = x1; y += h; continue; } else if(ch < Log.CHR_SPC) { continue; } if(ch >= 256) ch = Log.CHR_UNK; glyph = Font.SIZES[ch]; if(glyph.u == 0 && glyph.v != 0) continue; else if(glyph.u == 0) glyph = Font.SIZES[Log.CHR_UNK]; u = glyph.u + 3 - glyph.s; v = h; tx = ((x + u) > x2) ? x1 : x; ty = ((x + u) > x2) ? y + h : y; x = tx; y = ty; if(x < x1 || y < y1 || x > x2 || y > y2) { break; } x += u; ix = x > ix ? x : ix; } return new Vec2i(ix - 2, y + h); } public static Vec2i txt_coord(int offset, int x, int y, int x1, int y1, int x2, int y2, String str) { int h = Font.YGLYPH; int tx, ty, u, v; FontChar glyph; char ch; int pos = 0; int lpos = 0; while(true) { pos = lpos; if(lpos >= str.length()) break; ch = str.charAt(lpos++); if(pos == offset) { return new Vec2i(x, y); } if(ch == Log.CHR_NLN) { x = x1; y += h; continue; } else if(ch < Log.CHR_SPC) { continue; } if(ch >= 256) ch = Log.CHR_UNK; glyph = Font.SIZES[ch]; if(glyph.u == 0 && glyph.v != 0) continue; else if(glyph.u == 0) glyph = Font.SIZES[Log.CHR_UNK]; u = glyph.u + 3 - glyph.s; v = h; tx = ((x + u) > x2) ? x1 : x; ty = ((x + u) > x2) ? y + h : y; x = tx; y = ty; if(x < x1 || y < y1 || x > x2 || y > y2) { break; } x += u; } return new Vec2i(x, y); } public static Offset txt_offset(int ox, int oy, int x, int y, int x1, int y1, int x2, int y2, String str) { int h = Font.YGLYPH; int tx, ty, u, v; FontChar glyph; char ch; int pos = 0; int lpos = 0; if(oy < y) { return null; } ox = ox < x1 ? x1 : ox; while(true) { pos = lpos; if(lpos >= str.length()) break; ch = str.charAt(lpos++); if(ch == Log.CHR_NLN) { if(ox >= x && oy >= y && oy < (y + h)) { return new Offset(pos, x, y); } x = x1; y += h; continue; } else if(ch < Log.CHR_SPC) { continue; } if(ch >= 256) ch = Log.CHR_UNK; glyph = Font.SIZES[ch]; if(glyph.u == 0 && glyph.v != 0) continue; else if(glyph.u == 0) glyph = Font.SIZES[Log.CHR_UNK]; u = glyph.u + 3 - glyph.s; v = h; tx = ((x + u) > x2) ? x1 : x; ty = ((x + u) > x2) ? y + h : y; if(ty > y && ox >= x && oy >= y && oy < (y + h)) { return new Offset(pos, tx, ty); } x = tx; y = ty; if(x < x1 || y < y1 || x > x2 || y > y2) { pos = lpos; break; } if(ox >= x && oy >= y && ox < (x + u) && oy < (y + h)) { return new Offset(pos, x, y); } x += u; } return new Offset(pos, x, y); } // public static void gfx_blit(int tex) { // ShaderContext shd = Shader.BLIT.use(); // GlState.bindTexture(tex); // shd.draw(); // shd.discard(); // } public static void drawGradientRect(int left, int top, int right, int bottom, int ctop, int cbottom) { float at = (float)(ctop >> 24 & 255) / 255.0F; float rt = (float)(ctop >> 16 & 255) / 255.0F; float gt = (float)(ctop >> 8 & 255) / 255.0F; float bt = (float)(ctop & 255) / 255.0F; float ab = (float)(cbottom >> 24 & 255) / 255.0F; float rb = (float)(cbottom >> 16 & 255) / 255.0F; float gb = (float)(cbottom >> 8 & 255) / 255.0F; float bb = (float)(cbottom & 255) / 255.0F; GlState.disableTexture2D(); GlState.enableBlend(); GlState.disableAlpha(); GlState.tryBlendFuncSeparate(770, 771, 1, 0); GlState.shadeModel(7425); RenderBuffer buf = Tessellator.getBuffer(); buf.begin(7, DefaultVertexFormats.POSITION_COLOR); buf.pos((double)right, (double)top, 0.0).color(rt, gt, bt, at).endVertex(); buf.pos((double)left, (double)top, 0.0).color(rt, gt, bt, at).endVertex(); buf.pos((double)left, (double)bottom, 0.0).color(rb, gb, bb, ab).endVertex(); buf.pos((double)right, (double)bottom, 0.0).color(rb, gb, bb, ab).endVertex(); Tessellator.draw(); GlState.shadeModel(7424); GlState.disableBlend(); GlState.enableAlpha(); GlState.enableTexture2D(); } public static void draw4GradientRect(int left, int top, int right, int bottom, int lopleft, int topright, int btmleft, int btmright) { GlState.disableTexture2D(); GlState.enableBlend(); GlState.disableAlpha(); GlState.tryBlendFuncSeparate(770, 771, 1, 0); GlState.shadeModel(7425); RenderBuffer buf = Tessellator.getBuffer(); buf.begin(7, DefaultVertexFormats.POSITION_COLOR); buf.pos((double)right, (double)top, 0.0).color(topright).endVertex(); buf.pos((double)left, (double)top, 0.0).color(lopleft).endVertex(); buf.pos((double)left, (double)bottom, 0.0).color(btmleft).endVertex(); buf.pos((double)right, (double)bottom, 0.0).color(btmright).endVertex(); Tessellator.draw(); GlState.shadeModel(7424); GlState.disableBlend(); GlState.enableAlpha(); GlState.enableTexture2D(); } public static void drawRect(int left, int top, int right, int bottom, int color) { if (left < right) { int i = left; left = right; right = i; } if (top < bottom) { int j = top; top = bottom; bottom = j; } float f3 = (float)(color >> 24 & 255) / 255.0F; float f = (float)(color >> 16 & 255) / 255.0F; float f1 = (float)(color >> 8 & 255) / 255.0F; float f2 = (float)(color & 255) / 255.0F; RenderBuffer worldrenderer = Tessellator.getBuffer(); GlState.enableBlend(); GlState.disableAlpha(); GlState.disableTexture2D(); GlState.tryBlendFuncSeparate(770, 771, 1, 0); GlState.shadeModel(7425); GlState.color(f, f1, f2, f3); worldrenderer.begin(7, DefaultVertexFormats.POSITION); worldrenderer.pos((double)left, (double)bottom, 0.0D).endVertex(); worldrenderer.pos((double)right, (double)bottom, 0.0D).endVertex(); worldrenderer.pos((double)right, (double)top, 0.0D).endVertex(); worldrenderer.pos((double)left, (double)top, 0.0D).endVertex(); Tessellator.draw(); GlState.shadeModel(7424); GlState.enableTexture2D(); GlState.disableBlend(); GlState.enableAlpha(); GlState.color(1.0f, 1.0f, 1.0f, 1.0f); } // public static void gfx_draw_rect(int x, int y, int w, int h, int border, int top, int bottom, int b_top, int b_bottom) { // drawGradientRect(x, y, x + w, y + h, b_top, b_bottom); // drawGradientRect(x + border, y + border, x + w - border, y + h - border, top, bottom); // } public static void drawRectColor(int x, int y, int w, int h, int color) { drawRect(x, y, x + w, y + h, color); } public static void drawGradient(int x, int y, int w, int h, int top, int bottom) { drawGradientRect(x, y, x + w, y + h, top, bottom); } public static void drawRectBorder(int x, int y, int w, int h, int color, int border) { drawRect(x, y, x + w, y + h, border); drawRect(x + 1, y + 1, x + w - 1, y + h - 1, color); } // public static void drawRect2Border(int x, int y, int w, int h, int color, int border) { // drawRect(x, y, x + w, y + h, border); // drawRect(x + 2, y + 2, x + w - 2, y + h - 2, color); // } public static void drawRect2GradBorder(int x, int y, int w, int h, int color, int border, int lopleft, int topright, int btmleft, int btmright) { drawRect(x, y, x + w, y + h, border); draw4GradientRect(x + 1, y + 1, x + w - 1, y + h - 1, lopleft, topright, btmleft, btmright); drawRect(x + 2, y + 2, x + w - 2, y + h - 2, color); } public static void drawGradient2GradBorder(int x, int y, int w, int h, int top, int bottom, int border, int lopleft, int topright, int btmleft, int btmright) { drawRect(x, y, x + w, y + h, border); draw4GradientRect(x + 1, y + 1, x + w - 1, y + h - 1, lopleft, topright, btmleft, btmright); drawGradientRect(x + 2, y + 2, x + w - 2, y + h - 2, top, bottom); } public static void drawGradient2Border(int x, int y, int w, int h, int top, int bottom, int b_top, int b_bottom) { drawGradientRect(x, y, x + w, y + h, b_top, b_bottom); drawGradientRect(x + 1, y + 1, x + w - 1, y + h - 1, top, bottom); } public static Vec2i getSize(String str) { return txt_size(0, 0, 0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE, str); } public static int getWidth(String str) { return txt_size(0, 0, 0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE, str).xpos; } public static void drawTextbox(String str, int x, int y, int back) { Vec2i size = txt_box(x + 2, y, x + 2, y, Integer.MAX_VALUE, Integer.MAX_VALUE, str); drawRect(x, y, size.xpos + 2, size.ypos, back); txt_draw(x + 2, y, x + 2, y, Integer.MAX_VALUE, Integer.MAX_VALUE, 0xffffffff, str); } public static void drawTextboxRight(String str, int x, int y, int back) { Vec2i size = getSize(str); drawTextbox(str, x - (size.xpos + 2), y, back); } public static void drawTextboxCentered(String str, int x, int y, int back) { Vec2i size = getSize(str); drawTextbox(str, x - (size.xpos + 2) / 2, y, back); } public static void drawText(String str, int x, int y, int color) { txt_draw(x, y, x, y, Integer.MAX_VALUE, Integer.MAX_VALUE, color, str); } public static void drawTextCentered(String str, int x, int y, int color) { Vec2i size = getSize(str); drawText(str, x - size.xpos / 2, y, color); } public static void drawTextRight(String str, int x, int y, int color) { Vec2i size = getSize(str); drawText(str, x - size.xpos, y, color); } public static void drawTextUpward(String str, int x, int y, int color) { Vec2i size = getSize(str); drawText(str, x - size.xpos / 2, y - size.ypos, color); } public static int mixColor(int c1, int c2) { return ((((c1 >> 24 & 255) + (c2 >> 24 & 255)) / 2) << 24) | ((((c1 >> 16 & 255) + (c2 >> 16 & 255)) / 2) << 16) | ((((c1 >> 8 & 255) + (c2 >> 8 & 255)) / 2) << 8) | (((c1 & 255) + (c2 & 255)) / 2); } public static void drawScaledBackground(Game gm, String texture) { drawScaledBackground(gm, texture, 0, 0, gm.fb_x, gm.fb_y); } public static void drawScaledBackground(Game gm, String texture, double x, double y, double width, double height) { GlState.enableTexture2D(); GlState.disableLighting(); GlState.disableFog(); RenderBuffer buf = Tessellator.getBuffer(); gm.getTextureManager().bindTexture(texture); GlState.color(1.0F, 1.0F, 1.0F, 1.0F); double scale = 32.0; buf.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); buf.pos(x, y + height, 0.0D).tex(0.0D, height / scale) .color(64, 64, 64, 255).endVertex(); buf.pos(x + width, y + height, 0.0D) .tex(width / scale, height / scale) .color(64, 64, 64, 255).endVertex(); buf.pos(x + width, y, 0.0D).tex(width / scale, 0.0) .color(64, 64, 64, 255).endVertex(); buf.pos(x, y, 0.0D).tex(0.0D, 0.0) .color(64, 64, 64, 255).endVertex(); Tessellator.draw(); GlState.disableTexture2D(); } }