diff --git a/CMakeLists.txt b/CMakeLists.txt index 86bde16..9ef4915 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,6 @@ project(vb01) set(CMAKE_BUILD_TYPE Debug) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -pedantic") -set(BUILD_SHARED_LIBS OFF) set(BUILD_TESTS OFF) set(BUILD_SAMPLES OFF) set(BUILD_WITH_ASSIMP OFF) @@ -38,7 +37,7 @@ include_directories(external/glm/glm) include_directories(external/glad) include_directories(external/stb) -add_library(${LIB_NAME} SHARED external/glad/glad.c ${LIB_SRC}) +add_library(${LIB_NAME} external/glad/glad.c ${LIB_SRC}) set(TINYXML2_DIR external/tinyxml2) set(GLFW_DIR external/glfw) diff --git a/abstractGuiManager.cpp b/abstractGuiManager.cpp index f30f2c8..5c37d69 100644 --- a/abstractGuiManager.cpp +++ b/abstractGuiManager.cpp @@ -94,22 +94,32 @@ namespace vb01Gui{ } } - void AbstractGuiManager::findClickedButton(){ - bool textboxClicked = false, listboxClicked = false; - + vector AbstractGuiManager::findClickedButtons(){ + vector clickedButtons; + Vector2 mousePos = getCursorPos(); + for (int i = 0; i < buttons.size(); i++) { - Vector2 mousePos = getCursorPos(); - Button *b = buttons[i]; - bool withinX = mousePos.x > b->getPos().x && mousePos.x < b->getPos().x + b->getSize().x; - bool withinY = mousePos.y > b->getPos().y && mousePos.y < b->getPos().y + b->getSize().y; + bool withinX = mousePos.x > buttons[i]->getPos().x && mousePos.x < buttons[i]->getPos().x + buttons[i]->getSize().x; + bool withinY = mousePos.y > buttons[i]->getPos().y && mousePos.y < buttons[i]->getPos().y + buttons[i]->getSize().y; - if (b->isActive() && withinX && withinY){ + if (withinX && withinY) + clickedButtons.push_back(buttons[i]); + } + + return clickedButtons; + } + + void AbstractGuiManager::updateGui(){ + bool textboxClicked = false, listboxClicked = false; + vector clickedButtons = findClickedButtons(); + + for (Button *b : clickedButtons) + if (b->isActive()){ b->onClick(); updateCurrentListbox(b, listboxClicked); updateCurrentSlider(b); updateCurrentTextbox(b, textboxClicked); } - } if(!textboxClicked && currentTextbox){ currentTextbox->disable(); @@ -238,6 +248,18 @@ namespace vb01Gui{ return text; } + Node* AbstractGuiManager::getGuiRectangle(string name){ + Node *guiRect = nullptr; + + for(Node *rect : guiRectangles) + if(rect->getName() == name){ + guiRect = rect; + break; + } + + return guiRect; + } + void AbstractGuiManager::removeAllButtons(vector exceptions){ int targetId = 0; diff --git a/abstractGuiManager.h b/abstractGuiManager.h index efcf824..90de87f 100644 --- a/abstractGuiManager.h +++ b/abstractGuiManager.h @@ -19,7 +19,8 @@ namespace vb01Gui{ class AbstractGuiManager{ public: void update(); - void findClickedButton(); + std::vector findClickedButtons(); + void updateGui(); void addButton(Button *b){buttons.push_back(b);} void removeButton(Button*); void removeButton(std::string); @@ -35,6 +36,7 @@ namespace vb01Gui{ void addText(vb01::Text *t){texts.push_back(t);} void removeText(vb01::Text*); vb01::Text* getText(std::string); + vb01::Node* getGuiRectangle(std::string); void removeSlider(Slider*); void removeAllButtons(std::vector = std::vector{}); void removeAllListboxes(std::vector = std::vector{}); @@ -54,7 +56,11 @@ namespace vb01Gui{ ); inline std::vector getButtons(){return buttons;} inline std::vector getListboxes(){return listboxes;} + inline std::vector getCheckboxes(){return checkboxes;} + inline std::vector getSliders(){return sliders;} inline std::vector getTextboxes(){return textboxes;} + inline std::vector getGuiRectangles(){return guiRectangles;} + inline std::vector getTexts(){return texts;} private: void updateCurrentListbox(Button*, bool&); void updateCurrentSlider(Button*); diff --git a/box.h b/box.h index c6b3bd0..96c7e1d 100755 --- a/box.h +++ b/box.h @@ -8,6 +8,7 @@ namespace vb01{ public: Box(Vector3); void setSize(Vector3); + inline Vector3 getSize(){return size;} private: Vector3 size; }; diff --git a/button.cpp b/button.cpp index 4de82b7..5f67102 100644 --- a/button.cpp +++ b/button.cpp @@ -15,18 +15,19 @@ using namespace std; using namespace vb01; namespace vb01Gui{ - Button::Button(Vector2 pos, Vector2 size, string name, string fontPath, int trigger, bool separate, string imagePath){ - this->pos = pos; - this->size = size; - this->name = name; - this->separate = separate; - this->imagePath = imagePath; - this->trigger = trigger; - + Button::Button(Vector3 p, Vector2 s, string n, string fontPath, int t, bool sep, string ip) : + pos(p), + size(s), + name(n), + trigger(t), + separate(sep), + imagePath(ip), + textOffset(Vector3(0, s.y, .1)) + { Root *root = Root::getSingleton(); guiNode = root->getGuiNode(); rect = new Quad(Vector3(size.x, size.y, 0), false); - rectNode = new Node(Vector3(pos.x, pos.y, 0)); + rectNode = new Node(pos); Material *mat = new Material(root->getLibPath() + "gui"); if(imagePath == ""){ @@ -47,9 +48,9 @@ namespace vb01Gui{ if(separate){ text = new Text(fontPath, stringToWstring(name)); - text->setScale(.2); - textNode = new Node(Vector3(pos.x, pos.y + size.y, - .1)); + float sc = .2; + textNode = new Node(pos + textOffset, Quaternion::QUAT_W, Vector3(sc, sc, 1)); textNode->addText(text); Material *textMat = new Material(root->getLibPath() + "text"); @@ -79,14 +80,14 @@ namespace vb01Gui{ GLFWwindow *window = Root::getSingleton()->getWindow(); glfwGetWindowSize(window, &width, &height); - float posRatio[] = {pos.x / initWindowSize[0], pos.y / initWindowSize[1]}; - float sizeRatio[] = {size.x / initWindowSize[0], size.y / initWindowSize[1]}; + float posRatio[] = {pos.x / initWindowSize[0], pos.y / initWindowSize[1]}; + float sizeRatio[] = {size.x / initWindowSize[0], size.y / initWindowSize[1]}; - pos = Vector2(width * posRatio[0], height * posRatio[1]); - size = Vector2(width * sizeRatio[0], height * sizeRatio[1]); + pos = Vector3(width * posRatio[0], height * posRatio[1], pos.z); + size = Vector2(width * sizeRatio[0], height * sizeRatio[1]); - initWindowSize[0] = width; - initWindowSize[1] = height; + initWindowSize[0] = width; + initWindowSize[1] = height; if(textNode) textNode->setVisible(active); @@ -102,15 +103,13 @@ namespace vb01Gui{ mouseOver = false; } - void Button::setPos(Vector2 pos){ + void Button::setPos(Vector3 pos){ this->pos = pos; - float z1 = rectNode->getPosition().z; - rectNode->setPosition(Vector3(pos.x, pos.y, z1)); - if(textNode){ - float z2 = textNode->getPosition().z; - textNode->setPosition(Vector3(pos.x, pos.y + size.y, z2)); - } + rectNode->setPosition(pos); + + if(textNode) + textNode->setPosition(pos + textOffset); } void Button::setSize(Vector2 size){ @@ -123,16 +122,6 @@ namespace vb01Gui{ ((Material::Vector4Uniform*)rect->getMaterial()->getUniform(diffColUni))->value = color; } - void Button::setZOrder(float zOrder){ - Vector3 rectPos = rectNode->getPosition(); - rectNode->setPosition(Vector3(rectPos.x, rectPos.y, zOrder)); - - if(textNode){ - Vector3 textPos = textNode->getPosition(); - textNode->setPosition(Vector3(textPos.x, textPos.y, zOrder - .1)); - } - } - void Button::setImage(string image){ int texId = -1; Material *mat = rect->getMaterial(); diff --git a/button.h b/button.h index 6a99bfd..dc340c9 100644 --- a/button.h +++ b/button.h @@ -18,14 +18,14 @@ namespace vb01{ namespace vb01Gui{ class Button{ public: - Button(vb01::Vector2, vb01::Vector2, std::string, std::string, int = -1, bool = true, std::string = ""); + Button(vb01::Vector3, vb01::Vector2, std::string, std::string, int = -1, bool = true, std::string = ""); virtual ~Button(); - void update(); + virtual void update(); virtual void onMouseOver(); virtual void onMouseOff(); virtual void onClick(){} - inline vb01::Vector2 getPos(){return pos;} - void setPos(vb01::Vector2); + inline vb01::Vector3 getPos(){return pos;} + void setPos(vb01::Vector3); inline vb01::Vector2 getSize(){return size;} void setSize(vb01::Vector2); inline std::string getName(){return name;} @@ -35,14 +35,14 @@ namespace vb01Gui{ inline vb01::Vector4 getColor(){return color;} inline int getTrigger(){return trigger;} void setColor(vb01::Vector4); - void setZOrder(float); void setImage(std::string); protected: int trigger, initWindowSize[2]; bool separate, active = true, mouseOver = false; vb01::Quad *rect; vb01::Node *rectNode, *textNode = nullptr, *guiNode; - vb01::Vector2 pos, size; + vb01::Vector3 pos, textOffset; + vb01::Vector2 size; vb01::Text *text = nullptr; std::string name, imagePath, texUni = "texturingEnabled", diffColUni = "diffuseColor"; std::vector textures; diff --git a/checkbox.cpp b/checkbox.cpp index 95dfdc9..79b0ec5 100644 --- a/checkbox.cpp +++ b/checkbox.cpp @@ -7,18 +7,15 @@ using namespace vb01; using namespace std; namespace vb01Gui{ - Checkbox::CheckboxButton::CheckboxButton(Checkbox *ch, Vector2 pos, Vector2 size, string name, bool separate) : Button(pos, size, name, "", -1, separate) { - checkbox = ch; - } + Checkbox::CheckboxButton::CheckboxButton(Checkbox *ch, Vector3 pos, Vector2 size, string name, bool separate) : Button(pos, size, name, "", -1, separate), checkbox(ch) {} void Checkbox::CheckboxButton::onClick() { checkbox->check(); - float col = (checkbox->isChecked() ? .6 : .2); - setColor(Vector4(col, col, col, 1)); + float col = (checkbox->isChecked() ? .6 : .2); + setColor(Vector4(col, col, col, 1)); } - Checkbox::Checkbox(Vector2 pos, string fontPath){ - this->pos = pos; + Checkbox::Checkbox(Vector3 p, string fontPath) : pos(p){ checkboxButton = new CheckboxButton(this, pos, Vector2(length,length), "CheckboxButton", false); /* diff --git a/checkbox.h b/checkbox.h index e1d8bd6..f0f7125 100644 --- a/checkbox.h +++ b/checkbox.h @@ -12,7 +12,7 @@ namespace vb01{ namespace vb01Gui{ class Checkbox { public: - Checkbox(vb01::Vector2, std::string); + Checkbox(vb01::Vector3, std::string); ~Checkbox(); void update(){} virtual void check(); @@ -20,7 +20,7 @@ namespace vb01Gui{ private: class CheckboxButton : public Button { public: - CheckboxButton(Checkbox*, vb01::Vector2, vb01::Vector2, std::string, bool); + CheckboxButton(Checkbox*, vb01::Vector3, vb01::Vector2, std::string, bool); void onClick(); private: Checkbox *checkbox = nullptr; @@ -28,9 +28,9 @@ namespace vb01Gui{ const int length = 15; bool checked = false; - vb01::Vector2 pos; + vb01::Vector3 pos; CheckboxButton *checkboxButton; - vb01::Node *checkNode = nullptr; + vb01::Node *checkNode = nullptr; public: inline CheckboxButton* getCheckboxButton(){return checkboxButton;} }; diff --git a/gui.vert b/gui.vert index 17b5eff..836761c 100755 --- a/gui.vert +++ b/gui.vert @@ -12,6 +12,6 @@ void main(){ float x, y; x = (aVert.x + pos.x - screen.x * .5) / (screen.x * .5); y = (screen.y * .5 - (aVert.y + pos.y)) / (screen.y * .5); - gl_Position = vec4(x, y, pos.z + aVert.z, 1); + gl_Position = vec4(x, y, -(pos.z + aVert.z), 1); texCoords = aTexCoords; } diff --git a/imageReader.h b/imageReader.h index a52a67c..0cabda7 100644 --- a/imageReader.h +++ b/imageReader.h @@ -15,7 +15,7 @@ namespace vb01{ private: ImageReader(){} - bool flip = false; + bool flip = true; }; } diff --git a/listbox.cpp b/listbox.cpp index d37c347..29caa16 100644 --- a/listbox.cpp +++ b/listbox.cpp @@ -12,7 +12,7 @@ using namespace vb01; using namespace std; namespace vb01Gui{ - Listbox::ListboxButton::ListboxButton(Listbox *l, Vector2 pos, Vector2 size, string name) : Button(pos, size, name, "", -1, false){listbox = l;} + Listbox::ListboxButton::ListboxButton(Listbox *l, Vector3 pos, Vector2 size, string name) : Button(pos, size, name, "", -1, false), listbox(l) {} void Listbox::ListboxButton::onClick(){ if(!listbox->isOpen()) @@ -29,47 +29,38 @@ namespace vb01Gui{ } } - Listbox::ScrollingButton::ScrollingButton(Vector2 pos, Vector2 size, string name) : Button(pos, size, name, "", -1, false){} + Listbox::ScrollingButton::ScrollingButton(Vector3 pos, Vector2 size, string name) : Button(pos, size, name, "", -1, false){} void Listbox::ScrollingButton::onClick(){} - Listbox::Listbox(Vector2 pos, Vector2 size, std::vector &lines, int maxDisplay, string fontPath, bool closeable){ - this->pos = pos; - this->size = size; - this->maxDisplay = maxDisplay; - this->fontPath = fontPath; - this->lineHeight = size.y; - this->closeable = closeable; - + Listbox::Listbox(Vector3 p, Vector2 s, std::vector &lines, int md, string fp, bool cl) : + pos(p), + size(s), + maxDisplay(md), + fontPath(fp), + closeable(cl), + textOffset(Vector3(0, 0, .3)) + { Root *root = Root::getSingleton(); Vector2 mousePos = getCursorPos(); guiNode = Root::getSingleton()->getGuiNode(); + string texUni = "texturingEnabled", diffColUni = "diffuseColor"; + textMat = new Material(root->getLibPath() + "text"); + textMat->addBoolUniform(texUni, false); + textMat->addVec4Uniform(diffColUni, Vector4::VEC_IJKL); - for(int i = 0; i < lines.size(); i++){ - Text *text = new Text(fontPath, stringToWstring(lines[i])); - text->setScale(.2); + if(!lines.empty()){ + for(int i = 0; i < lines.size(); i++) + addLine(stringToWstring(lines[i])); - Material *textMat = new Material(root->getLibPath() + "text"); - textMat->addBoolUniform(texUni, false); - textMat->addVec4Uniform(diffColUni, Vector4::VEC_IJKL); - text->setMaterial(textMat); - - Node *node = new Node(Vector3(pos.x, pos.y + size.y * (i + 1), textZCoord)); - node->addText(text); - guiNode->attachChild(node); - node->setVisible(false); - - this->lines.push_back(text); + this->lines[0]->getNode()->setVisible(true); } - this->lines[0]->getNode()->setVisible(true); - listboxButton = new ListboxButton(this, pos, size, "ListboxButton"); - scrollingButton = new ScrollingButton(Vector2(pos.x + size.x - 20, pos.y + lineHeight), Vector2(20, lineHeight * (maxDisplay - 2) / (maxDisplay + 1)), "scrollingButton"); + scrollingButton = new ScrollingButton(Vector3(pos.x + size.x - 20, pos.y + lineHeight, pos.z - .05), Vector2(20, lineHeight * (maxDisplay - 2) / (maxDisplay + 1)), "scrollingButton"); scrollingButton->setColor(Vector4(.2, .2, .2, 1)); - scrollingButton->setZOrder(-.05); scrollingButton->setActive(false); Quad *selRect = new Quad(Vector3(size.x, size.y, 0), false); @@ -99,13 +90,14 @@ namespace vb01Gui{ delete selRectNode; } + //TODO selection rectangle Z offset void Listbox::update(){ scrollingButton->update(); listboxButton->update(); if(open){ Vector2 mousePos = getCursorPos(); - Vector2 p = pos; + Vector3 p = pos; if(mousePos.y > pos.y && mousePos.y < pos.y + size.y * maxDisplay){ selectedOption = scrollOffset + ((int)(mousePos.y - pos.y) / ((int)size.y)); @@ -120,9 +112,9 @@ namespace vb01Gui{ p.y = pos.y + size.y * (maxDisplay - 1); } - selRectNode->setPosition(Vector3(p.x, p.y, -.05)); + selRectNode->setPosition(Vector3(p.x, p.y, p.z + .05)); - Vector2 scrollButtonPos = Vector2(pos.x + size.x - 20, pos.y + lineHeight + lineHeight * scrollOffset * (double(maxDisplay - 2) / (maxDisplay + 1))); + Vector3 scrollButtonPos = Vector3(pos.x + size.x - 20, pos.y + lineHeight + lineHeight * scrollOffset * (double(maxDisplay - 2) / (maxDisplay + 1)), pos.z - .05); scrollingButton->setPos(scrollButtonPos); } } @@ -141,8 +133,11 @@ namespace vb01Gui{ } void Listbox::openUp(){ + if(lines.empty()) return; + open = true; - lines[selectedOption]->getNode()->setPosition(Vector3(pos.x, pos.y + size.y * (selectedOption-scrollOffset + 1), textZCoord)); + Vector3 selOpPos = pos + Vector3(0, size.y * (selectedOption - scrollOffset + 1), 0) + textOffset; + lines[selectedOption]->getNode()->setPosition(selOpPos); lines[selectedOption]->getNode()->setVisible(false); Vector2 size = listboxButton->getSize(); size.y *= maxDisplay; @@ -167,7 +162,7 @@ namespace vb01Gui{ for(int i = scrollOffset; i < scrollOffset + maxDisplay; i++) lines[i]->getNode()->setVisible(false); - lines[selectedOption]->getNode()->setPosition(Vector3(pos.x, pos.y + size.y, textZCoord)); + lines[selectedOption]->getNode()->setPosition(pos + Vector3(0, size.y, 0) + textOffset); lines[selectedOption]->getNode()->setVisible(true); onClose(); @@ -221,11 +216,16 @@ namespace vb01Gui{ } void Listbox::addLine(wstring line){ - Text *t = new Text(fontPath, line); - Node *node = new Node(Vector3(pos.x, pos.y - size.y * lines.size(), textZCoord)); - node->addText(t); - guiNode->attachChild(node); - lines.push_back(t); + float sc = .2; + Node *node = new Node(pos + Vector3(0, size.y * (lines.size() + 1), 0) + textOffset, Quaternion::QUAT_W, Vector3(sc, sc, 1)); + Root::getSingleton()->getGuiNode()->attachChild(node); + node->setVisible(false); + + Text *text = new Text(fontPath, line); + text->setMaterial(textMat); + node->addText(text); + + lines.push_back(text); } string Listbox::convert(string str){ diff --git a/listbox.h b/listbox.h index 49c361c..33fb7aa 100644 --- a/listbox.h +++ b/listbox.h @@ -8,6 +8,7 @@ namespace vb01{ class Node; + class Material; class Text; } @@ -16,13 +17,13 @@ namespace vb01Gui{ public: class ListboxButton : public Button{ public: - ListboxButton(Listbox*, vb01::Vector2, vb01::Vector2, std::string); + ListboxButton(Listbox*, vb01::Vector3, vb01::Vector2, std::string); void onClick(); private: Listbox *listbox = nullptr; }; - Listbox(vb01::Vector2, vb01::Vector2, std::vector&, int, std::string, bool = true); + Listbox(vb01::Vector3, vb01::Vector2, std::vector&, int, std::string, bool = true); ~Listbox(); void update(); void openUp(); @@ -40,30 +41,33 @@ namespace vb01Gui{ inline bool isCloseable(){return closeable;} void appendLines(std::vector&); inline int getSelectedOption(){return selectedOption;} + inline void setMaxDisplay(int md){this->maxDisplay = md;} inline int getMaxDisplay(){return maxDisplay;} inline int getNumLines(){return lines.size();} std::vector getContents(); - inline vb01::Vector2 getPos(){return pos;} + inline vb01::Vector3 getPos(){return pos;} inline vb01::Vector2 getSize(){return size;} private: class ScrollingButton : public Button{ public: - ScrollingButton(vb01::Vector2, vb01::Vector2, std::string); + ScrollingButton(vb01::Vector3, vb01::Vector2, std::string); void onClick(); private: }; std::string convert(std::string); - float textZCoord = -.3, lineHeight; + float lineHeight; int maxDisplay, scrollOffset = 0; bool open = false, closeable = false; std::string fontPath; - vb01::Vector2 pos, size; + vb01::Vector3 pos, textOffset; + vb01::Vector2 size; ListboxButton *listboxButton; ScrollingButton *scrollingButton; vb01::Node *selRectNode, *guiNode; std::vector lines; + vb01::Material *textMat = nullptr; protected: int selectedOption = 0; public: diff --git a/material.h b/material.h index 4524849..d9cf752 100755 --- a/material.h +++ b/material.h @@ -160,9 +160,12 @@ namespace vb01{ inline void addVec4Uniform(std::string name, Vector4 value){uniforms.push_back(new Vector4Uniform(name, value));} inline void addTexUniform(std::string name, Texture *value, bool animatable){uniforms.push_back(new TextureUniform(name, value, animatable));} inline Shader* getShader(){return shader;} + inline bool isTransparent(){return transparent;} + inline void setTransparent(bool t){this->transparent = t;} private: std::vector uniforms; Shader *shader = nullptr; + bool transparent = false; }; } diff --git a/mesh.cpp b/mesh.cpp index 46ff1d6..c8c8a25 100755 --- a/mesh.cpp +++ b/mesh.cpp @@ -38,43 +38,8 @@ namespace vb01{ glDeleteBuffers(1, &VBO); } - void Mesh::construct(){ - string libPath = Root::getSingleton()->getLibPath(); - environmentShader = new Shader(libPath + "environmentPreFilter"); - irradianceShader = new Shader(libPath + "irradiance"); - brdfIntegrationShader = new Shader(libPath + "brdfIntegration"); - - prefilterMap = new Texture(preFilterMapSize, false); - irradianceMap = new Texture(irradianceMapSize, false); - postfilterMap = new Texture(environmentMapSize, false, 5); - brdfIntegrationMap = new Texture(brdfMapSize, brdfMapSize, false); - - initFramebuffer(preFilterFramebuffer, preFilterRenderbuffer, preFilterMapSize); - initFramebuffer(irrandianceFramebuffer, irradianceRenderbuffer, irradianceMapSize); - initFramebuffer(postFilterFramebuffer, postFilterRenderbuffer, environmentMapSize); - initFramebuffer(brdfFramebuffer, brdfRenderbuffer, brdfMapSize); - - initMesh(); - } - - void Mesh::initFramebuffer(u32 &framebuffer, u32 &renderbuffer, int width){ - glGenFramebuffers(1, &framebuffer); - glGenRenderbuffers(1, &renderbuffer); - - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); - glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); - - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, width); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer); - - if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - cout << "Mesh framebuffer not complete\n"; - - glBindFramebuffer(GL_FRAMEBUFFER, *Root::getSingleton()->getFBO()); - } - //TODO allow to init meshes to be drawn statically or dynamically - void Mesh::initMesh(){ + void Mesh::construct(){ glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); @@ -108,6 +73,22 @@ namespace vb01{ } } + void Mesh::initFramebuffer(u32 &framebuffer, u32 &renderbuffer, int width){ + glGenFramebuffers(1, &framebuffer); + glGenRenderbuffers(1, &renderbuffer); + + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, width); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer); + + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + cout << "Mesh framebuffer not complete\n"; + + glBindFramebuffer(GL_FRAMEBUFFER, *Root::getSingleton()->getFBO()); + } + void Mesh::updateVerts(MeshData meshData){ glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferSubData(GL_ARRAY_BUFFER, 0, 3 * sizeof(MeshData::Vertex) * meshBase.numTris, meshData.vertices); @@ -417,4 +398,25 @@ namespace vb01{ glPolygonMode(GL_FRONT_AND_BACK, wireframe ? GL_LINE : GL_FILL); glDrawElements(GL_TRIANGLES, 3 * meshBase.numTris, GL_UNSIGNED_INT, 0); } + + void Mesh::setReflect(bool reflect){ + this->reflect = reflect; + + if(reflect && !environmentShader){ + string libPath = Root::getSingleton()->getLibPath(); + environmentShader = new Shader(libPath + "environmentPreFilter"); + irradianceShader = new Shader(libPath + "irradiance"); + brdfIntegrationShader = new Shader(libPath + "brdfIntegration"); + + prefilterMap = new Texture(preFilterMapSize, false); + irradianceMap = new Texture(irradianceMapSize, false); + postfilterMap = new Texture(environmentMapSize, false, 5); + brdfIntegrationMap = new Texture(brdfMapSize, brdfMapSize, false); + + initFramebuffer(preFilterFramebuffer, preFilterRenderbuffer, preFilterMapSize); + initFramebuffer(irrandianceFramebuffer, irradianceRenderbuffer, irradianceMapSize); + initFramebuffer(postFilterFramebuffer, postFilterRenderbuffer, environmentMapSize); + initFramebuffer(brdfFramebuffer, brdfRenderbuffer, brdfMapSize); + } + } } diff --git a/mesh.h b/mesh.h index c73d7cd..6d69172 100755 --- a/mesh.h +++ b/mesh.h @@ -24,9 +24,9 @@ namespace vb01{ void updateVerts(MeshData); virtual void update(); void render(); + void setReflect(bool); inline void setMaterial(Material *mat){this->material = mat;} inline void setCastShadow(bool castShadow){this->castShadow = castShadow;} - inline void setReflect(bool r){this->reflect = r;} inline void setReflective(bool r){this->reflective = r;} inline void setWireframe(bool w){this->wireframe = w;} inline void setSkeleton(Skeleton *sk){this->skeleton = sk;} @@ -41,7 +41,6 @@ namespace vb01{ inline Texture* getBrdfIntegrationMap(){return brdfIntegrationMap;} inline MeshData getMeshBase(){return meshBase;} private: - void initMesh(); void initFramebuffer(u32&, u32&, int); void updateSkeleton(Shader*); void updatePrefilterMap(Vector3, glm::mat4&, glm::vec3[6]); diff --git a/node.cpp b/node.cpp index 7472f30..d57cd3e 100755 --- a/node.cpp +++ b/node.cpp @@ -43,7 +43,17 @@ namespace vb01{ } void Node::update(){ - if(visible){ + bool render = true; + Node *ancestor = this; + + while(ancestor){ + render = ancestor->isVisible(); + ancestor = ancestor->getParent(); + + if(!render) break; + } + + if(render){ for(Light *l : lights) l->update(); @@ -412,6 +422,21 @@ namespace vb01{ return origin; } + Node* Node::findDescendant(string name, bool allDescendants){ + vector descendants = children; + + if(allDescendants){ + descendants.clear(); + getDescendants(descendants); + } + + for(Node *desc : descendants) + if(desc->getName() == name) + return desc; + + return nullptr; + } + void Node::updateShaders(){ Root *root = Root::getSingleton(); diff --git a/node.h b/node.h index 1758e91..bce352c 100755 --- a/node.h +++ b/node.h @@ -45,9 +45,12 @@ namespace vb01{ Quaternion globalToLocalOrientation(Quaternion); Vector3 localToGlobalScale(Vector3); Vector3 globalToLocalScale(Vector3); + Node* findDescendant(std::string, bool=false); + inline void dettachMesh(int id){meshes.erase(meshes.begin() + id);} inline Skeleton* getSkeleton(int i){return skeletons[i];} inline int getNumSkeletons(){return skeletons.size();} inline Text* getText(int i){return texts[i];} + inline std::vector& getTexts(){return texts;} inline std::vector& getMeshes(){return meshes;} inline std::vector& getSkeletons(){return skeletons;} inline Mesh* getMesh(int i){return meshes[i];} diff --git a/rayCaster.cpp b/rayCaster.cpp index 342dc1e..43e09df 100644 --- a/rayCaster.cpp +++ b/rayCaster.cpp @@ -1,5 +1,3 @@ -#include - #include "rayCaster.h" #include "mesh.h" #include "node.h" @@ -7,11 +5,11 @@ using namespace std; namespace vb01{ - vector RayCaster::cast(Vector3 rayPos, Vector3 rayDir, Node *node, const float rayLength){ - return cast(rayPos, rayDir, vector{node}, rayLength); + vector RayCaster::cast(Vector3 rayPos, Vector3 rayDir, Node *node, const float rayLength, const float distToRay){ + return cast(rayPos, rayDir, vector{node}, rayLength, distToRay); } - vector RayCaster::cast(Vector3 rayPos, Vector3 rayDir, vector nodes, const float rayLength){ + vector RayCaster::cast(Vector3 rayPos, Vector3 rayDir, vector nodes, const float rayLength, const float distToRay){ vector results; for(Node *node : nodes){ @@ -19,7 +17,7 @@ namespace vb01{ node->getDescendants(descendants); for(Node *desc : descendants){ - vector res = retrieveCollisions(rayPos, rayDir, desc, rayLength); + vector res = retrieveCollisions(rayPos, rayDir, desc, rayLength, distToRay); results.insert(results.end(), res.begin(), res.end()); } } @@ -29,7 +27,7 @@ namespace vb01{ return results; } - vector RayCaster::retrieveCollisions(Vector3 rayPos, Vector3 rayDir, Node *node, float rayLength){ + vector RayCaster::retrieveCollisions(Vector3 rayPos, Vector3 rayDir, Node *node, float rayLength, const float distToRay){ Vector3 pos = node->localToGlobalPosition(Vector3::VEC_ZERO); Quaternion rot = node->localToGlobalOrientation(Quaternion::QUAT_W); vector results; @@ -40,6 +38,26 @@ namespace vb01{ u32 *indices = m->getMeshBase().indices; for(int i = 0; i < numVerts / 3; i++){ + if(distToRay > 0.0){ + bool skip = false; + + for(int j = 0; j < 3; j++){ + Vector3 rayPosToVert = (vertices[i * 3 + j].pos - rayPos); + float angle = rayDir.getAngleBetween(rayPosToVert.norm()); + + if(angle > PI / 2) angle = PI - angle; + + float dist = sin(angle) * rayPosToVert.getLength(); + + if(dist > distToRay){ + skip = true; + break; + } + } + + if(skip) continue; + } + Vector3 pointA = pos + rot * vertices[indices[i * 3]].pos, pointB = pos + rot * vertices[indices[i * 3 + 1]].pos, pointC = pos + rot * vertices[indices[i * 3 + 2]].pos; Vector3 hypVec = pointA - rayPos; Vector3 perpVec = (pointB - pointA).cross(pointC - pointA).norm(); @@ -64,9 +82,10 @@ namespace vb01{ Vector3 bisecAVec = ((pointB - pointA) + (pointC - pointA)); Vector3 bisecBVec = ((pointA - pointB) + (pointC - pointB)); Vector3 bisecCVec = ((pointB - pointC) + (pointA - pointC)); - bool withinBisecA = (contactPoint - pointA).norm().getAngleBetween(bisecAVec.norm()) <= angleA / 2; - bool withinBisecB = (contactPoint - pointB).norm().getAngleBetween(bisecBVec.norm()) <= angleB / 2; - bool withinBisecC = (contactPoint - pointC).norm().getAngleBetween(bisecCVec.norm()) <= angleC / 2; + float eps = .1; + bool withinBisecA = ((contactPoint - pointA).norm().getAngleBetween(bisecAVec.norm()) - angleA / 2) <= eps; + bool withinBisecB = ((contactPoint - pointB).norm().getAngleBetween(bisecBVec.norm()) - angleB / 2) <= eps; + bool withinBisecC = ((contactPoint - pointC).norm().getAngleBetween(bisecCVec.norm()) - angleC / 2) <= eps; if(withinBisecA && withinBisecB && withinBisecC){ CollisionResult result; diff --git a/rayCaster.h b/rayCaster.h index 2e8deb8..1d47027 100644 --- a/rayCaster.h +++ b/rayCaster.h @@ -15,10 +15,10 @@ namespace vb01{ Mesh *mesh = nullptr; }; - static std::vector cast(Vector3, Vector3, Node*, const float = .0); - static std::vector cast(Vector3, Vector3, std::vector, const float = .0); + static std::vector cast(Vector3, Vector3, Node*, const float = .0, const float = .0); + static std::vector cast(Vector3, Vector3, std::vector, const float = .0, const float = .0); private: - static std::vector retrieveCollisions(Vector3, Vector3, Node*, const float); + static std::vector retrieveCollisions(Vector3, Vector3, Node*, const float, const float); static void sortResults(std::vector&); }; diff --git a/root.cpp b/root.cpp index 581b8cc..01bb698 100755 --- a/root.cpp +++ b/root.cpp @@ -153,7 +153,7 @@ namespace vb01{ AnimationController::getSingleton()->update(); - updateNodeTree(rootNode); + updateNodeTree(rootNode, false); LineRenderer::getSingleton()->drawLines(); @@ -167,33 +167,28 @@ namespace vb01{ updateGuiPlane(); glEnable(GL_DEPTH_TEST); - updateNodeTree(guiNode); + updateNodeTree(guiNode, true); glfwSwapBuffers(window); glfwPollEvents(); } //TODO replace sorting algorithm - void Root::updateNodeTree(Node *node){ + //TODO specify differentiation of nodes with translucent meshes AND texts + void Root::updateNodeTree(Node *node, bool gui){ vector descendants, opaqueNodes, transparentNodes; node->getDescendants(descendants); for(Node *desc : descendants){ - if(!desc->getMeshes().empty()) - for(Mesh *mesh : desc->getMeshes()){ - Material *mat = mesh->getMaterial(); - vector uniforms = mat->getUniformsByType(Material::Uniform::TEXTURE); - - if(!uniforms.empty()) - for(Material::Uniform *uni : uniforms){ - bool transparent = ((Material::TextureUniform*)uni)->value->isTransparent(); - (transparent ? transparentNodes : opaqueNodes).push_back(desc); - } - else - opaqueNodes.push_back(desc); - } - else - opaqueNodes.push_back(desc); + if(!desc->getMeshes().empty()) + for(Mesh *mesh : desc->getMeshes()){ + (mesh->getMaterial()->isTransparent() ? transparentNodes : opaqueNodes).push_back(desc); + break; + } + else if(!desc->getTexts().empty()) + transparentNodes.push_back(desc); + else + opaqueNodes.push_back(desc); } for(Node *node : opaqueNodes) @@ -202,22 +197,30 @@ namespace vb01{ int numNodes = transparentNodes.size(); for(int i = 0; i < numNodes; i++){ + float d1 = transparentNodes[i]->getPosition().z; + + if(!gui){ Vector3 v1 = transparentNodes[i]->getPosition() - camera->getPosition(); float a1 = v1.norm().getAngleBetween(camera->getDirection()); - float d1 = v1.getLength() * cos(a1); + d1 = v1.getLength() * cos(a1); + } - for(int j = i; j < numNodes; j++){ - Vector3 v2 = transparentNodes[j]->getPosition() - camera->getPosition(); - float a2 = v2.norm().getAngleBetween(camera->getDirection()); - float d2 = v2.getLength() * cos(a2); + for(int j = i; j < numNodes; j++){ + float d2 = transparentNodes[j]->getPosition().z; - if(d1 < d2) - swap(transparentNodes[i], transparentNodes[j]); + if(!gui){ + Vector3 v2 = transparentNodes[j]->getPosition() - camera->getPosition(); + float a2 = v2.norm().getAngleBetween(camera->getDirection()); + d2 = v2.getLength() * cos(a2); } + + if(d1 > d2) + swap(transparentNodes[i], transparentNodes[j]); + } } for(Node *node : transparentNodes) - node->update(); + node->update(); } void Root::updateBloomFramebuffer(){ diff --git a/root.h b/root.h index 2c87162..3c87e7e 100755 --- a/root.h +++ b/root.h @@ -70,7 +70,7 @@ namespace vb01{ void initGuiPlane(Texture*, Texture*); void updateBloomFramebuffer(); void updateGuiPlane(); - void updateNodeTree(vb01::Node*); + void updateNodeTree(vb01::Node*, bool); }; } diff --git a/slider.cpp b/slider.cpp index 077e34e..4976359 100644 --- a/slider.cpp +++ b/slider.cpp @@ -12,9 +12,7 @@ using namespace std; using namespace vb01; namespace vb01Gui{ - Slider::MovableSliderButton::MovableSliderButton(Slider *slider, Vector2 pos, Vector2 size, string name, bool separate) : Button(pos, size, name, "", -1, separate) { - this->slider = slider; - } + Slider::MovableSliderButton::MovableSliderButton(Slider *sl, Vector3 pos, Vector2 size, string name, bool separate) : Button(pos, size, name, "", -1, separate), slider(sl) {} void Slider::MovableSliderButton::onClick() { clicked = !clicked; @@ -33,9 +31,7 @@ namespace vb01Gui{ } } - Slider::StaticSliderButton::StaticSliderButton(Slider *slider, Vector2 pos, Vector2 size, string name, bool separate) : Button(pos, size, name, "", -1, separate) { - this->slider = slider; - } + Slider::StaticSliderButton::StaticSliderButton(Slider *sl, Vector3 pos, Vector2 size, string name, bool separate) : Button(pos, size, name, "", -1, separate), slider(sl) {} void Slider::StaticSliderButton::onClick() { Vector2 cursorPos = getCursorPos(); @@ -43,20 +39,14 @@ namespace vb01Gui{ slider->setValue(((double) buttonClickPoint / slider->getSize().x) * slider->getMaxValue()); } - Slider::Slider(Vector2 pos, Vector2 size, double minValue, double maxValue) { - this->pos = pos; - this->size = size; - this->minValue = minValue; - this->maxValue = maxValue; - + Slider::Slider(Vector3 p, Vector2 s, double min, double max) : pos(p), size(s), minValue(min), maxValue(max) { staticSliderButton = new StaticSliderButton(this, pos, size, "StaticSliderButton", false); - movableSliderButton = new MovableSliderButton(this, Vector2(pos.x + staticSliderButton->getSize().x / 1, pos.y - 15), Vector2(10, 40), "MovableSliderButton", false); + movableSliderButton = new MovableSliderButton(this, pos + Vector3(staticSliderButton->getSize().x, -15, 0), Vector2(10, 40), "MovableSliderButton", false); value = (maxValue - minValue) / 2; } - Slider::~Slider() { - } + Slider::~Slider() {} void Slider::update() { if (value < minValue) @@ -64,15 +54,16 @@ namespace vb01Gui{ else if (value > maxValue) value = maxValue; - Vector2 p = movableSliderButton->getPos(), s = movableSliderButton->getSize(); + Vector3 p = movableSliderButton->getPos(); + Vector2 s = movableSliderButton->getSize(); p.x = pos.x + (double) size.x / maxValue * value; movableSliderButton->update(); movableSliderButton->setPos(p); - if(textbox && !textbox->isEnabled()){ - ostringstream ss; - ss << value; - textbox->setEntry(stringToWstring(ss.str())); - } + if(textbox && !textbox->isEnabled()){ + ostringstream ss; + ss << value; + textbox->setEntry(stringToWstring(ss.str())); + } } } diff --git a/slider.h b/slider.h index ce629b5..6280fc4 100644 --- a/slider.h +++ b/slider.h @@ -8,7 +8,7 @@ namespace vb01Gui{ class Slider { public: - Slider(vb01::Vector2, vb01::Vector2, double, double); + Slider(vb01::Vector3, vb01::Vector2, double, double); ~Slider(); void update(); inline void setTextbox(Textbox *t){this->textbox=t;} @@ -16,13 +16,13 @@ namespace vb01Gui{ inline double getValue(){return value;} inline double getMaxValue(){return maxValue;} inline void setValue(double v){this->value=v;} - inline vb01::Vector2 getPos(){return pos;} + inline vb01::Vector3 getPos(){return pos;} inline vb01::Vector2 getSize(){return size;} inline Textbox* getTextbox(){return textbox;} private: class MovableSliderButton : public Button { public: - MovableSliderButton(Slider*, vb01::Vector2, vb01::Vector2, std::string, bool); + MovableSliderButton(Slider*, vb01::Vector3, vb01::Vector2, std::string, bool); void onClick(); void update(); private: @@ -32,7 +32,7 @@ namespace vb01Gui{ class StaticSliderButton : public Button { public: - StaticSliderButton(Slider*, vb01::Vector2, vb01::Vector2, std::string, bool); + StaticSliderButton(Slider*, vb01::Vector3, vb01::Vector2, std::string, bool); void onClick(); private: Slider *slider; @@ -41,7 +41,8 @@ namespace vb01Gui{ MovableSliderButton *movableSliderButton = nullptr; StaticSliderButton *staticSliderButton = nullptr; double minValue, value, maxValue; - vb01::Vector2 pos, size; + vb01::Vector3 pos; + vb01::Vector2 size; Textbox *textbox = nullptr; public: inline MovableSliderButton* getMovableSliderButton(){return movableSliderButton;} diff --git a/text.cpp b/text.cpp index eab2c7f..b04db8d 100755 --- a/text.cpp +++ b/text.cpp @@ -80,17 +80,19 @@ namespace vb01{ Vector2 size = glyph.size, bearing = glyph.bearing; if(horizontal) - advanceOffset.x += (size.x + bearing.x); + advanceOffset.x += node->getScale().x * (size.x + bearing.x); else - advanceOffset.y += size.y; + advanceOffset.y += node->getScale().y * size.y; } } void Text::prepareGlyphs(Glyph glyph, Vector2 advanceOffset){ Vector3 nodePos = node->getPosition(); Vector2 origin = Vector2(nodePos.x, nodePos.y) + (advanceOffset * scale); + Vector3 scale = node->getScale(); - Vector2 size = glyph.size * scale, bearing = glyph.bearing * scale; + Vector2 size = Vector2(glyph.size.x * scale.x, glyph.size.y * scale.y); + Vector2 bearing = Vector2(glyph.bearing.x * scale.x, glyph.bearing.y * scale.y); float data[] = { origin.x + bearing.x, origin.y - bearing.y, 0, 0, diff --git a/text.vert b/text.vert index cf029b7..5f15a79 100755 --- a/text.vert +++ b/text.vert @@ -11,6 +11,6 @@ void main(){ float x, y; x = (aVert.x - screen.x * .5) / (screen.x * .5); y = (screen.y * .5 - (aVert.y)) / (screen.y * .5); - gl_Position = vec4(x, y, pos.z, 1); + gl_Position = vec4(x, y, -pos.z, 1); texCoords = aVert.zw; } diff --git a/textbox.cpp b/textbox.cpp index b3da348..53feae7 100644 --- a/textbox.cpp +++ b/textbox.cpp @@ -14,7 +14,7 @@ using namespace vb01; using namespace std; namespace vb01Gui{ - Textbox::TextboxButton::TextboxButton(Textbox *t, Vector2 pos, Vector2 size, string name) : Button(pos, size, name, "", -1, false) {textbox = t;} + Textbox::TextboxButton::TextboxButton(Textbox *t, Vector3 pos, Vector2 size, string name) : Button(pos, size, name, "", -1, false), textbox(t) {} void Textbox::TextboxButton::onClick(){ if(!textbox->isEnabled()) @@ -23,28 +23,25 @@ namespace vb01Gui{ textbox->disable(); } - Textbox::Textbox(Vector2 pos, Vector2 size, string fontPath, wstring entry){ - this->pos = pos; - this->size = size; - this->fontPath = fontPath; - + Textbox::Textbox(Vector3 p, Vector2 s, string fp, wstring entry) : pos(p), size(s), fontPath(fp), cursorZCoord(.01){ textboxButton = new TextboxButton(this, pos, size, "TextboxButton"); string libPath = Root::getSingleton()->getLibPath(); guiNode = Root::getSingleton()->getGuiNode(); text = new Text(fontPath, entry); - text->setScale(.5); Material *textMat = new Material(libPath + "text"); textMat->addBoolUniform("texturingEnabled", false); textMat->addVec4Uniform("diffuseColor", Vector4(1, 1, 1, 1)); text->setMaterial(textMat); - textNode = new Node(Vector3(pos.x, pos.y + size.y, -.1)); + + float sc = .5; + textNode = new Node(Vector3(pos.x, pos.y + size.y, pos.z + cursorZCoord), Quaternion::QUAT_W, Vector3(sc, sc, 1)); textNode->addText(text); guiNode->attachChild(textNode); cursorPosOffset = entry.length(); cursorRect = new Quad(Vector3(cursorWidth, size.y, 0), false); - cursorNode = new Node(Vector3(pos.x + text->getLength(), pos.y, cursorZCoord)); + cursorNode = new Node(Vector3(pos.x + text->getLength(), pos.y, pos.z + cursorZCoord)); Material *mat = new Material(libPath + "gui"); mat->addBoolUniform("texturingEnabled", false); mat->addVec4Uniform("diffuseColor", Vector4(1, 1, 1, 1)); diff --git a/textbox.h b/textbox.h index ce7d18a..007e062 100644 --- a/textbox.h +++ b/textbox.h @@ -15,7 +15,7 @@ namespace vb01Gui{ class Textbox{ public: - Textbox(vb01::Vector2, vb01::Vector2, std::string, std::wstring = L""); + Textbox(vb01::Vector3, vb01::Vector2, std::string, std::wstring = L""); ~Textbox(); void update(); void enable(); @@ -33,7 +33,7 @@ namespace vb01Gui{ private: class TextboxButton : public Button{ public: - TextboxButton(Textbox*, vb01::Vector2, vb01::Vector2, std::string); + TextboxButton(Textbox*, vb01::Vector3, vb01::Vector2, std::string); void onClick(); private: Textbox *textbox; @@ -41,9 +41,10 @@ namespace vb01Gui{ inline bool canChangeCursor(){return vb01::getTime() - lastBlinkTime > 250;} inline bool canDeleteChar(){return vb01::getTime() - lastDeleteTime > 50;} - float cursorZCoord = -.2; + float cursorZCoord; const int cursorWidth = 5; - vb01::Vector2 pos, size; + vb01::Vector3 pos; + vb01::Vector2 size; std::wstring entry = L""; std::string fontPath = ""; bool enabled = false, canShowCursor = false, capitalLeters = false, deleteCharacters = false;