diff --git a/build/linux/Makefile b/build/linux/Makefile index 9051926..69cd592 100644 --- a/build/linux/Makefile +++ b/build/linux/Makefile @@ -11,10 +11,10 @@ endif CXX=g++ DEBUG=-g CXXFLAGS+=$(DEBUG) -Wall `sdl2-config --cflags` -I../../src -I../../src/states -I../../src/gui -c -LDFLAGS+= -Wall -L../../../sdl/$(LIB_DIR) -Wl,-rpath=$(LIB_DIR)/ -lSDL2 -lSDL2_image -lpthread -Wl,--no-undefined -lm -ldl -pthread -lrt -Wl,-Bstatic -lGLEW -Wl,-Bdynamic -lGL +LDFLAGS+= -Wall -L../../../sdl/$(LIB_DIR) -Wl,-rpath=$(LIB_DIR)/ -lSDL2 -lSDL2_image -lSDL2_ttf -lpthread -Wl,--no-undefined -lm -ldl -pthread -lrt -Wl,-Bstatic -lGLEW -Wl,-Bdynamic -lGL VPATH=../../src BINARY=RtB$(BITS) -OBJ=main.o Asset.o AssetCache.o AssetManager.o Core.o fio.o checksum.o Log.o Quat.o Mat4.o Vec.o Mesh.o Texture.o Program.o RenderScene.o RenderSet.o RenderObject.o RenderCamera.o RenderView.o states/TestState.o states/MenuState.o SysInfo.o Gui.o gui/GuiElement.o gui/GuiButton.o gui/GuiList.o +OBJ=main.o Asset.o AssetCache.o AssetManager.o Core.o fio.o checksum.o Log.o Quat.o Mat4.o Vec.o Mesh.o Texture.o Program.o RenderScene.o RenderSet.o RenderObject.o RenderCamera.o RenderView.o states/TestState.o states/MenuState.o SysInfo.o Font.o Gui.o gui/GuiElement.o gui/GuiButton.o gui/GuiList.o OBJ_DIR=obj $(BINARY): $(patsubst %,$(OBJ_DIR)/%,$(OBJ)) @@ -41,5 +41,5 @@ $(OBJ_DIR)/%.o: %.cpp $(CXX) $(CXXFLAGS) $< -o $@ clean: - rm -f $(OBJ_DIR)/*.o + rm -rf $(OBJ_DIR)/* rm -rf build/* diff --git a/src/AssetCache.cpp b/src/AssetCache.cpp index 2cc9b88..b10f498 100644 --- a/src/AssetCache.cpp +++ b/src/AssetCache.cpp @@ -247,7 +247,7 @@ int AssetCache::toFile(const char *cache_file) { #else fprintf(file, "%s %u %jd\n", asset->filename.c_str(), asset->data_checksum, (intmax_t)asset->data_length); #endif - LOG(LOG_DEBUG) << ": saving " << asset->filename.c_str() << " bytes " << asset->data_length; + //LOG(LOG_DEBUG) << ": saving " << asset->filename.c_str() << " bytes " << asset->data_length; } fclose(file); return 0; diff --git a/src/Core.cpp b/src/Core.cpp index 13ed015..360c616 100644 --- a/src/Core.cpp +++ b/src/Core.cpp @@ -193,6 +193,31 @@ int Core::initSystem() { default_font = new Font("fonts/default.ttf", 16, asset->getData(), asset->getDataLength()); font_table = new HashTable(8); font_table->setnull(default_font); + // Program Management + program_table = new HashTable(16); + program_table->setnull(NULL); + // ** FRAMEBUFFER PROGRAM ** + // Load in our Framebuffer program (who else is to manage?) + Program *program = new Program(); + std::string shader_file; + shader_file = "shaders/" + core.shader_version + "/fb_fs.glsl"; + Asset *shader_asset = asset_manager->loadFile(shader_file.c_str()); + if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) { + LOG(LOG_ERROR) << "Failed to add Shader!"; + return 1; + } + shader_asset->unloadData(); + shader_file = "shaders/" + core.shader_version + "/fb_vs.glsl"; + shader_asset = asset_manager->loadFile(shader_file.c_str()); + if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) { + LOG(LOG_ERROR) << FUNC_NAME << "Failed to add Shader" << shader_file << "!"; + } + shader_asset->unloadData(); + if (program->doCompile() != 0) { + LOG(LOG_ERROR) << FUNC_NAME << ": Failed to compile framebuffer GLSL Program!"; + } + setProgram("fb", program); + //asset->unloadData(); // Create our basic RenderScene @@ -207,9 +232,8 @@ int Core::initSystem() { tick_delta = 0; tick_accumulator = tick_rate; - pushState(new TestState()); - flags |= IS_RUNNING; + pushState(new MenuState()); return 0; } int Core::closeSystem() { @@ -385,3 +409,13 @@ Font* Core::getFont(const char *font_name) { } return font; } +Program* Core::getProgram(const char *program_name) { + return program_table->get(program_name); +} +int Core::setProgram(const char *program_name, Program *program) { + Program *old_prog = program_table->get(program_name); + if (old_prog != NULL) delete old_prog; + program_table->set(program_name, program); + return 0; +} + diff --git a/src/Core.hpp b/src/Core.hpp index 2e859c9..fc30c82 100644 --- a/src/Core.hpp +++ b/src/Core.hpp @@ -44,6 +44,10 @@ class Core { HashTable *font_table; Font *default_font; // + Program *getProgram(const char *program_name); + int setProgram(const char *program_name, Program *program); + HashTable *program_table; + // int pushState(State *state); int popState(); int getWidth(); diff --git a/src/Gui.cpp b/src/Gui.cpp index 7b000d6..df9ea0f 100644 --- a/src/Gui.cpp +++ b/src/Gui.cpp @@ -124,9 +124,12 @@ int Gui::onEvent(SDL_Event event) { return 0; } int Gui::addElement(GuiElement *element) { + if (element == NULL) { + LOG(LOG_WARNING) << FUNC_NAME << ": NULL element passed"; + return 1; + } // - if (element->object == NULL && !(element->type & GuiElement::LIST)) { - element->object = new RenderObject(); + if (!(element->type & GuiElement::LIST)) { element->object->setMesh(element_mesh); set_basic->addObject(element->object); if (element->flags & GuiElement::HIDDEN) element->object->hide(); @@ -151,6 +154,22 @@ int Gui::addElement(GuiElement *element) { } return elements.size()-1; } +int Gui::delElement(const char *name) { + GuiElement *element; + std::vector::iterator element_it, element_end; + for (element_it = elements.begin(), element_end = elements.end(); element_it != element_end;) { + element = *element_it; + if (strcmp(element->text.c_str(), name) == 0) { + if (element->object != NULL) set_basic->remObject(element->object); + delete element; + element_it = elements.erase(element_it); + return 0; + } else { + ++element_it; + } + } + return 1; +} int Gui::setView(int width, int height) { w = width; h = height; diff --git a/src/Gui.hpp b/src/Gui.hpp index 21bed5c..664dbf5 100644 --- a/src/Gui.hpp +++ b/src/Gui.hpp @@ -17,6 +17,7 @@ class Gui { Gui(); ~Gui(); int addElement(GuiElement *element); + int delElement(const char *name); void updateElements(); int getWidth(); int getHeight(); diff --git a/src/Program.cpp b/src/Program.cpp index 3fe08a4..1666efa 100644 --- a/src/Program.cpp +++ b/src/Program.cpp @@ -94,8 +94,17 @@ int Program::deactivate() { } /* ======== Cleaning ======== */ int Program::doClean() { - // TODO: glDetachShader - // TODO: glDeleteProgram + // detach and delete shader (should actually detach earlier FIXME + size_t i; + for (i = 0; i < shader_prog.size(); i++) { + GLuint shader = shader_prog.at(i); + glDetachShader(program, shader); + glDeleteShader(shader); + } + shader_prog.clear(); + // delete program + glDeleteProgram(program); + program = 0; return 0; } /* ======== Variable interfaces ======== */ diff --git a/src/RenderScene.cpp b/src/RenderScene.cpp index 1ab258a..8bf891e 100644 --- a/src/RenderScene.cpp +++ b/src/RenderScene.cpp @@ -168,7 +168,7 @@ RenderCamera* RenderScene::getCamera(int id) { try { return cameras.at(id-1); } catch (const std::out_of_range& oor) { - LOG(LOG_ERROR) << FUNC_NAME << ": RenderCamera index out of range: " << oor.what(); + LOG(LOG_WARNING) << FUNC_NAME << ": RenderCamera index out of range: " << oor.what(); } return NULL; } @@ -204,6 +204,16 @@ int RenderScene::remSet(RenderSet *set) { LOG(LOG_WARNING) << FUNC_NAME << ": Could not remove RenderSet"; return 1; } +int RenderScene::delSet(RenderSet *set) { + std::vector::iterator it; + if ((it = std::find(sets.begin(), sets.end(), set)) != sets.end()) { + sets.erase(it); + delete set; + return 0; + } + LOG(LOG_WARNING) << FUNC_NAME << ": Could not delete RenderSet"; + return 1; +} RenderSet* RenderScene::getSet(int id) { try { diff --git a/src/RenderScene.hpp b/src/RenderScene.hpp index 35b4fbe..1de7113 100644 --- a/src/RenderScene.hpp +++ b/src/RenderScene.hpp @@ -27,6 +27,7 @@ class RenderScene { std::vector *getCameras(); int addSet(RenderSet *set); int remSet(RenderSet *set); + int delSet(RenderSet *set); int remSet(int id); RenderSet* getSet(int id); std::vector *getSets(); diff --git a/src/RenderSet.cpp b/src/RenderSet.cpp index 99e9ee6..a629bc5 100644 --- a/src/RenderSet.cpp +++ b/src/RenderSet.cpp @@ -5,6 +5,7 @@ This header file defines the RenderSet class. ================================================================ */ #include "RenderSet.hpp" #include "Log.hpp" +#include /* ======== Constructors and Destructors ======== */ RenderSet::RenderSet() { program = NULL; @@ -20,7 +21,27 @@ int RenderSet::addObject(RenderObject *object) { } return 0; } +int RenderSet::remObject(RenderObject *object) { + std::vector::iterator it; + if ((it = std::find(objects.begin(), objects.end(), object)) != objects.end()) { + objects.erase(it); + return 0; + } + LOG(LOG_WARNING) << FUNC_NAME << ": Could not remove RenderObject"; + return 1; +} +int RenderSet::delObject(RenderObject *object) { + std::vector::iterator it; + if ((it = std::find(objects.begin(), objects.end(), object)) != objects.end()) { + objects.erase(it); + delete object; + return 0; + } + LOG(LOG_WARNING) << FUNC_NAME << ": Could not delete RenderObject"; + return 1; +} + int RenderSet::setProgram(Program *prog) { program = prog; return 0; -} \ No newline at end of file +} diff --git a/src/RenderSet.hpp b/src/RenderSet.hpp index 06b203e..6abebc5 100644 --- a/src/RenderSet.hpp +++ b/src/RenderSet.hpp @@ -20,6 +20,8 @@ class RenderSet { RenderSet(); ~RenderSet(); int addObject(RenderObject *object); + int remObject(RenderObject *object); + int delObject(RenderObject *object); int setProgram(Program *prog); private: int mode; // bitflag, 0 = normal, 1 = hide diff --git a/src/gui/GuiButton.cpp b/src/gui/GuiButton.cpp index 0afa0d3..a85324f 100644 --- a/src/gui/GuiButton.cpp +++ b/src/gui/GuiButton.cpp @@ -1,8 +1,8 @@ #include "GuiButton.hpp" #include "Log.hpp" -GuiButton::GuiButton(std::string string, Texture *texture_) { - text.assign(string); +GuiButton::GuiButton(const char *name, Texture *texture_) { + text.assign(name); texture = texture_; } GuiButton::~GuiButton() { @@ -10,25 +10,7 @@ GuiButton::~GuiButton() { } int GuiButton::doUpdate(int c_width, int c_height) { - float ex = x * 2; - float ey = y * 2; - if (pflags & TOP) { - ey = c_height - ey + h - offset_y; - } else if (pflags & BOTTOM) { - ey = -c_height + ey - h + offset_y; - } else if (pflags & VCENTER) { - ey = ey; - } - if (pflags & LEFT) { - ex = -c_width + ex - w + offset_x; - } else if (pflags & RIGHT) { - ex = c_width - ex + w - offset_x; - } else if (pflags & HCENTER) { - ex = ex; - } - if (object == NULL) return 1; // return if we haven't been added to Gui yet - object->setTranslation(ex, 0.0f, ey); - object->calcMatrix(); + GuiElement::doUpdate(c_width, c_height); if (texture != NULL) object->setTexture(texture); return 0; } diff --git a/src/gui/GuiButton.hpp b/src/gui/GuiButton.hpp index 83970a7..e1469a5 100644 --- a/src/gui/GuiButton.hpp +++ b/src/gui/GuiButton.hpp @@ -1,12 +1,11 @@ #ifndef GUIBUTTON_HPP #define GUIBUTTON_HPP #include "GuiElement.hpp" -#include #include "Texture.hpp" class GuiButton : public GuiElement { public: - GuiButton(std::string text, Texture *texture); + GuiButton(const char *name, Texture *texture); ~GuiButton(); virtual int doUpdate(int c_width, int c_height); protected: diff --git a/src/gui/GuiElement.cpp b/src/gui/GuiElement.cpp index 66bcda7..52f1d9f 100644 --- a/src/gui/GuiElement.cpp +++ b/src/gui/GuiElement.cpp @@ -2,31 +2,35 @@ #include "Core.hpp" // UGH #include "Gui.hpp" // UGH x2 #include "Log.hpp" +#include GuiElement::GuiElement(const char *string, GuiElement *parent_) { - parent = parent_; parent->addChild(this); type = DEFAULT; text.assign(string); - object = NULL; + object = new RenderObject(); view = NULL; pflags = 0; flags = 0; - x = 0.25; y = 0.25; + x = y = 0; offset_x = offset_y = 0; - w = 0.25; h = 0.25; + w = 32.0f; h = 32.0f; + margin_l = margin_r = margin_t = margin_b = 0.0f; + padding_l = padding_r = padding_t = padding_b = 0.0f; } GuiElement::GuiElement(const char *string) { parent = NULL; type = DEFAULT; text.assign(string); - object = NULL; + object = new RenderObject(); pflags = 0; flags = 0; view = NULL; offset_x = offset_y = 0; - x = 0.25; y = 0.25; - w = 0.25; h = 0.25; + x = y = 0; + w = 32.0f; h = 32.0f; + margin_l = margin_r = margin_t = margin_b = 0.0f; + padding_l = padding_r = padding_t = padding_b = 0.0f; } GuiElement::GuiElement(const char *string, int group_id, int this_id) { parent = NULL; @@ -34,34 +38,52 @@ GuiElement::GuiElement(const char *string, int group_id, int this_id) { text.assign(string); gid = group_id; id = this_id; - object = NULL; + object = new RenderObject(); view = NULL; pflags = 0; flags = 0; - x = 0.25; y = 0.25; + x = y = 0; offset_x = offset_y = 0; - w = 0.25; h = 0.25; + w = 32.0f; h = 32.0f; + margin_l = margin_r = margin_t = margin_b = 0.0f; + padding_l = padding_r = padding_t = padding_b = 0.0f; } GuiElement::GuiElement() { parent = NULL; type = DEFAULT; - x = 0.25; y = 0.25; + x = y = 0; offset_x = offset_y = 0; - w = 0.25; h = 0.25; - view = NULL; - object = NULL; + w = 32.0f; h = 32.0f; + margin_l = margin_r = margin_t = margin_b = 0.0f; + padding_l = padding_r = padding_t = padding_b = 0.0f; + object = new RenderObject(); view = NULL; pflags = 0; flags = 0; } GuiElement::~GuiElement() { if (view != NULL) delete view; + if (object != NULL) delete object; } /* ======== Relationships ======== */ int GuiElement::addChild(GuiElement *child) { + // adopt the child! + if (child->parent != NULL && child->parent != this) { + child->parent->remChild(child); + } + child->parent = this; children.push_back(child); return children.size()-1; } +int GuiElement::remChild(GuiElement *child) { + child->parent = NULL; + std::vector::iterator it; + if ((it = std::find(children.begin(), children.end(), child)) != children.end()) { + children.erase(it); + return 0; + } + return 1; +} int GuiElement::setParent(GuiElement *parent_) { parent = parent_; // TODO: detach from old parent @@ -104,7 +126,6 @@ int GuiElement::setGeometry(float x_, float y_, float w_, float h_) { x = x_; y = y_; w = w_; h = h_; //view->setView(w, h); - if (object == NULL) return 1; object->setScale(w, 1.0, h); //object->setTranslation(x, 0.0, y); object->calcMatrix(); @@ -113,7 +134,6 @@ int GuiElement::setGeometry(float x_, float y_, float w_, float h_) { void GuiElement::setSize(float width, float height) { w = width; h = height; - if (object == NULL) return; object->setScale(w, 1.0, h); //object->setTranslation(x, 0.0, y); object->calcMatrix(); @@ -130,25 +150,45 @@ void GuiElement::setOffset(float offx, float offy) { offset_x = offx; offset_y = offy; } +void GuiElement::setPadding(float l, float r, float t, float b) { + padding_l = l; + padding_r = r; + padding_t = t; + padding_b = b; +} +void GuiElement::setMargin(float l, float r, float t, float b) { + margin_l = l; + margin_r = r; + margin_t = t; + margin_b = b; +} + /* ======== Render, eugh ======== */ int GuiElement::doUpdate(int c_width, int c_height) { - float ex = x * 2; - float ey = y * 2; - if (pflags & TOP) { - ey = c_height - ey + h; - } else if (pflags & BOTTOM) { - ey = -c_height + ey - h; - } else if (pflags & VCENTER) { - ey = ey; + // if we have no parent, we manage ourselves (poorly) + if (parent == NULL) { + float off_x = x; + float off_y = y; + if (pflags & GuiElement::HCENTER) { + off_x += (c_width/2.0f) - (w/2.0f); + } else if (pflags & GuiElement::RIGHT) { + off_x += c_width - w; + } + if (pflags & GuiElement::VCENTER) { + off_y += (c_height/2.0f) - (h/2.0f); + } else if (pflags & GuiElement::BOTTOM) { + off_y += c_height - h; + } + setPosition(off_x, off_y); } - if (pflags & LEFT) { - ex = -c_width + ex - w; - } else if (pflags & RIGHT) { - ex = c_width - ex + w; - } else if (pflags & HCENTER) { - ex = ex; - } - object->setTranslation(ex, 0.0f, ey); + // mod_x and mod_y are the modifiers to get our pixel origin set to (0, 0) at the top-left of the screen + float mod_x = -c_width + w; + float mod_y = c_height - h; + // real_x and real_y are our x and y coordinates in top-left screen terms + float real_x = x*2; + float real_y = -y*2; + //mod_x -= w*2; + object->setTranslation(mod_x+real_x, 0.0f, mod_y+real_y); object->calcMatrix(); return 0; } @@ -179,11 +219,11 @@ RenderView* GuiElement::getView() { } void GuiElement::hide() { flags |= HIDDEN; - if (object != NULL) object->hide(); + object->hide(); } void GuiElement::show() { flags &= ~HIDDEN; - if (object != NULL) object->show(); + object->show(); } int GuiElement::getFlags() { return flags; diff --git a/src/gui/GuiElement.hpp b/src/gui/GuiElement.hpp index 029da99..2192cba 100644 --- a/src/gui/GuiElement.hpp +++ b/src/gui/GuiElement.hpp @@ -12,6 +12,7 @@ This file describes the GuiElement class. This is the base class for further GUI #include "RenderCamera.hpp" class GuiElement { friend class Gui; + friend class GuiList; public: enum Type { DEFAULT = 0, @@ -43,6 +44,7 @@ class GuiElement { // int setText(const char *string); GuiElement *getHit(float xhit, float yhit); int addChild(GuiElement *child); + int remChild(GuiElement *child); int setParent(GuiElement *parent); int setPFlags(int pflags); RenderView *getView(); @@ -53,22 +55,26 @@ class GuiElement { void setSize(float width, float height); void setPosition(float newx, float newy); void setOffset(float offx, float offy); + void setMargin(float l, float r, float t, float b); + void setPadding(float l, float r, float t, float b); int getFlags(); void hide(); void show(); protected: - std::vector children; // children of this element - RenderView *view; // Ugh, we use FBOs for GUI elements cuz otherwise it's too annoying. - GuiElement *parent; // parent of this element - std::string text; // text of this element int type; // flag for this type int pflags; // positioning flags int flags; // flags + std::string text; // text of this element + GuiElement *parent; // parent of this element + std::vector children; // children of this element + RenderObject *object;// render object + RenderView *view; // Ugh, we use FBOs for GUI elements cuz otherwise it's too annoying. int gid; // group id for this element int id; // id for this element - RenderObject *object;// render object, as set by manager class, Gui // float x, y, w, h; // position and dimensions for this element float offset_x, offset_y; // offset x and y + float margin_l, margin_r, margin_t, margin_b; + float padding_l, padding_r, padding_t, padding_b; }; #endif diff --git a/src/gui/GuiList.cpp b/src/gui/GuiList.cpp index f195308..3f13313 100644 --- a/src/gui/GuiList.cpp +++ b/src/gui/GuiList.cpp @@ -1,46 +1,120 @@ #include "GuiList.hpp" #include "Log.hpp" -GuiList::GuiList(std::string string) { - text.assign(string); +GuiList::GuiList(const char *name) { + text.assign(name); type = LIST; + dflags = HORIZONTAL|RIGHT; } GuiList::~GuiList() { } +int GuiList::setDFlags(int dir_flags_) { + dflags = dir_flags_; + return 0; +} int GuiList::doUpdate(int c_width, int c_height) { - float ex = x * 2; - float ey = y * 2; - if (pflags & TOP) { - ey = c_height - ey + offset_y; - } else if (pflags & BOTTOM) { - ey = -c_height + ey - offset_y; - } else if (pflags & VCENTER) { - ey = ey + offset_y; + float off_x, off_y; + int width, height; + if (parent == NULL) { + LOG(LOG_INFO) << "I yam not a child: " << text; + off_x = 0.0f; + off_y = 0.0f; + width = c_width; + height = c_height; + } else { + LOG(LOG_INFO) << "I yam a child: " << text; + off_x = parent->x; + off_y = parent->y; + width = parent->getWidth(); + height = parent->getHeight(); } - if (pflags & LEFT) { - ex = -c_width + ex + offset_x; - } else if (pflags & RIGHT) { - ex = c_width - ex - offset_x; - } else if (pflags & HCENTER) { - ex = ex + offset_x; + float coff_x = 0.0f; // center position offset for child + float coff_y = 0.0f; // ^ + if (pflags & GuiElement::HCENTER) { + off_x += width/2.0f; + } else if (pflags & GuiElement::RIGHT) { + off_x += width; + off_x -= margin_r; + } else { + off_x += margin_l; } - float off_x = offset_x*2; - float off_y = offset_y*2; + if (pflags & GuiElement::VCENTER) { + off_y += height/2.0f; + } else if (pflags & GuiElement::BOTTOM) { + off_y += height; + off_y -= margin_b; + } else { + off_y += margin_t; + } + if (parent == NULL) { + x = off_x; + y = off_y; + } + + // Set light position offsets for the first element (if one exists) if we're building the list towards a non-standard direction - this is needed for right-origin and bottom-origin position flags (so the first element isn't off-screen/out of place) GuiElement *child; + if (children.size() > 0) { + child = children.front(); + if (pflags & GuiElement::RIGHT && dflags & GuiList::LEFT) { + //off_x -= child->getWidth(); + } + if (pflags & GuiElement::BOTTOM && dflags & GuiList::UP) { + //off_y -= child->getHeight(); + } + } + std::vector::iterator element_it, element_end; for (element_it = children.begin(), element_end = children.end(); element_it != element_end; ++element_it) { child = *element_it; if (child->getFlags() & HIDDEN) continue; - off_x += (child->getWidth()*2); - off_y = child->getHeight()*2; - child->setOffset(off_x, off_y); + if (dflags & GuiList::LEFT) { + off_x -= child->getWidth(); + off_x -= child->margin_r; + } else { + off_x += child->margin_l; + } + if (dflags & GuiList::UP) { + off_y -= child->getHeight(); + off_y -= child->margin_b; + } else { + off_y += child->margin_t; + } + if (pflags & GuiList::HCENTER) { + coff_x = child->getWidth()/2.0f; + } else { + coff_x = 0.0f; + } + if (pflags & GuiList::VCENTER) { + coff_y = child->getHeight()/2.0f; + } else { + coff_y = 0.0f; + } + + child->setPosition(off_x-coff_x, off_y-coff_y); + + if (dflags & GuiList::DOWN) { + off_y += child->getHeight(); + off_y += child->margin_b; + } else { + off_y -= child->margin_t; + } + if (dflags & GuiList::RIGHT) { + off_x += child->getWidth(); + off_x += child->margin_r; + } else { + off_x -= child->margin_l; + } child->doUpdate(c_width, c_height); + setSize(off_x, off_y); + } + if (pflags & GuiList::HCENTER) { + x -= off_x/2; + } + if (pflags & GuiList::VCENTER) { + y -= off_y/2; } - setSize(off_x/2, off_y/2); - if (object == NULL) return 1; // return if we haven't been added to Gui yet - object->setTranslation(ex+offset_x, 0.0f, ey+offset_y); object->calcMatrix(); return 0; } diff --git a/src/gui/GuiList.hpp b/src/gui/GuiList.hpp index 0720ced..f4047af 100644 --- a/src/gui/GuiList.hpp +++ b/src/gui/GuiList.hpp @@ -1,12 +1,22 @@ #ifndef GUILIST_HPP #define GUILIST_HPP #include "GuiElement.hpp" -#include class GuiList : public GuiElement { public: - GuiList(std::string text); + GuiList(const char *name); ~GuiList(); - virtual int doUpdate(int c_width, int c_height); + enum DFlags { + HORIZONTAL = (1 << 1), + VERTICAL = (1 << 2), + UP = (1 << 3), + DOWN = (1 << 4), + LEFT = (1 << 5), + RIGHT = (1 << 6) + }; + int doUpdate(int c_width, int c_height); + int setDFlags(int dir_flags_); + private: + int dflags; }; #endif diff --git a/src/states/MenuState.cpp b/src/states/MenuState.cpp index 773dafd..e3841b7 100644 --- a/src/states/MenuState.cpp +++ b/src/states/MenuState.cpp @@ -1,7 +1,12 @@ #include "MenuState.hpp" +#include "Log.hpp" +#include "Core.hpp" +#include "GuiElement.hpp" +#include "GuiList.hpp" +#include "GuiButton.hpp" /* ======== Construction and Destruction ======== */ MenuState::MenuState() { - + camera = NULL; } MenuState::~MenuState() { @@ -14,11 +19,70 @@ int MenuState::onEvent(SDL_Event event) { return 0; } int MenuState::onCede() { + gui->delElement("menu"); return 0; } int MenuState::onRise() { + // Get our services + gui = core.getGui(); + scene = core.getScene(); + asset_manager = core.getAssetManager(); + // We recreate everything cuz why not + // ** CAMERA CREATION ** + /*camera = new RenderCamera(); + camera->setRenderView(new RenderView(width, height)); + camera->updateProjection(width, height); + camera->setPitch(80.0f); + camera->setPosition(0, 30, 0); + camera->doRefresh(); + + scene->addCamera(camera);*/ + + // create our menu list + GuiList *glist = new GuiList("menu"); + glist->setPFlags(GuiElement::TOP|GuiElement::HCENTER); + glist->setDFlags(GuiList::DOWN); + glist->setGeometry(0.0f, 64.0f, 0.0f, 0.0f); + // Add our menu logo + GuiButton *gbutton = new GuiButton("logo", core.getTexture("ui/icon_isocube.png")); + gbutton->setGeometry(0.0f, 0.0f, 128.0f, 128.0f); + glist->addChild(gbutton); + // Add our Create button + gbutton = new GuiButton("Create", core.getTexture("ui/icon_token.png")); + gbutton->setGeometry(0.0f, 0.0f, 128.0f, 128.0f); + glist->addChild(gbutton); + // Add our Join button + gbutton = new GuiButton("Join", core.getTexture("ui/icon_token.png")); + gbutton->setGeometry(0.0f, 0.0f, 128.0f, 8.0f); + glist->addChild(gbutton); + // Add our Quit button + gbutton = new GuiButton("Quit", core.getTexture("ui/icon_token.png")); + gbutton->setGeometry(0.0f, 0.0f, 64.0f, 64.0f); + glist->addChild(gbutton); + // Add our entire list + GuiList* glist2 = new GuiList("menu2"); + glist2->setPFlags(GuiElement::LEFT|GuiElement::TOP); + glist2->setDFlags(GuiList::RIGHT); + gbutton = new GuiButton("Quit", core.getTexture("ui/icon_perscube.png")); + gbutton->setGeometry(0.0f, 0.0f, 128.0f, 128.0f); + glist2->addChild(gbutton); + gbutton = new GuiButton("Quit2", core.getTexture("ui/icon_perscube.png")); + gbutton->setGeometry(0.0f, 0.0f, 128.0f, 128.0f); + glist2->addChild(gbutton); + gbutton = new GuiButton("Quit3", core.getTexture("ui/icon_perscube.png")); + gbutton->setGeometry(0.0f, 0.0f, 128.0f, 128.0f); + glist2->addChild(gbutton); + + glist->addChild(glist2); + // Add our entire list + gui->addElement(glist); + // manual update + gui->updateElements(); + + // ** PROGRAM LOADING ** return 0; } int MenuState::onInit() { + return 0; } diff --git a/src/states/MenuState.hpp b/src/states/MenuState.hpp index 8172789..43a4ab0 100644 --- a/src/states/MenuState.hpp +++ b/src/states/MenuState.hpp @@ -6,6 +6,9 @@ MenuState.cpp/MenuState.hpp provide the Main Menu state that the program first a #ifndef MENUSTATE_HPP #define MENUSTATE_HPP #include "State.hpp" +#include "RenderScene.hpp" +#include "AssetManager.hpp" +#include "Gui.hpp" class MenuState : public State { friend class Core; public: @@ -17,5 +20,11 @@ class MenuState : public State { virtual int onInit(); virtual int onCede(); virtual int onRise(); + private: + Program *menu_program; + RenderScene *scene; + RenderCamera *camera; + AssetManager *asset_manager; + Gui *gui; }; #endif diff --git a/src/states/TestState.cpp b/src/states/TestState.cpp index 31b8eef..755518e 100644 --- a/src/states/TestState.cpp +++ b/src/states/TestState.cpp @@ -26,6 +26,7 @@ int TestState::onEvent(SDL_Event event) { if (event.type == SDL_MULTIGESTURE) { LOG(LOG_INFO) << "gesture: " << event.mgesture.x << "x" << event.mgesture.y << ", rot:" << event.mgesture.dTheta << ", pinch:" << event.mgesture.dDist << ", fingers:" << event.mgesture.numFingers; RenderCamera *camera = scene->getCamera(1); + if (camera == NULL) return 0; Vec3 camera_pos = camera->getPosition(); camera_pos.y -= event.mgesture.dDist*128.0f; @@ -39,6 +40,7 @@ int TestState::onEvent(SDL_Event event) { LOG(LOG_INFO) << "finger: " << event.tfinger.fingerId << " " << event.tfinger.x << "x" << event.tfinger.y << " " << event.tfinger.dx << "x" << event.tfinger.dy; RenderCamera *camera = scene->getCamera(1); + if (camera == NULL) return 0; Vec3 camera_pos = camera->getPosition(); int width = core.getWidth(); int height = core.getHeight(); @@ -58,6 +60,7 @@ int TestState::onEvent(SDL_Event event) { } else if (event.type == SDL_MOUSEMOTION && event.motion.which != SDL_TOUCH_MOUSEID) { LOG(LOG_INFO) << "mouse motion: " << event.motion.xrel << "x" << event.motion.yrel << " "; RenderCamera *camera = scene->getCamera(1); + if (camera == NULL) return 0; if (event.motion.state & SDL_BUTTON_MMASK) { camera->setYaw(camera->getYaw() - event.motion.xrel); } else if (event.motion.state & SDL_BUTTON_RMASK) { @@ -75,6 +78,7 @@ int TestState::onEvent(SDL_Event event) { camera->doRefresh(); } else if (event.type == SDL_MOUSEWHEEL) { RenderCamera *camera = scene->getCamera(1); + if (camera == NULL) return 0; Vec3 camera_pos = camera->getPosition(); camera_pos.y -= event.wheel.y; camera->setPosition(camera_pos.x, camera_pos.y, camera_pos.z); @@ -82,6 +86,7 @@ int TestState::onEvent(SDL_Event event) { } else if (event.type == SDL_KEYUP) { if (event.key.keysym.sym == SDLK_SPACE) { RenderCamera *camera = scene->getCamera(1); + if (camera == NULL) return 0; if (camera->getRenderMode() == 0) { camera->setRenderMode(1); } else { @@ -104,29 +109,9 @@ int TestState::onInit() { // Get our services asset_manager = core.getAssetManager(); gui = core.getGui(); - // TEMP: our framebuffer rendering program - Program *program = new Program(); - // FIXME: check for GLSL version and automagically load the appropriate shader file - std::string shader_file; - shader_file = "shaders/" + core.shader_version + "/fb_fs.glsl"; - Asset *shader_asset = asset_manager->loadFile(shader_file.c_str()); - if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) { - LOG(LOG_ERROR) << "Failed to add Shader!"; - return 1; - } - shader_asset->unloadData(); - shader_file = "shaders/" + core.shader_version + "/fb_vs.glsl"; - shader_asset = asset_manager->loadFile(shader_file.c_str()); - if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) { - LOG(LOG_ERROR) << "Failed to add Shader!"; - return 1; - } - shader_asset->unloadData(); - if (program->doCompile() != 0) { - LOG(LOG_ERROR) << "Failed to compile GLSL Program!"; - return 1; - } // TEMP: our model rendering program + std::string shader_file; + Asset *shader_asset; Program *program_model = new Program(); shader_file = "shaders/" + core.shader_version + "/default_fs.glsl"; shader_asset = asset_manager->loadFile(shader_file.c_str()); @@ -157,9 +142,11 @@ int TestState::onInit() { camera->setPosition(0, 30, 0); camera->doRefresh(); - scene->addCamera(camera); + //scene->addCamera(camera); + + Program *program = core.getProgram("fb"); - program->attachTexture(0, camera->getRenderView()->getTex()); + //program->attachTexture(0, camera->getRenderView()->getTex()); (camera->getRenderView()->setProgram(program));