]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
c++'d texture loading
authorClyne Sullivan <tullivan99@gmail.com>
Fri, 26 Feb 2016 13:47:49 +0000 (08:47 -0500)
committerClyne Sullivan <tullivan99@gmail.com>
Fri, 26 Feb 2016 13:47:49 +0000 (08:47 -0500)
Changelog
include/Texture.h
include/common.h
include/world.h
src/Texture.cpp
src/gameplay.cpp
src/ui.cpp
src/world.cpp

index 2ac88bd1ebbd4fd4de9c6f2b822e135571425597..b85c19577d8fa119b06f2d6178c7752832f86a8e 100644 (file)
--- a/Changelog
+++ b/Changelog
        - very neatly documented/optimized ui.cpp (very neat)
        - looked into better automated Makefiles
        - improving villages, began work on shops
+
+2/26/2015:
+==========
+
+       - made fonts more memory-efficient
+       - C++-ified loaded texture handlers
+       - documented more stuff
+       - made merchant menu
index c6376cb885df52bef9771de6262ac4cb2a0f7c6c..659c32d185068bcfc155df66198411c32bd50bd9 100644 (file)
@@ -27,13 +27,13 @@ namespace Texture{
         * later referencing of the texture.
         */
        
-       GLuint loadTexture(const char *fileName);
+       GLuint loadTexture(std::string fileName);
        
        void freeTextures(void);
        
        void initColorIndex();
        vec2 getIndex(Color c);
-       dim2 imageDim(const char *fileName);
+       dim2 imageDim(std::string fileName);
 }
 
 /**
index 71335f2648e8e0c6987923050ec31f508ea449af..6ba6f03b7b6417ad1cd7c5d4436ea809d661b97d 100644 (file)
@@ -68,7 +68,7 @@ typedef struct {
        float z;
 } vec3;
 
-typedef vec2 dim2;
+typedef ivec2 dim2;
 
 /**
  * This structure contains two sets of coordinates for ray drawing.
index 56f1577200f4684ecd391ad82df19fc4b40f722f..c0668655eb103f073960b80397579f0bf572e741 100644 (file)
@@ -129,6 +129,12 @@ public:
         */
        
        Village(const char *meme, World *w);
+       
+       /**
+        * Destructor...
+        */
+        
+       ~Village(void){}
 };
 
 /**
@@ -282,9 +288,7 @@ public:
        std::vector<Particles   *>      particles;
        
        
-       
-       
-       std::vector<Village *    >      village;
+       std::vector<Village     *>      village;
        
        /**
         * A vector of all light elements in this world.
index 1487dcd6a895cf06986d5b0bcaa0631f321092ea..1aaadf6944bf373333d2117bfb5cac6f2b9a57e2 100644 (file)
@@ -1,45 +1,62 @@
 #include <Texture.h>
 #include <string.h>
 
+/**
+ * A structure for keeping track of loaded textures.
+ */
+
 struct texture_t {
-       char *name;
-       GLuint tex;
-       dim2 dim;
-} __attribute__ ((packed));
+       std::string name;       /**< The file path of the texture.              */
+       GLuint tex;                     /**< The GLuint for the loaded texture. */
+       dim2 dim;                       /**< The dimensions of the texture.             */
+};
 
