summaryrefslogtreecommitdiff
path: root/engine-ocean/Game/Systems/UI
diff options
context:
space:
mode:
Diffstat (limited to 'engine-ocean/Game/Systems/UI')
-rw-r--r--engine-ocean/Game/Systems/UI/ButtonAction/buttonaction.cpp6
-rw-r--r--engine-ocean/Game/Systems/UI/ButtonAction/buttonaction.h13
-rw-r--r--engine-ocean/Game/Systems/UI/ButtonAction/showwindowaction.cpp33
-rw-r--r--engine-ocean/Game/Systems/UI/ButtonAction/showwindowaction.h21
-rw-r--r--engine-ocean/Game/Systems/UI/UITextures/UIButton.h94
-rw-r--r--engine-ocean/Game/Systems/UI/UITextures/uibutton.cpp202
-rw-r--r--engine-ocean/Game/Systems/UI/UITextures/uidisplay.cpp130
-rw-r--r--engine-ocean/Game/Systems/UI/UITextures/uidisplay.h67
-rw-r--r--engine-ocean/Game/Systems/UI/UITextures/uitexture.cpp6
-rw-r--r--engine-ocean/Game/Systems/UI/UITextures/uitexture.h39
-rw-r--r--engine-ocean/Game/Systems/UI/uielement.cpp6
-rw-r--r--engine-ocean/Game/Systems/UI/uielement.h40
-rw-r--r--engine-ocean/Game/Systems/UI/uisystem.cpp383
-rw-r--r--engine-ocean/Game/Systems/UI/uisystem.h89
14 files changed, 1129 insertions, 0 deletions
diff --git a/engine-ocean/Game/Systems/UI/ButtonAction/buttonaction.cpp b/engine-ocean/Game/Systems/UI/ButtonAction/buttonaction.cpp
new file mode 100644
index 0000000..c7314f6
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/ButtonAction/buttonaction.cpp
@@ -0,0 +1,6 @@
+#include "buttonaction.h"
+
+ButtonAction::ButtonAction()
+{
+
+}
diff --git a/engine-ocean/Game/Systems/UI/ButtonAction/buttonaction.h b/engine-ocean/Game/Systems/UI/ButtonAction/buttonaction.h
new file mode 100644
index 0000000..d6c1674
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/ButtonAction/buttonaction.h
@@ -0,0 +1,13 @@
+#ifndef BUTTONACTION_H
+#define BUTTONACTION_H
+
+
+class ButtonAction
+{
+public:
+ ButtonAction();
+ virtual void activate() = 0;
+ virtual void deactivate() = 0;
+};
+
+#endif // BUTTONACTION_H
diff --git a/engine-ocean/Game/Systems/UI/ButtonAction/showwindowaction.cpp b/engine-ocean/Game/Systems/UI/ButtonAction/showwindowaction.cpp
new file mode 100644
index 0000000..e6b9797
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/ButtonAction/showwindowaction.cpp
@@ -0,0 +1,33 @@
+#include "showwindowaction.h"
+#include "Game/Systems/UI/uisystem.h"
+#include <map>
+
+ShowWindowAction::ShowWindowAction(std::map<std::string, std::shared_ptr<UIScreen>>& all_screens,
+ std::set<std::string>& shownScreens,
+ const std::string screenName):
+ m_screens(all_screens),
+ m_shownScreens(shownScreens)
+{
+ m_screenName = screenName;
+}
+
+
+
+void ShowWindowAction::activate(){
+ std::cout << "activated window show!!!" << std::endl;
+
+ // add screen to be rendered, and also set it be the only one active
+ //m_screens[m_screenName] = m_screen;
+// for (auto &screen : m_screens){
+// screen.second->isActive = false;
+// }
+
+// m_screens[m_screenName]->isActive = true;
+ m_shownScreens.insert(m_screenName);
+ m_screens[m_screenName]->isActive = true;
+
+}
+
+void ShowWindowAction::deactivate(){
+ m_shownScreens.erase(m_screenName);
+}
diff --git a/engine-ocean/Game/Systems/UI/ButtonAction/showwindowaction.h b/engine-ocean/Game/Systems/UI/ButtonAction/showwindowaction.h
new file mode 100644
index 0000000..781f093
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/ButtonAction/showwindowaction.h
@@ -0,0 +1,21 @@
+#ifndef SHOWWINDOWACTION_H
+#define SHOWWINDOWACTION_H
+#include "Game/Systems/UI/uisystem.h"
+#include <map>
+#include "buttonaction.h"
+
+class ShowWindowAction : public ButtonAction
+{
+public:
+ ShowWindowAction(std::map<std::string, std::shared_ptr<UIScreen>>& screens,
+ std::set<std::string>& shownScreens,
+ const std::string screenName);
+ void activate() override;
+ void deactivate() override;
+private:
+ std::set<std::string>& m_shownScreens;
+ std::string m_screenName;
+ std::map<std::string, std::shared_ptr<UIScreen>>& m_screens;
+};
+
+#endif // SHOWWINDOWACTION_H
diff --git a/engine-ocean/Game/Systems/UI/UITextures/UIButton.h b/engine-ocean/Game/Systems/UI/UITextures/UIButton.h
new file mode 100644
index 0000000..8cf02ee
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/UITextures/UIButton.h
@@ -0,0 +1,94 @@
+#ifndef UIBUTTON_H
+#define UIBUTTON_H
+#include "Game/Systems/UI/ButtonAction/buttonaction.h"
+#include "Game/Systems/UI/UITextures/uidisplay.h"
+#include "Graphics/global.h"
+#include <GLFW/glfw3.h>
+#include <set>
+#include "uitexture.h"
+
+enum CornerPosition {
+ TOPLEFT,
+ TOPRIGHT,
+ BOTTOMLEFT,
+ BOTTOMRIGHT,
+ NONE
+};
+
+class UIButton : public UITexture
+{
+public:
+ UIButton(TextureData tex, glm::vec2 pos, glm::vec2 scale, std::set<std::string>& shownScreens,
+ bool isCloseButton = false, CornerPosition corner = NONE, AspectRatio ratio = LAND_FIT);
+ ~UIButton();
+ void draw() override;
+ GLuint getTexID() override;
+ glm::vec2 getPos() override;
+ glm::vec2 getScale() override;
+ float getTextureRatio() override;
+ AspectRatio getAspectRatio();
+
+
+
+ void setWindowPos(int width, int height) override;
+ glm::vec2 getWindowPos();
+
+ int getHeight() override;
+ int getWidth() override;
+ Bounds2f getBounds() override;
+ float getTextureScaleAspect() override;
+
+ void addButtonAction(std::shared_ptr<ButtonAction> &action);
+ bool onButtonPress();
+ void setWindowToClose(std::string windowID);
+
+ void setParentDisplay(std::string parent);
+ std::string getParentDisplay();
+
+ CornerPosition getCornerPos();
+ bool hasCornerPos = false;
+ void setToCorner(const CornerPosition corner, int width, int height);
+
+ void setTransformationMat(glm::vec2 translation, glm::vec2 scale);
+ glm::mat4 getTransformationMat();
+
+
+
+private:
+ glm::mat4 getScaleMatrix(glm::vec2 scale);
+ int getScreenHeight();
+ int getScreenWidth();
+ void setTexID(GLuint &newTexID);
+
+
+ TextureData m_tex;
+ glm::vec2 m_pos;
+ glm::vec2 m_scale;
+ Bounds2f m_bounds;
+ glm::vec2 m_windowPos; // width, height
+ float m_windowHeight = 480.f;
+ float m_windowWidth = 640.f;
+ float m_toScreenScale = 1.f;
+
+ int m_screenImageHeight;
+ int m_screenImageWidth;
+ float m_tex_aspectRatio = 1.f;
+ bool m_isCloseButton = false;
+ std::string m_attachedWindow;
+
+ std::vector<std::shared_ptr<ButtonAction>> m_actions;
+ std::set<std::string>& m_shownScreens;
+
+ CornerPosition m_cornerPos;
+ std::string m_parentDisplay;
+
+ glm::mat4 m_transformationMat;
+ float m_textureAspect = 1.f;
+
+ AspectRatio m_aspectRatio;
+
+
+
+};
+
+#endif // UIButton_H
diff --git a/engine-ocean/Game/Systems/UI/UITextures/uibutton.cpp b/engine-ocean/Game/Systems/UI/UITextures/uibutton.cpp
new file mode 100644
index 0000000..031be2f
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/UITextures/uibutton.cpp
@@ -0,0 +1,202 @@
+#include "UIButton.h"
+#include "Game/Systems/UI/UITextures/UIDisplay.h"
+#include <set>
+
+UIButton::UIButton(TextureData tex, glm::vec2 pos, glm::vec2 scale, std::set<std::string>& shownScreens,
+ bool isCloseButton, CornerPosition corner, AspectRatio ratio):
+ m_tex(tex),
+ m_shownScreens(shownScreens),
+ m_aspectRatio(ratio)
+{
+
+ // set variables
+ m_isCloseButton = isCloseButton;
+ m_pos = pos;
+ m_scale = scale;
+ m_tex_aspectRatio = static_cast<float>(m_tex.height)/static_cast<float>(m_tex.width);
+
+ setToCorner(corner, 640, 480);
+ setWindowPos(640, 480);
+ setTransformationMat(m_pos, scale);
+
+}
+UIButton::~UIButton(){
+ glDeleteTextures(1, &m_tex.textureID);
+}
+
+
+AspectRatio UIButton::getAspectRatio(){
+ return m_aspectRatio;
+}
+
+glm::mat4 UIButton::getScaleMatrix(glm::vec2 scale) {
+ glm::mat4 M = glm::mat4(1.f);
+ M[0][0] = scale.x; //* (m_screenImageHeight/m_screenImageWidth);
+ M[1][1] = scale.y; //* (m_tex_aspectRatio);
+ M[2][2] = 1.f;
+ return M;
+}
+
+void UIButton::setTransformationMat(glm::vec2 translation, glm::vec2 scale){
+ glm::mat4 transMat = glm::mat4(1.f);
+ transMat[3] = glm::vec4(translation.x, translation.y, 0.f, 1.f);
+ glm::mat4 scaleMat = getScaleMatrix(glm::vec2(scale));
+ m_transformationMat = transMat*scaleMat;
+}
+
+glm::mat4 UIButton::getTransformationMat(){
+ return m_transformationMat;
+}
+
+float UIButton::getTextureRatio(){
+ return m_tex_aspectRatio;
+}
+
+
+void UIButton::draw(){}
+
+GLuint UIButton::getTexID(){
+ return m_tex.textureID;
+}
+
+glm::vec2 UIButton::getPos(){
+ return m_pos;
+}
+
+glm::vec2 UIButton::getScale(){
+ return m_scale;
+}
+
+//void UIButton::setTexID(GLuint &newTexID){
+// m_tex.textureID = newTexID;
+//}
+
+void UIButton::setWindowPos(int width, int height){
+ m_windowHeight = static_cast<float>(height);
+ m_windowWidth = static_cast<float>(width);
+
+ // find where on window it is, for bound checking
+ float xpos = .5f*(m_pos.x + 1.f)*m_windowWidth;
+ float ypos = (1.f-.5f*(m_pos.y + 1.f))*m_windowHeight;
+ m_windowPos = glm::vec2(xpos, ypos);
+
+ // set everything according to window dimensions -- this is for bound checking
+ m_toScreenScale = m_windowHeight*m_scale.y;
+ m_screenImageHeight = m_toScreenScale;
+ m_screenImageWidth = m_toScreenScale * m_tex_aspectRatio;
+
+ float windowRatio = m_windowHeight/m_windowWidth;
+ m_textureAspect = windowRatio / m_tex_aspectRatio;
+
+ // calculate window bounds
+ glm::vec2 halfDimensions = glm::vec2(m_screenImageWidth, m_screenImageHeight)*.5f;
+ m_bounds.max = glm::vec2(m_windowPos.x + halfDimensions.x, m_windowPos.y - halfDimensions.y);
+ m_bounds.min = glm::vec2(m_windowPos.x - halfDimensions.x, m_windowPos.y + halfDimensions.y);
+}
+
+float UIButton::getTextureScaleAspect(){
+ return m_textureAspect;
+}
+
+void UIButton::setParentDisplay(std::string parent){
+ m_parentDisplay = parent;
+
+}
+
+std::string UIButton::getParentDisplay(){
+ return m_parentDisplay;
+
+}
+
+CornerPosition UIButton::getCornerPos(){
+ return m_cornerPos;
+
+}
+
+void UIButton::setToCorner(const CornerPosition corner, int width, int height){
+
+ m_toScreenScale = static_cast<float>(height)*m_scale.y;
+ m_screenImageHeight = m_toScreenScale;
+ m_screenImageWidth = m_toScreenScale * m_tex_aspectRatio;
+
+ // in texture space
+ float xtrans = m_screenImageWidth/(.5f*static_cast<float>(width));
+ float ytrans = m_screenImageHeight/(.5f*static_cast<float>(height));
+
+ // find where window pos should be
+ switch(corner){
+ case TOPLEFT:
+ m_pos = glm::vec2(-1+xtrans, 1-ytrans);
+
+ break;
+ case TOPRIGHT:
+ m_pos = glm::vec2(1-xtrans, 1-ytrans);
+
+ break;
+ case BOTTOMLEFT:
+ m_pos = glm::vec2(-1+xtrans, -1+ytrans);
+
+ break;
+ case BOTTOMRIGHT:
+ m_pos = glm::vec2(1-xtrans, -1+ytrans);
+ break;
+ default:
+ break;
+ }
+}
+
+glm::vec2 UIButton::getWindowPos(){
+ return m_windowPos;
+}
+
+int UIButton::getHeight(){
+ return m_tex.height;
+}
+int UIButton::getWidth(){
+ return m_tex.width;
+}
+
+int UIButton::getScreenHeight(){
+ return m_screenImageHeight;
+}
+int UIButton::getScreenWidth(){
+ return m_screenImageWidth;
+}
+
+// remember that origin is top left corner!!
+Bounds2f UIButton::getBounds(){
+
+ return m_bounds;
+}
+
+void UIButton::addButtonAction(std::shared_ptr<ButtonAction> &action){
+ m_actions.push_back(action);
+}
+
+//////*/ for close button only
+void UIButton::setWindowToClose(std::string windowID){
+ if (m_isCloseButton){
+ m_attachedWindow = windowID;
+ }
+
+}
+
+bool UIButton::onButtonPress(){
+ // if button is a close button, then deactivate everything
+ if (m_isCloseButton){
+ std::cout << "shownWindowSize: " << m_shownScreens.size() << std::endl;
+ //m_shownScreens.erase(m_attachedWindow);
+ std::cout << "new shownWindowSize: " << m_shownScreens.size() << std::endl;
+ std::cout << "CLOSE WINDOW: " << m_attachedWindow << std::endl;
+ return true;
+
+
+ } else {
+ for (auto &action : m_actions){
+ action->activate();
+ }
+ return false;
+ }
+
+}
+
diff --git a/engine-ocean/Game/Systems/UI/UITextures/uidisplay.cpp b/engine-ocean/Game/Systems/UI/UITextures/uidisplay.cpp
new file mode 100644
index 0000000..2ddaf62
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/UITextures/uidisplay.cpp
@@ -0,0 +1,130 @@
+#include "uidisplay.h"
+#include <set>
+
+UIDisplay::UIDisplay(TextureData tex, glm::vec2 pos, glm::vec2 scale,
+ std::set<std::string>& shownScreens,
+ AspectRatio ratio):
+ m_tex(tex),
+ m_shownScreens(shownScreens),
+ m_aspectRatio(ratio)
+{
+
+ m_pos = (pos);
+ m_scale = (scale);
+ m_tex_aspectRatio = static_cast<float>(m_tex.height)/static_cast<float>(m_tex.width);
+ setTransformationMat(pos, scale);
+// std::cout << "tex aspect ratio:" << m_tex_aspectRatio << std::endl;
+
+// std::cout << "aspect ratio w: " << m_tex.width << std::endl;
+// std::cout << "aspect ratio h: " << m_tex.height << std::endl;
+
+
+ setWindowPos(640, 480);
+// std::cout << "screen image height: " << m_screenImageHeight << std::endl;
+// std::cout << "screen image width: " << m_screenImageWidth << std::endl;
+
+}
+
+UIDisplay::~UIDisplay(){
+ glDeleteTextures(1, &m_tex.textureID);
+}
+
+void UIDisplay::draw(){}
+
+GLuint UIDisplay::getTexID(){
+ return m_tex.textureID;
+}
+
+glm::vec2 UIDisplay::getPos(){
+ return m_pos;
+}
+
+glm::vec2 UIDisplay::getScale(){
+ return m_scale;
+}
+
+AspectRatio UIDisplay::getAspectRatio(){
+ return m_aspectRatio;
+}
+
+void UIDisplay::setWindowPos(int width, int height){
+ float xpos = .5f*(m_pos.x + 1.f)*static_cast<float>(width);
+ float ypos = (1.f-.5f*(m_pos.y + 1.f))*static_cast<float>(height);
+ m_windowPos = glm::vec2(xpos, ypos);
+
+ // set everything according to window dimensions
+ m_toScreenScale = static_cast<float>(height)*m_scale.y;
+ m_screenImageHeight = m_toScreenScale;
+ m_screenImageWidth = m_toScreenScale * m_tex_aspectRatio;
+
+ float windowRatio = static_cast<float>(height)/static_cast<float>(width);
+ m_textureAspect = windowRatio / m_tex_aspectRatio;
+}
+
+void UIDisplay::setPos(glm::vec2 pos){
+ m_pos = pos;
+ setTransformationMat(m_pos, m_scale);
+}
+void UIDisplay::setScale(glm::vec2 scale){
+ m_scale = scale;
+ setTransformationMat(m_pos, m_scale);
+}
+
+float UIDisplay::getTextureScaleAspect(){
+ return m_textureAspect;
+}
+
+glm::vec2 UIDisplay::getWindowPos(){
+ return m_windowPos;
+}
+
+int UIDisplay::getHeight(){
+ return m_tex.height;
+}
+int UIDisplay::getWidth(){
+ return m_tex.width;
+}
+
+int UIDisplay::getScreenHeight(){
+ return m_screenImageHeight;
+}
+int UIDisplay::getScreenWidth(){
+ return m_screenImageWidth;
+}
+
+glm::mat4 UIDisplay::getScaleMatrix(glm::vec2 scale) {
+ glm::mat4 M = glm::mat4(1.f);
+ M[0][0] = scale.x;//* (m_screenImageHeight/m_screenImageWidth);
+ M[1][1] = scale.y; //* (m_tex_aspectRatio);
+ M[2][2] = 1.f;
+ return M;
+}
+
+void UIDisplay::setTransformationMat(glm::vec2 translation, glm::vec2 scale){
+ glm::mat4 transMat = glm::mat4(1.f);
+ transMat[3] = glm::vec4(translation.x, translation.y, 0.f, 1.f);
+
+ glm::mat4 scaleMat = getScaleMatrix(glm::vec2(scale));
+
+ m_transformationMat = transMat*scaleMat;
+}
+
+glm::mat4 UIDisplay::getTransformationMat(){
+ return m_transformationMat;
+}
+
+// remember that origin is top left corner!!
+Bounds2f UIDisplay::getBounds(){
+ glm::vec2 halfDimensions = glm::vec2(m_screenImageWidth, m_screenImageHeight)*.5f;
+ m_bounds.max = glm::vec2(m_windowPos.x + halfDimensions.x, m_windowPos.y - halfDimensions.y);
+ m_bounds.min = glm::vec2(m_windowPos.x - halfDimensions.x, m_windowPos.y + halfDimensions.y);
+ return m_bounds;
+}
+
+float UIDisplay::getTextureRatio(){
+ return m_tex_aspectRatio;
+}
+
+
+
+
diff --git a/engine-ocean/Game/Systems/UI/UITextures/uidisplay.h b/engine-ocean/Game/Systems/UI/UITextures/uidisplay.h
new file mode 100644
index 0000000..4b739cc
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/UITextures/uidisplay.h
@@ -0,0 +1,67 @@
+#ifndef UIDISPLAY_H
+#define UIDISPLAY_H
+#include "uitexture.h"
+#include <set>
+
+
+
+class UIDisplay : public UITexture
+{
+public:
+ UIDisplay(TextureData tex, glm::vec2 pos, glm::vec2 scale, std::set<std::string>& shownScreens,
+ AspectRatio ratio = FIT_SCREEN);
+ ~UIDisplay();
+ void draw() override;
+ GLuint getTexID() override;
+ glm::vec2 getPos() override;
+ glm::vec2 getScale() override;
+
+ void setWindowPos(int width, int height) override;
+ glm::vec2 getWindowPos();
+
+ int getHeight() override;
+ int getWidth() override;
+ Bounds2f getBounds() override;
+ float getTextureRatio() override;
+ float getTextureScaleAspect() override;
+ void setPos(glm::vec2 pos);
+ void setScale(glm::vec2 scale);
+
+ AspectRatio getAspectRatio();
+
+
+ // glm::vec2 getCornerPos(CornerPosition corner, glm::vec2 elementDimensions);
+ void setTransformationMat(glm::vec2 translation, glm::vec2 scale);
+ glm::mat4 getTransformationMat();
+
+private:
+ int getScreenHeight();
+ int getScreenWidth();
+ void setTexID(GLuint &newTexID);
+ glm::mat4 getScaleMatrix(glm::vec2 scale);
+
+
+
+ TextureData m_tex;
+ glm::vec2 m_pos;
+ glm::vec2 m_scale;
+ Bounds2f m_bounds;
+ glm::vec2 m_windowPos; // width, height
+ int m_windowHeight = 480.f;
+ int m_windowWidth = 640.f;
+ float m_toScreenScale = 1.f;
+
+ int m_screenImageHeight;
+ int m_screenImageWidth;
+ float m_tex_aspectRatio = 1.f;
+ bool m_isCloseButton = false;
+ std::string m_attachedWindow;
+
+ std::set<std::string>& m_shownScreens;
+ glm::mat4 m_transformationMat;
+ float m_textureAspect = 1.f;
+
+ AspectRatio m_aspectRatio;
+};
+
+#endif // UIDISPLAY_H
diff --git a/engine-ocean/Game/Systems/UI/UITextures/uitexture.cpp b/engine-ocean/Game/Systems/UI/UITextures/uitexture.cpp
new file mode 100644
index 0000000..8680baf
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/UITextures/uitexture.cpp
@@ -0,0 +1,6 @@
+#include "uitexture.h"
+
+UITexture::UITexture()
+{
+
+}
diff --git a/engine-ocean/Game/Systems/UI/UITextures/uitexture.h b/engine-ocean/Game/Systems/UI/UITextures/uitexture.h
new file mode 100644
index 0000000..53e429d
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/UITextures/uitexture.h
@@ -0,0 +1,39 @@
+#ifndef UITEXTURE_H
+#define UITEXTURE_H
+#include "Graphics/global.h"
+#include <GLFW/glfw3.h>
+
+struct Bounds2f{
+ glm::vec2 min;
+ glm::vec2 max;
+};
+
+enum AspectRatio {
+ LAND_FIT,
+ LAND_FILL,
+ PORTRAIT_FIT,
+ PORTRAIT_FILL,
+ FIT_SCREEN
+};
+
+class UITexture
+{
+public:
+ UITexture();
+ virtual void draw() = 0;
+ virtual GLuint getTexID() = 0;
+ virtual glm::vec2 getPos() = 0;
+ virtual glm::vec2 getScale() = 0;
+ virtual int getHeight() = 0;
+ virtual int getWidth() = 0;
+ virtual Bounds2f getBounds() = 0;
+ virtual void setWindowPos(int width, int height) = 0;
+ virtual float getTextureRatio() = 0;
+ virtual float getTextureScaleAspect() = 0;
+
+
+
+
+};
+
+#endif // UITEXTURE_H
diff --git a/engine-ocean/Game/Systems/UI/uielement.cpp b/engine-ocean/Game/Systems/UI/uielement.cpp
new file mode 100644
index 0000000..bb7d91f
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/uielement.cpp
@@ -0,0 +1,6 @@
+#include "uielement.h"
+
+UIElement::UIElement()
+{
+
+}
diff --git a/engine-ocean/Game/Systems/UI/uielement.h b/engine-ocean/Game/Systems/UI/uielement.h
new file mode 100644
index 0000000..c2c3a2e
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/uielement.h
@@ -0,0 +1,40 @@
+#ifndef UIELEMENT_H
+#define UIELEMENT_H
+
+
+#include "Game/Systems/UI/UITextures/uitexture.h"
+#include "Game/TypeMap.h"
+#include <memory>
+class UIElement
+{
+public:
+ UIElement();
+
+ template <typename T>
+ void addComponent(std::unique_ptr<T> &&component){
+ m_components.put<T>(std::forward<std::unique_ptr<T>>(component));
+ }
+
+ template <typename T>
+ bool hasComponent(){
+ return m_components.contains<T>();
+ }
+
+ template <class T>
+ T* getComponent(){
+ auto comp = m_components.find<T>();
+ assert(comp != m_components.end());
+ return static_cast<T*>(comp->second.get());
+ }
+
+ template <class T>
+ void removeComponent(){
+ m_components.remove<T>();
+ }
+
+private:
+
+ TypeMap<std::unique_ptr<UITexture>> m_components;
+};
+
+#endif // UIELEMENT_H
diff --git a/engine-ocean/Game/Systems/UI/uisystem.cpp b/engine-ocean/Game/Systems/UI/uisystem.cpp
new file mode 100644
index 0000000..09aff49
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/uisystem.cpp
@@ -0,0 +1,383 @@
+#include "uisystem.h"
+#include "Game/GameWorld.h"
+#include "Game/Systems/UI/ButtonAction/showwindowaction.h"
+#include "Game/Systems/UI/UITextures/UIButton.h"
+#include "Game/Systems/UI/UITextures/uidisplay.h"
+#define GLFW_POINTING_HAND_CURSOR
+
+UISystem::UISystem(std::shared_ptr<Camera> camera,
+ std::map<int, Input>& input_map,
+ std::set<std::string>& shownScreens):
+ m_camera(camera),
+ m_input_map(input_map),
+ m_shownScreens(shownScreens)
+{
+
+
+ initializeStartScreen();
+ initializeScreenMap();
+ //m_pointerCursor = glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR);
+
+}
+
+UISystem::~UISystem(){
+ for (auto &screenID : m_all_screens){
+ glDeleteVertexArrays(1, &screenID.second->screenVAOID);
+ }
+}
+
+void UISystem::initializeScreenMap(){
+ initializeProfileScreen();
+ initializeInventory();
+ initializeScreen();
+
+ m_shownScreens.insert("home");
+
+}
+
+void UISystem::initializeScreen(){
+ std::shared_ptr<UIScreen> home = std::make_shared<UIScreen>();
+ home->isActive = true;
+ home->screenVAOID = Global::graphics.makeVAO(m_quadPos);
+ m_quad_numVertices = 4;
+
+ float topLevel = .85f;
+
+ makeButtonElement(home, "profileButton", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/profileicon.png", glm::vec2(.85f,topLevel), glm::vec2(.05f), AspectRatio::LAND_FILL);
+ std::shared_ptr<ButtonAction> showProfile = std::make_shared<ShowWindowAction>(m_all_screens, m_shownScreens, "profile");
+ home->screenElements.at("profileButton")->getComponent<UIButton>()->addButtonAction(showProfile);
+
+ makeButtonElement(home, "inventoryButton", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/inventoryicon.png", glm::vec2(.75f, topLevel), glm::vec2(.05f), AspectRatio::LAND_FILL);
+ std::shared_ptr<ButtonAction> showInv = std::make_shared<ShowWindowAction>(m_all_screens, m_shownScreens, "inventory");
+ home->screenElements.at("inventoryButton")->getComponent<UIButton>()->addButtonAction(showInv);
+
+ makeButtonElement(home, "questsButton", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/questicon.png", glm::vec2(.65f, topLevel), glm::vec2(.05f), AspectRatio::LAND_FILL);
+ makeButtonElement(home, "settingsButton", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/settings_icon.png", glm::vec2(-.85f, topLevel), glm::vec2(.05f), AspectRatio::LAND_FILL);
+ makeDisplayElement(home, "healthbar", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/healthbar.png", glm::vec2(0.f, -.5f), glm::vec2(.4f), AspectRatio::LAND_FIT);
+
+// TextureData reflectTex;
+// reflectTex.textureID = Global::graphics.getReflectionTexture();
+// reflectTex.width = Global::graphics.REFLECTION_W;
+// reflectTex.height = Global::graphics.REFLECTION_H;
+// makeDisplayElement(home, "reflection", reflectTex, glm::vec2(.5f, -.5f), glm::vec2(.3f), AspectRatio::LAND_FIT);
+
+// TextureData refractTex;
+// refractTex.textureID = Global::graphics.getRefractionTexture();
+// refractTex.width = Global::graphics.REFRACTION_W;
+// refractTex.height = Global::graphics.REFRACTION_H;
+// makeDisplayElement(home, "refract", refractTex, glm::vec2(-.5f, -.5f), glm::vec2(.3f), AspectRatio::LAND_FIT);
+
+
+
+
+ home->elementsDepthOrder.push_back("profileButton");
+ home->elementsDepthOrder.push_back("inventoryButton");
+ home->elementsDepthOrder.push_back("questsButton");
+ home->elementsDepthOrder.push_back("settingsButton");
+ home->elementsDepthOrder.push_back("healthbar");
+ // home->elementsDepthOrder.push_back("reflection");
+ // home->elementsDepthOrder.push_back("refract");
+
+
+
+ m_all_screens.insert({"home", home});
+}
+
+void UISystem::initializeProfileScreen(){
+
+ std::shared_ptr<UIScreen> profile = std::make_shared<UIScreen>();
+ profile->isActive = false;
+ profile->screenVAOID = Global::graphics.makeVAO(m_quadPos);
+ m_quad_numVertices = 4;
+
+ float topLevel = .85f;
+
+ // eventually should be display, not button
+ makeDisplayElement(profile, "bg", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/inventory_bg.png", glm::vec2(0.f), glm::vec2(1.0f));
+ makeDisplayElement(profile, "profileDisplay", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/mouse_profile.png", glm::vec2(0.f), glm::vec2(1.0f), AspectRatio::LAND_FIT);
+ makeButtonElement(profile, "closeButton", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/close_icon.png", glm::vec2(0.f), glm::vec2(.05f), AspectRatio::LAND_FILL, true, CornerPosition::TOPRIGHT);
+ profile->screenElements.at("closeButton")->getComponent<UIButton>()->setWindowToClose("profile");
+
+ profile->elementsDepthOrder.push_back("bg");
+ profile->elementsDepthOrder.push_back("profileDisplay");
+ profile->elementsDepthOrder.push_back("closeButton");
+
+ m_all_screens.insert({"profile", profile});
+}
+
+void UISystem::initializeInventory(){
+ std::shared_ptr<UIScreen> inv = std::make_shared<UIScreen>();
+ inv->isActive = false;
+ inv->screenVAOID = Global::graphics.makeVAO(m_quadPos);
+ m_quad_numVertices = 4;
+
+ makeDisplayElement(inv, "bg", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/inventory_bg.png", glm::vec2(0.f), glm::vec2(1.0f));
+ makeDisplayElement(inv, "inventoryDisplay", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/inventory_page.png", glm::vec2(0.f), glm::vec2(1.0f), AspectRatio::LAND_FIT);
+ makeButtonElement(inv, "closeButton", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/close_icon.png", glm::vec2(0.f), glm::vec2(.05f), AspectRatio::LAND_FILL, true, CornerPosition::TOPRIGHT);
+ inv->screenElements.at("closeButton")->getComponent<UIButton>()->setWindowToClose("inventory");
+ inv->elementsDepthOrder.push_back("bg");
+ inv->elementsDepthOrder.push_back("inventoryDisplay");
+ inv->elementsDepthOrder.push_back("closeButton");
+
+ m_all_screens.insert({"inventory", inv});
+}
+
+void UISystem::initializeStartScreen(){
+
+ std::shared_ptr<UIScreen> start = std::make_shared<UIScreen>();
+ start->isActive = true;
+ start->screenVAOID = Global::graphics.makeVAO(m_quadPos);
+
+ float topLevel = .85f;
+
+ // eventually should be display, not button
+ makeDisplayElement(start, "startDisplay", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/title.png", glm::vec2(0.f), glm::vec2(1.0f), AspectRatio::LAND_FIT);
+ makeButtonElement(start, "startButton", "/Users/jesswan/Desktop/cs1950u/cs1950u-jjesswan/Resources/Images/enterbutton.png", glm::vec2(0.f, -.57f), glm::vec2(.19f), AspectRatio::LAND_FIT, true);
+ start->screenElements.at("startButton")->getComponent<UIButton>()->setWindowToClose("start");
+
+ start->elementsDepthOrder.push_back("startDisplay");
+ start->elementsDepthOrder.push_back("startButton");
+
+ m_all_screens.insert({"start", start});
+ m_shownScreens.insert("start");
+}
+
+glm::vec2 UISystem::drawAspect(AspectRatio aspectType, float textureAspect){
+ switch(aspectType){
+ case FIT_SCREEN:
+ return glm::vec2(1.f);
+ break;
+ case LAND_FIT:case PORTRAIT_FILL:
+ return glm::vec2(1.f, textureAspect);
+ break;
+ case LAND_FILL: case PORTRAIT_FIT:
+ return glm::vec2(1.f/textureAspect, 1.f);
+ break;
+ }
+}
+
+
+
+void UISystem::makeButtonElement(std::shared_ptr<UIScreen> &screen,
+ std::string elementName, const char* filename,
+ const glm::vec2 pos, const glm::vec2 scale,
+ AspectRatio aspectRatio,
+ bool isCloseButton,
+ CornerPosition corner){
+ TextureData tex = Global::graphics.loadTextureFromFile(filename);
+
+ std::shared_ptr<UIElement> uiElement = std::make_shared<UIElement>();
+
+ uiElement->addComponent<UIButton>(std::make_unique<UIButton>(tex, pos, scale, m_shownScreens, isCloseButton, corner, aspectRatio));
+ screen->screenElements.insert({elementName, uiElement});
+}
+
+void UISystem::makeDisplayElement(std::shared_ptr<UIScreen> &screen,
+ std::string elementName, const char* filename,
+ const glm::vec2 pos, const glm::vec2 scale,
+ AspectRatio aspectRatio){
+ TextureData tex = Global::graphics.loadTextureFromFile(filename);
+
+ std::shared_ptr<UIElement> uiElement = std::make_shared<UIElement>();
+ uiElement->addComponent<UIDisplay>(std::make_unique<UIDisplay>(tex, pos, scale, m_shownScreens, aspectRatio));
+ screen->screenElements.insert({elementName, uiElement});
+}
+
+void UISystem::makeDisplayElement(std::shared_ptr<UIScreen> &screen,
+ std::string elementName, TextureData &tex,
+ const glm::vec2 pos, const glm::vec2 scale,
+ AspectRatio aspectRatio){
+
+ std::shared_ptr<UIElement> uiElement = std::make_shared<UIElement>();
+ uiElement->addComponent<UIDisplay>(std::make_unique<UIDisplay>(tex, pos, scale, m_shownScreens, aspectRatio));
+ screen->screenElements.insert({elementName, uiElement});
+}
+
+void UISystem::renderScreen(){
+ // bind shader
+ Global::graphics.bindShader("ui");
+
+ // for window resizing
+ Global::graphics.setCameraData(m_camera);
+
+ // enable alpha blending
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ // disable depth testing
+ glDisable(GL_DEPTH_TEST);
+
+ for (auto &screenID : m_shownScreens){
+ // bind quad
+ glBindVertexArray(m_all_screens[screenID]->screenVAOID);
+ glEnableVertexAttribArray(0);
+
+ // loop through inventory ui elements
+
+ // loop through ui elements
+ for (auto &gui: m_all_screens[screenID]->elementsDepthOrder){
+ if (m_all_screens[screenID]->screenElements[gui]->hasComponent<UIDisplay>()){
+ GLuint texID;
+ if (gui == "reflection"){
+ //std::cout << "rendering reflection" << std::endl;
+ texID = Global::graphics.getReflectionTexture();
+ } else if (gui == "refract"){
+ texID = Global::graphics.getRefractionTexture();
+ } else {
+ texID = m_all_screens[screenID]->screenElements[gui]->getComponent<UIDisplay>()->getTexID();
+ }
+ glm::mat4 transMat = m_all_screens[screenID]->screenElements[gui]->getComponent<UIDisplay>()->getTransformationMat();
+ float texAspect = m_all_screens[screenID]->screenElements[gui]->getComponent<UIDisplay>()->getTextureScaleAspect();
+ AspectRatio ratio = m_all_screens[screenID]->screenElements[gui]->getComponent<UIDisplay>()->getAspectRatio();
+
+ glActiveTexture(GL_TEXTURE5);
+ glBindTexture(GL_TEXTURE_2D, texID);
+
+ glm::vec2 texScale = drawAspect(ratio, texAspect);
+
+ glUniform2f(glGetUniformLocation(Global::graphics.getShaderID("ui"), "textureScale"), texScale.x, texScale.y);
+ glUniformMatrix4fv(glGetUniformLocation(Global::graphics.getShaderID("ui"), "transform"), 1, GL_FALSE, glm::value_ptr(transMat[0]));
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, m_quad_numVertices);
+ }
+ if (m_all_screens[screenID]->screenElements[gui]->hasComponent<UIButton>()){
+ GLuint texID = m_all_screens[screenID]->screenElements[gui]->getComponent<UIButton>()->getTexID();
+ glm::mat4 transMat = m_all_screens[screenID]->screenElements[gui]->getComponent<UIButton>()->getTransformationMat();
+ float texAspect = m_all_screens[screenID]->screenElements[gui]->getComponent<UIButton>()->getTextureScaleAspect();
+ AspectRatio ratio = m_all_screens[screenID]->screenElements[gui]->getComponent<UIButton>()->getAspectRatio();
+
+ glActiveTexture(GL_TEXTURE5);
+ glBindTexture(GL_TEXTURE_2D, texID);
+
+ glm::vec2 texScale = drawAspect(ratio, texAspect);
+
+ glUniform2f(glGetUniformLocation(Global::graphics.getShaderID("ui"), "textureScale"), texScale.x, texScale.y);
+ glUniformMatrix4fv(glGetUniformLocation(Global::graphics.getShaderID("ui"), "transform"), 1, GL_FALSE, glm::value_ptr(transMat[0]));
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, m_quad_numVertices);
+
+
+ }
+
+ }
+ glDisableVertexAttribArray(0);
+ glBindVertexArray(0);
+ }
+ glDisable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+}
+
+
+
+void UISystem::draw(){
+ renderScreen();
+}
+
+glm::mat4 UISystem::getScaleMatrix(glm::vec2 scale) {
+ glm::mat4 M = glm::mat4(1.f);
+ M[0][0] = scale.x * (m_aspectRatio);
+ M[1][1] = scale.y;
+ M[2][2] = 0.f;
+ return M;
+}
+
+glm::mat4 UISystem::makeTransformationMat(glm::vec2 translation, glm::vec2 scale){
+ glm::mat4 transMat = glm::mat4(1.f);
+ transMat[3] = glm::vec4(translation.x, translation.y, 0.f, 1.f);
+
+ glm::mat4 scaleMat = getScaleMatrix(glm::vec2(scale));
+
+ return transMat*scaleMat;
+}
+
+void UISystem::update(double deltaTime){
+ // allow for one more update cycle before deactivating click
+ if (m_input_map[GLFW_MOUSE_BUTTON_LEFT].isClicked){
+ // check if clicked inside gui
+ // only act on the front-most gui being clicked
+ std::set<std::string>::iterator it = m_shownScreens.begin();
+ while(it != m_shownScreens.end()) {
+ std::set<std::string>::iterator current = it++;
+ std::string screenID = *current;
+ // render all active screens
+ if (m_all_screens[screenID]->isActive){
+ // loop through ui elements
+ for (auto &gui: m_all_screens[screenID]->screenElements){
+ if (gui.second->hasComponent<UIButton>()){
+ bool isInside = false;
+ Bounds2f buttonBounds = gui.second->getComponent<UIButton>()->getBounds();
+ isInside = checkInsideGUI(m_mousepos, buttonBounds);
+ if (isInside){
+ bool toClose = gui.second->getComponent<UIButton>()->onButtonPress();
+ if (toClose){
+ m_shownScreens.erase(current);
+
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (m_input_map[GLFW_MOUSE_BUTTON_LEFT].checkClickTime > 1){
+ m_input_map[GLFW_MOUSE_BUTTON_LEFT].isClicked = false;
+ } else {
+ m_input_map[GLFW_MOUSE_BUTTON_LEFT].checkClickTime ++;
+ }
+ }
+}
+
+bool UISystem::checkInsideGUI(glm::vec2 mouseClickPos, Bounds2f guiBounds){
+ if (mouseClickPos.x < guiBounds.max.x
+ && mouseClickPos.x > guiBounds.min.x
+ && mouseClickPos.y > guiBounds.max.y
+ && mouseClickPos.y < guiBounds.min.y){
+ return true;
+ }
+
+ return false;
+}
+
+
+void UISystem::scrollEvent(double distance){}
+
+void UISystem::mousePosEvent(double xpos, double ypos){
+ m_mousepos = glm::vec2(xpos, ypos);
+
+ for (auto &screenID : m_shownScreens){
+ Global::graphics.bindShader("ui");
+ //glUniform1i(glGetUniformLocation(Global::graphics.getShaderID("ui"), "hovering"), false);
+ // render all active screens
+ if (m_all_screens[screenID]->isActive){
+ // loop through ui elements
+ for (auto &gui: m_all_screens[screenID]->screenElements){
+ if (gui.second->hasComponent<UIButton>()){
+ bool isInside;
+ Bounds2f buttonBounds = gui.second->getComponent<UIButton>()->getBounds();
+ isInside = checkInsideGUI(m_mousepos, buttonBounds);
+ if (isInside){
+ //glfwSetCursor(window, m_pointerCursor);
+ // hover effect
+ //glUniform1i(glGetUniformLocation(Global::graphics.getShaderID("ui"), "hovering"), true);
+ }
+ }
+ }
+ }
+ }
+}
+
+void UISystem::onWindowResize(int width, int height){
+ m_windowWidth = width;
+ m_windowHeight = height;
+ m_aspectRatio = static_cast<float>(m_windowHeight)/static_cast<float>(m_windowWidth);
+
+ for (auto &screen : m_all_screens){
+ // loop through ui elements
+ for (auto &gui: screen.second->screenElements){
+ if (gui.second->hasComponent<UIButton>()){
+ gui.second->getComponent<UIButton>()->setWindowPos(width, height);
+ }
+ if (gui.second->hasComponent<UIDisplay>()){
+ gui.second->getComponent<UIDisplay>()->setWindowPos(width, height);
+ }
+ }
+ }
+}
diff --git a/engine-ocean/Game/Systems/UI/uisystem.h b/engine-ocean/Game/Systems/UI/uisystem.h
new file mode 100644
index 0000000..1094861
--- /dev/null
+++ b/engine-ocean/Game/Systems/UI/uisystem.h
@@ -0,0 +1,89 @@
+#ifndef UISYSTEM_H
+#define UISYSTEM_H
+#include "Game/GameWorld.h"
+#include "Game/Systems/UI/UITextures/UIButton.h"
+#include "Game/Systems/UI/UITextures/uitexture.h"
+#include "Game/Systems/UI/uielement.h"
+#include "Graphics/global.h"
+#include <GLFW/glfw3.h>
+#include "Game/Systems/system.h"
+
+struct UIScreen{
+ bool isActive = false;
+ GLuint screenVAOID;
+ std::map<std::string, std::shared_ptr<UIElement>> screenElements;
+ std::vector<std::string> elementsDepthOrder;
+};
+
+
+class UISystem : public System
+{
+public:
+ UISystem(std::shared_ptr<Camera> camera,
+ std::map<int, Input>& input_map,
+ std::set<std::string>& shownScreens);
+ ~UISystem();
+
+ void draw() override;
+ void update(double deltaTime) override;
+ void scrollEvent(double distance) override;
+ void mousePosEvent(double xpos, double ypos) override;
+ void onWindowResize(int width, int height);
+ GLuint makeVAO(std::vector<float> positions);
+
+private:
+
+ int m_quad_numVertices = 4;
+
+ void initializeScreenMap();
+ void initializeScreen();
+ void initializeStartScreen();
+ void initializeInventory();
+
+
+ void renderScreen();
+ glm::mat4 makeTransformationMat(glm::vec2 translation, glm::vec2 scale);
+ glm::mat4 getScaleMatrix(glm::vec2 scale);
+ bool checkInsideGUI(glm::vec2 mouseClickPos, Bounds2f guiBounds);
+ void initializeProfileScreen();
+
+
+ void makeButtonElement(std::shared_ptr<UIScreen> &screen, std::string elementName, const char* filename, const glm::vec2 pos, const glm::vec2 scale, AspectRatio aspectRatio, bool isCloseButton = false, CornerPosition corner = NONE);
+ void makeDisplayElement(std::shared_ptr<UIScreen> &screen, std::string elementName, const char* filename, const glm::vec2 pos, const glm::vec2 scale, AspectRatio aspectRatio = FIT_SCREEN);
+ void makeDisplayElement(std::shared_ptr<UIScreen> &screen, std::string elementName, TextureData &tex, const glm::vec2 pos, const glm::vec2 scale, AspectRatio aspectRatio = FIT_SCREEN);
+
+
+
+ std::shared_ptr<Camera> m_camera;
+ float m_windowWidth = 640;
+ float m_windowHeight = 480;
+ float m_aspectRatio = 480.f/640.f;
+
+ glm::vec2 m_mousepos = glm::vec2(0.f);
+ std::map<int, Input>& m_input_map;
+
+ std::map<std::string, std::shared_ptr<UIScreen>> m_all_screens;
+
+ GLFWcursor* m_pointerCursor;
+
+ std::shared_ptr<ButtonAction> showProfileAction;
+
+ std::set<std::string>& m_shownScreens;
+ float m_showStartScreen = true;
+
+
+ float dim = 1.0f;
+ std::vector<float> m_quadPos = {
+ -1.0f, 1.0f,
+ -1.0f, -1.0f,
+ 1.0f, 1.0f,
+ 1.0f, -1.0f
+ };
+
+ glm::vec2 drawAspect(AspectRatio aspectType, float textureAspect);
+
+
+
+};
+
+#endif // UISYSTEM_H