slider fixes, dragevent fixes, new component
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
963e8b6585
commit
63feb835cd
@ -768,6 +768,10 @@ Fix gridded data cell manager saving attached items on realm save
|
|||||||
Fix render signals caching between frames (not reseting global flags per usual)
|
Fix render signals caching between frames (not reseting global flags per usual)
|
||||||
Capture image from opengl to pixel-check
|
Capture image from opengl to pixel-check
|
||||||
Add ui tests
|
Add ui tests
|
||||||
|
Fix image panel displaying texture flipped
|
||||||
|
Fix drag event relative positions
|
||||||
|
Fix slider behavior
|
||||||
|
New character customizer component
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|||||||
@ -32,7 +32,6 @@ import electrosphere.renderer.ui.elements.Slider;
|
|||||||
import electrosphere.renderer.ui.elements.VirtualScrollable;
|
import electrosphere.renderer.ui.elements.VirtualScrollable;
|
||||||
import electrosphere.renderer.ui.elements.Window;
|
import electrosphere.renderer.ui.elements.Window;
|
||||||
import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback;
|
import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback;
|
||||||
import electrosphere.renderer.ui.elementtypes.ValueElement;
|
|
||||||
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
|
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
|
||||||
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
|
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
|
||||||
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
|
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
|
||||||
@ -393,39 +392,39 @@ public class MenuGeneratorsLevelEditor {
|
|||||||
xDiv.setMaxHeight(50);
|
xDiv.setMaxHeight(50);
|
||||||
xDiv.setFlexDirection(YogaFlexDirection.Row);
|
xDiv.setFlexDirection(YogaFlexDirection.Row);
|
||||||
xDiv.addChild(Label.createLabel("X: "));
|
xDiv.addChild(Label.createLabel("X: "));
|
||||||
xDiv.addChild(Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
|
xDiv.addChild(Slider.createSlider((ValueChangeEvent event) -> {
|
||||||
LightManager lightManager = Globals.renderingEngine.getLightManager();
|
LightManager lightManager = Globals.renderingEngine.getLightManager();
|
||||||
DirectionalLight directionalLight = lightManager.getDirectionalLight();
|
DirectionalLight directionalLight = lightManager.getDirectionalLight();
|
||||||
Vector3f direction = directionalLight.getDirection();
|
Vector3f direction = directionalLight.getDirection();
|
||||||
direction.x = event.getAsFloat() * 2 - 1;
|
direction.x = event.getAsFloat() * 2 - 1;
|
||||||
directionalLight.setDirection(direction);
|
directionalLight.setDirection(direction);
|
||||||
}}));
|
}));
|
||||||
scrollable.addChild(xDiv);
|
scrollable.addChild(xDiv);
|
||||||
|
|
||||||
Div yDiv = Div.createDiv();
|
Div yDiv = Div.createDiv();
|
||||||
yDiv.setMaxHeight(50);
|
yDiv.setMaxHeight(50);
|
||||||
yDiv.setFlexDirection(YogaFlexDirection.Row);
|
yDiv.setFlexDirection(YogaFlexDirection.Row);
|
||||||
yDiv.addChild(Label.createLabel("Y: "));
|
yDiv.addChild(Label.createLabel("Y: "));
|
||||||
yDiv.addChild(Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
|
yDiv.addChild(Slider.createSlider((ValueChangeEvent event) -> {
|
||||||
LightManager lightManager = Globals.renderingEngine.getLightManager();
|
LightManager lightManager = Globals.renderingEngine.getLightManager();
|
||||||
DirectionalLight directionalLight = lightManager.getDirectionalLight();
|
DirectionalLight directionalLight = lightManager.getDirectionalLight();
|
||||||
Vector3f direction = directionalLight.getDirection();
|
Vector3f direction = directionalLight.getDirection();
|
||||||
direction.y = event.getAsFloat() * 2 - 1;
|
direction.y = event.getAsFloat() * 2 - 1;
|
||||||
directionalLight.setDirection(direction);
|
directionalLight.setDirection(direction);
|
||||||
}}));
|
}));
|
||||||
scrollable.addChild(yDiv);
|
scrollable.addChild(yDiv);
|
||||||
|
|
||||||
Div zDiv = Div.createDiv();
|
Div zDiv = Div.createDiv();
|
||||||
zDiv.setMaxHeight(50);
|
zDiv.setMaxHeight(50);
|
||||||
zDiv.setFlexDirection(YogaFlexDirection.Row);
|
zDiv.setFlexDirection(YogaFlexDirection.Row);
|
||||||
zDiv.addChild(Label.createLabel("Z: "));
|
zDiv.addChild(Label.createLabel("Z: "));
|
||||||
zDiv.addChild(Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
|
zDiv.addChild(Slider.createSlider((ValueChangeEvent event) -> {
|
||||||
LightManager lightManager = Globals.renderingEngine.getLightManager();
|
LightManager lightManager = Globals.renderingEngine.getLightManager();
|
||||||
DirectionalLight directionalLight = lightManager.getDirectionalLight();
|
DirectionalLight directionalLight = lightManager.getDirectionalLight();
|
||||||
Vector3f direction = directionalLight.getDirection();
|
Vector3f direction = directionalLight.getDirection();
|
||||||
direction.z = event.getAsFloat() * 2 - 1;
|
direction.z = event.getAsFloat() * 2 - 1;
|
||||||
directionalLight.setDirection(direction);
|
directionalLight.setDirection(direction);
|
||||||
}}));
|
}));
|
||||||
scrollable.addChild(zDiv);
|
scrollable.addChild(zDiv);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import electrosphere.client.entity.camera.CameraEntityUtils;
|
|||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.menu.WindowUtils;
|
import electrosphere.menu.WindowUtils;
|
||||||
import electrosphere.renderer.actor.ActorUtils;
|
import electrosphere.renderer.actor.ActorUtils;
|
||||||
|
import electrosphere.renderer.ui.components.CharacterCustomizer;
|
||||||
import electrosphere.renderer.ui.elements.ActorPanel;
|
import electrosphere.renderer.ui.elements.ActorPanel;
|
||||||
import electrosphere.renderer.ui.elements.Button;
|
import electrosphere.renderer.ui.elements.Button;
|
||||||
import electrosphere.renderer.ui.elements.FormElement;
|
import electrosphere.renderer.ui.elements.FormElement;
|
||||||
@ -13,7 +14,6 @@ import electrosphere.renderer.ui.elements.Label;
|
|||||||
import electrosphere.renderer.ui.elements.Slider;
|
import electrosphere.renderer.ui.elements.Slider;
|
||||||
import electrosphere.renderer.ui.elements.VirtualScrollable;
|
import electrosphere.renderer.ui.elements.VirtualScrollable;
|
||||||
import electrosphere.renderer.ui.elementtypes.Element;
|
import electrosphere.renderer.ui.elementtypes.Element;
|
||||||
import electrosphere.renderer.ui.elementtypes.ValueElement;
|
|
||||||
import electrosphere.renderer.ui.events.ValueChangeEvent;
|
import electrosphere.renderer.ui.events.ValueChangeEvent;
|
||||||
import electrosphere.renderer.ui.macros.InputMacros;
|
import electrosphere.renderer.ui.macros.InputMacros;
|
||||||
|
|
||||||
@ -59,9 +59,9 @@ public class MenuGeneratorsUITesting {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// slider test
|
// slider test
|
||||||
Slider slider = Slider.createSlider(new ValueElement.ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
|
Slider slider = Slider.createSlider((ValueChangeEvent event) -> {
|
||||||
|
|
||||||
}});
|
});
|
||||||
virtualScrollable.addChild(slider);
|
virtualScrollable.addChild(slider);
|
||||||
|
|
||||||
rVal.addChild(virtualScrollable);
|
rVal.addChild(virtualScrollable);
|
||||||
|
|||||||
@ -157,6 +157,14 @@ public class FramebufferUtils {
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a texture framebuffer
|
||||||
|
* @param openGLState The opengl engine state
|
||||||
|
* @param width The width of the texture
|
||||||
|
* @param height The height of the texture
|
||||||
|
* @return The texture
|
||||||
|
* @throws Exception Thrown if the framebuffer fails to initialize
|
||||||
|
*/
|
||||||
public static Framebuffer generateTextureFramebuffer(OpenGLState openGLState, int width, int height) throws Exception {
|
public static Framebuffer generateTextureFramebuffer(OpenGLState openGLState, int width, int height) throws Exception {
|
||||||
Framebuffer buffer = new Framebuffer();
|
Framebuffer buffer = new Framebuffer();
|
||||||
buffer.bind(openGLState);
|
buffer.bind(openGLState);
|
||||||
|
|||||||
@ -233,6 +233,11 @@ public class ElementService extends SignalServiceImpl {
|
|||||||
Vector2i absPos = getAbsolutePosition(currentElement);
|
Vector2i absPos = getAbsolutePosition(currentElement);
|
||||||
clickEvent.setRelativeX(clickEvent.getCurrentX() - absPos.x);
|
clickEvent.setRelativeX(clickEvent.getCurrentX() - absPos.x);
|
||||||
clickEvent.setRelativeY(clickEvent.getCurrentY() - absPos.y);
|
clickEvent.setRelativeY(clickEvent.getCurrentY() - absPos.y);
|
||||||
|
} else if(event instanceof DragEvent){
|
||||||
|
DragEvent dragEvent = (DragEvent)event;
|
||||||
|
Vector2i absPos = getAbsolutePosition(currentElement);
|
||||||
|
dragEvent.setRelativeX(dragEvent.getCurrentX() - absPos.x);
|
||||||
|
dragEvent.setRelativeY(dragEvent.getCurrentY() - absPos.y);
|
||||||
}
|
}
|
||||||
propagate = currentElement.handleEvent(event);
|
propagate = currentElement.handleEvent(event);
|
||||||
}
|
}
|
||||||
@ -429,11 +434,10 @@ public class ElementService extends SignalServiceImpl {
|
|||||||
*/
|
*/
|
||||||
public void drag(int x, int y, int lastX, int lastY, int deltaX, int deltaY){
|
public void drag(int x, int y, int lastX, int lastY, int deltaX, int deltaY){
|
||||||
if(currentDragElement != null){
|
if(currentDragElement != null){
|
||||||
//need to calculate offset based on parent positions
|
DragEvent event = new DragEvent(x, y, lastX, lastY, deltaX, deltaY, DragEventType.DRAG, currentDragElement);
|
||||||
//the positions for x, y, lastX, and lastY are all in absolute-to-screen coordinates
|
Vector2i absPos = this.getAbsolutePosition(currentDragElement);
|
||||||
//the logic for things like slider depend on the
|
event.setRelativeX(x - absPos.x);
|
||||||
Vector2i absPos = getAbsolutePosition(currentDragElement);
|
event.setRelativeY(y - absPos.y);
|
||||||
DragEvent event = new DragEvent(x - absPos.x, y - absPos.y, lastX - absPos.x, lastY - absPos.y, deltaX, deltaY, DragEventType.DRAG, currentDragElement);
|
|
||||||
currentDragElement.handleEvent(event);
|
currentDragElement.handleEvent(event);
|
||||||
}
|
}
|
||||||
// fireEvent(event,event.getCurrentX(),event.getCurrentY());
|
// fireEvent(event,event.getCurrentX(),event.getCurrentY());
|
||||||
@ -450,11 +454,10 @@ public class ElementService extends SignalServiceImpl {
|
|||||||
*/
|
*/
|
||||||
public void dragRelease(int x, int y, int lastX, int lastY, int deltaX, int deltaY){
|
public void dragRelease(int x, int y, int lastX, int lastY, int deltaX, int deltaY){
|
||||||
if(currentDragElement != null){
|
if(currentDragElement != null){
|
||||||
//need to calculate offset based on parent positions
|
DragEvent event = new DragEvent(x, y, lastX, lastY, deltaX, deltaY, DragEventType.RELEASE, currentDragElement);
|
||||||
//the positions for x, y, lastX, and lastY are all in absolute-to-screen coordinates
|
Vector2i absPos = this.getAbsolutePosition(currentDragElement);
|
||||||
//the logic for things like slider depend on the
|
event.setRelativeX(x - absPos.x);
|
||||||
Vector2i absPos = getAbsolutePosition(currentDragElement);
|
event.setRelativeY(y - absPos.y);
|
||||||
DragEvent event = new DragEvent(x - absPos.x, y - absPos.y, lastX - absPos.x, lastY - absPos.y, deltaX, deltaY, DragEventType.RELEASE, currentDragElement);
|
|
||||||
currentDragElement.handleEvent(event);
|
currentDragElement.handleEvent(event);
|
||||||
currentDragElement = null;
|
currentDragElement = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,160 @@
|
|||||||
|
package electrosphere.renderer.ui.components;
|
||||||
|
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.entity.types.creature.CreatureTemplate;
|
||||||
|
import electrosphere.game.data.creature.type.CreatureData;
|
||||||
|
import electrosphere.game.data.creature.type.visualattribute.AttributeVariant;
|
||||||
|
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
|
||||||
|
import electrosphere.net.parser.net.message.CharacterMessage;
|
||||||
|
import electrosphere.renderer.actor.Actor;
|
||||||
|
import electrosphere.renderer.actor.ActorStaticMorph;
|
||||||
|
import electrosphere.renderer.actor.ActorUtils;
|
||||||
|
import electrosphere.renderer.ui.elements.ActorPanel;
|
||||||
|
import electrosphere.renderer.ui.elements.Button;
|
||||||
|
import electrosphere.renderer.ui.elements.Div;
|
||||||
|
import electrosphere.renderer.ui.elements.Label;
|
||||||
|
import electrosphere.renderer.ui.elements.ScrollableContainer;
|
||||||
|
import electrosphere.renderer.ui.elements.Slider;
|
||||||
|
import electrosphere.renderer.ui.elements.StringCarousel;
|
||||||
|
import electrosphere.renderer.ui.elementtypes.Element;
|
||||||
|
import electrosphere.renderer.ui.events.ValueChangeEvent;
|
||||||
|
import electrosphere.util.Utilities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Panel to customize a character
|
||||||
|
*/
|
||||||
|
public class CharacterCustomizer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum width of the component
|
||||||
|
*/
|
||||||
|
public static final int MIN_WIDTH = 500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum height of the component
|
||||||
|
*/
|
||||||
|
public static final int MIN_HEIGHT = 500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a character customizer panel
|
||||||
|
* @param race The race of the character
|
||||||
|
* @return The panel component
|
||||||
|
*/
|
||||||
|
public static Element createCharacterCustomizerPanel(String race){
|
||||||
|
//figure out race data
|
||||||
|
CreatureData selectedRaceType = Globals.gameConfigCurrent.getCreatureTypeLoader().getType(race);
|
||||||
|
|
||||||
|
//spawn camera so renderer doesn't crash (once render pipeline is modularized this shouldn't be necessary)
|
||||||
|
Globals.playerCamera = CameraEntityUtils.spawnBasicCameraEntity(new Vector3f(0,0,0), new Vector3f(0,0.3f,1).normalize());
|
||||||
|
Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera);
|
||||||
|
|
||||||
|
//create actor panel
|
||||||
|
Actor characterActor = ActorUtils.createActorFromModelPath(selectedRaceType.getModelPath());
|
||||||
|
ActorPanel actorPanel = ActorPanel.create(characterActor);
|
||||||
|
actorPanel.setAnimation(selectedRaceType.getIdleData().getAnimation().getNameThirdPerson());
|
||||||
|
actorPanel.setPosition(new Vector3f(0,-0.5f,-0.6f));
|
||||||
|
actorPanel.setScale(new Vector3f(1.0f));
|
||||||
|
|
||||||
|
//have to build static morph while looping through attributes
|
||||||
|
ActorStaticMorph staticMorph = new ActorStaticMorph();
|
||||||
|
|
||||||
|
//create creature template
|
||||||
|
CreatureTemplate template = CreatureTemplate.create(race);
|
||||||
|
|
||||||
|
//create scrollable
|
||||||
|
ScrollableContainer scrollable = ScrollableContainer.createScrollable();
|
||||||
|
scrollable.setMinWidth(MIN_WIDTH);
|
||||||
|
scrollable.setMinHeight(MIN_HEIGHT);
|
||||||
|
|
||||||
|
//create edit controls here
|
||||||
|
for(VisualAttribute attribute : selectedRaceType.getVisualAttributes()){
|
||||||
|
if(attribute.getType().equals(VisualAttribute.TYPE_BONE)){
|
||||||
|
//add label for slider
|
||||||
|
Label sliderName = new Label(0.6f);
|
||||||
|
sliderName.setText(attribute.getAttributeId());
|
||||||
|
sliderName.setMinWidth(200);
|
||||||
|
//add a slider
|
||||||
|
Slider boneSlider = Slider.createSlider((ValueChangeEvent event) -> {
|
||||||
|
if(characterActor.getStaticMorph() != null){
|
||||||
|
staticMorph.updateValue(attribute.getSubtype(), attribute.getPrimaryBone(), event.getAsFloat());
|
||||||
|
if(attribute.getMirrorBone() != null){
|
||||||
|
staticMorph.updateValue(attribute.getSubtype(), attribute.getMirrorBone(), event.getAsFloat());
|
||||||
|
}
|
||||||
|
template.getAttributeValue(attribute.getAttributeId()).setValue(event.getAsFloat());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
float min = attribute.getMinValue();
|
||||||
|
float max = attribute.getMaxValue();
|
||||||
|
float defaultValue = min + (max - min)/2.0f;
|
||||||
|
boneSlider.setMinimum(min);
|
||||||
|
boneSlider.setMaximum(max);
|
||||||
|
boneSlider.setValue(defaultValue);
|
||||||
|
boneSlider.setMinWidth(200);
|
||||||
|
//actually add attributes to static morph
|
||||||
|
if(attribute.getPrimaryBone() != null && staticMorph.getBoneTransforms(attribute.getPrimaryBone()) == null){
|
||||||
|
staticMorph.initBoneTransforms(attribute.getPrimaryBone());
|
||||||
|
}
|
||||||
|
if(attribute.getMirrorBone() != null && staticMorph.getBoneTransforms(attribute.getMirrorBone()) == null){
|
||||||
|
staticMorph.initBoneTransforms(attribute.getMirrorBone());
|
||||||
|
}
|
||||||
|
//add attribute to creature template
|
||||||
|
template.putAttributeValue(attribute.getAttributeId(), defaultValue);
|
||||||
|
|
||||||
|
scrollable.addChild(Div.createRow(sliderName,boneSlider));
|
||||||
|
} else if(attribute.getType().equals(VisualAttribute.TYPE_REMESH)){
|
||||||
|
//add label for carousel
|
||||||
|
Label scrollableName = new Label(0.6f);
|
||||||
|
scrollableName.setText(attribute.getAttributeId());
|
||||||
|
scrollableName.setMinWidth(200);
|
||||||
|
//add a carousel
|
||||||
|
StringCarousel variantCarousel = StringCarousel.create(
|
||||||
|
// attribute.getVariants().stream().filter(variant -> ),
|
||||||
|
attribute.getVariants().stream().map(variant -> variant.getId()).collect(Collectors.toList()),
|
||||||
|
(ValueChangeEvent event) -> {
|
||||||
|
//TODO: implement updating visuals
|
||||||
|
template.getAttributeValue(attribute.getAttributeId()).setVariantId(event.getAsString());
|
||||||
|
AttributeVariant variant = null;
|
||||||
|
for(AttributeVariant variantCurrent : attribute.getVariants()){
|
||||||
|
if(variantCurrent.getId().equals(event.getAsString())){
|
||||||
|
variant = variantCurrent;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(variant != null){
|
||||||
|
Globals.assetManager.addModelPathToQueue(variant.getModel());
|
||||||
|
for(String mesh : variant.getMeshes()){
|
||||||
|
characterActor.getMeshMask().queueMesh(variant.getModel(), mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
variantCarousel.setMinWidth(200);
|
||||||
|
//set the current attrib for the template
|
||||||
|
template.putAttributeValue(attribute.getAttributeId(), attribute.getVariants().get(0).getId());
|
||||||
|
|
||||||
|
scrollable.addChild(Div.createRow(scrollableName,variantCarousel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//finally set static morph
|
||||||
|
characterActor.setActorStaticMorph(staticMorph);
|
||||||
|
|
||||||
|
//create layout
|
||||||
|
Div rVal = Div.createCol(
|
||||||
|
Div.createRow(
|
||||||
|
scrollable,
|
||||||
|
actorPanel
|
||||||
|
),
|
||||||
|
Button.createButton("Create", () -> {
|
||||||
|
Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestCreateCharacterMessage(Utilities.stringify(template)));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -20,23 +20,26 @@ import electrosphere.renderer.RenderPipelineState;
|
|||||||
import electrosphere.renderer.RenderingEngine;
|
import electrosphere.renderer.RenderingEngine;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.debug.DebugRendering;
|
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.model.Model;
|
||||||
import electrosphere.renderer.ui.elementtypes.DraggableElement;
|
import electrosphere.renderer.ui.elementtypes.DraggableElement;
|
||||||
import electrosphere.renderer.ui.elementtypes.DrawableElement;
|
|
||||||
import electrosphere.renderer.ui.events.DragEvent;
|
import electrosphere.renderer.ui.events.DragEvent;
|
||||||
import electrosphere.renderer.ui.events.DragEvent.DragEventType;
|
import electrosphere.renderer.ui.events.DragEvent.DragEventType;
|
||||||
import electrosphere.renderer.ui.events.Event;
|
import electrosphere.renderer.ui.events.Event;
|
||||||
|
|
||||||
public class ActorPanel extends StandardElement implements DrawableElement, DraggableElement {
|
public class ActorPanel extends BufferedStandardDrawableContainerElement implements DraggableElement {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default width of an actor panel
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT_WIDTH = 500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default height of an actor panel
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT_HEIGHT = 500;
|
||||||
|
|
||||||
static Vector3f color = new Vector3f(1.0f);
|
static Vector3f color = new Vector3f(1.0f);
|
||||||
|
|
||||||
Material customMat = new Material();
|
|
||||||
Framebuffer elementBuffer;
|
|
||||||
|
|
||||||
Actor actor;
|
Actor actor;
|
||||||
Matrix4d modelMatrix = new Matrix4d();
|
Matrix4d modelMatrix = new Matrix4d();
|
||||||
String currentAnim;
|
String currentAnim;
|
||||||
@ -56,14 +59,16 @@ public class ActorPanel extends StandardElement implements DrawableElement, Drag
|
|||||||
|
|
||||||
static final Vector3f windowDrawDebugColor = new Vector3f(0.0f,0.0f,1.0f);
|
static final Vector3f windowDrawDebugColor = new Vector3f(0.0f,0.0f,1.0f);
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public ActorPanel(OpenGLState openGLState, int x, int y, int width, int height, Actor actor){
|
public ActorPanel(OpenGLState openGLState, int x, int y, int width, int height, Actor actor){
|
||||||
super();
|
super();
|
||||||
try {
|
|
||||||
elementBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height);
|
//must manually set because framebuffer is allocated on set
|
||||||
} catch(Exception e){
|
//these default to -1 until they are set with methods, but methods allocate on each set
|
||||||
LoggerInterface.loggerRenderer.ERROR(e);
|
//to break chicken-and-egg problem, manually set here
|
||||||
}
|
this.width = DEFAULT_WIDTH;
|
||||||
customMat.setTexturePointer(elementBuffer.getTexture().getTexturePointer());
|
this.height = DEFAULT_HEIGHT;
|
||||||
|
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.internalPositionX = x;
|
this.internalPositionX = x;
|
||||||
this.internalPositionY = y;
|
this.internalPositionY = y;
|
||||||
@ -72,6 +77,36 @@ public class ActorPanel extends StandardElement implements DrawableElement, Drag
|
|||||||
this.aspectRatio = (float)width / (float)height;
|
this.aspectRatio = (float)width / (float)height;
|
||||||
recalculateModelMatrix();
|
recalculateModelMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param actor The actor
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
this.aspectRatio = (float)DEFAULT_WIDTH / (float)DEFAULT_HEIGHT;
|
||||||
|
this.recalculateModelMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an actor panel
|
||||||
|
* @param actor The actor to put in the panel
|
||||||
|
* @return The actor panel
|
||||||
|
*/
|
||||||
|
public static ActorPanel create(Actor actor){
|
||||||
|
ActorPanel rVal = new ActorPanel(actor);
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -86,122 +121,113 @@ public class ActorPanel extends StandardElement implements DrawableElement, Drag
|
|||||||
int parentHeight
|
int parentHeight
|
||||||
) {
|
) {
|
||||||
|
|
||||||
elementBuffer.bind(openGLState);
|
if(this.elementBuffer != null){
|
||||||
// Globals.renderingEngine.setViewportSize(width, height);
|
elementBuffer.bind(openGLState);
|
||||||
|
// Globals.renderingEngine.setViewportSize(width, height);
|
||||||
|
|
||||||
RenderingEngine.setFOV(FOV);
|
RenderingEngine.setFOV(FOV);
|
||||||
RenderingEngine.setAspectRatio(aspectRatio);
|
RenderingEngine.setAspectRatio(aspectRatio);
|
||||||
|
|
||||||
openGLState.glDepthTest(true);
|
openGLState.glDepthTest(true);
|
||||||
openGLState.glDepthFunc(GL_LESS);
|
openGLState.glDepthFunc(GL_LESS);
|
||||||
glDepthMask(true);
|
glDepthMask(true);
|
||||||
openGLState.glViewport(width, height);
|
openGLState.glViewport(width, height);
|
||||||
|
|
||||||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
Model actorModel = Globals.assetManager.fetchModel(actor.getModelPath());
|
Model actorModel = Globals.assetManager.fetchModel(actor.getModelPath());
|
||||||
|
|
||||||
if(currentAnim != null){
|
if(currentAnim != null){
|
||||||
if((!actor.isPlayingAnimation() || !actor.isPlayingAnimation(currentAnim)) &&
|
if((!actor.isPlayingAnimation() || !actor.isPlayingAnimation(currentAnim)) &&
|
||||||
actorModel != null &&
|
actorModel != null &&
|
||||||
actorModel.getAnimation(currentAnim) != null
|
actorModel.getAnimation(currentAnim) != null
|
||||||
){
|
){
|
||||||
actor.playAnimation(currentAnim,3);
|
actor.playAnimation(currentAnim,3);
|
||||||
actor.incrementAnimationTime(0.0001);
|
actor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set rendering engine state
|
||||||
|
//
|
||||||
|
renderPipelineState.setUseMeshShader(true);
|
||||||
|
renderPipelineState.setBufferStandardUniforms(true);
|
||||||
|
renderPipelineState.setBufferNonStandardUniforms(true);
|
||||||
|
renderPipelineState.setUseMaterial(true);
|
||||||
|
renderPipelineState.setUseShadowMap(true);
|
||||||
|
renderPipelineState.setUseBones(true);
|
||||||
|
renderPipelineState.setUseLight(true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
actor.applySpatialData(modelMatrix,new Vector3d(actorPosition));
|
||||||
|
actor.draw(renderPipelineState,openGLState);
|
||||||
|
|
||||||
|
RenderingEngine.setFOV(Globals.verticalFOV);
|
||||||
|
RenderingEngine.setAspectRatio(Globals.aspectRatio);
|
||||||
|
|
||||||
|
openGLState.glDepthTest(false);
|
||||||
|
|
||||||
|
//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);
|
||||||
|
|
||||||
|
float ndcX = (float)getInternalX()/parentWidth;
|
||||||
|
float ndcY = (float)getInternalY()/parentHeight;
|
||||||
|
float ndcWidth = (float)getInternalWidth()/parentWidth;
|
||||||
|
float ndcHeight = (float)getInternalHeight()/parentHeight;
|
||||||
|
|
||||||
|
Vector3f boxPosition = new Vector3f(ndcX,ndcY,0);
|
||||||
|
Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set rendering engine state
|
||||||
|
//
|
||||||
|
renderPipelineState.setUseMeshShader(true);
|
||||||
|
renderPipelineState.setBufferStandardUniforms(false);
|
||||||
|
renderPipelineState.setBufferNonStandardUniforms(true);
|
||||||
|
renderPipelineState.setUseMaterial(true);
|
||||||
|
renderPipelineState.setUseShadowMap(false);
|
||||||
|
renderPipelineState.setUseBones(false);
|
||||||
|
renderPipelineState.setUseLight(false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", color);
|
||||||
|
planeModel.getMeshes().get(0).setMaterial(elementMat);
|
||||||
|
planeModel.draw(renderPipelineState,Globals.renderingEngine.getOpenGLState());
|
||||||
|
} else {
|
||||||
|
LoggerInterface.loggerRenderer.ERROR("Actor Panel unable to find plane model!!", new Exception());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_ACTOR_PANEL){
|
||||||
|
DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Set rendering engine state
|
|
||||||
//
|
|
||||||
renderPipelineState.setUseMeshShader(true);
|
|
||||||
renderPipelineState.setBufferStandardUniforms(true);
|
|
||||||
renderPipelineState.setBufferNonStandardUniforms(true);
|
|
||||||
renderPipelineState.setUseMaterial(true);
|
|
||||||
renderPipelineState.setUseShadowMap(true);
|
|
||||||
renderPipelineState.setUseBones(true);
|
|
||||||
renderPipelineState.setUseLight(true);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
actor.applySpatialData(modelMatrix,new Vector3d(actorPosition));
|
|
||||||
actor.draw(renderPipelineState,openGLState);
|
|
||||||
|
|
||||||
RenderingEngine.setFOV(Globals.verticalFOV);
|
|
||||||
RenderingEngine.setAspectRatio(Globals.aspectRatio);
|
|
||||||
|
|
||||||
openGLState.glDepthTest(false);
|
|
||||||
|
|
||||||
//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);
|
|
||||||
|
|
||||||
float ndcX = (float)getInternalX()/parentWidth;
|
|
||||||
float ndcY = (float)getInternalY()/parentHeight;
|
|
||||||
float ndcWidth = (float)getInternalWidth()/parentWidth;
|
|
||||||
float ndcHeight = (float)getInternalHeight()/parentHeight;
|
|
||||||
|
|
||||||
Vector3f boxPosition = new Vector3f(ndcX,ndcY,0);
|
|
||||||
Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set rendering engine state
|
|
||||||
//
|
|
||||||
renderPipelineState.setUseMeshShader(true);
|
|
||||||
renderPipelineState.setBufferStandardUniforms(false);
|
|
||||||
renderPipelineState.setBufferNonStandardUniforms(true);
|
|
||||||
renderPipelineState.setUseMaterial(true);
|
|
||||||
renderPipelineState.setUseShadowMap(false);
|
|
||||||
renderPipelineState.setUseBones(false);
|
|
||||||
renderPipelineState.setUseLight(false);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", color);
|
|
||||||
planeModel.getMeshes().get(0).setMaterial(customMat);
|
|
||||||
planeModel.draw(renderPipelineState,Globals.renderingEngine.getOpenGLState());
|
|
||||||
} else {
|
|
||||||
LoggerInterface.loggerRenderer.ERROR("Actor Panel unable to find plane model!!", new Exception());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_ACTOR_PANEL){
|
|
||||||
DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean visible = false;
|
|
||||||
|
|
||||||
|
|
||||||
public void setVisible(boolean draw) {
|
|
||||||
this.visible = draw;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getVisible(){
|
|
||||||
return this.visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAnimation(String animation){
|
public void setAnimation(String animation){
|
||||||
currentAnim = animation;
|
currentAnim = animation;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,171 @@
|
|||||||
|
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 org.lwjgl.opengl.GL45;
|
||||||
|
|
||||||
|
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,
|
||||||
|
int parentFramebufferPointer,
|
||||||
|
int parentPosX,
|
||||||
|
int parentPosY,
|
||||||
|
int parentWidth,
|
||||||
|
int parentHeight
|
||||||
|
) {
|
||||||
|
|
||||||
|
float ndcWidth = (float)getWidth()/parentWidth;
|
||||||
|
float ndcHeight = (float)getHeight()/parentHeight;
|
||||||
|
float ndcX = (float)(getInternalX() + parentPosX)/parentWidth;
|
||||||
|
float ndcY = (float)(getInternalY() + parentPosY)/parentHeight;
|
||||||
|
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(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,
|
||||||
|
parentFramebufferPointer,
|
||||||
|
parentPosX + this.internalPositionX,
|
||||||
|
parentPosY + this.internalPositionY,
|
||||||
|
parentWidth,
|
||||||
|
parentHeight
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//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);
|
||||||
|
|
||||||
|
//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 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -72,6 +72,23 @@ public class Div extends StandardContainerElement implements ClickableElement,Dr
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a wrapper div
|
||||||
|
* @param child The child to wrap
|
||||||
|
* @param width The width of the wrapper
|
||||||
|
* @param height The height of the wrapper
|
||||||
|
* @return The wrapper element
|
||||||
|
*/
|
||||||
|
public static Div createWrapper(Element child, int width, int height){
|
||||||
|
Div rVal = new Div();
|
||||||
|
rVal.setWidth(width);
|
||||||
|
rVal.setHeight(height);
|
||||||
|
if(child != null){
|
||||||
|
rVal.addChild(child);
|
||||||
|
}
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -39,7 +39,7 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag
|
|||||||
|
|
||||||
|
|
||||||
//rendering data for positioning the model
|
//rendering data for positioning the model
|
||||||
Vector3f texPosition = new Vector3f(0,0,0);
|
Vector3f texPosition = new Vector3f(1,1,0);
|
||||||
Vector3f texScale = new Vector3f(1,1,0);
|
Vector3f texScale = new Vector3f(1,1,0);
|
||||||
Vector3f boxPosition = new Vector3f();
|
Vector3f boxPosition = new Vector3f();
|
||||||
Vector3f boxDimensions = new Vector3f();
|
Vector3f boxDimensions = new Vector3f();
|
||||||
|
|||||||
@ -6,9 +6,6 @@ import electrosphere.engine.Globals;
|
|||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.renderer.OpenGLState;
|
import electrosphere.renderer.OpenGLState;
|
||||||
import electrosphere.renderer.RenderPipelineState;
|
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.model.Model;
|
||||||
import electrosphere.renderer.texture.Texture;
|
import electrosphere.renderer.texture.Texture;
|
||||||
import electrosphere.renderer.ui.elementtypes.ContainerElement;
|
import electrosphere.renderer.ui.elementtypes.ContainerElement;
|
||||||
@ -19,32 +16,38 @@ import electrosphere.renderer.ui.events.Event;
|
|||||||
import static org.lwjgl.opengl.GL11.*;
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
import static org.lwjgl.opengl.GL30.*;
|
import static org.lwjgl.opengl.GL30.*;
|
||||||
|
|
||||||
public class ScrollableContainer extends StandardContainerElement implements DrawableElement {
|
public class ScrollableContainer extends BufferedStandardDrawableContainerElement {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default width of a slider
|
||||||
|
*/
|
||||||
|
static final int DEFAULT_HEIGHT = 50;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default height of a slider
|
||||||
|
*/
|
||||||
|
static final int DEFAULT_WIDTH = 50;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color associated with the scrollable
|
||||||
|
*/
|
||||||
Vector3f color = new Vector3f(1.0f);
|
Vector3f color = new Vector3f(1.0f);
|
||||||
|
|
||||||
boolean focused = false;
|
|
||||||
|
|
||||||
public boolean visible = false;
|
|
||||||
|
|
||||||
Framebuffer widgetBuffer;
|
|
||||||
Material customMat = new Material();
|
|
||||||
Vector3f boxPosition = new Vector3f();
|
Vector3f boxPosition = new Vector3f();
|
||||||
Vector3f boxDimensions = new Vector3f();
|
Vector3f boxDimensions = new Vector3f();
|
||||||
Vector3f texPosition = new Vector3f(0,0,0);
|
Vector3f texPosition = new Vector3f(0,0,0);
|
||||||
Vector3f texScale = new Vector3f(1,1,0);
|
Vector3f texScale = new Vector3f(1,1,0);
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public ScrollableContainer(OpenGLState openGLState, int positionX, int positionY, int width, int height){
|
public ScrollableContainer(OpenGLState openGLState, int positionX, int positionY, int width, int height){
|
||||||
super();
|
super();
|
||||||
try {
|
|
||||||
widgetBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height);
|
//must manually set because framebuffer is allocated on set
|
||||||
} catch(Exception e){
|
//these default to -1 until they are set with methods, but methods allocate on each set
|
||||||
LoggerInterface.loggerRenderer.ERROR(e);
|
//to break chicken-and-egg problem, manually set here
|
||||||
}
|
this.width = DEFAULT_WIDTH;
|
||||||
// widgetBuffer = FramebufferUtils.generateScreensizeTextureFramebuffer();
|
this.height = DEFAULT_HEIGHT;
|
||||||
customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer());
|
|
||||||
// customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer());
|
|
||||||
float ndcX = (float)positionX/Globals.WINDOW_WIDTH;
|
float ndcX = (float)positionX/Globals.WINDOW_WIDTH;
|
||||||
float ndcY = (float)positionY/Globals.WINDOW_HEIGHT;
|
float ndcY = (float)positionY/Globals.WINDOW_HEIGHT;
|
||||||
float ndcWidth = (float)width/Globals.WINDOW_WIDTH;
|
float ndcWidth = (float)width/Globals.WINDOW_WIDTH;
|
||||||
@ -55,6 +58,29 @@ public class ScrollableContainer extends StandardContainerElement implements Dra
|
|||||||
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
setWidth(DEFAULT_HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a scrollable container element
|
||||||
|
* @return The scrollable
|
||||||
|
*/
|
||||||
|
public static ScrollableContainer createScrollable(){
|
||||||
|
return new ScrollableContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -62,16 +88,6 @@ public class ScrollableContainer extends StandardContainerElement implements Dra
|
|||||||
return false;
|
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
|
//recursively check if focused element is child of input element or is input element
|
||||||
boolean containsFocusedElement(Element parent){
|
boolean containsFocusedElement(Element parent){
|
||||||
Element focusedElement = Globals.elementService.getFocusedElement();
|
Element focusedElement = Globals.elementService.getFocusedElement();
|
||||||
@ -98,103 +114,113 @@ public class ScrollableContainer extends StandardContainerElement implements Dra
|
|||||||
int parentWidth,
|
int parentWidth,
|
||||||
int parentHeight
|
int parentHeight
|
||||||
) {
|
) {
|
||||||
//figure out if currently focused element is a child or subchild of this container
|
if(this.elementBuffer != null){
|
||||||
if(containsFocusedElement(this)){
|
//figure out if currently focused element is a child or subchild of this container
|
||||||
//if it is, if it is offscreen, calculate offset to put it onscreen
|
if(containsFocusedElement(this)){
|
||||||
Element focused = Globals.elementService.getFocusedElement();
|
//if it is, if it is offscreen, calculate offset to put it onscreen
|
||||||
if(
|
Element focused = Globals.elementService.getFocusedElement();
|
||||||
focused.getRelativeX() + focused.getWidth() > this.width ||
|
if(
|
||||||
focused.getRelativeY() + focused.getHeight() > this.height ||
|
focused.getRelativeX() + focused.getWidth() > this.width ||
|
||||||
focused.getRelativeX() < 0 ||
|
focused.getRelativeY() + focused.getHeight() > this.height ||
|
||||||
focused.getRelativeY() < 0
|
focused.getRelativeX() < 0 ||
|
||||||
){
|
focused.getRelativeY() < 0
|
||||||
int neededOffsetX = 0;
|
){
|
||||||
int neededOffsetY = 0;
|
int neededOffsetX = 0;
|
||||||
//basically if we're offscreen negative, pull to positive
|
int neededOffsetY = 0;
|
||||||
//if we're offscreen positive and we're not as large as the screen, pull from the positive into focus
|
//basically if we're offscreen negative, pull to positive
|
||||||
//if we are larger than the screen, set position to 0
|
//if we're offscreen positive and we're not as large as the screen, pull from the positive into focus
|
||||||
if(focused.getRelativeX() < 0){
|
//if we are larger than the screen, set position to 0
|
||||||
neededOffsetX = -focused.getRelativeX();
|
if(focused.getRelativeX() < 0){
|
||||||
} else if(focused.getRelativeX() + focused.getWidth() > this.width){
|
|
||||||
if(focused.getWidth() > this.width){
|
|
||||||
neededOffsetX = -focused.getRelativeX();
|
neededOffsetX = -focused.getRelativeX();
|
||||||
} else {
|
} else if(focused.getRelativeX() + focused.getWidth() > this.width){
|
||||||
neededOffsetX = -((focused.getRelativeX() - this.width) + focused.getWidth());
|
if(focused.getWidth() > this.width){
|
||||||
|
neededOffsetX = -focused.getRelativeX();
|
||||||
|
} else {
|
||||||
|
neededOffsetX = -((focused.getRelativeX() - this.width) + focused.getWidth());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if(focused.getRelativeY() < 0){
|
||||||
if(focused.getRelativeY() < 0){
|
|
||||||
neededOffsetY = -focused.getRelativeY();
|
|
||||||
} else if(focused.getRelativeY() + focused.getHeight() > this.height){
|
|
||||||
if(focused.getHeight() > this.height){
|
|
||||||
neededOffsetY = -focused.getRelativeY();
|
neededOffsetY = -focused.getRelativeY();
|
||||||
} else {
|
} else if(focused.getRelativeY() + focused.getHeight() > this.height){
|
||||||
neededOffsetY = -((focused.getRelativeY() - this.height) + focused.getHeight());
|
if(focused.getHeight() > this.height){
|
||||||
// System.out.println(focused.getPositionY() + " " + this.height + " " + focused.getHeight());
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//apply offset to all children
|
}
|
||||||
for(Element child : childList){
|
|
||||||
int newX = child.getRelativeX() + neededOffsetX;
|
float ndcWidth = (float)getWidth()/parentWidth;
|
||||||
int newY = child.getRelativeY() + neededOffsetY;
|
float ndcHeight = (float)getHeight()/parentHeight;
|
||||||
child.setPositionX(newX);
|
float ndcX = (float)(getInternalX() + parentPosX)/parentWidth;
|
||||||
child.setPositionY(newY);
|
float ndcY = (float)(getInternalY() + parentPosY)/parentHeight;
|
||||||
// System.out.println(currentX + " " + currentY);
|
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);
|
||||||
|
|
||||||
|
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,
|
||||||
|
parentFramebufferPointer,
|
||||||
|
parentPosX + this.internalPositionX,
|
||||||
|
parentPosY + this.internalPositionY,
|
||||||
|
parentWidth,
|
||||||
|
parentHeight
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
//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);
|
||||||
|
|
||||||
float ndcX = (float)internalPositionX/parentWidth;
|
//render background of window
|
||||||
float ndcY = (float)internalPositionY/parentHeight;
|
if(planeModel != null && windowFrame != null){
|
||||||
float ndcWidth = (float)internalWidth/parentWidth;
|
planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
|
||||||
float ndcHeight = (float)internalHeight/parentHeight;
|
planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions);
|
||||||
boxPosition = new Vector3f(ndcX,ndcY,0);
|
planeModel.pushUniformToMesh("plane", "tPosition", texPosition);
|
||||||
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
planeModel.pushUniformToMesh("plane", "tDimension", texScale);
|
||||||
|
planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", color);
|
||||||
//grab assets required to render window
|
elementMat.setTexturePointer(windowFrame.getTexturePointer());
|
||||||
Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID);
|
planeModel.getMeshes().get(0).setMaterial(elementMat);
|
||||||
Texture windowFrame = Globals.assetManager.fetchTexture("Textures/ui/uiFrame1.png");
|
planeModel.drawUI();
|
||||||
|
}
|
||||||
|
|
||||||
widgetBuffer.bind(openGLState);
|
if(planeModel != null){
|
||||||
openGLState.glViewport(width, height);
|
planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
|
||||||
|
planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions);
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
planeModel.pushUniformToMesh("plane", "tPosition", texPosition);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
planeModel.pushUniformToMesh("plane", "tDimension", texScale);
|
||||||
|
planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", color);
|
||||||
for(Element child : childList){
|
elementMat.setTexturePointer(elementBuffer.getTexture().getTexturePointer());
|
||||||
if(child instanceof DrawableElement){
|
planeModel.getMeshes().get(0).setMaterial(elementMat);
|
||||||
DrawableElement drawableChild = (DrawableElement) child;
|
planeModel.drawUI();
|
||||||
drawableChild.draw(renderPipelineState,openGLState,widgetBuffer.getFramebufferPointer(),0,0,width,height);
|
} else {
|
||||||
|
LoggerInterface.loggerRenderer.ERROR("ScrollableContainer unable to find plane model!!", new Exception());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,26 +46,25 @@ public class Slider extends StandardDrawableElement implements ClickableElement,
|
|||||||
|
|
||||||
static Material mat;
|
static Material mat;
|
||||||
|
|
||||||
|
int drawMarginX = 5;
|
||||||
|
int drawMarginY = 5;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static final int idealMargin = 5; //5 pixels margin ideally
|
static final int idealMargin = 5; //5 pixels margin ideally
|
||||||
|
|
||||||
static final Vector3f windowDrawDebugColor = new Vector3f(1.0f,1.0f,1.0f);
|
static final Vector3f windowDrawDebugColor = new Vector3f(1.0f,1.0f,1.0f);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default width of a slider
|
||||||
|
*/
|
||||||
static final int DEFAULT_HEIGHT = 20;
|
static final int DEFAULT_HEIGHT = 20;
|
||||||
static final int DEFAULT_WIDTH = 100;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a slider element
|
* The default height of a slider
|
||||||
* @param callback the Logic to fire when the slider changes value
|
|
||||||
* @return the slider element
|
|
||||||
*/
|
*/
|
||||||
public static Slider createSlider(ValueChangeEventCallback callback){
|
static final int DEFAULT_WIDTH = 100;
|
||||||
Slider slider = new Slider();
|
|
||||||
slider.setOnValueChangeCallback(callback);
|
|
||||||
return slider;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a slider element
|
* Creates a slider element
|
||||||
@ -126,17 +125,17 @@ public class Slider extends StandardDrawableElement implements ClickableElement,
|
|||||||
Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer);
|
Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer);
|
||||||
openGLState.glViewport(parentWidth, parentHeight);
|
openGLState.glViewport(parentWidth, parentHeight);
|
||||||
|
|
||||||
int marginX = Math.max(width - idealMargin * 2, 0);
|
int drawMarginX = Math.max(width - idealMargin * 2, 0);
|
||||||
if(marginX < idealMargin){
|
if(drawMarginX < idealMargin){
|
||||||
marginX = 0;
|
drawMarginX = 0;
|
||||||
} else {
|
} else {
|
||||||
marginX = idealMargin;
|
drawMarginX = idealMargin;
|
||||||
}
|
}
|
||||||
int marginY = Math.max(height - idealMargin * 2, 0);
|
int drawMarginY = Math.max(height - idealMargin * 2, 0);
|
||||||
if(marginY < idealMargin){
|
if(drawMarginY < idealMargin){
|
||||||
marginY = 0;
|
drawMarginY = 0;
|
||||||
} else {
|
} else {
|
||||||
marginY = idealMargin;
|
drawMarginY = idealMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -158,10 +157,10 @@ public class Slider extends StandardDrawableElement implements ClickableElement,
|
|||||||
planeModel.drawUI();
|
planeModel.drawUI();
|
||||||
|
|
||||||
//actual slider
|
//actual slider
|
||||||
ndcX = (float)(getInternalX() + marginX + parentPosX)/parentWidth;
|
ndcWidth = (float)((getInternalWidth() - drawMarginX * 2) * getValueAsPercentage())/parentWidth;
|
||||||
ndcY = (float)(getInternalY() + marginY + parentPosY)/parentHeight;
|
ndcHeight = (float)(getInternalHeight() - drawMarginY * 2)/parentHeight;
|
||||||
ndcWidth = (float)((getInternalWidth() - marginX * 2) * getValueAsPercentage())/parentWidth;
|
ndcX = (float)(getInternalX() + drawMarginX + parentPosX)/parentWidth;
|
||||||
ndcHeight = (float)(getInternalHeight() - marginY * 2)/parentHeight;
|
ndcY = (float)(getInternalY() + drawMarginY + parentPosY)/parentHeight;
|
||||||
boxPosition = new Vector3f(ndcX,ndcY,0);
|
boxPosition = new Vector3f(ndcX,ndcY,0);
|
||||||
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
||||||
planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
|
planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
|
||||||
@ -173,7 +172,7 @@ public class Slider extends StandardDrawableElement implements ClickableElement,
|
|||||||
LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model!!", new Exception());
|
LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model!!", new Exception());
|
||||||
}
|
}
|
||||||
if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_SLIDER){
|
if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_SLIDER){
|
||||||
boxDimensions.x = (float)((width - marginX * 2) * 1.0f)/parentWidth;
|
boxDimensions.x = (float)((width - drawMarginX * 2) * 1.0f)/parentWidth;
|
||||||
DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor);
|
DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,6 +247,15 @@ public class Slider extends StandardDrawableElement implements ClickableElement,
|
|||||||
onValueChange = callback;
|
onValueChange = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current value from the percentage
|
||||||
|
* @param percentage The percentage
|
||||||
|
* @return The value
|
||||||
|
*/
|
||||||
|
private float valueFromPercentage(float percentage){
|
||||||
|
return (percentage * (max - min) + min);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handleEvent(Event event) {
|
public boolean handleEvent(Event event) {
|
||||||
@ -280,6 +288,7 @@ public class Slider extends StandardDrawableElement implements ClickableElement,
|
|||||||
switch(menuEvent.getType()){
|
switch(menuEvent.getType()){
|
||||||
case INCREMENT:
|
case INCREMENT:
|
||||||
value = Math.min(value + ((max - min) * 0.01f),max);
|
value = Math.min(value + ((max - min) * 0.01f),max);
|
||||||
|
value = this.valueFromPercentage(value);
|
||||||
if(onValueChange != null){
|
if(onValueChange != null){
|
||||||
onValueChange.execute(new ValueChangeEvent(value));
|
onValueChange.execute(new ValueChangeEvent(value));
|
||||||
}
|
}
|
||||||
@ -287,6 +296,7 @@ public class Slider extends StandardDrawableElement implements ClickableElement,
|
|||||||
break;
|
break;
|
||||||
case DECREMENT:
|
case DECREMENT:
|
||||||
value = Math.max(value - ((max - min) * 0.01f),min);
|
value = Math.max(value - ((max - min) * 0.01f),min);
|
||||||
|
value = this.valueFromPercentage(value);
|
||||||
if(onValueChange != null){
|
if(onValueChange != null){
|
||||||
onValueChange.execute(new ValueChangeEvent(value));
|
onValueChange.execute(new ValueChangeEvent(value));
|
||||||
}
|
}
|
||||||
@ -308,9 +318,10 @@ public class Slider extends StandardDrawableElement implements ClickableElement,
|
|||||||
propagate = onDrag.execute(dragEvent);
|
propagate = onDrag.execute(dragEvent);
|
||||||
} else {
|
} else {
|
||||||
//default behavior
|
//default behavior
|
||||||
int percentage = dragEvent.getCurrentX() - getInternalX();
|
int percentage = dragEvent.getRelativeX() - getInternalX();
|
||||||
int max = width;
|
int max = getInternalWidth();
|
||||||
value = Math.max(Math.min((float)percentage/max,1.0f),0.0f);
|
value = Math.max(Math.min((float)percentage/max,1.0f),0.0f);
|
||||||
|
value = this.valueFromPercentage(value);
|
||||||
if(onValueChange != null){
|
if(onValueChange != null){
|
||||||
onValueChange.execute(new ValueChangeEvent(value));
|
onValueChange.execute(new ValueChangeEvent(value));
|
||||||
}
|
}
|
||||||
@ -321,9 +332,10 @@ public class Slider extends StandardDrawableElement implements ClickableElement,
|
|||||||
propagate = onDragRelease.execute(dragEvent);
|
propagate = onDragRelease.execute(dragEvent);
|
||||||
} else {
|
} else {
|
||||||
//default behavior
|
//default behavior
|
||||||
int percentage = dragEvent.getCurrentX() - getInternalX();
|
int percentage = dragEvent.getRelativeX() - getInternalX();
|
||||||
int max = width;
|
int max = getInternalWidth();
|
||||||
value = Math.max(Math.min((float)percentage/max,1.0f),0.0f);
|
value = Math.max(Math.min((float)percentage/max,1.0f),0.0f);
|
||||||
|
value = this.valueFromPercentage(value);
|
||||||
if(onValueChange != null){
|
if(onValueChange != null){
|
||||||
onValueChange.execute(new ValueChangeEvent(value));
|
onValueChange.execute(new ValueChangeEvent(value));
|
||||||
}
|
}
|
||||||
@ -338,8 +350,9 @@ public class Slider extends StandardDrawableElement implements ClickableElement,
|
|||||||
} else {
|
} else {
|
||||||
//default behavior
|
//default behavior
|
||||||
int percentage = clickEvent.getRelativeX() - getInternalX();
|
int percentage = clickEvent.getRelativeX() - getInternalX();
|
||||||
int max = width;
|
int max = getInternalWidth();
|
||||||
value = Math.max(Math.min((float)percentage/max,1.0f),0.0f);
|
value = Math.max(Math.min((float)percentage/max,1.0f),0.0f);
|
||||||
|
value = this.valueFromPercentage(value);
|
||||||
if(onValueChange != null){
|
if(onValueChange != null){
|
||||||
onValueChange.execute(new ValueChangeEvent(value));
|
onValueChange.execute(new ValueChangeEvent(value));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -137,16 +137,6 @@ public class StandardContainerElement extends StandardElement implements Contain
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public void setWidth(int width) {
|
|
||||||
// this.width = width;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public void setHeight(int height) {
|
|
||||||
// this.height = height;
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPositionX(int posX) {
|
public void setPositionX(int posX) {
|
||||||
internalPositionX = posX;
|
internalPositionX = posX;
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package electrosphere.renderer.ui.elements;
|
|||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.lwjgl.util.yoga.Yoga;
|
import org.lwjgl.util.yoga.Yoga;
|
||||||
@ -50,6 +51,27 @@ public class StringCarousel extends StandardContainerElement implements Drawable
|
|||||||
Yoga.YGNodeStyleSetMinWidth(this.yogaNode, 1);
|
Yoga.YGNodeStyleSetMinWidth(this.yogaNode, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
private StringCarousel(){
|
||||||
|
super();
|
||||||
|
this.font = Globals.fontManager.getFont("default");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a string carousel element
|
||||||
|
* @param options The options for the carousel
|
||||||
|
* @return The carousel
|
||||||
|
*/
|
||||||
|
public static StringCarousel create(List<String> options, Consumer<ValueChangeEvent> callback){
|
||||||
|
StringCarousel rVal = new StringCarousel();
|
||||||
|
rVal.setOnValueChangeCallback(new ValueChangeEventCallback() {public void execute(ValueChangeEvent event) {
|
||||||
|
callback.accept(event);
|
||||||
|
}});
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
public void addOption(String option){
|
public void addOption(String option){
|
||||||
options.add(option);
|
options.add(option);
|
||||||
if(currentOption == -1){
|
if(currentOption == -1){
|
||||||
|
|||||||
@ -97,6 +97,21 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
|
|||||||
this.setHeight(height);
|
this.setHeight(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a window
|
||||||
|
* @param openGLState The opengl state
|
||||||
|
* @param posX The x position of the window
|
||||||
|
* @param posY The y position of the window
|
||||||
|
* @param width The width of the window
|
||||||
|
* @param height The height of the window
|
||||||
|
* @param showDecorations true to show window decorations, false otherwise
|
||||||
|
* @return The window element
|
||||||
|
*/
|
||||||
|
public static Window create(OpenGLState openGLState, int posX, int posY, int width, int height, boolean showDecorations){
|
||||||
|
Window rVal = new Window(openGLState, posX, posY, width, height, showDecorations);
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(
|
public void draw(
|
||||||
RenderPipelineState renderPipelineState,
|
RenderPipelineState renderPipelineState,
|
||||||
|
|||||||
@ -14,6 +14,9 @@ public class DragEvent implements Event {
|
|||||||
int currentY;
|
int currentY;
|
||||||
int previousX;
|
int previousX;
|
||||||
int previousY;
|
int previousY;
|
||||||
|
//relative positions
|
||||||
|
int relativeX;
|
||||||
|
int relativeY;
|
||||||
int deltaX;
|
int deltaX;
|
||||||
int deltaY;
|
int deltaY;
|
||||||
DragEventType type;
|
DragEventType type;
|
||||||
@ -66,4 +69,20 @@ public class DragEvent implements Event {
|
|||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getRelativeX(){
|
||||||
|
return relativeX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRelativeY(){
|
||||||
|
return relativeY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRelativeX(int relX){
|
||||||
|
this.relativeX = relX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRelativeY(int relY){
|
||||||
|
this.relativeY = relY;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
32
src/test/java/electrosphere/renderer/ui/MainMenuTests.java
Normal file
32
src/test/java/electrosphere/renderer/ui/MainMenuTests.java
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package electrosphere.renderer.ui;
|
||||||
|
|
||||||
|
import electrosphere.menu.WindowUtils;
|
||||||
|
import electrosphere.menu.mainmenu.MenuGeneratorsUITesting;
|
||||||
|
import electrosphere.test.annotations.IntegrationTest;
|
||||||
|
import electrosphere.test.template.UITestTemplate;
|
||||||
|
import electrosphere.test.testutils.TestEngineUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests rendering the main menu
|
||||||
|
*/
|
||||||
|
public class MainMenuTests extends UITestTemplate {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests creating a window
|
||||||
|
*/
|
||||||
|
@IntegrationTest
|
||||||
|
public void test_UITestWindow_Create(){
|
||||||
|
//create ui testing window
|
||||||
|
TestEngineUtils.simulateFrames(1);
|
||||||
|
WindowUtils.replaceMainMenuContents(MenuGeneratorsUITesting.createUITestMenu());
|
||||||
|
|
||||||
|
//wait for ui updates
|
||||||
|
TestEngineUtils.flush();
|
||||||
|
|
||||||
|
TestEngineUtils.simulateFrames(1);
|
||||||
|
|
||||||
|
// TestRenderingUtils.saveTestRender("./test/java/renderer/ui/elements/window.png");
|
||||||
|
this.checkRender("Basic", "./test/java/renderer/ui/uitest.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package electrosphere.renderer.ui.elements;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for a slider element
|
||||||
|
*/
|
||||||
|
public class SliderTests {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package electrosphere.renderer.ui.elements;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for a string carousel
|
||||||
|
*/
|
||||||
|
public class StringCarouselTests {
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,9 +1,11 @@
|
|||||||
package electrosphere.renderer.ui.elements;
|
package electrosphere.renderer.ui.elements;
|
||||||
|
|
||||||
import electrosphere.test.annotations.IntegrationTest;
|
import electrosphere.test.annotations.IntegrationTest;
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.menu.WindowStrings;
|
||||||
import electrosphere.menu.WindowUtils;
|
import electrosphere.menu.WindowUtils;
|
||||||
import electrosphere.menu.mainmenu.MenuGeneratorsUITesting;
|
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
|
||||||
|
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
|
||||||
import electrosphere.test.template.UITestTemplate;
|
import electrosphere.test.template.UITestTemplate;
|
||||||
import electrosphere.test.testutils.TestEngineUtils;
|
import electrosphere.test.testutils.TestEngineUtils;
|
||||||
|
|
||||||
@ -19,15 +21,17 @@ public class WindowTest extends UITestTemplate {
|
|||||||
public void testCreateWindow(){
|
public void testCreateWindow(){
|
||||||
//create ui testing window
|
//create ui testing window
|
||||||
TestEngineUtils.simulateFrames(1);
|
TestEngineUtils.simulateFrames(1);
|
||||||
WindowUtils.replaceMainMenuContents(MenuGeneratorsUITesting.createUITestMenu());
|
Window window = Window.create(Globals.renderingEngine.getOpenGLState(),50,50,500,500,true);
|
||||||
|
window.setParentAlignItem(YogaAlignment.Center);
|
||||||
|
window.setParentJustifyContent(YogaJustification.Center);
|
||||||
|
WindowUtils.replaceWindow(WindowStrings.WINDOW_MENU_MAIN, window);
|
||||||
|
|
||||||
//wait for ui updates
|
//wait for ui updates
|
||||||
TestEngineUtils.flush();
|
TestEngineUtils.flush();
|
||||||
|
|
||||||
TestEngineUtils.simulateFrames(1);
|
TestEngineUtils.simulateFrames(1);
|
||||||
|
|
||||||
// TestRenderingUtils.saveTestRender("./test/java/renderer/ui/elements/window.png");
|
this.checkRender("Basic", "./test/java/renderer/ui/elements/window1.png");
|
||||||
this.checkRender("Basic", "./test/java/renderer/ui/elements/ui-test.png");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
BIN
test/java/renderer/ui/elements/window1.png
Normal file
BIN
test/java/renderer/ui/elements/window1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Loading…
Reference in New Issue
Block a user