From af14bf15a559c00585871fe16344de0ad5423f2b Mon Sep 17 00:00:00 2001 From: Fiesta87 Date: Fri, 20 Jan 2017 20:17:49 +0100 Subject: [PATCH] Add text GUI --- .gitignore | 1 + src/globalgamejam/gui/Image.java | 92 ++++++++ src/globalgamejam/gui/Label.java | 356 +++++++++++++++++++++++++++++++ 3 files changed, 449 insertions(+) create mode 100644 src/globalgamejam/gui/Image.java create mode 100644 src/globalgamejam/gui/Label.java diff --git a/.gitignore b/.gitignore index aaedf82..7453573 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* /.idea/ +/bin/ diff --git a/src/globalgamejam/gui/Image.java b/src/globalgamejam/gui/Image.java new file mode 100644 index 0000000..9e02ad6 --- /dev/null +++ b/src/globalgamejam/gui/Image.java @@ -0,0 +1,92 @@ +package globalgamejam.gui; + +public class Image { + protected float x, y; + protected float width, height; + protected int angle; + protected int textureID; + + public Image(float x, float y, float width, float height, int textureID) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.textureID = textureID; + } + + public float getX() { + return x; + } + + public void setX(float x) { + this.x = x; + } + + public float getY() { + return y; + } + + public void setY(float y) { + this.y = y; + } + + public float getWidth() { + return width; + } + + /** + * @param width the width to set + */ + public void setWidth(float width) { + this.width = width; + } + + public float getHeight() { + return height; + } + + /** + * @param height the height to set + */ + public void setHeight(float height) { + this.height = height; + } + + public int getTextureID() { + return textureID; + } + + /** + * IT DOESN'T WORKS + * Rotate the image in the counter-clock wise of the specified angle in degrees + * @param rotationAngle (int) : the angle to rotate in degrees + */ + public void rotate(int rotationAngle){ + this.angle += rotationAngle; + this.angle = this.angle % 360; + } + + /** + * IT DOESN'T WORKS + * Set the angle of the Image + * @param angle (int) : the angle, between -360 and +360 degrees + */ + public void rotateTo(int angle){ + this.angle = angle; + this.angle = this.angle % 360; + } + + /** + * IT DOESN'T WORKS + * Return the actuel angle + * @return angle (int) : the actual angle + */ + public int getAngle() { + return angle; + } + + public void setPosition(float x, float y){ + this.setX(x); + this.setY(y); + } +} diff --git a/src/globalgamejam/gui/Label.java b/src/globalgamejam/gui/Label.java new file mode 100644 index 0000000..2a03987 --- /dev/null +++ b/src/globalgamejam/gui/Label.java @@ -0,0 +1,356 @@ +package globalgamejam.gui; +import static org.lwjgl.opengl.GL11.*; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import java.nio.ByteBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL12; + +/** + * usefull to print 2D text in openGL LWJGL application + * @author Jean-Baptiste Pommeret (Fiesta) + * @version 1.0 + */ +public class Label { + + private static final int BYTES_PER_PIXEL = 4;//3 for RGB, 4 for RGBA + + private Image label; + private float x, y; + private String text; + private Color color; + private int size; + private int witdh, height; + + private String font; + + /** + * Full constructor of a Label + * @param text (String) : the text to print + * @param xC (float) : the x coordonnate of the frame where start printing the Label (upper left corner) + * @param yC (float) : the y coordonnate of the frame where start printing the Label (upper left corner) + * @param color (java.awt.Color) : the Color you wish for the text + * @param font (String) : the font (i.e. "Arial" or "Times new roman") + * @param size (int) : the font size + */ + public Label(String text, float xC, float yC, Color color, String font, int size){ + this.text = text; + this.x = xC; + this.y = yC; + this.color = color; + this.size = size; + this.font = font; + + Font f_font = new Font(font, Font.PLAIN, size); + + // to get the width of the text + BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); + FontMetrics fm = img.getGraphics().getFontMetrics(f_font); + + this.witdh = fm.stringWidth(this.text); + this.height = fm.getHeight(); + + final BufferedImage image = new BufferedImage(this.witdh, this.height, BufferedImage.TYPE_INT_ARGB); +// makeTransparent(image); + + Graphics g = image.getGraphics(); + g.setFont(f_font); + g.setColor(this.color); + g.drawString(this.text, 0, size); + g.dispose(); + + int[] pixels = new int[image.getWidth() * image.getHeight()]; + image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); + + ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * BYTES_PER_PIXEL); //4 for RGBA, 3 for RGB + + for(int y = 0; y < image.getHeight(); y++){ + for(int x = 0; x < image.getWidth(); x++){ + int pixel = pixels[y * image.getWidth() + x]; + buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component + buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component + buffer.put((byte) (pixel & 0xFF)); // Blue component + buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component. Only for RGBA + } + } + + buffer.flip(); //FOR THE LOVE OF GOD DO NOT FORGET THIS + + // You now have a ByteBuffer filled with the color data of each pixel. + // Now just create a texture ID and bind it. Then you can load it using + // whatever OpenGL method you want, for example: + + int textureID = glGenTextures(); //Generate texture ID + glBindTexture(GL_TEXTURE_2D, textureID); //Bind texture ID + + //Setup wrap mode + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE); + + //Setup texture scaling filtering + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + //Send texel data to OpenGL + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + glBindTexture(GL_TEXTURE_2D, 0); + + this.label = new Image(xC, yC, image.getWidth(), image.getHeight(), textureID); + } + + /** + * Default constructor of a Label. Call the full constructor -> Label("", 100, 100, Color.white, "Arial", 30) + */ + public Label(){ + this(""); + } + + /** + * Construct a Label from the text param and default statement. + * Call the full constructor -> Label(text, 100, 100, Color.white, "Arial", 30) + * @param text (String) : the text to print + */ + public Label(String text){ + this(text, 100, 100, Color.white, "Arial", 30); + } + + /** + * Return the actual Color of the Label + * @return color (java.awt.Color) : the Color of the Label + */ + public Color getColor() { + return color; + } + + /** + * Set the Color of the Label. Automaticaly update the Label to use the new Color + * @param color (java.awt.Color) : the new Color of the Label + */ + public void setColor(Color color) { + this.color = color; + + Font f_font = new Font(font, Font.PLAIN, size); + + // to get the width of the text + BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); + FontMetrics fm = img.getGraphics().getFontMetrics(f_font); + + this.witdh = fm.stringWidth(this.text); + this.height = fm.getHeight(); + + final BufferedImage image = new BufferedImage(this.witdh, this.height, BufferedImage.TYPE_INT_ARGB); +// makeTransparent(image); + + Graphics g = image.getGraphics(); + g.setFont(f_font); + g.setColor(this.color); + g.drawString(this.text, 0, size); + g.dispose(); + + int[] pixels = new int[image.getWidth() * image.getHeight()]; + image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); + + ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * BYTES_PER_PIXEL); //4 for RGBA, 3 for RGB + + for(int y = 0; y < image.getHeight(); y++){ + for(int x = 0; x < image.getWidth(); x++){ + int pixel = pixels[y * image.getWidth() + x]; + buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component + buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component + buffer.put((byte) (pixel & 0xFF)); // Blue component + buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component. Only for RGBA + } + } + + buffer.flip(); //FOR THE LOVE OF GOD DO NOT FORGET THIS + + // You now have a ByteBuffer filled with the color data of each pixel. + // Now just create a texture ID and bind it. Then you can load it using + // whatever OpenGL method you want, for example: + + int textureID = glGenTextures(); //Generate texture ID + glBindTexture(GL_TEXTURE_2D, textureID); //Bind texture ID + + //Setup wrap mode + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE); + + //Setup texture scaling filtering + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + //Send texel data to OpenGL + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + glBindTexture(GL_TEXTURE_2D, 0); + + this.label = new Image(this.x, this.y, image.getWidth(), image.getHeight(), textureID); + } + + /** + * Return the text of the Label + * @return text (String) : the text of the Label + */ + public String getText() { + return text; + } + + /** + * Set the text of the Label. Automaticaly update the Label to use the new text + * @param text (String) : the new text to display + */ + public void setText(String text) { + this.text = text; + + Font f_font = new Font(font, Font.PLAIN, size); + + // to get the width of the text + BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); + FontMetrics fm = img.getGraphics().getFontMetrics(f_font); + + this.witdh = fm.stringWidth(this.text); + this.height = fm.getHeight(); + + final BufferedImage image = new BufferedImage(this.witdh, this.height, BufferedImage.TYPE_INT_ARGB); +// makeTransparent(image); + + Graphics g = image.getGraphics(); + g.setFont(f_font); + g.setColor(this.color); + g.drawString(this.text, 0, size); + g.dispose(); + + int[] pixels = new int[image.getWidth() * image.getHeight()]; + image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); + + ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * BYTES_PER_PIXEL); //4 for RGBA, 3 for RGB + + for(int y = 0; y < image.getHeight(); y++){ + for(int x = 0; x < image.getWidth(); x++){ + int pixel = pixels[y * image.getWidth() + x]; + buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component + buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component + buffer.put((byte) (pixel & 0xFF)); // Blue component + buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component. Only for RGBA + } + } + + buffer.flip(); //FOR THE LOVE OF GOD DO NOT FORGET THIS + + // You now have a ByteBuffer filled with the color data of each pixel. + // Now just create a texture ID and bind it. Then you can load it using + // whatever OpenGL method you want, for example: + + int textureID = glGenTextures(); //Generate texture ID + glBindTexture(GL_TEXTURE_2D, textureID); //Bind texture ID + + //Setup wrap mode + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE); + + //Setup texture scaling filtering + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + //Send texel data to OpenGL + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.getWidth(), image.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + glBindTexture(GL_TEXTURE_2D, 0); + + this.label = new Image(this.x, this.y, image.getWidth(), image.getHeight(), textureID); + } + + /** + * Return the x coordonnate of the Label (upper left corner) + * @return x (float) : the x coordonnate of the Label + */ + public float getX() { + return x; + } + + /** + * Set the x coordonnate of the Label (upper left corner) + * @param x (float) : the new x coordonnate of the Label + */ + public void setX(float x) { + this.x = x; + label.setX(x); + } + + /** + * Return the y coordonnate of the Label (upper left corner) + * @return y (float) : the y coordonnate of the Label + */ + public float getY() { + return y; + } + + /** + * Set the y coordonnate of the Label (upper left corner) + * @param y (float) : the new y coordonnate of the Label + */ + public void setY(float y) { + this.y = y; + label.setY(y); + } + + /** + * Set both x and y coordonnate of the Label + * @param x (float) : the new x coordonnate of the Label + * @param y (float) : the new y coordonnate of the Label + */ + public void setPosition(float x, float y){ + this.setX(x); + this.setY(y); + } + + /** + * Return the Image of the Label + * @return label (Image) : the Image of the Label + */ + public Image getLabel(){ + return this.label; + } + + /** + * Return the witdh of the Label + * @return witdh (int) : the width + */ + public int getWitdh() { + return witdh; + } + + /** + * Return the height of the Label + * @return height (int) : the height + */ + public int getHeight() { + return height; + } + + /** + * make the image transparent + * @param obj_img (BufferedImage) : the BufferedImage to make transparent + */ +/* private void makeTransparent(BufferedImage obj_img){ + byte alpha = (byte)255; + alpha %= 0xff; + for (int cx=0;cx