From e6d946db53893d2b3e3b39dbe1bf268f3e398b5f Mon Sep 17 00:00:00 2001 From: austin Date: Tue, 17 Sep 2024 16:53:36 -0400 Subject: [PATCH] gut old ui handling of positioning --- .../Shaders/ui/font/bitmapchar/bitmapchar.vs | 2 +- buildNumber.properties | 4 +- docs/src/progress/renderertodo.md | 3 + .../controls/ControlHandler.java | 4 +- .../menu/debug/ImGuiUIFramework.java | 1 - .../mainmenu/MenuGeneratorsLevelEditor.java | 6 +- .../mainmenu/MenuGeneratorsUITesting.java | 4 + .../electrosphere/renderer/RenderUtils.java | 12 +- .../renderer/debug/DebugRendering.java | 20 +- .../renderer/framebuffer/Framebuffer.java | 28 +++ .../renderer/pipelines/UIPipeline.java | 6 +- .../renderer/ui/ElementService.java | 29 ++- .../ui/components/NaturalInventoryPanel.java | 218 +++++++++--------- .../ui/components/PlayerInventoryWindow.java | 4 +- .../renderer/ui/elements/ActorPanel.java | 43 +--- .../renderer/ui/elements/BitmapCharacter.java | 56 +---- ...feredStandardDrawableContainerElement.java | 49 ++-- .../renderer/ui/elements/Button.java | 38 ++- .../renderer/ui/elements/Div.java | 23 +- .../renderer/ui/elements/FormElement.java | 12 +- .../renderer/ui/elements/ImagePanel.java | 29 +-- .../renderer/ui/elements/Label.java | 41 +--- .../ui/elements/ScrollableContainer.java | 58 ++--- .../renderer/ui/elements/Slider.java | 58 +++-- .../ui/elements/StandardContainerElement.java | 154 +------------ .../StandardDrawableContainerElement.java | 3 +- .../ui/elements/StandardDrawableElement.java | 3 +- .../renderer/ui/elements/StandardElement.java | 132 ++++++----- .../renderer/ui/elements/StringCarousel.java | 13 +- .../renderer/ui/elements/TextBox.java | 17 +- .../renderer/ui/elements/TextInput.java | 26 +-- .../renderer/ui/elements/ToggleInput.java | 39 ++-- .../ui/elements/VirtualScrollable.java | 39 +--- .../renderer/ui/elements/Window.java | 218 ++++++++---------- .../renderer/ui/elements/Word.java | 17 +- .../ui/elementtypes/DrawableElement.java | 9 +- .../renderer/ui/elementtypes/Element.java | 30 +-- .../ui/elements/BitmapCharacterTests.java | 28 +++ .../renderer/ui/elements/ButtonTests.java | 3 +- .../renderer/ui/elements/ImagePanelTests.java | 16 ++ .../java/renderer/ui/elements/bitmapchar1.png | Bin 0 -> 10788 bytes 41 files changed, 597 insertions(+), 898 deletions(-) create mode 100644 src/test/java/electrosphere/renderer/ui/elements/BitmapCharacterTests.java create mode 100644 test/java/renderer/ui/elements/bitmapchar1.png diff --git a/assets/Shaders/ui/font/bitmapchar/bitmapchar.vs b/assets/Shaders/ui/font/bitmapchar/bitmapchar.vs index 9246ac38..b918d70e 100644 --- a/assets/Shaders/ui/font/bitmapchar/bitmapchar.vs +++ b/assets/Shaders/ui/font/bitmapchar/bitmapchar.vs @@ -15,7 +15,7 @@ void main(){ vec2 finalPos = vec2( ((aPos.x + 1)/2 * mDimension.x + mPosition.x) * 2 - 1, - ((aPos.y + 1)/2 * -mDimension.y + mPosition.y) * 2 - 1 + ((aPos.y + 1)/2 * mDimension.y + (1 - mDimension.y) - mPosition.y) * 2 - 1 ); gl_Position = vec4(finalPos.x, finalPos.y, 0.0, 1.0); diff --git a/buildNumber.properties b/buildNumber.properties index 6d159426..97453e56 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Mon Sep 16 18:21:53 EDT 2024 -buildNumber=331 +#Mon Sep 16 19:58:57 EDT 2024 +buildNumber=333 diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index fa8e9ad9..181eb7d7 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -780,6 +780,9 @@ Component-ify natural and equip inventory menus Post Processing Pipeline w/ blur Blur on open inventory/main menu in game +(09/17/2024) +Framebuffer position drilling + # TODO diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java index 54eea293..499192ec 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -1244,8 +1244,8 @@ public class ControlHandler { menuNavigationControlList.add(controls.get(DATA_STRING_INPUT_CODE_MENU_SELECT)); controls.get(DATA_STRING_INPUT_CODE_MENU_SELECT).setOnPress(new ControlMethod(){public void execute(){ Globals.elementService.click(new ClickEvent( - Globals.elementService.getFocusedElement().getInternalX() + 1, - Globals.elementService.getFocusedElement().getInternalY() + 1, + Globals.elementService.getFocusedElement().getAbsoluteX() + 1, + Globals.elementService.getFocusedElement().getAbsoluteY() + 1, true, Globals.mouseCallback.getButton(GLFW_MOUSE_BUTTON_2) )); diff --git a/src/main/java/electrosphere/menu/debug/ImGuiUIFramework.java b/src/main/java/electrosphere/menu/debug/ImGuiUIFramework.java index 85dc400f..59d889ec 100644 --- a/src/main/java/electrosphere/menu/debug/ImGuiUIFramework.java +++ b/src/main/java/electrosphere/menu/debug/ImGuiUIFramework.java @@ -77,7 +77,6 @@ public class ImGuiUIFramework { } else { LoggerInterface.loggerUI.WARNING(indentStr + "--" + rootEl + "--"); - LoggerInterface.loggerUI.WARNING(indentStr + rootEl.getInternalX() + " " + rootEl.getInternalY() + " " + rootEl.getInternalWidth() + " " + rootEl.getInternalHeight()); LoggerInterface.loggerUI.WARNING(indentStr + rootEl.getAbsoluteX() + " " + rootEl.getAbsoluteY() + " " + rootEl.getWidth() + " " + rootEl.getHeight()); LoggerInterface.loggerUI.WARNING("\n"); } diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsLevelEditor.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsLevelEditor.java index 08ec578b..21a22107 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsLevelEditor.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsLevelEditor.java @@ -41,7 +41,7 @@ public class MenuGeneratorsLevelEditor { rVal.setJustifyContent(YogaJustification.Start); //left-right rVal.setAlignItems(YogaAlignment.Center); - rVal.setAlignContent(YogaAlignment.Start); + rVal.setAlignContent(YogaAlignment.Center); // @@ -66,7 +66,9 @@ public class MenuGeneratorsLevelEditor { WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorCreationMenu()); }); createLevelButton.setMarginBottom(30); - rVal.addChild(createLevelButton); + Div createWrapper = Div.createDiv(); + createWrapper.addChild(createLevelButton); + rVal.addChild(createWrapper); // diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsUITesting.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsUITesting.java index 0c6afee7..dbf39fd6 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsUITesting.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsUITesting.java @@ -54,6 +54,7 @@ public class MenuGeneratorsUITesting { Arrays.asList(new String[]{ "Generic", "Slider", + "Button", "CharacterCustomizer", "NaturalInventoryPanel", "EquipInventoryPanel", @@ -115,6 +116,9 @@ public class MenuGeneratorsUITesting { formEl.addChild(Slider.createSlider((ValueChangeEvent event) -> { })); } break; + case "Button": { + formEl.addChild(Button.createButton("test", () -> {})); + } break; case "CharacterCustomizer": { formEl.addChild(CharacterCustomizer.createCharacterCustomizerPanel("human")); } break; diff --git a/src/main/java/electrosphere/renderer/RenderUtils.java b/src/main/java/electrosphere/renderer/RenderUtils.java index 3de45f88..c33074bd 100644 --- a/src/main/java/electrosphere/renderer/RenderUtils.java +++ b/src/main/java/electrosphere/renderer/RenderUtils.java @@ -647,22 +647,22 @@ public class RenderUtils { //texture coords FloatBuffer textureArrayBufferData = BufferUtils.createFloatBuffer(12); textureArrayBufferData.put(0); - textureArrayBufferData.put(1); - - textureArrayBufferData.put(0); - textureArrayBufferData.put(0); - - textureArrayBufferData.put(1); textureArrayBufferData.put(0); textureArrayBufferData.put(0); textureArrayBufferData.put(1); textureArrayBufferData.put(1); + textureArrayBufferData.put(1); + + textureArrayBufferData.put(0); textureArrayBufferData.put(0); textureArrayBufferData.put(1); textureArrayBufferData.put(1); + + textureArrayBufferData.put(1); + textureArrayBufferData.put(0); textureArrayBufferData.flip(); diff --git a/src/main/java/electrosphere/renderer/debug/DebugRendering.java b/src/main/java/electrosphere/renderer/debug/DebugRendering.java index 3ed7a626..42686812 100644 --- a/src/main/java/electrosphere/renderer/debug/DebugRendering.java +++ b/src/main/java/electrosphere/renderer/debug/DebugRendering.java @@ -11,7 +11,7 @@ import org.joml.Vector3f; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.model.Model; import electrosphere.renderer.shader.ShaderProgram; import electrosphere.renderer.ui.elements.ImagePanel; @@ -36,8 +36,6 @@ public class DebugRendering { glDisable(GL_DEPTH_TEST); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - int parentPosX = 0; - int parentPosY = 0; for(Element currentElement : Globals.elementService.getWindowList()){ if(currentElement instanceof DrawableElement){ DrawableElement drawable = (DrawableElement) currentElement; @@ -45,11 +43,9 @@ public class DebugRendering { drawable.draw( Globals.renderingEngine.getRenderPipelineState(), Globals.renderingEngine.getOpenGLState(), - RenderingEngine.GL_DEFAULT_FRAMEBUFFER, - parentPosX, - parentPosY, - Globals.WINDOW_WIDTH, - Globals.WINDOW_HEIGHT + Globals.renderingEngine.defaultFramebuffer, + 0, + 0 ); } } @@ -63,7 +59,7 @@ public class DebugRendering { static ShaderProgram windowDrawDebugProgram = null; static ShaderProgram elementDrawDebugProgram = null; static Model planeModel = null; - public static void drawUIBounds(int parentFramebufferPointer, Vector3f boxPosition, Vector3f boxDimensions, Vector3f color){ + public static void drawUIBounds(Framebuffer parentFramebuffer, Vector3f boxPosition, Vector3f boxDimensions, Vector3f color){ if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS){ if(planeModel == null){ planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); @@ -72,7 +68,7 @@ public class DebugRendering { elementDrawDebugProgram = Globals.assetManager.fetchShader("Shaders/ui/debug/windowContentBorder/windowContentBound.vs", null, "Shaders/ui/debug/windowContentBorder/windowContentBound.fs"); } if(elementDrawDebugProgram != null && planeModel != null){ - Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer); + parentFramebuffer.bind(Globals.renderingEngine.getOpenGLState()); Globals.renderingEngine.getOpenGLState().setActiveShader(Globals.renderingEngine.getRenderPipelineState(), elementDrawDebugProgram); planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); @@ -87,7 +83,7 @@ public class DebugRendering { } } - public static void drawUIBoundsWindow(int parentFramebufferPointer, Vector3f boxPosition, Vector3f boxDimensions, Vector3f color){ + public static void drawUIBoundsWindow(Framebuffer parentFramebuffer, Vector3f boxPosition, Vector3f boxDimensions, Vector3f color){ if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS){ if(planeModel == null){ planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); @@ -96,7 +92,7 @@ public class DebugRendering { windowDrawDebugProgram = Globals.assetManager.fetchShader("Shaders/ui/debug/windowBorder/windowBound.vs", null, "Shaders/ui/debug/windowBorder/windowBound.fs"); } if(windowDrawDebugProgram != null && planeModel != null){ - Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer); + parentFramebuffer.bind(Globals.renderingEngine.getOpenGLState()); Globals.renderingEngine.getOpenGLState().setActiveShader(Globals.renderingEngine.getRenderPipelineState(), windowDrawDebugProgram); planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); diff --git a/src/main/java/electrosphere/renderer/framebuffer/Framebuffer.java b/src/main/java/electrosphere/renderer/framebuffer/Framebuffer.java index e8b1b08e..30bbda0d 100644 --- a/src/main/java/electrosphere/renderer/framebuffer/Framebuffer.java +++ b/src/main/java/electrosphere/renderer/framebuffer/Framebuffer.java @@ -366,4 +366,32 @@ public class Framebuffer { return multiplier; } + /** + * Gets the width of a framebuffer + * @return The width + */ + public int getWidth(){ + if(texture != null){ + return texture.getWidth(); + } + if(this.framebufferPointer == DEFAULT_FRAMEBUFFER_POINTER){ + return Globals.WINDOW_WIDTH; + } + throw new Error("Calling getWidth on framebuffer with no texture assigned!"); + } + + /** + * Gets the height of a framebuffer + * @return The height + */ + public int getHeight(){ + if(texture != null){ + return texture.getHeight(); + } + if(this.framebufferPointer == DEFAULT_FRAMEBUFFER_POINTER){ + return Globals.WINDOW_HEIGHT; + } + throw new Error("Calling getHeight on framebuffer with no texture assigned!"); + } + } diff --git a/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java b/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java index 0ad0e5bb..86d63cc8 100644 --- a/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java @@ -65,10 +65,6 @@ public class UIPipeline implements RenderPipeline { renderPipelineState.setUseBones(false); renderPipelineState.setUseLight(false); - //the initial parent position values - int parentPosX = 0; - int parentPosY = 0; - //set opengl state openGLState.glDepthTest(false); openGLState.glBlend(true); @@ -77,7 +73,7 @@ public class UIPipeline implements RenderPipeline { if(currentElement instanceof DrawableElement){ DrawableElement drawable = (DrawableElement) currentElement; if(drawable.getVisible()){ - drawable.draw(renderPipelineState, openGLState, RenderingEngine.GL_DEFAULT_FRAMEBUFFER, parentPosX, parentPosY, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + drawable.draw(renderPipelineState, openGLState, Globals.renderingEngine.defaultFramebuffer, 0, 0); } } } diff --git a/src/main/java/electrosphere/renderer/ui/ElementService.java b/src/main/java/electrosphere/renderer/ui/ElementService.java index 7f1a7dd3..07093f20 100644 --- a/src/main/java/electrosphere/renderer/ui/ElementService.java +++ b/src/main/java/electrosphere/renderer/ui/ElementService.java @@ -224,7 +224,7 @@ public class ElementService extends SignalServiceImpl { ListIterator windowIterator = elementList.listIterator(elementList.size()); while(windowIterator.hasPrevious()){ Element currentWindow = windowIterator.previous(); - Stack elementStack = buildElementPositionalStack(new Stack(), currentWindow, x, y, 0, 0); + Stack elementStack = buildElementPositionalStack(new Stack(), currentWindow, x, y); Element currentElement = null; while(elementStack.size() > 0 && propagate == true){ currentElement = elementStack.pop(); @@ -330,17 +330,14 @@ public class ElementService extends SignalServiceImpl { * @param offsetY the y offset accumulated * @return the stack, filled with all relevant elements */ - Stack buildElementPositionalStack(Stack inputStack, Element current, int x, int y, int offsetX, int offsetY){ + Stack buildElementPositionalStack(Stack inputStack, Element current, int x, int y){ //if contains x,y, call function on el - if(elementContainsPoint(current,x,y,offsetX,offsetY)){ + if(elementContainsPoint(current,x,y)){ inputStack.push(current); } if(current instanceof ContainerElement){ - ContainerElement container = (ContainerElement)current; - int xLoc = x - container.getInternalX() - container.getChildOffsetX(); - int yLoc = y - container.getInternalY() - container.getChildOffsetY(); for(Element el : ((ContainerElement)current).getChildren()){ - buildElementPositionalStack(inputStack, el, xLoc, yLoc, offsetX, offsetY); + buildElementPositionalStack(inputStack, el, x, y); } } return inputStack; @@ -350,7 +347,7 @@ public class ElementService extends SignalServiceImpl { ListIterator windowIterator = elementList.listIterator(elementList.size()); while(windowIterator.hasPrevious()){ Element currentWindow = windowIterator.previous(); - Stack elementStack = buildElementPositionalStack(new Stack(), currentWindow, event.getCurrentX(), event.getCurrentY(), 0, 0); + Stack elementStack = buildElementPositionalStack(new Stack(), currentWindow, event.getCurrentX(), event.getCurrentY()); Element currentElement = null; while(elementStack.size() > 0){ currentElement = elementStack.pop(); @@ -372,7 +369,7 @@ public class ElementService extends SignalServiceImpl { ListIterator windowIterator = elementList.listIterator(elementList.size()); while(windowIterator.hasPrevious()){ Element currentWindow = windowIterator.previous(); - Stack elementStack = buildElementPositionalStack(new Stack(), currentWindow, currentX, currentY, 0, 0); + Stack elementStack = buildElementPositionalStack(new Stack(), currentWindow, currentX, currentY); Element currentElement = null; while(elementStack.size() > 0){ currentElement = elementStack.pop(); @@ -391,12 +388,12 @@ public class ElementService extends SignalServiceImpl { * @param y the y component of the coordinate * @return True if it contains that point, false otherwise */ - boolean elementContainsPoint(Element el, int x, int y, int offsetX, int offsetY){ + boolean elementContainsPoint(Element el, int x, int y){ return - x >= el.getInternalX() + offsetX && - x <= el.getInternalX() + offsetX + el.getInternalWidth() && - y >= el.getInternalY() + offsetY && - y <= el.getInternalY() + offsetY + el.getInternalHeight(); + x >= el.getAbsoluteX() && + x <= el.getAbsoluteX() + el.getWidth() && + y >= el.getAbsoluteY() && + y <= el.getAbsoluteY() + el.getHeight(); } /** @@ -475,8 +472,8 @@ public class ElementService extends SignalServiceImpl { int relX = 0; int relY = 0; for(Element el : ancestryList){ - relX = relX + el.getInternalX(); - relY = relY + el.getInternalY(); + relX = relX + el.getRelativeX(); + relY = relY + el.getRelativeY(); } return new Vector2i(relX,relY); } diff --git a/src/main/java/electrosphere/renderer/ui/components/NaturalInventoryPanel.java b/src/main/java/electrosphere/renderer/ui/components/NaturalInventoryPanel.java index a222622c..a0981fb7 100644 --- a/src/main/java/electrosphere/renderer/ui/components/NaturalInventoryPanel.java +++ b/src/main/java/electrosphere/renderer/ui/components/NaturalInventoryPanel.java @@ -16,6 +16,7 @@ import electrosphere.renderer.ui.elements.Div; import electrosphere.renderer.ui.elements.ImagePanel; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection; import electrosphere.renderer.ui.elementtypes.ContainerElement; import electrosphere.renderer.ui.elementtypes.DraggableElement.DragEventCallback; import electrosphere.renderer.ui.elementtypes.Element; @@ -93,116 +94,121 @@ public class NaturalInventoryPanel { //label 1 (inventory) div.addChild(Label.createLabel("INVENTORY")); - int columns = 8; - int columnWidth = 60; - int rowHeight = 60; - for(int i = 0; i < inventory.getCapacity(); i++){ - String texturePath = "Textures/ui/uiFrame1.png"; - boolean hasItem = false; - if(i < inventory.getItems().size()){ - Entity currentItem = inventory.getItems().get(i); - //get texture path from item - texturePath = ItemUtils.getItemIcon(currentItem); - //flag that this isn't an empty slot - hasItem = true; - } - if(!Globals.assetManager.hasLoadedTexture(texturePath)){ - Globals.assetManager.addTexturePathtoQueue(texturePath); - } - int posX = (10 + i % columns * columnWidth); - int posY = 60 + (i / columns * rowHeight); - int posXf = posX; - int posYf = posY; - int itemPosX = posX; - int itemPosY = posY; - int panelWidth = 50; - int panelHeight = 50; - ImagePanel panel = ImagePanel.createImagePanelAbsolute(posX,posY,panelWidth,panelHeight,texturePath); - if(hasItem == true){ - int itemId = i; - panel.setOnDragStart(new DragEventCallback() {public boolean execute(DragEvent event){ - // System.out.println("Drag start"); - Globals.dragSourceInventory = inventory; - Globals.draggedItem = inventory.getItems().get(itemId); - ContainerElement container = (ContainerElement)panel.getParent(); - container.removeChild(panel); - WindowUtils.pushItemIconToItemWindow(panel); - //add a dummy icon in place of the existing one - dummyPanel = ImagePanel.createImagePanelAbsolute(posXf,posYf,panelWidth,panelHeight,"Textures/ui/uiFrame1.png"); - container.addChild(dummyPanel); - //play sound effect - if(Globals.virtualAudioSourceManager != null){ - Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventoryGrabItem.ogg", VirtualAudioSourceType.UI, false); - } - return false; - }}); - panel.setOnDrag(new DragEventCallback() {public boolean execute(DragEvent event){ - // System.out.println("Drag"); - panel.setPositionX(event.getCurrentX() - panelWidth / 2); - panel.setPositionY(event.getCurrentY() - panelHeight / 2); - return false; - }}); - panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){ - if(panel.getParent() != div){ - if(panel.getParent() != null){ - ContainerElement container = (ContainerElement)panel.getParent(); - container.removeChild(panel); - } - div.addChild(panel); - Globals.elementService.fireEvent(event, event.getCurrentX(), event.getCurrentY()); - } - //dummy panel handling - destroyDummyPanel(); - panel.setPositionX(div.getAbsoluteX() + itemPosX); - panel.setPositionY(div.getAbsoluteY() + itemPosY); - return false; - }}); - } else { - panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){ - if(Globals.dragSourceInventory instanceof RelationalInventoryState){ - RelationalInventoryState sourceInventory = (RelationalInventoryState) Globals.dragSourceInventory; - Entity item = Globals.draggedItem; - if(ClientEquipState.hasEquipState(entity) && InventoryUtils.hasEquipInventory(entity)){ - RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(entity); - ClientEquipState equipState = ClientEquipState.getEquipState(entity); - equipState.commandAttemptUnequip(equipInventory.getItemSlot(item)); - } - //update ui - // Globals.dragSourceInventory = null; - // Globals.draggedItem = null; - //clear item container ui - WindowUtils.cleanItemDraggingWindow(); - //dummy panel handling - destroyDummyPanel(); - //rerender both inventories - //re-render inventory - WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, MenuGeneratorsInventory.createCharacterInventoryMenu(sourceInventory)); - //re-render inventory - WindowUtils.replaceWindow(WindowUtils.getInventoryWindowID(inventory.getId()), PlayerInventoryWindow.createPlayerInventoryWindow(Globals.playerEntity)); + { + //contains all the item panels + Div panelContainer = Div.createDiv(); + panelContainer.setFlexDirection(YogaFlexDirection.Row); + + for(int i = 0; i < inventory.getCapacity(); i++){ + String texturePath = "Textures/ui/uiFrame1.png"; + boolean hasItem = false; + if(i < inventory.getItems().size()){ + Entity currentItem = inventory.getItems().get(i); + //get texture path from item + texturePath = ItemUtils.getItemIcon(currentItem); + //flag that this isn't an empty slot + hasItem = true; + } + if(!Globals.assetManager.hasLoadedTexture(texturePath)){ + Globals.assetManager.addTexturePathtoQueue(texturePath); + } + int panelWidth = 50; + int panelHeight = 50; + ImagePanel panel = ImagePanel.createImagePanel(texturePath); + panel.setMinWidth(panelWidth); + panel.setMinHeight(panelHeight); + panel.setMarginRight(10); + panel.setMarginBottom(10); + if(hasItem == true){ + int itemId = i; + panel.setOnDragStart(new DragEventCallback() {public boolean execute(DragEvent event){ + // System.out.println("Drag start"); + Globals.dragSourceInventory = inventory; + Globals.draggedItem = inventory.getItems().get(itemId); + ContainerElement container = (ContainerElement)panel.getParent(); + container.removeChild(panel); + WindowUtils.pushItemIconToItemWindow(panel); + //set new flex values now that its in this item dragging window + panel.setAbsolutePosition(true); + panel.setPositionX(panel.getAbsoluteX()); + panel.setPositionY(panel.getAbsoluteY()); + //add a dummy icon in place of the existing one + dummyPanel = ImagePanel.createImagePanel("Textures/ui/uiFrame1.png"); + dummyPanel.setMinWidth(panelWidth); + dummyPanel.setMinHeight(panelHeight); + dummyPanel.setMarginRight(10); + dummyPanel.setMarginBottom(10); + panelContainer.addChild(dummyPanel); //play sound effect if(Globals.virtualAudioSourceManager != null){ - Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventorySlotItem.ogg", VirtualAudioSourceType.UI, false); + Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventoryGrabItem.ogg", VirtualAudioSourceType.UI, false); } - } - //now the fun begins :) - //if transfer item - // remove item from current inventory - // place item in new inventory - // trigger recreation of the menu - //if drop item - // remove item from current inventory - // create item in world in front of character - // trigger recreation of the menu - //if neither of above - // replace item icon position to origin - // System.out.println("Release drag"); - return false; - }}); + return false; + }}); + panel.setOnDrag(new DragEventCallback() {public boolean execute(DragEvent event){ + // System.out.println("Drag"); + panel.setPositionX(event.getCurrentX() - panelWidth / 2); + panel.setPositionY(event.getCurrentY() - panelHeight / 2); + return false; + }}); + panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){ + if(panel.getParent() != div){ + if(panel.getParent() != null){ + ContainerElement container = (ContainerElement)panel.getParent(); + container.removeChild(panel); + } + div.addChild(panel); + Globals.elementService.fireEvent(event, event.getCurrentX(), event.getCurrentY()); + } + //dummy panel handling + destroyDummyPanel(); + return false; + }}); + } else { + panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){ + if(Globals.dragSourceInventory instanceof RelationalInventoryState){ + RelationalInventoryState sourceInventory = (RelationalInventoryState) Globals.dragSourceInventory; + Entity item = Globals.draggedItem; + if(ClientEquipState.hasEquipState(entity) && InventoryUtils.hasEquipInventory(entity)){ + RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(entity); + ClientEquipState equipState = ClientEquipState.getEquipState(entity); + equipState.commandAttemptUnequip(equipInventory.getItemSlot(item)); + } + //update ui + // Globals.dragSourceInventory = null; + // Globals.draggedItem = null; + //clear item container ui + WindowUtils.cleanItemDraggingWindow(); + //dummy panel handling + destroyDummyPanel(); + //rerender both inventories + //re-render inventory + WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, MenuGeneratorsInventory.createCharacterInventoryMenu(sourceInventory)); + //re-render inventory + WindowUtils.replaceWindow(WindowUtils.getInventoryWindowID(inventory.getId()), PlayerInventoryWindow.createPlayerInventoryWindow(Globals.playerEntity)); + //play sound effect + if(Globals.virtualAudioSourceManager != null){ + Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventorySlotItem.ogg", VirtualAudioSourceType.UI, false); + } + } + //now the fun begins :) + //if transfer item + // remove item from current inventory + // place item in new inventory + // trigger recreation of the menu + //if drop item + // remove item from current inventory + // create item in world in front of character + // trigger recreation of the menu + //if neither of above + // replace item icon position to origin + // System.out.println("Release drag"); + return false; + }}); + } + panelContainer.addChild(panel); } - // imagePanel.setWidth(width); - // imagePanel.setHeight(height); - // imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture)); - div.addChild(panel); + div.addChild(panelContainer); } return div; } diff --git a/src/main/java/electrosphere/renderer/ui/components/PlayerInventoryWindow.java b/src/main/java/electrosphere/renderer/ui/components/PlayerInventoryWindow.java index b300c87e..484c6b12 100644 --- a/src/main/java/electrosphere/renderer/ui/components/PlayerInventoryWindow.java +++ b/src/main/java/electrosphere/renderer/ui/components/PlayerInventoryWindow.java @@ -29,8 +29,8 @@ public class PlayerInventoryWindow { * @return The panel component */ public static Window createPlayerInventoryWindow(Entity entity){ - int width = 500; - int height = 500; + int width = 750; + int height = 750; Window rVal = Window.createExpandableCenterAligned(Globals.renderingEngine.getOpenGLState(), width, height); diff --git a/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java b/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java index 71b180b9..54eee199 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java @@ -6,7 +6,6 @@ import static org.lwjgl.opengl.GL11.GL_LESS; import static org.lwjgl.opengl.GL11.glClear; import static org.lwjgl.opengl.GL11.glClearColor; import static org.lwjgl.opengl.GL11.glDepthMask; -import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER; import org.joml.Matrix4d; import org.joml.Quaterniond; @@ -20,6 +19,7 @@ import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.debug.DebugRendering; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.elementtypes.DraggableElement; import electrosphere.renderer.ui.events.DragEvent; @@ -63,15 +63,7 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme public ActorPanel(OpenGLState openGLState, int x, int y, int width, int height, Actor actor){ super(); - //must manually set because framebuffer is allocated on set - //these default to -1 until they are set with methods, but methods allocate on each set - //to break chicken-and-egg problem, manually set here - this.width = DEFAULT_WIDTH; - this.height = DEFAULT_HEIGHT; - this.actor = actor; - this.internalPositionX = x; - this.internalPositionY = y; this.setWidth(width); this.setHeight(height); this.aspectRatio = (float)width / (float)height; @@ -85,12 +77,6 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme private ActorPanel(Actor actor){ super(); - //must manually set because framebuffer is allocated on set - //these default to -1 until they are set with methods, but methods allocate on each set - //to break chicken-and-egg problem, manually set here - this.width = DEFAULT_WIDTH; - this.height = DEFAULT_HEIGHT; - this.actor = actor; this.setWidth(DEFAULT_WIDTH); this.setHeight(DEFAULT_HEIGHT); @@ -114,16 +100,14 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { if(this.elementBuffer != null){ elementBuffer.bind(openGLState); - // Globals.renderingEngine.setViewportSize(width, height); + openGLState.glViewport(elementBuffer.getWidth(), elementBuffer.getHeight()); RenderingEngine.setFOV(FOV); RenderingEngine.setAspectRatio(aspectRatio); @@ -131,7 +115,6 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme openGLState.glDepthTest(true); openGLState.glDepthFunc(GL_LESS); glDepthMask(true); - openGLState.glViewport(width, height); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -175,15 +158,13 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme //this call binds the screen as the "texture" we're rendering to //have to call before actually rendering - openGLState.glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer); - - //set viewport - openGLState.glViewport(parentWidth, parentHeight); + framebuffer.bind(openGLState); + openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight()); - float ndcX = (float)(getInternalX() + parentPosX)/parentWidth; - float ndcY = (float)(getInternalY() + parentPosY)/parentHeight; - float ndcWidth = (float)getInternalWidth()/parentWidth; - float ndcHeight = (float)getInternalHeight()/parentHeight; + float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth(); + float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight(); + float ndcWidth = (float)getWidth()/framebuffer.getWidth(); + float ndcHeight = (float)getHeight()/framebuffer.getHeight(); Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); @@ -222,7 +203,7 @@ public class ActorPanel extends BufferedStandardDrawableContainerElement impleme } if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_ACTOR_PANEL){ - DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor); + DebugRendering.drawUIBounds(framebuffer, boxPosition, boxDimensions, windowDrawDebugColor); } } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java b/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java index 664a7e61..b001a636 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java +++ b/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java @@ -4,14 +4,13 @@ import electrosphere.engine.Globals; import electrosphere.engine.assetmanager.AssetDataStrings; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.elementtypes.DrawableElement; -import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.font.Font; import org.joml.Vector3f; -import org.lwjgl.util.yoga.Yoga; /** * A single character @@ -75,18 +74,16 @@ public class BitmapCharacter extends StandardElement implements DrawableElement public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ){ - Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer); - openGLState.glViewport(parentWidth, parentHeight); - float ndcX = (float)(getInternalX() + parentPosX)/parentWidth; - float ndcY = (float)(parentHeight - (getInternalY() + parentPosY))/parentHeight; - float ndcWidth = (float)getInternalWidth()/parentWidth; - float ndcHeight = (float)getInternalHeight()/parentHeight; + framebuffer.bind(openGLState); + openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight()); + float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth(); + float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight(); + float ndcWidth = (float)getWidth()/framebuffer.getWidth(); + float ndcHeight = (float)getHeight()/framebuffer.getHeight(); // float charWidth = ndcWidth/cols; // float charHeight = ndcHeight/rows; char toDraw = text.charAt(0); @@ -111,42 +108,9 @@ public class BitmapCharacter extends StandardElement implements DrawableElement charModel.drawUI(); } } - - public boolean visible = false; - - public boolean getVisible() { - return visible; - } - - public void setVisible(boolean draw) { - this.visible = draw; - } public boolean handleEvent(Event event){ return true; } - - @Override - public void applyYoga(int parentX, int parentY) { - if(this.yogaNode != Element.NULL_YOGA_ELEMENT){ - //get the values from yoga - float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); - float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); - //apply the values to this component - this.internalPositionX = (int)leftRaw; - this.internalPositionY = (int)topRaw; - this.internalWidth = (int)Yoga.YGNodeLayoutGetWidth(yogaNode); - if(!Float.isFinite(this.internalWidth)){ - this.internalWidth = 0; - } - this.internalHeight = (int)Yoga.YGNodeLayoutGetHeight(yogaNode); - if(!Float.isFinite(this.internalHeight)){ - this.internalHeight = 0; - } - //calculate absolute values - this.absoluteX = parentX + internalPositionX; - this.absoluteY = parentY + internalPositionY; - } - } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/BufferedStandardDrawableContainerElement.java b/src/main/java/electrosphere/renderer/ui/elements/BufferedStandardDrawableContainerElement.java index cd39faf2..5c7340f6 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/BufferedStandardDrawableContainerElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/BufferedStandardDrawableContainerElement.java @@ -6,7 +6,6 @@ import static org.lwjgl.opengl.GL11.glClear; import static org.lwjgl.opengl.GL11.glClearColor; import org.joml.Vector3f; -import org.lwjgl.opengl.GL45; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; @@ -59,17 +58,15 @@ public class BufferedStandardDrawableContainerElement extends StandardDrawableC public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { - float ndcWidth = (float)getWidth()/parentWidth; - float ndcHeight = (float)getHeight()/parentHeight; - float ndcX = (float)(getInternalX() + parentPosX)/parentWidth; - float ndcY = (float)(getInternalY() + parentPosY)/parentHeight; + float ndcWidth = (float)getWidth()/framebuffer.getWidth(); + float ndcHeight = (float)getHeight()/framebuffer.getHeight(); + float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth(); + float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight(); Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); Vector3f texPosition = new Vector3f(0,0,0); @@ -81,7 +78,7 @@ public class BufferedStandardDrawableContainerElement extends StandardDrawableC elementBuffer.bind(openGLState); - openGLState.glViewport(width, height); + openGLState.glViewport(elementBuffer.getWidth(), elementBuffer.getHeight()); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -92,18 +89,16 @@ public class BufferedStandardDrawableContainerElement extends StandardDrawableC drawableChild.draw( renderPipelineState, openGLState, - parentFramebufferPointer, - parentPosX + this.internalPositionX, - parentPosY + this.internalPositionY, - parentWidth, - parentHeight + this.elementBuffer, + this.getAbsoluteX(), + this.getAbsoluteY() ); } } //this call binds the screen as the "texture" we're rendering to //have to call before actually rendering - openGLState.glBindFramebuffer(GL45.GL_FRAMEBUFFER, parentFramebufferPointer); - openGLState.glViewport(parentWidth, parentHeight); + framebuffer.bind(openGLState); + openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight()); //render background of window if(planeModel != null && windowFrame != null){ @@ -130,21 +125,9 @@ public class BufferedStandardDrawableContainerElement extends StandardDrawableC } @Override - public void setWidth(int width) { - if(width <= 1){ - throw new Error("Provided invalid width! " + width); - } - super.setWidth(width); - this.regenerateFramebuffer(width, height); - } - - @Override - public void setHeight(int height) { - if(height <= 1){ - throw new Error("Provided invalid height! " + height); - } - super.setHeight(height); - this.regenerateFramebuffer(width, height); + public void applyYoga(int parentX, int parentY){ + super.applyYoga(parentX, parentY); + this.regenerateFramebuffer(this.getWidth(), this.getHeight()); } /** diff --git a/src/main/java/electrosphere/renderer/ui/elements/Button.java b/src/main/java/electrosphere/renderer/ui/elements/Button.java index 47d7f58d..8c7f5969 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Button.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Button.java @@ -1,13 +1,12 @@ package electrosphere.renderer.ui.elements; import org.joml.Vector3f; -import org.lwjgl.opengl.GL30; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; -import electrosphere.renderer.debug.DebugRendering; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Model; import electrosphere.renderer.texture.Texture; @@ -57,6 +56,7 @@ public class Button extends StandardContainerElement implements DrawableElement, rValLabel.setText(text); rVal.addChild(rValLabel); rVal.setOnClick(callback); + rVal.setAlignSelf(YogaAlignment.Start); return rVal; } @@ -75,6 +75,7 @@ public class Button extends StandardContainerElement implements DrawableElement, callback.run(); return false; }}); + rVal.setAlignSelf(YogaAlignment.Start); return rVal; } @@ -139,23 +140,22 @@ public class Button extends StandardContainerElement implements DrawableElement, } } + @Override public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { // //Draw decorations - float ndcWidth = (float)getWidth()/parentWidth; - float ndcHeight = (float)getHeight()/parentHeight; - float ndcX = (float)(getInternalX() + parentPosX)/parentWidth; - float ndcY = (float)(getInternalY() + parentPosY)/parentHeight; + float ndcWidth = (float)getWidth()/framebuffer.getWidth(); + float ndcHeight = (float)getHeight()/framebuffer.getHeight(); + float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth(); + float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight(); boxPosition = new Vector3f(ndcX,ndcY,0); boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); @@ -169,8 +169,8 @@ public class Button extends StandardContainerElement implements DrawableElement, //this call binds the screen as the "texture" we're rendering to //have to call before actually rendering - openGLState.glBindFramebuffer(GL30.GL_FRAMEBUFFER, parentFramebufferPointer); - openGLState.glViewport(parentWidth, parentHeight); + framebuffer.bind(openGLState); + openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight()); //error if assets are null if(planeModel == null || windowFrame == null){ @@ -198,18 +198,12 @@ public class Button extends StandardContainerElement implements DrawableElement, drawableChild.draw( renderPipelineState, openGLState, - parentFramebufferPointer, - parentPosX + this.internalPositionX, - parentPosY + this.internalPositionY, - parentWidth, - parentHeight + framebuffer, + framebufferPosX, + framebufferPosY ); } } - - if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_BUTTON){ - DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor); - } } @Override diff --git a/src/main/java/electrosphere/renderer/ui/elements/Div.java b/src/main/java/electrosphere/renderer/ui/elements/Div.java index 23a079fd..2d92a912 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Div.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Div.java @@ -3,10 +3,9 @@ package electrosphere.renderer.ui.elements; import org.joml.Vector3f; import org.lwjgl.util.yoga.Yoga; -import electrosphere.engine.Globals; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; -import electrosphere.renderer.debug.DebugRendering; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.ui.elementtypes.ClickableElement; import electrosphere.renderer.ui.elementtypes.DraggableElement; import electrosphere.renderer.ui.elementtypes.DrawableElement; @@ -176,28 +175,16 @@ public class Div extends StandardContainerElement implements ClickableElement,Dr public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { for(Element child : childList){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; - drawableChild.draw(renderPipelineState,openGLState,parentFramebufferPointer,parentPosX + this.internalPositionX,parentPosY + this.internalPositionY,parentWidth,parentHeight); + drawableChild.draw(renderPipelineState,openGLState,framebuffer,framebufferPosX,framebufferPosY); } } - - if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_DIV){ - float ndcX = (float)internalPositionX/parentWidth; - float ndcY = (float)internalPositionY/parentHeight; - float ndcWidth = (float)getWidth()/parentWidth; - float ndcHeight = (float)getHeight()/parentHeight; - Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); - Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); - DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor); - } } @Override diff --git a/src/main/java/electrosphere/renderer/ui/elements/FormElement.java b/src/main/java/electrosphere/renderer/ui/elements/FormElement.java index b1115440..b85a4c8c 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/FormElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/FormElement.java @@ -4,6 +4,7 @@ import org.lwjgl.util.yoga.Yoga; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.Event; @@ -19,19 +20,18 @@ public class FormElement extends StandardContainerElement implements DrawableEle Yoga.YGNodeStyleSetDisplay(yogaNode, Yoga.YGDisplayFlex); } + @Override public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { for(Element child : childList){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; - drawableChild.draw(renderPipelineState,openGLState,parentFramebufferPointer,parentPosX + this.internalPositionX,parentPosY + this.internalPositionY,parentWidth,parentHeight); + drawableChild.draw(renderPipelineState,openGLState,framebuffer, framebufferPosX, framebufferPosY); } } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java b/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java index 79b82c1c..d0901af0 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java @@ -1,19 +1,18 @@ package electrosphere.renderer.ui.elements; -import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER; - import org.joml.Vector3f; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; -import electrosphere.renderer.debug.DebugRendering; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Model; import electrosphere.renderer.texture.Texture; import electrosphere.renderer.ui.elementtypes.DraggableElement; import electrosphere.renderer.ui.elementtypes.DrawableElement; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; import electrosphere.renderer.ui.events.DragEvent; import electrosphere.renderer.ui.events.DragEvent.DragEventType; import electrosphere.renderer.ui.events.Event; @@ -58,6 +57,7 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag */ public static ImagePanel createImagePanel(String texturePath){ ImagePanel rVal = new ImagePanel(texturePath); + rVal.setAlignSelf(YogaAlignment.Start); return rVal; } @@ -118,17 +118,15 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { - float ndcWidth = (float)getInternalWidth()/parentWidth; - float ndcHeight = (float)getInternalHeight()/parentHeight; - float ndcX = (float)(getInternalX() + parentPosX)/parentWidth; - float ndcY = (float)(getInternalY() + parentPosY)/parentHeight; + float ndcWidth = (float)getWidth()/framebuffer.getWidth(); + float ndcHeight = (float)getHeight()/framebuffer.getHeight(); + float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth(); + float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight(); boxPosition = new Vector3f(ndcX,ndcY,0); boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); @@ -141,8 +139,8 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag //this call binds the screen as the "texture" we're rendering to //have to call before actually rendering - openGLState.glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer); - openGLState.glViewport(parentWidth, parentHeight); + framebuffer.bind(openGLState); + openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight()); renderPipelineState.setUseMaterial(true); renderPipelineState.setBufferNonStandardUniforms(true); @@ -159,9 +157,6 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag LoggerInterface.loggerRenderer.ERROR("Image Panel unable to find plane model!!", new Exception()); } - if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS){ - DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor); - } } //controls whether the image panel is visible or not diff --git a/src/main/java/electrosphere/renderer/ui/elements/Label.java b/src/main/java/electrosphere/renderer/ui/elements/Label.java index 7d617ace..82c5d529 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Label.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Label.java @@ -7,7 +7,7 @@ import electrosphere.engine.Globals; import electrosphere.engine.signal.Signal.SignalType; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; -import electrosphere.renderer.debug.DebugRendering; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.Event; @@ -23,9 +23,6 @@ public class Label extends StandardContainerElement implements DrawableElement { */ public static final float DEFAULT_FONT_SIZE = 1.0f; - public boolean visible = false; - - String text = ""; int textPixelWidth = 0; @@ -84,7 +81,7 @@ public class Label extends StandardContainerElement implements DrawableElement { for(int i = 0; i < text.length(); i++){ char toDraw = text.charAt(i); Vector3f bitMapDimension = this.font.getDimensionOfCharacterDiscrete(toDraw); - BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.height, toDraw); + BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.getHeight(), toDraw); accumulatingWidth += bitMapDimension.x * fontSize; childList.add(newLetter); Yoga.YGNodeInsertChild(yogaNode, newLetter.getYogaNode(), childList.size() - 1); @@ -116,41 +113,19 @@ public class Label extends StandardContainerElement implements DrawableElement { public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { for(Element child : childList){ ((DrawableElement)child).draw( renderPipelineState, openGLState, - parentFramebufferPointer, - parentPosX + this.internalPositionX, - parentPosY + this.internalPositionY, - parentWidth, - parentHeight + framebuffer, + framebufferPosX, + framebufferPosY ); } - - if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_LABEL){ - float ndcX = (float)(internalPositionX)/parentWidth; - float ndcY = (float)(internalPositionY)/parentHeight; - float ndcWidth = (float)internalWidth/parentWidth; - float ndcHeight = (float)internalHeight/parentHeight; - Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); - Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); - DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor); - } - } - - public boolean getVisible() { - return visible; - } - - public void setVisible(boolean draw) { - this.visible = draw; } public boolean handleEvent(Event event){ diff --git a/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java b/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java index e1f8b6a4..b6ef750a 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java @@ -6,15 +6,14 @@ import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.model.Model; -import electrosphere.renderer.texture.Texture; import electrosphere.renderer.ui.elementtypes.ContainerElement; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.Event; import static org.lwjgl.opengl.GL11.*; -import static org.lwjgl.opengl.GL30.*; public class ScrollableContainer extends BufferedStandardDrawableContainerElement { @@ -42,12 +41,6 @@ public class ScrollableContainer extends BufferedStandardDrawableContainerElemen public ScrollableContainer(OpenGLState openGLState, int positionX, int positionY, int width, int height){ super(); - //must manually set because framebuffer is allocated on set - //these default to -1 until they are set with methods, but methods allocate on each set - //to break chicken-and-egg problem, manually set here - this.width = DEFAULT_WIDTH; - this.height = DEFAULT_HEIGHT; - float ndcX = (float)positionX/Globals.WINDOW_WIDTH; float ndcY = (float)positionY/Globals.WINDOW_HEIGHT; float ndcWidth = (float)width/Globals.WINDOW_WIDTH; @@ -64,12 +57,6 @@ public class ScrollableContainer extends BufferedStandardDrawableContainerElemen private ScrollableContainer(){ super(); - //must manually set because framebuffer is allocated on set - //these default to -1 until they are set with methods, but methods allocate on each set - //to break chicken-and-egg problem, manually set here - this.width = DEFAULT_WIDTH; - this.height = DEFAULT_HEIGHT; - setWidth(DEFAULT_WIDTH); setHeight(DEFAULT_HEIGHT); } @@ -108,11 +95,9 @@ public class ScrollableContainer extends BufferedStandardDrawableContainerElemen public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { if(this.elementBuffer != null){ //figure out if currently focused element is a child or subchild of this container @@ -160,20 +145,19 @@ public class ScrollableContainer extends BufferedStandardDrawableContainerElemen // } // } - float ndcWidth = (float)getWidth()/parentWidth; - float ndcHeight = (float)getHeight()/parentHeight; - float ndcX = (float)(getInternalX() + parentPosX)/parentWidth; - float ndcY = (float)(getInternalY() + parentPosY)/parentHeight; + float ndcWidth = (float)getWidth()/framebuffer.getWidth(); + float ndcHeight = (float)getHeight()/framebuffer.getHeight(); + float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth(); + float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight(); boxPosition = new Vector3f(ndcX,ndcY,0); boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); //grab assets required to render window Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); - Texture windowFrame = Globals.assetManager.fetchTexture("Textures/ui/uiFrame1.png"); elementBuffer.bind(openGLState); - openGLState.glViewport(width, height); + openGLState.glViewport(elementBuffer.getWidth(), elementBuffer.getHeight()); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -184,31 +168,17 @@ public class ScrollableContainer extends BufferedStandardDrawableContainerElemen drawableChild.draw( renderPipelineState, openGLState, - parentFramebufferPointer, - parentPosX + this.internalPositionX, - parentPosY + this.internalPositionY, - parentWidth, - parentHeight + framebuffer, + framebufferPosX, + framebufferPosY ); } } //this call binds the screen as the "texture" we're rendering to //have to call before actually rendering - openGLState.glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer); - openGLState.glViewport(parentWidth, parentHeight); + framebuffer.bind(openGLState); + openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight()); - //render background of window - if(planeModel != null && windowFrame != null){ - planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); - planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); - planeModel.pushUniformToMesh("plane", "tPosition", texPosition); - planeModel.pushUniformToMesh("plane", "tDimension", texScale); - planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", color); - elementMat.setTexturePointer(windowFrame.getTexturePointer()); - planeModel.getMeshes().get(0).setMaterial(elementMat); - planeModel.drawUI(); - } - if(planeModel != null){ planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); diff --git a/src/main/java/electrosphere/renderer/ui/elements/Slider.java b/src/main/java/electrosphere/renderer/ui/elements/Slider.java index 1cfda195..e006a088 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Slider.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Slider.java @@ -8,7 +8,7 @@ import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; -import electrosphere.renderer.debug.DebugRendering; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.elementtypes.ClickableElement; @@ -101,10 +101,10 @@ public class Slider extends StandardDrawableElement implements ClickableElement, mat.set_diffuse("Textures/ui/square.png"); mat.set_specular("Textures/ui/square.png"); } - this.internalPositionX = positionX; - this.internalPositionY = positionY; - this.width = width; - this.height = height; + setPositionX(positionX); + setPositionY(positionY); + setWidth(width); + setHeight(height); this.colorBackground.set(colorBackground); this.colorForeground.set(colorForeground); } @@ -115,23 +115,21 @@ public class Slider extends StandardDrawableElement implements ClickableElement, public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { - Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer); - openGLState.glViewport(parentWidth, parentHeight); + framebuffer.bind(openGLState); + openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight()); - int drawMarginX = Math.max(width - idealMargin * 2, 0); + int drawMarginX = Math.max(this.getWidth() - idealMargin * 2, 0); if(drawMarginX < idealMargin){ drawMarginX = 0; } else { drawMarginX = idealMargin; } - int drawMarginY = Math.max(height - idealMargin * 2, 0); + int drawMarginY = Math.max(this.getHeight() - idealMargin * 2, 0); if(drawMarginY < idealMargin){ drawMarginY = 0; } else { @@ -139,10 +137,10 @@ public class Slider extends StandardDrawableElement implements ClickableElement, } - float ndcWidth = (float)getInternalWidth()/parentWidth; - float ndcHeight = (float)getInternalHeight()/parentHeight; - float ndcX = (float)(getInternalX() + parentPosX)/parentWidth; - float ndcY = (float)(getInternalY() + parentPosY)/parentHeight; + float ndcWidth = (float)getWidth()/framebuffer.getWidth(); + float ndcHeight = (float)getHeight()/framebuffer.getHeight(); + float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth(); + float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight(); Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); @@ -157,10 +155,10 @@ public class Slider extends StandardDrawableElement implements ClickableElement, planeModel.drawUI(); //actual slider - ndcWidth = (float)((getInternalWidth() - drawMarginX * 2) * getValueAsPercentage())/parentWidth; - ndcHeight = (float)(getInternalHeight() - drawMarginY * 2)/parentHeight; - ndcX = (float)(getInternalX() + drawMarginX + parentPosX)/parentWidth; - ndcY = (float)(getInternalY() + drawMarginY + parentPosY)/parentHeight; + ndcWidth = (float)((getWidth() - drawMarginX * 2) * getValueAsPercentage())/framebuffer.getWidth(); + ndcHeight = (float)(getHeight() - drawMarginY * 2)/framebuffer.getHeight(); + ndcX = (float)(this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX) + drawMarginX)/framebuffer.getWidth(); + ndcY = (float)(this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY) + drawMarginY)/framebuffer.getHeight(); boxPosition = new Vector3f(ndcX,ndcY,0); boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); @@ -171,10 +169,6 @@ public class Slider extends StandardDrawableElement implements ClickableElement, } else { LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model!!", new Exception()); } - if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_SLIDER){ - boxDimensions.x = (float)((width - drawMarginX * 2) * 1.0f)/parentWidth; - DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor); - } } @@ -318,8 +312,8 @@ public class Slider extends StandardDrawableElement implements ClickableElement, propagate = onDrag.execute(dragEvent); } else { //default behavior - int percentage = dragEvent.getRelativeX() - getInternalX(); - int max = getInternalWidth(); + int percentage = dragEvent.getRelativeX() - getAbsoluteX(); + int max = getWidth(); value = Math.max(Math.min((float)percentage/max,1.0f),0.0f); value = this.valueFromPercentage(value); if(onValueChange != null){ @@ -332,8 +326,8 @@ public class Slider extends StandardDrawableElement implements ClickableElement, propagate = onDragRelease.execute(dragEvent); } else { //default behavior - int percentage = dragEvent.getRelativeX() - getInternalX(); - int max = getInternalWidth(); + int percentage = dragEvent.getRelativeX() - getAbsoluteX(); + int max = getWidth(); value = Math.max(Math.min((float)percentage/max,1.0f),0.0f); value = this.valueFromPercentage(value); if(onValueChange != null){ @@ -349,8 +343,8 @@ public class Slider extends StandardDrawableElement implements ClickableElement, propagate = this.onClick.execute((ClickEvent)event); } else { //default behavior - int percentage = clickEvent.getRelativeX() - getInternalX(); - int max = getInternalWidth(); + int percentage = clickEvent.getRelativeX() - getAbsoluteX(); + int max = getWidth(); value = Math.max(Math.min((float)percentage/max,1.0f),0.0f); value = this.valueFromPercentage(value); if(onValueChange != null){ diff --git a/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java b/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java index 35a5b1a5..268a26be 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java @@ -7,7 +7,6 @@ import org.lwjgl.util.yoga.Yoga; import electrosphere.engine.Globals; import electrosphere.engine.signal.Signal.SignalType; -import electrosphere.logger.LoggerInterface; import electrosphere.renderer.ui.elementtypes.ContainerElement; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; @@ -23,132 +22,6 @@ public class StandardContainerElement extends StandardElement implements Contain super(); } - @Override - public int getWidth() { - if(width == -1){ - if(childList.size() > 0){ - int minX = -1; - int maxX = -1; - for(Element child : childList){ - if(minX == -1){ - minX = child.getRelativeX(); - } else if(child.getRelativeX() < minX){ - minX = child.getRelativeX(); - } - if(maxX == -1){ - maxX = child.getRelativeX() + child.getWidth(); - } else if(child.getRelativeX() + child.getWidth() > maxX){ - maxX = child.getRelativeX() + child.getWidth(); - } - } - if(minX == -1){ - minX = 0; - } - if(maxX == -1){ - maxX = 0; - } - return maxX - minX; - } else { - return 1; - } - } else { - return width; - } - } - - @Override - public int getHeight() { - if(height == -1){ - if(childList.size() > 0){ - int minY = -1; - int maxY = -1; - for(Element child : childList){ - if(minY == -1){ - minY = child.getRelativeY(); - } else if(child.getRelativeY() < minY){ - minY = child.getRelativeY(); - } - if(maxY == -1){ - maxY = child.getRelativeY() + child.getHeight(); - } else if(child.getRelativeY() + child.getHeight() > maxY){ - maxY = child.getRelativeY() + child.getHeight(); - } - } - if(minY == -1){ - minY = 0; - } - if(maxY == -1){ - maxY = 0; - } - return maxY - minY; - } else { - return 1; - } - } else { - return height; - } - } - - @Override - public int getRelativeX() { - if(internalPositionX == -1){ - if(childList.size() > 0){ - int minX = -1; - for(Element child : childList){ - if(minX == -1){ - minX = child.getRelativeX(); - } else if(child.getRelativeX() < minX){ - minX = child.getRelativeX(); - } - } - if(minX == -1){ - minX = 0; - } - return minX; - } else { - return internalPositionX; - } - } else { - return internalPositionX; - } - } - - @Override - public int getRelativeY() { - if(internalPositionY == -1){ - if(childList.size() > 0){ - int minY = -1; - for(Element child : childList){ - if(minY == -1){ - minY = child.getRelativeY(); - } else if(child.getRelativeY() < minY){ - minY = child.getRelativeY(); - } - } - if(minY == -1){ - minY = 0; - } - return minY; - } else { - return internalPositionY; - } - } else { - return internalPositionY; - } - } - - @Override - public void setPositionX(int posX) { - internalPositionX = posX; - absoluteX = posX; - } - @Override - - public void setPositionY(int posY) { - internalPositionY = posY; - absoluteY = posY; - } - @Override public void setDirection(int layout) { Yoga.YGNodeStyleSetDirection(yogaNode, layout); @@ -180,8 +53,6 @@ public class StandardContainerElement extends StandardElement implements Contain child.setParent(this); if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; - drawableChild.setParentWidth(width); - drawableChild.setParentHeight(height); drawableChild.setVisible(true); Yoga.YGNodeInsertChild(yogaNode, drawableChild.getYogaNode(), childList.size() - 1); } @@ -240,31 +111,10 @@ public class StandardContainerElement extends StandardElement implements Contain public void applyYoga(int parentX, int parentY) { if(this.yogaNode != Element.NULL_YOGA_ELEMENT){ //get the values from yoga - float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); - float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); - float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); - if(!Float.isFinite(widthRaw)){ - widthRaw = 0; - } - float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); - if(!Float.isFinite(heightRaw)){ - heightRaw = 0; - } - LoggerInterface.loggerUI.DEBUG("" + this); - LoggerInterface.loggerUI.DEBUG("pos(" + leftRaw + "," + topRaw + ") dim(" + widthRaw + "," + heightRaw + ")"); - //apply the values to this component - if(!useAbsolutePosition){ - this.internalPositionX = (int)leftRaw; - this.internalPositionY = (int)topRaw; - this.internalWidth = (int)widthRaw; - this.internalHeight = (int)heightRaw; - //calculate absolute values - this.absoluteX = parentX + internalPositionX; - this.absoluteY = parentY + internalPositionY; - } + super.applyYoga(parentX, parentY); //apply yoga values to all children for(Element child : this.getChildren()){ - child.applyYoga(parentX + internalPositionX,parentY + internalPositionY); + child.applyYoga(this.getAbsoluteX(),this.getAbsoluteY()); } } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/StandardDrawableContainerElement.java b/src/main/java/electrosphere/renderer/ui/elements/StandardDrawableContainerElement.java index 63777715..c8b87cf8 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/StandardDrawableContainerElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/StandardDrawableContainerElement.java @@ -2,6 +2,7 @@ package electrosphere.renderer.ui.elements; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.FocusableElement; @@ -31,7 +32,7 @@ public class StandardDrawableContainerElement extends StandardContainerElement i } @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentPosX, int parentPosY, int parentWidth, int parentHeight) { + public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, Framebuffer framebuffer, int framebufferPosX, int framebufferPosY) { throw new UnsupportedOperationException("Unimplemented method 'draw'"); } diff --git a/src/main/java/electrosphere/renderer/ui/elements/StandardDrawableElement.java b/src/main/java/electrosphere/renderer/ui/elements/StandardDrawableElement.java index 2695d963..d28c6736 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/StandardDrawableElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/StandardDrawableElement.java @@ -2,6 +2,7 @@ package electrosphere.renderer.ui.elements; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.FocusableElement; @@ -31,7 +32,7 @@ public class StandardDrawableElement extends StandardElement implements Drawable } @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentPosX, int parentPosY, int parentWidth, int parentHeight) { + public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, Framebuffer framebuffer, int framebufferPosX, int framebufferPosY) { throw new UnsupportedOperationException("Unimplemented method 'draw'"); } diff --git a/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java b/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java index 2d981ee0..b9c3363c 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java @@ -2,6 +2,7 @@ package electrosphere.renderer.ui.elements; import org.lwjgl.util.yoga.Yoga; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.Event; @@ -11,18 +12,14 @@ import electrosphere.renderer.ui.events.Event; public class StandardElement implements Element { //these are set by the - public int width = -1; - public int height = -1; - - public int parentWidth = 1; - public int parentHeight = 1; + private int width = -1; + private int height = -1; - int internalWidth; - int internalHeight; - int internalPositionX; - int internalPositionY; - int absoluteX; - int absoluteY; + + private int relativeX; + private int relativeY; + private int absoluteX; + private int absoluteY; boolean useAbsolutePosition = false; Element parent = null; @@ -51,12 +48,12 @@ public class StandardElement implements Element { @Override public int getRelativeX() { - return internalPositionX; + return relativeX; } @Override public int getRelativeY() { - return internalPositionY; + return relativeY; } @Override @@ -81,38 +78,22 @@ public class StandardElement implements Element { @Override public void setWidth(int width) { - this.internalWidth = width; - this.width = width; Yoga.YGNodeStyleSetWidth(this.yogaNode, width); } @Override public void setHeight(int height) { - this.internalHeight = height; - this.height = height; Yoga.YGNodeStyleSetHeight(this.yogaNode, height); } @Override public void setPositionX(int posX) { - this.internalPositionX = posX; - this.absoluteX = posX; + Yoga.YGNodeStyleSetPosition(this.yogaNode, Yoga.YGEdgeLeft, posX); } @Override public void setPositionY(int posY) { - this.internalPositionY = posY; - this.absoluteY = posY; - } - - @Override - public void setParentWidth(int width) { - this.parentWidth = width; - } - - @Override - public void setParentHeight(int height) { - this.parentHeight = height; + Yoga.YGNodeStyleSetPosition(this.yogaNode, Yoga.YGEdgeTop, posY); } public void setMarginTop(int marginTop){ @@ -131,23 +112,6 @@ public class StandardElement implements Element { Yoga.YGNodeStyleSetMargin(this.yogaNode, Yoga.YGEdgeLeft, marginLeft); } - public int getInternalX(){ - return internalPositionX; - } - - public int getInternalY(){ - return internalPositionY; - } - - public int getInternalWidth(){ - return internalWidth; - } - - - public int getInternalHeight(){ - return internalHeight; - } - public Element getParent(){ return this.parent; } @@ -177,16 +141,14 @@ public class StandardElement implements Element { float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); - if(!useAbsolutePosition){ - //apply the values to this component - this.internalPositionX = (int)leftRaw; - this.internalPositionY = (int)topRaw; - this.internalWidth = (int)widthRaw; - this.internalHeight = (int)heightRaw; - //calculate absolute values - this.absoluteX = parentX + internalPositionX; - this.absoluteY = parentY + internalPositionY; - } + //apply the values to this component + this.relativeX = (int)leftRaw; + this.relativeY = (int)topRaw; + this.width = (int)widthRaw; + this.height = (int)heightRaw; + //calculate absolute values + this.absoluteX = parentX + this.relativeX; + this.absoluteY = parentY + this.relativeY; } } @@ -240,6 +202,48 @@ public class StandardElement implements Element { Yoga.YGNodeStyleSetMinHeightPercent(yogaNode, percent); } + /** + * Converts an absolute (to the screen) position to a position within a framebuffer + * @param absolutePos The absolute position + * @param framebufferPos The position of the framebuffer on the screen + * @return The position within the framebuffer + */ + public int absoluteToFramebuffer(int absolutePos, int framebufferPos){ + return absolutePos - framebufferPos; + } + + @Override + public void setAlignSelf(YogaAlignment alignment){ + int alignmentInteger = Yoga.YGAlignAuto; + switch(alignment){ + case Auto: + alignmentInteger = Yoga.YGAlignAuto; + break; + case Start: + alignmentInteger = Yoga.YGAlignFlexStart; + break; + case End: + alignmentInteger = Yoga.YGAlignFlexEnd; + break; + case Around: + alignmentInteger = Yoga.YGAlignSpaceAround; + break; + case Between: + alignmentInteger = Yoga.YGAlignSpaceBetween; + break; + case Stretch: + alignmentInteger = Yoga.YGAlignStretch; + break; + case Baseline: + alignmentInteger = Yoga.YGAlignBaseline; + break; + case Center: + alignmentInteger = Yoga.YGAlignCenter; + break; + } + Yoga.YGNodeStyleSetAlignSelf(this.yogaNode, alignmentInteger); + } + /** * The value of the grow property * @param grow The grow value @@ -248,4 +252,16 @@ public class StandardElement implements Element { Yoga.YGNodeStyleSetFlexGrow(yogaNode, grow); } + public boolean getVisible() { + return visible; + } + + public void setVisible(boolean draw) { + this.visible = draw; + } + + public void setDisplay(int value){ + Yoga.YGNodeStyleSetDisplay(this.yogaNode, value); + } + } diff --git a/src/main/java/electrosphere/renderer/ui/elements/StringCarousel.java b/src/main/java/electrosphere/renderer/ui/elements/StringCarousel.java index a89a0b2c..16104ebc 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/StringCarousel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/StringCarousel.java @@ -11,6 +11,7 @@ import electrosphere.engine.Globals; import electrosphere.engine.signal.Signal.SignalType; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.FocusableElement; @@ -119,7 +120,7 @@ public class StringCarousel extends StandardContainerElement implements Drawable for(int i = 0; i < textCurrent.length(); i++){ char toDraw = textCurrent.charAt(i); Vector3f bitMapDimension = this.font.getDimensionOfCharacterDiscrete(toDraw); - BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.height, toDraw); + BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.getHeight(), toDraw); accumulatingWidth += bitMapDimension.x * fontSize; addChild(newLetter); } @@ -153,14 +154,12 @@ public class StringCarousel extends StandardContainerElement implements Drawable public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { for(Element child : childList){ - ((DrawableElement)child).draw(renderPipelineState, openGLState, parentFramebufferPointer, parentPosX + this.internalPositionX, parentPosY + this.internalPositionY, parentWidth, parentHeight); + ((DrawableElement)child).draw(renderPipelineState, openGLState, framebuffer, framebufferPosX, framebufferPosY); } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/TextBox.java b/src/main/java/electrosphere/renderer/ui/elements/TextBox.java index a1eb9098..5be699b4 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/TextBox.java +++ b/src/main/java/electrosphere/renderer/ui/elements/TextBox.java @@ -4,6 +4,7 @@ import electrosphere.engine.Globals; import electrosphere.engine.signal.Signal.SignalType; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.Event; @@ -128,11 +129,9 @@ public class TextBox extends StandardDrawableContainerElement { public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ){ //draw characters @@ -140,11 +139,9 @@ public class TextBox extends StandardDrawableContainerElement { ((DrawableElement)child).draw( renderPipelineState, openGLState, - parentFramebufferPointer, - parentPosX + this.internalPositionX, - parentPosY + this.internalPositionY, - parentWidth, - parentHeight + framebuffer, + framebufferPosX, + framebufferPosY ); } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/TextInput.java b/src/main/java/electrosphere/renderer/ui/elements/TextInput.java index 23e6cc74..0e766aa6 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/TextInput.java +++ b/src/main/java/electrosphere/renderer/ui/elements/TextInput.java @@ -5,6 +5,7 @@ import electrosphere.engine.signal.Signal.SignalType; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Model; import electrosphere.renderer.texture.Texture; @@ -22,7 +23,6 @@ import electrosphere.renderer.ui.events.ValueChangeEvent; import electrosphere.renderer.ui.font.Font; import org.joml.Vector3f; -import org.lwjgl.opengl.GL30; import org.lwjgl.util.yoga.Yoga; import java.util.regex.Pattern; @@ -106,7 +106,7 @@ public class TextInput extends StandardContainerElement implements DrawableEleme for(int i = 0; i < text.length(); i++){ char toDraw = text.charAt(i); Vector3f bitMapDimension = this.font.getDimensionOfCharacterDiscrete(toDraw); - BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.height, toDraw); + BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.getHeight(), toDraw); newLetter.setColor(color); this.addChild(newLetter); } @@ -137,19 +137,17 @@ public class TextInput extends StandardContainerElement implements DrawableEleme public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { // //Draw decorations - float ndcWidth = (float)getInternalWidth()/parentWidth; - float ndcHeight = (float)getInternalHeight()/parentHeight; - float ndcX = (float)(getInternalX() + parentPosX)/parentWidth; - float ndcY = (float)(getInternalY() + parentPosY)/parentHeight; + float ndcWidth = (float)getWidth()/framebuffer.getWidth(); + float ndcHeight = (float)getHeight()/framebuffer.getHeight(); + float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth(); + float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight(); boxPosition = new Vector3f(ndcX,ndcY,0); boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); @@ -163,8 +161,8 @@ public class TextInput extends StandardContainerElement implements DrawableEleme //this call binds the screen as the "texture" we're rendering to //have to call before actually rendering - openGLState.glBindFramebuffer(GL30.GL_FRAMEBUFFER, parentFramebufferPointer); - openGLState.glViewport(parentWidth, parentHeight); + framebuffer.bind(openGLState); + openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight()); //error if assets are null if(planeModel == null || windowFrame == null){ @@ -187,7 +185,7 @@ public class TextInput extends StandardContainerElement implements DrawableEleme // //Draw children elements for(Element child : childList){ - ((DrawableElement)child).draw(renderPipelineState, openGLState, parentFramebufferPointer, parentPosX + this.internalPositionX, parentPosY + this.internalPositionY, parentWidth, parentHeight); + ((DrawableElement)child).draw(renderPipelineState, openGLState, framebuffer, framebufferPosX, framebufferPosY); } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/ToggleInput.java b/src/main/java/electrosphere/renderer/ui/elements/ToggleInput.java index 16ea0872..b68916d8 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ToggleInput.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ToggleInput.java @@ -6,6 +6,7 @@ import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.elementtypes.ClickableElement; @@ -112,20 +113,18 @@ public class ToggleInput extends StandardDrawableElement implements ClickableEle public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ){ - Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer); - openGLState.glViewport(parentWidth, parentHeight); + framebuffer.bind(openGLState); + openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight()); - float ndcWidth = (float)getInternalWidth()/parentWidth; - float ndcHeight = (float)getInternalHeight()/parentHeight; - float ndcX = (float)(getInternalX() + parentPosX)/parentWidth; - float ndcY = (float)(getInternalY() + parentPosY)/parentHeight; + float ndcWidth = (float)getWidth()/framebuffer.getWidth(); + float ndcHeight = (float)getHeight()/framebuffer.getHeight(); + float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth(); + float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight(); Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); @@ -145,15 +144,15 @@ public class ToggleInput extends StandardDrawableElement implements ClickableEle circleOffsetActual = -CIRCLE_OFFSET_FROM_CENTER; } //ratio to adjust the circlewidth by to always show a circle and not a deformed oval - float circleRatio = getInternalWidth() / (float)getInternalHeight(); + float circleRatio = getWidth() / (float)getHeight(); Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); if(planeModel != null){ //draw bar - ndcX = (float)(getInternalX() + (getInternalWidth() * ((1.0f - CIRCLE_WIDTH)/2.0f)) + parentPosX)/parentWidth; - ndcY = (float)(getInternalY() + (getInternalHeight() * ((1.0f - BAR_HEIGHT) / 2.0f)) + parentPosY)/parentHeight; - ndcWidth = (float)((getInternalWidth()) - (getInternalWidth() * ((1.0f - CIRCLE_WIDTH))))/parentWidth; - ndcHeight = (float)(getInternalHeight() * BAR_HEIGHT)/parentHeight; + ndcX = (float)(this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX) + (getWidth() * ((1.0f - CIRCLE_WIDTH)/2.0f)))/framebuffer.getWidth(); + ndcY = (float)(this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY) + (getHeight() * ((1.0f - BAR_HEIGHT) / 2.0f)))/framebuffer.getHeight(); + ndcWidth = (float)((getWidth()) - (getWidth() * ((1.0f - CIRCLE_WIDTH))))/framebuffer.getWidth(); + ndcHeight = (float)(getHeight() * BAR_HEIGHT)/framebuffer.getHeight(); boxPosition = new Vector3f(ndcX,ndcY,0); boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); planeModel.getMeshes().get(0).setMaterial(barMat); @@ -163,10 +162,10 @@ public class ToggleInput extends StandardDrawableElement implements ClickableEle planeModel.drawUI(); //draw circle - ndcX = (float)(getInternalX() + (getInternalWidth() * ((1.0f - CIRCLE_WIDTH) / 2.0f)) + (getInternalWidth() * circleOffsetActual) + parentPosX)/parentWidth; - ndcY = (float)(getInternalY() + (getInternalHeight() * ((1.0f - (CIRCLE_WIDTH * circleRatio)) / 2.0f)) + parentPosY)/parentHeight; - ndcWidth = (float)((getInternalWidth() * CIRCLE_WIDTH))/parentWidth; - ndcHeight = (float)(getInternalHeight() * (CIRCLE_WIDTH * circleRatio))/parentHeight; + ndcX = (float)(this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX) + (getWidth() * ((1.0f - CIRCLE_WIDTH) / 2.0f)) + (getWidth() * circleOffsetActual))/framebuffer.getWidth(); + ndcY = (float)(this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY) + (getHeight() * ((1.0f - (CIRCLE_WIDTH * circleRatio)) / 2.0f)))/framebuffer.getHeight(); + ndcWidth = (float)((getWidth() * CIRCLE_WIDTH))/framebuffer.getWidth(); + ndcHeight = (float)(getHeight() * (CIRCLE_WIDTH * circleRatio))/framebuffer.getHeight(); boxPosition = new Vector3f(ndcX,ndcY,0); boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); planeModel.getMeshes().get(0).setMaterial(circleMat); diff --git a/src/main/java/electrosphere/renderer/ui/elements/VirtualScrollable.java b/src/main/java/electrosphere/renderer/ui/elements/VirtualScrollable.java index e5dacf9e..55a0376c 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/VirtualScrollable.java +++ b/src/main/java/electrosphere/renderer/ui/elements/VirtualScrollable.java @@ -4,6 +4,7 @@ import org.lwjgl.util.yoga.Yoga; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.ScrollableElement; @@ -38,11 +39,9 @@ public class VirtualScrollable extends StandardContainerElement implements Drawa public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { for(Element child : childList){ if(child instanceof DrawableElement){ @@ -51,11 +50,9 @@ public class VirtualScrollable extends StandardContainerElement implements Drawa drawableChild.draw( renderPipelineState, openGLState, - parentFramebufferPointer, - parentPosX + internalPositionX, - (int)(parentPosY + internalPositionY + scroll), - parentWidth, - parentHeight + framebuffer, + framebufferPosX, + framebufferPosY ); } } @@ -69,7 +66,7 @@ public class VirtualScrollable extends StandardContainerElement implements Drawa */ private boolean childIsInBounds(DrawableElement element){ boolean rVal = true; - if(element.getInternalY() + scroll < 0 ||element.getInternalY() + scroll > this.height){ + if(element.getAbsoluteX() + scroll < 0 ||element.getAbsoluteY() + scroll > this.getHeight()){ return false; } return rVal; @@ -85,20 +82,6 @@ public class VirtualScrollable extends StandardContainerElement implements Drawa this.visible = draw; } - @Override - public void setWidth(int width) { - this.internalWidth = width; - this.width = width; - Yoga.YGNodeStyleSetWidth(this.yogaNode, width); - } - - @Override - public void setHeight(int height) { - this.internalHeight = height; - this.height = height; - Yoga.YGNodeStyleSetHeight(this.yogaNode, height); - } - @Override public int getChildOffsetY(){ return (int)scroll; @@ -121,15 +104,15 @@ public class VirtualScrollable extends StandardContainerElement implements Drawa //calculate max scroll double maxScroll = 0; for(Element child : this.getChildren()){ - if(child.getInternalY() + child.getInternalHeight() > maxScroll){ - maxScroll = child.getInternalY() + child.getInternalHeight() - this.internalHeight; + if(child.getAbsoluteY() + child.getHeight() > maxScroll){ + maxScroll = child.getAbsoluteY() + child.getHeight() - this.getHeight(); } } if(scroll < - maxScroll){ scroll = -maxScroll; } for(Element childElement : this.getChildren()){ - childElement.setPositionX((int)(childElement.getInternalX() + scroll)); + childElement.setPositionX((int)(childElement.getAbsoluteX() + scroll)); } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/Window.java b/src/main/java/electrosphere/renderer/ui/elements/Window.java index df318d8a..fdb86026 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Window.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Window.java @@ -4,7 +4,6 @@ import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT; import static org.lwjgl.opengl.GL11.glClear; import static org.lwjgl.opengl.GL11.glClearColor; -import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER; import java.util.LinkedList; import java.util.List; @@ -19,7 +18,6 @@ import electrosphere.engine.signal.Signal.SignalType; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; -import electrosphere.renderer.debug.DebugRendering; import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.FramebufferUtils; import electrosphere.renderer.model.Material; @@ -43,8 +41,6 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme Framebuffer widgetBuffer; Material customMat = new Material(); - Vector3f boxPosition = new Vector3f(); - Vector3f boxDimensions = new Vector3f(); Vector3f texPosition = new Vector3f(0,0,0); Vector3f texScale = new Vector3f(1,1,0); @@ -78,12 +74,6 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme LoggerInterface.loggerRenderer.ERROR(e); } customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer()); - float ndcWidth = (float)width/Globals.WINDOW_WIDTH; - float ndcHeight = (float)height/Globals.WINDOW_HEIGHT; - float ndcX = (float)positionX/Globals.WINDOW_WIDTH; - float ndcY = (float)positionY/Globals.WINDOW_HEIGHT; - boxPosition = new Vector3f(ndcX,ndcY,0); - boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); this.showDecorations = showDecorations; //yoga node for the actually visible part this.yogaNode = Yoga.YGNodeNew(); @@ -94,6 +84,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme setParentAlignContent(YogaAlignment.Start); setParentAlignItem(YogaAlignment.Start); setParentJustifyContent(YogaJustification.Start); + this.setFlexDirection(YogaFlexDirection.Column); this.setWidth(width); this.setHeight(height); } @@ -113,12 +104,6 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme LoggerInterface.loggerRenderer.ERROR(e); } customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer()); - float ndcWidth = (float)width/Globals.WINDOW_WIDTH; - float ndcHeight = (float)height/Globals.WINDOW_HEIGHT; - float ndcX = (float)positionX/Globals.WINDOW_WIDTH; - float ndcY = (float)positionY/Globals.WINDOW_HEIGHT; - boxPosition = new Vector3f(ndcX,ndcY,0); - boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); //yoga node for the actually visible part this.yogaNode = Yoga.YGNodeNew(); this.layout = YGNode.create(this.yogaNode).layout(); @@ -128,6 +113,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme setParentAlignContent(YogaAlignment.Start); setParentAlignItem(YogaAlignment.Start); setParentJustifyContent(YogaJustification.Start); + this.setFlexDirection(YogaFlexDirection.Column); this.setMinWidth(width); this.setMinHeight(height); } @@ -181,19 +167,16 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ) { - - float ndcWidth = (float)this.getInternalWidth()/Globals.WINDOW_WIDTH; - float ndcHeight = (float)this.getInternalHeight()/Globals.WINDOW_HEIGHT; - float ndcX = (float)this.getInternalX()/Globals.WINDOW_WIDTH; - float ndcY = (float)this.getInternalY()/Globals.WINDOW_HEIGHT; - boxPosition = new Vector3f(ndcX,ndcY,0); - boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); + float ndcWidth = (float)this.getWidth()/framebuffer.getWidth(); + float ndcHeight = (float)this.getHeight()/framebuffer.getHeight(); + float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth(); + float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight(); + Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); + Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); widgetBuffer.bind(openGLState); openGLState.glViewport(width, height); @@ -208,13 +191,13 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme for(Element child : childList){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; - drawableChild.draw(renderPipelineState,openGLState,widgetBuffer.getFramebufferPointer(),parentPosX,parentPosY,width,height); + drawableChild.draw(renderPipelineState,openGLState,widgetBuffer,this.getAbsoluteX(),this.getAbsoluteY()); } } //this call binds the screen as the "texture" we're rendering to //have to call before actually rendering - openGLState.glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer); - openGLState.glViewport(parentWidth, parentHeight); + framebuffer.bind(openGLState); + openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight()); //error if assets are null if(planeModel == null || windowFrame == null){ @@ -244,10 +227,6 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme planeModel.getMeshes().get(0).setMaterial(customMat); planeModel.drawUI(); } - - if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_WINDOW){ - DebugRendering.drawUIBoundsWindow(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor); - } } /** @@ -278,26 +257,12 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme public void setWidth(int width){ this.width = width; Yoga.YGNodeStyleSetWidth(this.yogaNode, width); - for(Element child : childList){ - if(child instanceof DrawableElement){ - DrawableElement drawableChild = (DrawableElement) child; - drawableChild.setParentWidth(width); - drawableChild.setParentHeight(height); - } - } } @Override public void setHeight(int height){ this.height = height; Yoga.YGNodeStyleSetHeight(this.yogaNode, height); - for(Element child : childList){ - if(child instanceof DrawableElement){ - DrawableElement drawableChild = (DrawableElement) child; - drawableChild.setParentWidth(width); - drawableChild.setParentHeight(height); - } - } } @Override @@ -343,12 +308,9 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme public int width = 1; public int height = 1; - public int positionX = 0; - public int positionY = 0; + public int absoluteX = 0; + public int absoluteY = 0; - public int parentWidth = 1; - public int parentHeight = 1; - int marginTop = 0; int marginRight = 0; int marginBottom = 0; @@ -364,14 +326,6 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme return height; } - public int getPositionX() { - return positionX; - } - - public int getPositionY() { - return positionY; - } - public boolean getVisible() { return visible; } @@ -380,16 +334,6 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme this.visible = draw; } - @Override - public void setPositionX(int positionX) { - this.positionX = positionX; - } - - @Override - public void setPositionY(int positionY) { - this.positionY = positionY; - } - public int getMarginTop(){ return marginTop; } @@ -422,16 +366,6 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme this.marginLeft = marginLeft; } - @Override - public void setParentWidth(int width) { - this.width = width; - } - - @Override - public void setParentHeight(int height) { - this.height = height; - } - //the yoga node id long yogaNode = -1; //the layout object @@ -469,14 +403,14 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); //apply the values to this component - this.positionX = (int)leftRaw; - this.positionY = (int)topRaw; + this.absoluteX = (int)leftRaw; + this.absoluteY = (int)topRaw; this.width = (int)widthRaw; this.height = (int)heightRaw; //apply yoga values to all children LoggerInterface.loggerUI.DEBUG("==Apply yoga to windoow=="); for(Element child : this.getChildren()){ - child.applyYoga(this.positionX,this.positionY); + child.applyYoga(this.absoluteX,this.absoluteY); } } } @@ -596,14 +530,44 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme Yoga.YGNodeStyleSetAlignContent(this.yogaNode, alignmentInteger); } + @Override + public void setAlignSelf(YogaAlignment alignment){ + int alignmentInteger = Yoga.YGAlignAuto; + switch(alignment){ + case Auto: + alignmentInteger = Yoga.YGAlignAuto; + break; + case Start: + alignmentInteger = Yoga.YGAlignFlexStart; + break; + case End: + alignmentInteger = Yoga.YGAlignFlexEnd; + break; + case Around: + alignmentInteger = Yoga.YGAlignSpaceAround; + break; + case Between: + alignmentInteger = Yoga.YGAlignSpaceBetween; + break; + case Stretch: + alignmentInteger = Yoga.YGAlignStretch; + break; + case Baseline: + alignmentInteger = Yoga.YGAlignBaseline; + break; + case Center: + alignmentInteger = Yoga.YGAlignCenter; + break; + } + Yoga.YGNodeStyleSetAlignSelf(this.yogaNode, alignmentInteger); + } + @Override public void addChild(Element child) { childList.add(child); child.setParent(this); if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; - drawableChild.setParentWidth(width); - drawableChild.setParentHeight(height); drawableChild.setVisible(false); Yoga.YGNodeInsertChild(yogaNode, drawableChild.getYogaNode(), childList.size() - 1); } @@ -646,26 +610,6 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme return null; } - @Override - public int getInternalX() { - return positionX; - } - - @Override - public int getInternalY() { - return positionY; - } - - @Override - public int getInternalWidth() { - return width; - } - - @Override - public int getInternalHeight() { - return height; - } - @Override public int getChildOffsetX(){ return 0; @@ -815,26 +759,6 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme } } - @Override - public int getRelativeX() { - return this.positionX; - } - - @Override - public int getRelativeY() { - return this.positionY; - } - - @Override - public int getAbsoluteX() { - return this.positionX; - } - - @Override - public int getAbsoluteY() { - return this.positionY; - } - @Override public void setAbsolutePosition(boolean useAbsolutePosition) { //not implemented @@ -847,4 +771,44 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme throw new UnsupportedOperationException(); } + /** + * Converts an absolute (to the screen) position to a position within a framebuffer + * @param absolutePos The absolute position + * @param framebufferPos The position of the framebuffer on the screen + * @return The position within the framebuffer + */ + public int absoluteToFramebuffer(int absolutePos, int framebufferPos){ + return absolutePos - framebufferPos; + } + + @Override + public int getRelativeX() { + return absoluteX; + } + + @Override + public int getRelativeY() { + return absoluteY; + } + + @Override + public int getAbsoluteX() { + return absoluteX; + } + + @Override + public int getAbsoluteY() { + return absoluteY; + } + + @Override + public void setPositionX(int positionX) { + Yoga.YGNodeStyleSetPosition(this.yogaNode, Yoga.YGEdgeLeft, positionX); + } + + @Override + public void setPositionY(int positionY) { + Yoga.YGNodeStyleSetPosition(this.yogaNode, Yoga.YGEdgeTop, positionY); + } + } diff --git a/src/main/java/electrosphere/renderer/ui/elements/Word.java b/src/main/java/electrosphere/renderer/ui/elements/Word.java index 205224f9..fd9b6800 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Word.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Word.java @@ -5,6 +5,7 @@ import electrosphere.engine.signal.Signal.SignalType; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.Event; @@ -108,11 +109,9 @@ public class Word extends StandardDrawableContainerElement { public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, - int parentFramebufferPointer, - int parentPosX, - int parentPosY, - int parentWidth, - int parentHeight + Framebuffer framebuffer, + int framebufferPosX, + int framebufferPosY ){ //draw characters @@ -120,11 +119,9 @@ public class Word extends StandardDrawableContainerElement { ((DrawableElement)child).draw( renderPipelineState, openGLState, - parentFramebufferPointer, - parentPosX + this.internalPositionX, - parentPosY + this.internalPositionY, - parentWidth, - parentHeight + framebuffer, + framebufferPosX, + framebufferPosY ); } } diff --git a/src/main/java/electrosphere/renderer/ui/elementtypes/DrawableElement.java b/src/main/java/electrosphere/renderer/ui/elementtypes/DrawableElement.java index d4953da2..644ee3c8 100644 --- a/src/main/java/electrosphere/renderer/ui/elementtypes/DrawableElement.java +++ b/src/main/java/electrosphere/renderer/ui/elementtypes/DrawableElement.java @@ -2,6 +2,7 @@ package electrosphere.renderer.ui.elementtypes; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.framebuffer.Framebuffer; /** * A UI Element that is actually drawable to the screen @@ -24,13 +25,9 @@ public interface DrawableElement extends Element { * Draws the element * @param renderPipelineState The render pipeline state * @param openGLState The opengl state - * @param parentFramebufferPointer The parent's framebuffer pointer - * @param parentPosX the parent's position x - * @param parentPosY the parent's position y - * @param parentWidth the parent's width - * @param parentHeight the parent's height + * @param framebuffer The framebuffer to render to */ - public abstract void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentPosX, int parentPosY, int parentWidth, int parentHeight); + public abstract void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, Framebuffer framebuffer, int framebufferPosX, int framebufferPosY); } diff --git a/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java b/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java index 875e1102..60b02f79 100644 --- a/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java +++ b/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java @@ -1,5 +1,6 @@ package electrosphere.renderer.ui.elementtypes; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; import electrosphere.renderer.ui.events.Event; public interface Element { @@ -35,8 +36,6 @@ public interface Element { public void setAbsolutePosition(boolean useAbsolutePosition); //parent data - public void setParentWidth(int width); - public void setParentHeight(int height); public Element getParent(); public void setParent(Element parent); @@ -46,32 +45,11 @@ public interface Element { public void setMarginBottom(int marginBottom); public void setMarginLeft(int marginLeft); - - - - // - // I N T E R N A L - // /** - * Gets the internal x position. This is the position x value used by the layout manager. It corresponds to what is actually displayed. - * @return The internal position x coordinate + * Sets the self alignment + * @param alignment the alignment style */ - public int getInternalX(); - /** - * Gets the internal y position. This is the position y value used by the layout manager. It corresponds to what is actually displayed. - * @return The internal position y coordinate - */ - public int getInternalY(); - /** - * Gets the internal width. This is the width value used by the layout manager. It corresponds to what is actually displayed. - * @return The internal width - */ - public int getInternalWidth(); - /** - * Gets the internal height. This is the height value used by the layout manager. It corresponds to what is actually displayed. - * @return The internal height - */ - public int getInternalHeight(); + public void setAlignSelf(YogaAlignment alignment); // diff --git a/src/test/java/electrosphere/renderer/ui/elements/BitmapCharacterTests.java b/src/test/java/electrosphere/renderer/ui/elements/BitmapCharacterTests.java new file mode 100644 index 00000000..7b68ba6f --- /dev/null +++ b/src/test/java/electrosphere/renderer/ui/elements/BitmapCharacterTests.java @@ -0,0 +1,28 @@ +package electrosphere.renderer.ui.elements; +import electrosphere.engine.Globals; +import electrosphere.menu.WindowUtils; +import electrosphere.test.annotations.IntegrationTest; +import electrosphere.test.template.UITestTemplate; +import electrosphere.test.testutils.TestEngineUtils; + +/** + * Tests the button ui component + */ +public class BitmapCharacterTests extends UITestTemplate { + + @IntegrationTest + public void test_Create(){ + //setup + this.setupBlankView(); + BitmapCharacter el = new BitmapCharacter(Globals.fontManager.getFont("default"), 16, 24, 'A'); + WindowUtils.replaceMainMenuContents(el); + + + //wait for ui updates + TestEngineUtils.flush(); + TestEngineUtils.simulateFrames(1); + + this.checkRender("Basic", "./test/java/renderer/ui/elements/bitmapchar1.png"); + } + +} diff --git a/src/test/java/electrosphere/renderer/ui/elements/ButtonTests.java b/src/test/java/electrosphere/renderer/ui/elements/ButtonTests.java index 085c2bdf..d486e88e 100644 --- a/src/test/java/electrosphere/renderer/ui/elements/ButtonTests.java +++ b/src/test/java/electrosphere/renderer/ui/elements/ButtonTests.java @@ -13,7 +13,8 @@ public class ButtonTests extends UITestTemplate { public void test_Create(){ //setup this.setupBlankView(); - WindowUtils.replaceMainMenuContents(Button.createButton("test", () -> {})); + Button button = Button.createButton("test", () -> {}); + WindowUtils.replaceMainMenuContents(button); //wait for ui updates diff --git a/src/test/java/electrosphere/renderer/ui/elements/ImagePanelTests.java b/src/test/java/electrosphere/renderer/ui/elements/ImagePanelTests.java index cfda24f1..5648ae3a 100644 --- a/src/test/java/electrosphere/renderer/ui/elements/ImagePanelTests.java +++ b/src/test/java/electrosphere/renderer/ui/elements/ImagePanelTests.java @@ -16,6 +16,22 @@ public class ImagePanelTests extends UITestTemplate { WindowUtils.replaceMainMenuContents(ImagePanel.createImagePanelAbsolute(0,0,50,50,"Textures/default_diffuse.png")); + //wait for ui updates + TestEngineUtils.flush(); + TestEngineUtils.simulateFrames(1); + + this.checkRender("Basic", "./test/java/renderer/ui/elements/imagepanel1.png"); + } + + @IntegrationTest + public void test_CreateInsideScrollable(){ + //setup + this.setupBlankView(); + ScrollableContainer container = ScrollableContainer.createScrollable(); + container.addChild(ImagePanel.createImagePanelAbsolute(0,0,50,50,"Textures/default_diffuse.png")); + WindowUtils.replaceMainMenuContents(container); + + //wait for ui updates TestEngineUtils.flush(); TestEngineUtils.simulateFrames(1); diff --git a/test/java/renderer/ui/elements/bitmapchar1.png b/test/java/renderer/ui/elements/bitmapchar1.png new file mode 100644 index 0000000000000000000000000000000000000000..cea8d0d59a54de44617e68b8597efb3086e61f45 GIT binary patch literal 10788 zcmeI2|4$or7{^a!gTbJSENeC+g_t}>M`Epyr0Na>dywTzZ)SqmJr*YmEu#$WsgmVEA~ zC!f#r`S#B1c|Lbf?#okE{G6Qn{)x$vpcRAh?TVYxnwVBz$xV-qSOE1o({3T8Sz0s;07o!H3ISu_z!`-s>=~|b=>ipIv zUVdBTzAK->5TeAE;~SyC!x|yB*iG<|c!tA@QR$|)hsQZ2#SPZUD|8dbyNl{X?&uE_ z3twrXWjoExHq+K}|3RNsZ;Djb80yC_%67!;XEhko-I1DX$l_qL*`t?aBT=U;h|Qa6 zJoyuy4B3R4U&~omy5?eC5^X;#EQ1 z|7VH=$1x2rj@GC+?-G`*~C7w>*J-b(ZBi!TuW+83xM zdpBiFe4kEPZ|tXx!2=XZs*^jYrt=k)A*u#b5mErHNFD$TiKqZD02n|PB^dzM1gQeJ zQb`p63<(tg3;+i3vQ07oz9tfp0AK(xfX{G}0Z?a1B!p)JhLEIX@j6j@RW*F0wB?=J zR#_~CAa|-7q!OemMch;s2~Aa)fD_OOphAQ?2m~Mjpa28{dFz8*03-kufItAbfK&kF z0w4jP00aW50LTSEf@hop(aIl3a)>jS3-Ey=QPzzMA(Cqddh@}yqye3zQ^xCclreXS h`soTd{hv^0%wX29Ar`{{?Z#nF9a- literal 0 HcmV?d00001