]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
kinda big: texture redo, main cleanup
authorClyne Sullivan <tullivan99@gmail.com>
Thu, 22 Dec 2016 02:29:59 +0000 (21:29 -0500)
committerClyne Sullivan <tullivan99@gmail.com>
Thu, 22 Dec 2016 02:29:59 +0000 (21:29 -0500)
13 files changed:
include/common.hpp
include/components.hpp
include/engine.hpp
include/texture.hpp
include/world.hpp
main.cpp
src/components.cpp
src/engine.cpp
src/inventory.cpp
src/texture.cpp
src/ui.cpp
src/ui_menu.cpp
src/world.cpp

index 7b98ea928533f9d9cd86122e6ed25ebb1c58ca09..df41aa170363ffa6e3a535dbd941879ce2db5544 100644 (file)
@@ -58,10 +58,9 @@ typedef unsigned int uint;
 
 #define BREAKPOINT __asm__("int $3")
 
-template<typename T>
-inline const T * const& coalesce(const void * &p1, const void * &p2)
+inline const char* coalesce(const char * p1, const char * p2)
 {
-       return ((p1 == nullptr) ? reinterpret_cast<T*>(p2) : p1);
+       return ((p1 == nullptr) ? p2 : p1);
 }
 
 /**
@@ -81,12 +80,9 @@ typedef ivec2 dim2;
  * Creates a coordinate out of floating point integers.
  */
 struct vec2 {
-       float x; /**< The x coordinate */
-       float y; /**< The y coordinate */
+       float x;
+       float y;
 
-       /**
-        * Constructs a vec2 with the specified coordinates.
-        */
        vec2(float _x = 0.0f, float _y = 0.0f)
                : x(_x), y(_y) {}
 
@@ -109,11 +105,14 @@ struct vec2 {
                return vec2 (x + v.x, y + v.y);
        }
 
-       template<typename T>
-       const vec2 operator*(const T &n) {
+       vec2 operator*(const float&n) const {
                return vec2 (x * n, y * n);
        }
 
+       vec2 operator/(const float& n) const {
+               return vec2 (x / n, y / n);
+       }
+
        // std::swap can't work due to being packed
 
        inline void swapX(vec2 &v) {
@@ -126,6 +125,10 @@ struct vec2 {
                y = v.y, v.y = t;
        }
 
+       std::string toString(void) const {
+               return "(" + std::to_string(x) + ", " + std::to_string(y) + ")";
+       }
+
 } __attribute__ ((packed));
 
 /**
index 4f8ef563643be67ef9586304fa5cbaf46f9c0071..f6521f87be936de613fdec1a3b022750b78603c4 100644 (file)
@@ -126,15 +126,11 @@ struct Solid {
 
 struct SpriteData {
 
-       SpriteData(std::string path, vec2 offset):
-               offset(offset) {
-                       pic = Texture::loadTexture(path);
-                       size = Texture::imageDim(path);
-               }
+       SpriteData(std::string path, vec2 offset)
+               : tex(path), offset(offset) {}
 
-       GLuint pic;
+       Texture tex;
        vec2 offset;
-       vec2 size;
 };
 
 using Frame = std::vector<std::pair<SpriteData, vec2>>;
@@ -193,15 +189,17 @@ struct Sprite {
                }
 
                for (auto &s : sprite) {
+                       const auto& size = s.first.tex.getDim();
+
                        if (s.second.x < st.x)
                                st.x = s.second.x;
                        if (s.second.y < st.y)
                                st.y = s.second.y;
 
-                       if (s.second.x + s.first.size.x > dim.x)
-                               dim.x = s.second.x + s.first.size.x;
-                       if (s.second.y + s.first.size.y > dim.y)
-                               dim.y = s.second.y + s.first.size.y;
+                       if (s.second.x + size.x > dim.x)
+                               dim.x = s.second.x + size.x;
+                       if (s.second.y + size.y > dim.y)
+                               dim.y = s.second.y + size.y;
                }
 
                return dim;
@@ -299,9 +297,9 @@ public:
 class RenderSystem : public entityx::System<RenderSystem> {
 private:
        std::string loadTexString;
-       std::atomic<GLuint> loadTexResult;
+       Texture loadTexResult;
 public:
-       GLuint loadTexture(const std::string& file);
+       Texture loadTexture(const std::string& file);
        void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override;
 };
 
index c842b599333d9cce38e0c68e64d9dbd994f20083..6e0c5a0d6fa4a52cb2060960a61c08db4a02fefc 100644 (file)
@@ -47,7 +47,7 @@ namespace game {
         events.emit<GameEndEvent>();
     }
 
-       extern SpriteLoader sprite_l;
+       //extern SpriteLoader sprite_l;
 }
 
 
index ad5211c5ef6b913e8c515a6d436d94fc2220979e..e9082b3967697a1cb1b51d2c0ff7f65200fb88ee 100644 (file)
@@ -1,11 +1,10 @@
-/** @file Texture.h
+/**
+ * @file Texture.h
  * @brief Defines a method for loading textures.
- *
  * This file gives facilities for easily loading and binding textures.
  */
-
-#ifndef TEXTURE_H
-#define TEXTURE_H
+#ifndef TEXTURE_HPP_
+#define TEXTURE_HPP_
 
 #include <common.hpp>
 
 #define DEBUG
 
 /**
- * Texture functions are given a namespace for better organization.
+ * @class Texture
+ * Handles a single texture, loaded from the given file.
  */
-namespace Texture {
+class Texture {
+private:
+       std::string name; /**< The name (path) of the loaded file. */
+       GLuint tex;       /**< The GLuint for the loaded texture. */
+       vec2 dim;         /**< The dimensions of the loaded texture. */
 
+public:
        /**
-        * Loads a texture from the given file name, returning the GLuint used for
-        * later referencing of the texture.
+        * Attempts to create a texture.
+        * Either:
+        * - Creates an empty class (no arguments given)
+        * - Load a texture from the given file, crashing if file not found
+        * - Fills the class with the given values
+        * @param file the path to the desired texture
+        * @param t the GLuint for the texture, if known
+        * @param v the size of the texture, if known
         */
+       Texture(const std::string& file = "", const GLuint& t = 0xFFFFF, const vec2& v = vec2(0, 0));
 
-       GLuint loadTexture(std::string fileName);
-    GLuint genColor(Color c);
+       /**
+        * Gets the name (path) of the loaded texture.
+        * @return the texture's name
+        */
+       const std::string& getName(void) const;
 
-       void freeTextures(void);
+       /**
+        * Gets the dimensions of the loaded texture.
+        * @return the texture's dimensions
+        */
+       const vec2& getDim(void) const;
 
-       void initColorIndex();
-       vec2 getIndex(Color c);
-       vec2 imageDim(std::string fileName);
-}
+       /**
+        * Binds the texture, so it may be used for rendering.
+        */
+       inline void use(void) const
+       { glBindTexture(GL_TEXTURE_2D, tex); }
 
-class SpriteLoader {
-private:
-       std::unordered_map<uint64_t, GLuint> sprites;
-       std::unordered_map<std::string, uint64_t> spritesLoc;
-
-       uint64_t freeID = 0;
-       uint64_t increaseID() {
-               uint64_t id_t = 0;
-               while (1) {
-                       try {
-                               sprites.at(id_t);
-                       } catch (const std::out_of_range& oor) {
-                               freeID = id_t;
-                               return freeID;
-                       }
-                       id_t++;
-               }
-       }
-public:
-       uint64_t loadSprite(std::string s)      {
-               uint64_t tex_e = 0;
-               try {
-                       tex_e = spritesLoc.at(s);
-               } catch (const std::out_of_range& oor) {
-                       sprites.emplace(increaseID(), Texture::loadTexture (s));
-                       spritesLoc.emplace(s, freeID);
-                       return freeID;
-               }
-               return tex_e;
-       }
-
-       GLuint getSprite(uint64_t id) {
-               return sprites.at(id);
-       }
+       /**
+        * Frees GPU resources for the loaded texture.
+        */
+       inline void destroy(void)
+       { glDeleteTextures(1, &tex), tex = 0xFFFFF; }
+
+       /**
+        * Checks if a texture is currently loaded in this class.
+        * @return true if there is not a loaded texture
+        */
+       inline bool isEmpty(void) const
+       { return (tex == 0xFFFFF); }
 };
 
 /**
- * DRAFT texture iterator?
+ * @class ColorTex
+ * Creates a single-pixel texture of the given color.
  */
-class TextureIterator {
-private:
-       std::vector<std::pair<GLuint, std::string>> textures;
-       std::vector<std::pair<GLuint, std::string>>::iterator position;
+class ColorTex : public Texture {
 public:
-       TextureIterator(void) {
-               position = std::begin(textures);
-       }
-       ~TextureIterator(void) {
-               textures.clear();
-       }
-       TextureIterator(const std::vector<std::string> &l) {
-               for (const auto &s : l)
-                       textures.emplace_back(Texture::loadTexture(s), s);
-
-               position = std::begin(textures);
-       }
-       void operator++(int) noexcept {
-               if (++position < std::end(textures))
-                       glBindTexture(GL_TEXTURE_2D, (*position).first);
-               else
-                       position = std::end(textures) - 1;
-       }
-       void operator--(int) noexcept {
-               if (--position >= std::begin(textures))
-                       glBindTexture(GL_TEXTURE_2D, (*position).first);
-               else
-                       position = std::begin(textures);
-       }
-       void operator()(const int &index) {
-               if (index < 0 || index > static_cast<int>(textures.size()))
-                       throw std::invalid_argument("texture index out of range");
-
-               position = std::begin(textures) + index;
-               glBindTexture(GL_TEXTURE_2D, (*position).first);
-       }
-       const std::string& getTexturePath(const int &index) {
-               if (index < 0 || index > static_cast<int>(textures.size()))
-                       throw std::invalid_argument("texture index out of range");
-
-               return textures[index].second;
-       }
-       const vec2 getTextureDim(void) {
-               return Texture::imageDim((*position).second);
-       }
+       ColorTex(void);
+
+       /**
+        * Creates a texture of the given color.
+        * @param color the desired color
+        */
+       ColorTex(const Color& color);
 };
 
 /**
- * The Texturec class.
- *
- * This class can handle an array of textures and allows easy binding of those
- * textures.
+ * A collection of preloaded colors, to save resources.
  */
+namespace Colors {
+       extern ColorTex white; /**< A solid white texture. */
+       extern ColorTex black; /**< A solid black texture. */
+       extern ColorTex red;   /**< A solid red texture. */
 
-class Texturec{
+       /**
+        * Creates the colors.
+        */
+       void init(void);
+}
+
+/**
+ * @class TextureIterator
+ * Keeps a collection of textures for easy usage/looping.
+ */
+class TextureIterator {
 private:
-       unsigned int texState;
+       /**
+        * The set of textures to loop through.
+        */
+       std::vector<Texture> textures;
 
+       /**
+        * The current position in the texture array.
+        * @see textures
+        */
+       std::vector<Texture>::iterator position;
 public:
+       TextureIterator(void)
+               : position(std::begin(textures)) {}
+       ~TextureIterator(void) {}
 
-       std::vector<GLuint> image;
-       std::vector<std::string> texLoc;
-
-       Texturec(uint amt, ...);
-       Texturec(uint amt,const char **paths);
-       Texturec(std::vector<std::string>vec);
-       Texturec(std::initializer_list<std::string> l);
-
-       ~Texturec();
+       /**
+        * Constructs a set of textures from the given list.
+        * @param l the list of textures
+        */
+       TextureIterator(const std::vector<std::string> &l);
+       /**
+        * Shifts to the next texture in the array, stopping at the end if we're there.
+        * Also binds the texture.
+        */
+       void operator++(int) noexcept;
 
-       void bindNext();
-       void bindPrev();
-       void bind(unsigned int);
+       /**
+        * Shifts back in the array, staying at the beginning if we're there.
+        * Also binds the texture.
+        */
+       void operator--(int) noexcept;
+       /**
+        * Goes to the given index in the list.
+        * @param index the index to use
+        */
+       void operator()(const int &index);
+       /**
+        * Gets the dimensions of the currently selected texture.
+        * @return the texture's dimensions
+        */
+       inline const vec2& getTextureDim(void)
+       { return position->getDim(); }
 };
 
-#endif //TEXTURE_H
+/**
+ * Frees all loaded textures, rendering them all useless.
+ */
+void unloadTextures(void);
+
+#endif //TEXTURE_HPP_
index 5c021bfb097780c12a9fd1e0c1c41ae8c9e13335..8b24987066265eb80bc8216d1a8986296c47537e 100644 (file)
@@ -108,8 +108,7 @@ struct WorldData2 {
 
        // Indoor variables
        bool indoor;                 /**< Set to true if this is an indoor world. */
-       float indoorWidth;           /**< The width of the indoor texture (house). */
-       GLuint indoorTex;            /**< The texture to draw (house). */
+       Texture indoorTex;           /**< The house's inside texture. */
        std::string outdoor;         /**< The file name of the outdoor world. */
        vec2 outdoorCoords;          /**< The coordinates the player should spawn to when exiting. */
 
index a3901a3dc3792bc491abbfa0dd6df5755b04f7b9..857970727d73110b68c19d71cbff102124fd60ec 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -1,81 +1,66 @@
-/* ----------------------------------------------------------------------------
-** The main file, home of the main loop.
-** --------------------------------------------------------------------------*/
-// ...
-/* ----------------------------------------------------------------------------
-** Includes section
-** --------------------------------------------------------------------------*/
-
-#include <brice.hpp>
-
-#include <entityx/entityx.h>
+/**
+ * @file main.cpp
+ * The main file, where it all happens.
+ */
 
-#include <window.hpp>
-#include <render.hpp>
-#include <engine.hpp>
+// standard library includes
+#include <fstream>
+#include <mutex>
+#include <chrono>
+using namespace std::literals::chrono_literals;
 
 // local library includes
+#include <entityx/entityx.h>
 #include <tinyxml2.h>
 using namespace tinyxml2;
 
-// local game includes
-#include <common.hpp>
+// our own includes
+#include <brice.hpp>
 #include <config.hpp>
-#include <world.hpp>
-#include <ui.hpp>
+#include <common.hpp>
+#include <engine.hpp>
 #include <gametime.hpp>
 #include <player.hpp>
+#include <window.hpp>
+#include <world.hpp>
+#include <render.hpp>
+#include <ui.hpp>
 
-#include <fstream>
-#include <mutex>
-#include <chrono>
-
-using namespace std::literals::chrono_literals;
-
-/* ----------------------------------------------------------------------------
-** Variables section
-** --------------------------------------------------------------------------*/
-
-// the currently used folder to grab XML files
+/**
+ * The currently used folder to look for XML files in.
+ */
 std::string xmlFolder;
 
-// the current menu
+/**
+ * The current menu, if any are open (TODO why is this here)
+ */
 Menu *currentMenu;
 
-// keeps a simple palette of colors for single-color draws
-GLuint colorIndex;
-
-// the mouse's texture
-GLuint mouseTex;
-
-// the center of the screen
+/**
+ * The current center of the screen, updated in main render.
+ */
 vec2 offset;
 
-/*
- * fps contains the game's current FPS, debugY contains the player's
- * y coordinates, updated at a certain interval. These are used in
- * the debug menu (see below).
+/**
+ * The current FPS of the game.
  */
+static unsigned int fps = 0;
 
-static unsigned int fps=0;
-//static float debugY=0;
-
-// handles all logic operations
-void logic(void);
-
-// handles all rendering operations
 void render(void);
 
-/*******************************************************************************
-** MAIN ************************************************************************
-********************************************************************************/
-
+/**
+ * The main program.
+ * Init, load, run. Die.
+ */
 int main(int argc, char *argv[])
 {
        static bool worldReset = false, worldDontReallyRun = false;
        std::string worldActuallyUseThisXMLFile;
 
-       // handle command line arguments
+       //
+       // get command line arguments, if any
+       //
+
        if (argc > 1) {
                for (int i = 1; i < argc; i++) {
                        std::string s = argv[i];
@@ -89,49 +74,67 @@ int main(int argc, char *argv[])
                }
        }
 
+       //
+       // init the main game engine
+       //
+
        game::engine.init();
+       // used three times below
+       auto worldSys = game::engine.getSystem<WorldSystem>();
 
+       //
        // initialize GLEW
+       //
+
 #ifndef __WIN32__
        glewExperimental = GL_TRUE;
 #endif
 
-       GLenum err;
-       if ((err = glewInit()) != GLEW_OK)
-               UserError(std::string("GLEW was not able to initialize! Error: ") + reinterpret_cast<const char *>(glewGetErrorString(err)));
+       auto glewError = glewInit();
+       if (glewError != GLEW_OK)
+               UserError(std::string("GLEW was not able to initialize! Error: ")
+                       + reinterpret_cast<const char *>(glewGetErrorString(glewError)));
+
+       //
+       // start the random number generator (TODO our own?)
+       //
 
-       // start the random number generator
        randInit(millis());
 
-       // 'basic' OpenGL setup
+       //
+       // some basic OpenGL setup stuff
+       //
+
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-       SDL_GL_SetSwapInterval(1); // v-sync
-       SDL_ShowCursor(SDL_DISABLE); // hide the mouse
+       // enable v-sync (TODO but 1000 fps?)
+       SDL_GL_SetSwapInterval(1);
+       // hide the cursor
+       SDL_ShowCursor(SDL_DISABLE);
+       // switch to pixel grid
        glViewport(0, 0, game::SCREEN_WIDTH, game::SCREEN_HEIGHT);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       glClearColor(1,1,1,1);
-
-       // TODO
-       Texture::initColorIndex();
+       glClearColor(1, 1, 1, 1);
 
+       //
        // initialize shaders
-       std::cout << "Initializing shaders!\n";
+       //
 
-       // create shaders
+       std::cout << "Initializing shaders!\n";
        Render::initShaders();
+       Colors::init();
+
+       //
+       // load some saved data
+       //
 
-       // load up some fresh hot brice
        game::briceLoad();
        game::briceUpdate();
 
-       // load sprites used in the inventory menu. See src/inventory.cpp
-       //initInventorySprites();
-
-       // load mouse texture, and other inventory textures
-       mouseTex = Texture::loadTexture("assets/mouse.png");
-
+       //
        // get a world
+       //
+
        if (xmlFolder.empty())
                xmlFolder = "xml/";
 
@@ -143,69 +146,57 @@ int main(int argc, char *argv[])
        // alphabetically sort files
        strVectorSortAlpha(&xmlFiles);
 
+       // kill the world if needed
        if (worldReset) {
-               for (const auto &xf : xmlFiles) {
-                       if (xf[0] != '.') {
-                               XMLDocument xmld;
-                               auto file = xmlFolder + xf;
-                               xmld.LoadFile(file.c_str());
-
-                               auto xmle = xmld.FirstChildElement("World");
-
-                               if (xmle == nullptr) {
-                                       xmle = xmld.FirstChildElement("IndoorWorld");
-
-                                       if (xmle == nullptr)
-                                               continue;
-                               }
-
-                               xmle = xmle->FirstChildElement();
-                               while (xmle) {
-                                       xmle->DeleteAttribute("x");
-                                       xmle->DeleteAttribute("y");
-                                       xmle->DeleteAttribute("health");
-                                       xmle->DeleteAttribute("alive");
-                                       xmle->DeleteAttribute("dindex");
-                                       xmle = xmle->NextSiblingElement();
-                               }
-
-                               xmld.SaveFile(file.c_str(), false);
-                       }
-               }
-
+               // TODO TODO TODO we do xml/*.dat now...
                game::briceClear();
-
-               std::ofstream pdat ("xml/.main.dat", std::ios::out);
-               pdat.close();
        }
 
+       // either load the given XML, or find one
        if (!worldActuallyUseThisXMLFile.empty()) {
-               game::engine.getSystem<WorldSystem>()->load(worldActuallyUseThisXMLFile);
+               worldSys->load(worldActuallyUseThisXMLFile);
        } else {
                // load the first valid XML file for the world
                for (const auto &xf : xmlFiles) {
                        if (xf[0] != '.') {
                                // read it in
                                std::cout << "File to load: " << xf << '\n';
-                               game::engine.getSystem<WorldSystem>()->load(xf);
+                               worldSys->load(xf);
                                break;
                        }
                }
        }
 
+       //
+       // initialize ui
+       //
+
        ui::menu::init();
 
 
+       /////////////////////////////
+       //                         //
+       // actually start the game //
+       //                         //
+       /////////////////////////////
 
        if (!worldDontReallyRun) {
-               // the main loop, in all of its gloriousness..
+               // the main loop, in all of its gloriousness...
                std::thread thMain ([&] {
                        const bool &run = game::engine.shouldRun;
                        while (run) {
                                game::time::mainLoopHandler();
 
-                               if (game::time::tickHasPassed())
-                                       logic();
+                               if (game::time::tickHasPassed()) {
+                                       // calculate the world shading value
+                                       worldShade = 50 * sin((game::time::getTickCount() + (DAY_CYCLE / 2)) / (DAY_CYCLE / PI));
+
+                                       // update fades
+                                       ui::fadeUpdate();
+
+                                       // increment game ticker
+                                       game::time::tick();
+                               }
 
                                game::engine.update(game::time::getDeltaTime());
 
@@ -217,74 +208,88 @@ int main(int argc, char *argv[])
                std::thread thDebug ([&] {
                        const bool &run = game::engine.shouldRun;
                        while (run) {
-                               fps = 1000 / game::time::getDeltaTime();
-//                             debugY = player->loc.y;
-
+                               fps = 1000 / game::time::getDeltaTime(); // TODO really?
                                std::this_thread::sleep_for(1s);
                        }
                });
 
+               // thre render loop, renders
                const bool &run = game::engine.shouldRun;
                while (run) {
                        render();
                        game::engine.render(0);
                }
 
+               // on game end, get back together
                thMain.join();
                thDebug.join();
-               //game::engine.getSystem<WorldSystem>()->thAmbient.join();
+               //game::engine.getSystem<WorldSystem>()->thAmbient.join(); // segfault or something
        }
 
-       // put away the brice for later
+       //
+       // put away the brice for later, save world
+       //
+
        game::briceSave();
+       worldSys->save();
+
+       //
+       // close things, free stuff, yada yada
+       //
 
-       // free library resources
     Mix_HaltMusic();
     Mix_CloseAudio();
 
-//    destroyInventory();
        ui::destroyFonts();
-    Texture::freeTextures();
-
-       // close up the game stuff
-       game::engine.getSystem<WorldSystem>()->save();
+    unloadTextures();
 
        game::engine.getSystem<WindowSystem>()->die();
 
+       //
+       // goodbye
+       //
+
     return 0; // Calls everything passed to atexit
 }
 
 void render() {
-       const auto SCREEN_WIDTH = game::SCREEN_WIDTH;
-       const auto SCREEN_HEIGHT = game::SCREEN_HEIGHT;
+       static const Texture mouseTex ("assets/mouse.png");
+       static const glm::mat4 view = glm::lookAt(
+               glm::vec3(0.0f, 0.0f, 0.0f),   // pos
+               glm::vec3(0.0f, 0.0f, -10.0f), // looking at
+               glm::vec3(0.0f, 1.0f, 0.0f)    // up vector
+       );
+
+       static const auto& SCREEN_WIDTH2  = game::SCREEN_WIDTH / 2.0f;
+       static const auto& SCREEN_HEIGHT2 = game::SCREEN_HEIGHT / 2.0f;
+
+       //
+       // set the ortho
+       //
 
        auto ps = game::engine.getSystem<PlayerSystem>();
        auto ploc = ps->getPosition();
        offset.x = ploc.x + ps->getWidth() / 2;
 
        const auto& worldWidth = game::engine.getSystem<WorldSystem>()->getWidth();
-       if (worldWidth < (int)SCREEN_WIDTH)
+       if (worldWidth < (int)SCREEN_WIDTH2 * 2)
                offset.x = 0;
-       else if (offset.x - SCREEN_WIDTH / 2 < worldWidth * -0.5f)
-               offset.x = ((worldWidth * -0.5f) + SCREEN_WIDTH / 2);
-       else if (offset.x + SCREEN_WIDTH / 2 > worldWidth *  0.5f)
-               offset.x = ((worldWidth *  0.5f) - SCREEN_WIDTH / 2);
+       else if (offset.x - SCREEN_WIDTH2 < worldWidth * -0.5f)
+               offset.x = ((worldWidth * -0.5f) + SCREEN_WIDTH2);
+       else if (offset.x + SCREEN_WIDTH2 > worldWidth *  0.5f)
+               offset.x = ((worldWidth *  0.5f) - SCREEN_WIDTH2);
 
        // ortho y snapping
-       offset.y = std::max(ploc.y /*+ player->height / 2*/, SCREEN_HEIGHT / 2.0f);
+       offset.y = std::max(ploc.y /*+ player->height / 2*/, SCREEN_HEIGHT2);
 
        // "setup"
-       glm::mat4 projection = glm::ortho(floor(offset.x - SCREEN_WIDTH / 2),          // left
-                                         floor(offset.x + SCREEN_WIDTH / 2),          // right
-                                         floor(offset.y - SCREEN_HEIGHT / 2),         // bottom
-                                         floor(offset.y + SCREEN_HEIGHT / 2),         // top
+       glm::mat4 projection = glm::ortho(floor(offset.x - SCREEN_WIDTH2),             // left
+                                         floor(offset.x + SCREEN_WIDTH2),             // right
+                                         floor(offset.y - SCREEN_HEIGHT2),            // bottom
+                                         floor(offset.y + SCREEN_HEIGHT2),            // top
                                          static_cast<decltype(floor(10.0f))>(10.0),   // near
                                          static_cast<decltype(floor(10.0f))>(-10.0)); // far
 
-       glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f),   // pos
-                                                                glm::vec3(0.0f, 0.0f, -10.0f), // looking at
-                                                                glm::vec3(0.0f, 1.0f, 0.0f));  // up vector
-
        glm::mat4 ortho = projection * view;
 
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -316,30 +321,10 @@ void render() {
        // draw the debug overlay if desired
        if (ui::debug) {
                auto pos = game::engine.getSystem<PlayerSystem>()->getPosition();
-               ui::putText(offset.x - SCREEN_WIDTH / 2, (offset.y + SCREEN_HEIGHT / 2) - ui::fontSize,
-                           "loc: (%+.2f, %+.2f)\noffset: (%+.2f, %+.2f)\nfps: %d\nticks: %d\nxml: %s",
-                                       pos.x,
-                                       pos.y,
-                                       offset.x,
-                                       offset.y,
-                                       fps,
-                                       game::time::getTickCount(),
-                                       game::engine.getSystem<WorldSystem>()->getXMLFile().c_str()
-                           );
-               /*ui::putText(offset.x-SCREEN_WIDTH/2, (offset.y+SCREEN_HEIGHT/2)-ui::fontSize,
-                                       "fps: %d\ngrounded:%d\nresolution: %ux%u\nentity cnt: %d\nloc: (%+.2f, %+.2f)\nticks: %u\nvolume: %f\nweather: %s\nxml: %s",
-                                       fps,
-                                       0,//player->ground,
-                                       SCREEN_WIDTH,                           // Window dimensions
-                                       SCREEN_HEIGHT,                          //
-                                       0,//currentWorld->entity.size(),// Size of entity array
-                                       0,//player->loc.x,                              // The player's x coordinate
-                                       debugY,                                         // The player's y coordinate
-                                       game::time::getTickCount(),
-                                       game::config::VOLUME_MASTER,
-                                       game::engine.getSystem<WorldSystem>()->getWeatherStr().c_str(),
-                                       ""//currentXML.c_str()
-                               );*/
+               ui::putText(offset.x - SCREEN_WIDTH2, (offset.y + SCREEN_HEIGHT2) - ui::fontSize,
+                           "loc: %s\noffset: %s\nfps: %d\nticks: %d\nxml: %s",
+                                       pos.toString().c_str(), offset.toString().c_str(), fps,
+                                       game::time::getTickCount(), game::engine.getSystem<WorldSystem>()->getXMLFile().c_str());
        }
 
        // draw the menu
@@ -349,108 +334,8 @@ void render() {
        // draw the mouse
        Render::textShader.use();
                glActiveTexture(GL_TEXTURE0);
-               glBindTexture(GL_TEXTURE_2D, mouseTex);
+               mouseTex.use();
                Render::useShader(&Render::textShader);
                Render::drawRect(ui::mouse, ui::mouse + 15, -9.9);
        Render::textShader.unuse();
 }
-
-void logic(){
-//     static bool NPCSelected    = false;
-//     static bool ObjectSelected = false;
-
-       // exit the game if the player falls out of the world
-       /*if (player->loc.y < 0)
-               game::endGame();*/
-
-       /*if (player->inv->usingi) {
-               for (auto &e : currentWorld->entity) {
-                       if (player->inv->usingi && !e->isHit() &&
-                               player->inv->detectCollision(vec2 { e->loc.x, e->loc.y }, vec2 { e->loc.x + e->width, e->loc.y + e->height})) {
-                               e->takeHit(25, 10);
-                               break;
-                       }
-               }
-               player->inv->usingi = false;
-       }*/
-
-       /*for (auto &e : currentWorld->entity) {
-               if (e->isAlive() && ((e->type == NPCT) || (e->type == MERCHT) || (e->type == OBJECTT))) {
-                       if (e->type == OBJECTT && ObjectSelected) {
-                               e->near = false;
-                               continue;
-                       } else if (e->canMove) {
-                               if (!currentWorld->goWorldLeft(dynamic_cast<NPC *>(e)))
-                                       currentWorld->goWorldRight(dynamic_cast<NPC *>(e));
-                               e->wander((rand() % 120 + 30));
-                               if (NPCSelected) {
-                                       e->near = false;
-                                       continue;
-                               }
-                       }
-
-                       if(e->isInside(ui::mouse) && player->isNear(e)) {
-                               e->near = true;
-                               if (e->type == OBJECTT)
-                                       ObjectSelected = true;
-                               else
-                                       NPCSelected = true;
-
-                               if ((SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)) && !ui::dialogBoxExists) {
-                                       if (ui::mouse.x < player->loc.x && player->right)
-                                               player->left = true, player->right = false;
-                                       else if(ui::mouse.x > player->loc.x && player->left)
-                                               player->right = true, player->left = false;
-                                       e->interact();
-                               }
-                       } else {
-                               e->near = false;
-                       }
-               } else if (e->type == MOBT) {
-                       e->near = player->isNear(e);
-                       e->wander();
-               }
-       }*/
-
-       // calculate the world shading value
-       worldShade = 50 * sin((game::time::getTickCount() + (DAY_CYCLE / 2)) / (DAY_CYCLE / PI));
-
-       // update fades
-       ui::fadeUpdate();
-
-       // create weather particles if necessary
-       /*auto weather = game::engine.getSystem<WorldSystem>()->getWeatherId();
-       auto worldWidth = game::engine.getSystem<WorldSystem>()->getWidth();
-       if (weather == WorldWeather::Rain) {
-               for (unsigned int r = (randGet() % 25) + 11; r--;) {
-                       currentWorld->addParticle(randGet() % worldWidth - (worldWidth / 2),
-                                                                         offset.y + game::SCREEN_HEIGHT / 2,
-                                                                         HLINES(1.25),                                                                         // width
-                                                                         HLINES(1.25),                                                                         // height
-                                                                         randGet() % 7 * .01 * (randGet() % 2 == 0 ? -1 : 1),  // vel.x
-                                                                         (4 + randGet() % 6) * .05,                                                    // vel.y
-                                                                         { 0, 0, 255 },                                                                                // RGB color
-                                                                         2500,                                                                                         // duration (ms)
-                                                                         (1 << 0) | (1 << 1)                                                                   // gravity and bounce
-                                                                         );
-               }
-       } else if (weather == WorldWeather::Snowy) {
-               for (unsigned int r = (randGet() % 25) + 11; r--;) {
-                       currentWorld->addParticle(randGet() % worldWidth - (worldWidth / 2),
-                                                                         offset.y + game::SCREEN_HEIGHT / 2,
-                                                                         HLINES(1.25),                                                                         // width
-                                                                         HLINES(1.25),                                                                         // height
-                                                       .0001 + randGet() % 7 * .01 * (randGet() % 2 == 0 ? -1 : 1),    // vel.x
-                                                                         (4 + randGet() % 6) * -.03,                                                   // vel.y
-                                                                         { 255, 255, 255 },                                                                    // RGB color
-                                                                         5000,                                                                                         // duration (ms)
-                                                                         0                                                                                                     // no gravity, no bounce
-                                                                         );
-               }
-       }*/
-
-       // increment game ticker
-       game::time::tick();
-       //NPCSelected = false;
-       //ObjectSelected = false;
-}
index a398bece24c3a12fa8b51ef6933b48cb26e3fc16..8a66f80ed90845b0911ffc38025f80096c5d7064 100644 (file)
@@ -52,11 +52,11 @@ void PhysicsSystem::update(entityx::EntityManager &en, entityx::EventManager &ev
        });
 }
 
-GLuint RenderSystem::loadTexture(const std::string& file)
+Texture RenderSystem::loadTexture(const std::string& file)
 {
        loadTexString = file;
-       loadTexResult = 0xFFFF;
-       while (loadTexResult == 0xFFFF)
+       loadTexResult = Texture();
+       while (loadTexResult.isEmpty())
                std::this_thread::sleep_for(std::chrono::milliseconds(1));
        return loadTexResult;
 }
@@ -66,7 +66,7 @@ void RenderSystem::update(entityx::EntityManager &en, entityx::EventManager &ev,
        (void)ev;
 
        if (!loadTexString.empty()) {
-               loadTexResult = Texture::loadTexture(loadTexString);
+               loadTexResult = Texture(loadTexString);
                loadTexString.clear();
        }
 
@@ -95,17 +95,16 @@ void RenderSystem::update(entityx::EntityManager &en, entityx::EventManager &ev,
                }
 
                for (auto &S : sprite.sprite) {
-                       float width = HLINES(S.first.size.x);
-                       float height = HLINES(S.first.size.y);
+                       const auto& size = S.first.tex.getDim() * game::HLINE;
 
                        vec2 loc = vec2(pos.x + S.first.offset.x, pos.y + S.first.offset.y);
 
                        GLfloat coords[] = {loc.x,                      loc.y,                  visible.z,
-                                                               loc.x + width,  loc.y,                  visible.z,
-                                                               loc.x + width,  loc.y + height, visible.z,
+                                                               loc.x + size.x, loc.y,                  visible.z,
+                                                               loc.x + size.x, loc.y + size.y, visible.z,
 
-                                                               loc.x + width,  loc.y + height, visible.z,
-                                                               loc.x,                  loc.y + height, visible.z,
+                                                               loc.x + size.x, loc.y + size.y, visible.z,
+                                                               loc.x,                  loc.y + size.y, visible.z,
                                                                loc.x,                  loc.y,                  visible.z};
 
 
@@ -116,7 +115,7 @@ void RenderSystem::update(entityx::EntityManager &en, entityx::EventManager &ev,
                                glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, flashAmt, flashAmt, 1.0);
                        }*/
 
-                       glBindTexture(GL_TEXTURE_2D, S.first.pic);
+                       S.first.tex.use();
 
                        glUniform1i(Render::worldShader.uniform[WU_texture], 0);
                        Render::worldShader.enable();
@@ -270,7 +269,7 @@ std::vector<Frame> developFrame(XMLElement* xml)
                                std::string sname = sxml->Name();
                                if (sname == "src") {
                                        tmpf.push_back(std::make_pair(SpriteData(sxml->GetText(), vec2(0,0)), vec2(0,0)));
-                                       std::cout << tmpf.back().first.pic << std::endl;
+                                       //std::cout << tmpf.back().first.pic << std::endl;
                                }
                                sxml = sxml->NextSiblingElement();
                        }
index e5b2b36391324dc24fa4a373ed44e8659be5c342..b42b1625fefe6044c88ce527fd8e7f43561897f7 100644 (file)
@@ -60,7 +60,7 @@ void Engine::update(entityx::TimeDelta dt)
 namespace game {
        entityx::EventManager events;
        entityx::EntityManager entities (events);
-       SpriteLoader sprite_l;
+       //SpriteLoader sprite_l;
 
     Engine engine;
 }
index 91e81daedb5f16f5c2dafc5e65d8c3a0ab4803c3..fb999ea54ca20588d35a0ddc3ac47cffdd321908 100644 (file)
@@ -7,7 +7,7 @@
 
 constexpr const char* ICON_TEX_FILE_PATH = "config/invIcons.txt";
 
-static std::vector<GLuint> iconTextures;
+static std::vector<Texture> iconTextures;
 
 void InventorySystem::configure(entityx::EventManager &ev)
 {
@@ -18,7 +18,7 @@ void InventorySystem::loadIcons(void) {
     iconTextures.clear();
     auto icons = readFileA(ICON_TEX_FILE_PATH);
     for (const auto& s : icons)
-        iconTextures.push_back(Texture::loadTexture(s));
+        iconTextures.push_back(s);
 }
 
 void InventorySystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt)
@@ -27,14 +27,13 @@ void InventorySystem::update(entityx::EntityManager &en, entityx::EventManager &
     (void)ev;
     (void)dt;
 
-    static auto color = Texture::genColor(Color(0, 0, 0));
     vec2 start = vec2(offset.x, 100);// - game::SCREEN_WIDTH / 2 + 20, game::SCREEN_HEIGHT - 40);
 
     //std::cout << start.x << ' ' << start.y << std::endl;
 
     Render::textShader.use();
         glActiveTexture(GL_TEXTURE0);
-        glBindTexture(GL_TEXTURE_2D, color);
+        Colors::black.use();
         Render::useShader(&Render::textShader);
         Render::drawRect(start, start + 20, -9.9f);
     Render::textShader.unuse();
index a232e0e2157df3e17899f1ccee3f4c2e5a382b30..640b06e1af24a21a2eaba1238a9b71413421e0da 100644 (file)
 
 #include <texture.hpp>
 
-/**
- * A structure for keeping track of loaded textures.
- */
-
-typedef struct {
-       std::string name;       /**< The file path of the texture.              */
-       GLuint tex;                     /**< The GLuint for the loaded texture. */
-       dim2 dim;                       /**< The dimensions of the texture.             */
-} texture_t;
+namespace Colors
+{
+       ColorTex white;
+       ColorTex black;
+       ColorTex red;
+
+       void init(void) {
+               white = ColorTex(Color(255, 255, 255));
+               black = ColorTex(Color(0, 0, 0));
+               red = ColorTex(Color(255, 0, 0));
+       }
+}
 
-struct index_t {
-       Color color;
-       int indexx;
-       int indexy;
-};
+void loadTexture(const std::string& file, Texture& texture);
 
-// convert any type to octal
-template <typename T>
-uint toOctal(T toConvert)
+Texture::Texture(const std::string& file, const GLuint& t, const vec2& v)
+       : name(file), tex(t), dim(v)
 {
-    int n = 0;
-    uint t = 0;
-    while (toConvert > 0) {
-        t += (pow(10, n++)) * (static_cast<int>(toConvert) % 8);
-        toConvert /= 8;
-    }
-    return t;
+       if (t == 0xFFFFF && !file.empty())
+               loadTexture(file, *this);
 }
 
-/**
- * A vector of all loaded textures.
- *
- * Should a texture be asked to be loaded twice, loadTexture() can reference
- * this array and reuse GLuint's to save memory.
- */
+const std::string& Texture::getName(void) const
+{
+       return name;
+}
 
-static std::vector<texture_t> LoadedTexture;
+const vec2& Texture::getDim(void) const
+{
+       return dim;
+}
 
-namespace Texture{
-       Color pixels[8][4];
+ColorTex::ColorTex(void)
+{
+       Texture();
+}
 
-       GLuint loadTexture(std::string fileName) {
-               SDL_Surface *image;
+ColorTex::ColorTex(const Color& color)
+{
+       unsigned char data[4] = {
+               static_cast<unsigned char>(color.red),
+               static_cast<unsigned char>(color.green),
+               static_cast<unsigned char>(color.blue),
+               static_cast<unsigned char>(color.alpha),
+       };
+
+       GLuint object;
+       glActiveTexture(GL_TEXTURE0);
+       glGenTextures(1, &object);                              // Turns "object" into a texture
+       glBindTexture(GL_TEXTURE_2D, object);   // Binds "object" to the top of the stack
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
+       Texture("", object, vec2());
+}
 
-               // check if texture is already loaded
-               for(auto &t : LoadedTexture) {
-                       if (t.name == fileName) {
+static std::vector<Texture> loadedTextures;
 
-#ifdef DEBUG
-                               DEBUG_printf("Reusing loaded texture for %s\n", fileName.c_str());
-#endif // DEBUG
-
-                               return t.tex;
-                       }
-               }
+void loadTexture(const std::string& file, Texture& texture)
+{
+       auto preloaded =
+               std::find_if(std::begin(loadedTextures), std::end(loadedTextures),
+               [&file](const Texture& t) { return (t.getName() == file); });
 
-               // load SDL_surface of texture
-               if (!(image = IMG_Load(fileName.c_str())))
-                       return 0;
+       if (preloaded == std::end(loadedTextures)) {
+               auto image = IMG_Load(file.c_str());
+               if (image == nullptr)
+                       UserError("File not found: " + file);
 
 #ifdef DEBUG
-               DEBUG_printf("Loaded image file: %s\n", fileName.c_str());
+               DEBUG_printf("Loaded image file: %s\n", file.c_str());
 #endif // DEBUG
 
-               /*
-                * Load texture through OpenGL.
-                */
+               // load texture through OpenGL
                GLuint object;
                glGenTextures(1, &object);                              // Turns "object" into a texture
                glBindTexture(GL_TEXTURE_2D, object);   // Binds "object" to the top of the stack
-               glPixelStoref(GL_UNPACK_ALIGNMENT,1);
-
+               glPixelStoref(GL_UNPACK_ALIGNMENT, 1);
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);      // Sets the "min" filter
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);      // The the "max" filter of the stack
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // Wrap the texture to the matrix
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); //
-               glTexImage2D(GL_TEXTURE_2D,  // Sets the texture to the image file loaded above
-                                        0,
-                                        GL_RGBA,
-                                        image->w,
-                                        image->h,
-                                        0,
-                                        GL_RGBA,
-                                        GL_UNSIGNED_BYTE,
-                                        image->pixels
-                                       );
+               glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->w, image->h, 0,
+                                        GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
+
+               // add texture to loadedTextures
+               loadedTextures.emplace_back(file, object, vec2(image->w, image->h));
 
-               // add texture to LoadedTexture
-               LoadedTexture.push_back(texture_t{fileName,object,{image->w,image->h}});
+               texture = loadedTextures.back();
 
                // free the SDL_Surface
                SDL_FreeSurface(image);
-
-               return object;
-       }
-
-    GLuint genColor(Color c)
-    {
-        std::string out;
-
-        // add the red
-        out += static_cast<int>(c.red);
-
-        // add the green
-        out += static_cast<int>(c.green);
-
-        // add the blue
-        out += static_cast<int>(c.blue);
-
-        // add the alpha
-        out += static_cast<int>(c.alpha);
-
-        GLuint object;
-
-        glActiveTexture(GL_TEXTURE0);
-        glGenTextures(1,&object);                              // Turns "object" into a texture
-               glBindTexture(GL_TEXTURE_2D,object);    // Binds "object" to the top of the stack
-               //glPixelStorei(GL_UNPACK_ALIGNMENT,1);
-
-               //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);    // Sets the "min" filter
-               //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);    // The the "max" filter of the stack
-
-               //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // Wrap the texture to the matrix
-               //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); //
-
-               glTexImage2D(GL_TEXTURE_2D,     // Sets the texture to the image file loaded above
-                                        0,                 // level
-                                        GL_RGBA,           // internal format
-                                        1,                 // width
-                                        1,                 // height
-                                        0,                 // border
-                                        GL_RGBA,           // image format
-                                        GL_UNSIGNED_BYTE,  // type
-                                        out.data()         // source
-                                       );
-
-        return object;
-    }
-
-       vec2 imageDim(std::string fileName) {
-               for(auto &t : LoadedTexture) {
-                       if (t.name == fileName)
-                               return vec2(t.dim.x, t.dim.y);
-               }
-               return vec2(0,0);
-       }
-
-       void freeTextures(void) {
-               while(!LoadedTexture.empty()) {
-                       glDeleteTextures(1, &LoadedTexture.back().tex);
-                       LoadedTexture.pop_back();
-               }
-       }
-
-       #define CINDEX_WIDTH (8*4*3)
-       void initColorIndex() {
-               unsigned int i;
-               GLubyte *buffer;
-               GLfloat *bufferf;
-
-               buffer  = new GLubyte[CINDEX_WIDTH];
-               bufferf = new GLfloat[CINDEX_WIDTH];
-
-               colorIndex = loadTexture("assets/colorIndex.png");
-               glActiveTexture(GL_TEXTURE0);
-               glBindTexture(GL_TEXTURE_2D, colorIndex);
-               glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);
-
-               for(i = 0; i < CINDEX_WIDTH; i++)
-                       bufferf[i] = (float)buffer[i] / 255.0f;
-
-               i = 0;
-               for(unsigned int y = 0; y < 8; y++) {
-                       for(unsigned int x = 0; x < 4; x++) {
-                                       if (i >= CINDEX_WIDTH) {
-                                               delete[] buffer;
-                                               delete[] bufferf;
-                                               return;
-                                       }
-                                       pixels[y][x].red = buffer[i++];
-                                       pixels[y][x].green = buffer[i++];
-                                       pixels[y][x].blue = buffer[i++];
-                       }
-               }
-               delete[] buffer;
-               delete[] bufferf;
-       }
-
-       //sqrt((255-145)^2+(90-145)^2+(0-0)^2);
-       std::vector<index_t>ind;
-       vec2 getIndex(Color c) {
-               for(auto &i : ind) {
-                       if (c.red == i.color.red && c.green == i.color.green && c.blue == i.color.blue) {
-                               return {float(i.indexx), float(i.indexy)};
-                       }
-               }
-               uint buf[2];
-               float buff = 999;
-               float shit = 999;
-               for(uint y = 0; y < 8; y++) {
-                       for(uint x = 0; x < 4; x++) {
-                               buff = sqrt(pow((pixels[y][x].red-      c.red),  2)+
-                                                       pow((pixels[y][x].green-c.green),2)+
-                                                       pow((pixels[y][x].blue- c.blue), 2));
-                               if (buff < shit) {
-                                       shit = buff;
-                                       buf[0] = y;
-                                       buf[1] = x;
-                               }
-                       }
-               }
-               ind.push_back({c, (int)buf[1], (int)buf[0]});
-               return {float(buf[1]),float(buf[0])};
+       } else {
+               texture = *preloaded;
        }
 }
 
-Texturec::Texturec(uint amt, ...) {
-       va_list fNames;
-       texState = 0;
-       va_start(fNames, amt);
-       for (unsigned int i = 0; i < amt; i++) {
-               std::string l = va_arg(fNames, char *);
-               image.push_back(Texture::loadTexture(l));
-               texLoc.push_back(l);
-       }
-       va_end(fNames);
-}
 
-Texturec::Texturec(std::initializer_list<std::string> l)
+TextureIterator::TextureIterator(const std::vector<std::string> &l)
 {
-       texState = 0;
-       std::for_each(l.begin(), l.end(), [&](std::string s) { image.push_back(Texture::loadTexture(s)); texLoc.push_back(s);});
+       for (const auto& s : l)
+               textures.emplace_back(s);
+       position = std::begin(textures);
 }
 
-Texturec::Texturec(std::vector<std::string>v) {
-       texState = 0;
-       std::for_each(v.begin(), v.end(), [&](std::string s) { image.push_back(Texture::loadTexture(s)); texLoc.push_back(s);});
+void TextureIterator::operator++(int) noexcept
+{
+       if (++position >= std::end(textures))
+               position = std::end(textures) - 1;
+       position->use();
 }
 
-Texturec::Texturec(uint amt,const char **paths) {
-       texState = 0;
-       for (unsigned int i = 0; i < amt; i++) {
-               image.push_back(Texture::loadTexture(paths[i]));
-               texLoc.push_back(paths[i]);
-       }
+void TextureIterator::operator--(int) noexcept
+{
+       if (--position < std::begin(textures))
+               position = std::begin(textures);
+       position->use();
 }
 
-Texturec::~Texturec() {
-}
+void TextureIterator::operator()(const int &index)
+{
+       if (index < 0 || index > static_cast<int>(textures.size()))
+               throw std::invalid_argument("texture index out of range");
 
-void Texturec::bind(unsigned int bn) {
-       texState = bn;
-       glBindTexture(GL_TEXTURE_2D,image[(int)texState]);
+       position = std::begin(textures) + index;
+       position->use();
 }
 
-void Texturec::bindNext() {
-       bind(++texState);
-}
 
-void Texturec::bindPrev() {
-       bind(--texState);
+void unloadTextures(void)
+{
+       while (!loadedTextures.empty()) {
+               loadedTextures.back().destroy();
+               loadedTextures.pop_back();
+       }
 }
+
index 1994382b3cf882baa0e4ce055b955d9460b938f2..e87c74af5d241830b6984ea723cde624f8d71d03 100644 (file)
@@ -667,11 +667,8 @@ namespace ui {
                              0,1,
                              0,0};
 
-        static GLuint boxT = Texture::genColor(Color(0,0,0));
-        static GLuint lineT = Texture::genColor(Color(255,255,255));
-
         glActiveTexture(GL_TEXTURE0);
-        glBindTexture(GL_TEXTURE_2D, boxT);
+               Colors::black.use();
         glUniform1i(Render::textShader.uniform[WU_texture], 0);
 
         Render::textShader.use();
@@ -681,7 +678,7 @@ namespace ui {
         glVertexAttribPointer(Render::textShader.tex, 2, GL_FLOAT, GL_FALSE, 0, box_tex);
         glDrawArrays(GL_TRIANGLES, 0 ,6);
 
-        glBindTexture(GL_TEXTURE_2D, lineT);
+        Colors::white.use();
         glUniform1i(Render::textShader.uniform[WU_texture], 0);
 
         glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, 0, line_strip);
@@ -698,13 +695,13 @@ namespace ui {
 
        void drawNiceBoxColor(vec2 c1, vec2 c2, float z, Color c) {
                // the textures for the box corners
-               static GLuint box_corner =              Texture::loadTexture("assets/ui/button_corners.png");
-               static GLuint box_side_top =    Texture::loadTexture("assets/ui/button_top_bot_borders.png");
-               static GLuint box_side =                Texture::loadTexture("assets/ui/button_side_borders.png");
+               static Texture boxCorner  ("assets/ui/button_corners.png");
+               static Texture boxSideTop ("assets/ui/button_top_bot_borders.png");
+               static Texture boxSide    ("assets/ui/button_side_borders.png");
 
                // the dimensions of the corner textures
-               static vec2 box_corner_dim_t =  Texture::imageDim("assets/ui/button_corners.png");
-               static vec2 box_corner_dim = vec2(box_corner_dim_t.x / 2.0, box_corner_dim_t.y / 2.0);
+               static const auto& boxCornerDim  = boxCorner.getDim();
+               static const auto& boxCornerDim2 = boxCornerDim / 2;
 
                // the amount of bytes to skip in the OpenGL arrays (see below)
                auto stride = 5 * sizeof(GLfloat);
@@ -714,81 +711,80 @@ namespace ui {
                if (c1.y > c2.y) c1.swapY(c2); // std::swap(c1.y, c2.y);
 
                // if the box is too small, we will not be able to draw it
-               if (c2.x - c1.x < (box_corner_dim_t.x)) return;
-               if (c2.y - c1.y < (box_corner_dim_t.y)) return;
-
+               if (c2.x - c1.x < (boxCornerDim.x) || c2.y - c1.y < (boxCornerDim.y))
+                       return;
 
-               GLfloat box_ul[] = {c1.x,                                               c2.y - box_corner_dim.y, z,     0.0f, 0.5f,
-                               c1.x + box_corner_dim.x,        c2.y - box_corner_dim.y, z,     0.5f, 0.5f,
-                               c1.x + box_corner_dim.x,        c2.y,                                    z,     0.5f, 1.0f,
+               GLfloat box_ul[] = {c1.x,                                               c2.y - boxCornerDim2.y, z,      0.0f, 0.5f,
+                               c1.x + boxCornerDim2.x,         c2.y - boxCornerDim2.y, z,      0.5f, 0.5f,
+                               c1.x + boxCornerDim2.x, c2.y,                               z,  0.5f, 1.0f,
 
-                               c1.x + box_corner_dim.x,        c2.y,                                    z, 0.5f, 1.0f,
-                                       c1.x,                                           c2.y,                                    z, 0.0f, 1.0f,
-                               c1.x,                                           c2.y - box_corner_dim.y, z,     0.0f, 0.5f};
+                               c1.x + boxCornerDim2.x, c2.y,                                   z, 0.5f, 1.0f,
+                                       c1.x,                                           c2.y,                                   z, 0.0f, 1.0f,
+                               c1.x,                                           c2.y - boxCornerDim2.y, z,      0.0f, 0.5f};
 
-               GLfloat box_ll[] = {c1.x,                                               c1.y,                                    z,     0.0f, 0.0f,
-                               c1.x + box_corner_dim.x,        c1.y,                                    z,     0.5f, 0.0f,
-                               c1.x + box_corner_dim.x,        c1.y + box_corner_dim.y, z,     0.5f, 0.5f,
+               GLfloat box_ll[] = {c1.x,                                               c1.y,                                   z,      0.0f, 0.0f,
+                               c1.x + boxCornerDim2.x,         c1.y,                                   z,      0.5f, 0.0f,
+                               c1.x + boxCornerDim2.x, c1.y + boxCornerDim2.y, z,      0.5f, 0.5f,
 
-                               c1.x + box_corner_dim.x,        c1.y + box_corner_dim.y, z, 0.5f, 0.5f,
-                                       c1.x,                                           c1.y + box_corner_dim.y, z, 0.0f, 0.5f,
-                               c1.x,                                           c1.y,                                    z,     0.0f, 0.0f};
+                               c1.x + boxCornerDim2.x, c1.y + boxCornerDim2.y, z, 0.5f, 0.5f,
+                                       c1.x,                                           c1.y + boxCornerDim2.y, z, 0.0f, 0.5f,
+                               c1.x,                                           c1.y,                                   z, 0.0f, 0.0f};
 
-               GLfloat box_ur[] = {c2.x - box_corner_dim.x,    c2.y - box_corner_dim.y, z,     0.5f, 0.5f,
-                               c2.x,                                           c2.y - box_corner_dim.y, z,     1.0f, 0.5f,
+               GLfloat box_ur[] = {c2.x - boxCornerDim2.x,     c2.y - boxCornerDim2.y, z,      0.5f, 0.5f,
+                               c2.x,                                           c2.y - boxCornerDim2.y, z,      1.0f, 0.5f,
                                c2.x,                                           c2.y,                                    z,     1.0f, 1.0f,
 
                                c2.x,                                           c2.y,                                    z, 1.0f, 1.0f,
-                                       c2.x - box_corner_dim.x,        c2.y,                                    z, 0.5f, 1.0f,
-                               c2.x - box_corner_dim.x,        c2.y - box_corner_dim.y, z,     0.5f, 0.5f};
+                                       c2.x - boxCornerDim2.x,         c2.y,                                    z, 0.5f, 1.0f,
+                               c2.x - boxCornerDim2.x,         c2.y - boxCornerDim2.y, z,      0.5f, 0.5f};
 
-               GLfloat box_lr[] = {c2.x - box_corner_dim.x,    c1.y,                                    z,     0.5f, 0.0f,
+               GLfloat box_lr[] = {c2.x - boxCornerDim2.x,     c1.y,                                    z,     0.5f, 0.0f,
                                c2.x,                                           c1.y,                                    z,     1.0f, 0.0f,
-                               c2.x,                                           c1.y + box_corner_dim.y, z,     1.0f, 0.5f,
+                               c2.x,                                           c1.y + boxCornerDim2.y, z,      1.0f, 0.5f,
 
-                               c2.x,                                           c1.y + box_corner_dim.y, z, 1.0f, 0.5f,
-                                       c2.x - box_corner_dim.x,        c1.y + box_corner_dim.y, z, 0.0f, 0.5f,
-                               c2.x - box_corner_dim.x,        c1.y,                                    z,     0.5f, 0.0f};
+                               c2.x,                                           c1.y + boxCornerDim2.y, z, 1.0f, 0.5f,
+                                       c2.x - boxCornerDim2.x,         c1.y + boxCornerDim2.y, z, 0.0f, 0.5f,
+                               c2.x - boxCornerDim2.x,         c1.y,                                    z,     0.5f, 0.0f};
 
-               GLfloat box_l[] =  {c1.x,                                               c1.y + box_corner_dim.y, z, 0.0f, 0.0f,
-                                                       c1.x + box_corner_dim.x,        c1.y + box_corner_dim.y, z, 0.5f, 0.0f,
-                                                       c1.x + box_corner_dim.x,        c2.y - box_corner_dim.y, z, 0.5f, 1.0f,
+               GLfloat box_l[] =  {c1.x,                                               c1.y + boxCornerDim2.y, z, 0.0f, 0.0f,
+                                                       c1.x + boxCornerDim2.x, c1.y + boxCornerDim2.y, z, 0.5f, 0.0f,
+                                                       c1.x + boxCornerDim2.x, c2.y - boxCornerDim2.y, z, 0.5f, 1.0f,
 
-                                                       c1.x + box_corner_dim.x,        c2.y - box_corner_dim.y, z, 0.5f, 1.0f,
-                                                       c1.x,                                           c2.y - box_corner_dim.y, z, 0.0f, 1.0f,
-                                                       c1.x,                                           c1.y + box_corner_dim.y, z, 0.0f, 0.0f};
+                                                       c1.x + boxCornerDim2.x, c2.y - boxCornerDim2.y, z, 0.5f, 1.0f,
+                                                       c1.x,                                           c2.y - boxCornerDim2.y, z, 0.0f, 1.0f,
+                                                       c1.x,                                           c1.y + boxCornerDim2.y, z, 0.0f, 0.0f};
 
-               GLfloat box_r[] =  {c2.x - box_corner_dim.x,    c1.y + box_corner_dim.y, z, 0.5f, 0.0f,
-                                                       c2.x,                                           c1.y + box_corner_dim.y, z, 1.0f, 0.0f,
-                                                       c2.x,                                           c2.y - box_corner_dim.y, z, 1.0f, 1.0f,
+               GLfloat box_r[] =  {c2.x - boxCornerDim2.x,     c1.y + boxCornerDim2.y, z, 0.5f, 0.0f,
+                                                       c2.x,                                           c1.y + boxCornerDim2.y, z, 1.0f, 0.0f,
+                                                       c2.x,                                           c2.y - boxCornerDim2.y, z, 1.0f, 1.0f,
 
-                                                       c2.x,                                           c2.y - box_corner_dim.y, z, 1.0f, 1.0f,
-                                                       c2.x - box_corner_dim.x,        c2.y - box_corner_dim.y, z, 0.5f, 1.0f,
-                                                       c2.x - box_corner_dim.x,        c1.y + box_corner_dim.y, z, 0.5f, 0.0f};
+                                                       c2.x,                                           c2.y - boxCornerDim2.y, z, 1.0f, 1.0f,
+                                                       c2.x - boxCornerDim2.x, c2.y - boxCornerDim2.y, z, 0.5f, 1.0f,
+                                                       c2.x - boxCornerDim2.x, c1.y + boxCornerDim2.y, z, 0.5f, 0.0f};
 
-        GLfloat box_b[] =  {c1.x + box_corner_dim.x,   c1.y,                                    z,     0.0f, 0.0f,
-                                                       c2.x - box_corner_dim.x,        c1.y,                                    z, 1.0f, 0.0f,
-                                                       c2.x - box_corner_dim.x,        c1.y + box_corner_dim.y, z,     1.0f, 0.5f,
+        GLfloat box_b[] =  {c1.x + boxCornerDim2.x,    c1.y,                                    z,     0.0f, 0.0f,
+                                                       c2.x - boxCornerDim2.x, c1.y,                                    z, 1.0f, 0.0f,
+                                                       c2.x - boxCornerDim2.x, c1.y + boxCornerDim2.y, z,      1.0f, 0.5f,
 
-                                                       c2.x - box_corner_dim.x,        c1.y + box_corner_dim.y, z,     1.0f, 0.5f,
-                                                       c1.x + box_corner_dim.x,        c1.y + box_corner_dim.y, z, 0.0f, 0.5f,
-                                                       c1.x + box_corner_dim.x,        c1.y,                                    z, 0.0f, 0.0f};
+                                                       c2.x - boxCornerDim2.x, c1.y + boxCornerDim2.y, z,      1.0f, 0.5f,
+                                                       c1.x + boxCornerDim2.x, c1.y + boxCornerDim2.y, z, 0.0f, 0.5f,
+                                                       c1.x + boxCornerDim2.x, c1.y,                                    z, 0.0f, 0.0f};
 
-        GLfloat box_t[] =  {c1.x + box_corner_dim.x,   c2.y - box_corner_dim.y, z,     0.0f, 0.5f,
-                                                       c2.x - box_corner_dim.x,        c2.y - box_corner_dim.y, z, 1.0f, 0.5f,
-                                                       c2.x - box_corner_dim.x,        c2.y,                                    z,     1.0f, 1.0f,
+        GLfloat box_t[] =  {c1.x + boxCornerDim2.x,    c2.y - boxCornerDim2.y, z,      0.0f, 0.5f,
+                                                       c2.x - boxCornerDim2.x, c2.y - boxCornerDim2.y, z, 1.0f, 0.5f,
+                                                       c2.x - boxCornerDim2.x, c2.y,                                    z,     1.0f, 1.0f,
 
-                                                       c2.x - box_corner_dim.x,        c2.y,                                    z,     1.0f, 1.0f,
-                                                       c1.x + box_corner_dim.x,        c2.y,                                    z, 0.0f, 1.0f,
-                                                       c1.x + box_corner_dim.x,        c2.y - box_corner_dim.y, z, 0.0f, 0.5f};
+                                                       c2.x - boxCornerDim2.x, c2.y,                                    z,     1.0f, 1.0f,
+                                                       c1.x + boxCornerDim2.x, c2.y,                                    z, 0.0f, 1.0f,
+                                                       c1.x + boxCornerDim2.x, c2.y - boxCornerDim2.y, z, 0.0f, 0.5f};
 
-               GLfloat box_f[] =  {c1.x + box_corner_dim.x,    c1.y + box_corner_dim.y, z, 0.5f, 0.5f,
-                                                       c2.x - box_corner_dim.x,        c1.y + box_corner_dim.y, z, 0.5f, 0.5f,
-                                                       c2.x - box_corner_dim.x,        c2.y - box_corner_dim.y, z, 0.5f, 0.5f,
+               GLfloat box_f[] =  {c1.x + boxCornerDim2.x,     c1.y + boxCornerDim2.y, z, 0.5f, 0.5f,
+                                                       c2.x - boxCornerDim2.x, c1.y + boxCornerDim2.y, z, 0.5f, 0.5f,
+                                                       c2.x - boxCornerDim2.x, c2.y - boxCornerDim2.y, z, 0.5f, 0.5f,
 
-                                                       c2.x - box_corner_dim.x,        c2.y - box_corner_dim.y, z, 0.5f, 0.5f,
-                                                       c1.x + box_corner_dim.x,        c2.y - box_corner_dim.y, z, 0.5f, 0.5f,
-                                                       c1.x + box_corner_dim.x,        c1.y + box_corner_dim.y, z, 0.5f, 0.5f};
+                                                       c2.x - boxCornerDim2.x, c2.y - boxCornerDim2.y, z, 0.5f, 0.5f,
+                                                       c1.x + boxCornerDim2.x, c2.y - boxCornerDim2.y, z, 0.5f, 0.5f,
+                                                       c1.x + boxCornerDim2.x, c1.y + boxCornerDim2.y, z, 0.5f, 0.5f};
 
                glActiveTexture(GL_TEXTURE0);
                glUniform1f(Render::textShader.uniform[WU_texture], 0);
@@ -797,7 +793,7 @@ namespace ui {
                Render::textShader.enable();
 
                glUniform4f(Render::textShader.uniform[WU_tex_color], c.red, c.green, c.blue, c.alpha);
-               glBindTexture(GL_TEXTURE_2D, box_corner);
+               boxCorner.use();
 
                // draw upper left corner
         glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, stride, &box_ul[0]);
@@ -824,7 +820,7 @@ namespace ui {
         glVertexAttribPointer(Render::textShader.tex,   2, GL_FLOAT, GL_FALSE, stride, &box_f[3]);
         glDrawArrays(GL_TRIANGLES, 0, 6);
 
-               glBindTexture(GL_TEXTURE_2D, box_side);
+               boxSide.use();
 
                // draw the left edge of the box
                glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, stride, &box_l[0]);
@@ -836,7 +832,7 @@ namespace ui {
         glVertexAttribPointer(Render::textShader.tex,   2, GL_FLOAT, GL_FALSE, stride, &box_r[3]);
         glDrawArrays(GL_TRIANGLES, 0, 6);
 
-               glBindTexture(GL_TEXTURE_2D, box_side_top);
+               boxSideTop.use();
 
                // draw bottom of the box
                glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, stride, &box_b[0]);
@@ -1097,8 +1093,8 @@ EXIT:
                        return;
                }
 
-               auto fadeTex = Texture::genColor( (fadeWhite ? Color(255, 255, 255, fadeIntensity) :
-                                                              Color(0, 0, 0, fadeIntensity)) );
+               ColorTex fadeTex (fadeWhite ? Color(255, 255, 255, fadeIntensity) :
+                   Color(0, 0, 0, fadeIntensity));
 
 
         GLfloat tex[] = {0.0, 0.0,
@@ -1117,7 +1113,7 @@ EXIT:
                Render::textShader.use();
                Render::textShader.enable();
 
-               glBindTexture(GL_TEXTURE_2D, fadeTex);
+               fadeTex.use();
         glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, 0, backdrop);
         glVertexAttribPointer(Render::textShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex);
         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@@ -1127,7 +1123,7 @@ EXIT:
 
                setFontZ(-8.0);
 
-               glDeleteTextures(1, &fadeTex);
+               fadeTex.destroy();
     }
 
        void fadeUpdate(void) {
index 59b44e68b6578729f05ee882a9d01276c4d659b4..779feda3ff2f8326a8b93abc8457224e2e2269fd 100644 (file)
@@ -236,14 +236,13 @@ namespace ui {
             }
 
                        static float cMult = 1.0f;
-                       static GLuint backTex = Texture::genColor(Color(0, 0, 0, 204));
-                       //static GLuint bsTex = Texture::genColor(Color(30, 30, 30));
+                       static const ColorTex back (Color(0, 0, 0, 204));
 
                        //draw the dark transparent background
             glColor4f(0.0f, 0.0f, 0.0f, .8f);
                        Render::textShader.use();
 
-                       glBindTexture(GL_TEXTURE_2D, backTex);
+                       back.use();
                        Render::drawRect(vec2(offset.x - SCREEN_WIDTH / 2 - 1, offset.y - (SCREEN_HEIGHT / 2)),
                                         vec2(offset.x + SCREEN_WIDTH / 2, offset.y + (SCREEN_HEIGHT / 2)), -8.5);
 
index 68b8f345aa35d1621f2babf80f669b0a2111316b..059b6c706ac930ec10f69154461f29bc1da5baf9 100644 (file)
@@ -277,10 +277,11 @@ void WorldSystem::load(const std::string& file)
                        if (!world.indoor)
                                UserError("<house> can only be used inside <IndoorWorld>");
 
-                       world.indoorWidth = wxml->FloatAttribute("width");
-                       auto str = wxml->StrAttribute("texture");
-                       auto tex = render.loadTexture(str);
-                       world.indoorTex = tex;
+                       //world.indoorWidth = wxml->FloatAttribute("width");
+                       world.indoorTex = render.loadTexture(wxml->StrAttribute("texture"));
+                       //auto str = wxml->StrAttribute("texture");
+                       //auto tex = render.loadTexture(str);
+                       //world.indoorTex = tex;
                }
 
                // weather tag
@@ -855,26 +856,26 @@ void WorldSystem::render(void)
        // draw the remaining layers
        for (int i = 0; i < 4; i++) {
                bgTex++;
-               auto dim = bgTex.getTextureDim();
-               dim.x = HLINES(dim.x);
-               dim.y = HLINES(dim.y);
                auto xcoord = offset.x * bgDraw[i][2];
 
                bg_items.clear();
                bg_tex.clear();
 
+               vec2 dim = bgTex.getTextureDim() * game::HLINE;
+
                if (world.indoor && i == 3) {
-                       glBindTexture(GL_TEXTURE_2D, world.indoorTex);
+                       world.indoorTex.use();
 
                        const auto& startx = world.startX;
+                       dim = world.indoorTex.getDim() * game::HLINE;
 
-                       bg_items.emplace_back(startx,                     GROUND_HEIGHT_MINIMUM,         7 - (i * 0.1f));
-               bg_items.emplace_back(startx + world.indoorWidth, GROUND_HEIGHT_MINIMUM,             7 - (i * 0.1f));
-               bg_items.emplace_back(startx + world.indoorWidth, GROUND_HEIGHT_MINIMUM + dim.y, 7 - (i * 0.1f));
+                       bg_items.emplace_back(startx,         GROUND_HEIGHT_MINIMUM,         7 - (i * 0.1f));
+               bg_items.emplace_back(startx + dim.x, GROUND_HEIGHT_MINIMUM,         7 - (i * 0.1f));
+               bg_items.emplace_back(startx + dim.x, GROUND_HEIGHT_MINIMUM + dim.y, 7 - (i * 0.1f));
 
-               bg_items.emplace_back(startx + world.indoorWidth, GROUND_HEIGHT_MINIMUM + dim.y, 7 - (i * 0.1f));
-               bg_items.emplace_back(startx,                     GROUND_HEIGHT_MINIMUM + dim.y, 7 - (i * 0.1f));
-               bg_items.emplace_back(startx,                     GROUND_HEIGHT_MINIMUM,         7 - (i * 0.1f));
+               bg_items.emplace_back(startx + dim.x, GROUND_HEIGHT_MINIMUM + dim.y, 7 - (i * 0.1f));
+               bg_items.emplace_back(startx,         GROUND_HEIGHT_MINIMUM + dim.y, 7 - (i * 0.1f));
+               bg_items.emplace_back(startx,         GROUND_HEIGHT_MINIMUM,         7 - (i * 0.1f));
                } else {
                        for (int j = world.startX; j <= -world.startX; j += dim.x) {
                    bg_items.emplace_back(j         + xcoord, GROUND_HEIGHT_MINIMUM,         7 - (i * 0.1f));
@@ -1041,11 +1042,10 @@ void WorldSystem::render(void)
                // the ending pixel of the world
                static const float e = static_cast<float>(SCREEN_WIDTH) / 2.0f;
 
-               static const auto blackTex = Texture::genColor(Color(0, 0, 0));
                static const float sheight = static_cast<float>(SCREEN_HEIGHT);
 
                if (offset.x + world.startX > s) {
-                       glBindTexture(GL_TEXTURE_2D, blackTex);
+                       Colors::black.use();
                        glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.0f);
 
                        GLfloat blackBarLeft[] = {
@@ -1064,7 +1064,7 @@ void WorldSystem::render(void)
                }
 
                if (offset.x - world.startX < e) {
-                       glBindTexture(GL_TEXTURE_2D, blackTex);
+                       Colors::black.use();
                        glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.0f);
 
                        GLfloat blackBarRight[] = {
@@ -1088,10 +1088,9 @@ void WorldSystem::render(void)
        } else {
                Render::useShader(&Render::worldShader);
                Render::worldShader.use();
-               static const GLuint rug = Texture::genColor(Color {255, 0, 0});
-               glBindTexture(GL_TEXTURE_2D, rug);
+               Colors::red.use();
                vec2 ll = vec2 {world.startX, GROUND_HEIGHT_MINIMUM};
-               Render::drawRect(ll, ll + vec2 {world.indoorWidth, 4}, -3);
+               Render::drawRect(ll, ll + vec2(world.indoorTex.getDim().x, 4), -3);
                Render::worldShader.unuse();
        }