package electrosphere.renderer.ui; 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 static org.lwjgl.opengl.GL30.glBindFramebuffer; import java.util.LinkedList; import java.util.List; 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.framebuffer.FramebufferUtils; import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.elementtypes.ContainerElement; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.NavigableElement; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.events.NavigationEvent; /** * * @author amaterasu */ public class Window implements DrawableElement, ContainerElement, NavigableElement { List childList = new LinkedList(); 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); NavigationEventCallback navCallback; static final Vector3f windowDrawDebugColor = new Vector3f(1.0f,0.0f,0.0f); public Window(int positionX, int positionY, int width, int height){ //TODO: figure out why this has to be 1920x1080 widgetBuffer = FramebufferUtils.generateTextureFramebuffer(width, height); // widgetBuffer = FramebufferUtils.generateScreensizeTextureFramebuffer(); customMat.setTexturePointer(widgetBuffer.getTexturePointer()); // customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").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; this.width = width; this.height = height; boxPosition = new Vector3f(ndcX,ndcY,0); boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); } @Override public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { widgetBuffer.bind(); 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(),width,height); } } //this call binds the screen as the "texture" we're rendering to //have to call before actually rendering glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer); openGLState.glViewport(parentWidth, parentHeight); Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); if(planeModel != null){ planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); planeModel.getMeshes().get(0).setMaterial(customMat); planeModel.drawUI(); } else { LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model!!", new Exception()); } if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_WINDOW){ DebugRendering.drawUIBoundsWindow(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor); } } public void pack() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public void setWidth(int width){ this.width = 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; for(Element child : childList){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; drawableChild.setParentWidth(width); drawableChild.setParentHeight(height); } } } // public void setTextureCoord(int x, int y){ // float ndcX = (float)x/Globals.WINDOW_WIDTH; // float ndcY = (float)y/Globals.WINDOW_HEIGHT; // texPosition = new Vector3f(ndcX,ndcY,0); // } // public void setTextureScale(int x, int y){ // float ndcWidth = (float)x/Globals.WINDOW_WIDTH; // float ndcHeight = (float)y/Globals.WINDOW_HEIGHT; // texScale = new Vector3f(ndcWidth,ndcHeight,0); // } public int width = 1; public int height = 1; public int positionX = 0; public int positionY = 0; public int parentWidth = 1; public int parentHeight = 1; public boolean visible = false; public int getWidth() { return width; } public int getHeight() { return height; } public int getPositionX() { return positionX; } public int getPositionY() { return positionY; } public boolean getVisible() { return visible; } public void setVisible(boolean draw) { this.visible = draw; } @Override public void setPositionX(int positionX) { this.positionX = positionX; } @Override public void setPositionY(int positionY) { this.positionY = positionY; } @Override public void setParentWidth(int width) { this.width = width; } @Override public void setParentHeight(int height) { this.height = height; } @Override public void addChild(Element child) { childList.add(child); if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; drawableChild.setParentWidth(width); drawableChild.setParentHeight(height); drawableChild.setVisible(false); } } @Override public List getChildren() { return childList; } @Override public void removeChild(Element child) { childList.remove(child); } public boolean handleEvent(Event event){ boolean propagate = true; if(event instanceof NavigationEvent && navCallback != null){ if(!navCallback.execute((NavigationEvent)event)){ propagate = false; } } return propagate; } @Override public void setOnNavigationCallback(NavigationEventCallback callback) { navCallback = callback; } }