2 //**************************************************************************
6 //**************************************************************************
8 // HEADER FILES ------------------------------------------------------------
11 #define WIN32_LEAN_AND_MEAN
21 // MACROS ------------------------------------------------------------------
23 // TYPES -------------------------------------------------------------------
25 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
27 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
29 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
31 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
34 extern int numtextures;
35 extern texture_t** textures;
39 extern int maxTexSize; // Maximum supported texture size.
40 extern int ratioLimit;
43 // PUBLIC DATA DEFINITIONS -------------------------------------------------
47 // Properties of the current texture.
53 texsize_t *lumptexsizes; // Sizes for all the lumps.
54 unsigned short *spriteheights;
56 // PRIVATE DATA DEFINITIONS ------------------------------------------------
58 // Texture names for all lumps. Although the list will contain names for
59 // ALL lumps, only the graphics entries that aren't flats, wall textures or
61 static GLuint *lumptexnames, *lumptexnames2; // Support for two parts.
62 static int *rawlumps, numrawlumps; // Raw screen lumps (just lump numbers).
64 static GLuint *flattexnames, *texnames, *spritenames;
65 static char *texmasked; // 1 if the texture is masked.
66 //static int total_texmem_used = 0;
68 static GLuint dltexname; // Name of the dynamic light texture.
70 static int glmode[6] = // Indexed by 'mipmapping'.
74 GL_NEAREST_MIPMAP_NEAREST,
75 GL_LINEAR_MIPMAP_NEAREST,
76 GL_NEAREST_MIPMAP_LINEAR,
77 GL_LINEAR_MIPMAP_LINEAR
81 // CODE --------------------------------------------------------------------
83 int FindNextPower2(int num)
86 for(cumul=1; num > cumul; cumul *= 2);
90 float NextPower2Ratio(int num)
92 return num/(float)FindNextPower2(num);
97 // Allocate memory for the flat texture numbers.
98 flattexnames = Z_Malloc(sizeof(GLuint)*numflats, PU_STATIC, 0);
99 memset(flattexnames, 0, sizeof(GLuint)*numflats);
101 texnames = Z_Malloc(sizeof(GLuint)*numtextures, PU_STATIC, 0);
102 memset(texnames, 0, sizeof(GLuint)*numtextures);
104 texmasked = Z_Malloc(numtextures, PU_STATIC, 0);
105 memset(texmasked, 0, numtextures);
108 spritenames = Z_Malloc(sizeof(GLuint)*numspritelumps, PU_STATIC, 0);
109 memset(spritenames, 0, sizeof(GLuint)*numspritelumps);
110 spriteheights = Z_Malloc(sizeof(short)*numspritelumps, PU_STATIC, 0);
111 memset(spriteheights, 0, sizeof(short)*numspritelumps);
113 // Standard lump textures (raw images and other gfx).
115 lumptexnames = Z_Malloc(sizeof(GLuint)*numlumps, PU_STATIC, 0);
116 memset(lumptexnames, 0, sizeof(GLuint)*numlumps);
118 lumptexnames2 = Z_Malloc(sizeof(GLuint)*numlumps, PU_STATIC, 0);
119 memset(lumptexnames2, 0, sizeof(GLuint)*numlumps);
121 lumptexsizes = Z_Malloc(sizeof(texsize_t)*numlumps, PU_STATIC, 0);
122 memset(lumptexsizes, 0, sizeof(texsize_t)*numlumps);
124 // Raw screen lump book keeping.
128 // The dynamic light map.
131 // The palette lump, for color information (really?).
132 pallump = W_GetNumForName("PLAYPAL");
137 glDeleteTextures(numflats, flattexnames);
138 memset(flattexnames, 0, sizeof(GLuint)*numflats);
140 glDeleteTextures(numtextures, texnames);
141 memset(texnames, 0, sizeof(GLuint)*numtextures);
143 memset(texmasked, 0, numtextures);
145 glDeleteTextures(numspritelumps, spritenames);
146 memset(spritenames, 0, sizeof(GLuint)*numspritelumps);
147 memset(spriteheights, 0, sizeof(short)*numspritelumps);
149 // total_texmem_used = 0;
151 glDeleteTextures(1, &dltexname);
154 // Normal patch/raw image textures aren't deleted here (see below).
157 void OGL_ResetLumpTexData()
159 glDeleteTextures(numlumps, lumptexnames);
160 glDeleteTextures(numlumps, lumptexnames2);
161 memset(lumptexnames, 0, sizeof(GLuint)*numlumps);
162 memset(lumptexnames2, 0, sizeof(GLuint)*numlumps);
163 memset(lumptexsizes, 0, sizeof(texsize_t)*numlumps);
165 // Free the raw lumps book keeping table.
171 // Binds the texture if necessary.
172 void OGL_BindTexture(GLuint texname)
174 if(curtex != texname)
176 glBindTexture(GL_TEXTURE_2D, texname);
181 void PalToRGB(byte *palidx, byte *rgb)
186 *(rgb+i) = gammatable[usegamma][*(palidx+i)];
190 void PalIdxToRGB(byte *pal, int idx, byte *rgb)
192 PalToRGB(pal+idx*3, rgb);
195 unsigned int OGL_BindTexFlat(int lump)
199 byte *flatptr = W_CacheLumpNum(lump, PU_STATIC);
200 byte *palette = W_CacheLumpNum(pallump=W_GetNumForName("PLAYPAL"), PU_CACHE);
201 byte *rgbflat = _alloca(3*lumpinfo[lump].size);
203 if (lumpinfo[lump].size < 4096)
205 printf ("Invalid Texture lump (%s,%d) found. Using texture 0\n",lumpinfo[lump].name, lump);
210 //printf( "OGL_SetFlat: Loading flat %d.\n",idx);
211 // Convert the data to RGB.
212 for(i=0, p=0; i<lumpinfo[lump].size; i++)
213 PalIdxToRGB(palette, flatptr[i], rgbflat+i*3);
215 // Generate and bind the texture.
216 glGenTextures(1, &name);//flattexnames+idx);
217 glBindTexture(GL_TEXTURE_2D, name);//flattexnames[idx]);
219 // Set the texture properties.
222 glTexImage2D(GL_TEXTURE_2D, 0, 3, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, rgbflat);
225 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 64, 64, GL_RGB, GL_UNSIGNED_BYTE, rgbflat);
227 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmapping]);
228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
231 Z_ChangeTag(flatptr, PU_CACHE);
235 // Returns the OpenGL name of the texture.
236 unsigned int OGL_PrepareFlat(int idx)
238 idx = flattranslation[idx];
239 if(!flattexnames[idx])
241 // The flat isn't yet bound with OpenGL.
242 flattexnames[idx] = OGL_BindTexFlat(firstflat+idx);
246 return flattexnames[idx];
249 void OGL_SetFlat(int idx)
251 glBindTexture(GL_TEXTURE_2D, OGL_PrepareFlat(idx));
254 // Return GL_RGB or GL_RGBA.
255 static int DrawRealPatch(byte *rgbflat, byte *rgbaflat, byte *palette, int texwidth,
256 int texheight, patch_t *patch, boolean maskZero)
261 byte *desttop1, *desttop2;
262 byte *dest1=NULL, *dest2=NULL;
266 /* y -= SHORT(patch->topoffset);
267 x -= SHORT(patch->leftoffset);
268 if(x < 0 || x+SHORT(patch->width) > SCREENWIDTH || y < 0
269 || y+SHORT(patch->height) > SCREENHEIGHT)
271 I_Error("Bad V_DrawPatch");
274 desttop1 = rgbflat;// + y*SCREENWIDTH+x;
276 w = SHORT(patch->width);
277 for(; col < w; /*x++,*/ col++, desttop1+=3, desttop2+=4)
279 column = (column_t *)((byte *)patch+LONG(patch->columnofs[col]));
280 // Step through the posts in a column
281 while(column->topdelta != 0xff)
283 source = (byte *)column+3;
284 if(rgbflat) dest1 = desttop1 + column->topdelta*texwidth*3;
285 if(rgbaflat) dest2 = desttop2 + column->topdelta*texwidth*4;
286 count = column->length;
289 int palidx = *source++;
292 if(!maskZero || palidx) PalIdxToRGB(palette, palidx, dest1);
297 if(!maskZero || palidx)
299 PalIdxToRGB(palette, palidx, dest2);
300 *(dest2+3) = 0xff; // This pixel is not clear.
305 column = (column_t *)((byte *)column+column->length+4);
308 // Scan through the RGBA buffer and check for sub-0xff alpha.
309 if(rgbflat && rgbaflat) // Which one is it?
311 for(i=0; i<texwidth*texheight; i++)
312 if(*(rgbaflat + i*4 + 3) != 0xff) return GL_RGBA;
314 if(rgbflat) return GL_RGB;
316 //else return GL_RGBA; // Must be rgba.
317 // No alpha was found, RGB is enough.
321 // Returns the OpenGL texture name.
322 unsigned int OGL_PrepareTexture(int idx)
327 //glBindTexture(GL_TEXTURE_2D, 0);
334 idx = texturetranslation[idx];
337 // The texture must be given to OpenGL.
339 texture_t *tex = textures[idx];
340 byte *palette = W_CacheLumpNum(pallump, PU_CACHE);
341 byte *rgbflat = _alloca(3*tex->width*tex->height);
344 if(tex->patchcount > 1)
347 for(i=0; i<tex->width; i++)
349 colptr = R_GetColumn(idx,i);
350 for(k=0; k<tex->height; k++)
351 PalIdxToRGB(palette, colptr[k], rgbflat+(k*tex->width+i)*3);
356 // This texture has only only one patch. It might be masked.
357 byte *rgbaflat = _alloca(4*tex->width*tex->height);
358 memset(rgbaflat, 0, 4*tex->width*tex->height);
359 textype = DrawRealPatch(rgbflat, rgbaflat, palette, tex->width, tex->height,
360 W_CacheLumpNum(tex->patches[0].patch, PU_CACHE), false);
361 if(textype == GL_RGBA) rgbflat = rgbaflat;
364 // Generate and bind the texture.
365 glGenTextures(1, texnames+idx);
366 glBindTexture(GL_TEXTURE_2D, texnames[idx]);
367 gluBuild2DMipmaps(GL_TEXTURE_2D, (textype==GL_RGB)?3:4, tex->width,
368 tex->height, textype, GL_UNSIGNED_BYTE, rgbflat);
369 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
370 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmapping]);
371 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
373 if(textype == GL_RGBA) texmasked[idx] = 1; // Yes it is.
375 texw = textures[idx]->width;
376 texh = textures[idx]->height;
377 texmask = texmasked[idx];
378 return texnames[idx];
381 void OGL_SetTexture(int idx)
383 glBindTexture(GL_TEXTURE_2D, OGL_PrepareTexture(idx));
386 int LineAverageRGB(byte *imgdata, int components, int width, int line, byte *rgb,
389 byte *start = imgdata + components*width*line;
391 int integerRGB[3] = {0,0,0};
393 for(i=0; i<width; i++)
395 byte *pixpos = start + i*components;
396 if(*(pixpos+3) > 0) // Not transparent?
399 for(c=0; c<3; c++) integerRGB[c] += pixpos[c];
402 // All transparent? Sorry...
405 // We're going to make it!
406 for(c=0; c<3; c++) rgb[c] = integerRGB[c]/count;
407 return 1; // Successful.
410 void ImageAverageRGB(byte *imgdata, int components, int width, int height, byte *rgb,
413 int i, c, integerRGB[3] = {0,0,0}, count = 0;
415 for(i=0; i<height; i++)
417 if(LineAverageRGB(imgdata, components, width, i, rgb, palette))
420 for(c=0; c<3; c++) integerRGB[c] += rgb[c];
423 if(count) // If there were pixels...
425 rgb[c] = integerRGB[c]/count;
428 unsigned int OGL_PrepareSky(int idx, boolean zeroMask)
430 if(idx != texturetranslation[idx])
431 I_Error("Skytex: %d, translated: %d\n", idx, texturetranslation[idx]);
433 idx = texturetranslation[idx];
438 byte *palette = W_CacheLumpNum(pallump, PU_CACHE);
439 texture_t *tex = textures[idx];
440 int textype, numpels = 256*256; // 'Full' size.
441 byte *imgdata, *colptr;
442 // Choose the right format.
446 imgdata = _alloca(4*numpels);
447 memset(imgdata, 0, 4*numpels);
452 imgdata = _alloca(3*numpels);
453 memset(imgdata, 0, 3*numpels);
455 if(tex->patchcount > 1)
457 for(i=0; i<tex->width; i++)
459 colptr = R_GetColumn(idx, i);
460 for(k=0; k<tex->height; k++)
462 if(textype == GL_RGB)
463 PalIdxToRGB(palette, colptr[k], imgdata+(k*256+i)*3);
464 else if(textype == GL_RGBA && colptr[k])
466 byte *imgpos = imgdata+(k*256+i)*4;
467 PalIdxToRGB(palette, colptr[k], imgpos);
468 *(imgpos+3) = 0xff; // Not transparent, this pixel.
475 // This texture has only only one patch.
476 if(textype == GL_RGB)
477 DrawRealPatch(imgdata, 0, palette, 256, tex->height,
478 W_CacheLumpNum(tex->patches[0].patch, PU_CACHE), false);
479 else if(textype == GL_RGBA) // Mask out zeros.
480 DrawRealPatch(0, imgdata, palette, 256, tex->height,
481 W_CacheLumpNum(tex->patches[0].patch, PU_CACHE), true);
483 if(textype == GL_RGBA) // For masked data, calculate the alpha-fill color.
486 ImageAverageRGB(imgdata, 4, 256, 200, rgbAverage, palette);
487 // Fill all the transparent places.
488 for(i=0; i<256*200; i++)
490 byte *pixel = imgdata + 4*i;
491 if(!pixel[3]) memcpy(pixel, rgbAverage, 3);
494 // Calculate the topline RGB for sky top fadeouts.
495 memset(topLineRGB, 0, 3);
496 LineAverageRGB(imgdata, (textype==GL_RGB)?3:4, 256, 0, topLineRGB, palette);
498 // Generate and bind the texture.
499 glGenTextures(1, texnames+idx);
500 glBindTexture(GL_TEXTURE_2D, texnames[idx]);
503 glTexImage2D(GL_TEXTURE_2D, 0, (textype==GL_RGB)?3:4, 256, 256, 0, GL_RGB,
504 GL_UNSIGNED_BYTE, imgdata);
507 gluBuild2DMipmaps(GL_TEXTURE_2D, (textype==GL_RGB)?3:4, 256, 256, textype,
508 GL_UNSIGNED_BYTE, imgdata);
509 // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
510 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmapping]);
511 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
513 // Do we have a masked texture?
514 if(textype == GL_RGBA)
519 texw = textures[idx]->width;
520 texh = textures[idx]->height;
521 texmask = texmasked[idx];
522 return texnames[idx];
525 unsigned int OGL_PrepareSprite(int pnum)
527 if(!spritenames[pnum])
529 // There's no name for this patch, load it in.
530 patch_t *patch = W_CacheLumpNum(firstspritelump+pnum, PU_CACHE);
531 int p2width = FindNextPower2(patch->width),
532 p2height = OGL_ValidTexHeight2(patch->width, patch->height);// FindNextPower2(patch->height);
533 int flatsize = 4*p2width*p2height;
534 byte *rgbaflat = _alloca(flatsize);
536 //printf( "orig: %d x %d => %d x %d\n", patch->width, patch->height, p2width, p2height);
538 memset(rgbaflat, 0, flatsize);
539 DrawRealPatch(0, rgbaflat, W_CacheLumpNum(pallump,PU_CACHE),
540 p2width, p2height, patch, false);
542 // Generate and bind the texture.
543 glGenTextures(1, spritenames+pnum);
544 glBindTexture(GL_TEXTURE_2D, spritenames[pnum]);
545 gluBuild2DMipmaps(GL_TEXTURE_2D, 4, p2width, p2height, GL_RGBA,
546 GL_UNSIGNED_BYTE, rgbaflat);
547 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmapping]);
548 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
549 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
550 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
552 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 = _alloca(3*256*256); // Let's hope there's enough stack!
587 byte *dat2 = _alloca(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;
635 // Bind the correct part.
636 if(part <= 1) glBindTexture(GL_TEXTURE_2D, lumptexnames[lump]);
637 if(part == 2) glBindTexture(GL_TEXTURE_2D, lumptexnames2[lump]);
638 // We don't track the current texture with raw images.
642 // Copies a rectangular region of the source buffer to the destination
643 // buffer. Doesn't perform clipping, so be careful.
644 static void pixBlt(byte *src, int srcWidth, byte *dest, int destWidth, int pixelSize,
645 int srcRegX, int srcRegY, int destRegX, int destRegY,
646 int regWidth, int regHeight)
648 int y; // Y in the copy region.
649 for(y=0; y<regHeight; y++) // Copy line by line.
650 memcpy(dest + pixelSize*(destRegX + (y+destRegY)*destWidth),
651 src + pixelSize*(srcRegX + (y+srcRegY)*srcWidth),
655 // Notices ratiolimit.
656 int OGL_ValidTexHeight2(int width, int height)
658 int p2w, p2h = FindNextPower2(height);
661 if(!ratioLimit) return p2h;
663 p2w = FindNextPower2(width);
664 // Do we have to notice that the texture will be split?
667 int part2width = FindNextPower2(width - maxTexSize);
668 int height1 = maxTexSize/ratioLimit,
669 height2 = part2width/ratioLimit;
670 minheight = height1 > height2? height1 : height2;
672 else minheight = p2w/ratioLimit;
674 if(minheight > p2h) return minheight;
678 void OGL_SetPatch(int lump) // No mipmaps are generated.
680 if(!lumptexnames[lump])
683 patch_t *patch = W_CacheLumpNum(lump, PU_CACHE);
684 int p2width = FindNextPower2(patch->width),
685 p2height = OGL_ValidTexHeight2(patch->width, patch->height);//FindNextPower2(patch->height);
686 int numpels = p2width*p2height;
687 byte *rgbflat = _alloca(3*numpels),
688 *rgbaflat = _alloca(4*numpels);
691 memset(rgbaflat, 0, 4*numpels);
692 ptype = DrawRealPatch(rgbflat, rgbaflat, W_CacheLumpNum(pallump,PU_CACHE),
693 p2width, p2height, patch, false);
695 // See if we have to split the patch into two parts.
696 if(p2width > maxTexSize) // Nothing about the height...
698 // Notice: This is only vertical splitting, p2height
699 // applies to both parts.
700 // The width of the first part is maxTexSize.
701 int part2width = FindNextPower2(patch->width - maxTexSize);
702 byte *tempbuff = _alloca(4*maxTexSize*p2height);
703 if(part2width > maxTexSize)
704 I_Error("OGL_SetPatch: Too wide texture (really: %d, pow2: %d).\n", patch->width, p2width);
705 // We'll use a temporary buffer for doing to splitting.
707 pixBlt(ptype==GL_RGB? rgbflat : rgbaflat, p2width, tempbuff,
708 maxTexSize, ptype==GL_RGB? 3 : 4,
709 0, 0, 0, 0, maxTexSize, p2height);
710 // Generate a texture.
711 glGenTextures(1, lumptexnames+lump);
712 glBindTexture(GL_TEXTURE_2D, lumptexnames[lump]);
713 // There won't be mipmapping versions.
714 glTexImage2D(GL_TEXTURE_2D, 0, ptype==GL_RGB? 3 : 4, maxTexSize, p2height,
715 0, ptype, GL_UNSIGNED_BYTE, tempbuff);
716 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
717 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
718 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
719 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
722 pixBlt(ptype==GL_RGB? rgbflat : rgbaflat, p2width, tempbuff,
723 part2width, ptype==GL_RGB? 3 : 4,
724 maxTexSize, 0, 0, 0, part2width, p2height);
725 // Generate a texture.
726 glGenTextures(1, lumptexnames2+lump);
727 glBindTexture(GL_TEXTURE_2D, lumptexnames2[lump]);
728 // There won't be mipmapping versions.
729 glTexImage2D(GL_TEXTURE_2D, 0, ptype==GL_RGB? 3 : 4, part2width, p2height,
730 0, ptype, GL_UNSIGNED_BYTE, tempbuff);
731 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
732 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
733 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
734 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
736 OGL_BindTexture(lumptexnames[lump]);
738 lumptexsizes[lump].w = maxTexSize;
739 lumptexsizes[lump].w2 = patch->width - maxTexSize;
741 else // We can use the normal one-part method.
743 // Generate a texture.
744 glGenTextures(1, lumptexnames+lump);
745 glBindTexture(GL_TEXTURE_2D, lumptexnames[lump]);
746 // There won't be mipmapping versions.
747 glTexImage2D(GL_TEXTURE_2D, 0, (ptype==GL_RGB)?3:4, p2width, p2height,
748 0, ptype, GL_UNSIGNED_BYTE, (ptype==GL_RGB)?rgbflat:rgbaflat);
749 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
750 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
752 lumptexsizes[lump].w = patch->width;
753 lumptexsizes[lump].w2 = 0;
755 // The rest of the size information.
756 lumptexsizes[lump].h = patch->height;
757 lumptexsizes[lump].offx = -patch->leftoffset;
758 lumptexsizes[lump].offy = -patch->topoffset;
762 OGL_BindTexture(lumptexnames[lump]);
764 curtex = lumptexnames[lump];
768 // Drawing polygons with an unset texture causes a segfault with Mesa 3.0.
769 // I guess Windows OpenGL handles this ok.
770 // I am disabling texturing when needed rather than binding an unset texture.
771 void OGL_SetNoTexture()
774 //glBindTexture(GL_TEXTURE_2D, 0);
775 glDisable( GL_TEXTURE_2D );
781 GLuint OGL_PrepareLightTexture()
785 // We need to generate the texture, I see.
786 byte *image = W_CacheLumpName("DLIGHT", PU_CACHE);
788 I_Error("OGL_SetLightTexture: no dlight texture.\n");
789 // The dynamic light map is a 64x64 grayscale 8-bit image.
790 glGenTextures(1, &dltexname);
791 glBindTexture(GL_TEXTURE_2D, dltexname);
793 glTexImage2D(GL_TEXTURE_2D, 0, 1, 64, 64, 0, GL_LUMINANCE,
794 GL_UNSIGNED_BYTE, image);
795 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
796 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
797 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
798 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
806 int OGL_GetLumpTexWidth(int lump)
808 return lumptexsizes[lump].w;
811 int OGL_GetLumpTexHeight(int lump)
813 return lumptexsizes[lump].h;
816 // Updates the textures, flats and sprites.
817 void OGL_UpdateTexParams(int mipmode)
822 for(i=0; i<numtextures; i++)
823 if(texnames[i]) // Is the texture loaded?
825 glBindTexture(GL_TEXTURE_2D, texnames[i]);
826 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmode]);
829 for(i=0; i<numflats; i++)
830 if(flattexnames[i]) // Is the texture loaded?
832 glBindTexture(GL_TEXTURE_2D, flattexnames[i]);
833 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmode]);
836 for(i=0; i<numspritelumps; i++)
839 glBindTexture(GL_TEXTURE_2D, spritenames[i]);
840 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmode]);
844 // Updates the raw screen smoothing (linear magnification).
845 // This is the main reason for having the rawlumps table.
846 void OGL_UpdateRawScreenParams(int smoothing)
849 int glmode = (smoothing)? GL_LINEAR : GL_NEAREST;
851 for(i=0; i<numrawlumps; i++)
854 glBindTexture(GL_TEXTURE_2D, lumptexnames[rawlumps[i]]);
855 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glmode);
857 glBindTexture(GL_TEXTURE_2D, lumptexnames2[rawlumps[i]]);
858 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glmode);