3 cvar_t gl_max_size = {"gl_max_size", "1024"};
4 cvar_t gl_picmip = {"gl_picmip", "0"};
5 cvar_t gl_lerpimages = {"gl_lerpimages", "1"};
6 cvar_t r_upload = {"r_upload", "1"};
8 int gl_filter_min = GL_LINEAR_MIPMAP_LINEAR; //NEAREST;
9 int gl_filter_max = GL_LINEAR;
20 byte *texels[MAXMIPS];
21 unsigned short texelsize[MAXMIPS][2];
24 // LordHavoc: CRC to identify cache mismatchs
29 char lerped; // whether this texture was uploaded with or without interpolation
32 #define MAX_GLTEXTURES 4096
33 gltexture_t gltextures[MAX_GLTEXTURES];
39 int minimize, maximize;
43 {"GL_NEAREST", GL_NEAREST, GL_NEAREST},
44 {"GL_LINEAR", GL_LINEAR, GL_LINEAR},
45 {"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
46 {"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR},
47 {"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST},
48 {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
56 void Draw_TextureMode_f (void)
63 for (i=0 ; i< 6 ; i++)
64 if (gl_filter_min == modes[i].minimize)
66 Con_Printf ("%s\n", modes[i].name);
69 Con_Printf ("current filter is unknown???\n");
73 for (i=0 ; i< 6 ; i++)
75 if (!Q_strcasecmp (modes[i].name, Cmd_Argv(1) ) )
80 Con_Printf ("bad filter name\n");
84 gl_filter_min = modes[i].minimize;
85 gl_filter_max = modes[i].maximize;
89 // change all the existing mipmap texture objects
90 for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
94 glBindTexture(GL_TEXTURE_2D, glt->texnum);
95 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
96 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
101 extern int buildnumber;
103 char engineversion[40];
105 void GL_UploadTexture (gltexture_t *glt);
106 void gl_textures_start()
110 for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
111 GL_UploadTexture(glt);
114 void gl_textures_shutdown()
118 void GL_Textures_Init (void)
120 Cvar_RegisterVariable (&gl_max_size);
121 Cvar_RegisterVariable (&gl_picmip);
122 Cvar_RegisterVariable (&gl_lerpimages);
123 Cvar_RegisterVariable (&r_upload);
128 // 3dfx can only handle 256 wide textures
129 if (!Q_strncasecmp ((char *)gl_renderer, "3dfx",4) || strstr((char *)gl_renderer, "Glide"))
130 Cvar_Set ("gl_max_size", "256");
132 Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_f);
134 R_RegisterModule("GL_Textures", gl_textures_start, gl_textures_shutdown);
142 int GL_FindTexture (char *identifier)
147 for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
149 if (!strcmp (identifier, glt->identifier))
150 return gltextures[i].texnum;
156 extern byte qgamma[];
158 // LordHavoc: gamma correction and improved resampling
159 void GL_ResampleTextureLerpLine (byte *in, byte *out, int inwidth, int outwidth)
161 int j, xi, oldx = 0, f, fstep, l1, l2, endx;
162 fstep = (int) (inwidth*65536.0f/outwidth);
164 for (j = 0,f = 0;j < outwidth;j++, f += fstep)
169 in += (xi - oldx) * 4;
176 *out++ = qgamma[(byte) ((in[0] * l1 + in[4] * l2) >> 16)];
177 *out++ = qgamma[(byte) ((in[1] * l1 + in[5] * l2) >> 16)];
178 *out++ = qgamma[(byte) ((in[2] * l1 + in[6] * l2) >> 16)];
179 *out++ = (byte) ((in[3] * l1 + in[7] * l2) >> 16) ;
181 else // last pixel of the line has no pixel to lerp to
183 *out++ = qgamma[in[0]];
184 *out++ = qgamma[in[1]];
185 *out++ = qgamma[in[2]];
196 void GL_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
198 // LordHavoc: gamma correction and greatly improved resampling
199 if (gl_lerpimages.value)
201 int i, j, yi, oldy, f, fstep, l1, l2, endy = (inheight-1);
202 byte *inrow, *out, *row1, *row2;
204 fstep = (int) (inheight*65536.0f/outheight);
206 row1 = malloc(outwidth*4);
207 row2 = malloc(outwidth*4);
210 GL_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth);
211 GL_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth);
212 for (i = 0, f = 0;i < outheight;i++,f += fstep)
217 inrow = (byte *)indata + inwidth*4*yi;
219 memcpy(row1, row2, outwidth*4);
221 GL_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth);
223 GL_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth);
225 memcpy(row2, row1, outwidth*4);
232 for (j = 0;j < outwidth;j++)
234 *out++ = (byte) ((*row1++ * l1 + *row2++ * l2) >> 16);
235 *out++ = (byte) ((*row1++ * l1 + *row2++ * l2) >> 16);
236 *out++ = (byte) ((*row1++ * l1 + *row2++ * l2) >> 16);
237 *out++ = (byte) ((*row1++ * l1 + *row2++ * l2) >> 16);
242 else // last line has no pixels to lerp to
244 for (j = 0;j < outwidth;j++)
260 unsigned frac, fracstep;
261 byte *inrow, *out, *inpix;
264 fracstep = inwidth*0x10000/outwidth;
265 for (i=0 ; i<outheight ; i++)
267 inrow = (byte *)indata + inwidth*(i*inheight/outheight)*4;
268 frac = fracstep >> 1;
269 for (j=0 ; j<outwidth ; j+=4)
271 inpix = inrow + ((frac >> 14) & ~3);*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = *inpix++ ;frac += fracstep;
272 inpix = inrow + ((frac >> 14) & ~3);*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = *inpix++ ;frac += fracstep;
273 inpix = inrow + ((frac >> 14) & ~3);*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = *inpix++ ;frac += fracstep;
274 inpix = inrow + ((frac >> 14) & ~3);*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = qgamma[*inpix++];*out++ = *inpix++ ;frac += fracstep;
282 GL_Resample8BitTexture -- JACK
286 void GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight, unsigned char *out, int outwidth, int outheight)
289 unsigned char *inrow;
290 unsigned frac, fracstep;
292 fracstep = inwidth*0x10000/outwidth;
293 for (i=0 ; i<outheight ; i++, out += outwidth)
295 inrow = in + inwidth*(i*inheight/outheight);
296 frac = fracstep >> 1;
297 for (j=0 ; j<outwidth ; j+=4)
299 out[j ] = inrow[frac>>16];frac += fracstep;
300 out[j+1] = inrow[frac>>16];frac += fracstep;
301 out[j+2] = inrow[frac>>16];frac += fracstep;
302 out[j+3] = inrow[frac>>16];frac += fracstep;
313 Operates in place, quartering the size of the texture
317 void GL_MipMap (byte *in, int width, int height)
325 for (i=0 ; i<height ; i++, in+=width)
327 for (j=0 ; j<width ; j+=8, out+=4, in+=8)
329 out[0] = (in[0] + in[4] + in[width+0] + in[width+4])>>2;
330 out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2;
331 out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2;
332 out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2;
342 Mipping for 8 bit textures
346 void GL_MipMap8Bit (byte *in, int width, int height)
349 unsigned short r,g,b;
350 byte *out, *at1, *at2, *at3, *at4;
354 for (i=0 ; i<height ; i++, in+=width)
356 for (j=0 ; j<width ; j+=2, out+=1, in+=2)
358 at1 = (byte *) (d_8to24table + in[0]);
359 at2 = (byte *) (d_8to24table + in[1]);
360 at3 = (byte *) (d_8to24table + in[width+0]);
361 at4 = (byte *) (d_8to24table + in[width+1]);
363 r = (at1[0]+at2[0]+at3[0]+at4[0]); r>>=5;
364 g = (at1[1]+at2[1]+at3[1]+at4[1]); g>>=5;
365 b = (at1[2]+at2[2]+at3[2]+at4[2]); b>>=5;
367 out[0] = d_15to8table[(r<<0) + (g<<5) + (b<<10)];
379 void GL_Upload32 (void *data, int width, int height, qboolean mipmap, qboolean alpha)
381 int samples, scaled_width, scaled_height, i;
382 byte *in, *out, *scaled;
384 for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
386 for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
389 scaled_width >>= (int)gl_picmip.value;
390 scaled_height >>= (int)gl_picmip.value;
392 if (scaled_width > gl_max_size.value)
393 scaled_width = gl_max_size.value;
394 if (scaled_height > gl_max_size.value)
395 scaled_height = gl_max_size.value;
401 for (i = 3;i < width*height*4;i += 4)
409 samples = alpha ? gl_alpha_format : gl_solid_format;
411 texels += scaled_width * scaled_height;
413 scaled = malloc(scaled_width*scaled_height*4);
414 if (scaled_width == width && scaled_height == height)
416 // LordHavoc: gamma correct while copying
418 out = (byte *)scaled;
419 for (i = 0;i < width*height;i++)
421 *out++ = qgamma[*in++];
422 *out++ = qgamma[*in++];
423 *out++ = qgamma[*in++];
428 GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
430 glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
436 while (scaled_width > 1 || scaled_height > 1)
438 GL_MipMap ((byte *)scaled, scaled_width, scaled_height);
441 if (scaled_width < 1)
443 if (scaled_height < 1)
446 glTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
452 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
453 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
457 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
458 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
463 void GL_Upload8_EXT (byte *data, int width, int height, qboolean mipmap)
465 int scaled_width, scaled_height;
468 for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
470 for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
473 scaled_width >>= (int)gl_picmip.value;
474 scaled_height >>= (int)gl_picmip.value;
476 if (scaled_width > gl_max_size.value)
477 scaled_width = gl_max_size.value;
478 if (scaled_height > gl_max_size.value)
479 scaled_height = gl_max_size.value;
481 texels += scaled_width * scaled_height;
483 if (scaled_width == width && scaled_height == height)
487 glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX , GL_UNSIGNED_BYTE, data);
490 scaled = malloc(scaled_width*scaled_height*4);
491 memcpy (scaled, data, width*height);
495 scaled = malloc(scaled_width*scaled_height*4);
496 GL_Resample8BitTexture (data, width, height, (void*) scaled, scaled_width, scaled_height);
499 glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
505 while (scaled_width > 1 || scaled_height > 1)
507 GL_MipMap8Bit ((byte *)scaled, scaled_width, scaled_height);
510 if (scaled_width < 1)
512 if (scaled_height < 1)
515 glTexImage2D (GL_TEXTURE_2D, miplevel, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
523 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
524 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
528 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
529 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
535 extern qboolean VID_Is8bit();
543 void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha)
545 static unsigned *trans;
554 // if there are no transparent pixels, make it a 3 component
555 // texture even if it was specified as otherwise
559 for (i=0 ; i<s ; i++)
563 trans[i] = d_8to24table[p];
566 trans[i] = 0; // force to black
573 if (VID_Is8bit() && (data!=scrap_texels[0]))
575 GL_Upload8_EXT (data, width, height, mipmap);
584 // LordHavoc: dodge the copy if it will be uploaded as 8bit
585 if (VID_Is8bit() && (data!=scrap_texels[0]))
587 GL_Upload8_EXT (data, width, height, mipmap);
592 // Sys_Error ("GL_Upload8: s&3");
596 *outdata++ = d_8to24table[*indata++];
599 *outdata++ = d_8to24table[*indata++];
600 *outdata++ = d_8to24table[*indata++];
602 for (i = 0;i < s;i+=4)
604 *outdata++ = d_8to24table[*indata++];
605 *outdata++ = d_8to24table[*indata++];
606 *outdata++ = d_8to24table[*indata++];
607 *outdata++ = d_8to24table[*indata++];
611 GL_Upload32 (trans, width, height, mipmap, alpha);
616 void GL_AllocTexels(gltexture_t *glt, int width, int height, int mipmapped)
618 int i, w, h, size, done;
620 free(glt->texels[0]);
621 glt->texelsize[0][0] = width;
622 glt->texelsize[0][1] = height;
626 w = width;h = height;
629 for (i = 0;i < MAXMIPS;i++)
631 glt->texelsize[i][0] = w;
632 glt->texelsize[i][1] = h;
633 glt->texels[i] = (void *)size;
650 glt->texels[i++] = NULL;
651 glt->texels[0] = malloc(size);
652 for (i = 1;i < MAXMIPS && glt->texels[i];i++)
653 glt->texels[i] += (int) glt->texels[0];
657 glt->texels[0] = malloc(width*height*4);
658 for (i = 1;i < MAXMIPS;i++)
659 glt->texels[i] = NULL;
662 Sys_Error("GL_AllocTexels: out of memory\n");
665 // in can be the same as out
666 void GL_MipReduce(byte *in, byte *out, int width, int height, int destwidth, int destheight)
668 int x, y, width2, height2, nextrow;
669 if (width > destwidth)
671 if (height > destheight)
675 height2 = height >> 1;
676 nextrow = width << 2;
677 for (y = 0;y < height2;y++)
679 for (x = 0;x < width2;x++)
681 out[0] = (byte) ((in[0] + in[4] + in[nextrow ] + in[nextrow+4]) >> 2);
682 out[1] = (byte) ((in[1] + in[5] + in[nextrow+1] + in[nextrow+5]) >> 2);
683 out[2] = (byte) ((in[2] + in[6] + in[nextrow+2] + in[nextrow+6]) >> 2);
684 out[3] = (byte) ((in[3] + in[7] + in[nextrow+3] + in[nextrow+7]) >> 2);
688 in += nextrow; // skip a line
695 for (y = 0;y < height;y++)
697 for (x = 0;x < width2;x++)
699 out[0] = (byte) ((in[0] + in[4]) >> 1);
700 out[1] = (byte) ((in[1] + in[5]) >> 1);
701 out[2] = (byte) ((in[2] + in[6]) >> 1);
702 out[3] = (byte) ((in[3] + in[7]) >> 1);
711 if (height > destheight)
714 height2 = height >> 1;
715 nextrow = width << 2;
716 for (y = 0;y < height2;y++)
718 for (x = 0;x < width;x++)
720 out[0] = (byte) ((in[0] + in[nextrow ]) >> 1);
721 out[1] = (byte) ((in[1] + in[nextrow+1]) >> 1);
722 out[2] = (byte) ((in[2] + in[nextrow+2]) >> 1);
723 out[3] = (byte) ((in[3] + in[nextrow+3]) >> 1);
727 in += nextrow; // skip a line
731 Sys_Error("GL_MipReduce: desired size already achieved\n");
735 void GL_UploadTexture (gltexture_t *glt)
737 int mip, width, height;
740 glBindTexture(GL_TEXTURE_2D, glt->texnum);
742 height = glt->height;
743 for (mip = 0;mip < MAXMIPS && glt->texels[mip];mip++)
744 glTexImage2D(GL_TEXTURE_2D, mip, glt->alpha ? 4 : 3, glt->texelsize[mip][0], glt->texelsize[mip][1], 0, GL_RGBA, GL_UNSIGNED_BYTE, glt->texels[mip]);
747 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
748 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
752 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
753 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
755 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
763 int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha, int bytesperpixel)
766 int i, width2, height2, width3, height3, w, h, mip;
772 // LordHavoc: do a CRC to confirm the data really is the same as previous occurances.
773 crc = CRC_Block(data, width*height*bytesperpixel);
774 // see if the texture is already present
777 for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
779 if (!strcmp (identifier, glt->identifier))
781 // LordHavoc: everyone hates cache mismatchs, so I fixed it
782 if (crc != glt->crc || width != glt->width || height != glt->height)
784 Con_DPrintf("GL_LoadTexture: cache mismatch, replacing old texture\n");
785 goto GL_LoadTexture_setup; // drop out with glt pointing to the texture to replace
786 //Sys_Error ("GL_LoadTexture: cache mismatch");
788 if ((gl_lerpimages.value != 0) != glt->lerped)
789 goto GL_LoadTexture_setup; // drop out with glt pointing to the texture to replace
794 // LordHavoc: although this could be an else condition as it was in the original id code,
795 // it is more clear this way
796 // LordHavoc: check if there are still slots available
797 if (numgltextures >= MAX_GLTEXTURES)
798 Sys_Error ("GL_LoadTexture: ran out of texture slots (%d)\n", MAX_GLTEXTURES);
799 glt = &gltextures[numgltextures++];
801 strcpy (glt->identifier, identifier);
802 glt->texnum = texture_extension_number;
803 texture_extension_number++;
804 // LordHavoc: label to drop out of the loop into the setup code
805 GL_LoadTexture_setup:
806 // calculate power of 2 size
807 width2 = 1;while (width2 < width) width2 <<= 1;
808 height2 = 1;while (height2 < height) height2 <<= 1;
809 // calculate final size (mipmapped downward to this)
810 width3 = width2 >> (int) gl_picmip.value;
811 height3 = height2 >> (int) gl_picmip.value;
812 while (width3 > (int) gl_max_size.value) width3 >>= 1;
813 while (height3 > (int) gl_max_size.value) height3 >>= 1;
814 if (width3 < 1) width3 = 1;
815 if (height3 < 1) height3 = 1;
818 GL_AllocTexels(glt, width3, height3, mipmap);
819 glt->crc = crc; // LordHavoc: used to verify textures are identical
821 glt->height = height;
822 glt->mipmap = mipmap;
823 glt->bytesperpixel = bytesperpixel;
824 glt->lerped = gl_lerpimages.value != 0;
825 glt->alpha = false; // updated later
826 if (width == width3 && height == height3) // perfect match
828 if (bytesperpixel == 1) // 8bit
829 Image_Copy8bitRGBA(data, glt->texels[0], width*height, d_8to24table);
831 Image_CopyRGBAGamma(data, glt->texels[0], width*height);
833 else if (width == width2 && height == height2) // perfect match for top level, but needs to be reduced
836 temptexels2 = malloc(width2*height2*4); // scaleup buffer
837 if (bytesperpixel == 1) // 8bit
838 Image_Copy8bitRGBA(data, temptexels2, width*height, d_8to24table);
840 Image_CopyRGBAGamma(data, temptexels2, width*height);
841 while (width2 > width3 || height2 > height3)
843 w = width2;h = height2;
844 if (width2 > width3) width2 >>= 1;
845 if (height2 > height3) height2 >>= 1;
846 if (width2 <= width3 && height2 <= height3) // size achieved
847 GL_MipReduce(temptexels2, glt->texels[0], w, h, width3, height3);
849 GL_MipReduce(temptexels2, temptexels2, w, h, width3, height3);
856 // pre-scaleup buffer
857 temptexels = malloc(width*height*4);
858 if (bytesperpixel == 1) // 8bit
859 Image_Copy8bitRGBA(data, temptexels, width*height, d_8to24table);
861 Image_CopyRGBAGamma(data, temptexels, width*height);
862 if (width2 != width3 || height2 != height3) // reduced by gl_pic_mip or gl_max_size
865 temptexels2 = malloc(width2*height2*4); // scaleup buffer
866 GL_ResampleTexture(temptexels, width, height, temptexels2, width2, height2);
867 while (width2 > width3 || height2 > height3)
869 w = width2;h = height2;
870 if (width2 > width3) width2 >>= 1;
871 if (height2 > height3) height2 >>= 1;
872 if (width2 <= width3 && height2 <= height3) // size achieved
873 GL_MipReduce(temptexels2, glt->texels[0], w, h, width3, height3);
875 GL_MipReduce(temptexels2, temptexels2, w, h, width3, height3);
879 else // copy directly
880 GL_ResampleTexture(temptexels, width, height, glt->texels[0], width2, height2);
885 byte *in = glt->texels[0] + 3;
886 for (i = 0;i < width*height;i++, in += 4)
893 // this loop is skipped if there are no mipmaps to generate
894 for (mip = 1;mip < MAXMIPS && glt->texels[mip];mip++)
895 GL_MipReduce(glt->texels[mip-1], glt->texels[mip], glt->texelsize[mip-1][0], glt->texelsize[mip-1][1], 1, 1);
896 GL_UploadTexture(glt);
898 // if (bytesperpixel == 1) // 8bit
899 // GL_Upload8 (data, width, height, mipmap, alpha);
901 // GL_Upload32 (data, width, height, mipmap, true);
911 int GL_LoadPicTexture (qpic_t *pic)
913 return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true, 1);
916 int GL_GetTextureSlots (int count)
918 gltexture_t *glt, *first;
920 first = glt = &gltextures[numgltextures];
923 glt->identifier[0] = 0;
924 glt->texnum = texture_extension_number++;
928 glt->bytesperpixel = 0;
932 return first->texnum;