Renderer/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java
austin 73a5d79bc2
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
tests, datastructure, debug work
2024-09-08 21:39:54 -04:00

202 lines
8.6 KiB
Java

package electrosphere.renderer.ui.elements;
import org.joml.Vector3f;
import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderPipelineState;
import electrosphere.renderer.framebuffer.Framebuffer;
import electrosphere.renderer.framebuffer.FramebufferUtils;
import electrosphere.renderer.model.Material;
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 StandardContainerElement implements DrawableElement {
Vector3f color = new Vector3f(1.0f);
boolean focused = false;
public boolean visible = false;
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);
public ScrollableContainer(OpenGLState openGLState, int positionX, int positionY, int width, int height){
super();
try {
widgetBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height);
} catch(Exception e){
LoggerInterface.loggerRenderer.ERROR(e);
}
// widgetBuffer = FramebufferUtils.generateScreensizeTextureFramebuffer();
customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer());
// customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer());
float ndcX = (float)positionX/Globals.WINDOW_WIDTH;
float ndcY = (float)positionY/Globals.WINDOW_HEIGHT;
float ndcWidth = (float)width/Globals.WINDOW_WIDTH;
float ndcHeight = (float)height/Globals.WINDOW_HEIGHT;
setWidth(width);
setHeight(height);
boxPosition = new Vector3f(ndcX,ndcY,0);
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
}
@Override
public boolean handleEvent(Event event) {
return false;
}
@Override
public boolean getVisible() {
return visible;
}
@Override
public void setVisible(boolean visible) {
this.visible = visible;
}
//recursively check if focused element is child of input element or is input element
boolean containsFocusedElement(Element parent){
Element focusedElement = Globals.elementService.getFocusedElement();
if(parent == focusedElement){
return true;
} else if(parent instanceof ContainerElement){
ContainerElement container = (ContainerElement)parent;
for(Element child : container.getChildren()){
if(containsFocusedElement(child)){
return true;
}
}
}
return false;
}
@Override
public void draw(
RenderPipelineState renderPipelineState,
OpenGLState openGLState,
int parentFramebufferPointer,
int parentPosX,
int parentPosY,
int parentWidth,
int parentHeight
) {
//figure out if currently focused element is a child or subchild of this container
if(containsFocusedElement(this)){
//if it is, if it is offscreen, calculate offset to put it onscreen
Element focused = Globals.elementService.getFocusedElement();
if(
focused.getRelativeX() + focused.getWidth() > this.width ||
focused.getRelativeY() + focused.getHeight() > this.height ||
focused.getRelativeX() < 0 ||
focused.getRelativeY() < 0
){
int neededOffsetX = 0;
int neededOffsetY = 0;
//basically if we're offscreen negative, pull to positive
//if we're offscreen positive and we're not as large as the screen, pull from the positive into focus
//if we are larger than the screen, set position to 0
if(focused.getRelativeX() < 0){
neededOffsetX = -focused.getRelativeX();
} else if(focused.getRelativeX() + focused.getWidth() > this.width){
if(focused.getWidth() > this.width){
neededOffsetX = -focused.getRelativeX();
} else {
neededOffsetX = -((focused.getRelativeX() - this.width) + focused.getWidth());
}
}
if(focused.getRelativeY() < 0){
neededOffsetY = -focused.getRelativeY();
} else if(focused.getRelativeY() + focused.getHeight() > this.height){
if(focused.getHeight() > this.height){
neededOffsetY = -focused.getRelativeY();
} else {
neededOffsetY = -((focused.getRelativeY() - this.height) + focused.getHeight());
// System.out.println(focused.getPositionY() + " " + this.height + " " + focused.getHeight());
}
}
//apply offset to all children
for(Element child : childList){
int newX = child.getRelativeX() + neededOffsetX;
int newY = child.getRelativeY() + neededOffsetY;
child.setPositionX(newX);
child.setPositionY(newY);
// System.out.println(currentX + " " + currentY);
}
}
}
float ndcX = (float)internalPositionX/parentWidth;
float ndcY = (float)internalPositionY/parentHeight;
float ndcWidth = (float)internalWidth/parentWidth;
float ndcHeight = (float)internalHeight/parentHeight;
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");
widgetBuffer.bind(openGLState);
openGLState.glViewport(width, height);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for(Element child : childList){
if(child instanceof DrawableElement){
DrawableElement drawableChild = (DrawableElement) child;
drawableChild.draw(renderPipelineState,openGLState,widgetBuffer.getFramebufferPointer(),0,0,width,height);
}
}
//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);
//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);
customMat.setTexturePointer(windowFrame.getTexturePointer());
planeModel.getMeshes().get(0).setMaterial(customMat);
planeModel.drawUI();
}
if(planeModel != 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);
customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer());
planeModel.getMeshes().get(0).setMaterial(customMat);
planeModel.drawUI();
} else {
LoggerInterface.loggerRenderer.ERROR("ScrollableContainer unable to find plane model!!", new Exception());
}
}
}