-struct index_t{
+struct index_t {
        Color color;
        int indexx;
        int indexy;
 };
 
-struct texture_t *LoadedTexture[256];
-unsigned int LoadedTextureCounter = 0;
+/**
+ * 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.
+ */
+
+static std::vector<struct texture_t> LoadedTexture;
 
 namespace Texture{
        Color pixels[8][4];
-       GLuint loadTexture(const char *fileName){
+       
+       GLuint loadTexture(std::string fileName){
                SDL_Surface *image;
                GLuint object = 0;
 
-               for(unsigned int i=0;i<LoadedTextureCounter;i++){
-                       if(!strcmp(LoadedTexture[i]->name,fileName)){
+               // check if texture is already loaded
+               for(auto &t : LoadedTexture){
+                       if(t.name == fileName){
+                               
 #ifdef DEBUG
-                               DEBUG_printf("Reusing loaded texture for %s\n",fileName);
+                               DEBUG_printf("Reusing loaded texture for %s\n", fileName.c_str());
 #endif // DEBUG
-                               return LoadedTexture[i]->tex;
+                               
+                               return t.tex;
                        }
                }
 
-               if(!fileName)
-                       return 0;
-
-               if(!(image = IMG_Load(fileName)))
+               // load SDL_surface of texture
+               if(!(image = IMG_Load(fileName.c_str())))
                        return 0;
+                       
 #ifdef DEBUG
-               DEBUG_printf("Loaded image file: %s\n", fileName);
+               DEBUG_printf("Loaded image file: %s\n", fileName.c_str());
 #endif // DEBUG
                
+               /*
+                * Load texture through OpenGL.
+                */
+               
                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);
@@ -61,33 +78,27 @@ namespace Texture{
                                         image->pixels
                                         );
                
-               LoadedTexture[LoadedTextureCounter]               = new struct texture_t;               //(struct texture_t *)malloc(sizeof(struct texture_t));
-               LoadedTexture[LoadedTextureCounter]->name = new char[strlen(fileName)+1];       //(char *)malloc(safe_strlen(fileName));
-               LoadedTexture[LoadedTextureCounter]->tex  = object;
-               strcpy(LoadedTexture[LoadedTextureCounter]->name,fileName);
-               LoadedTexture[LoadedTextureCounter]->dim.x = image->w;
-               LoadedTexture[LoadedTextureCounter]->dim.y = image->h;
-               LoadedTextureCounter++;
+               // add texture to LoadedTexture
+               LoadedTexture.push_back((struct texture_t){fileName,object,{image->w,image->h}});               
                
-               SDL_FreeSurface(image); // Free the surface
+               // free the SDL_Surface
+               SDL_FreeSurface(image);
 
                return object;
        }
 
-       dim2 imageDim(const char *fileName){
-               for(unsigned int i=0;i<LoadedTextureCounter;i++){
-                       if(!strcmp(LoadedTexture[i]->name,fileName)){
-                               return LoadedTexture[i]->dim;
-                       }
+       dim2 imageDim(std::string fileName){
+               for(auto &t : LoadedTexture){
+                       if(t.name == fileName)
+                               return t.dim;
                }
                return {0,0};
        }
        
        void freeTextures(void){
-               for(unsigned int i=0;i<LoadedTextureCounter;i++){
-                       glDeleteTextures(1,&LoadedTexture[i]->tex);
-                       delete[] LoadedTexture[i]->name;
-                       delete LoadedTexture[i];
+               while(!LoadedTexture.empty()){
+                       glDeleteTextures(1, &LoadedTexture.back().tex);
+                       LoadedTexture.pop_back();
                }
        }
 
index 4bbc672c36d1fd4b729d2f18162d2431cac9a6ec..e3c117115310c005afae15feab07677057e7257e 100644 (file)
@@ -321,6 +321,7 @@ extern std::vector<NPC *> AIpreaddr;
 void destroyEverything(void){
        currentWorld->save();
        delete currentWorld;
+       delete[] currentXML;
        
        while(!AIpreload.empty())
                AIpreload.pop_back();
index 0d1fb49e7b97969bc76d68a3d1bbdebddd1025cb..d66c1706c9a6c306a13803afdb435e6b7c04c6c1 100644 (file)
@@ -35,7 +35,9 @@ typedef struct {
        ivec2   ad;             /**< Number of pixels to advance cursor. */
 } FT_Tex;
 
-static FT_Tex ftmap[FT_CHAR_COUNT];
+static FT_Tex ftmap16[FT_CHAR_COUNT],
+                         ftmap24[FT_CHAR_COUNT],
+                         *ftmapptr;
 
 static FT_Library   ftl;
 static FT_Face      ftf;
@@ -186,8 +188,13 @@ namespace ui {
                        abort();
                }
                
-               fontSize = 0;
-               memset(&ftmap, 0, FT_CHAR_COUNT * sizeof(FT_Tex));
+               fontSize = 16;
+               
+               //ftmap16 = new FT_Tex[FT_CHAR_COUNT];
+               //ftmap24 = new FT_Tex[FT_CHAR_COUNT];
+               
+               memset(&ftmap16, 0, FT_CHAR_COUNT * sizeof(FT_Tex));
+               memset(&ftmap24, 0, FT_CHAR_COUNT * sizeof(FT_Tex));
                
 #ifdef DEBUG
                DEBUG_printf("Initialized FreeType2.\n",NULL);
@@ -207,6 +214,9 @@ namespace ui {
         */
        
        void destroyFonts(void){
+               //delete[] ftmap16;
+               //delete[] ftmap24;
+               
                FT_Done_Face(ftf);
                FT_Done_FreeType(ftl);
                
@@ -220,8 +230,13 @@ namespace ui {
         */
        
        void setFontFace(const char *ttf){
-               if(FT_New_Face(ftl,ttf,0,&ftf)){
-                       std::cout<<"Error! Couldn't open "<<ttf<<"."<<std::endl;
+               std::unique_ptr<uint8_t[]> rgbaBuf;
+               size_t rgbaBufSize, ftsize;
+               unsigned int i,j;
+               FT_Error fte;
+               
+               if((fte = FT_New_Face(ftl,ttf,0,&ftf))){
+                       std::cout<<"Error! Couldn't open "<<ttf<<" (Error "<<fte<<")."<<std::endl;
                        abort();
                }
                
@@ -229,6 +244,77 @@ namespace ui {
                DEBUG_printf("Using font %s\n",ttf);
 #endif // DEBUG
 
+               /*
+                * Load the font in the two sizes we use, 16px and 24px.
+                */
+               
+               ftmapptr = ftmap16;
+               ftsize = 16;
+
+               do{
+                       FT_Set_Pixel_Sizes(ftf, 0, ftsize);
+                       
+                       // allocate texture space
+                       for(i=0; i < FT_CHAR_COUNT; i++)
+                               glGenTextures(1, &ftmapptr[i].tex);
+                       
+                       // Load all characters we expect to use
+                       for(i=33; i<126; i++){
+                       
+                               // Load the bitmap for the current character.
+                               if(FT_Load_Char(ftf,i,FT_LOAD_RENDER)){
+                                       std::cout<<"Error! Unsupported character "<<(char)i<<" ("<<i<<")."<<std::endl;
+                                       abort();
+                               }
+                               
+                               /*
+                                * Set up the OpenGL texture thing.
+                                */
+                       
+                               glBindTexture(GL_TEXTURE_2D, ftmapptr[i-33].tex);
+                               
+                               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S                , GL_CLAMP_TO_EDGE);
+                               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T                , GL_CLAMP_TO_EDGE);
+                               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER    , GL_LINEAR              );
+                               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER    , GL_LINEAR              );
+                               
+                               glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+                       
+                               /*
+                                * Convert the bitmap font given to us from FreeType into an RGBA
+                                * format, for ease of drawing.
+                                */
+                       
+                               rgbaBuf.reset(new uint8_t [(rgbaBufSize = ftf->glyph->bitmap.width * ftf->glyph->bitmap.rows * 4)]);
+                               rgbaBufSize /= 4;
+                       
+                               // populate the buffer
+                               for(j=0; j < rgbaBufSize; j++){
+                                       rgbaBuf[j * 4] = rgbaBuf[j * 4 + 1] = rgbaBuf[j * 4 + 2] = 255;
+                                       rgbaBuf[j * 4 + 3] = ftf->glyph->bitmap.buffer[j] ? 255 : 0;
+                               }
+                               
+                               // save important character information
+                               ftmapptr[i-33].wh = { (int)ftf->glyph->bitmap.width, (int)ftf->glyph->bitmap.rows };
+                               ftmapptr[i-33].bl = { ftf->glyph->bitmap_left,            ftf->glyph->bitmap_top       };
+                               ftmapptr[i-33].ad = { ftf->glyph->advance.x >> 6,         ftf->glyph->advance.y >> 6   };
+                       
+                               // do the thing
+                               glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ftf->glyph->bitmap.width, ftf->glyph->bitmap.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaBuf.get());
+                               rgbaBuf.reset();
+                       }
+
+                       // repeat for 24px, or exit
+                       if(ftmapptr == ftmap16){
+                               ftmapptr = ftmap24;
+                               ftsize = 24;
+                       }else{
+                               break;
+                       }
+                       
+               }while(1);
+
+               setFontSize(16);
        }
        
        /**
@@ -237,66 +323,14 @@ namespace ui {
         */
        
        void setFontSize(unsigned int size){
-               unsigned int i,j;
-               
-               std::unique_ptr<uint8_t[]> rgbaBuf;
-               size_t rgbaBufSize = 0;
-               
-               FT_Set_Pixel_Sizes(ftf,0,(fontSize = size));
-               
-               // delete old characters, make space for new ones
-               for(i=0; i < FT_CHAR_COUNT; i++){
-                       glDeleteTextures(1, &ftmap[i].tex);
-                       glGenTextures(1, &ftmap[i].tex);
-               }
-               
-               // Load all characters we expect to use
-               for(i=33;i<126;i++){
-               
-                       // Load the bitmap for the current character.
-                       if(FT_Load_Char(ftf,i,FT_LOAD_RENDER)){
-                               std::cout<<"Error! Unsupported character "<<(char)i<<" ("<<i<<")."<<std::endl;
-                               abort();
-                       }
-                       
-                       /*
-                        * Set up the OpenGL texture thing.
-                        */
-               
-                       glBindTexture(GL_TEXTURE_2D, ftmap[i-33].tex);
-                       
-                       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S                , GL_CLAMP_TO_EDGE);
-                       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T                , GL_CLAMP_TO_EDGE);
-                       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER    , GL_LINEAR              );
-                       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER    , GL_LINEAR              );
-                       
-                       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-               
-                       /*
-                        * Convert the bitmap font given to us from FreeType into an RGBA
-                        * format, for ease of drawing.
-                        */
-               
-                       rgbaBuf.reset(new uint8_t [(rgbaBufSize = ftf->glyph->bitmap.width * ftf->glyph->bitmap.rows * 4)]);
-                       rgbaBufSize /= 4;
-               
-                       // populate the buffer
-                       for(j=0; j < rgbaBufSize; j++){
-                               rgbaBuf[j * 4    ] = 
-                               rgbaBuf[j * 4 + 1] = 
-                               rgbaBuf[j * 4 + 2] = 255;
-                               rgbaBuf[j * 4 + 3] = ftf->glyph->bitmap.buffer[j] ? 255 : 0;
-                       }
-                       
-                       // save important character information
-                       ftmap[i-33].wh = { (int)ftf->glyph->bitmap.width, (int)ftf->glyph->bitmap.rows };
-                       ftmap[i-33].bl = { ftf->glyph->bitmap_left,               ftf->glyph->bitmap_top       };
-                       ftmap[i-33].ad = { ftf->glyph->advance.x >> 6,    ftf->glyph->advance.y >> 6   };
-               
-                       // do the thing
-                       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ftf->glyph->bitmap.width, ftf->glyph->bitmap.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaBuf.get());
-                       
-                       rgbaBuf.release();
+               switch((fontSize = size)){
+               case 24:
+                       ftmapptr = ftmap24;
+                       break;
+               default:
+               case 16:
+                       ftmapptr = ftmap16;
+                       break;
                }
        }
        
@@ -318,16 +352,16 @@ namespace ui {
                ivec2 c1,c2;
 
                // calculate coordinates
-               c1 = { (int)floor(x) + ftmap[c-33].bl.x,
-                      (int)floor(y) + ftmap[c-33].bl.y };
-               c2 = ftmap[c-33].wh;
+               c1 = { (int)floor(x) + ftmapptr[c-33].bl.x,
+                      (int)floor(y) + ftmapptr[c-33].bl.y };
+               c2 = ftmapptr[c-33].wh;
                
                /*
                 *      Draw the character
                 */
                
                glEnable(GL_TEXTURE_2D);
-               glBindTexture(GL_TEXTURE_2D, ftmap[c-33].tex);
+               glBindTexture(GL_TEXTURE_2D, ftmapptr[c-33].tex);
                
                glPushMatrix();
                glTranslatef(0,-c2.y,0);
@@ -346,7 +380,7 @@ namespace ui {
                glDisable(GL_TEXTURE_2D);
 
                // return the number of pixels the cursor should move
-               return ftmap[c-33].ad;
+               return ftmapptr[c-33].ad;
        }
        
        /**
@@ -427,7 +461,7 @@ namespace ui {
 
                        // handle everything else
                        }else
-                               width += ftmap[i].wh.x + fontSize * .1;
+                               width += ftmapptr[i].wh.x + fontSize * .1;
 
                }while(s[++i]);
 
index 303d53b020c9121a13ae12d1367f971f29f770de..eb9f12ec699fe2daeea2d76d5d6ccc1eae2382d5 100644 (file)
@@ -140,6 +140,11 @@ void World::deleteEntities(void){
        while(!light.empty()){
                light.pop_back();
        }
+       while(!village.empty()){
+               delete village.back();
+               village.pop_back();
+       }
+       
 }
 
 World::~World(void){