155 lines
5.9 KiB
Java
155 lines
5.9 KiB
Java
package electrosphere.renderer.ui.elements;
|
|
|
|
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 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.DrawableElement;
|
|
import electrosphere.renderer.ui.elementtypes.Element;
|
|
|
|
/**
|
|
* A drawable container component that draws to an internal framebuffer before rendering that framebuffer on its own draw call**
|
|
*/
|
|
public class BufferedStandardDrawableContainerElement extends StandardDrawableContainerElement {
|
|
|
|
/**
|
|
* The default width of an actor panel
|
|
*/
|
|
public static final int DEFAULT_WIDTH = 50;
|
|
|
|
/**
|
|
* The default height of an actor panel
|
|
*/
|
|
public static final int DEFAULT_HEIGHT = 50;
|
|
|
|
/**
|
|
* The material that contains the internal framebuffer's texture
|
|
*/
|
|
Material elementMat;
|
|
|
|
/**
|
|
* The internal framebuffer for this component (all children are rendered to this, then this texture is rendered to a quad itself)
|
|
*/
|
|
Framebuffer elementBuffer;
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
public BufferedStandardDrawableContainerElement(){
|
|
super();
|
|
elementMat = new Material();
|
|
this.regenerateFramebuffer(DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
|
}
|
|
|
|
|
|
@Override
|
|
public void draw(
|
|
RenderPipelineState renderPipelineState,
|
|
OpenGLState openGLState,
|
|
Framebuffer framebuffer,
|
|
int framebufferPosX,
|
|
int framebufferPosY
|
|
) {
|
|
|
|
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);
|
|
Vector3f texScale = new Vector3f(1,1,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(elementBuffer.getWidth(), elementBuffer.getHeight());
|
|
|
|
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,
|
|
this.elementBuffer,
|
|
this.getAbsoluteX(),
|
|
this.getAbsoluteY()
|
|
);
|
|
}
|
|
}
|
|
//this call binds the screen as the "texture" we're rendering to
|
|
//have to call before actually rendering
|
|
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);
|
|
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);
|
|
planeModel.pushUniformToMesh("plane", "tPosition", texPosition);
|
|
planeModel.pushUniformToMesh("plane", "tDimension", texScale);
|
|
elementMat.setTexturePointer(elementBuffer.getTexture().getTexturePointer());
|
|
planeModel.getMeshes().get(0).setMaterial(elementMat);
|
|
planeModel.drawUI();
|
|
} else {
|
|
LoggerInterface.loggerRenderer.ERROR("ScrollableContainer unable to find plane model!!", new Exception());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void applyYoga(int parentX, int parentY){
|
|
super.applyYoga(parentX, parentY);
|
|
this.regenerateFramebuffer(this.getWidth(), this.getHeight());
|
|
}
|
|
|
|
/**
|
|
* Regenerates the backing framebuffer
|
|
* @param width The width of the new buffer
|
|
* @param height The height of the new buffer
|
|
*/
|
|
protected void regenerateFramebuffer(int width, int height){
|
|
if(width <= 1 || height <= 1){
|
|
throw new Error("Invalid dimensions set! " + width + " " + height);
|
|
}
|
|
if(elementBuffer != null){
|
|
elementBuffer.free();
|
|
}
|
|
try {
|
|
elementBuffer = FramebufferUtils.generateTextureFramebuffer(Globals.renderingEngine.getOpenGLState(), width, height);
|
|
} catch(Exception e){
|
|
LoggerInterface.loggerRenderer.ERROR(e);
|
|
}
|
|
elementMat.setTexturePointer(elementBuffer.getTexture().getTexturePointer());
|
|
}
|
|
|
|
|
|
}
|