+ int textype;
+ int inputbytesperpixel;
+ int internalbytesperpixel;
+ int glformat;
+ int glinternalformat;
+ int align;
+}
+textypeinfo_t;
+
+static textypeinfo_t textype_qpalette = {TEXTYPE_QPALETTE, 1, 4, GL_RGBA, 3, 1};
+static textypeinfo_t textype_rgb = {TEXTYPE_RGB , 3, 3, GL_RGB , 3, 3};
+static textypeinfo_t textype_rgba = {TEXTYPE_RGBA , 4, 4, GL_RGBA, 3, 1};
+static textypeinfo_t textype_qpalette_alpha = {TEXTYPE_QPALETTE, 1, 4, GL_RGBA, 4, 1};
+static textypeinfo_t textype_rgba_alpha = {TEXTYPE_RGBA , 4, 4, GL_RGBA, 4, 1};
+
+// a tiling texture (most common type)
+#define GLIMAGETYPE_TILE 0
+// a fragments texture (contains one or more fragment textures)
+#define GLIMAGETYPE_FRAGMENTS 1
+
+// a gltextureimage can have one (or more if fragments) gltextures inside
+typedef struct gltextureimage_s
+{
+ struct gltextureimage_s *imagechain;
+ int texturecount;
+ int type; // one of the GLIMAGETYPE_ values
+ int texnum; // GL texture slot number
+ int width, height;
+ int bytesperpixel; // bytes per pixel
+ int glformat; // GL_RGB or GL_RGBA
+ int glinternalformat; // 3 or 4
+ int flags;
+ short *blockallocation; // fragment allocation
+}
+gltextureimage_t;
+
+typedef struct gltexture_s
+{
+ // pointer to texturepool (check this to see if the texture is allocated)
+ struct gltexturepool_s *pool;
+ // pointer to next texture in texturepool chain
+ struct gltexture_s *chain;
+ // pointer into gltextureimage array
+ gltextureimage_t *image;
+ // name of the texture (this might be removed someday), no duplicates
+ char *identifier;
+ // location in the image, and size
+ int x, y, width, height;
+ // copy of the original texture supplied to the upload function, for re-uploading or deferred uploads (non-precached)
+ qbyte *inputtexels;
+ // to identify cache mismatchs (this might be removed someday)
+ int crc;
+ // flags supplied to the LoadTexture/ProceduralTexture functions
+ // (might be altered to remove TEXF_ALPHA), and GLTEXF_ private flags
+ int flags;
+ // procedural texture generation function, called once per frame if the texture is used
+ int (*generate)(qbyte *buffer, int width, int height, void *parameterdata, int parameterdatasize);
+ // data provided to generate, persistent from call to call
+ qbyte *proceduraldata;
+ // size of data
+ int proceduraldatasize;
+ // used only to avoid updating the texture more than once per frame
+ int proceduralframecount;
+ // pointer to one of the textype_ structs
+ textypeinfo_t *textype;
+}
+gltexture_t;
+
+#define TEXTUREPOOL_SENTINEL 0xC0DEDBAD
+
+typedef struct gltexturepool_s
+{
+ int sentinel;
+ struct gltextureimage_s *imagechain;
+ struct gltexture_s *gltchain;
+ struct gltexturepool_s *next;
+}
+gltexturepool_t;
+
+static gltexturepool_t *gltexturepoolchain = NULL;
+
+static qbyte *resizebuffer = NULL, *colorconvertbuffer;
+static int resizebuffersize = 0;
+static qbyte *texturebuffer;
+static int texturebuffersize = 0;
+
+static int realmaxsize = 0;
+
+static textypeinfo_t *R_GetTexTypeInfo(int textype, int flags)
+{
+ if (flags & TEXF_ALPHA)
+ {
+ switch(textype)
+ {
+ case TEXTYPE_QPALETTE:
+ return &textype_qpalette_alpha;
+ case TEXTYPE_RGB:
+ Host_Error("R_GetTexTypeInfo: RGB format has no alpha, TEXF_ALPHA not allowed\n");
+ return NULL;
+ case TEXTYPE_RGBA:
+ return &textype_rgba_alpha;
+ default:
+ Host_Error("R_GetTexTypeInfo: unknown texture format\n");
+ return NULL;
+ }
+ }
+ else
+ {
+ switch(textype)
+ {
+ case TEXTYPE_QPALETTE:
+ return &textype_qpalette;
+ case TEXTYPE_RGB:
+ return &textype_rgb;
+ case TEXTYPE_RGBA:
+ return &textype_rgba;
+ default:
+ Host_Error("R_GetTexTypeInfo: unknown texture format\n");
+ return NULL;
+ }
+ }
+}
+
+static void R_UploadTexture(gltexture_t *t);