1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
3 *
4 *
5 * PrBoom: a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
11 * Copyright 2005, 2006 by
12 * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 * 02111-1307, USA.
28 *
29 * DESCRIPTION:
30 *
31 *---------------------------------------------------------------------
32 */
33
34 #include "z_zone.h"
35 #ifdef _WIN32
36 #define WIN32_LEAN_AND_MEAN
37 #include <windows.h>
38 #endif
39 #ifndef CALLBACK
40 #define CALLBACK
41 #endif
42 #include <stdio.h>
43 #include <string.h>
44 #include <math.h>
45 #include <SDL.h>
46 #include <SDL_opengl.h>
47 #include "doomtype.h"
48 #include "w_wad.h"
49 #include "m_argv.h"
50 #include "d_event.h"
51 #include "v_video.h"
52 #include "doomstat.h"
53 #include "r_bsp.h"
54 #include "r_main.h"
55 #include "r_draw.h"
56 #include "r_sky.h"
57 #include "r_plane.h"
58 #include "r_data.h"
59 #include "p_maputl.h"
60 #include "p_tick.h"
61 #include "m_bbox.h"
62 #include "lprintf.h"
63 #include "gl_intern.h"
64 #include "gl_struct.h"
65
66 /* TEXTURES */
67 static GLTexture **gld_GLTextures=NULL;
68 /* PATCHES FLATS SPRITES */
69 static GLTexture **gld_GLPatchTextures=NULL;
70
71 boolean use_mipmapping=false;
72
73 int gld_max_texturesize=0;
74 char *gl_tex_format_string;
75 //int gl_tex_format=GL_RGBA8;
76 int gl_tex_format=GL_RGB5_A1;
77 //int gl_tex_format=GL_RGBA4;
78 //int gl_tex_format=GL_RGBA2;
79
80 GLTexture *last_gltexture=NULL;
81 int last_cm=-1;
82
83 int transparent_pal_index;
84 unsigned char gld_palmap[256];
85
gld_InitPalettedTextures(void)86 void gld_InitPalettedTextures(void)
87 {
88 const unsigned char *playpal;
89 int pal[256];
90 int i,j;
91
92 playpal=W_CacheLumpName("PLAYPAL");
93 for (i=0; i<256; i++) {
94 pal[i] = (playpal[i*3+0] << 16) | (playpal[i*3+1] << 8) | playpal[i*3+2];
95 gld_palmap[i] = i;
96 }
97 transparent_pal_index = -1;
98 for (i=0; i<256; i++) {
99 for (j=i+1; j<256; j++) {
100 if (pal[i] == pal[j]) {
101 transparent_pal_index = j;
102 gld_palmap[j] = i;
103 break;
104 }
105 }
106 if (transparent_pal_index >= 0)
107 break;
108 }
109 W_UnlockLumpName("PLAYPAL");
110 }
111
gld_GetTexDimension(int value)112 int gld_GetTexDimension(int value)
113 {
114 int i;
115
116 i=1;
117 while (i<value)
118 i*=2;
119 if (i>gld_max_texturesize)
120 i=gld_max_texturesize;
121 return i;
122 }
123
gld_AddNewGLTexture(int texture_num)124 static GLTexture *gld_AddNewGLTexture(int texture_num)
125 {
126 if (texture_num<0)
127 return NULL;
128 if (texture_num>=numtextures)
129 return NULL;
130 if (!gld_GLTextures)
131 {
132 gld_GLTextures=Z_Malloc(numtextures*sizeof(GLTexture *),PU_STATIC,0);
133 memset(gld_GLTextures,0,numtextures*sizeof(GLTexture *));
134 }
135 if (!gld_GLTextures[texture_num])
136 {
137 gld_GLTextures[texture_num]=Z_Malloc(sizeof(GLTexture),PU_STATIC,0);
138 memset(gld_GLTextures[texture_num], 0, sizeof(GLTexture));
139 gld_GLTextures[texture_num]->textype=GLDT_UNREGISTERED;
140 }
141 return gld_GLTextures[texture_num];
142 }
143
gld_AddNewGLPatchTexture(int lump)144 static GLTexture *gld_AddNewGLPatchTexture(int lump)
145 {
146 if (lump<0)
147 return NULL;
148 if (lump>=numlumps)
149 return NULL;
150 if (!gld_GLPatchTextures)
151 {
152 gld_GLPatchTextures=Z_Malloc(numlumps*sizeof(GLTexture *),PU_STATIC,0);
153 memset(gld_GLPatchTextures,0,numlumps*sizeof(GLTexture *));
154 }
155 if (!gld_GLPatchTextures[lump])
156 {
157 gld_GLPatchTextures[lump]=Z_Malloc(sizeof(GLTexture),PU_STATIC,0);
158 memset(gld_GLPatchTextures[lump], 0, sizeof(GLTexture));
159 gld_GLPatchTextures[lump]->textype=GLDT_UNREGISTERED;
160 }
161 return gld_GLPatchTextures[lump];
162 }
163
gld_SetTexturePalette(GLenum target)164 void gld_SetTexturePalette(GLenum target)
165 {
166 const unsigned char *playpal;
167 unsigned char pal[1024];
168 int i;
169
170 playpal=W_CacheLumpName("PLAYPAL");
171 for (i=0; i<256; i++) {
172 pal[i*4+0] = playpal[i*3+0];
173 pal[i*4+1] = playpal[i*3+1];
174 pal[i*4+2] = playpal[i*3+2];
175 pal[i*4+3] = 255;
176 }
177 pal[transparent_pal_index*4+0]=0;
178 pal[transparent_pal_index*4+1]=0;
179 pal[transparent_pal_index*4+2]=0;
180 pal[transparent_pal_index*4+3]=0;
181 gld_ColorTableEXT(target, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, pal);
182 W_UnlockLumpName("PLAYPAL");
183 }
184
gld_AddPatchToTexture_UnTranslated(GLTexture * gltexture,unsigned char * buffer,const rpatch_t * patch,int originx,int originy,int paletted)185 static void gld_AddPatchToTexture_UnTranslated(GLTexture *gltexture, unsigned char *buffer, const rpatch_t *patch, int originx, int originy, int paletted)
186 {
187 int x,y,j;
188 int xs,xe;
189 int js,je;
190 const rcolumn_t *column;
191 const byte *source;
192 int i, pos;
193 const unsigned char *playpal;
194
195 if (!gltexture)
196 return;
197 if (!patch)
198 return;
199 playpal=W_CacheLumpName("PLAYPAL");
200 xs=0;
201 xe=patch->width;
202 if ((xs+originx)>=gltexture->realtexwidth)
203 return;
204 if ((xe+originx)<=0)
205 return;
206 if ((xs+originx)<0)
207 xs=-originx;
208 if ((xe+originx)>gltexture->realtexwidth)
209 xe+=(gltexture->realtexwidth-(xe+originx));
210 for (x=xs;x<xe;x++)
211 {
212 #ifdef RANGECHECK
213 if (x>=patch->width)
214 {
215 lprintf(LO_ERROR,"gld_AddPatchToTexture_UnTranslated x>=patch->width (%i >= %i)\n",x,patch->width);
216 return;
217 }
218 #endif
219 column = &patch->columns[x];
220 for (i=0; i<column->numPosts; i++) {
221 const rpost_t *post = &column->posts[i];
222 y=(post->topdelta+originy);
223 js=0;
224 je=post->length;
225 if ((js+y)>=gltexture->realtexheight)
226 continue;
227 if ((je+y)<=0)
228 continue;
229 if ((js+y)<0)
230 js=-y;
231 if ((je+y)>gltexture->realtexheight)
232 je+=(gltexture->realtexheight-(je+y));
233 source = column->pixels + post->topdelta;
234 if (paletted) {
235 pos=(((js+y)*gltexture->buffer_width)+x+originx);
236 for (j=js;j<je;j++,pos+=(gltexture->buffer_width))
237 {
238 #ifdef RANGECHECK
239 if (pos>=gltexture->buffer_size)
240 {
241 lprintf(LO_ERROR,"gld_AddPatchToTexture_UnTranslated pos>=size (%i >= %i)\n",pos+3,gltexture->buffer_size);
242 return;
243 }
244 #endif
245 buffer[pos]=gld_palmap[source[j]];
246 }
247 } else {
248 pos=4*(((js+y)*gltexture->buffer_width)+x+originx);
249 for (j=js;j<je;j++,pos+=(4*gltexture->buffer_width))
250 {
251 #ifdef RANGECHECK
252 if ((pos+3)>=gltexture->buffer_size)
253 {
254 lprintf(LO_ERROR,"gld_AddPatchToTexture_UnTranslated pos+3>=size (%i >= %i)\n",pos+3,gltexture->buffer_size);
255 return;
256 }
257 #endif
258 buffer[pos]=playpal[source[j]*3];
259 buffer[pos+1]=playpal[source[j]*3+1];
260 buffer[pos+2]=playpal[source[j]*3+2];
261 buffer[pos+3]=255;
262 }
263 }
264 }
265 }
266 W_UnlockLumpName("PLAYPAL");
267 }
268
gld_AddPatchToTexture(GLTexture * gltexture,unsigned char * buffer,const rpatch_t * patch,int originx,int originy,int cm,int paletted)269 void gld_AddPatchToTexture(GLTexture *gltexture, unsigned char *buffer, const rpatch_t *patch, int originx, int originy, int cm, int paletted)
270 {
271 int x,y,j;
272 int xs,xe;
273 int js,je;
274 const rcolumn_t *column;
275 const byte *source;
276 int i, pos;
277 const unsigned char *playpal;
278 const unsigned char *outr;
279
280 if (!gltexture)
281 return;
282 if (!patch)
283 return;
284 if ((cm==CR_DEFAULT) || (cm==CR_LIMIT))
285 {
286 gld_AddPatchToTexture_UnTranslated(gltexture,buffer,patch,originx,originy, paletted);
287 return;
288 }
289 if (cm<CR_LIMIT)
290 outr=colrngs[cm];
291 else
292 outr=translationtables + 256*((cm-CR_LIMIT)-1);
293 playpal=W_CacheLumpName("PLAYPAL");
294 xs=0;
295 xe=patch->width;
296 if ((xs+originx)>=gltexture->realtexwidth)
297 return;
298 if ((xe+originx)<=0)
299 return;
300 if ((xs+originx)<0)
301 xs=-originx;
302 if ((xe+originx)>gltexture->realtexwidth)
303 xe+=(gltexture->realtexwidth-(xe+originx));
304 for (x=xs;x<xe;x++)
305 {
306 #ifdef RANGECHECK
307 if (x>=patch->width)
308 {
309 lprintf(LO_ERROR,"gld_AddPatchToTexture x>=patch->width (%i >= %i)\n",x,patch->width);
310 return;
311 }
312 #endif
313 column = &patch->columns[x];
314 for (i=0; i<column->numPosts; i++) {
315 const rpost_t *post = &column->posts[i];
316 y=(post->topdelta+originy);
317 js=0;
318 je=post->length;
319 if ((js+y)>=gltexture->realtexheight)
320 continue;
321 if ((je+y)<=0)
322 continue;
323 if ((js+y)<0)
324 js=-y;
325 if ((je+y)>gltexture->realtexheight)
326 je+=(gltexture->realtexheight-(je+y));
327 source = column->pixels + post->topdelta;
328 if (paletted) {
329 pos=(((js+y)*gltexture->buffer_width)+x+originx);
330 for (j=js;j<je;j++,pos+=(gltexture->buffer_width))
331 {
332 #ifdef RANGECHECK
333 if (pos>=gltexture->buffer_size)
334 {
335 lprintf(LO_ERROR,"gld_AddPatchToTexture_UnTranslated pos>=size (%i >= %i)\n",pos+3,gltexture->buffer_size);
336 return;
337 }
338 #endif
339 buffer[pos]=gld_palmap[outr[source[j]]];
340 }
341 } else {
342 pos=4*(((js+y)*gltexture->buffer_width)+x+originx);
343 for (j=js;j<je;j++,pos+=(4*gltexture->buffer_width))
344 {
345 #ifdef RANGECHECK
346 if ((pos+3)>=gltexture->buffer_size)
347 {
348 lprintf(LO_ERROR,"gld_AddPatchToTexture pos+3>=size (%i >= %i)\n",pos+3,gltexture->buffer_size);
349 return;
350 }
351 #endif
352 buffer[pos]=playpal[outr[source[j]]*3];
353 buffer[pos+1]=playpal[outr[source[j]]*3+1];
354 buffer[pos+2]=playpal[outr[source[j]]*3+2];
355 buffer[pos+3]=255;
356 }
357 }
358 }
359 }
360 W_UnlockLumpName("PLAYPAL");
361 }
362
gld_AddFlatToTexture(GLTexture * gltexture,unsigned char * buffer,const unsigned char * flat,int paletted)363 static void gld_AddFlatToTexture(GLTexture *gltexture, unsigned char *buffer, const unsigned char *flat, int paletted)
364 {
365 int x,y,pos;
366 const unsigned char *playpal;
367
368 if (!gltexture)
369 return;
370 if (!flat)
371 return;
372 if (paletted) {
373 for (y=0;y<gltexture->realtexheight;y++)
374 {
375 pos=(y*gltexture->buffer_width);
376 for (x=0;x<gltexture->realtexwidth;x++,pos++)
377 {
378 #ifdef RANGECHECK
379 if (pos>=gltexture->buffer_size)
380 {
381 lprintf(LO_ERROR,"gld_AddFlatToTexture pos>=size (%i >= %i)\n",pos,gltexture->buffer_size);
382 return;
383 }
384 #endif
385 buffer[pos]=gld_palmap[flat[y*64+x]];
386 }
387 }
388 } else {
389 playpal=W_CacheLumpName("PLAYPAL");
390 for (y=0;y<gltexture->realtexheight;y++)
391 {
392 pos=4*(y*gltexture->buffer_width);
393 for (x=0;x<gltexture->realtexwidth;x++,pos+=4)
394 {
395 #ifdef RANGECHECK
396 if ((pos+3)>=gltexture->buffer_size)
397 {
398 lprintf(LO_ERROR,"gld_AddFlatToTexture pos+3>=size (%i >= %i)\n",pos+3,gltexture->buffer_size);
399 return;
400 }
401 #endif
402 buffer[pos]=playpal[flat[y*64+x]*3];
403 buffer[pos+1]=playpal[flat[y*64+x]*3+1];
404 buffer[pos+2]=playpal[flat[y*64+x]*3+2];
405 buffer[pos+3]=255;
406 }
407 }
408 W_UnlockLumpName("PLAYPAL");
409 }
410 }
411
412 //e6y: "force" flag for loading texture with zero index
gld_RegisterTexture(int texture_num,boolean mipmap,boolean force)413 GLTexture *gld_RegisterTexture(int texture_num, boolean mipmap, boolean force)
414 {
415 GLTexture *gltexture;
416
417 //e6y: textures with zero index should be loaded sometimes
418 if (texture_num==NO_TEXTURE && !force)
419 return NULL;
420 gltexture=gld_AddNewGLTexture(texture_num);
421 if (!gltexture)
422 return NULL;
423 if (gltexture->textype==GLDT_UNREGISTERED)
424 {
425 texture_t *texture=NULL;
426
427 if ((texture_num>=0) || (texture_num<numtextures))
428 texture=textures[texture_num];
429 if (!texture)
430 return NULL;
431 gltexture->textype=GLDT_BROKEN;
432 gltexture->index=texture_num;
433 gltexture->mipmap=mipmap;
434 gltexture->realtexwidth=texture->width;
435 gltexture->realtexheight=texture->height;
436 gltexture->leftoffset=0;
437 gltexture->topoffset=0;
438 gltexture->tex_width=gld_GetTexDimension(gltexture->realtexwidth);
439 gltexture->tex_height=gld_GetTexDimension(gltexture->realtexheight);
440 gltexture->width=MIN(gltexture->realtexwidth, gltexture->tex_width);
441 gltexture->height=MIN(gltexture->realtexheight, gltexture->tex_height);
442 gltexture->buffer_width=gltexture->tex_width;
443 gltexture->buffer_height=gltexture->tex_height;
444 #ifdef USE_GLU_IMAGESCALE
445 gltexture->width=gltexture->tex_width;
446 gltexture->height=gltexture->tex_height;
447 gltexture->buffer_width=gltexture->realtexwidth;
448 gltexture->buffer_height=gltexture->realtexheight;
449 #endif
450 if (gltexture->mipmap & use_mipmapping)
451 {
452 gltexture->width=gltexture->tex_width;
453 gltexture->height=gltexture->tex_height;
454 gltexture->buffer_width=gltexture->realtexwidth;
455 gltexture->buffer_height=gltexture->realtexheight;
456 }
457 gltexture->buffer_size=gltexture->buffer_width*gltexture->buffer_height*4;
458 if (gltexture->realtexwidth>gltexture->buffer_width)
459 return gltexture;
460 if (gltexture->realtexheight>gltexture->buffer_height)
461 return gltexture;
462 gltexture->textype=GLDT_TEXTURE;
463 }
464 return gltexture;
465 }
466
gld_BindTexture(GLTexture * gltexture)467 void gld_BindTexture(GLTexture *gltexture)
468 {
469 const rpatch_t *patch;
470 int i;
471 unsigned char *buffer;
472
473 if (gltexture==last_gltexture)
474 return;
475 last_gltexture=gltexture;
476 if (!gltexture) {
477 glBindTexture(GL_TEXTURE_2D, 0);
478 last_gltexture = NULL;
479 last_cm = -1;
480 return;
481 }
482 if (gltexture->textype!=GLDT_TEXTURE)
483 {
484 glBindTexture(GL_TEXTURE_2D, 0);
485 last_gltexture = NULL;
486 last_cm = -1;
487 return;
488 }
489 if (gltexture->glTexID[CR_DEFAULT]!=0)
490 {
491 glBindTexture(GL_TEXTURE_2D, gltexture->glTexID[CR_DEFAULT]);
492 glGetTexParameteriv(GL_TEXTURE_2D,GL_TEXTURE_RESIDENT,&i);
493 #ifdef _DEBUG
494 if (i!=GL_TRUE)
495 lprintf(LO_INFO, "glGetTexParam: %i\n", i);
496 #endif
497 if (i==GL_TRUE)
498 return;
499 }
500 buffer=(unsigned char*)Z_Malloc(gltexture->buffer_size,PU_STATIC,0);
501 if (!(gltexture->mipmap & use_mipmapping) & gl_paletted_texture)
502 memset(buffer,transparent_pal_index,gltexture->buffer_size);
503 else
504 memset(buffer,0,gltexture->buffer_size);
505 patch=R_CacheTextureCompositePatchNum(gltexture->index);
506 gld_AddPatchToTexture(gltexture, buffer, patch,
507 0, 0,
508 CR_DEFAULT, !(gltexture->mipmap & use_mipmapping) & gl_paletted_texture);
509 R_UnlockTextureCompositePatchNum(gltexture->index);
510 if (gltexture->glTexID[CR_DEFAULT]==0)
511 glGenTextures(1,&gltexture->glTexID[CR_DEFAULT]);
512 glBindTexture(GL_TEXTURE_2D, gltexture->glTexID[CR_DEFAULT]);
513 #ifdef USE_GLU_MIPMAP
514 if (gltexture->mipmap & use_mipmapping)
515 {
516 gluBuild2DMipmaps(GL_TEXTURE_2D, gl_tex_format,
517 gltexture->buffer_width, gltexture->buffer_height,
518 GL_RGBA, GL_UNSIGNED_BYTE, buffer);
519 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
520 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
521 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter);
522 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_mipmap_filter);
523 if (gl_texture_filter_anisotropic)
524 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0);
525 }
526 else
527 #endif /* USE_GLU_MIPMAP */
528 {
529 #ifdef USE_GLU_IMAGESCALE
530 if ((gltexture->buffer_width!=gltexture->tex_width) ||
531 (gltexture->buffer_height!=gltexture->tex_height)
532 )
533 {
534 unsigned char *scaledbuffer;
535
536 scaledbuffer=(unsigned char*)Z_Malloc(gltexture->tex_width*gltexture->tex_height*4,PU_STATIC,0);
537 if (scaledbuffer)
538 {
539 gluScaleImage(GL_RGBA,
540 gltexture->buffer_width, gltexture->buffer_height,
541 GL_UNSIGNED_BYTE,buffer,
542 gltexture->tex_width, gltexture->tex_height,
543 GL_UNSIGNED_BYTE,scaledbuffer);
544 Z_Free(buffer);
545 buffer=scaledbuffer;
546 glTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format,
547 gltexture->tex_width, gltexture->tex_height,
548 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
549 }
550 }
551 else
552 #endif /* USE_GLU_IMAGESCALE */
553 {
554 if (gl_paletted_texture) {
555 gld_SetTexturePalette(GL_TEXTURE_2D);
556 glTexImage2D( GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT,
557 gltexture->buffer_width, gltexture->buffer_height,
558 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, buffer);
559 } else {
560 glTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format,
561 gltexture->buffer_width, gltexture->buffer_height,
562 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
563 }
564 }
565 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
566 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
567 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter);
568 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_filter);
569 }
570 Z_Free(buffer);
571 }
572
gld_RegisterPatch(int lump,int cm)573 GLTexture *gld_RegisterPatch(int lump, int cm)
574 {
575 const rpatch_t *patch;
576 GLTexture *gltexture;
577
578 gltexture=gld_AddNewGLPatchTexture(lump);
579 if (!gltexture)
580 return NULL;
581 if (gltexture->textype==GLDT_UNREGISTERED)
582 {
583 patch=R_CachePatchNum(lump);
584 if (!patch)
585 return NULL;
586 gltexture->textype=GLDT_BROKEN;
587 gltexture->index=lump;
588 gltexture->mipmap=false;
589 gltexture->realtexwidth=patch->width;
590 gltexture->realtexheight=patch->height;
591 gltexture->leftoffset=patch->leftoffset;
592 gltexture->topoffset=patch->topoffset;
593 gltexture->tex_width=gld_GetTexDimension(gltexture->realtexwidth);
594 gltexture->tex_height=gld_GetTexDimension(gltexture->realtexheight);
595 gltexture->width=MIN(gltexture->realtexwidth, gltexture->tex_width);
596 gltexture->height=MIN(gltexture->realtexheight, gltexture->tex_height);
597 gltexture->buffer_width=gltexture->tex_width;
598 gltexture->buffer_height=gltexture->tex_height;
599 #ifdef USE_GLU_IMAGESCALE
600 gltexture->width=MIN(gltexture->realtexwidth, gltexture->tex_width);
601 gltexture->height=MIN(gltexture->realtexheight, gltexture->tex_height);
602 gltexture->buffer_width=MAX(gltexture->realtexwidth, gltexture->tex_width);
603 gltexture->buffer_height=MAX(gltexture->realtexheight, gltexture->tex_height);
604 #endif
605 gltexture->buffer_size=gltexture->buffer_width*gltexture->buffer_height*4;
606 R_UnlockPatchNum(lump);
607 if (gltexture->realtexwidth>gltexture->buffer_width)
608 return gltexture;
609 if (gltexture->realtexheight>gltexture->buffer_height)
610 return gltexture;
611 gltexture->textype=GLDT_PATCH;
612 }
613 return gltexture;
614 }
615
gld_BindPatch(GLTexture * gltexture,int cm)616 void gld_BindPatch(GLTexture *gltexture, int cm)
617 {
618 const rpatch_t *patch;
619 int i;
620 unsigned char *buffer;
621
622 if ((gltexture==last_gltexture) && (cm==last_cm))
623 return;
624 last_gltexture=gltexture;
625 last_cm=cm;
626 if (!gltexture)
627 return;
628 if (gltexture->textype!=GLDT_PATCH)
629 {
630 glBindTexture(GL_TEXTURE_2D, 0);
631 last_gltexture = NULL;
632 last_cm = -1;
633 return;
634 }
635 if (gltexture->glTexID[cm]!=0)
636 {
637 glBindTexture(GL_TEXTURE_2D, gltexture->glTexID[cm]);
638 glGetTexParameteriv(GL_TEXTURE_2D,GL_TEXTURE_RESIDENT,&i);
639 #ifdef _DEBUG
640 if (i!=GL_TRUE)
641 lprintf(LO_INFO, "glGetTexParam: %i\n", i);
642 #endif
643 if (i==GL_TRUE)
644 return;
645 }
646 patch=R_CachePatchNum(gltexture->index);
647 buffer=(unsigned char*)Z_Malloc(gltexture->buffer_size,PU_STATIC,0);
648 if (gl_paletted_texture)
649 memset(buffer,transparent_pal_index,gltexture->buffer_size);
650 else
651 memset(buffer,0,gltexture->buffer_size);
652 gld_AddPatchToTexture(gltexture, buffer, patch, 0, 0, cm, gl_paletted_texture);
653 if (gltexture->glTexID[cm]==0)
654 glGenTextures(1,&gltexture->glTexID[cm]);
655 glBindTexture(GL_TEXTURE_2D, gltexture->glTexID[cm]);
656 #ifdef USE_GLU_IMAGESCALE
657 if ((gltexture->buffer_width>gltexture->tex_width) ||
658 (gltexture->buffer_height>gltexture->tex_height)
659 )
660 {
661 unsigned char *scaledbuffer;
662
663 scaledbuffer=(unsigned char*)Z_Malloc(gltexture->tex_width*gltexture->tex_height*4,PU_STATIC,0);
664 if (scaledbuffer)
665 {
666 gluScaleImage(GL_RGBA,
667 gltexture->buffer_width, gltexture->buffer_height,
668 GL_UNSIGNED_BYTE,buffer,
669 gltexture->tex_width, gltexture->tex_height,
670 GL_UNSIGNED_BYTE,scaledbuffer);
671 Z_Free(buffer);
672 buffer=scaledbuffer;
673 glTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format,
674 gltexture->tex_width, gltexture->tex_height,
675 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
676 }
677 }
678 else
679 #endif /* USE_GLU_IMAGESCALE */
680 {
681 if (gl_paletted_texture) {
682 gld_SetTexturePalette(GL_TEXTURE_2D);
683 glTexImage2D( GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT,
684 gltexture->buffer_width, gltexture->buffer_height,
685 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, buffer);
686 } else {
687 glTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format,
688 gltexture->buffer_width, gltexture->buffer_height,
689 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
690 }
691 }
692 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
693 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
694 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter);
695 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_filter);
696 Z_Free(buffer);
697 R_UnlockPatchNum(gltexture->index);
698 }
699
gld_RegisterFlat(int lump,boolean mipmap)700 GLTexture *gld_RegisterFlat(int lump, boolean mipmap)
701 {
702 GLTexture *gltexture;
703
704 gltexture=gld_AddNewGLPatchTexture(firstflat+lump);
705 if (!gltexture)
706 return NULL;
707 if (gltexture->textype==GLDT_UNREGISTERED)
708 {
709 gltexture->textype=GLDT_BROKEN;
710 gltexture->index=firstflat+lump;
711 gltexture->mipmap=mipmap;
712 gltexture->realtexwidth=64;
713 gltexture->realtexheight=64;
714 gltexture->leftoffset=0;
715 gltexture->topoffset=0;
716 gltexture->tex_width=gld_GetTexDimension(gltexture->realtexwidth);
717 gltexture->tex_height=gld_GetTexDimension(gltexture->realtexheight);
718 gltexture->width=MIN(gltexture->realtexwidth, gltexture->tex_width);
719 gltexture->height=MIN(gltexture->realtexheight, gltexture->tex_height);
720 gltexture->buffer_width=gltexture->tex_width;
721 gltexture->buffer_height=gltexture->tex_height;
722 #ifdef USE_GLU_IMAGESCALE
723 gltexture->width=gltexture->tex_width;
724 gltexture->height=gltexture->tex_height;
725 gltexture->buffer_width=gltexture->realtexwidth;
726 gltexture->buffer_height=gltexture->realtexheight;
727 #endif
728 if (gltexture->mipmap & use_mipmapping)
729 {
730 gltexture->width=gltexture->tex_width;
731 gltexture->height=gltexture->tex_height;
732 gltexture->buffer_width=gltexture->realtexwidth;
733 gltexture->buffer_height=gltexture->realtexheight;
734 }
735 gltexture->buffer_size=gltexture->buffer_width*gltexture->buffer_height*4;
736 if (gltexture->realtexwidth>gltexture->buffer_width)
737 return gltexture;
738 if (gltexture->realtexheight>gltexture->buffer_height)
739 return gltexture;
740 gltexture->textype=GLDT_FLAT;
741 }
742 return gltexture;
743 }
744
gld_BindFlat(GLTexture * gltexture)745 void gld_BindFlat(GLTexture *gltexture)
746 {
747 const unsigned char *flat;
748 int i;
749 unsigned char *buffer;
750
751 if (gltexture==last_gltexture)
752 return;
753 last_gltexture=gltexture;
754 if (!gltexture)
755 return;
756 if (gltexture->textype!=GLDT_FLAT)
757 {
758 glBindTexture(GL_TEXTURE_2D, 0);
759 last_gltexture = NULL;
760 last_cm = -1;
761 return;
762 }
763 if (gltexture->glTexID[CR_DEFAULT]!=0)
764 {
765 glBindTexture(GL_TEXTURE_2D, gltexture->glTexID[CR_DEFAULT]);
766 glGetTexParameteriv(GL_TEXTURE_2D,GL_TEXTURE_RESIDENT,&i);
767 #ifdef _DEBUG
768 if (i!=GL_TRUE)
769 lprintf(LO_INFO, "glGetTexParam: %i\n", i);
770 #endif
771 if (i==GL_TRUE)
772 return;
773 }
774 flat=W_CacheLumpNum(gltexture->index);
775 buffer=(unsigned char*)Z_Malloc(gltexture->buffer_size,PU_STATIC,0);
776 if (!(gltexture->mipmap & use_mipmapping) & gl_paletted_texture)
777 memset(buffer,transparent_pal_index,gltexture->buffer_size);
778 else
779 memset(buffer,0,gltexture->buffer_size);
780 gld_AddFlatToTexture(gltexture, buffer, flat, !(gltexture->mipmap & use_mipmapping) & gl_paletted_texture);
781 if (gltexture->glTexID[CR_DEFAULT]==0)
782 glGenTextures(1,&gltexture->glTexID[CR_DEFAULT]);
783 glBindTexture(GL_TEXTURE_2D, gltexture->glTexID[CR_DEFAULT]);
784 #ifdef USE_GLU_MIPMAP
785 if (gltexture->mipmap & use_mipmapping)
786 {
787 gluBuild2DMipmaps(GL_TEXTURE_2D, gl_tex_format,
788 gltexture->buffer_width, gltexture->buffer_height,
789 GL_RGBA, GL_UNSIGNED_BYTE, buffer);
790 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
791 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
792 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter);
793 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_mipmap_filter);
794 if (gl_texture_filter_anisotropic)
795 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0);
796 }
797 else
798 #endif /* USE_GLU_MIPMAP */
799 {
800 #ifdef USE_GLU_IMAGESCALE
801 if ((gltexture->buffer_width!=gltexture->tex_width) ||
802 (gltexture->buffer_height!=gltexture->tex_height)
803 )
804 {
805 unsigned char *scaledbuffer;
806
807 scaledbuffer=(unsigned char*)Z_Malloc(gltexture->tex_width*gltexture->tex_height*4,PU_STATIC,0);
808 if (scaledbuffer)
809 {
810 gluScaleImage(GL_RGBA,
811 gltexture->buffer_width, gltexture->buffer_height,
812 GL_UNSIGNED_BYTE,buffer,
813 gltexture->tex_width, gltexture->tex_height,
814 GL_UNSIGNED_BYTE,scaledbuffer);
815 Z_Free(buffer);
816 buffer=scaledbuffer;
817 glTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format,
818 gltexture->tex_width, gltexture->tex_height,
819 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
820 }
821 }
822 else
823 #endif /* USE_GLU_IMAGESCALE */
824 {
825 if (gl_paletted_texture) {
826 gld_SetTexturePalette(GL_TEXTURE_2D);
827 glTexImage2D( GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT,
828 gltexture->buffer_width, gltexture->buffer_height,
829 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, buffer);
830 } else {
831 glTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format,
832 gltexture->buffer_width, gltexture->buffer_height,
833 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
834 }
835 }
836 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
837 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
838 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter);
839 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_filter);
840 }
841 Z_Free(buffer);
842 W_UnlockLumpNum(gltexture->index);
843 }
844
gld_CleanTextures(void)845 static void gld_CleanTextures(void)
846 {
847 int i,j;
848
849 if (!gld_GLTextures)
850 return;
851 for (i=0; i<numtextures; i++)
852 {
853 if (gld_GLTextures[i])
854 {
855 for (j=0; j<(CR_LIMIT+MAXPLAYERS); j++)
856 glDeleteTextures(1,&(gld_GLTextures[i]->glTexID[j]));
857 Z_Free(gld_GLTextures[i]);
858 }
859 }
860 memset(gld_GLTextures,0,numtextures*sizeof(GLTexture *));
861 }
862
gld_CleanPatchTextures(void)863 static void gld_CleanPatchTextures(void)
864 {
865 int i,j;
866
867 if (!gld_GLPatchTextures)
868 return;
869 for (i=0; i<numlumps; i++)
870 {
871 if (gld_GLPatchTextures[i])
872 {
873 for (j=0; j<(CR_LIMIT+MAXPLAYERS); j++)
874 glDeleteTextures(1,&(gld_GLPatchTextures[i]->glTexID[j]));
875 Z_Free(gld_GLPatchTextures[i]);
876 }
877 }
878 memset(gld_GLPatchTextures,0,numlumps*sizeof(GLTexture *));
879 }
880
gld_Precache(void)881 void gld_Precache(void)
882 {
883 register int i;
884 register byte *hitlist;
885
886 if (demoplayback)
887 return;
888
889 {
890 size_t size = numflats > numsprites ? numflats : numsprites;
891 hitlist = Z_Malloc((size_t)numtextures > size ? numtextures : size,PU_LEVEL,0);
892 }
893
894 // Precache flats.
895
896 memset(hitlist, 0, numflats);
897
898 for (i = numsectors; --i >= 0; )
899 hitlist[sectors[i].floorpic] = hitlist[sectors[i].ceilingpic] = 1;
900
901 for (i = numflats; --i >= 0; )
902 if (hitlist[i])
903 gld_BindFlat(gld_RegisterFlat(i,true));
904
905 // Precache textures.
906
907 memset(hitlist, 0, numtextures);
908
909 for (i = numsides; --i >= 0;)
910 hitlist[sides[i].bottomtexture] =
911 hitlist[sides[i].toptexture] =
912 hitlist[sides[i].midtexture] = 1;
913
914 // Sky texture is always present.
915 // Note that F_SKY1 is the name used to
916 // indicate a sky floor/ceiling as a flat,
917 // while the sky texture is stored like
918 // a wall texture, with an episode dependend
919 // name.
920
921 hitlist[skytexture] = 0;
922
923 for (i = numtextures; --i >= 0; )
924 if (hitlist[i])
925 gld_BindTexture(gld_RegisterTexture(i,true,false));
926
927 // Precache sprites.
928 memset(hitlist, 0, numsprites);
929
930 {
931 thinker_t *th;
932 for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
933 if (th->function == P_MobjThinker)
934 hitlist[((mobj_t *)th)->sprite] = 1;
935 }
936
937 for (i=numsprites; --i >= 0;)
938 if (hitlist[i])
939 {
940 int j = sprites[i].numframes;
941 while (--j >= 0)
942 {
943 short *sflump = sprites[i].spriteframes[j].lump;
944 int k = 7;
945 do
946 gld_BindPatch(gld_RegisterPatch(firstspritelump + sflump[k],CR_DEFAULT),CR_DEFAULT);
947 while (--k >= 0);
948 }
949 }
950 Z_Free(hitlist);
951 }
952
gld_CleanMemory(void)953 void gld_CleanMemory(void)
954 {
955 gld_CleanTextures();
956 gld_CleanPatchTextures();
957 }
958