+typedef struct _imgopengl
+{
+ gfxhash_t hash;
+ GLuint texID;
+ int width, height;
+ unsigned char*data;
+ struct _imgopengl*next;
+} imgopengl_t;
+
+static imgopengl_t*img2texid = 0;
+
+static gfxhash_t gfximage_hash(gfximage_t*img)
+{
+ int t;
+ int size = img->width*img->height*4;
+ U8*data = (U8*)img->data;
+ gfxhash_t hash;
+ hash_md5(data, size, hash.d);
+ return hash;
+}
+
+static void delTextures()
+{
+ imgopengl_t*i = img2texid;
+ while(i) {
+ imgopengl_t*next = i->next;
+ if(i->data) {
+ glDeleteTextures(1, &i->texID);
+ free(i->data);
+ }
+ memset(i, 0, sizeof(imgopengl_t));
+ free(i);
+ i = next;
+ }
+}
+
+static imgopengl_t*addTexture(gfximage_t*img)
+{
+ gfxhash_t hash = gfximage_hash(img);
+ imgopengl_t*i = img2texid;
+
+ int width_bits = 0;
+ int height_bits = 0;
+ while(1<<width_bits < img->width)
+ width_bits++;
+ while(1<<height_bits < img->height)
+ height_bits++;
+ int newwidth = 1<<width_bits;
+ int newheight = 1<<height_bits;
+
+ while(i) {
+ if(gfxhash_compare(&hash, &i->hash) && newwidth==i->width && newheight==i->height) {
+ return i;
+ }
+ i = i->next;
+ }
+
+ GLuint texIDs[1];
+ glGenTextures(1, texIDs);
+
+ i = malloc(sizeof(imgopengl_t));
+ i->hash = hash;
+ i->texID = texIDs[0];
+ i->next = img2texid;
+ img2texid = i;
+
+ i->width = newwidth;
+ i->height = newheight;
+
+ unsigned char*data = malloc(newwidth*newheight*4);
+ i->data = data;
+ int x,y;
+ for(y=0;y<img->height;y++) {
+ for(x=0;x<img->width;x++) {
+ data[(y*newwidth+x)*4+0] = img->data[y*img->width+x].r;
+ data[(y*newwidth+x)*4+1] = img->data[y*img->width+x].g;
+ data[(y*newwidth+x)*4+2] = img->data[y*img->width+x].b;
+ data[(y*newwidth+x)*4+3] = img->data[y*img->width+x].a;
+ }
+ int lastx = img->width - 1;
+ for(;x<newwidth;x++) {
+ data[(y*newwidth+x)*4+0] = img->data[y*img->width+lastx].r;
+ data[(y*newwidth+x)*4+1] = img->data[y*img->width+lastx].g;
+ data[(y*newwidth+x)*4+2] = img->data[y*img->width+lastx].b;
+ data[(y*newwidth+x)*4+3] = img->data[y*img->width+lastx].a;
+ }
+ }
+ int lasty = img->height - 1;
+ for(;y<newheight;y++) {
+ for(x=0;x<newwidth;x++) {
+ data[(y*newwidth+x)*4+0] = img->data[lasty*img->width+x].r;
+ data[(y*newwidth+x)*4+1] = img->data[lasty*img->width+x].g;
+ data[(y*newwidth+x)*4+2] = img->data[lasty*img->width+x].b;
+ data[(y*newwidth+x)*4+3] = img->data[lasty*img->width+x].a;
+ }
+ }
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, i->texID);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, i->width, i->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
+ return i;
+};
+