package electrosphere.renderer.ui.elements; import electrosphere.main.Globals; import electrosphere.renderer.Material; import electrosphere.renderer.Model; import electrosphere.engine.assetmanager.AssetDataStrings; import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.FramebufferUtils; import electrosphere.renderer.texture.Texture; import electrosphere.renderer.ui.DrawableElement; import electrosphere.renderer.ui.FocusableElement; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.events.FocusEvent; import electrosphere.renderer.ui.font.FontUtils; import org.joml.Vector3f; import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER; import static org.lwjgl.opengl.GL30.glBindFramebuffer; /** * * @author amaterasu */ public class TextInput implements DrawableElement, FocusableElement { Framebuffer widgetBuffer; Material customMat = new Material(); Vector3f boxPosition = new Vector3f(0,0,0); Vector3f boxDimensions = new Vector3f(1,1,0); Vector3f texPosition = new Vector3f(0,0,0); Vector3f texScale = new Vector3f(1,1,0); String text = ""; int fontWidth = 10; int fontHeight = 20; int linePaddingHorizonal = 2; int linePaddingVertical = 5; boolean focused = false; FocusEventCallback onFocusCallback = null; FocusEventCallback onLoseFocusCallback = null; Vector3f color = new Vector3f(0,0,0); public TextInput(int positionX, int positionY, int width, int height){ //TODO: figure out why this has to be 1920x1080 // widgetBuffer = FramebufferUtils.generateTextureFramebuffer(500, 500); widgetBuffer = FramebufferUtils.generateScreensizeTextureFramebuffer(); customMat.setTexturePointer(widgetBuffer.getTexturePointer()); // customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer()); // customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/default_diffuse.png").getTexturePointer()); setPositionX(positionX); setPositionY(positionY); setWidth(width); setHeight(height); } @Override public void setPositionY(int positionY) { float ndcY = (float)positionY/(float)Globals.WINDOW_HEIGHT; boxPosition.y = ndcY; this.positionY = positionY; } @Override public void setPositionX(int positionX) { float ndcX = (float)positionX/(float)Globals.WINDOW_WIDTH; boxPosition.x = ndcX; this.positionX = positionX; } @Override public void setHeight(int height) { float ndcHeight = (float)height/(float)parentHeight; boxDimensions.y = ndcHeight; Framebuffer newBuffer = FramebufferUtils.generateTextureFramebuffer(width, height); Framebuffer oldBuffer = widgetBuffer; widgetBuffer = newBuffer; customMat.setTexturePointer(widgetBuffer.getTexturePointer()); oldBuffer.free(); // customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer()); this.height = height; } @Override public void setWidth(int width) { float ndcWidth = (float)width/(float)parentWidth; boxDimensions.x = ndcWidth; Framebuffer newBuffer = FramebufferUtils.generateTextureFramebuffer(width, height); Framebuffer oldBuffer = widgetBuffer; widgetBuffer = newBuffer; customMat.setTexturePointer(widgetBuffer.getTexturePointer()); oldBuffer.free(); // widgetBuffer = FramebufferUtils.generateTextureFramebuffer(width, height); // customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer()); this.width = width; } @Override public void setParentWidth(int parentWidth){ this.parentWidth = parentWidth; } @Override public void setParentHeight(int parentHeight){ this.parentHeight = parentHeight; } public void setFontWidth(int width){ fontWidth = width; } public void setFontHeight(int height){ fontHeight = height; } public int getFontWidth(){ return fontWidth; } public int getFontHeight(){ return fontHeight; } public String getText(){ return text; } public void setText(String text){ this.text = text; } @Override public void draw(int parentFramebufferPointer, int parentWidth, int parentHeight) { widgetBuffer.bind(); Globals.renderingEngine.setViewportSize(width, height); //monowidth for the moment float charWidth = (float)fontWidth/(float)width; float charHeight = (float)fontHeight/(float)height; float charSpacing = (float)linePaddingHorizonal/(float)width; float lineSpacing = (float)linePaddingVertical/(float)height; Model charModel = Globals.assetManager.fetchModel(AssetDataStrings.ASSET_STRING_BITMAP_FONT); int verticalPosition = 0; int horizontalPosition = 0; int charPos = 0; while(charPos < text.length()){ char currentChar = text.charAt(charPos); if(currentChar == '\n'){ verticalPosition++; horizontalPosition = 0; } else { Vector3f characterPosition = new Vector3f(horizontalPosition * (charWidth + charSpacing),-verticalPosition * (charHeight + lineSpacing),0); Vector3f characterDimensions = new Vector3f(charWidth,charHeight,0); Vector3f bitMapPosition = FontUtils.getPositionOfCharacter(currentChar); Vector3f bitMapDimension = FontUtils.getDimensionOfCharacter(currentChar); if(charModel != null && currentChar != ' '){ charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "mPosition", characterPosition); charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "mDimension", characterDimensions); charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "tPosition", bitMapPosition); charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "tDimension", bitMapDimension); charModel.pushUniformToMesh(AssetDataStrings.ASSET_STRING_BITMAP_FONT_MESH_NAME, "color", color); charModel.drawUI(); } horizontalPosition++; } charPos++; } //draw the previous texture to a quad Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer); Globals.renderingEngine.setViewportSize(parentWidth, parentHeight); Model planeModel = Globals.assetManager.fetchModel(Globals.planeModelID); planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "tPosition", new Vector3f(0,0,0)); planeModel.pushUniformToMesh("plane", "tDimension", new Vector3f(1,1,0)); planeModel.meshes.get(0).setMaterial(customMat); planeModel.drawUI(); } public int width = 1; public int height = 1; public int positionX = 0; public int positionY = 0; public int parentWidth = 1; public int parentHeight = 1; public boolean visible = false; public int getWidth() { return width; } public int getHeight() { return height; } public int getPositionX() { return positionX; } public int getPositionY() { return positionY; } public boolean getVisible() { return visible; } public void setVisible(boolean draw) { this.visible = draw; } public boolean handleEvent(Event event){ boolean propagate = true; if(event instanceof FocusEvent){ this.focused = ((FocusEvent)event).isFocused(); if(this.focused && onFocusCallback != null){ propagate = onFocusCallback.execute((FocusEvent)event); } else if(!this.focused && onLoseFocusCallback != null){ propagate = onLoseFocusCallback.execute((FocusEvent)event); } } return propagate; } @Override public boolean isFocused() { // TODO Auto-generated method stub return focused; } @Override public void setOnFocus(FocusEventCallback callback) { // TODO Auto-generated method stub onFocusCallback = callback; } @Override public void setOnLoseFocus(FocusEventCallback callback) { // TODO Auto-generated method stub onLoseFocusCallback = callback; } }