summaryrefslogtreecommitdiff
path: root/src/main/java/net/tylermurphy/Minecraft/UI
diff options
context:
space:
mode:
authorTyler Murphy <tylerm@tylerm.dev>2023-04-17 12:12:01 -0400
committerTyler Murphy <tylerm@tylerm.dev>2023-04-17 12:12:01 -0400
commit180aad05decc7eefa87e4e45d6747c48f40e5361 (patch)
tree51545197f7c94b4022acab880772c9f4fc65db0e /src/main/java/net/tylermurphy/Minecraft/UI
downloadminecraftjava-180aad05decc7eefa87e4e45d6747c48f40e5361.tar.gz
minecraftjava-180aad05decc7eefa87e4e45d6747c48f40e5361.tar.bz2
minecraftjava-180aad05decc7eefa87e4e45d6747c48f40e5361.zip
Diffstat (limited to 'src/main/java/net/tylermurphy/Minecraft/UI')
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/Text/Character.java72
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/Text/Line.java44
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/Text/MetaFile.java157
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/Text/TextMaster.java63
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/Text/TextMeshCreator.java140
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/Text/TextMeshData.java25
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/Text/Word.java29
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/UI.java38
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/UIComponent.java104
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/UIFactory/CommandUI.java23
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/UIFactory/CoreUI.java76
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/UIFactory/F3UI.java53
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/UIFactory/SavingUI.java17
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/UIFactory/UIStore.java24
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/UIFont.java31
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/UIImage.java30
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/UILayerQuickSort.java38
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/UIMaster.java65
-rwxr-xr-xsrc/main/java/net/tylermurphy/Minecraft/UI/UIText.java110
19 files changed, 1139 insertions, 0 deletions
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/Text/Character.java b/src/main/java/net/tylermurphy/Minecraft/UI/Text/Character.java
new file mode 100755
index 0000000..d7d78cf
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/Text/Character.java
@@ -0,0 +1,72 @@
+package net.tylermurphy.Minecraft.UI.Text;
+
+
+public class Character {
+
+ private int id;
+ private double xTextureCoord;
+ private double yTextureCoord;
+ private double xMaxTextureCoord;
+ private double yMaxTextureCoord;
+ private double xOffset;
+ private double yOffset;
+ private double sizeX;
+ private double sizeY;
+ private double xAdvance;
+
+
+ protected Character(int id, double xTextureCoord, double yTextureCoord, double xTexSize, double yTexSize,
+ double xOffset, double yOffset, double sizeX, double sizeY, double xAdvance) {
+ this.id = id;
+ this.xTextureCoord = xTextureCoord;
+ this.yTextureCoord = yTextureCoord;
+ this.xOffset = xOffset;
+ this.yOffset = yOffset;
+ this.sizeX = sizeX;
+ this.sizeY = sizeY;
+ this.xMaxTextureCoord = xTexSize + xTextureCoord;
+ this.yMaxTextureCoord = yTexSize + yTextureCoord;
+ this.xAdvance = xAdvance;
+ }
+
+ protected int getId() {
+ return id;
+ }
+
+ protected double getxTextureCoord() {
+ return xTextureCoord;
+ }
+
+ protected double getyTextureCoord() {
+ return yTextureCoord;
+ }
+
+ protected double getXMaxTextureCoord() {
+ return xMaxTextureCoord;
+ }
+
+ protected double getYMaxTextureCoord() {
+ return yMaxTextureCoord;
+ }
+
+ protected double getxOffset() {
+ return xOffset;
+ }
+
+ protected double getyOffset() {
+ return yOffset;
+ }
+
+ protected double getSizeX() {
+ return sizeX;
+ }
+
+ protected double getSizeY() {
+ return sizeY;
+ }
+
+ protected double getxAdvance() {
+ return xAdvance;
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/Text/Line.java b/src/main/java/net/tylermurphy/Minecraft/UI/Text/Line.java
new file mode 100755
index 0000000..ec80db5
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/Text/Line.java
@@ -0,0 +1,44 @@
+package net.tylermurphy.Minecraft.UI.Text;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Line {
+
+ private double maxLength;
+ private double spaceSize;
+
+ private List<Word> words = new ArrayList<Word>();
+ private double currentLineLength = 0;
+
+
+ protected Line(double spaceWidth, double fontSize, double maxLength) {
+ this.spaceSize = spaceWidth * fontSize;
+ this.maxLength = maxLength;
+ }
+
+ protected boolean attemptToAddWord(Word word) {
+ double additionalLength = word.getWordWidth();
+ additionalLength += !words.isEmpty() ? spaceSize : 0;
+ if (currentLineLength + additionalLength <= maxLength) {
+ words.add(word);
+ currentLineLength += additionalLength;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ protected double getMaxLength() {
+ return maxLength;
+ }
+
+ protected double getLineLength() {
+ return currentLineLength;
+ }
+
+ protected List<Word> getWords() {
+ return words;
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/Text/MetaFile.java b/src/main/java/net/tylermurphy/Minecraft/UI/Text/MetaFile.java
new file mode 100755
index 0000000..1d22499
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/Text/MetaFile.java
@@ -0,0 +1,157 @@
+package net.tylermurphy.Minecraft.UI.Text;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.tylermurphy.Minecraft.Util.Constants;
+import net.tylermurphy.Minecraft.Render.Data.Display;
+
+public class MetaFile {
+
+ private static final int PAD_TOP = 0;
+ private static final int PAD_LEFT = 1;
+ private static final int PAD_BOTTOM = 2;
+ private static final int PAD_RIGHT = 3;
+
+ private static final int DESIRED_PADDING = 8;
+
+ private static final String SPLITTER = " ";
+ private static final String NUMBER_SEPARATOR = ",";
+
+ private double aspectRatio;
+
+ private double verticalPerPixelSize;
+ private double horizontalPerPixelSize;
+ private double spaceWidth;
+ private int[] padding;
+ private int paddingWidth;
+ private int paddingHeight;
+
+ private Map<Integer, Character> metaData = new HashMap<Integer, Character>();
+
+ private BufferedReader reader;
+ private Map<String, String> values = new HashMap<String, String>();
+
+ protected MetaFile(String file) {
+ this.aspectRatio = (double) Display.getWidth() / (double) Display.getHeight();
+ openFile(file);
+ loadPaddingData();
+ loadLineSizes();
+ int imageWidth = getValueOfVariable("scaleW");
+ loadCharacterData(imageWidth);
+ close();
+ }
+
+ protected double getSpaceWidth() {
+ return spaceWidth;
+ }
+
+ protected Character getCharacter(int ascii) {
+ return metaData.get(ascii);
+ }
+
+ private boolean processNextLine() {
+ values.clear();
+ String line = null;
+ try {
+ line = reader.readLine();
+ } catch (IOException e1) {
+ }
+ if (line == null) {
+ return false;
+ }
+ for (String part : line.split(SPLITTER)) {
+ String[] valuePairs = part.split("=");
+ if (valuePairs.length == 2) {
+ values.put(valuePairs[0], valuePairs[1]);
+ }
+ }
+ return true;
+ }
+
+ private int getValueOfVariable(String variable) {
+ int i = 0;
+ try {
+ i = Integer.parseInt(values.get(variable));
+ }catch(Exception e) {
+ e.printStackTrace();
+ }
+ return i;
+ }
+
+ private int[] getValuesOfVariable(String variable) {
+ String[] numbers = values.get(variable).split(NUMBER_SEPARATOR);
+ int[] actualValues = new int[numbers.length];
+ for (int i = 0; i < actualValues.length; i++) {
+ actualValues[i] = Integer.parseInt(numbers[i]);
+ }
+ return actualValues;
+ }
+
+ private void close() {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void openFile(String file) {
+ try {
+ FileReader isr = new FileReader(new File(Constants.FNT_LOCATION + file + ".fnt"));
+ reader = new BufferedReader(isr);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.err.println("Couldn't read font meta file!");
+ }
+ }
+
+ private void loadPaddingData() {
+ processNextLine();
+ this.padding = getValuesOfVariable("padding");
+ this.paddingWidth = padding[PAD_LEFT] + padding[PAD_RIGHT];
+ this.paddingHeight = padding[PAD_TOP] + padding[PAD_BOTTOM];
+ }
+
+ private void loadLineSizes() {
+ processNextLine();
+ int lineHeightPixels = getValueOfVariable("lineHeight") - paddingHeight;
+ verticalPerPixelSize = TextMeshCreator.LINE_HEIGHT / (double) lineHeightPixels;
+ horizontalPerPixelSize = verticalPerPixelSize / aspectRatio;
+ }
+
+ private void loadCharacterData(int imageWidth) {
+ processNextLine();
+ processNextLine();
+ while (processNextLine()) {
+ Character c = loadCharacter(imageWidth);
+ if (c != null) {
+ metaData.put(c.getId(), c);
+ }
+ }
+ }
+
+ private Character loadCharacter(int imageSize) {
+ int id = getValueOfVariable("id");
+ if (id == TextMeshCreator.SPACE_ASCII) {
+ this.spaceWidth = (getValueOfVariable("xadvance") - paddingWidth) * horizontalPerPixelSize;
+ return null;
+ }
+ double xTex = ((double) getValueOfVariable("x") + (padding[PAD_LEFT] - DESIRED_PADDING)) / imageSize;
+ double yTex = ((double) getValueOfVariable("y") + (padding[PAD_TOP] - DESIRED_PADDING)) / imageSize;
+ int width = getValueOfVariable("width") - (paddingWidth - (2 * DESIRED_PADDING));
+ int height = getValueOfVariable("height") - ((paddingHeight) - (2 * DESIRED_PADDING));
+ double quadWidth = width * horizontalPerPixelSize;
+ double quadHeight = height * verticalPerPixelSize;
+ double xTexSize = (double) width / imageSize;
+ double yTexSize = (double) height / imageSize;
+ double xOff = (getValueOfVariable("xoffset") + padding[PAD_LEFT] - DESIRED_PADDING) * horizontalPerPixelSize;
+ double yOff = (getValueOfVariable("yoffset") + (padding[PAD_TOP] - DESIRED_PADDING)) * verticalPerPixelSize;
+ double xAdvance = (getValueOfVariable("xadvance") - paddingWidth) * horizontalPerPixelSize;
+ return new Character(id, xTex, yTex, xTexSize, yTexSize, xOff, yOff, quadWidth, quadHeight, xAdvance);
+ }
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/Text/TextMaster.java b/src/main/java/net/tylermurphy/Minecraft/UI/Text/TextMaster.java
new file mode 100755
index 0000000..2616722
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/Text/TextMaster.java
@@ -0,0 +1,63 @@
+package net.tylermurphy.Minecraft.UI.Text;
+
+import java.util.ArrayList;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.tylermurphy.Minecraft.Render.FontRenderer;
+import net.tylermurphy.Minecraft.UI.UIComponent;
+import net.tylermurphy.Minecraft.UI.UIFont;
+import net.tylermurphy.Minecraft.UI.UIText;
+
+public class TextMaster {
+
+ private static Map<UIFont, List<UIText>> texts = new HashMap<UIFont, List<UIText>>();
+
+ private static void proccessText(UIText text) {
+ UIFont fontType = text.getFont();
+ List<UIText> batch = texts.get(fontType);
+ if (batch != null) {
+ batch.add(text);
+ } else {
+ List<UIText> newBatch = new ArrayList<net.tylermurphy.Minecraft.UI.UIText>();
+ newBatch.add(text);
+ texts.put(fontType, newBatch);
+ }
+ }
+
+ public static void render(List<UIComponent> components,FontRenderer fontrenderer){
+ for(UIComponent component : components) {
+ UIText text;
+ if(component instanceof UIText) {
+ text = (UIText)component;
+ } else {
+ continue;
+ }
+ loadText(text);
+ proccessText(text);
+ }
+ fontrenderer.render(TextMaster.texts);
+ TextMaster.texts.clear();
+ }
+
+ public static void loadText(UIText text){
+ UIFont font = text.getFont();
+ List<UIText> textBatch = texts.get(font);
+ if(textBatch == null){
+ textBatch = new ArrayList<UIText>();
+ texts.put(font, textBatch);
+ }
+ textBatch.add(text);
+ }
+
+ public static void removeText(UIText text){
+ List<UIText> textBatch = texts.get(text.getFont());
+ textBatch.remove(text);
+ if(textBatch.isEmpty()){
+ texts.remove(text.getFont());
+ }
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/Text/TextMeshCreator.java b/src/main/java/net/tylermurphy/Minecraft/UI/Text/TextMeshCreator.java
new file mode 100755
index 0000000..bd84abb
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/Text/TextMeshCreator.java
@@ -0,0 +1,140 @@
+package net.tylermurphy.Minecraft.UI.Text;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.tylermurphy.Minecraft.UI.UIText;
+
+public class TextMeshCreator {
+
+ protected static final double LINE_HEIGHT = 0.03f;
+ protected static final int SPACE_ASCII = 32;
+
+ private MetaFile metaData;
+
+ public TextMeshCreator(String metaFile) {
+ metaData = new MetaFile(metaFile);
+ }
+
+ public TextMeshData createTextMesh(UIText text) {
+ List<Line> lines = createStructure(text);
+ TextMeshData data = createQuadVertices(text, lines);
+ return data;
+ }
+
+ private List<Line> createStructure(UIText text) {
+ char[] chars = text.getTextString().toCharArray();
+ List<Line> lines = new ArrayList<Line>();
+ Line currentLine = new Line(metaData.getSpaceWidth(), text.getFontSize(), text.getMaxLineSize());
+ Word currentWord = new Word(text.getFontSize());
+ for (char c : chars) {
+ int ascii = (int) c;
+ if (ascii == SPACE_ASCII) {
+ boolean added = currentLine.attemptToAddWord(currentWord);
+ if (!added) {
+ lines.add(currentLine);
+ currentLine = new Line(metaData.getSpaceWidth(), text.getFontSize(), text.getMaxLineSize());
+ currentLine.attemptToAddWord(currentWord);
+ }
+ currentWord = new Word(text.getFontSize());
+ continue;
+ }
+ Character character = metaData.getCharacter(ascii);
+ currentWord.addCharacter(character);
+ }
+ completeStructure(lines, currentLine, currentWord, text);
+ return lines;
+ }
+
+ private void completeStructure(List<Line> lines, Line currentLine, Word currentWord, UIText text) {
+ boolean added = currentLine.attemptToAddWord(currentWord);
+ if (!added) {
+ lines.add(currentLine);
+ currentLine = new Line(metaData.getSpaceWidth(), text.getFontSize(), text.getMaxLineSize());
+ currentLine.attemptToAddWord(currentWord);
+ }
+ lines.add(currentLine);
+ }
+
+ private TextMeshData createQuadVertices(UIText text, List<Line> lines) {
+ text.setNumberOfLines(lines.size());
+ double curserX = 0f;
+ double curserY = 0f;
+ double maxX = 0;
+ List<Float> vertices = new ArrayList<Float>();
+ List<Float> textureCoords = new ArrayList<Float>();
+ for (Line line : lines) {
+ if (text.isCentered()) {
+ curserX = (line.getMaxLength() - line.getLineLength()) / 2;
+ }
+ for (Word word : line.getWords()) {
+ for (Character letter : word.getCharacters()) {
+ double newMaxX = addVerticesForCharacter(curserX, curserY, letter, text.getFontSize(), vertices);
+ maxX = Math.max(newMaxX, maxX);
+ addTexCoords(textureCoords, letter.getxTextureCoord(), letter.getyTextureCoord(),
+ letter.getXMaxTextureCoord(), letter.getYMaxTextureCoord());
+ curserX += letter.getxAdvance() * text.getFontSize();
+ }
+ curserX += metaData.getSpaceWidth() * text.getFontSize();
+ }
+ curserX = 0;
+ curserY += LINE_HEIGHT * text.getFontSize();
+ }
+ text.setMaxX(maxX);
+ return new TextMeshData(listToArray(vertices), listToArray(textureCoords));
+ }
+
+ private double addVerticesForCharacter(double curserX, double curserY, Character character, double fontSize,
+ List<Float> vertices) {
+ double x = curserX + (character.getxOffset() * fontSize);
+ double y = curserY + (character.getyOffset() * fontSize);
+ double maxX = x + (character.getSizeX() * fontSize);
+ double maxY = y + (character.getSizeY() * fontSize);
+ double properX = (2 * x) - 1;
+ double properY = (-2 * y) + 1;
+ double properMaxX = (2 * maxX) - 1;
+ double properMaxY = (-2 * maxY) + 1;
+ addVertices(vertices, properX, properY, properMaxX, properMaxY);
+ return maxX;
+ }
+
+ private static void addVertices(List<Float> vertices, double x, double y, double maxX, double maxY) {
+ vertices.add((float) x);
+ vertices.add((float) y);
+ vertices.add((float) x);
+ vertices.add((float) maxY);
+ vertices.add((float) maxX);
+ vertices.add((float) maxY);
+ vertices.add((float) maxX);
+ vertices.add((float) maxY);
+ vertices.add((float) maxX);
+ vertices.add((float) y);
+ vertices.add((float) x);
+ vertices.add((float) y);
+ }
+
+ private static void addTexCoords(List<Float> texCoords, double x, double y, double maxX, double maxY) {
+ texCoords.add((float) x);
+ texCoords.add((float) y);
+ texCoords.add((float) x);
+ texCoords.add((float) maxY);
+ texCoords.add((float) maxX);
+ texCoords.add((float) maxY);
+ texCoords.add((float) maxX);
+ texCoords.add((float) maxY);
+ texCoords.add((float) maxX);
+ texCoords.add((float) y);
+ texCoords.add((float) x);
+ texCoords.add((float) y);
+ }
+
+
+ private static float[] listToArray(List<Float> listOfFloats) {
+ float[] array = new float[listOfFloats.size()];
+ for (int i = 0; i < array.length; i++) {
+ array[i] = listOfFloats.get(i);
+ }
+ return array;
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/Text/TextMeshData.java b/src/main/java/net/tylermurphy/Minecraft/UI/Text/TextMeshData.java
new file mode 100755
index 0000000..2226e93
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/Text/TextMeshData.java
@@ -0,0 +1,25 @@
+package net.tylermurphy.Minecraft.UI.Text;
+
+public class TextMeshData {
+
+ private float[] vertexPositions;
+ private float[] textureCoords;
+
+ protected TextMeshData(float[] vertexPositions, float[] textureCoords){
+ this.vertexPositions = vertexPositions;
+ this.textureCoords = textureCoords;
+ }
+
+ public float[] getVertexPositions() {
+ return vertexPositions;
+ }
+
+ public float[] getTextureCoords() {
+ return textureCoords;
+ }
+
+ public int getVertexCount() {
+ return vertexPositions.length/2;
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/Text/Word.java b/src/main/java/net/tylermurphy/Minecraft/UI/Text/Word.java
new file mode 100755
index 0000000..9256619
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/Text/Word.java
@@ -0,0 +1,29 @@
+package net.tylermurphy.Minecraft.UI.Text;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Word {
+
+ private List<Character> characters = new ArrayList<Character>();
+ private double width = 0;
+ private double fontSize;
+
+ protected Word(double fontSize){
+ this.fontSize = fontSize;
+ }
+
+ protected void addCharacter(Character character){
+ characters.add(character);
+ width += character.getxAdvance() * fontSize;
+ }
+
+ protected List<Character> getCharacters(){
+ return characters;
+ }
+
+ protected double getWordWidth(){
+ return width;
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/UI.java b/src/main/java/net/tylermurphy/Minecraft/UI/UI.java
new file mode 100755
index 0000000..1f1f1e0
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/UI.java
@@ -0,0 +1,38 @@
+package net.tylermurphy.Minecraft.UI;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class UI {
+
+ public boolean enabled = true;
+
+ protected List<UIComponent> children = new ArrayList<UIComponent>();
+
+ protected UIComponent findKey(String key) {
+ for(UIComponent component : children) {
+ UIComponent c = component.findKey(key);
+ if(c!=null) return c;
+ }
+ return null;
+ }
+
+ protected UIText findText(String key) {
+ return (UIText) findKey(key);
+ }
+
+ protected UIImage findImage(String key) {
+ return (UIImage) findKey(key);
+ }
+
+ protected void add(UIComponent component) {
+ children.add(component);
+ };
+
+ protected void prepare() {
+ if(!enabled) return;
+ for(UIComponent component : children)
+ component.prepare(null);
+ }
+
+ } \ No newline at end of file
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/UIComponent.java b/src/main/java/net/tylermurphy/Minecraft/UI/UIComponent.java
new file mode 100755
index 0000000..ffe39eb
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/UIComponent.java
@@ -0,0 +1,104 @@
+package net.tylermurphy.Minecraft.UI;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.joml.Matrix4f;
+import org.joml.Vector2f;
+import org.joml.Vector4f;
+
+import net.tylermurphy.Minecraft.Render.Data.Display;
+import net.tylermurphy.Minecraft.Util.Maths;
+
+public abstract class UIComponent {
+
+ private List<UIComponent> children = new ArrayList<UIComponent>();
+
+ private Vector4f size = new Vector4f(0,100,0,100);
+ private Vector4f position = new Vector4f(0,0,0,0);
+
+ protected boolean enabled = true;
+
+ private String key;
+
+ private int zIndex = 1;
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public int getZIndex() {
+ return zIndex;
+ }
+
+ public void setZIndex(int zIndex) {
+ this.zIndex = zIndex;
+ }
+
+ public UIComponent findKey(String key) {
+ if(this.key != null && this.key.equals(key)) return this;
+ for(UIComponent component : children) {
+ UIComponent c = component.findKey(key);
+ if(c!=null) return c;
+ }
+ return null;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ };
+
+ public void add(UIComponent component) {
+ children.add(component);
+ };
+
+ protected List<UIComponent> getComponents() {
+ return children;
+ };
+
+ public void prepare(UIComponent parent) {
+ if(this.enabled) UIMaster.componentBatch.add(this);
+ for(UIComponent component : children) {
+ component.prepare(component);
+ }
+ }
+
+ public void setSize(float xScale, float xOffset, float yScale, float yOffset) {
+ this.size = new Vector4f(xScale,xOffset,yScale,yOffset);
+ }
+
+ public Vector4f getSize() {
+ return size;
+ }
+
+ public void setPosition(float xScale, float xOffset, float yScale, float yOffset) {
+ this.position = new Vector4f(xScale,xOffset,yScale,yOffset);
+ }
+
+ public Vector4f getPosition() {
+ return position;
+ }
+
+ public Vector2f getConvertedSize() {
+ return new Vector2f(
+ size.x + size.y/Display.getWidth(),
+ size.z + size.w/Display.getHeight()
+ );
+ }
+
+ public Vector2f getConvertedPosition() {
+ return new Vector2f(
+ (position.x + position.y/Display.getWidth()),
+ (position.w/Display.getHeight() + position.z)
+ );
+ }
+
+ public Matrix4f getMatrix() {
+ return Maths.createTransformationMatrix(new Vector2f(getConvertedPosition().x*2-1,getConvertedPosition().y*2-1), getConvertedSize());
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/CommandUI.java b/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/CommandUI.java
new file mode 100755
index 0000000..259958a
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/CommandUI.java
@@ -0,0 +1,23 @@
+package net.tylermurphy.Minecraft.UI.UIFactory;
+
+import static net.tylermurphy.Minecraft.UI.UIMaster.*;
+
+import net.tylermurphy.Minecraft.UI.UIText;
+
+public class CommandUI {
+
+ public static void initCommandUI() {
+
+
+ createUI(3);
+ setEnabled(false);
+
+ UIText commandBar = new UIText("/",1,UIStore.FONTS.get("yugothic"),1000,false);
+ commandBar.setPosition(0, 0, 1-.1f, 0);
+ commandBar.setKey("commandBar");
+ commandBar.setStretchBackdrop(true);
+
+ add(commandBar);
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/CoreUI.java b/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/CoreUI.java
new file mode 100755
index 0000000..ec9ff74
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/CoreUI.java
@@ -0,0 +1,76 @@
+package net.tylermurphy.Minecraft.UI.UIFactory;
+
+import static net.tylermurphy.Minecraft.UI.UIMaster.add;
+import static net.tylermurphy.Minecraft.UI.UIMaster.createUI;
+
+import net.tylermurphy.Minecraft.UI.UIImage;
+import net.tylermurphy.Minecraft.UI.UIText;
+
+public class CoreUI {
+
+ public static void initCoreUI() {
+
+ createUI(0);
+ UIImage image = new UIImage();
+ image.setTexture(UIStore.TEXTURES.get("crosshair"));
+ image.setPosition(.5f, -15f, .5f, -15f);
+ image.setSize(0, 30, 0, 30);
+ image.setKey("crosshair");
+ UIImage heart1 = new UIImage();
+ heart1.setTexture(UIStore.TEXTURES.get("heart_full_texture"));
+ heart1.setPosition(0, 20, 1f, -20);
+ heart1.setSize(0, 20, 0, 20);
+ heart1.setKey("heart1");
+ UIImage heart2 = new UIImage();
+ heart2.setTexture(UIStore.TEXTURES.get("heart_full_texture"));
+ heart2.setPosition(0, 50, 1f, -20);
+ heart2.setSize(0, 20, 0, 20);
+ heart2.setKey("heart2");
+ UIImage heart3 = new UIImage();
+ heart3.setTexture(UIStore.TEXTURES.get("heart_full_texture"));
+ heart3.setPosition(0, 80, 1f, -20);
+ heart3.setSize(0, 20, 0, 20);
+ heart3.setKey("heart3");
+ UIImage heart4 = new UIImage();
+ heart4.setTexture(UIStore.TEXTURES.get("heart_full_texture"));
+ heart4.setPosition(0, 110, 1f, -20);
+ heart4.setSize(0, 20, 0, 20);
+ heart4.setKey("heart4");
+ UIImage heart5 = new UIImage();
+ heart5.setTexture(UIStore.TEXTURES.get("heart_full_texture"));
+ heart5.setPosition(0, 140, 1f, -20);
+ heart5.setSize(0, 20, 0, 20);
+ heart5.setKey("heart5");
+ UIImage heart6 = new UIImage();
+ heart6.setTexture(UIStore.TEXTURES.get("heart_full_texture"));
+ heart6.setPosition(0, 170, 1f, -20);
+ heart6.setSize(0, 20, 0, 20);
+ heart6.setKey("heart6");
+ UIImage heart7 = new UIImage();
+ heart7.setTexture(UIStore.TEXTURES.get("heart_full_texture"));
+ heart7.setPosition(0, 200, 1f, -20);
+ heart7.setSize(0, 20, 0, 20);
+ heart7.setKey("heart7");
+ UIImage heart8 = new UIImage();
+ heart8.setTexture(UIStore.TEXTURES.get("heart_full_texture"));
+ heart8.setPosition(0, 230, 1f, -20);
+ heart8.setSize(0, 20, 0, 20);
+ heart8.setKey("heart8");
+ UIImage heart9 = new UIImage();
+ heart9.setTexture(UIStore.TEXTURES.get("heart_full_texture"));
+ heart9.setPosition(0, 260, 1f, -20);
+ heart9.setSize(0, 20, 0, 20);
+ heart9.setKey("heart9");
+ UIImage heart10 = new UIImage();
+ heart10.setTexture(UIStore.TEXTURES.get("heart_full_texture"));
+ heart10.setPosition(0, 290, 1f, -20);
+ heart10.setSize(0, 20, 0, 20);
+ heart10.setKey("heart10");
+ UIText dead = new UIText("You have died, press k to respawn.",1,UIStore.FONTS.get("yugothic"),1000,false);
+ dead.setPosition(0.4f, 0, .5f, -20);
+ dead.setKey("dead");
+ dead.setEnabled(false);
+ add(image,heart1,heart2,heart3,heart4,heart5,heart6,heart7,heart8,heart9,heart10,dead);
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/F3UI.java b/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/F3UI.java
new file mode 100755
index 0000000..3ec7d84
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/F3UI.java
@@ -0,0 +1,53 @@
+package net.tylermurphy.Minecraft.UI.UIFactory;
+
+import static net.tylermurphy.Minecraft.UI.UIMaster.add;
+import static net.tylermurphy.Minecraft.UI.UIMaster.createUI;
+import static net.tylermurphy.Minecraft.UI.UIMaster.setEnabled;
+
+import net.tylermurphy.Minecraft.Render.Data.Texture;
+import net.tylermurphy.Minecraft.UI.UIFont;
+import net.tylermurphy.Minecraft.UI.UIText;
+
+public class F3UI {
+
+ public static void initF3UI() {
+
+ createUI(1);
+ setEnabled(false);
+
+ String maxMem = "Max memory (bytes): " + Runtime.getRuntime().maxMemory();
+ String freeMem = "Free memory (bytes): " + Runtime.getRuntime().freeMemory();
+ String allocMem = "Allocated memory (bytes): " + Runtime.getRuntime().totalMemory();
+ String cores = "Available processors (cores): "+ Runtime.getRuntime().availableProcessors();
+
+ UIText maxMemText = new UIText(maxMem,1,UIStore.FONTS.get("yugothic"),1000,false);
+ maxMemText.setPosition(0, 0, .125f, 0);
+ UIText freeMemText = new UIText(freeMem,1,UIStore.FONTS.get("yugothic"),1000,false);
+ freeMemText.setPosition(0, 0, .15f, 0);
+ freeMemText.setKey("freemem");
+ UIText allocMemText = new UIText(allocMem,1,UIStore.FONTS.get("yugothic"),1000,false);
+ allocMemText.setPosition(0, 0, .175f, 0);
+ UIText coresText = new UIText(cores,1,UIStore.FONTS.get("yugothic"),1000,false);
+ coresText.setPosition(0, 0, .2f, .2f);
+
+ UIText position = new UIText("",1,UIStore.FONTS.get("yugothic"),1000,false);
+ position.setPosition(0, 0, 0, 0);
+ position.setKey("position");
+ UIText rotation = new UIText("",1,UIStore.FONTS.get("yugothic"),1000,false);
+ rotation.setPosition(0, 0, .025f, 0);
+ rotation.setKey("rotation");
+ UIText fps = new UIText("",1,UIStore.FONTS.get("yugothic"),1000,false);
+ fps.setPosition(0, 0, .05f, 0);
+ fps.setKey("fps");
+ UIText tps = new UIText("",1,UIStore.FONTS.get("yugothic"),1000,false);
+ tps.setPosition(0, 0, 0.075f, 0);
+ tps.setKey("tps");
+
+ UIText block = new UIText("Block Selected: minecraft:dirt",1,UIStore.FONTS.get("yugothic"),1000,false);
+ block.setPosition(0, 0, .25f, 0);
+ block.setKey("block");
+
+ add(maxMemText,freeMemText,allocMemText,coresText,position,rotation,fps,block,tps);
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/SavingUI.java b/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/SavingUI.java
new file mode 100755
index 0000000..7826e4a
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/SavingUI.java
@@ -0,0 +1,17 @@
+package net.tylermurphy.Minecraft.UI.UIFactory;
+
+import static net.tylermurphy.Minecraft.UI.UIMaster.*;
+
+import net.tylermurphy.Minecraft.UI.UIText;
+
+public class SavingUI {
+
+ public static void initSavingUI() {
+ createUI(2);
+ UIText saving = new UIText("Saving...",1,UIStore.FONTS.get("yugothic"),1000,false);
+ saving.setPosition(0.5f, -50, 0.5f, -20);
+ add(saving);
+ setEnabled(false);
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/UIStore.java b/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/UIStore.java
new file mode 100755
index 0000000..b4c7c8a
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/UIFactory/UIStore.java
@@ -0,0 +1,24 @@
+package net.tylermurphy.Minecraft.UI.UIFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.tylermurphy.Minecraft.Render.Data.Texture;
+import net.tylermurphy.Minecraft.UI.UIFont;
+
+public class UIStore {
+
+ public static Map<String,Integer> TEXTURES = new HashMap<String,Integer>();
+ public static Map<String,UIFont> FONTS = new HashMap<String,UIFont>();
+
+ public static void InitalizeStoreData() {
+
+ FONTS.put("yugothic", new UIFont(Texture.loadFontAtlas("font/yugothic"),"yugothic"));
+ TEXTURES.put("heart_full_texture",Texture.loadTexture("gui/heart_full"));
+ TEXTURES.put("heart_half_texture",Texture.loadTexture("gui/heart_half"));
+ TEXTURES.put("heart_empty_texture",Texture.loadTexture("gui/heart_empty"));
+ TEXTURES.put("crosshair",Texture.loadTexture("gui/crosshair"));
+
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/UIFont.java b/src/main/java/net/tylermurphy/Minecraft/UI/UIFont.java
new file mode 100755
index 0000000..6f93b37
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/UIFont.java
@@ -0,0 +1,31 @@
+package net.tylermurphy.Minecraft.UI;
+
+import net.tylermurphy.Minecraft.Render.Data.Texture;
+import net.tylermurphy.Minecraft.UI.Text.TextMeshCreator;
+import net.tylermurphy.Minecraft.UI.Text.TextMeshData;
+
+public class UIFont {
+
+ private int textureAtlas;
+ private TextMeshCreator loader;
+
+
+ public UIFont(int textureAtlas, String fontFile) {
+ this.textureAtlas = textureAtlas;
+ this.loader = new TextMeshCreator(fontFile);
+ }
+
+ public UIFont(String font) {
+ this.textureAtlas = Texture.loadFontAtlas(font);
+ this.loader = new TextMeshCreator(font);
+ }
+
+ public int getTextureAtlas() {
+ return textureAtlas;
+ }
+
+ public TextMeshData loadText(UIText text) {
+ return loader.createTextMesh(text);
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/UIImage.java b/src/main/java/net/tylermurphy/Minecraft/UI/UIImage.java
new file mode 100755
index 0000000..7e772ab
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/UIImage.java
@@ -0,0 +1,30 @@
+package net.tylermurphy.Minecraft.UI;
+
+import org.joml.Vector2f;
+
+import net.tylermurphy.Minecraft.Render.Data.Display;
+
+public class UIImage extends UIComponent {
+
+ private int texture;
+
+ public void setTexture(int texture) {
+ this.texture = texture;
+ }
+
+ public int getTexture() {
+ return texture;
+ }
+
+ public boolean clicked() {
+ Vector2f pos = Display.getCursorPos();
+ float x1 = super.getConvertedPosition().x*Display.getWidth();
+ float y1 = super.getConvertedPosition().y*Display.getHeight();
+ float x2 = super.getConvertedPosition().x*Display.getWidth()+super.getConvertedSize().x*Display.getWidth();
+ float y2 = super.getConvertedPosition().y*Display.getHeight()+super.getConvertedSize().y*Display.getHeight();
+ if(pos.x >= x1 && pos.x <= x2 && pos.y >= y1 && pos.y <= y2)
+ return true;
+ return false;
+ }
+
+}
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/UILayerQuickSort.java b/src/main/java/net/tylermurphy/Minecraft/UI/UILayerQuickSort.java
new file mode 100755
index 0000000..6355347
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/UILayerQuickSort.java
@@ -0,0 +1,38 @@
+package net.tylermurphy.Minecraft.UI;
+
+import java.util.List;
+
+public class UILayerQuickSort {
+
+ public static void quickSort(List<UIComponent> arr, int start, int end){
+
+ int partition = partition(UIMaster.componentBatch, start, end);
+
+ if(partition-1>start) {
+ quickSort(UIMaster.componentBatch, start, partition - 1);
+ }
+ if(partition+1<end) {
+ quickSort(UIMaster.componentBatch, partition + 1, end);
+ }
+ }
+
+ public static int partition(List<UIComponent> arr, int start, int end){
+
+ UIComponent pivot = arr.get(end);
+
+ for(int i=start; i<end; i++){
+ if(arr.get(i).getZIndex()<pivot.getZIndex()){
+ UIComponent temp= arr.get(start);
+ arr.set(start, arr.get(i));
+ arr.set(i, temp);
+ start++;
+ }
+ }
+
+ UIComponent temp = arr.get(start);
+ arr.set(start, pivot);
+ arr.set(end, temp);
+
+ return start;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/UIMaster.java b/src/main/java/net/tylermurphy/Minecraft/UI/UIMaster.java
new file mode 100755
index 0000000..8709aab
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/UIMaster.java
@@ -0,0 +1,65 @@
+package net.tylermurphy.Minecraft.UI;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.tylermurphy.Minecraft.Render.FontRenderer;
+import net.tylermurphy.Minecraft.Render.GuiRenderer;
+import net.tylermurphy.Minecraft.UI.Text.TextMaster;
+
+public class UIMaster {
+
+ private static List<UI> uis = new ArrayList<UI>();
+ private static int bindedID = 0;
+ protected static List<UIComponent> componentBatch = new ArrayList<UIComponent>();
+
+ public static void createUI(int id) {
+ uis.add(id,new UI());
+ bindedID = id;
+ }
+
+ private static UI getUI() {
+ return uis.get(bindedID);
+ }
+
+ public static void add(UIComponent... components) {
+ for(UIComponent component : components) {
+ getUI().add(component);
+ }
+ }
+
+ public static UIImage getImage(String key) {
+ return (UIImage) getUI().findKey(key);
+ }
+
+ public static UIText getText(String key) {
+ return (UIText) getUI().findKey(key);
+ }
+
+ public static void bindUI(int id) {
+ bindedID = id;
+ }
+
+ public static void setEnabled(boolean value) {
+ getUI().enabled = value;
+ }
+
+ public static boolean isEnabled() {
+ return getUI().enabled;
+ }
+
+ public static void renderUI(GuiRenderer renderer, FontRenderer fontrenderer) {
+ for(UI ui : uis) {
+ if(!ui.enabled) continue;
+ ui.prepare();
+ }
+ try{
+ UILayerQuickSort.quickSort(componentBatch, 0, componentBatch.size()-1);
+ } catch (Exception ignore) {}
+ renderer.render(componentBatch);
+ TextMaster.render(componentBatch,fontrenderer);
+ componentBatch.clear();
+ }
+
+}
+
diff --git a/src/main/java/net/tylermurphy/Minecraft/UI/UIText.java b/src/main/java/net/tylermurphy/Minecraft/UI/UIText.java
new file mode 100755
index 0000000..fa2e0bc
--- /dev/null
+++ b/src/main/java/net/tylermurphy/Minecraft/UI/UIText.java
@@ -0,0 +1,110 @@
+package net.tylermurphy.Minecraft.UI;
+
+import net.tylermurphy.Minecraft.Render.Data.Mesh;
+import org.joml.Vector3f;
+
+import net.tylermurphy.Minecraft.UI.Text.TextMaster;
+import net.tylermurphy.Minecraft.UI.Text.TextMeshData;
+
+public class UIText extends UIComponent{
+
+ private String textString;
+ private final float fontSize;
+
+ private final Vector3f colour = new Vector3f(255f, 255f, 255f);
+
+ private final float lineMaxSize;
+ private int numberOfLines;
+ private double maxX;
+
+ private final UIFont font;
+
+ private final boolean centerText;
+ private boolean stretchBackdrop = false;
+
+ private Mesh mesh;
+
+ public UIText(String text, float fontSize, UIFont font, float maxLineLength ,boolean centered) {
+ this.textString = text;
+ this.fontSize = fontSize;
+ this.font = font;
+ this.lineMaxSize = maxLineLength;
+ this.centerText = centered;
+ TextMeshData data = font.loadText(this);
+ this.mesh = new Mesh(data.getVertexPositions().length).store(data.getVertexPositions(), 2).store(data.getTextureCoords(), 2).finish();
+ TextMaster.loadText(this);
+ }
+
+ public void remove() {
+ TextMaster.removeText(this);
+ }
+
+ public UIFont getFont() {
+ return font;
+ }
+
+ public void setColour(float r, float g, float b) {
+ colour.set(r, g, b);
+ }
+
+ public Vector3f getColour() {
+ return colour;
+ }
+
+ public int getNumberOfLines() {
+ return numberOfLines;
+ }
+
+ public int getMesh() {
+ return mesh.getID();
+ }
+
+ public int getVertexCount() {
+ return mesh.getVertexCount();
+ }
+
+ public float getFontSize() {
+ return fontSize;
+ }
+
+ public void setNumberOfLines(int number) {
+ this.numberOfLines = number;
+ }
+
+ public boolean isCentered() {
+ return centerText;
+ }
+
+ public float getMaxLineSize() {
+ return lineMaxSize;
+ }
+
+ public String getTextString() {
+ return textString;
+ }
+
+ public void setText(String textString) {
+ this.textString = textString;
+
+ mesh.delete();
+ TextMeshData data = font.loadText(this);
+ this.mesh = new Mesh(data.getVertexPositions().length).store(data.getVertexPositions(), 2).store(data.getTextureCoords(), 2).finish();
+ }
+
+ public void setMaxX(double maxX) {
+ this.maxX = maxX;
+ }
+
+ public double getMaxX() {
+ return maxX;
+ }
+
+ public void setStretchBackdrop(boolean stretchBackdrop) {
+ this.stretchBackdrop = stretchBackdrop;
+ }
+
+ public boolean getStretchBackdrop() {
+ return this.stretchBackdrop;
+ }
+
+}