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