1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20 // r_surf.c: surface-related refresh code
21
22 #include "quakedef.h"
23
24 #ifndef GL_RGBA4
25 #define GL_RGBA4 0
26 #endif
27
28
29 int lightmap_bytes; // 1, 2, or 4
30
31 int lightmap_textures;
32
33 unsigned blocklights[18*18];
34
35 #define BLOCK_WIDTH 128
36 #define BLOCK_HEIGHT 128
37
38 #define MAX_LIGHTMAPS 64
39 int active_lightmaps;
40
41 typedef struct glRect_s {
42 unsigned char l,t,w,h;
43 } glRect_t;
44
45 glpoly_t *lightmap_polys[MAX_LIGHTMAPS];
46 qboolean lightmap_modified[MAX_LIGHTMAPS];
47 glRect_t lightmap_rectchange[MAX_LIGHTMAPS];
48
49 int allocated[MAX_LIGHTMAPS][BLOCK_WIDTH];
50
51 // the lightmap texture data needs to be kept in
52 // main memory so texsubimage can update properly
53 byte lightmaps[4*MAX_LIGHTMAPS*BLOCK_WIDTH*BLOCK_HEIGHT];
54
55 // For gl_texsort 0
56 msurface_t *skychain = NULL;
57 msurface_t *waterchain = NULL;
58
59
60
61 /*
62 ====================================================
63 PENTA: Added for brush model vertex array support...
64
65 We first add vertices to a dynamically allocated buffer (malloc)
66 at the end of level loading we copy that to a "quake" allocated
67 buffer (on the Hunk)
68 ====================================================
69 */
70 mmvertex_t *globalVertexTable = NULL;
71
72 mmvertex_t *tempVertices = NULL;
73 int tempVerticesSize = 0;
74 int numTempVertices = 0;
75
R_GetNextVertexIndex(void)76 int R_GetNextVertexIndex(void) {
77 return numTempVertices;
78 }
79 /*
80 Returns the index of the vertex the date was copied to...
81 */
R_AllocateVertexInTemp(vec3_t pos,float texture[2],float lightmap[2])82 int R_AllocateVertexInTemp(vec3_t pos, float texture [2], float lightmap[2]) {
83
84 int i;
85 mmvertex_t *temp;
86
87
88 if (!tempVertices) {
89 tempVerticesSize = 512;
90 tempVertices = malloc(tempVerticesSize*sizeof(mmvertex_t));
91 numTempVertices = 0;
92 }
93
94 if (numTempVertices >= tempVerticesSize) {
95
96 tempVerticesSize+=512;
97 temp = malloc(tempVerticesSize*sizeof(mmvertex_t));
98 if (!temp) Sys_Error("R_AllocateVertexInTemp: malloc failed\n");
99 Q_memcpy(temp,tempVertices,(tempVerticesSize-512)*sizeof(mmvertex_t));
100 free(tempVertices);
101 tempVertices = temp;
102 }
103
104 VectorCopy(pos,tempVertices[numTempVertices].position);
105 for (i=0; i<2; i++) {
106 tempVertices[numTempVertices].texture[i] = texture[i];
107 tempVertices[numTempVertices].lightmap[i] = lightmap[i];
108 }
109 numTempVertices++;
110 return numTempVertices-1;
111 }
112
R_CopyVerticesToHunk(void)113 void R_CopyVerticesToHunk(void)
114 {
115 globalVertexTable = Hunk_Alloc(numTempVertices*sizeof(mmvertex_t));
116 Q_memcpy(globalVertexTable,tempVertices,numTempVertices*sizeof(mmvertex_t));
117 free(tempVertices);
118 Con_Printf("Copied %i vertices to hunk\n",numTempVertices);
119
120 tempVertices = NULL;
121 tempVerticesSize = 0;
122 numTempVertices = 0;
123 }
124
R_EnableVertexTable(int fields)125 void R_EnableVertexTable(int fields) {
126
127 glVertexPointer(3, GL_FLOAT, VERTEXSIZE*sizeof(float), globalVertexTable);
128 glEnableClientState(GL_VERTEX_ARRAY);
129
130 if (fields & VERTEX_TEXTURE) {
131 qglClientActiveTextureARB(GL_TEXTURE0_ARB);
132 glTexCoordPointer(2, GL_FLOAT, VERTEXSIZE*sizeof(float), (float *)(globalVertexTable)+3);
133 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
134 }
135
136 if (fields & VERTEX_LIGHTMAP) {
137 qglClientActiveTextureARB(GL_TEXTURE1_ARB);
138 glTexCoordPointer(2, GL_FLOAT, VERTEXSIZE*sizeof(float), (float *)(globalVertexTable)+5);
139 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
140 }
141 qglClientActiveTextureARB(GL_TEXTURE0_ARB);
142 }
143
R_DisableVertexTable(int fields)144 void R_DisableVertexTable(int fields) {
145
146 glVertexPointer(3, GL_FLOAT, 0, globalVertexTable);
147 glDisableClientState(GL_VERTEX_ARRAY);
148
149 if (fields & VERTEX_TEXTURE) {
150 qglClientActiveTextureARB(GL_TEXTURE0_ARB);
151 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
152 }
153
154 if (fields & VERTEX_LIGHTMAP) {
155 qglClientActiveTextureARB(GL_TEXTURE1_ARB);
156 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
157 }
158 qglClientActiveTextureARB(GL_TEXTURE0_ARB);
159 }
160
161 void R_RenderDynamicLightmaps (msurface_t *fa);
162
163 /*
164 ===============
165 R_AddDynamicLights
166 ===============
167 */
R_AddDynamicLights(msurface_t * surf)168 void R_AddDynamicLights (msurface_t *surf)
169 {
170 int lnum;
171 int sd, td;
172 float dist, rad, minlight;
173 vec3_t impact, local;
174 int s, t;
175 int i;
176 int smax, tmax;
177 mtexinfo_t *tex;
178
179 smax = (surf->extents[0]>>4)+1;
180 tmax = (surf->extents[1]>>4)+1;
181 tex = surf->texinfo;
182
183 for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
184 {
185 if ( !(surf->dlightbits & (1<<lnum) ) )
186 continue; // not lit by this light
187
188 rad = cl_dlights[lnum].radius;
189 dist = DotProduct (cl_dlights[lnum].origin, surf->plane->normal) -
190 surf->plane->dist;
191 rad -= fabs(dist);
192 minlight = cl_dlights[lnum].minlight;
193 if (rad < minlight)
194 continue;
195 minlight = rad - minlight;
196
197 for (i=0 ; i<3 ; i++)
198 {
199 impact[i] = cl_dlights[lnum].origin[i] -
200 surf->plane->normal[i]*dist;
201 }
202
203 local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
204 local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
205
206 local[0] -= surf->texturemins[0];
207 local[1] -= surf->texturemins[1];
208
209 for (t = 0 ; t<tmax ; t++)
210 {
211 td = local[1] - t*16;
212 if (td < 0)
213 td = -td;
214 for (s=0 ; s<smax ; s++)
215 {
216 sd = local[0] - s*16;
217 if (sd < 0)
218 sd = -sd;
219 if (sd > td)
220 dist = sd + (td>>1);
221 else
222 dist = td + (sd>>1);
223 if (dist < minlight)
224 blocklights[t*smax + s] += (rad - dist)*256;
225 }
226 }
227 }
228 }
229
230
231 /*
232 ===============
233 R_BuildLightMap
234
235 Combine and scale multiple lightmaps into the 8.8 format in blocklights
236 ===============
237 */
R_BuildLightMap(msurface_t * surf,byte * dest,int stride)238 void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
239 {
240 int smax, tmax;
241 int t;
242 int i, j, size;
243 byte *lightmap;
244 unsigned scale;
245 int maps;
246 unsigned *bl;
247
248 surf->cached_dlight = (surf->dlightframe == r_framecount);
249
250 smax = (surf->extents[0]>>4)+1;
251 tmax = (surf->extents[1]>>4)+1;
252 size = smax*tmax;
253 lightmap = surf->samples;
254
255 // set to full bright if no light data
256 if (r_fullbright.value || !cl.worldmodel->lightdata)
257 {
258 for (i=0 ; i<size ; i++)
259 blocklights[i] = 255*256;
260 goto store;
261 }
262
263 // clear to no light
264 for (i=0 ; i<size ; i++)
265 blocklights[i] = 0;
266
267 // add all the lightmaps
268 if (lightmap)
269 for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
270 maps++)
271 {
272 scale = d_lightstylevalue[surf->styles[maps]];
273 surf->cached_light[maps] = scale; // 8.8 fraction
274 for (i=0 ; i<size ; i++)
275 blocklights[i] += lightmap[i] * scale;
276 lightmap += size; // skip to next lightmap
277 }
278
279 // add all the dynamic lights
280 if (surf->dlightframe == r_framecount)
281 R_AddDynamicLights (surf);
282
283 // bound, invert, and shift
284 store:
285 switch (gl_lightmap_format)
286 {
287 case GL_RGBA:
288 stride -= (smax<<2);
289 bl = blocklights;
290 for (i=0 ; i<tmax ; i++, dest += stride)
291 {
292 for (j=0 ; j<smax ; j++)
293 {
294 t = *bl++;
295 t >>= 7;
296 if (t > 255)
297 t = 255;
298 //dest[3] = 255-t;
299 dest[3] = t;
300 dest += 4;
301 }
302 }
303 break;
304 case GL_ALPHA:
305 case GL_LUMINANCE:
306 case GL_INTENSITY:
307 bl = blocklights;
308 for (i=0 ; i<tmax ; i++, dest += stride)
309 {
310 for (j=0 ; j<smax ; j++)
311 {
312 t = *bl++;
313 t >>= 7;
314 if (t > 255)
315 t = 255;
316 //dest[j] = 255-t;
317 dest[j] = t;
318 }
319 }
320 break;
321 default:
322 Sys_Error ("Bad lightmap format");
323 }
324 }
325
326
327 /*
328 ===============
329 R_TextureAnimation
330
331 Returns the proper texture for a given time and base texture
332 ===============
333 */
R_TextureAnimation(texture_t * base)334 texture_t *R_TextureAnimation (texture_t *base)
335 {
336 int reletive;
337 int count;
338
339 if (currententity->frame)
340 {
341 if (base->alternate_anims)
342 base = base->alternate_anims;
343 }
344
345 if (!base->anim_total)
346 return base;
347
348 reletive = (int)(cl.time*10) % base->anim_total;
349
350 count = 0;
351 while (base->anim_min > reletive || base->anim_max <= reletive)
352 {
353 base = base->anim_next;
354 if (!base)
355 Sys_Error ("R_TextureAnimation: broken cycle");
356 if (++count > 100)
357 Sys_Error ("R_TextureAnimation: infinite cycle");
358 }
359
360 return base;
361 }
362
363
364 /*
365 =============================================================
366
367 BRUSH MODELS
368
369 =============================================================
370 */
371
372
373 extern int solidskytexture;
374 extern int alphaskytexture;
375 extern float speedscale; // for top sky and bottom sky
376
377 void DrawGLWaterPoly (glpoly_t *p);
378 void DrawGLWaterPolyLightmap (glpoly_t *p);
379
380 //lpMTexFUNC qgl MTexCoord2fSGIS = NULL;
381 //lpSelTexFUNC qgl SelectTextureSGIS = NULL;
382
383 /* NV_register_combiners command function pointers
384 PENTA: I put them here because mtex functions are above it, and I hadent't any ispiration for some other place.
385 */
386 PFNGLCOMBINERPARAMETERFVNVPROC qglCombinerParameterfvNV = NULL;
387 PFNGLCOMBINERPARAMETERIVNVPROC qglCombinerParameterivNV = NULL;
388 PFNGLCOMBINERPARAMETERFNVPROC qglCombinerParameterfNV = NULL;
389 PFNGLCOMBINERPARAMETERINVPROC qglCombinerParameteriNV = NULL;
390 PFNGLCOMBINERINPUTNVPROC qglCombinerInputNV = NULL;
391 PFNGLCOMBINEROUTPUTNVPROC qglCombinerOutputNV = NULL;
392 PFNGLFINALCOMBINERINPUTNVPROC qglFinalCombinerInputNV = NULL;
393 PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC qglGetCombinerInputParameterfvNV = NULL;
394 PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC qglGetCombinerInputParameterivNV = NULL;
395 PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC qglGetCombinerOutputParameterfvNV = NULL;
396 PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC qglGetCombinerOutputParameterivNV = NULL;
397 PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC qglGetFinalCombinerInputParameterfvNV = NULL;
398 PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC qglGetFinalCombinerInputParameterivNV = NULL;
399
400
401 PFNGLTEXIMAGE3DEXT qglTexImage3DEXT = NULL;
402 PFNGLDEPTHBOUNDSNV qglDepthBoundsNV = NULL;
403
404 PFNGLACTIVETEXTUREARBPROC qglActiveTextureARB = NULL;
405 PFNGLCLIENTACTIVETEXTUREARBPROC qglClientActiveTextureARB = NULL;
406 PFNGLMULTITEXCOORD1FARBPROC qglMultiTexCoord1fARB = NULL;
407 PFNGLMULTITEXCOORD2FARBPROC qglMultiTexCoord2fARB = NULL;
408 PFNGLMULTITEXCOORD2FVARBPROC qglMultiTexCoord2fvARB = NULL;
409 PFNGLMULTITEXCOORD3FARBPROC qglMultiTexCoord3fARB = NULL;
410 PFNGLMULTITEXCOORD3FVARBPROC qglMultiTexCoord3fvARB = NULL;
411
412 /*
413 ARB_vertex_program
414 PFNGLBINDPROGRAMARBPROC qglBindProgramARB = NULL;
415 PFNGLDELETEPROGRAMSARBPROC qglDeleteProgramsARB = NULL;
416 PFNGLGENPROGRAMSARBPROC qglGenProgramsARB = NULL;
417 PFNGLGETPROGRAMIVARBPROC qglGetProgramivARB = NULL;
418 PFNGLGETPROGRAMSTRINGARBPROC qglGetProgramStringARB = NULL;
419 PFNGLGETVERTEXATTRIBDVARBPROC qglGetVertexAttribdvARB = NULL;
420 PFNGLGETVERTEXATTRIBFVARBPROC qglGetVertexAttribfvARB = NULL;
421 PFNGLGETVERTEXATTRIBIVARBPROC qglGetVertexAttribivARB = NULL;
422 PFNGLGETVERTEXATTRIBPOINTERVARBPROC qglGetVertexAttribPointervARB = NULL;
423 PFNGLISPROGRAMARBPROC qglIsProgramARB = NULL;
424 PFNGPROGRAMSTRINGARBPROC qglProgramStringARB = NULL;
425 PFNGLTRACKMATRIXNVPROC glTrackMatrixNV = NULL;
426 PFNGLVERTEXATTRIB1DARBPROC qglVertexAttrib1dARB = NULL;
427 PFNGLVERTEXATTRIB1DVARBPROC qglVertexAttrib1dvARB = NULL;
428 PFNGLVERTEXATTRIB1FARBPROC qglVertexAttrib1fARB = NULL;
429 PFNGLVERTEXATTRIB1FVARBPROC qglVertexAttrib1fvARB = NULL;
430 PFNGLVERTEXATTRIB1SARBPROC qglVertexAttrib1sARB = NULL;
431 PFNGLVERTEXATTRIB1SVARBPROC qglVertexAttrib1svARB = NULL;
432 PFNGLVERTEXATTRIB2DARBPROC qglVertexAttrib2dARB = NULL;
433 PFNGLVERTEXATTRIB2DVARBPROC qglVertexAttrib2dvARB = NULL;
434 PFNGLVERTEXATTRIB2FARBPROC qglVertexAttrib2fARB = NULL;
435 PFNGLVERTEXATTRIB2FVARBPROC qglVertexAttrib2fvARB = NULL;
436 PFNGLVERTEXATTRIB2SARBPROC qglVertexAttrib2sARB = NULL;
437 PFNGLVERTEXATTRIB2SVARBPROC qglVertexAttrib2svARB = NULL;
438 PFNGLVERTEXATTRIB3DARBPROC qglVertexAttrib3dARB = NULL;
439 PFNGLVERTEXATTRIB3DVARBPROC qglVertexAttrib3dvARB = NULL;
440 PFNGLVERTEXATTRIB3FARBPROC qglVertexAttrib3fARB = NULL;
441 PFNGLVERTEXATTRIB3FVARBPROC qglVertexAttrib3fvARB = NULL;
442 PFNGLVERTEXATTRIB3SARBPROC qglVertexAttrib3sARB = NULL;
443 PFNGLVERTEXATTRIB3SVARBPROC qglVertexAttrib3svARB = NULL;
444 PFNGLVERTEXATTRIB4DARBPROC qglVertexAttrib4dARB = NULL;
445 PFNGLVERTEXATTRIB4DVARBPROC qglVertexAttrib4dvARB = NULL;
446 PFNGLVERTEXATTRIB4FARBPROC qglVertexAttrib4fARB = NULL;
447 PFNGLVERTEXATTRIB4FVARBPROC qglVertexAttrib4fvARB = NULL;
448 PFNGLVERTEXATTRIB4SARBPROC qglVertexAttrib4sARB = NULL;
449 PFNGLVERTEXATTRIB4SVARBPROC qglVertexAttrib4svARB = NULL;
450 PFNGLVERTEXATTRIB4UBVARBPROC qglVertexAttrib4ubvARB = NULL;
451 */
452
453 PFNGLAREPROGRAMSRESIDENTNVPROC qglAreProgramsResidentNV = NULL;
454 PFNGLBINDPROGRAMNVPROC qglBindProgramNV = NULL;
455 PFNGLDELETEPROGRAMSNVPROC qglDeleteProgramsNV = NULL;
456 PFNGLEXECUTEPROGRAMNVPROC qglExecuteProgramNV = NULL;
457 PFNGLGENPROGRAMSNVPROC qglGenProgramsNV = NULL;
458 PFNGLGETPROGRAMPARAMETERDVNVPROC qglGetProgramParameterdvNV = NULL;
459 PFNGLGETPROGRAMPARAMETERFVNVPROC qglGetProgramParameterfvNV = NULL;
460 PFNGLGETPROGRAMIVNVPROC qglGetProgramivNV = NULL;
461 PFNGLGETPROGRAMSTRINGNVPROC qglGetProgramStringNV = NULL;
462 PFNGLGETTRACKMATRIXIVNVPROC qglGetTrackMatrixivNV = NULL;
463 PFNGLGETVERTEXATTRIBDVNVPROC qglGetVertexAttribdvNV = NULL;
464 PFNGLGETVERTEXATTRIBFVNVPROC qglGetVertexAttribfvNV = NULL;
465 PFNGLGETVERTEXATTRIBIVNVPROC qglGetVertexAttribivNV = NULL;
466 PFNGLGETVERTEXATTRIBPOINTERVNVPROC qglGetVertexAttribPointervNV = NULL;
467 PFNGLISPROGRAMNVPROC qglIsProgramNV = NULL;
468 PFNGLLOADPROGRAMNVPROC qglLoadProgramNV = NULL;
469 PFNGLPROGRAMPARAMETER4DNVPROC qglProgramParameter4dNV = NULL;
470 PFNGLPROGRAMPARAMETER4DVNVPROC qglProgramParameter4dvNV = NULL;
471 PFNGLPROGRAMPARAMETER4FNVPROC qglProgramParameter4fNV = NULL;
472 PFNGLPROGRAMPARAMETER4FVNVPROC qglProgramParameter4fvNV = NULL;
473 PFNGLPROGRAMPARAMETERS4DVNVPROC qglProgramParameters4dvNV = NULL;
474 PFNGLPROGRAMPARAMETERS4FVNVPROC qglProgramParameters4fvNV = NULL;
475 PFNGLREQUESTRESIDENTPROGRAMSNVPROC qglRequestResidentProgramsNV = NULL;
476 PFNGLTRACKMATRIXNVPROC qglTrackMatrixNV = NULL;
477 PFNGLVERTEXATTRIBPOINTERNVPROC qglVertexAttribPointerNV = NULL;
478 PFNGLVERTEXATTRIB1DNVPROC qglVertexAttrib1dNV = NULL;
479 PFNGLVERTEXATTRIB1DVNVPROC qglVertexAttrib1dvNV = NULL;
480 PFNGLVERTEXATTRIB1FNVPROC qglVertexAttrib1fNV = NULL;
481 PFNGLVERTEXATTRIB1FVNVPROC qglVertexAttrib1fvNV = NULL;
482 PFNGLVERTEXATTRIB1SNVPROC qglVertexAttrib1sNV = NULL;
483 PFNGLVERTEXATTRIB1SVNVPROC qglVertexAttrib1svNV = NULL;
484 PFNGLVERTEXATTRIB2DNVPROC qglVertexAttrib2dNV = NULL;
485 PFNGLVERTEXATTRIB2DVNVPROC qglVertexAttrib2dvNV = NULL;
486 PFNGLVERTEXATTRIB2FNVPROC qglVertexAttrib2fNV = NULL;
487 PFNGLVERTEXATTRIB2FVNVPROC qglVertexAttrib2fvNV = NULL;
488 PFNGLVERTEXATTRIB2SNVPROC qglVertexAttrib2sNV = NULL;
489 PFNGLVERTEXATTRIB2SVNVPROC qglVertexAttrib2svNV = NULL;
490 PFNGLVERTEXATTRIB3DNVPROC qglVertexAttrib3dNV = NULL;
491 PFNGLVERTEXATTRIB3DVNVPROC qglVertexAttrib3dvNV = NULL;
492 PFNGLVERTEXATTRIB3FNVPROC qglVertexAttrib3fNV = NULL;
493 PFNGLVERTEXATTRIB3FVNVPROC qglVertexAttrib3fvNV = NULL;
494 PFNGLVERTEXATTRIB3SNVPROC qglVertexAttrib3sNV = NULL;
495 PFNGLVERTEXATTRIB3SVNVPROC qglVertexAttrib3svNV = NULL;
496 PFNGLVERTEXATTRIB4DNVPROC qglVertexAttrib4dNV = NULL;
497 PFNGLVERTEXATTRIB4DVNVPROC qglVertexAttrib4dvNV = NULL;
498 PFNGLVERTEXATTRIB4FNVPROC qglVertexAttrib4fNV = NULL;
499 PFNGLVERTEXATTRIB4FVNVPROC qglVertexAttrib4fvNV = NULL;
500 PFNGLVERTEXATTRIB4SNVPROC qglVertexAttrib4sNV = NULL;
501 PFNGLVERTEXATTRIB4SVNVPROC qglVertexAttrib4svNV = NULL;
502 PFNGLVERTEXATTRIB4UBVNVPROC qglVertexAttrib4ubvNV = NULL;
503 PFNGLVERTEXATTRIBS1DVNVPROC qglVertexAttribs1dvNV = NULL;
504 PFNGLVERTEXATTRIBS1FVNVPROC qglVertexAttribs1fvNV = NULL;
505 PFNGLVERTEXATTRIBS1SVNVPROC qglVertexAttribs1svNV = NULL;
506 PFNGLVERTEXATTRIBS2DVNVPROC qglVertexAttribs2dvNV = NULL;
507 PFNGLVERTEXATTRIBS2FVNVPROC qglVertexAttribs2fvNV = NULL;
508 PFNGLVERTEXATTRIBS2SVNVPROC qglVertexAttribs2svNV = NULL;
509 PFNGLVERTEXATTRIBS3DVNVPROC qglVertexAttribs3dvNV = NULL;
510 PFNGLVERTEXATTRIBS3FVNVPROC qglVertexAttribs3fvNV = NULL;
511 PFNGLVERTEXATTRIBS3SVNVPROC qglVertexAttribs3svNV = NULL;
512 PFNGLVERTEXATTRIBS4DVNVPROC qglVertexAttribs4dvNV = NULL;
513 PFNGLVERTEXATTRIBS4FVNVPROC qglVertexAttribs4fvNV = NULL;
514 PFNGLVERTEXATTRIBS4SVNVPROC qglVertexAttribs4svNV = NULL;
515 PFNGLVERTEXATTRIBS4UBVNVPROC qglVertexAttribs4ubvNV = NULL;
516
517 // <AWE> There are some diffs with the function parameters. wgl stuff not present with MacOS X. -DC- and SDL
518 #if defined (__APPLE__) || defined (MACOSX) || defined (SDL) || defined (__glx__)
519
520 PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC qglFlushVertexArrayRangeAPPLE = NULL;
521 PFNGLVERTEXARRAYRANGEAPPLEPROC qglVertexArrayRangeAPPLE = NULL;
522
523 #else
524
525 PFNGLFLUSHVERTEXARRAYRANGENVPROC qglFlushVertexArrayRangeNV = NULL;
526 PFNGLVERTEXARRAYRANGENVPROC glVertexArrayRangeNV = NULL;
527 PFNWGLALLOCATEMEMORYNVPROC wglAllocateMemoryNV = NULL;
528 PFNWGLFREEMEMORYNVPROC wglFreeMemoryNV = NULL;
529
530 #endif /* __APPLE__ || MACOSX */
531
532 qboolean mtexenabled = false;
533
534 void GL_SelectTexture (GLenum target);
535
GL_DisableMultitexture(void)536 void GL_DisableMultitexture(void)
537 {
538 if (mtexenabled) {
539 glDisable(GL_TEXTURE_2D);
540 GL_SelectTexture(GL_TEXTURE0_ARB);
541 mtexenabled = false;
542 }
543 }
544
GL_EnableMultitexture(void)545 void GL_EnableMultitexture(void)
546 {
547 if (gl_mtexable) {
548 GL_SelectTexture(GL_TEXTURE1_ARB);
549 glEnable(GL_TEXTURE_2D);
550 mtexenabled = true;
551 }
552 }
553
554 #if 0
555 /*
556 ================
557 R_DrawSequentialPoly
558
559 Systems that have fast state and texture changes can
560 just do everything as it passes with no need to sort
561 ================
562 */
563 void R_DrawSequentialPoly (msurface_t *s)
564 {
565 glpoly_t *p;
566 float *v;
567 int i;
568 texture_t *t;
569
570 //
571 // normal lightmaped poly
572 //
573 if (! (s->flags & (SURF_DRAWSKY|SURF_DRAWTURB|SURF_UNDERWATER) ) )
574 {
575 p = s->polys;
576
577 t = R_TextureAnimation (s->texinfo->texture);
578 GL_Bind (t->gl_texturenum);
579 glBegin (GL_TRIANGLEFAN);
580 v = p->verts[0];
581 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
582 {
583 glTexCoord2f (v[3], v[4]);
584 glVertex3fv (v);
585 }
586 glEnd ();
587
588 GL_Bind (lightmap_textures + s->lightmaptexturenum);
589 glEnable (GL_BLEND);
590 glBegin (GL_TRIANGLEFAN);
591 v = p->verts[0];
592 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
593 {
594 glTexCoord2f (v[5], v[6]);
595 glVertex3fv (v);
596 }
597 glEnd ();
598
599 glDisable (GL_BLEND);
600
601 return;
602 }
603
604 //
605 // subdivided water surface warp
606 //
607 if (s->flags & SURF_DRAWTURB)
608 {
609 GL_Bind (s->texinfo->texture->gl_texturenum);
610 EmitWaterPolys (s);
611 return;
612 }
613
614 //
615 // subdivided sky warp
616 //
617 if (s->flags & SURF_DRAWSKY)
618 {
619 GL_Bind (solidskytexture);
620 speedscale = realtime*8;
621 speedscale -= (int)speedscale;
622
623 EmitSkyPolys (s);
624
625 glEnable (GL_BLEND);
626 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
627 GL_Bind (alphaskytexture);
628 speedscale = realtime*16;
629 speedscale -= (int)speedscale;
630 EmitSkyPolys (s);
631 if (gl_lightmap_format == GL_LUMINANCE)
632 glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
633
634 glDisable (GL_BLEND);
635 }
636
637 //
638 // underwater warped with lightmap
639 //
640 p = s->polys;
641
642 t = R_TextureAnimation (s->texinfo->texture);
643 GL_Bind (t->gl_texturenum);
644 DrawGLWaterPoly (p);
645
646 GL_Bind (lightmap_textures + s->lightmaptexturenum);
647 glEnable (GL_BLEND);
648 DrawGLWaterPolyLightmap (p);
649 glDisable (GL_BLEND);
650 }
651 #else
652 /*
653 ================
654 R_DrawSequentialPoly
655
656 Systems that have fast state and texture changes can
657 just do everything as it passes with no need to sort
658 PENTA: Isn't used anymore!
659 ================
660 */
R_DrawSequentialPoly(msurface_t * s)661 void R_DrawSequentialPoly (msurface_t *s)
662 {
663 glpoly_t *p;
664 float *v;
665 int i;
666 texture_t *t;
667 glRect_t *theRect;
668
669 //
670 // normal lightmaped poly
671 //
672
673 if (! (s->flags & (SURF_DRAWSKY|SURF_DRAWTURB) ) )
674 {
675 R_RenderDynamicLightmaps (s);
676 if (gl_mtexable) {
677 p = s->polys;
678
679 t = R_TextureAnimation (s->texinfo->texture);
680 // Binds world to texture env 0
681 GL_SelectTexture(GL_TEXTURE0_ARB);
682 GL_Bind (t->gl_texturenum);
683 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
684 // Binds lightmap to texenv 1
685 GL_EnableMultitexture(); // Same as SelectTexture (TEXTURE1)
686 GL_Bind (lightmap_textures + s->lightmaptexturenum);
687 i = s->lightmaptexturenum;
688 if (lightmap_modified[i])
689 {
690 lightmap_modified[i] = false;
691 theRect = &lightmap_rectchange[i];
692 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
693 BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE,
694 lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes);
695 theRect->l = BLOCK_WIDTH;
696 theRect->t = BLOCK_HEIGHT;
697 theRect->h = 0;
698 theRect->w = 0;
699 }
700 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
701 glBegin(GL_TRIANGLE_FAN);
702 //v = p->verts[0];
703 v = (float *)(&globalVertexTable[p->firstvertex]);
704 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
705 {
706 qglMultiTexCoord2fARB (GL_TEXTURE0_ARB, v[3], v[4]);
707 qglMultiTexCoord2fARB (GL_TEXTURE1_ARB, v[5], v[6]);
708 glVertex3fv (v);
709 }
710 glEnd ();
711 return;
712 } else {
713 p = s->polys;
714
715 t = R_TextureAnimation (s->texinfo->texture);
716 GL_Bind (t->gl_texturenum);
717 glBegin (GL_TRIANGLE_FAN);
718 //v = p->verts[0];
719 v = (float *)(&globalVertexTable[p->firstvertex]);
720 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
721 {
722 glTexCoord2f (v[3], v[4]);
723 glVertex3fv (v);
724 }
725 glEnd ();
726
727 GL_Bind (lightmap_textures + s->lightmaptexturenum);
728 glEnable (GL_BLEND);
729 glBegin (GL_TRIANGLE_FAN);
730 //v = p->verts[0];
731 v = (float *)(&globalVertexTable[p->firstvertex]);
732 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
733 {
734 glTexCoord2f (v[5], v[6]);
735 glVertex3fv (v);
736 }
737 glEnd ();
738
739 glDisable (GL_BLEND);
740 }
741
742 return;
743 }
744
745 //
746 // subdivided water surface warp
747 //
748
749 if (s->flags & SURF_DRAWTURB)
750 {
751 GL_DisableMultitexture();
752 GL_Bind (s->texinfo->texture->gl_texturenum);
753 EmitWaterPolys (s);
754 return;
755 }
756
757 //
758 // subdivided sky warp
759 //
760 if (s->flags & SURF_DRAWSKY)
761 {
762 GL_DisableMultitexture();
763 GL_Bind (solidskytexture);
764 speedscale = realtime*8;
765 speedscale -= (int)speedscale & ~127;
766
767 EmitSkyPolys (s);
768
769 glEnable (GL_BLEND);
770 GL_Bind (alphaskytexture);
771 speedscale = realtime*16;
772 speedscale -= (int)speedscale & ~127;
773 EmitSkyPolys (s);
774
775 glDisable (GL_BLEND);
776 return;
777 }
778 }
779 #endif
780
781
782 /*
783 ================
784 DrawGLWaterPoly
785
786 Warp the vertex coordinates
787 ================
788 */
DrawGLWaterPoly(glpoly_t * p)789 void DrawGLWaterPoly (glpoly_t *p)
790 {
791 int i;
792 float *v;
793 vec3_t nv;
794
795 GL_DisableMultitexture();
796
797 glBegin (GL_TRIANGLE_FAN);
798 //v = p->verts[0];
799 v = (float *)(&globalVertexTable[p->firstvertex]);
800 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
801 {
802 glTexCoord2f (v[3], v[4]);
803
804 nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime);
805 nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime);
806 nv[2] = v[2];
807
808 glVertex3fv (nv);
809 }
810 glEnd ();
811 }
812
DrawGLWaterPolyLightmap(glpoly_t * p)813 void DrawGLWaterPolyLightmap (glpoly_t *p)
814 {
815 int i;
816 float *v;
817 vec3_t nv;
818
819 GL_DisableMultitexture();
820
821 glBegin (GL_TRIANGLE_FAN);
822 //v = p->verts[0];
823 v = (float *)(&globalVertexTable[p->firstvertex]);
824 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
825 {
826 glTexCoord2f (v[5], v[6]);
827
828 nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime);
829 nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime);
830 nv[2] = v[2];
831
832 glVertex3fv (nv);
833 }
834 glEnd ();
835 }
836
837 /*
838 ================
839 DrawGLPoly
840 ================
841 */
DrawGLPoly(glpoly_t * p)842 void DrawGLPoly (glpoly_t *p)
843 {
844 int i;
845 float *v;
846
847 glBegin (GL_TRIANGLE_FAN);
848 //v = p->verts[0];
849 v = (float *)(&globalVertexTable[p->firstvertex]);
850 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
851 {
852 glTexCoord2f (v[3], v[4]);
853 glVertex3fv (v);
854 }
855 glEnd ();
856 }
857
858
859 /*
860 ================
861 R_BlendLightmaps
862
863 verm lightmaps achteraf
864 elke lightmap heeft zijn lijst, teken die lijst
865
866 we hebbend dit veranderd, we tekenen nu de lightmap
867 zodat we de depth buffer vullen voor stencil shadows
868 en gaan de lightmaps heel donker renderen als vorm
869 van ambient light
870
871 PENTA: Modifications
872 ================
873 */
R_BlendLightmaps(void)874 void R_BlendLightmaps (void)
875 {
876 int i, j;
877 glpoly_t *p;
878 float *v;
879
880 if (r_fullbright.value)
881 return;
882
883 if (gl_lightmap_format == GL_LUMINANCE)
884 glBlendFunc (GL_ZERO, GL_SRC_COLOR);
885 else if (gl_lightmap_format == GL_INTENSITY)
886 {
887 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
888 glColor4f (0,0,0,1);
889 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
890 }
891
892 if (!r_lightmap.value)
893 {
894 //glEnable (GL_BLEND); //PENTA: removed as test
895 }
896
897 glColor3f(sh_lightmapbright.value,sh_lightmapbright.value,sh_lightmapbright.value);
898 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
899
900 for (i=0 ; i<MAX_LIGHTMAPS ; i++)
901 {
902 p = lightmap_polys[i];
903 if (!p)
904 continue;
905 GL_Bind(lightmap_textures+i);
906
907 //draw all polygons that use this lightmap
908 for( ; p ; p=p->chain)
909 {
910 glBegin (GL_TRIANGLE_FAN);
911 //v = p->verts[0];
912 v = (float *)(&globalVertexTable[p->firstvertex]);
913 for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE)
914 {
915 glTexCoord2f (v[5], v[6]);
916 glVertex3fv (v);
917 }
918 glEnd ();
919 }
920 lightmap_polys[i] = NULL;
921 }
922
923 glColor3f(1,1,1);
924
925 glDisable (GL_BLEND);
926 if (gl_lightmap_format == GL_LUMINANCE)
927 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
928 else if (gl_lightmap_format == GL_INTENSITY)
929 {
930 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
931 glColor4f (1,1,1,1);
932 }
933 }
934
935 /*
936 ================
937 R_RenderBrushPoly
938
939 PENTA: Modifications
940 ================
941 */
R_RenderBrushPoly(msurface_t * fa)942 void R_RenderBrushPoly (msurface_t *fa)
943 {
944 texture_t *t;
945 glpoly_t *p;
946 int i;
947 float *v;
948
949 if (fa->flags & SURF_DRAWSKY)
950 { // warp texture, no lightmaps
951 EmitBothSkyLayers (fa);
952 return;
953 }
954
955 /*if (!busy_caustics)*/ {
956 t = R_TextureAnimation (fa->texinfo->texture);
957 GL_SelectTexture(GL_TEXTURE0_ARB);
958 GL_Bind (t->gl_texturenum);
959 }
960
961 if (fa->flags & SURF_DRAWTURB)
962 { // warp texture, no lightmaps
963 EmitWaterPolys (fa);
964 return;
965 }
966
967 if (fa->flags & SURF_PLANEBACK)
968 {
969 glNormal3f(-fa->plane->normal[0],-fa->plane->normal[1],-fa->plane->normal[2]);
970 } else {
971 glNormal3fv(&fa->plane->normal[0]);
972 }
973
974 /*if (!busy_caustics)*/ {
975 GL_SelectTexture(GL_TEXTURE1_ARB);
976 GL_Bind (lightmap_textures + fa->lightmaptexturenum);
977 }
978
979 p = fa->polys;
980 glBegin (GL_TRIANGLE_FAN);
981 //v = p->verts[0];
982 v = (float *)(&globalVertexTable[p->firstvertex]);
983 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
984 {
985 glTexCoord2f (v[3], v[4]);
986 qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, v[5], v[6]);
987 glVertex3fv (v);
988 }
989 glEnd ();
990 }
991
992 /*
993 ================
994 R_RenderBrushPoly
995
996 PENTA:
997 ================
998 */
R_RenderBrushPolyLuma(msurface_t * fa)999 void R_RenderBrushPolyLuma (msurface_t *fa)
1000 {
1001 int i;
1002 float *v;
1003 glpoly_t *p;
1004 texture_t *t;
1005
1006 if (fa->flags & SURF_DRAWSKY)
1007 return;
1008
1009 if (fa->flags & SURF_DRAWTURB)
1010 return;
1011
1012 t = R_TextureAnimation (fa->texinfo->texture);
1013
1014 GL_Bind (t->gl_lumitex);
1015
1016 glBegin (GL_TRIANGLE_FAN);
1017 p = fa->polys;
1018 //v = p->verts[0];
1019 v = (float *)(&globalVertexTable[p->firstvertex]);
1020 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
1021 {
1022 glTexCoord2f (v[3], v[4]);
1023 glVertex3fv (v);
1024 }
1025 glEnd ();
1026 }
1027
1028
1029
1030 /*
1031
1032 ================
1033
1034 R_RenderBrushPoly
1035
1036
1037
1038 PENTA:
1039
1040 ================
1041
1042 */
1043
R_RenderBrushPolyLightmap(msurface_t * fa)1044 void R_RenderBrushPolyLightmap (msurface_t *fa)
1045
1046 {
1047
1048 int i;
1049
1050 float *v;
1051
1052 glpoly_t *p;
1053
1054 if (fa->flags & SURF_DRAWSKY)
1055
1056 return;
1057
1058 if (fa->flags & SURF_DRAWTURB)
1059
1060 return;
1061
1062 GL_Bind (lightmap_textures+fa->lightmaptexturenum);
1063
1064 glBegin (GL_TRIANGLE_FAN);
1065
1066 p = fa->polys;
1067
1068 //v = p->verts[0];
1069 v = (float *)(&globalVertexTable[p->firstvertex]);
1070
1071 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
1072
1073 {
1074
1075 glTexCoord2f (v[5], v[6]);
1076
1077 glVertex3fv (v);
1078
1079 }
1080
1081 glEnd ();
1082
1083 }
1084
1085
R_RenderBrushPolyCaustics(msurface_t * fa)1086 void R_RenderBrushPolyCaustics (msurface_t *fa)
1087 { int i;
1088 float *v;
1089 glpoly_t *p;
1090
1091 glBegin (GL_TRIANGLE_FAN);
1092 p = fa->polys;
1093 //v = p->verts[0];
1094 v = (float *)(&globalVertexTable[p->firstvertex]);
1095 for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
1096 {
1097 glTexCoord2f (v[5], v[6]);
1098 glVertex3fv (v);
1099 }
1100
1101 glEnd ();
1102 }
1103 /*
1104 ================
1105 R_RenderDynamicLightmaps
1106 Multitexture
1107 ================
1108 */
R_RenderDynamicLightmaps(msurface_t * fa)1109 void R_RenderDynamicLightmaps (msurface_t *fa)
1110 {
1111 byte *base;
1112 int maps;
1113 glRect_t *theRect;
1114 int smax, tmax;
1115
1116 c_brush_polys++;
1117
1118 if (fa->flags & ( SURF_DRAWSKY | SURF_DRAWTURB) )
1119 return;
1120
1121 fa->polys->chain = lightmap_polys[fa->lightmaptexturenum];
1122 lightmap_polys[fa->lightmaptexturenum] = fa->polys;
1123
1124 // check for lightmap modification
1125 for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ;
1126 maps++)
1127 if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps])
1128 goto dynamic;
1129
1130 if (fa->dlightframe == r_framecount // dynamic this frame
1131 || fa->cached_dlight) // dynamic previously
1132 {
1133 dynamic:
1134 if (r_dynamic.value)
1135 {
1136 lightmap_modified[fa->lightmaptexturenum] = true;
1137 theRect = &lightmap_rectchange[fa->lightmaptexturenum];
1138 if (fa->light_t < theRect->t) {
1139 if (theRect->h)
1140 theRect->h += theRect->t - fa->light_t;
1141 theRect->t = fa->light_t;
1142 }
1143 if (fa->light_s < theRect->l) {
1144 if (theRect->w)
1145 theRect->w += theRect->l - fa->light_s;
1146 theRect->l = fa->light_s;
1147 }
1148 smax = (fa->extents[0]>>4)+1;
1149 tmax = (fa->extents[1]>>4)+1;
1150 if ((theRect->w + theRect->l) < (fa->light_s + smax))
1151 theRect->w = (fa->light_s-theRect->l)+smax;
1152 if ((theRect->h + theRect->t) < (fa->light_t + tmax))
1153 theRect->h = (fa->light_t-theRect->t)+tmax;
1154 base = lightmaps + fa->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT;
1155 base += fa->light_t * BLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes;
1156 R_BuildLightMap (fa, base, BLOCK_WIDTH*lightmap_bytes);
1157 }
1158 }
1159 }
1160
1161 /*
1162 ================
1163 R_MirrorChain
1164 ================
1165 */
R_MirrorChain(msurface_t * s)1166 void R_MirrorChain (msurface_t *s)
1167 {
1168 //if (mirror)
1169 // return;
1170 //mirror = true;
1171 //mirror_plane = s->plane;
1172 }
1173
1174
1175 #if 0
1176 /*
1177 ================
1178 R_DrawWaterSurfaces
1179 PENTA: Modifications
1180 ================
1181 */
1182 void R_DrawWaterSurfaces (void)
1183 {
1184 int i;
1185 msurface_t *s;
1186 texture_t *t;
1187
1188 //
1189 // go back to the world matrix
1190 //
1191 glLoadMatrixf (r_world_matrix);
1192
1193 glEnable (GL_BLEND);
1194 glColor4f (1,1,1,r_wateralpha.value);
1195 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1196
1197 for (i=0 ; i<cl.worldmodel->numtextures ; i++)
1198 {
1199 t = cl.worldmodel->textures[i];
1200 if (!t)
1201 continue;
1202 s = t->texturechain;
1203 if (!s)
1204 continue;
1205 if ( !(s->flags & SURF_DRAWTURB) )
1206 continue;
1207
1208 // set modulate mode explicitly
1209 GL_Bind (t->gl_texturenum);
1210
1211 for ( ; s ; s=s->texturechain)
1212 R_RenderBrushPoly (s);
1213
1214 t->texturechain = NULL;
1215 }
1216
1217 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1218
1219 glColor4f (1,1,1,1);
1220 glDisable (GL_BLEND);
1221 }
1222 #else
1223 /*
1224 ================
1225 R_DrawWaterSurfaces
1226
1227 PENTA: Modifications
1228 ================
1229 */
R_DrawWaterSurfaces(void)1230 void R_DrawWaterSurfaces (void)
1231 {
1232 int i;
1233 msurface_t *s;
1234 texture_t *t;
1235
1236 /*
1237 /*PENTA: we always draw water at the end of the frame
1238 if (r_wateralpha.value == 1.0 && gl_texsort.value)
1239 return;
1240 */
1241
1242 //
1243 // go back to the world matrix
1244 //
1245
1246 glLoadMatrixf (r_world_matrix);
1247
1248 if (r_wateralpha.value < 1.0) {
1249 if (gl_watershader.value < 1.0) {
1250 glEnable (GL_BLEND);
1251 glColor4f (1,1,1,r_wateralpha.value);
1252 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1253 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1254 } else {
1255 glEnable (GL_BLEND);
1256 glColor4f (1,1,1,r_wateralpha.value);
1257 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1258 //glBlendFunc(GL_DST_COLOR,GL_ONE);
1259
1260 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1261 glMatrixMode(GL_TEXTURE);
1262 glLoadIdentity();
1263 }
1264 } else {
1265 glColor4f (1,1,1,1);
1266 }
1267
1268 /*if (!gl_texsort.value) {
1269 if (!waterchain)
1270 return;
1271
1272 for ( s = waterchain ; s ; s=s->texturechain) {
1273 GL_Bind (s->texinfo->texture->gl_texturenum);
1274 EmitWaterPolys (s);
1275 }
1276
1277 waterchain = NULL;
1278 } else */{
1279
1280 for (i=0 ; i<cl.worldmodel->numtextures ; i++)
1281 {
1282 t = cl.worldmodel->textures[i];
1283 if (!t)
1284 continue;
1285 s = t->texturechain;
1286 if (!s)
1287 continue;
1288 if ( !(s->flags & SURF_DRAWTURB ) )
1289 continue;
1290
1291 if ( (s->flags & SURF_MIRROR ) )
1292 continue;
1293
1294 // set modulate mode explicitly
1295
1296 if (!OverrideFluidTex(t->name)) {
1297 GL_Bind (t->gl_texturenum);
1298 }
1299
1300 for ( ; s ; s=s->texturechain)
1301 EmitWaterPolys (s);
1302
1303 t->texturechain = NULL;
1304
1305 //PENTA: only translate back if we use shaders
1306 if ((gl_watershader.value == 1) && (r_wateralpha.value < 1) ) {
1307 glLoadIdentity();
1308 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1309 GL_DisableMultitexture() ;
1310 glLoadIdentity();
1311 glDisable(GL_TEXTURE_GEN_S);
1312 glDisable(GL_TEXTURE_GEN_T);
1313 glFogfv(GL_FOG_COLOR, fog_color);
1314 }
1315 }
1316 }
1317
1318 if (r_wateralpha.value < 1.0) {
1319
1320 if (gl_watershader.value < 1.0) {
1321 glColor4f (1,1,1,r_wateralpha.value);
1322 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1323 glDisable(GL_BLEND);
1324
1325 } else {
1326 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1327
1328 glColor4f (1,1,1,1);
1329 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1330 glDisable (GL_BLEND);
1331 glMatrixMode(GL_MODELVIEW);
1332 }
1333 } else {
1334 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1335 }
1336
1337 }
1338
1339 #endif
1340
1341 /*
1342 ================
1343 DrawTextureChains
1344 PENTA: Modifications
1345
1346 We fill the causistics chain here!
1347 ================
1348 */
DrawTextureChains(void)1349 void DrawTextureChains (void)
1350 {
1351 int i;
1352 msurface_t *s;
1353 texture_t *t, *tani;
1354 qboolean found = false;
1355
1356 //glBlendFunc(GL_ZERO,GL_SRC_COLOR);
1357 //glEnable(GL_BLEND);
1358 glDepthMask (1);
1359 GL_DisableMultitexture();
1360 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1361 glColor3f(sh_lightmapbright.value,sh_lightmapbright.value,sh_lightmapbright.value);
1362
1363 GL_EnableMultitexture();
1364 if (sh_colormaps.value) {
1365 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1366 } else {
1367 //No colormaps: Color maps are bound on tmu 0 so disable it
1368 //and let tu1 modulate itself with the light map brightness
1369 glDisable(GL_REGISTER_COMBINERS_NV);
1370 GL_SelectTexture(GL_TEXTURE0_ARB);
1371 glDisable(GL_TEXTURE_2D);
1372 GL_SelectTexture(GL_TEXTURE1_ARB);
1373 glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
1374 glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB);
1375 glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
1376 glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
1377 }
1378
1379
1380
1381 if (gl_wireframe.value) {
1382 GL_SelectTexture(GL_TEXTURE0_ARB);
1383 glDisable(GL_TEXTURE_2D);
1384 GL_SelectTexture(GL_TEXTURE1_ARB);
1385 glDisable(GL_TEXTURE_2D);
1386 }
1387
1388 causticschain = NULL; //clear chain here
1389
1390 R_EnableVertexTable(VERTEX_TEXTURE | VERTEX_LIGHTMAP);
1391
1392 for (i=0 ; i<cl.worldmodel->numtextures ; i++)
1393 {
1394 t = cl.worldmodel->textures[i];
1395 if (!t)
1396 continue;
1397
1398 s = t->texturechain;
1399 if (!s)
1400 continue;
1401
1402 found = true;
1403
1404 if (i == skytexturenum) {
1405 continue;
1406 //R_DrawSkyChain (s);
1407 }
1408 /*
1409 else if (i == mirrortexturenum && r_mirroralpha.value != 1.0)
1410 {
1411 R_MirrorChain (s);
1412 continue;
1413 }
1414 */
1415 //else
1416 {
1417
1418 //PENTA: water at end of frame
1419 if (s->flags & SURF_DRAWTURB)
1420 continue;
1421
1422 GL_SelectTexture(GL_TEXTURE0_ARB);
1423 tani = R_TextureAnimation (s->texinfo->texture);
1424 GL_Bind (tani->gl_texturenum);
1425
1426 //Do the ambient pass
1427 //now with arrays!
1428 GL_SelectTexture(GL_TEXTURE1_ARB);
1429 while (s) {
1430 //R_RenderBrushPoly (s);
1431 GL_Bind (lightmap_textures + s->lightmaptexturenum);
1432 glDrawArrays(GL_TRIANGLE_FAN,s->polys->firstvertex,s->polys->numverts);
1433 s=s->texturechain;
1434 c_brush_polys ++;
1435 }
1436 GL_SelectTexture(GL_TEXTURE0_ARB);
1437
1438 //Has this texture a luma texture then add it
1439
1440 if (t->gl_lumitex) {
1441 //vec3_t color_black = {0.0, 0.0, 0.0};
1442 glFogfv(GL_FOG_COLOR, color_black);
1443 glEnable(GL_BLEND);
1444 glBlendFunc(GL_ONE, GL_ONE);
1445 GL_SelectTexture(GL_TEXTURE1_ARB);
1446 glDisable(GL_TEXTURE_2D);
1447 GL_SelectTexture(GL_TEXTURE0_ARB);
1448 glColor3f(1, 1, 1);
1449
1450 s = t->texturechain;
1451 GL_Bind (t->gl_lumitex);
1452
1453 for ( ; s ; s=s->texturechain) {
1454 //R_RenderBrushPolyLuma (s);
1455 glDrawArrays(GL_TRIANGLE_FAN,s->polys->firstvertex,s->polys->numverts);
1456 }
1457
1458 glColor3f(sh_lightmapbright.value,sh_lightmapbright.value,sh_lightmapbright.value);
1459 GL_SelectTexture(GL_TEXTURE1_ARB);
1460 glEnable(GL_TEXTURE_2D);
1461 GL_SelectTexture(GL_TEXTURE0_ARB);
1462 GL_SelectTexture(GL_TEXTURE1_ARB);
1463 glDisable(GL_BLEND);
1464 glFogfv(GL_FOG_COLOR, fog_color);
1465 }
1466
1467 s = t->texturechain;
1468 //Make cauistics list
1469 while (s) {
1470 msurface_t *olds;
1471 olds = s;
1472 s=s->texturechain;
1473 //attach the surface for caustics drawing (post multipyied later)
1474 if (olds->flags & SURF_UNDERWATER) {
1475 olds->texturechain = causticschain;
1476 causticschain = olds;
1477 }
1478 }
1479
1480 }
1481
1482 t->texturechain = NULL;
1483 }
1484 R_DisableVertexTable(VERTEX_TEXTURE | VERTEX_LIGHTMAP);
1485 GL_SelectTexture(GL_TEXTURE1_ARB);
1486 GL_DisableMultitexture();
1487 //glDisable(GL_BLEND);
1488 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1489 glDepthMask (1);
1490 }
1491
1492 void R_DrawBrushModelCaustics (entity_t *e);
1493
1494 /*
1495 =============
1496 R_DrawCaustics
1497
1498 Tenebrae does "real cauistics", projected textures on all things including ents
1499 (Other mods seem to just add an extra, not properly projected layer to the polygons in the world.)
1500 =============
1501 */
R_DrawCaustics(void)1502 void R_DrawCaustics(void) {
1503
1504 msurface_t *s;
1505 int i;
1506 vec3_t mins, maxs;
1507
1508 GLfloat sPlane[4] = {0.01, 0.005, 0.0, 0.0 };
1509 GLfloat tPlane[4] = {0.0, 0.01, 0.005, 0.0 };
1510
1511 if (!gl_caustics.value) return;
1512
1513 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1514 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1515 glTexGenfv(GL_S, GL_OBJECT_PLANE, sPlane);
1516 glTexGenfv(GL_T, GL_OBJECT_PLANE, tPlane);
1517 glEnable(GL_TEXTURE_GEN_S);
1518 glEnable(GL_TEXTURE_GEN_T);
1519
1520 glEnable(GL_BLEND);
1521 glBlendFunc(GL_DST_COLOR, GL_ONE);
1522
1523 GL_Bind(caustics_textures[(int)(cl.time*16)&7]);
1524 busy_caustics = true;
1525 s = causticschain;
1526
1527 R_EnableVertexTable(0);
1528 while (s) {
1529 //R_RenderBrushPolyCaustics (s);
1530 glDrawArrays(GL_TRIANGLE_FAN,s->polys->firstvertex,s->polys->numverts);
1531 s = s->texturechain;
1532 }
1533 R_DisableVertexTable(0);
1534
1535 for (i=0 ; i<cl_numvisedicts ; i++)
1536 {
1537 currententity = cl_visedicts[i];
1538
1539 if (currententity->angles[0] || currententity->angles[1] || currententity->angles[2])
1540 {
1541 int i;
1542 for (i=0 ; i<3 ; i++)
1543 {
1544 mins[i] = currententity->origin[i] - currententity->model->radius;
1545 maxs[i] = currententity->origin[i] + currententity->model->radius;
1546 }
1547 } else {
1548 VectorAdd (currententity->origin,currententity->model->mins, mins);
1549 VectorAdd (currententity->origin,currententity->model->maxs, maxs);
1550 }
1551
1552 if (R_CullBox (mins, maxs))
1553 continue;
1554
1555 //quick hack! check if ent is below water
1556 if ((CL_PointContents(mins) != CONTENTS_WATER) && (CL_PointContents(maxs) != CONTENTS_WATER))
1557 continue;
1558
1559 if (mirror) {
1560 if (mirror_clipside == BoxOnPlaneSide(mins, maxs, mirror_plane)) {
1561 continue;
1562 }
1563
1564
1565 if ( BoxOnPlaneSide(mins, maxs, &mirror_far_plane) == 1) {
1566 return;
1567 }
1568 }
1569
1570 switch (currententity->model->type)
1571 {
1572 case mod_alias:
1573 R_DrawAliasModel (1.0);
1574 break;
1575
1576 case mod_brush:
1577 R_DrawBrushModelCaustics(currententity);
1578 break;
1579
1580 default:
1581 break;
1582 }
1583 }
1584
1585 busy_caustics = false;
1586 glDisable(GL_BLEND);
1587
1588 glDisable(GL_TEXTURE_GEN_S);
1589 glDisable(GL_TEXTURE_GEN_T);
1590 }
1591
1592
1593 /*
1594 =================
1595 R_DrawBrushModel
1596
1597 PENTA: Modifications
1598 =================
1599 */
R_DrawBrushModel(entity_t * e)1600 void R_DrawBrushModel (entity_t *e)
1601 {
1602 vec3_t mins, maxs;
1603 int i;
1604 msurface_t *psurf;
1605 mplane_t *pplane;
1606 model_t *clmodel;
1607 qboolean rotated;
1608 texture_t *t;
1609
1610 //bright = 1;
1611
1612 currententity = e;
1613 currenttexture = -1;
1614
1615 clmodel = e->model;
1616
1617 if (e->angles[0] || e->angles[1] || e->angles[2])
1618 {
1619 rotated = true;
1620 for (i=0 ; i<3 ; i++)
1621 {
1622 mins[i] = e->origin[i] - clmodel->radius;
1623 maxs[i] = e->origin[i] + clmodel->radius;
1624 }
1625 }
1626 else
1627 {
1628 rotated = false;
1629 VectorAdd (e->origin, clmodel->mins, mins);
1630 VectorAdd (e->origin, clmodel->maxs, maxs);
1631 }
1632
1633 if (R_CullBox (mins, maxs))
1634 return;
1635
1636 memset (lightmap_polys, 0, sizeof(lightmap_polys));
1637
1638 VectorSubtract (r_refdef.vieworg, e->origin, modelorg);
1639 if (rotated)
1640 {
1641 vec3_t temp;
1642 vec3_t forward, right, up;
1643
1644 VectorCopy (modelorg, temp);
1645 AngleVectors (e->angles, forward, right, up);
1646 modelorg[0] = DotProduct (temp, forward);
1647 modelorg[1] = -DotProduct (temp, right);
1648 modelorg[2] = DotProduct (temp, up);
1649 }
1650
1651 psurf = &clmodel->surfaces[clmodel->firstmodelsurface];
1652
1653 glPushMatrix ();
1654 e->angles[0] = -e->angles[0]; // stupid quake bug
1655 R_RotateForEntity (e);
1656 e->angles[0] = -e->angles[0]; // stupid quake bug
1657
1658 //Draw model with specified ambient color
1659 GL_DisableMultitexture();
1660 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1661
1662 if (!busy_caustics) {
1663 glColor3f(sh_lightmapbright.value,sh_lightmapbright.value,sh_lightmapbright.value);
1664
1665 GL_EnableMultitexture();
1666 if (sh_colormaps.value) {
1667 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1668 } else {
1669 //No colormaps: Color maps are bound on tmu 0 so disable it
1670 //and let tu1 modulate itself with the light map brightness
1671 glDisable(GL_REGISTER_COMBINERS_NV);
1672 GL_SelectTexture(GL_TEXTURE0_ARB);
1673 glDisable(GL_TEXTURE_2D);
1674 GL_SelectTexture(GL_TEXTURE1_ARB);
1675 glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
1676 glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB);
1677 glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
1678 glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
1679 }
1680 } else {
1681 glColor3f(1,1,1);
1682 }
1683
1684
1685
1686 //XYZ
1687
1688 if (gl_wireframe.value) {
1689
1690 GL_SelectTexture(GL_TEXTURE0_ARB);
1691
1692 glDisable(GL_TEXTURE_2D);
1693
1694 GL_SelectTexture(GL_TEXTURE1_ARB);
1695
1696 glDisable(GL_TEXTURE_2D);
1697
1698 }
1699
1700
1701 c_brush_polys += clmodel->nummodelsurfaces;
1702 //
1703 // draw texture
1704 //
1705 for (i=0 ; i<clmodel->nummodelsurfaces ; i++, psurf++)
1706 {
1707 // find which side of the node we are on
1708 pplane = psurf->plane;
1709
1710 //dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
1711
1712 // draw the polygon
1713 //if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
1714 // (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
1715 //{
1716 R_RenderBrushPoly (psurf);
1717 //}
1718 }
1719
1720 // if luma, draw it too
1721 psurf = &clmodel->surfaces[clmodel->firstmodelsurface];
1722 //vec3_t color_black = {0.0, 0.0, 0.0};
1723 glFogfv(GL_FOG_COLOR, color_black);
1724 glEnable(GL_BLEND);
1725 glBlendFunc(GL_ONE, GL_ONE);
1726 GL_SelectTexture(GL_TEXTURE1_ARB);
1727 glDisable(GL_TEXTURE_2D);
1728 GL_SelectTexture(GL_TEXTURE0_ARB);
1729 glColor3f(1, 1, 1);
1730
1731 for (i=0 ; i<clmodel->nummodelsurfaces ; i++, psurf++)
1732 {
1733 t = R_TextureAnimation (psurf->texinfo->texture);
1734 if ( t->gl_lumitex )
1735 R_RenderBrushPolyLuma (psurf);
1736 }
1737
1738 glColor3f(sh_lightmapbright.value,sh_lightmapbright.value,sh_lightmapbright.value);
1739 GL_SelectTexture(GL_TEXTURE1_ARB);
1740 glEnable(GL_TEXTURE_2D);
1741 GL_SelectTexture(GL_TEXTURE0_ARB);
1742 GL_SelectTexture(GL_TEXTURE1_ARB);
1743 glDisable(GL_BLEND);
1744 glFogfv(GL_FOG_COLOR, fog_color);
1745
1746 GL_DisableMultitexture();
1747 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1748 glPopMatrix ();
1749 }
1750
1751 /*
1752 =================
1753 R_DrawBrushModel
1754 =================
1755 */
R_DrawBrushModelCaustics(entity_t * e)1756 void R_DrawBrushModelCaustics (entity_t *e)
1757 {
1758 vec3_t mins, maxs;
1759 int i;
1760 msurface_t *psurf;
1761 float dot;
1762 mplane_t *pplane;
1763 model_t *clmodel;
1764 qboolean rotated;
1765
1766 //bright = 1;
1767
1768 currententity = e;
1769 currenttexture = -1;
1770
1771 clmodel = e->model;
1772
1773 if (e->angles[0] || e->angles[1] || e->angles[2])
1774 {
1775 rotated = true;
1776 for (i=0 ; i<3 ; i++)
1777 {
1778 mins[i] = e->origin[i] - clmodel->radius;
1779 maxs[i] = e->origin[i] + clmodel->radius;
1780 }
1781 }
1782 else
1783 {
1784 rotated = false;
1785 VectorAdd (e->origin, clmodel->mins, mins);
1786 VectorAdd (e->origin, clmodel->maxs, maxs);
1787 }
1788
1789 if (R_CullBox (mins, maxs))
1790 return;
1791
1792 VectorSubtract (r_refdef.vieworg, e->origin, modelorg);
1793 if (rotated)
1794 {
1795 vec3_t temp;
1796 vec3_t forward, right, up;
1797
1798 VectorCopy (modelorg, temp);
1799 AngleVectors (e->angles, forward, right, up);
1800 modelorg[0] = DotProduct (temp, forward);
1801 modelorg[1] = -DotProduct (temp, right);
1802 modelorg[2] = DotProduct (temp, up);
1803 }
1804
1805 psurf = &clmodel->surfaces[clmodel->firstmodelsurface];
1806
1807 glPushMatrix ();
1808 e->angles[0] = -e->angles[0]; // stupid quake bug
1809 R_RotateForEntity (e);
1810 e->angles[0] = -e->angles[0]; // stupid quake bug
1811
1812 //Draw model with specified ambient color
1813 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1814
1815 //
1816 // draw texture
1817 //
1818 for (i=0 ; i<clmodel->nummodelsurfaces ; i++, psurf++)
1819 {
1820 // find which side of the node we are on
1821 pplane = psurf->plane;
1822
1823 dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
1824
1825 // draw the polygon
1826 if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
1827 (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
1828 {
1829 R_RenderBrushPolyCaustics (psurf);
1830 }
1831 }
1832
1833 //R_BlendLightmaps (); nope no lightmaps
1834 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1835 glPopMatrix ();
1836 }
1837
1838 /*
1839 =================
1840 R_DrawBrushModel
1841 =================
1842 */
R_DrawBrushModelAmbient(entity_t * e)1843 void R_DrawBrushModelAmbient (entity_t *e)
1844 {
1845 vec3_t mins, maxs;
1846 int i;
1847 msurface_t *psurf;
1848 float dot;
1849 mplane_t *pplane;
1850 model_t *clmodel;
1851 qboolean rotated;
1852
1853 //bright = 1;
1854
1855 currententity = e;
1856 currenttexture = -1;
1857
1858 clmodel = e->model;
1859
1860 if (e->angles[0] || e->angles[1] || e->angles[2])
1861 {
1862 rotated = true;
1863 for (i=0 ; i<3 ; i++)
1864 {
1865 mins[i] = e->origin[i] - clmodel->radius;
1866 maxs[i] = e->origin[i] + clmodel->radius;
1867 }
1868 }
1869 else
1870 {
1871 rotated = false;
1872 VectorAdd (e->origin, clmodel->mins, mins);
1873 VectorAdd (e->origin, clmodel->maxs, maxs);
1874 }
1875
1876 if (R_CullBox (mins, maxs))
1877 return;
1878
1879 VectorSubtract (r_refdef.vieworg, e->origin, modelorg);
1880 if (rotated)
1881 {
1882 vec3_t temp;
1883 vec3_t forward, right, up;
1884
1885 VectorCopy (modelorg, temp);
1886 AngleVectors (e->angles, forward, right, up);
1887 modelorg[0] = DotProduct (temp, forward);
1888 modelorg[1] = -DotProduct (temp, right);
1889 modelorg[2] = DotProduct (temp, up);
1890 }
1891
1892 psurf = &clmodel->surfaces[clmodel->firstmodelsurface];
1893
1894 glPushMatrix ();
1895 e->angles[0] = -e->angles[0]; // stupid quake bug
1896 R_RotateForEntity (e);
1897 e->angles[0] = -e->angles[0]; // stupid quake bug
1898
1899 //Draw model with specified ambient color
1900 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1901
1902 //
1903 // draw texture
1904 //
1905 for (i=0 ; i<clmodel->nummodelsurfaces ; i++, psurf++)
1906 {
1907 // find which side of the node we are on
1908 pplane = psurf->plane;
1909
1910 dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
1911
1912 // draw the polygon
1913 if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
1914 (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
1915 {
1916 R_RenderBrushPolyLightmap (psurf);
1917 }
1918 }
1919
1920 //R_BlendLightmaps (); nope no lightmaps
1921 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1922 glPopMatrix ();
1923 }
1924
1925
1926 /*
1927 =============================================================
1928
1929 WORLD MODEL
1930
1931 =============================================================
1932 */
1933
1934 /*
1935 ================
1936 R_RecursiveWorldNode
1937
1938 PENTA: Modifications
1939 ================
1940 */
1941 qboolean didnode;
1942
R_RecursiveWorldNode(mnode_t * node)1943 void R_RecursiveWorldNode (mnode_t *node)
1944 {
1945 int c, side;
1946 mplane_t *plane;
1947 msurface_t *surf, **mark;
1948 mleaf_t *pleaf;
1949 double dot;
1950
1951 if (node->contents == CONTENTS_SOLID)
1952 return; // solid
1953
1954 if (node->visframe != r_visframecount)
1955 return;
1956
1957 if (R_CullBox (node->minmaxs, node->minmaxs+3))
1958 return;
1959
1960
1961 if (mirror) {
1962
1963 int side = BoxOnPlaneSide(node->minmaxs, node->minmaxs+3, mirror_plane);
1964 if ((mirror_clipside == side)) {
1965 return;
1966 }
1967
1968 if ( BoxOnPlaneSide(node->minmaxs, node->minmaxs+3, &mirror_far_plane) == 1) {
1969 return;
1970 }
1971 }
1972
1973
1974 // if a leaf node, draw stuff
1975 if (node->contents < 0)
1976 {
1977
1978 /*
1979 if (mirror) {
1980 if (mirror_clipside == BoxOnPlaneSide(node->minmaxs, node->minmaxs+3, mirror_plane)) {
1981 return;
1982 }
1983 }
1984
1985 */
1986 pleaf = (mleaf_t *)node;
1987
1988 mark = pleaf->firstmarksurface;
1989 c = pleaf->nummarksurfaces;
1990
1991 if (c)
1992 {
1993 do
1994 {
1995 /*
1996 if ((*mark)->flags & SURF_MIRROR) {
1997 if (!mirror)
1998 R_AllocateMirror((*mark));
1999 mark++;
2000 continue;
2001 }*/
2002
2003 (*mark)->visframe = r_framecount;
2004 mark++;
2005 } while (--c);
2006 }
2007
2008 // deal with model fragments in this leaf
2009 // steek de statishe moddellen voor dit leafy in de lijst
2010 // waarom zo ingewikkeld doen via efrags is nog niet helemaal duidelijk
2011 if (pleaf->efrags)
2012 R_StoreEfrags (&pleaf->efrags);
2013
2014 return;
2015 }
2016
2017 // node is just a decision point, so go down the apropriate sides
2018
2019 // find which side of the node we are on
2020 plane = node->plane;
2021
2022 switch (plane->type)
2023 {
2024 case PLANE_X:
2025 dot = modelorg[0] - plane->dist;
2026 break;
2027 case PLANE_Y:
2028 dot = modelorg[1] - plane->dist;
2029 break;
2030 case PLANE_Z:
2031 dot = modelorg[2] - plane->dist;
2032 break;
2033 default:
2034 dot = DotProduct (modelorg, plane->normal) - plane->dist;
2035 break;
2036 }
2037
2038 if (dot >= 0)
2039 side = 0;
2040 else
2041 side = 1;
2042
2043 // recurse down the children, front side first
2044 R_RecursiveWorldNode (node->children[side]);
2045
2046 // draw stuff
2047 c = node->numsurfaces;
2048
2049 if (c)
2050 {
2051 surf = cl.worldmodel->surfaces + node->firstsurface;
2052
2053 if (dot < 0 -BACKFACE_EPSILON)
2054 side = SURF_PLANEBACK;
2055 else if (dot > BACKFACE_EPSILON)
2056 side = 0;
2057 {
2058 for ( ; c ; c--, surf++)
2059 {
2060 if (surf->visframe != r_framecount)
2061 continue;
2062
2063 // don't backface underwater surfaces, because they warp
2064
2065 if ( (dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))
2066 continue; // wrong side
2067
2068
2069
2070 if (surf->flags & SURF_MIRROR) {
2071
2072 //PENTA the SURF_UNDERWATER check is needed so that we dont draw glass
2073 //twice since we design it as a water block we would render two poly's with the
2074 //mirror otherwice
2075 if( (! ((surf->flags & SURF_UNDERWATER) && (surf->flags & SURF_GLASS)) )|| (!(surf->flags & SURF_DRAWTURB)))
2076
2077 if (!mirror) R_AllocateMirror(surf);
2078 //destroy visframe
2079 surf->visframe = 0;
2080 continue;
2081 }
2082
2083 if ((surf->flags & SURF_DRAWTURB) && (surf->flags & SURF_MIRROR)) {
2084 continue;
2085 }
2086
2087 if ((surf->flags & SURF_DRAWTURB) && (mirror)) {
2088 continue;
2089 }
2090
2091 // if sorting by texture, just store it out
2092 /*if (gl_texsort.value)
2093 {*/
2094
2095 // add the surface to the proper texture chain
2096 //if (!mirror
2097 //|| surf->texinfo->texture != cl.worldmodel->textures[mirrortexturenum])
2098 //{
2099 surf->texturechain = surf->texinfo->texture->texturechain;
2100 surf->texinfo->texture->texturechain = surf;
2101 //}
2102
2103
2104 // add the poly to the proper lightmap chain
2105 //steek hem in de lijst en vermenigvuldig de lightmaps er achteraf over via
2106 //r_blendlightmaps
2107 //we steken geen lucht/water polys in de lijst omdat deze geen
2108 //lightmaps hebben
2109 if (!(surf->flags & (SURF_DRAWSKY | SURF_DRAWTURB))) {
2110 surf->polys->chain = lightmap_polys[surf->lightmaptexturenum];
2111 lightmap_polys[surf->lightmaptexturenum] = surf->polys;
2112 }
2113
2114 /*
2115 } else if (surf->flags & SURF_DRAWSKY) {
2116 surf->texturechain = skychain;
2117 skychain = surf;
2118 } else if (surf->flags & SURF_DRAWTURB) {
2119 surf->texturechain = waterchain;
2120 waterchain = surf;
2121 } else
2122 R_DrawSequentialPoly (surf);
2123 */
2124
2125 }
2126 }
2127
2128 }
2129
2130 // recurse down the back side
2131 R_RecursiveWorldNode (node->children[!side]);
2132 }
2133
2134
2135
2136 /*
2137 =============
2138 R_InitDrawWorld
2139
2140 Make sure everyting is set up correctly to draw
2141 the world model.
2142
2143 PENTA: Modifications
2144 =============
2145 */
R_InitDrawWorld(void)2146 void R_InitDrawWorld (void)
2147 {
2148 entity_t ent;
2149
2150 memset (&ent, 0, sizeof(ent));
2151 ent.model = cl.worldmodel;
2152
2153 VectorCopy (r_refdef.vieworg, modelorg);
2154
2155 currententity = &ent;
2156 currenttexture = -1;
2157
2158 glColor3f (1,1,1);
2159 memset (lightmap_polys, 0, sizeof(lightmap_polys));
2160 //#ifdef QUAKE2
2161
2162 R_ClearSkyBox ();
2163 //#endif
2164 //if (mirror) Con_Printf("RWorldn\n");
2165 //mark visible polygons/ents
2166 R_RecursiveWorldNode (cl.worldmodel->nodes);
2167 //#ifdef QUAKE2
2168
2169 if (gl_wireframe.value) return;
2170 R_DrawSkyBox ();
2171 //if (fog_enabled.value) glEnable(GL_FOG);
2172 //#endif
2173 }
2174
2175 /*
2176 =============
2177 R_DrawWorldAmbient
2178
2179 Draw the ambient lighting of the world
2180 the scene should be drawn (even if we want black ambient) since
2181 we need the depthbuffer to do correct
2182 stencil shadows.
2183 PENTA: New
2184 =============
2185 */
R_DrawWorldAmbient(void)2186 void R_DrawWorldAmbient (void) {
2187 R_BlendLightmaps ();
2188 }
2189
2190 /*
2191 =============
2192 R_WorldMultiplyTextures
2193
2194 Once we have drawn the lightmap in the depth buffer multiply the textures over it
2195 PENTA: New
2196 =============
2197 */
R_WorldMultiplyTextures(void)2198 void R_WorldMultiplyTextures(void) {
2199 DrawTextureChains ();
2200 //R_RenderDlights (); //render "fake" dynamic lights als die aan staan
2201 }
2202
2203 /*
2204 ===============
2205 R_MarkLeaves
2206
2207
2208 Markeer visible leafs voor dit frame
2209 aangeroepen vanuit render scene voor alle
2210 ander render code
2211 (hmm handig hiernaa kunnen we dus al van de vis voor de camera
2212 gebruik maken en toch nog stuff doen)
2213
2214 PENTA: Modifications
2215
2216 ===============
2217 */
R_MarkLeaves(void)2218 void R_MarkLeaves (void)
2219 {
2220 byte *vis;
2221 mnode_t *node;
2222 int i;
2223 byte solid[4096];
2224
2225 //zelfde leaf als vorige frame vermijd van vis opnieuw te calculaten
2226 // if (r_oldviewleaf == r_viewleaf && !r_novis.value)
2227 // return;
2228
2229 // return;
2230
2231 r_visframecount++;//begin nieuwe timestamp
2232 r_oldviewleaf = r_viewleaf;
2233
2234 if (r_novis.value)
2235 {
2236 vis = solid;
2237 memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3);
2238 }
2239 else
2240 vis = Mod_LeafPVS (r_viewleaf, cl.worldmodel);//vraag visible leafs vanuit dit leaf aan model
2241
2242 for (i=0 ; i<cl.worldmodel->numleafs ; i++)//overloop alle leafs
2243 {
2244 if (vis[i>>3] & (1<<(i&7))) // staat leaf i's vis bit op true ?
2245 {
2246 node = (mnode_t *)&cl.worldmodel->leafs[i+1];
2247 do
2248 {
2249 if (node->visframe == r_visframecount) //node al op true gezet dit frame, exit
2250 break;
2251 node->visframe = r_visframecount;//zet node zijn timestamp voor dit frame
2252 node = node->parent;//mark parents as vis
2253 } while (node);
2254 }
2255 }
2256 }
2257
2258
2259
2260 /*
2261 =============================================================================
2262
2263 LIGHTMAP ALLOCATION
2264
2265 =============================================================================
2266 */
2267
2268 // returns a texture number and the position inside it
AllocBlock(int w,int h,int * x,int * y)2269 int AllocBlock (int w, int h, int *x, int *y)
2270 {
2271 int i, j;
2272 int best, best2;
2273 int texnum;
2274
2275 for (texnum=0 ; texnum<MAX_LIGHTMAPS ; texnum++)
2276 {
2277 best = BLOCK_HEIGHT;
2278
2279 for (i=0 ; i<BLOCK_WIDTH-w ; i++)
2280 {
2281 best2 = 0;
2282
2283 for (j=0 ; j<w ; j++)
2284 {
2285 if (allocated[texnum][i+j] >= best)
2286 break;
2287 if (allocated[texnum][i+j] > best2)
2288 best2 = allocated[texnum][i+j];
2289 }
2290 if (j == w)
2291 { // this is a valid spot
2292 *x = i;
2293 *y = best = best2;
2294 }
2295 }
2296
2297 if (best + h > BLOCK_HEIGHT)
2298 continue;
2299
2300 for (i=0 ; i<w ; i++)
2301 allocated[texnum][*x + i] = best + h;
2302
2303 return texnum;
2304 }
2305
2306 Sys_Error ("AllocBlock: full");
2307 return 0;
2308 }
2309
2310
2311 mvertex_t *r_pcurrentvertbase;
2312 model_t *currentmodel;
2313
2314 int nColinElim;
2315
2316 //PENTA: temporaly storage for polygons that use an edge
2317 typedef struct {
2318 int used; //how many polygons use this edge
2319 glpoly_t *poly[2]; //pointer to the polygons who use this edge
2320 } temp_connect_t;
2321
2322 temp_connect_t *tempEdges;
2323
2324
2325 /*
2326 ================
2327 PENTA:
2328 SetupSurfaceConnectivity
2329
2330 Setup the neighour pointers of this surface's polygon.
2331 ================
2332 */
SetupSurfaceConnectivity(msurface_t * surf)2333 void SetupSurfaceConnectivity(msurface_t *surf)
2334 {
2335 int i,j,lindex;
2336 temp_connect_t *tempEdge;
2337
2338 if (surf->numedges > 50) {
2339 Con_Printf ("to many edges %i\n", surf->numedges);
2340 }
2341
2342 for (i=0 ; i<surf->numedges ; i++)
2343 {
2344 lindex = currentmodel->surfedges[surf->firstedge + i];
2345 tempEdge = tempEdges+abs(lindex);
2346
2347 surf->polys->neighbours[i] = NULL;
2348 for (j=0; j<tempEdge->used; j++) {
2349 if (tempEdge->poly[j] != surf->polys) {
2350 surf->polys->neighbours[i] = tempEdge->poly[j];
2351 }
2352 }
2353 }
2354 }
2355
2356 /*
2357 ================
2358 PENTA:
2359 PrintTempEdges
2360
2361 ================
2362 */
PrintTempEdges()2363 void PrintTempEdges()
2364 {
2365 int i;
2366 temp_connect_t *tempEdge;
2367
2368 for (i=0 ; i<currentmodel->numedges ; i++)
2369 {
2370 tempEdge = tempEdges+i;
2371
2372 Con_Printf("moord en brand %d\n",tempEdge->used);
2373 }
2374 }
2375
2376 /*
2377 ================
2378 BuildPolyFromSurface
2379
2380 Creer polygons van de lijst van surfaces om
2381 gemakkelijk aan opengl te geven
2382 ================
2383 */
BuildPolyFromSurface(msurface_t * fa)2384 void BuildPolyFromSurface (msurface_t *fa)
2385 {
2386 int i, lindex, lnumverts;
2387 medge_t *pedges, *r_pedge;
2388 int vertpage;
2389 float *vec;
2390 float s, t;
2391 glpoly_t *poly;
2392 temp_connect_t *tempEdge;
2393 float tex[2];
2394 float light[2];
2395
2396 // reconstruct the polygon
2397 pedges = currentmodel->edges;
2398 lnumverts = fa->numedges;
2399 vertpage = 0;
2400
2401 //
2402 // draw texture <= wat mag dit comment me betekenen?
2403 //
2404 poly = Hunk_Alloc (sizeof(glpoly_t));
2405 //PENTA: reserve space for neighbour pointers
2406 //PENTA: FIXME: pointers don't need to be 4 bytes
2407 poly->neighbours = Hunk_Alloc (lnumverts*4);
2408
2409 poly->next = fa->polys;
2410 poly->flags = fa->flags;
2411 fa->polys = poly;
2412 poly->numverts = lnumverts;
2413 poly->firstvertex = R_GetNextVertexIndex();
2414 for (i=0 ; i<lnumverts ; i++)
2415 {
2416 lindex = currentmodel->surfedges[fa->firstedge + i];
2417
2418 if (lindex > 0)
2419 {
2420 r_pedge = &pedges[lindex];
2421 vec = r_pcurrentvertbase[r_pedge->v[0]].position;
2422 }
2423 else
2424 {
2425 r_pedge = &pedges[-lindex];
2426 vec = r_pcurrentvertbase[r_pedge->v[1]].position;
2427 }
2428 tex[0] = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
2429 tex[0] /= fa->texinfo->texture->width;
2430
2431 tex[1] = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
2432 tex[1] /= fa->texinfo->texture->height;
2433
2434 //
2435 // lightmap texture coordinates
2436 //
2437 light[0] = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
2438 light[0] -= fa->texturemins[0];
2439 light[0] += fa->light_s*16;
2440 light[0] += 8;
2441 light[0] /= BLOCK_WIDTH*16; //fa->texinfo->texture->width;
2442
2443 light[1] = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
2444 light[1] -= fa->texturemins[1];
2445 light[1] += fa->light_t*16;
2446 light[1] += 8;
2447 light[1] /= BLOCK_HEIGHT*16; //fa->texinfo->texture->height;
2448
2449 //Push back the new vertex
2450 R_AllocateVertexInTemp(vec,tex,light);
2451
2452 //PENTA: Store in the tempedges table that this polygon uses the edge
2453 tempEdge = tempEdges+abs(lindex);
2454
2455 if (tempEdge->used < 2) {
2456 tempEdge->poly[tempEdge->used] = poly;
2457 tempEdge->used++;
2458 } else {
2459 Con_Printf ("BuildSurfaceDisplayList: Edge used by more than 2 surfaces\n");
2460 }
2461 }
2462
2463 poly->numverts = lnumverts;
2464
2465 }
2466
2467 /*
2468 ========================
2469 GL_CreateSurfaceLightmap
2470 ========================
2471 */
GL_CreateSurfaceLightmap(msurface_t * surf)2472 void GL_CreateSurfaceLightmap (msurface_t *surf)
2473 {
2474 int smax, tmax;
2475 byte *base;
2476
2477 if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB))
2478 return;
2479
2480 smax = (surf->extents[0]>>4)+1;
2481 tmax = (surf->extents[1]>>4)+1;
2482
2483 surf->lightmaptexturenum = AllocBlock (smax, tmax, &surf->light_s, &surf->light_t);
2484 base = lightmaps + surf->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT;
2485 base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * lightmap_bytes;
2486 R_BuildLightMap (surf, base, BLOCK_WIDTH*lightmap_bytes);
2487 }
2488
2489
2490 /*
2491 ==================
2492 GL_BuildLightmaps
2493
2494 Builds the lightmap texture
2495 with all the surfaces from all brush models
2496 ==================
2497 */
GL_BuildLightmaps(void)2498 void GL_BuildLightmaps (void)
2499 {
2500 int i, j;
2501 model_t *m;
2502 extern qboolean isPermedia;
2503
2504 memset (allocated, 0, sizeof(allocated));
2505
2506 r_framecount = 1; // no dlightcache
2507
2508 if (!lightmap_textures)
2509 {
2510 lightmap_textures = texture_extension_number;
2511 texture_extension_number += MAX_LIGHTMAPS;
2512 }
2513
2514 gl_lightmap_format = GL_LUMINANCE;
2515
2516 // default differently on the Permedia
2517 if (isPermedia)
2518 gl_lightmap_format = GL_RGBA;
2519
2520 if (COM_CheckParm ("-lm_1"))
2521 gl_lightmap_format = GL_LUMINANCE;
2522 if (COM_CheckParm ("-lm_a"))
2523 gl_lightmap_format = GL_ALPHA;
2524 if (COM_CheckParm ("-lm_i"))
2525 gl_lightmap_format = GL_INTENSITY;
2526 if (COM_CheckParm ("-lm_2"))
2527 gl_lightmap_format = GL_RGBA4;
2528 if (COM_CheckParm ("-lm_4"))
2529 gl_lightmap_format = GL_RGBA;
2530
2531 switch (gl_lightmap_format)
2532 {
2533 case GL_RGBA:
2534 lightmap_bytes = 4;
2535 break;
2536 case GL_RGBA4:
2537 lightmap_bytes = 2;
2538 break;
2539 case GL_LUMINANCE:
2540 case GL_INTENSITY:
2541 case GL_ALPHA:
2542 lightmap_bytes = 1;
2543 break;
2544 }
2545
2546 for (j=1 ; j<MAX_MODELS ; j++)
2547 {
2548 m = cl.model_precache[j];
2549 if (!m)
2550 break;
2551 if (m->name[0] == '*')
2552 continue;
2553
2554 r_pcurrentvertbase = m->vertexes;
2555 currentmodel = m;
2556
2557 //PENTA: Allocate storage for our edge table
2558 tempEdges = Hunk_TempAlloc(m->numedges * sizeof(temp_connect_t));
2559
2560 //clear tempedges
2561 for (i=0; i<m->numedges; i++) {
2562 tempEdges[i].used = 0;
2563 tempEdges[i].poly[0] = NULL;
2564 tempEdges[i].poly[1] = NULL;
2565 }
2566
2567
2568
2569 for (i=0 ; i<m->numsurfaces ; i++)
2570 {
2571 GL_CreateSurfaceLightmap (m->surfaces + i);
2572 if ( m->surfaces[i].flags & SURF_DRAWTURB )
2573 continue;
2574 /*#ifndef QUAKE2
2575 if ( m->surfaces[i].flags & SURF_DRAWSKY )
2576 continue;
2577 #endif*/
2578 BuildPolyFromSurface (m->surfaces + i);
2579 }
2580
2581 //PENTA: we now have the connectivity in tempEdges now store it in the polygons
2582 for (i=0 ; i<m->numsurfaces ; i++)
2583 {
2584 if ( m->surfaces[i].flags & SURF_DRAWTURB )
2585 continue;
2586 #ifndef QUAKE2
2587 if ( m->surfaces[i].flags & SURF_DRAWSKY )
2588 continue;
2589 #endif
2590 SetupSurfaceConnectivity (m->surfaces + i);
2591 }
2592
2593 }
2594 Con_Printf("Connectivity calculated\n");
2595
2596
2597 /*
2598 PENTA: Normalize texture coordinate s/t's since we now use them as tangent space
2599 */
2600 for (j=1 ; j<MAX_MODELS ; j++)
2601 {
2602 mtexinfo_t *texinfos;
2603
2604 m = cl.model_precache[j];
2605 if (!m)
2606 break;
2607 if (m->name[0] == '*')
2608 continue;
2609
2610 texinfos = m->texinfo;
2611 for (i=0; i<m->numtexinfo; i++) {
2612 VectorNormalize(texinfos[i].vecs[0]);
2613 VectorNormalize(texinfos[i].vecs[1]);
2614 }
2615 }
2616
2617
2618 /*
2619 if (!gl_texsort.value)
2620 GL_SelectTexture(GL_TEXTURE1_ARB);
2621 */
2622
2623 //
2624 // upload all lightmaps that were filled
2625 //
2626 for (i=0 ; i<MAX_LIGHTMAPS ; i++)
2627 {
2628 if (!allocated[i][0])
2629 break; // no more used
2630 lightmap_modified[i] = false;
2631 lightmap_rectchange[i].l = BLOCK_WIDTH;
2632 lightmap_rectchange[i].t = BLOCK_HEIGHT;
2633 lightmap_rectchange[i].w = 0;
2634 lightmap_rectchange[i].h = 0;
2635 GL_Bind(lightmap_textures + i);
2636 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2637 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2638 glTexImage2D (GL_TEXTURE_2D, 0, lightmap_bytes
2639 , BLOCK_WIDTH, BLOCK_HEIGHT, 0,
2640 gl_lightmap_format, GL_UNSIGNED_BYTE, lightmaps+i*BLOCK_WIDTH*BLOCK_HEIGHT*lightmap_bytes);
2641 }
2642
2643 /*
2644 if (!gl_texsort.value)
2645 GL_SelectTexture(GL_TEXTURE0_ARB);
2646 */
2647
2648 }
2649
2650