2 //**************************************************************************
6 //**************************************************************************
8 // HEADER FILES ------------------------------------------------------------
11 #define WIN32_LEAN_AND_MEAN
22 // MACROS ------------------------------------------------------------------
24 // TYPES -------------------------------------------------------------------
26 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
28 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
30 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
32 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
35 extern int numtextures;
36 extern texture_t** textures;
40 extern int maxTexSize; // Maximum supported texture size.
41 extern int ratioLimit;
44 // PUBLIC DATA DEFINITIONS -------------------------------------------------
48 // Properties of the current texture.
54 texsize_t *lumptexsizes; // Sizes for all the lumps.
55 unsigned short *spriteheights;
57 // PRIVATE DATA DEFINITIONS ------------------------------------------------
59 // Texture names for all lumps. Although the list will contain names for
60 // ALL lumps, only the graphics entries that aren't flats, wall textures or
62 static GLuint *lumptexnames, *lumptexnames2; // Support for two parts.
63 static int *rawlumps, numrawlumps; // Raw screen lumps (just lump numbers).
65 static GLuint *flattexnames, *texnames, *spritenames;
66 static char *texmasked; // 1 if the texture is masked.
67 //static int total_texmem_used = 0;
69 static GLuint dltexname; // Name of the dynamic light texture.
71 static int glmode[6] = // Indexed by 'mipmapping'.
75 GL_NEAREST_MIPMAP_NEAREST,
76 GL_LINEAR_MIPMAP_NEAREST,
77 GL_NEAREST_MIPMAP_LINEAR,
78 GL_LINEAR_MIPMAP_LINEAR
82 // CODE --------------------------------------------------------------------
84 int FindNextPower2(int num)
87 for(cumul=1; num > cumul; cumul *= 2);
91 float NextPower2Ratio(int num)
93 return num/(float)FindNextPower2(num);
98 // Allocate memory for the flat texture numbers.
99 flattexnames = Z_Malloc(sizeof(GLuint)*numflats, PU_STATIC, 0);
100 memset(flattexnames, 0, sizeof(GLuint)*numflats);
102 texnames = Z_Malloc(sizeof(GLuint)*numtextures, PU_STATIC, 0);
103 memset(texnames, 0, sizeof(GLuint)*numtextures);
105 texmasked = Z_Malloc(numtextures, PU_STATIC, 0);
106 memset(texmasked, 0, numtextures);
109 spritenames = Z_Malloc(sizeof(GLuint)*numspritelumps, PU_STATIC, 0);
110 memset(spritenames, 0, sizeof(GLuint)*numspritelumps);
111 spriteheights = Z_Malloc(sizeof(short)*numspritelumps, PU_STATIC, 0);
112 memset(spriteheights, 0, sizeof(short)*numspritelumps);
114 // Standard lump textures (raw images and other gfx).
116 lumptexnames = Z_Malloc(sizeof(GLuint)*numlumps, PU_STATIC, 0);
117 memset(lumptexnames, 0, sizeof(GLuint)*numlumps);
119 lumptexnames2 = Z_Malloc(sizeof(GLuint)*numlumps, PU_STATIC, 0);
120 memset(lumptexnames2, 0, sizeof(GLuint)*numlumps);
122 lumptexsizes = Z_Malloc(sizeof(texsize_t)*numlumps, PU_STATIC, 0);
123 memset(lumptexsizes, 0, sizeof(texsize_t)*numlumps);
125 // Raw screen lump book keeping.
129 // The dynamic light map.
132 // The palette lump, for color information (really?).
133 pallump = W_GetNumForName("PLAYPAL");
138 glDeleteTextures(numflats, flattexnames);
139 memset(flattexnames, 0, sizeof(GLuint)*numflats);
141 glDeleteTextures(numtextures, texnames);
142 memset(texnames, 0, sizeof(GLuint)*numtextures);
144 memset(texmasked, 0, numtextures);
146 glDeleteTextures(numspritelumps, spritenames);
147 memset(spritenames, 0, sizeof(GLuint)*numspritelumps);
148 memset(spriteheights, 0, sizeof(short)*numspritelumps);
150 // total_texmem_used = 0;
152 glDeleteTextures(1, &dltexname);
155 // Normal patch/raw image textures aren't deleted here (see below).
158 void OGL_ResetLumpTexData()
160 glDeleteTextures(numlumps, lumptexnames);
161 glDeleteTextures(numlumps, lumptexnames2);
162 memset(lumptexnames, 0, sizeof(GLuint)*numlumps);
163 memset(lumptexnames2, 0, sizeof(GLuint)*numlumps);
164 memset(lumptexsizes, 0, sizeof(texsize_t)*numlumps);
166 // Free the raw lumps book keeping table.
172 // Binds the texture if necessary.
173 void OGL_BindTexture(GLuint texname)
175 if(curtex != texname)
177 glBindTexture(GL_TEXTURE_2D, texname);
182 void PalToRGB(byte *palidx, byte *rgb)
187 *(rgb+i) = gammatable[usegamma][*(palidx+i)];
191 void PalIdxToRGB(byte *pal, int idx, byte *rgb)
193 PalToRGB(pal+idx*3, rgb);
196 unsigned int OGL_BindTexFlat(int lump)
200 byte *flatptr = W_CacheLumpNum(lump, PU_STATIC);
201 byte *palette = W_CacheLumpNum(pallump=W_GetNumForName("PLAYPAL"), PU_CACHE);
202 byte *rgbflat = (byte*)malloc(3*lumpinfo[lump].size);
204 //printf( "OGL_SetFlat: Loading flat %d.\n",idx);
205 // Convert the data to RGB.
206 for(i=0, p=0; i<lumpinfo[lump].size; i++)
207 PalIdxToRGB(palette, flatptr[i], rgbflat+i*3);
209 // Generate and bind the texture.
210 glGenTextures(1, &name);//flattexnames+idx);
211 glBindTexture(GL_TEXTURE_2D, name);//flattexnames[idx]);
213 // Set the texture properties.
216 glTexImage2D(GL_TEXTURE_2D, 0, 3, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, rgbflat);
219 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 64, 64, GL_RGB, GL_UNSIGNED_BYTE, rgbflat);
220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmapping]);
221 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
224 Z_ChangeTag(flatptr, PU_CACHE);
229 // Returns the OpenGL name of the texture.
230 unsigned int OGL_PrepareFlat(int idx)
232 idx = flattranslation[idx];
233 if(!flattexnames[idx])
235 // The flat isn't yet bound with OpenGL.
236 flattexnames[idx] = OGL_BindTexFlat(firstflat+idx);
240 return flattexnames[idx];
243 void OGL_SetFlat(int idx)
245 glBindTexture(GL_TEXTURE_2D, OGL_PrepareFlat(idx));
248 // Return GL_RGB or GL_RGBA.
249 static int DrawRealPatch(byte *rgbflat, byte *rgbaflat, byte *palette, int texwidth,
250 int texheight, patch_t *patch, boolean maskZero)
255 byte *desttop1, *desttop2;
256 byte *dest1=NULL, *dest2=NULL;
260 /* y -= SHORT(patch->topoffset);
261 x -= SHORT(patch->leftoffset);
262 if(x < 0 || x+SHORT(patch->width) > SCREENWIDTH || y < 0
263 || y+SHORT(patch->height) > SCREENHEIGHT)
265 I_Error("Bad V_DrawPatch");
268 desttop1 = rgbflat;// + y*SCREENWIDTH+x;
270 w = SHORT(patch->width);
271 for(; col < w; /*x++,*/ col++, desttop1+=3, desttop2+=4)
273 column = (column_t *)((byte *)patch+LONG(patch->columnofs[col]));
274 // Step through the posts in a column
275 while(column->topdelta != 0xff)
277 source = (byte *)column+3;
278 if(rgbflat) dest1 = desttop1 + column->topdelta*texwidth*3;
279 if(rgbaflat) dest2 = desttop2 + column->topdelta*texwidth*4;
280 count = column->length;
283 int palidx = *source++;
286 if(!maskZero || palidx) PalIdxToRGB(palette, palidx, dest1);
291 if(!maskZero || palidx)
293 PalIdxToRGB(palette, palidx, dest2);
294 *(dest2+3) = 0xff; // This pixel is not clear.
299 column = (column_t *)((byte *)column+column->length+4);
302 // Scan through the RGBA buffer and check for sub-0xff alpha.
303 if(rgbflat && rgbaflat) // Which one is it?
305 for(i=0; i<texwidth*texheight; i++)
306 if(*(rgbaflat + i*4 + 3) != 0xff) return GL_RGBA;
308 if(rgbflat) return GL_RGB;
310 //else return GL_RGBA; // Must be rgba.
311 // No alpha was found, RGB is enough.
315 // Returns the OpenGL texture name.
316 unsigned int OGL_PrepareTexture(int idx)
321 //glBindTexture(GL_TEXTURE_2D, 0);
328 idx = texturetranslation[idx];
331 // The texture must be given to OpenGL.
333 texture_t *tex = textures[idx];
334 byte *palette = W_CacheLumpNum(pallump, PU_CACHE);
335 byte *rgbflat = (byte *)malloc(3*tex->width*tex->height);
338 if(tex->patchcount > 1)
341 for(i=0; i<tex->width; i++)
343 colptr = R_GetColumn(idx,i);
344 for(k=0; k<tex->height; k++)
345 PalIdxToRGB(palette, colptr[k], rgbflat+(k*tex->width+i)*3);
350 // This texture has only only one patch. It might be masked.
351 byte *rgbaflat = (byte*)malloc(4*tex->width*tex->height);
352 memset(rgbaflat, 0, 4*tex->width*tex->height);
353 textype = DrawRealPatch(rgbflat, rgbaflat, palette, tex->width, tex->height,
354 W_CacheLumpNum(tex->patches[0].patch, PU_CACHE), false);
355 if(textype == GL_RGBA) { free(rgbflat); rgbflat = rgbaflat; }
356 else { free (rgbaflat); }
359 // Generate and bind the texture.
360 glGenTextures(1, texnames+idx);
361 glBindTexture(GL_TEXTURE_2D, texnames[idx]);
362 gluBuild2DMipmaps(GL_TEXTURE_2D, (textype==GL_RGB)?3:4, tex->width,
363 tex->height, textype, GL_UNSIGNED_BYTE, rgbflat);
364 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
365 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmapping]);
366 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
368 if(textype == GL_RGBA) texmasked[idx] = 1; // Yes it is.
372 texw = textures[idx]->width;
373 texh = textures[idx]->height;
374 texmask = texmasked[idx];
375 return texnames[idx];
378 void OGL_SetTexture(int idx)
380 glBindTexture(GL_TEXTURE_2D, OGL_PrepareTexture(idx));
383 int LineAverageRGB(byte *imgdata, int components, int width, int line, byte *rgb,
386 byte *start = imgdata + components*width*line;
388 int integerRGB[3] = {0,0,0};
390 for(i=0; i<width; i++)
392 byte *pixpos = start + i*components;
393 if(*(pixpos+3) > 0) // Not transparent?
396 for(c=0; c<3; c++) integerRGB[c] += pixpos[c];
399 // All transparent? Sorry...
402 // We're going to make it!
403 for(c=0; c<3; c++) rgb[c] = integerRGB[c]/count;
404 return 1; // Successful.
407 void ImageAverageRGB(byte *imgdata, int components, int width, int height, byte *rgb,
410 int i, c, integerRGB[3] = {0,0,0}, count = 0;
412 for(i=0; i<height; i++)
414 if(LineAverageRGB(imgdata, components, width, i, rgb, palette))
417 for(c=0; c<3; c++) integerRGB[c] += rgb[c];
420 if(count) // If there were pixels...
422 rgb[c] = integerRGB[c]/count;
425 unsigned int OGL_PrepareSky(int idx, boolean zeroMask)
427 if(idx != texturetranslation[idx])
428 I_Error("Skytex: %d, translated: %d\n", idx, texturetranslation[idx]);
430 idx = texturetranslation[idx];
435 byte *palette = W_CacheLumpNum(pallump, PU_CACHE);
436 texture_t *tex = textures[idx];
437 int textype, numpels = 256*256; // 'Full' size.
438 byte *imgdata, *colptr;
439 // Choose the right format.
443 imgdata = (byte *)malloc(4*numpels);
444 memset(imgdata, 0, 4*numpels);
449 imgdata = (byte *)malloc(3*numpels);
450 memset(imgdata, 0, 3*numpels);
452 if(tex->patchcount > 1)
454 for(i=0; i<tex->width; i++)
456 colptr = R_GetColumn(idx, i);
457 for(k=0; k<tex->height; k++)
459 if(textype == GL_RGB)
460 PalIdxToRGB(palette, colptr[k], imgdata+(k*256+i)*3);
461 else if(textype == GL_RGBA && colptr[k])
463 byte *imgpos = imgdata+(k*256+i)*4;
464 PalIdxToRGB(palette, colptr[k], imgpos);
465 *(imgpos+3) = 0xff; // Not transparent, this pixel.
472 // This texture has only only one patch.
473 if(textype == GL_RGB)
474 DrawRealPatch(imgdata, 0, palette, 256, tex->height,
475 W_CacheLumpNum(tex->patches[0].patch, PU_CACHE), false);
476 else if(textype == GL_RGBA) // Mask out zeros.
477 DrawRealPatch(0, imgdata, palette, 256, tex->height,
478 W_CacheLumpNum(tex->patches[0].patch, PU_CACHE), true);
480 if(textype == GL_RGBA) // For masked data, calculate the alpha-fill color.
483 ImageAverageRGB(imgdata, 4, 256, 200, rgbAverage, palette);
484 // Fill all the transparent places.
485 for(i=0; i<256*200; i++)
487 byte *pixel = imgdata + 4*i;
488 if(!pixel[3]) memcpy(pixel, rgbAverage, 3);
491 // Calculate the topline RGB for sky top fadeouts.
492 memset(topLineRGB, 0, 3);
493 LineAverageRGB(imgdata, (textype==GL_RGB)?3:4, 256, 0, topLineRGB, palette);
495 // Generate and bind the texture.
496 glGenTextures(1, texnames+idx);
497 glBindTexture(GL_TEXTURE_2D, texnames[idx]);
500 glTexImage2D(GL_TEXTURE_2D, 0, (textype==GL_RGB)?3:4, 256, 256, 0, GL_RGB,
501 GL_UNSIGNED_BYTE, imgdata);
504 gluBuild2DMipmaps(GL_TEXTURE_2D, (textype==GL_RGB)?3:4, 256, 256, textype,
505 GL_UNSIGNED_BYTE, imgdata);
506 // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
507 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmapping]);
508 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
510 // Do we have a masked texture?
511 if(textype == GL_RGBA)
518 texw = textures[idx]->width;
519 texh = textures[idx]->height;
520 texmask = texmasked[idx];
521 return texnames[idx];
524 unsigned int OGL_PrepareSprite(int pnum)
526 if(!spritenames[pnum])
528 // There's no name for this patch, load it in.
529 patch_t *patch = W_CacheLumpNum(firstspritelump+pnum, PU_CACHE);
530 int p2width = FindNextPower2(patch->width),
531 p2height = OGL_ValidTexHeight2(patch->width, patch->height);// FindNextPower2(patch->height);
532 int flatsize = 4*p2width*p2height;
533 byte *rgbaflat = (byte *)malloc(flatsize);
535 //printf( "orig: %d x %d => %d x %d\n", patch->width, patch->height, p2width, p2height);
537 memset(rgbaflat, 0, flatsize);
538 DrawRealPatch(0, rgbaflat, W_CacheLumpNum(pallump,PU_CACHE),
539 p2width, p2height, patch, false);
541 // Generate and bind the texture.
542 glGenTextures(1, spritenames+pnum);
543 glBindTexture(GL_TEXTURE_2D, spritenames[pnum]);
544 gluBuild2DMipmaps(GL_TEXTURE_2D, 4, p2width, p2height, GL_RGBA,
545 GL_UNSIGNED_BYTE, rgbaflat);
546 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmapping]);
547 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
548 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
549 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
551 spriteheights[pnum] = patch->height;
554 return spritenames[pnum];
557 void OGL_SetSprite(int pnum)
559 OGL_BindTexture(OGL_PrepareSprite(pnum));
562 void OGL_NewRawLump(int lump)
564 rawlumps = realloc(rawlumps, sizeof(int) * ++numrawlumps);
565 rawlumps[numrawlumps-1] = lump;
568 GLuint OGL_GetOtherPart(int lump)
570 return lumptexnames2[lump];
573 // Part is either 1 or 2. Part 0 means only the left side is loaded.
574 // No splittex is created in that case. Once a raw image is loaded
575 // as part 0 it must be deleted before the other part is loaded at the
577 void OGL_SetRawImage(int lump, int part)
579 if(part < 0 || part > 2) return; // Check the part.
581 if(!lumptexnames[lump])
583 // Load the raw texture data (320x200).
584 // We'll create two textures (256x256 and 64x256).
585 byte *raw = W_CacheLumpNum(lump, PU_CACHE);
586 byte *dat1 = (byte*)malloc(3*256*256);
587 byte *dat2 = (byte*)malloc(3*64*256);
588 byte *palette = W_CacheLumpNum(pallump, PU_CACHE);
590 memset(dat1, 0, 3*256*256); // Why must this be done?
594 // We can't go over the end.
595 if(k*320+i > lumpinfo[lump].size-1) break;
597 PalIdxToRGB(palette, *(raw+(k*320+i)), dat1+3*(k*256+i));
598 if(i<64 && part) // Part two?
599 PalIdxToRGB(palette, *(raw+(k*320+i+256)), dat2+3*(k*64+i));
602 // Do a special fill for textures with h<200 (part 0).
603 if(/*lumpinfo[lump].size/320 < 200 &&*/ !part)
605 int lines = lumpinfo[lump].size/320;
606 // Copy the missing data from the beginning.
607 memcpy(dat1+lines*256*3, dat1, 3*256*(256-lines));
610 // Generate and load the textures.
611 glGenTextures(1, lumptexnames+lump);
612 glBindTexture(GL_TEXTURE_2D, lumptexnames[lump]);
613 glTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, dat1);
614 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
615 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linearRaw? GL_LINEAR : GL_NEAREST);
619 // And the other part.
620 glGenTextures(1, lumptexnames2+lump);
621 glBindTexture(GL_TEXTURE_2D, lumptexnames2[lump]);
622 glTexImage2D(GL_TEXTURE_2D, 0, 3, 64, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, dat2);
623 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
624 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linearRaw? GL_LINEAR : GL_NEAREST);
625 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
627 // Add it to the list.
628 OGL_NewRawLump(lump);
631 lumptexsizes[lump].w = 256;
632 lumptexsizes[lump].w2 = 64;
633 lumptexsizes[lump].h = 200;
637 // Bind the correct part.
638 if(part <= 1) glBindTexture(GL_TEXTURE_2D, lumptexnames[lump]);
639 if(part == 2) glBindTexture(GL_TEXTURE_2D, lumptexnames2[lump]);
640 // We don't track the current texture with raw images.
644 // Copies a rectangular region of the source buffer to the destination
645 // buffer. Doesn't perform clipping, so be careful.
646 static void pixBlt(byte *src, int srcWidth, byte *dest, int destWidth, int pixelSize,
647 int srcRegX, int srcRegY, int destRegX, int destRegY,
648 int regWidth, int regHeight)
650 int y; // Y in the copy region.
651 for(y=0; y<regHeight; y++) // Copy line by line.
652 memcpy(dest + pixelSize*(destRegX + (y+destRegY)*destWidth),
653 src + pixelSize*(srcRegX + (y+srcRegY)*srcWidth),
657 // Notices ratiolimit.
658 int OGL_ValidTexHeight2(int width, int height)
660 int p2w, p2h = FindNextPower2(height);
663 if(!ratioLimit) return p2h;
665 p2w = FindNextPower2(width);
666 // Do we have to notice that the texture will be split?
669 int part2width = FindNextPower2(width - maxTexSize);
670 int height1 = maxTexSize/ratioLimit,
671 height2 = part2width/ratioLimit;
672 minheight = height1 > height2? height1 : height2;
674 else minheight = p2w/ratioLimit;
676 if(minheight > p2h) return minheight;
680 void OGL_SetPatch(int lump) // No mipmaps are generated.
682 if(!lumptexnames[lump])
685 patch_t *patch = W_CacheLumpNum(lump, PU_CACHE);
686 int p2width = FindNextPower2(patch->width),
687 p2height = OGL_ValidTexHeight2(patch->width, patch->height);//FindNextPower2(patch->height);
688 int numpels = p2width*p2height;
689 byte *rgbflat = (byte *)malloc(3*numpels),
690 *rgbaflat = (byte*)malloc(4*numpels);
693 memset(rgbaflat, 0, 4*numpels);
694 ptype = DrawRealPatch(rgbflat, rgbaflat, W_CacheLumpNum(pallump,PU_CACHE),
695 p2width, p2height, patch, false);
697 // See if we have to split the patch into two parts.
698 if(p2width > maxTexSize) // Nothing about the height...
700 // Notice: This is only vertical splitting, p2height
701 // applies to both parts.
702 // The width of the first part is maxTexSize.
703 int part2width = FindNextPower2(patch->width - maxTexSize);
704 byte *tempbuff = (byte*)malloc(4*maxTexSize*p2height);
705 if(part2width > maxTexSize)
706 I_Error("OGL_SetPatch: Too wide texture (really: %d, pow2: %d).\n", patch->width, p2width);
707 // We'll use a temporary buffer for doing to splitting.
709 pixBlt(ptype==GL_RGB? rgbflat : rgbaflat, p2width, tempbuff,
710 maxTexSize, ptype==GL_RGB? 3 : 4,
711 0, 0, 0, 0, maxTexSize, p2height);
712 // Generate a texture.
713 glGenTextures(1, lumptexnames+lump);
714 glBindTexture(GL_TEXTURE_2D, lumptexnames[lump]);
715 // There won't be mipmapping versions.
716 glTexImage2D(GL_TEXTURE_2D, 0, ptype==GL_RGB? 3 : 4, maxTexSize, p2height,
717 0, ptype, GL_UNSIGNED_BYTE, tempbuff);
718 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
719 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
720 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
721 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
724 pixBlt(ptype==GL_RGB? rgbflat : rgbaflat, p2width, tempbuff,
725 part2width, ptype==GL_RGB? 3 : 4,
726 maxTexSize, 0, 0, 0, part2width, p2height);
727 // Generate a texture.
728 glGenTextures(1, lumptexnames2+lump);
729 glBindTexture(GL_TEXTURE_2D, lumptexnames2[lump]);
730 // There won't be mipmapping versions.
731 glTexImage2D(GL_TEXTURE_2D, 0, ptype==GL_RGB? 3 : 4, part2width, p2height,
732 0, ptype, GL_UNSIGNED_BYTE, tempbuff);
733 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
734 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
735 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
736 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
738 OGL_BindTexture(lumptexnames[lump]);
740 lumptexsizes[lump].w = maxTexSize;
741 lumptexsizes[lump].w2 = patch->width - maxTexSize;
744 else // We can use the normal one-part method.
746 // Generate a texture.
747 glGenTextures(1, lumptexnames+lump);
748 glBindTexture(GL_TEXTURE_2D, lumptexnames[lump]);
749 // There won't be mipmapping versions.
750 glTexImage2D(GL_TEXTURE_2D, 0, (ptype==GL_RGB)?3:4, p2width, p2height,
751 0, ptype, GL_UNSIGNED_BYTE, (ptype==GL_RGB)?rgbflat:rgbaflat);
752 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
753 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
755 lumptexsizes[lump].w = patch->width;
756 lumptexsizes[lump].w2 = 0;
758 // The rest of the size information.
759 lumptexsizes[lump].h = patch->height;
760 lumptexsizes[lump].offx = -patch->leftoffset;
761 lumptexsizes[lump].offy = -patch->topoffset;
767 OGL_BindTexture(lumptexnames[lump]);
769 curtex = lumptexnames[lump];
773 // Drawing polygons with an unset texture causes a segfault with Mesa 3.0.
774 // I guess Windows OpenGL handles this ok.
775 // I am disabling texturing when needed rather than binding an unset texture.
776 void OGL_SetNoTexture()
779 //glBindTexture(GL_TEXTURE_2D, 0);
780 glDisable( GL_TEXTURE_2D );
786 GLuint OGL_PrepareLightTexture()
790 // We need to generate the texture, I see.
791 byte *image = W_CacheLumpName("DLIGHT", PU_CACHE);
793 I_Error("OGL_SetLightTexture: no dlight texture.\n");
794 // The dynamic light map is a 64x64 grayscale 8-bit image.
795 glGenTextures(1, &dltexname);
796 glBindTexture(GL_TEXTURE_2D, dltexname);
798 glTexImage2D(GL_TEXTURE_2D, 0, 1, 64, 64, 0, GL_LUMINANCE,
799 GL_UNSIGNED_BYTE, image);
800 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
801 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
802 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
803 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
811 int OGL_GetLumpTexWidth(int lump)
813 return lumptexsizes[lump].w;
816 int OGL_GetLumpTexHeight(int lump)
818 return lumptexsizes[lump].h;
821 // Updates the textures, flats and sprites.
822 void OGL_UpdateTexParams(int mipmode)
827 for(i=0; i<numtextures; i++)
828 if(texnames[i]) // Is the texture loaded?
830 glBindTexture(GL_TEXTURE_2D, texnames[i]);
831 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmode]);
834 for(i=0; i<numflats; i++)
835 if(flattexnames[i]) // Is the texture loaded?
837 glBindTexture(GL_TEXTURE_2D, flattexnames[i]);
838 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmode]);
841 for(i=0; i<numspritelumps; i++)
844 glBindTexture(GL_TEXTURE_2D, spritenames[i]);
845 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmode]);
849 // Updates the raw screen smoothing (linear magnification).
850 // This is the main reason for having the rawlumps table.
851 void OGL_UpdateRawScreenParams(int smoothing)
854 int glmode = (smoothing)? GL_LINEAR : GL_NEAREST;
856 for(i=0; i<numrawlumps; i++)
859 glBindTexture(GL_TEXTURE_2D, lumptexnames[rawlumps[i]]);
860 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glmode);
862 glBindTexture(GL_TEXTURE_2D, lumptexnames2[rawlumps[i]]);
863 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glmode);