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 = _alloca(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);
228 // Returns the OpenGL name of the texture.
229 unsigned int OGL_PrepareFlat(int idx)
231 idx = flattranslation[idx];
232 if(!flattexnames[idx])
234 // The flat isn't yet bound with OpenGL.
235 flattexnames[idx] = OGL_BindTexFlat(firstflat+idx);
239 return flattexnames[idx];
242 void OGL_SetFlat(int idx)
244 glBindTexture(GL_TEXTURE_2D, OGL_PrepareFlat(idx));
247 // Return GL_RGB or GL_RGBA.
248 static int DrawRealPatch(byte *rgbflat, byte *rgbaflat, byte *palette, int texwidth,
249 int texheight, patch_t *patch, boolean maskZero)
254 byte *desttop1, *desttop2;
255 byte *dest1=NULL, *dest2=NULL;
259 /* y -= SHORT(patch->topoffset);
260 x -= SHORT(patch->leftoffset);
261 if(x < 0 || x+SHORT(patch->width) > SCREENWIDTH || y < 0
262 || y+SHORT(patch->height) > SCREENHEIGHT)
264 I_Error("Bad V_DrawPatch");
267 desttop1 = rgbflat;// + y*SCREENWIDTH+x;
269 w = SHORT(patch->width);
270 for(; col < w; /*x++,*/ col++, desttop1+=3, desttop2+=4)
272 column = (column_t *)((byte *)patch+LONG(patch->columnofs[col]));
273 // Step through the posts in a column
274 while(column->topdelta != 0xff)
276 source = (byte *)column+3;
277 if(rgbflat) dest1 = desttop1 + column->topdelta*texwidth*3;
278 if(rgbaflat) dest2 = desttop2 + column->topdelta*texwidth*4;
279 count = column->length;
282 int palidx = *source++;
285 if(!maskZero || palidx) PalIdxToRGB(palette, palidx, dest1);
290 if(!maskZero || palidx)
292 PalIdxToRGB(palette, palidx, dest2);
293 *(dest2+3) = 0xff; // This pixel is not clear.
298 column = (column_t *)((byte *)column+column->length+4);
301 // Scan through the RGBA buffer and check for sub-0xff alpha.
302 if(rgbflat && rgbaflat) // Which one is it?
304 for(i=0; i<texwidth*texheight; i++)
305 if(*(rgbaflat + i*4 + 3) != 0xff) return GL_RGBA;
307 if(rgbflat) return GL_RGB;
309 //else return GL_RGBA; // Must be rgba.
310 // No alpha was found, RGB is enough.
314 // Returns the OpenGL texture name.
315 unsigned int OGL_PrepareTexture(int idx)
320 //glBindTexture(GL_TEXTURE_2D, 0);
327 idx = texturetranslation[idx];
330 // The texture must be given to OpenGL.
332 texture_t *tex = textures[idx];
333 byte *palette = W_CacheLumpNum(pallump, PU_CACHE);
334 byte *rgbflat = _alloca(3*tex->width*tex->height);
337 if(tex->patchcount > 1)
340 for(i=0; i<tex->width; i++)
342 colptr = R_GetColumn(idx,i);
343 for(k=0; k<tex->height; k++)
344 PalIdxToRGB(palette, colptr[k], rgbflat+(k*tex->width+i)*3);
349 // This texture has only only one patch. It might be masked.
350 byte *rgbaflat = _alloca(4*tex->width*tex->height);
351 memset(rgbaflat, 0, 4*tex->width*tex->height);
352 textype = DrawRealPatch(rgbflat, rgbaflat, palette, tex->width, tex->height,
353 W_CacheLumpNum(tex->patches[0].patch, PU_CACHE), false);
354 if(textype == GL_RGBA) rgbflat = rgbaflat;
357 // Generate and bind the texture.
358 glGenTextures(1, texnames+idx);
359 glBindTexture(GL_TEXTURE_2D, texnames[idx]);
360 gluBuild2DMipmaps(GL_TEXTURE_2D, (textype==GL_RGB)?3:4, tex->width,
361 tex->height, textype, GL_UNSIGNED_BYTE, rgbflat);
362 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
363 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmapping]);
364 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
366 if(textype == GL_RGBA) texmasked[idx] = 1; // Yes it is.
368 texw = textures[idx]->width;
369 texh = textures[idx]->height;
370 texmask = texmasked[idx];
371 return texnames[idx];
374 void OGL_SetTexture(int idx)
376 glBindTexture(GL_TEXTURE_2D, OGL_PrepareTexture(idx));
379 int LineAverageRGB(byte *imgdata, int components, int width, int line, byte *rgb,
382 byte *start = imgdata + components*width*line;
384 int integerRGB[3] = {0,0,0};
386 for(i=0; i<width; i++)
388 byte *pixpos = start + i*components;
389 if(*(pixpos+3) > 0) // Not transparent?
392 for(c=0; c<3; c++) integerRGB[c] += pixpos[c];
395 // All transparent? Sorry...
398 // We're going to make it!
399 for(c=0; c<3; c++) rgb[c] = integerRGB[c]/count;
400 return 1; // Successful.
403 void ImageAverageRGB(byte *imgdata, int components, int width, int height, byte *rgb,
406 int i, c, integerRGB[3] = {0,0,0}, count = 0;
408 for(i=0; i<height; i++)
410 if(LineAverageRGB(imgdata, components, width, i, rgb, palette))
413 for(c=0; c<3; c++) integerRGB[c] += rgb[c];
416 if(count) // If there were pixels...
418 rgb[c] = integerRGB[c]/count;
421 unsigned int OGL_PrepareSky(int idx, boolean zeroMask)
423 if(idx != texturetranslation[idx])
424 I_Error("Skytex: %d, translated: %d\n", idx, texturetranslation[idx]);
426 idx = texturetranslation[idx];
431 byte *palette = W_CacheLumpNum(pallump, PU_CACHE);
432 texture_t *tex = textures[idx];
433 int textype, numpels = 256*256; // 'Full' size.
434 byte *imgdata, *colptr;
435 // Choose the right format.
439 imgdata = _alloca(4*numpels);
440 memset(imgdata, 0, 4*numpels);
445 imgdata = _alloca(3*numpels);
446 memset(imgdata, 0, 3*numpels);
448 if(tex->patchcount > 1)
450 for(i=0; i<tex->width; i++)
452 colptr = R_GetColumn(idx, i);
453 for(k=0; k<tex->height; k++)
455 if(textype == GL_RGB)
456 PalIdxToRGB(palette, colptr[k], imgdata+(k*256+i)*3);
457 else if(textype == GL_RGBA && colptr[k])
459 byte *imgpos = imgdata+(k*256+i)*4;
460 PalIdxToRGB(palette, colptr[k], imgpos);
461 *(imgpos+3) = 0xff; // Not transparent, this pixel.
468 // This texture has only only one patch.
469 if(textype == GL_RGB)
470 DrawRealPatch(imgdata, 0, palette, 256, tex->height,
471 W_CacheLumpNum(tex->patches[0].patch, PU_CACHE), false);
472 else if(textype == GL_RGBA) // Mask out zeros.
473 DrawRealPatch(0, imgdata, palette, 256, tex->height,
474 W_CacheLumpNum(tex->patches[0].patch, PU_CACHE), true);
476 if(textype == GL_RGBA) // For masked data, calculate the alpha-fill color.
479 ImageAverageRGB(imgdata, 4, 256, 200, rgbAverage, palette);
480 // Fill all the transparent places.
481 for(i=0; i<256*200; i++)
483 byte *pixel = imgdata + 4*i;
484 if(!pixel[3]) memcpy(pixel, rgbAverage, 3);
487 // Calculate the topline RGB for sky top fadeouts.
488 memset(topLineRGB, 0, 3);
489 LineAverageRGB(imgdata, (textype==GL_RGB)?3:4, 256, 0, topLineRGB, palette);
491 // Generate and bind the texture.
492 glGenTextures(1, texnames+idx);
493 glBindTexture(GL_TEXTURE_2D, texnames[idx]);
496 glTexImage2D(GL_TEXTURE_2D, 0, (textype==GL_RGB)?3:4, 256, 256, 0, GL_RGB,
497 GL_UNSIGNED_BYTE, imgdata);
500 gluBuild2DMipmaps(GL_TEXTURE_2D, (textype==GL_RGB)?3:4, 256, 256, textype,
501 GL_UNSIGNED_BYTE, imgdata);
502 // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
503 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmapping]);
504 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
506 // Do we have a masked texture?
507 if(textype == GL_RGBA)
512 texw = textures[idx]->width;
513 texh = textures[idx]->height;
514 texmask = texmasked[idx];
515 return texnames[idx];
518 unsigned int OGL_PrepareSprite(int pnum)
520 if(!spritenames[pnum])
522 // There's no name for this patch, load it in.
523 patch_t *patch = W_CacheLumpNum(firstspritelump+pnum, PU_CACHE);
524 int p2width = FindNextPower2(patch->width),
525 p2height = OGL_ValidTexHeight2(patch->width, patch->height);// FindNextPower2(patch->height);
526 int flatsize = 4*p2width*p2height;
527 byte *rgbaflat = _alloca(flatsize);
529 //printf( "orig: %d x %d => %d x %d\n", patch->width, patch->height, p2width, p2height);
531 memset(rgbaflat, 0, flatsize);
532 DrawRealPatch(0, rgbaflat, W_CacheLumpNum(pallump,PU_CACHE),
533 p2width, p2height, patch, false);
535 // Generate and bind the texture.
536 glGenTextures(1, spritenames+pnum);
537 glBindTexture(GL_TEXTURE_2D, spritenames[pnum]);
538 gluBuild2DMipmaps(GL_TEXTURE_2D, 4, p2width, p2height, GL_RGBA,
539 GL_UNSIGNED_BYTE, rgbaflat);
540 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmapping]);
541 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
542 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
543 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
545 spriteheights[pnum] = patch->height;
547 return spritenames[pnum];
550 void OGL_SetSprite(int pnum)
552 OGL_BindTexture(OGL_PrepareSprite(pnum));
555 void OGL_NewRawLump(int lump)
557 rawlumps = realloc(rawlumps, sizeof(int) * ++numrawlumps);
558 rawlumps[numrawlumps-1] = lump;
561 GLuint OGL_GetOtherPart(int lump)
563 return lumptexnames2[lump];
566 // Part is either 1 or 2. Part 0 means only the left side is loaded.
567 // No splittex is created in that case. Once a raw image is loaded
568 // as part 0 it must be deleted before the other part is loaded at the
570 void OGL_SetRawImage(int lump, int part)
572 if(part < 0 || part > 2) return; // Check the part.
574 if(!lumptexnames[lump])
576 // Load the raw texture data (320x200).
577 // We'll create two textures (256x256 and 64x256).
578 byte *raw = W_CacheLumpNum(lump, PU_CACHE);
579 byte *dat1 = _alloca(3*256*256); // Let's hope there's enough stack!
580 byte *dat2 = _alloca(3*64*256);
581 byte *palette = W_CacheLumpNum(pallump, PU_CACHE);
583 memset(dat1, 0, 3*256*256); // Why must this be done?
587 // We can't go over the end.
588 if(k*320+i > lumpinfo[lump].size-1) break;
590 PalIdxToRGB(palette, *(raw+(k*320+i)), dat1+3*(k*256+i));
591 if(i<64 && part) // Part two?
592 PalIdxToRGB(palette, *(raw+(k*320+i+256)), dat2+3*(k*64+i));
595 // Do a special fill for textures with h<200 (part 0).
596 if(/*lumpinfo[lump].size/320 < 200 &&*/ !part)
598 int lines = lumpinfo[lump].size/320;
599 // Copy the missing data from the beginning.
600 memcpy(dat1+lines*256*3, dat1, 3*256*(256-lines));
603 // Generate and load the textures.
604 glGenTextures(1, lumptexnames+lump);
605 glBindTexture(GL_TEXTURE_2D, lumptexnames[lump]);
606 glTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, dat1);
607 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
608 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linearRaw? GL_LINEAR : GL_NEAREST);
612 // And the other part.
613 glGenTextures(1, lumptexnames2+lump);
614 glBindTexture(GL_TEXTURE_2D, lumptexnames2[lump]);
615 glTexImage2D(GL_TEXTURE_2D, 0, 3, 64, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, dat2);
616 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
617 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linearRaw? GL_LINEAR : GL_NEAREST);
618 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
620 // Add it to the list.
621 OGL_NewRawLump(lump);
624 lumptexsizes[lump].w = 256;
625 lumptexsizes[lump].w2 = 64;
626 lumptexsizes[lump].h = 200;
628 // Bind the correct part.
629 if(part <= 1) glBindTexture(GL_TEXTURE_2D, lumptexnames[lump]);
630 if(part == 2) glBindTexture(GL_TEXTURE_2D, lumptexnames2[lump]);
631 // We don't track the current texture with raw images.
635 // Copies a rectangular region of the source buffer to the destination
636 // buffer. Doesn't perform clipping, so be careful.
637 static void pixBlt(byte *src, int srcWidth, byte *dest, int destWidth, int pixelSize,
638 int srcRegX, int srcRegY, int destRegX, int destRegY,
639 int regWidth, int regHeight)
641 int y; // Y in the copy region.
642 for(y=0; y<regHeight; y++) // Copy line by line.
643 memcpy(dest + pixelSize*(destRegX + (y+destRegY)*destWidth),
644 src + pixelSize*(srcRegX + (y+srcRegY)*srcWidth),
648 // Notices ratiolimit.
649 int OGL_ValidTexHeight2(int width, int height)
651 int p2w, p2h = FindNextPower2(height);
654 if(!ratioLimit) return p2h;
656 p2w = FindNextPower2(width);
657 // Do we have to notice that the texture will be split?
660 int part2width = FindNextPower2(width - maxTexSize);
661 int height1 = maxTexSize/ratioLimit,
662 height2 = part2width/ratioLimit;
663 minheight = height1 > height2? height1 : height2;
665 else minheight = p2w/ratioLimit;
667 if(minheight > p2h) return minheight;
671 void OGL_SetPatch(int lump) // No mipmaps are generated.
673 if(!lumptexnames[lump])
676 patch_t *patch = W_CacheLumpNum(lump, PU_CACHE);
677 int p2width = FindNextPower2(patch->width),
678 p2height = OGL_ValidTexHeight2(patch->width, patch->height);//FindNextPower2(patch->height);
679 int numpels = p2width*p2height;
680 byte *rgbflat = _alloca(3*numpels),
681 *rgbaflat = _alloca(4*numpels);
684 memset(rgbaflat, 0, 4*numpels);
685 ptype = DrawRealPatch(rgbflat, rgbaflat, W_CacheLumpNum(pallump,PU_CACHE),
686 p2width, p2height, patch, false);
688 // See if we have to split the patch into two parts.
689 if(p2width > maxTexSize) // Nothing about the height...
691 // Notice: This is only vertical splitting, p2height
692 // applies to both parts.
693 // The width of the first part is maxTexSize.
694 int part2width = FindNextPower2(patch->width - maxTexSize);
695 byte *tempbuff = _alloca(4*maxTexSize*p2height);
696 if(part2width > maxTexSize)
697 I_Error("OGL_SetPatch: Too wide texture (really: %d, pow2: %d).\n", patch->width, p2width);
698 // We'll use a temporary buffer for doing to splitting.
700 pixBlt(ptype==GL_RGB? rgbflat : rgbaflat, p2width, tempbuff,
701 maxTexSize, ptype==GL_RGB? 3 : 4,
702 0, 0, 0, 0, maxTexSize, p2height);
703 // Generate a texture.
704 glGenTextures(1, lumptexnames+lump);
705 glBindTexture(GL_TEXTURE_2D, lumptexnames[lump]);
706 // There won't be mipmapping versions.
707 glTexImage2D(GL_TEXTURE_2D, 0, ptype==GL_RGB? 3 : 4, maxTexSize, p2height,
708 0, ptype, GL_UNSIGNED_BYTE, tempbuff);
709 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
710 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
711 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
712 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
715 pixBlt(ptype==GL_RGB? rgbflat : rgbaflat, p2width, tempbuff,
716 part2width, ptype==GL_RGB? 3 : 4,
717 maxTexSize, 0, 0, 0, part2width, p2height);
718 // Generate a texture.
719 glGenTextures(1, lumptexnames2+lump);
720 glBindTexture(GL_TEXTURE_2D, lumptexnames2[lump]);
721 // There won't be mipmapping versions.
722 glTexImage2D(GL_TEXTURE_2D, 0, ptype==GL_RGB? 3 : 4, part2width, p2height,
723 0, ptype, GL_UNSIGNED_BYTE, tempbuff);
724 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
725 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
726 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
727 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
729 OGL_BindTexture(lumptexnames[lump]);
731 lumptexsizes[lump].w = maxTexSize;
732 lumptexsizes[lump].w2 = patch->width - maxTexSize;
734 else // We can use the normal one-part method.
736 // Generate a texture.
737 glGenTextures(1, lumptexnames+lump);
738 glBindTexture(GL_TEXTURE_2D, lumptexnames[lump]);
739 // There won't be mipmapping versions.
740 glTexImage2D(GL_TEXTURE_2D, 0, (ptype==GL_RGB)?3:4, p2width, p2height,
741 0, ptype, GL_UNSIGNED_BYTE, (ptype==GL_RGB)?rgbflat:rgbaflat);
742 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
743 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
745 lumptexsizes[lump].w = patch->width;
746 lumptexsizes[lump].w2 = 0;
748 // The rest of the size information.
749 lumptexsizes[lump].h = patch->height;
750 lumptexsizes[lump].offx = -patch->leftoffset;
751 lumptexsizes[lump].offy = -patch->topoffset;
755 OGL_BindTexture(lumptexnames[lump]);
757 curtex = lumptexnames[lump];
761 // Drawing polygons with an unset texture causes a segfault with Mesa 3.0.
762 // I guess Windows OpenGL handles this ok.
763 // I am disabling texturing when needed rather than binding an unset texture.
764 void OGL_SetNoTexture()
767 //glBindTexture(GL_TEXTURE_2D, 0);
768 glDisable( GL_TEXTURE_2D );
774 GLuint OGL_PrepareLightTexture()
778 // We need to generate the texture, I see.
779 byte *image = W_CacheLumpName("DLIGHT", PU_CACHE);
781 I_Error("OGL_SetLightTexture: no dlight texture.\n");
782 // The dynamic light map is a 64x64 grayscale 8-bit image.
783 glGenTextures(1, &dltexname);
784 glBindTexture(GL_TEXTURE_2D, dltexname);
786 glTexImage2D(GL_TEXTURE_2D, 0, 1, 64, 64, 0, GL_LUMINANCE,
787 GL_UNSIGNED_BYTE, image);
788 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
789 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
790 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
791 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
799 int OGL_GetLumpTexWidth(int lump)
801 return lumptexsizes[lump].w;
804 int OGL_GetLumpTexHeight(int lump)
806 return lumptexsizes[lump].h;
809 // Updates the textures, flats and sprites.
810 void OGL_UpdateTexParams(int mipmode)
815 for(i=0; i<numtextures; i++)
816 if(texnames[i]) // Is the texture loaded?
818 glBindTexture(GL_TEXTURE_2D, texnames[i]);
819 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmode]);
822 for(i=0; i<numflats; i++)
823 if(flattexnames[i]) // Is the texture loaded?
825 glBindTexture(GL_TEXTURE_2D, flattexnames[i]);
826 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmode]);
829 for(i=0; i<numspritelumps; i++)
832 glBindTexture(GL_TEXTURE_2D, spritenames[i]);
833 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glmode[mipmode]);
837 // Updates the raw screen smoothing (linear magnification).
838 // This is the main reason for having the rawlumps table.
839 void OGL_UpdateRawScreenParams(int smoothing)
842 int glmode = (smoothing)? GL_LINEAR : GL_NEAREST;
844 for(i=0; i<numrawlumps; i++)
847 glBindTexture(GL_TEXTURE_2D, lumptexnames[rawlumps[i]]);
848 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glmode);
850 glBindTexture(GL_TEXTURE_2D, lumptexnames2[rawlumps[i]]);
851 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glmode);