1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 Copyright (C) 2011 COR Entertainment, LLC.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
14 See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 */
21 // R_SURF.C: surface-related refresh code
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <assert.h>
28
29 #include "r_local.h"
30
31 static vec3_t modelorg; // relative to viewpoint
32
33 vec3_t r_worldLightVec;
34 dlight_t *dynLight;
35
36 #define LIGHTMAP_BYTES 4
37
38 //Pretty safe bet most cards support this
39 #define LIGHTMAP_SIZE 2048
40 #define MAX_LIGHTMAPS 12
41
42 int c_visible_lightmaps;
43 int c_visible_textures;
44
45 // This is supposed to be faster on some older hardware.
46 #define GL_LIGHTMAP_FORMAT GL_BGRA
47
48 typedef struct
49 {
50 int current_lightmap_texture;
51
52 // For each column, what is the last row where a pixel is used
53 int allocated[LIGHTMAP_SIZE];
54
55 // Lightmap texture data (RGBA, alpha not used)
56 byte lightmap_buffer[4*LIGHTMAP_SIZE*LIGHTMAP_SIZE];
57 } gllightmapstate_t;
58
59 // TODO: dynamically allocate this so we can free it for RAM savings? It's
60 // using over 16 megs.
61 static gllightmapstate_t gl_lms;
62
63 static void LM_InitBlock( void );
64 static void LM_UploadBlock( );
65 static qboolean LM_AllocBlock (int w, int h, int *x, int *y);
66
67 extern void R_SetCacheState( msurface_t *surf );
68 extern void R_BuildLightMap (msurface_t *surf, byte *dest, int smax, int tmax, int stride);
69
70 /*
71 ===============
72 BSP_TextureAnimation
73
74 Returns the proper texture for a given time and base texture
75 XXX: AFAIK this is only used for the old .wal textures, and is a bit redundant
76 with the rscript system, although it is implemented more efficiently. Maybe
77 merge the two systems somehow?
78 ===============
79 */
BSP_TextureAnimation(mtexinfo_t * tex)80 image_t *BSP_TextureAnimation (mtexinfo_t *tex)
81 {
82 int c;
83
84 if (!tex->next)
85 return tex->image;
86
87 c = currententity->frame % tex->numframes;
88 while (c)
89 {
90 tex = tex->next;
91 c--;
92 }
93
94 return tex->image;
95 }
96
97
98
99 /*
100 =========================================
101
102 Textureless Surface Rendering
103 Used by the shadow system
104
105 =========================================
106 */
107
108 /*
109 ================
110 BSP_DrawTexturelessPoly
111 ================
112 */
BSP_DrawTexturelessPoly(msurface_t * fa)113 void BSP_DrawTexturelessPoly (msurface_t *fa)
114 {
115 R_InitVArrays(VERT_NO_TEXTURE);
116 R_AddSurfToVArray (fa);
117 R_KillVArrays();
118 }
119
BSP_DrawShadowPoly(msurface_t * fa,vec3_t origin)120 void BSP_DrawShadowPoly (msurface_t *fa, vec3_t origin)
121 {
122 R_AddShadowSurfToVArray (fa, origin);
123 }
124
BSP_DrawTexturelessInlineBModel(entity_t * e)125 void BSP_DrawTexturelessInlineBModel (entity_t *e)
126 {
127 int i;
128 msurface_t *psurf;
129
130 //
131 // draw texture
132 //
133 psurf = ¤tmodel->surfaces[currentmodel->firstmodelsurface];
134 for (i=0 ; i<currentmodel->nummodelsurfaces ; i++, psurf++)
135 {
136
137 // draw the polygon
138 BSP_DrawTexturelessPoly( psurf );
139 psurf->visframe = r_framecount;
140 }
141
142 qglDisable (GL_BLEND);
143 qglColor4f (1,1,1,1);
144 GL_TexEnv( GL_REPLACE );
145 }
146
BSP_DrawTexturelessBrushModel(entity_t * e)147 void BSP_DrawTexturelessBrushModel (entity_t *e)
148 {
149 vec3_t mins, maxs;
150 int i;
151 qboolean rotated;
152
153 if (currentmodel->nummodelsurfaces == 0)
154 return;
155
156 currententity = e;
157
158 if (e->angles[0] || e->angles[1] || e->angles[2])
159 {
160 rotated = true;
161 for (i=0 ; i<3 ; i++)
162 {
163 mins[i] = e->origin[i] - currentmodel->radius;
164 maxs[i] = e->origin[i] + currentmodel->radius;
165 }
166 }
167 else
168 {
169 rotated = false;
170 VectorAdd (e->origin, currentmodel->mins, mins);
171 VectorAdd (e->origin, currentmodel->maxs, maxs);
172 }
173
174 if (R_CullBox (mins, maxs)) {
175 return;
176 }
177
178 qglColor3f (1,1,1);
179
180 VectorSubtract (r_newrefdef.vieworg, e->origin, modelorg);
181
182 if (rotated)
183 {
184 vec3_t temp;
185 vec3_t forward, right, up;
186
187 VectorCopy (modelorg, temp);
188 AngleVectors (e->angles, forward, right, up);
189 modelorg[0] = DotProduct (temp, forward);
190 modelorg[1] = -DotProduct (temp, right);
191 modelorg[2] = DotProduct (temp, up);
192 }
193
194 qglPushMatrix ();
195 e->angles[0] = -e->angles[0]; // stupid quake bug
196 e->angles[2] = -e->angles[2]; // stupid quake bug
197 R_RotateForEntity (e);
198 e->angles[0] = -e->angles[0]; // stupid quake bug
199 e->angles[2] = -e->angles[2]; // stupid quake bug
200
201 BSP_DrawTexturelessInlineBModel (e);
202
203 qglPopMatrix ();
204 }
205
206
207
208 /*
209 =========================================
210
211 BSP Surface Rendering
212 Common between brush and world models
213
214 =========================================
215 */
216
217
218 /*
219 =========================================
220 Special surfaces - Somewhat less common, require more work to render
221 - Translucent ("alpha") surfaces
222 These are special because they have to be rendered all in one pass, despite
223 consisting of several different types of surfaces, so the code can't make
224 too many assumptions about the surface.
225 - Rscript surfaces (those with material shaders)
226 Rscript surfaces are first rendered through the "ordinary" path, then
227 this one.
228 - Wavy, rippling ("warp") surfaces
229 The code to actually render these is in r_warp.c.
230 =========================================
231 */
232
233
234 // The "special" surfaces use these for linked lists.
235 // The reason to have linked lists for surfaces from brush model entities
236 // separate from the linked lists for world surfaces is that the world
237 // surface linked lists can be preserved between frames if r_optimize is on,
238 // whereas the entity linked lists must be cleared each time an entity is
239 // drawn.
240 msurface_t *r_alpha_surfaces;
241 msurface_t *r_ent_alpha_surfaces;
242 msurface_t *r_rscript_surfaces; // no brush models can have rscript surfs
243 msurface_t *r_warp_surfaces;
244 msurface_t *r_ent_warp_surfaces;
245
246 // This is a chain of surfaces that may need to have their lightmaps updated.
247 // They are not rendered in the order of this chain and will be linked into
248 // other chains for rendering.
249 msurface_t *r_flicker_surfaces;
250
251
252 /*
253 ================
254 BSP_DrawWarpSurfaces
255 ================
256 */
BSP_DrawWarpSurfaces(qboolean forEnt)257 void BSP_DrawWarpSurfaces (qboolean forEnt)
258 {
259 msurface_t *surf;
260 image_t *image;
261
262 if (forEnt)
263 surf = r_ent_warp_surfaces;
264 else
265 surf = r_warp_surfaces;
266
267 if (surf == NULL)
268 return;
269
270 // no lightmaps rendered on these surfaces
271 GL_EnableMultitexture( false );
272 GL_TexEnv( GL_MODULATE );
273 qglColor4f( gl_state.inverse_intensity,
274 gl_state.inverse_intensity,
275 gl_state.inverse_intensity,
276 1.0F );
277 while (surf)
278 {
279 c_brush_polys++;
280 image = BSP_TextureAnimation (surf->texinfo);
281 GL_Bind (image->texnum);
282 R_RenderWaterPolys(surf, 0, 1, 1);
283 surf = surf->texturechain;
284 }
285
286 if (forEnt)
287 r_ent_warp_surfaces = NULL;
288
289 GL_EnableMultitexture( true );
290 GL_TexEnv( GL_REPLACE );
291 R_KillVArrays ();
292 }
293
294 /*
295 ================
296 BSP_DrawAlphaPoly
297 ================
298 */
BSP_DrawAlphaPoly(msurface_t * fa,int flags)299 void BSP_DrawAlphaPoly (msurface_t *fa, int flags)
300
301 {
302 float scroll;
303
304 scroll = 0;
305 if (flags & SURF_FLOWING)
306 {
307
308 scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
309 if (scroll == 0.0)
310
311 scroll = -64.0;
312 }
313
314 R_InitVArrays(VERT_SINGLE_TEXTURED);
315
316 R_AddTexturedSurfToVArray (fa, scroll);
317 R_KillVArrays();
318 }
319
320
321 /*
322 ================
323 R_DrawAlphaSurfaces
324
325 Draw water surfaces and windows.
326
327 Annoyingly, because alpha surfaces have to be drawn from back to front,
328 everything transparent-- water, rscripted surfs, and non-rscripted surfs-- has
329 to be drawn in a single pass. This is an inherently inefficient process.
330
331 The BSP tree is walked front to back, so unwinding the chain of alpha surfaces
332 will draw back to front, giving proper ordering FOR BSP SURFACES!
333
334
335 It's a bit wrong for entity surfaces (i.e. glass doors.) Because they are in
336 separate linked lists, the entity surfaces must be either always behind or
337 always in front of the world surfaces. I chose always in front because that
338 seems to fix all rendering issues, regardless of whether the entity actually
339 is in front. Search me why. NOTE: this bug existed even when it was all one
340 linked list, although at that time entity surfaces were always behind map
341 surfaces (added to the beginning of the linked list after all the BSP
342 rendering code.)
343 ================
344 */
R_DrawAlphaSurfaces_chain(msurface_t * chain)345 void R_DrawAlphaSurfaces_chain (msurface_t *chain)
346 {
347 msurface_t *s;
348 float intens;
349 rscript_t *rs_shader;
350 rs_stage_t *stage = NULL;
351 int texnum = 0;
352 float scaleX = 1.0f, scaleY = 1.0f;
353
354 // the textures are prescaled up for a better lighting range,
355 // so scale it back down
356 intens = gl_state.inverse_intensity;
357
358 qglDepthMask ( GL_FALSE );
359 qglEnable (GL_BLEND);
360 GL_TexEnv( GL_MODULATE );
361
362 for (s=chain ; s ; s=s->texturechain)
363 {
364 GL_Bind(s->texinfo->image->texnum);
365 c_brush_polys++;
366
367 if (s->texinfo->flags & SURF_TRANS33)
368 qglColor4f (intens, intens, intens, 0.33);
369 else if (s->texinfo->flags & SURF_TRANS66)
370 qglColor4f (intens, intens, intens, 0.66);
371 else
372 qglColor4f (intens, intens, intens, 1);
373
374 //moving trans brushes
375 if (s->entity)
376 {
377 qglLoadMatrixf (r_world_matrix); //moving trans brushes
378 s->entity->angles[0] = -s->entity->angles[0]; // stupid quake bug
379 s->entity->angles[2] = -s->entity->angles[2]; // stupid quake bug
380 R_RotateForEntity (s->entity);
381 s->entity->angles[0] = -s->entity->angles[0]; // stupid quake bug
382 s->entity->angles[2] = -s->entity->angles[2]; // stupid quake bug
383 }
384
385 rs_shader = NULL;
386 if (r_shaders->integer)
387 rs_shader = (rscript_t *)s->texinfo->image->script;
388
389 if (s->iflags & ISURF_DRAWTURB)
390 {
391 //water shaders
392 scaleX = scaleY = 1.0f;
393 if(rs_shader)
394 {
395 stage = rs_shader->stage;
396 if(stage)
397 { //for now, just map a reflection texture
398 texnum = stage->texture->texnum; //pass this to renderwaterpolys
399 }
400 if(stage->scale.scaleX != 0 && stage->scale.scaleY !=0)
401 {
402 scaleX = stage->scale.scaleX;
403 scaleY = stage->scale.scaleY;
404 }
405 }
406 R_RenderWaterPolys (s, texnum, scaleX, scaleY);
407 qglEnable (GL_BLEND);
408 GL_TexEnv( GL_MODULATE );
409 }
410 else if(rs_shader && !(s->texinfo->flags & SURF_FLOWING))
411 {
412 RS_Surface(s);
413 qglEnable (GL_BLEND);
414 GL_TexEnv( GL_MODULATE );
415 }
416 else
417 BSP_DrawAlphaPoly (s, s->texinfo->flags);
418 }
419
420 GL_TexEnv( GL_REPLACE );
421 qglColor4f (1,1,1,1);
422 qglDisable (GL_BLEND);
423 qglDepthMask ( GL_TRUE );
424 }
425
R_DrawAlphaSurfaces(void)426 void R_DrawAlphaSurfaces (void)
427 {
428 R_DrawAlphaSurfaces_chain (r_alpha_surfaces);
429 R_DrawAlphaSurfaces_chain (r_ent_alpha_surfaces);
430 qglLoadMatrixf (r_world_matrix); //moving trans brushes
431 r_ent_alpha_surfaces = NULL;
432 }
433
434 /*
435 ================
436 R_DrawRSSurfaces
437
438 Draw shader surfaces
439 ================
440 */
R_DrawRSSurfaces(void)441 void R_DrawRSSurfaces (void)
442 {
443 msurface_t *s = r_rscript_surfaces;
444
445 if(!s)
446 return;
447
448 if (!r_shaders->integer)
449 {
450 r_rscript_surfaces = NULL;
451 return;
452 }
453
454 qglDepthMask(false);
455 qglShadeModel (GL_SMOOTH);
456
457 qglEnable(GL_POLYGON_OFFSET_FILL);
458 qglPolygonOffset(-3, -2);
459
460 for (; s; s = s->rscriptchain)
461 RS_Surface(s);
462
463 qglDisable(GL_POLYGON_OFFSET_FILL);
464
465 GLSTATE_DISABLE_BLEND
466 GLSTATE_DISABLE_ALPHATEST
467
468 qglDepthMask(true);
469 }
470
471
472
473 /*
474 =========================================
475 Ordinary surfaces (fixed-function, normalmapped, and dynamically lit)
476 These are the most commonly used types of surfaces, so the rendering code path
477 for each is more optimized-- surfaces grouped by texinfo, VBOs, VBO batching,
478 etc.
479 =========================================
480 */
481
482 // The "ordinary" surfaces do not use global variables for linked lists. The
483 // linked lists are in the texinfo struct, so the textures can be grouped by
484 // texinfo. Like the "special" surfaces, there are separate linked lists for
485 // entity surfaces and world surfaces.
486
487 // State variables for detecting changes from one surface to the next. If any
488 // of these change, the current batch of polygons to render is flushed. This
489 // helps minimize GL state change calls and draw calls.
490 int r_currTex = -9999; //only bind a texture if it is not the same as previous surface
491 int r_currLMTex = -9999; //lightmap texture
492 mtexinfo_t *r_currTexInfo = NULL; //texinfo struct
493 float *r_currTangentSpaceTransform; //etc.
494
495 // VBO batching
496 // This system allows contiguous sequences of polygons to be merged into
497 // batches, even if they are added out of order.
498
499 // There is a linked list of these, but they are not dynamically allocated.
500 // They are allocated from a static array. This prevents us wasting CPU with
501 // lots of malloc/free calls. Keep this struct small for performance!
502 typedef struct vbobatch_s {
503 int first_vert, last_vert;
504 struct vbobatch_s *next;
505 } vbobatch_t;
506
507 #define MAX_VBO_BATCHES 100 // 100 ought to be enough. If we run out, we can
508 // always just draw some prematurely.
509
510 // use a static array and counter to avoid lots of malloc nonsense
511 int num_vbo_batches;
512 vbobatch_t vbobatch_buffer[MAX_VBO_BATCHES];
513 // never used directly; linked list base only
514 vbobatch_t first_vbobatch[] = {{-1, -1, NULL}};
515 // if false, flushVBOAccum will set up the VBO GL state
516 qboolean r_vboOn = false;
517 // for the rspeed_vbobatches HUD gauge
518 int c_vbo_batches;
519
520 // clear all accumulated surfaces without rendering
BSP_ClearVBOAccum(void)521 static inline void BSP_ClearVBOAccum (void)
522 {
523 memset (vbobatch_buffer, 0, sizeof(vbobatch_buffer));
524 num_vbo_batches = 0;
525 first_vbobatch->next = NULL;
526 }
527
528 // render all accumulated surfaces, then clear them
529 // XXX: assumes that global OpenGL state is correct for whatever surfaces are
530 // in the accumulator, so don't change state until you've called this!
BSP_FlushVBOAccum(void)531 static inline void BSP_FlushVBOAccum (void)
532 {
533 vbobatch_t *batch = first_vbobatch->next;
534
535 if (!batch)
536 return;
537
538 if (!r_vboOn)
539 {
540 GL_SetupWorldVBO ();
541 r_vboOn = true;
542 }
543
544 // XXX: for future reference, the glDrawRangeElements code was last seen
545 // here at revision 3246.
546 for (; batch; batch = batch->next)
547 {
548 qglDrawArrays (GL_TRIANGLES, batch->first_vert, batch->last_vert-batch->first_vert);
549 c_vbo_batches++;
550 }
551
552 BSP_ClearVBOAccum ();
553 }
554
555 // Add a new surface to the VBO batch accumulator. If its vertex data is next
556 // to any other surfaces within the VBO, opportunistically merge the surfaces
557 // together into a larger "batch," so they can be rendered with one draw call.
558 // Whenever two batches touch each other, they are merged. Hundreds of
559 // surfaces can be rendered with a single call, which is easier on the OpenGL
560 // pipeline.
BSP_AddToVBOAccum(int first_vert,int last_vert)561 static inline void BSP_AddToVBOAccum (int first_vert, int last_vert)
562 {
563 vbobatch_t *batch = first_vbobatch->next, *prev = first_vbobatch;
564 vbobatch_t *new;
565
566 if (!batch)
567 {
568 batch = first_vbobatch->next = vbobatch_buffer;
569 batch->first_vert = first_vert;
570 batch->last_vert = last_vert;
571 num_vbo_batches++;
572 return;
573 }
574
575 // This is optimal. Because of the way the surface linked lists are built
576 // by BSP_AddToTextureChain, they are usually in reverse order, so it's
577 // best to start toward the beginning of the list of VBO batches where
578 // you're more likely to merge something.
579
580 while (batch->next && batch->next->first_vert < first_vert)
581 {
582 prev = batch;
583 batch = batch->next;
584 }
585
586 if (batch->first_vert > last_vert)
587 {
588 new = &vbobatch_buffer[num_vbo_batches++];
589 new->next = batch;
590 prev->next = new;
591 new->first_vert = first_vert;
592 new->last_vert = last_vert;
593 }
594 else if (batch->last_vert == first_vert)
595 {
596 batch->last_vert = last_vert;
597 if (batch->next && batch->next->first_vert == last_vert)
598 {
599 // This is the special case where the new surface bridges the gap
600 // between two existing batches, allowing us to merge them into
601 // the first one. This is the only case where we actually remove a
602 // batch instead of growing one or adding one.
603 batch->last_vert = batch->next->last_vert;
604 if (batch->next == &vbobatch_buffer[num_vbo_batches-1])
605 num_vbo_batches--;
606 batch->next = batch->next->next;
607 }
608 return; //no need to check for maximum batch count being hit
609 }
610 else if (batch->next && batch->next->first_vert == last_vert)
611 {
612 batch->next->first_vert = first_vert;
613 return; //no need to check for maximum batch count being hit
614 }
615 else if (batch->first_vert == last_vert)
616 {
617 batch->first_vert = first_vert;
618 return; //no need to check for maximum batch count being hit
619 }
620 else //if (batch->last_vert < first_vert)
621 {
622 new = &vbobatch_buffer[num_vbo_batches++];
623 new->next = batch->next;
624 batch->next = new;
625 new->first_vert = first_vert;
626 new->last_vert = last_vert;
627 }
628
629 //running out of space
630 if (num_vbo_batches == MAX_VBO_BATCHES)
631 {
632 /* Com_Printf ("MUSTFLUSH\n");*/
633 BSP_FlushVBOAccum ();
634 }
635 }
636
637 /*
638 ================
639 BSP_NonGLSLTexinfoChanged
640
641 Update GL state as needed so we can draw a new batch of surfaces for the
642 provided texinfo (version for all fixed-function standard surfaces)
643 ================
644 */
BSP_NonGLSLTexinfoChanged(mtexinfo_t * texinfo)645 static void BSP_NonGLSLTexinfoChanged (mtexinfo_t *texinfo)
646 {
647 int texnum;
648
649 BSP_FlushVBOAccum ();
650
651 if (TexinfoIsAlphaBlended (texinfo))
652 {
653 if (!r_currTexInfo || !TexinfoIsAlphaBlended(r_currTexInfo))
654 {
655 qglEnable( GL_ALPHA_TEST );
656 }
657 }
658 else
659 {
660 if (!r_currTexInfo || TexinfoIsAlphaBlended(r_currTexInfo))
661 {
662 qglDisable( GL_ALPHA_TEST );
663 }
664 }
665
666 // do this here so only have to do it once instead of for each surface
667 texnum = BSP_TextureAnimation( texinfo )->texnum;
668
669 if(texnum != r_currTex)
670 {
671 qglActiveTextureARB(GL_TEXTURE0);
672 qglBindTexture(GL_TEXTURE_2D, texnum );
673 r_currTex = texnum;
674 }
675
676 r_currTexInfo = texinfo;
677 }
678
679 /*
680 ================
681 BSP_RenderLightmappedPoly
682
683 Main polygon rendering routine (all fixed-function standard surfaces)
684 ================
685 */
BSP_RenderLightmappedPoly(msurface_t * surf)686 static void BSP_RenderLightmappedPoly( msurface_t *surf)
687 {
688 float scroll;
689 unsigned lmtex = surf->lightmaptexturenum;
690
691 c_brush_polys++;
692
693 if (lmtex != r_currLMTex)
694 {
695 BSP_FlushVBOAccum ();
696 qglActiveTextureARB(GL_TEXTURE1);
697 qglBindTexture(GL_TEXTURE_2D, gl_state.lightmap_textures + lmtex );
698 }
699
700 if(gl_state.vbo && surf->has_vbo && !(surf->texinfo->flags & SURF_FLOWING))
701 {
702 BSP_AddToVBOAccum (surf->vbo_first_vert, surf->vbo_first_vert+surf->vbo_num_verts);
703 }
704 else
705 {
706 BSP_FlushVBOAccum ();
707 r_vboOn = false;
708 scroll = 0;
709 if (surf->texinfo->flags & SURF_FLOWING)
710 {
711 scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
712 if (scroll == 0.0)
713 scroll = -64.0;
714 }
715 R_InitVArrays (VERT_MULTI_TEXTURED);
716 R_AddLightMappedSurfToVArray (surf, scroll);
717 }
718
719 }
720
721 /*
722 ================
723 BSP_GLSLTexinfoChanged
724
725 Update GL state as needed so we can draw a new batch of surfaces for the
726 provided texinfo (version for all normalmapped and/or dynamically lit standard
727 surfaces)
728 ================
729 */
BSP_GLSLTexinfoChanged(mtexinfo_t * texinfo,qboolean dynamic)730 static void BSP_GLSLTexinfoChanged (mtexinfo_t *texinfo, qboolean dynamic)
731 {
732 int texnum;
733
734 BSP_FlushVBOAccum ();
735
736 if (TexinfoIsAlphaBlended (texinfo))
737 {
738 if (!r_currTexInfo || !TexinfoIsAlphaBlended(r_currTexInfo))
739 {
740 qglEnable( GL_ALPHA_TEST );
741 }
742 }
743 else
744 {
745 if (!r_currTexInfo || TexinfoIsAlphaBlended(r_currTexInfo))
746 {
747 qglDisable( GL_ALPHA_TEST );
748 }
749 }
750
751 // no texture animation for normalmapped surfaces, for some reason
752 texnum = texinfo->image->texnum;
753
754 if(texnum != r_currTex)
755 {
756 r_currTex = texnum;
757
758 if (!r_currTexInfo)
759 {
760 glUniform1iARB( g_location_surfTexture, 0);
761 glUniform1iARB( g_location_heightTexture, 1);
762 glUniform1iARB( g_location_normalTexture, 2);
763 glUniform1iARB( g_location_lmTexture, 3);
764 }
765
766 qglActiveTextureARB(GL_TEXTURE0);
767 qglBindTexture(GL_TEXTURE_2D, texnum);
768
769 qglActiveTextureARB(GL_TEXTURE1);
770 qglBindTexture(GL_TEXTURE_2D, texinfo->heightMap->texnum);
771
772 qglActiveTextureARB(GL_TEXTURE2);
773 qglBindTexture(GL_TEXTURE_2D, texinfo->normalMap->texnum);
774 KillFlags |= KILL_TMU2_POINTER;
775 }
776
777 if (dynamic)
778 {
779 if(gl_bspnormalmaps->integer && texinfo->has_heightmap)
780 {
781 if (!r_currTexInfo || !r_currTexInfo->has_heightmap)
782 {
783 glUniform1iARB( g_location_parallax, 1);
784 }
785 }
786 else
787 {
788 if (!r_currTexInfo || r_currTexInfo->has_heightmap)
789 {
790 glUniform1iARB( g_location_parallax, 0);
791 }
792 }
793 }
794
795 if (!gl_bspnormalmaps->integer)
796 {
797 if (!r_currTexInfo)
798 {
799 glUniform1iARB( g_location_liquid, 0 );
800 glUniform1iARB( g_location_shiny, 0 );
801 }
802 }
803 else if (r_currTexInfo &&
804 (texinfo->flags & (SURF_BLOOD|SURF_WATER|SURF_SHINY)) ==
805 (r_currTexInfo->flags & (SURF_BLOOD|SURF_WATER|SURF_SHINY)))
806 {
807 //no change to GL state is needed
808 }
809 else if (texinfo->flags & SURF_BLOOD)
810 {
811 //need to bind the blood drop normal map, and set flag, and time
812 glUniform1iARB( g_location_liquid, 8 ); //blood type 8, water 1
813 glUniform1iARB( g_location_shiny, 0 );
814 glUniform1fARB( g_location_rsTime, rs_realtime);
815 glUniform1iARB( g_location_liquidTexture, 4); //for blood we are going to need to send a diffuse texture with it
816 qglActiveTextureARB(GL_TEXTURE4);
817 qglBindTexture(GL_TEXTURE_2D, r_blooddroplets->texnum);
818 KillFlags |= KILL_TMU4_POINTER;
819 glUniform1iARB( g_location_liquidNormTex, 5);
820 qglActiveTextureARB(GL_TEXTURE5);
821 qglBindTexture(GL_TEXTURE_2D, r_blooddroplets_nm->texnum);
822 KillFlags |= KILL_TMU5_POINTER;
823 }
824 else if (texinfo->flags & SURF_WATER)
825 {
826 //need to bind the water drop normal map, and set flag, and time
827 glUniform1iARB( g_location_liquid, 1 );
828 glUniform1iARB( g_location_shiny, 0 );
829 glUniform1fARB( g_location_rsTime, rs_realtime);
830 glUniform1iARB( g_location_liquidNormTex, 4); //for blood we are going to need to send a diffuse texture with it(maybe even height!)
831 qglActiveTextureARB(GL_TEXTURE4);
832 qglBindTexture(GL_TEXTURE_2D, r_droplets->texnum);
833 KillFlags |= KILL_TMU4_POINTER;
834 }
835 else if (texinfo->flags & SURF_SHINY)
836 {
837 glUniform1iARB( g_location_liquid, 0 );
838 glUniform1iARB( g_location_shiny, 1 );
839
840 glUniform1iARB( g_location_chromeTex, 4);
841 qglActiveTextureARB(GL_TEXTURE4);
842 qglBindTexture(GL_TEXTURE_2D, r_mirrorspec->texnum);
843 KillFlags |= KILL_TMU4_POINTER;
844 }
845 else if (!r_currTexInfo || r_currTexInfo->flags & (SURF_BLOOD|SURF_WATER|SURF_SHINY))
846 {
847 glUniform1iARB( g_location_liquid, 0 );
848 glUniform1iARB( g_location_shiny, 0 );
849 }
850
851 r_currTexInfo = texinfo;
852 }
853
854 /*
855 ================
856 BSP_RenderGLSLLightmappedPoly
857
858 Main polygon rendering routine (all normalmapped and/or dynamically lit
859 standard surfaces)
860 ================
861 */
BSP_RenderGLSLLightmappedPoly(msurface_t * surf)862 static void BSP_RenderGLSLLightmappedPoly( msurface_t *surf)
863 {
864 static float scroll;
865 unsigned lmtex = surf->lightmaptexturenum;
866
867 c_brush_polys++;
868
869 scroll = 0;
870
871 if (lmtex != r_currLMTex)
872 {
873 BSP_FlushVBOAccum ();
874 qglActiveTextureARB(GL_TEXTURE3);
875 qglBindTexture(GL_TEXTURE_2D, gl_state.lightmap_textures + lmtex);
876 KillFlags |= KILL_TMU3_POINTER;
877 }
878
879 if (r_currTangentSpaceTransform != surf->tangentSpaceTransform)
880 {
881 BSP_FlushVBOAccum ();
882 glUniformMatrix3fvARB( g_tangentSpaceTransform, 1, GL_FALSE, (const GLfloat *) surf->tangentSpaceTransform );
883 r_currTangentSpaceTransform = (float *)surf->tangentSpaceTransform;
884 }
885
886 if(gl_state.vbo && surf->has_vbo && !(surf->texinfo->flags & SURF_FLOWING))
887 {
888 BSP_AddToVBOAccum (surf->vbo_first_vert, surf->vbo_first_vert+surf->vbo_num_verts);
889 }
890 else
891 {
892 BSP_FlushVBOAccum ();
893 r_vboOn = false;
894 scroll = 0;
895 if (surf->texinfo->flags & SURF_FLOWING)
896 {
897 scroll = -64 * ( (r_newrefdef.time / 40.0) - (int)(r_newrefdef.time / 40.0) );
898 if (scroll == 0.0)
899 scroll = -64.0;
900 }
901 R_InitVArrays (VERT_MULTI_TEXTURED);
902 R_AddLightMappedSurfToVArray (surf, scroll);
903 }
904 }
905
BSP_DrawNonGLSLSurfaces(qboolean forEnt)906 void BSP_DrawNonGLSLSurfaces (qboolean forEnt)
907 {
908 int i;
909
910 // reset VBO batching state
911 r_currTex = r_currLMTex = -99999;
912 r_currTexInfo = NULL;
913 r_currTangentSpaceTransform = NULL;
914
915 BSP_FlushVBOAccum ();
916
917 r_vboOn = false;
918
919 qglEnableClientState( GL_VERTEX_ARRAY );
920 qglClientActiveTextureARB (GL_TEXTURE0);
921 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
922 qglClientActiveTextureARB (GL_TEXTURE1);
923 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
924 KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER);
925
926 for (i = 0; i < currentmodel->num_unique_texinfos; i++)
927 {
928 msurface_t *s;
929 if (forEnt)
930 {
931 s = currentmodel->unique_texinfo[i]->e_lightmap_surfaces;
932 currentmodel->unique_texinfo[i]->e_lightmap_surfaces = NULL;
933 }
934 else
935 {
936 s = currentmodel->unique_texinfo[i]->w_lightmap_surfaces;
937 }
938 if (!s)
939 continue;
940 BSP_NonGLSLTexinfoChanged (s->texinfo->equiv);
941 for (; s; s = s->texturechain) {
942 BSP_RenderLightmappedPoly(s);
943 r_currLMTex = s->lightmaptexturenum;
944 }
945 }
946
947 BSP_FlushVBOAccum ();
948
949 qglActiveTextureARB(GL_TEXTURE1);
950 qglBindTexture(GL_TEXTURE_2D, 0 );
951
952 qglDisable (GL_ALPHA_TEST);
953
954 }
955
BSP_DrawGLSLSurfaces(qboolean forEnt)956 void BSP_DrawGLSLSurfaces (qboolean forEnt)
957 {
958 int i;
959
960 // reset VBO batching state
961 r_currTex = r_currLMTex = -99999;
962 r_currTexInfo = NULL;
963 r_currTangentSpaceTransform = NULL;
964
965 if (!gl_bspnormalmaps->integer)
966 {
967 return;
968 }
969
970 BSP_ClearVBOAccum ();
971
972 if(r_shadowmapcount == 2)
973 {
974 //static vegetation shadow
975 glUniform1iARB( g_location_bspShadowmapTexture2, 6);
976 qglActiveTextureARB(GL_TEXTURE6);
977 qglBindTexture(GL_TEXTURE_2D, r_depthtexture2->texnum);
978
979 glUniform1iARB( g_location_shadowmap, 1);
980 glUniform1iARB( g_Location_statshadow, 1 );
981
982 glUniform1fARB( g_location_xOffs, 1.0/(viddef.width*r_shadowmapscale->value));
983 glUniform1fARB( g_location_yOffs, 1.0/(viddef.height*r_shadowmapscale->value));
984 }
985 else
986 {
987 glUniform1iARB( g_location_shadowmap, 0);
988 glUniform1iARB( g_Location_statshadow, 0);
989 }
990
991 glUniform1iARB( g_location_dynamic, 0);
992 glUniform1iARB( g_location_parallax, 1);
993
994 r_vboOn = false;
995
996 qglEnableClientState( GL_VERTEX_ARRAY );
997 qglClientActiveTextureARB (GL_TEXTURE0);
998 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
999 qglClientActiveTextureARB (GL_TEXTURE1);
1000 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
1001 KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER);
1002
1003 for (i = 0; i < currentmodel->num_unique_texinfos; i++)
1004 {
1005 msurface_t *s;
1006 if (forEnt)
1007 {
1008 s = currentmodel->unique_texinfo[i]->e_glsl_surfaces;
1009 currentmodel->unique_texinfo[i]->e_glsl_surfaces = NULL;
1010 }
1011 else
1012 {
1013 s = currentmodel->unique_texinfo[i]->w_glsl_surfaces;
1014 }
1015 if (!s)
1016 continue;
1017 BSP_GLSLTexinfoChanged (s->texinfo->equiv, false);
1018 for (; s; s = s->texturechain) {
1019 BSP_RenderGLSLLightmappedPoly(s);
1020 r_currLMTex = s->lightmaptexturenum;
1021 }
1022 }
1023
1024 BSP_FlushVBOAccum ();
1025
1026 qglDisable (GL_ALPHA_TEST);
1027
1028 qglActiveTextureARB (GL_TEXTURE1);
1029 qglDisable (GL_TEXTURE_2D);
1030
1031 }
1032
BSP_DrawGLSLDynamicSurfaces(qboolean forEnt)1033 void BSP_DrawGLSLDynamicSurfaces (qboolean forEnt)
1034 {
1035 int i;
1036 dlight_t *dl = NULL;
1037 int lnum, sv_lnum = 0;
1038 float add, brightest = 0;
1039 vec3_t lightVec;
1040 float lightCutoffSquared = 0.0f;
1041 qboolean foundLight = false;
1042
1043 if (gl_dynamic->integer == 0)
1044 {
1045 return;
1046 }
1047
1048 dl = r_newrefdef.dlights;
1049 for (lnum=0; lnum<r_newrefdef.num_dlights; lnum++, dl++)
1050 {
1051 VectorSubtract (r_origin, dl->origin, lightVec);
1052 add = dl->intensity - VectorLength(lightVec)/10;
1053 if (add > brightest) //only bother with lights close by
1054 {
1055 brightest = add;
1056 sv_lnum = lnum; //remember the position of most influencial light
1057 }
1058 }
1059
1060 if(brightest > 0)
1061 {
1062 //we have a light
1063 foundLight= true;
1064 dynLight = r_newrefdef.dlights;
1065 dynLight += sv_lnum; //our most influential light
1066
1067 lightCutoffSquared = ( dynLight->intensity - DLIGHT_CUTOFF );
1068
1069 if( lightCutoffSquared <= 0.0f )
1070 lightCutoffSquared = 0.0f;
1071
1072 lightCutoffSquared *= 2.0f;
1073 lightCutoffSquared *= lightCutoffSquared;
1074
1075 // reset VBO batching state
1076 r_currTex = r_currLMTex = -99999;
1077 r_currTexInfo = NULL;
1078 r_currTangentSpaceTransform = NULL;
1079
1080 BSP_ClearVBOAccum ();
1081
1082 glUniform3fARB( g_location_lightPosition, dynLight->origin[0], dynLight->origin[1], dynLight->origin[2]);
1083 glUniform3fARB( g_location_lightColour, dynLight->color[0], dynLight->color[1], dynLight->color[2]);
1084
1085 glUniform1fARB( g_location_lightCutoffSquared, lightCutoffSquared);
1086
1087 if(gl_shadowmaps->integer)
1088 {
1089 //dynamic shadow
1090 glUniform1iARB( g_location_bspShadowmapTexture, 7);
1091 qglActiveTextureARB(GL_TEXTURE7);
1092 qglBindTexture(GL_TEXTURE_2D, r_depthtexture->texnum);
1093
1094 glUniform1iARB( g_location_shadowmap, 1);
1095
1096 glUniform1fARB( g_location_xOffs, 1.0/(viddef.width*r_shadowmapscale->value));
1097 glUniform1fARB( g_location_yOffs, 1.0/(viddef.height*r_shadowmapscale->value));
1098 }
1099 else
1100 glUniform1iARB( g_location_shadowmap, 0);
1101 }
1102
1103 glUniform1iARB( g_location_dynamic, foundLight);
1104
1105 r_vboOn = false;
1106
1107 qglEnableClientState( GL_VERTEX_ARRAY );
1108 qglClientActiveTextureARB (GL_TEXTURE0);
1109 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
1110 qglClientActiveTextureARB (GL_TEXTURE1);
1111 qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
1112 KillFlags |= (KILL_TMU0_POINTER | KILL_TMU1_POINTER);
1113
1114 for (i = 0; i < currentmodel->num_unique_texinfos; i++)
1115 {
1116 msurface_t *s;
1117 if (forEnt)
1118 {
1119 s = currentmodel->unique_texinfo[i]->e_glsl_dynamic_surfaces;
1120 currentmodel->unique_texinfo[i]->e_glsl_dynamic_surfaces = NULL;
1121 }
1122 else
1123 {
1124 s = currentmodel->unique_texinfo[i]->w_glsl_dynamic_surfaces;
1125 }
1126 if (!s)
1127 continue;
1128 BSP_GLSLTexinfoChanged (s->texinfo->equiv, true);
1129 for (; s; s = s->texturechain) {
1130 BSP_RenderGLSLLightmappedPoly(s);
1131 r_currLMTex = s->lightmaptexturenum;
1132 }
1133 }
1134
1135 BSP_FlushVBOAccum ();
1136
1137 qglDisable (GL_ALPHA_TEST);
1138
1139 qglActiveTextureARB (GL_TEXTURE1);
1140 qglDisable (GL_TEXTURE_2D);
1141 }
1142
1143
1144
1145
1146 /*
1147 =========================================
1148 This is the "API" for the BSP surface renderer backend, hiding most of the
1149 complexity of the previous functions.
1150 =========================================
1151 */
1152
1153
1154 /*
1155 ================
1156 BSP_ClearWorldTextureChains
1157
1158 Reset linked lists for the world (non-entity/non-brushmodel) surfaces. This
1159 need not be called every frame if r_optimize is on. No equivalent function is
1160 needed for entity surfaces because they are reset automatically when they are
1161 drawn.
1162 ================
1163 */
BSP_ClearWorldTextureChains(void)1164 void BSP_ClearWorldTextureChains (void)
1165 {
1166 int i;
1167
1168 for (i = 0; i < currentmodel->num_unique_texinfos; i++)
1169 {
1170 currentmodel->unique_texinfo[i]->w_lightmap_surfaces = NULL;
1171 currentmodel->unique_texinfo[i]->w_glsl_surfaces = NULL;
1172 currentmodel->unique_texinfo[i]->w_glsl_dynamic_surfaces = NULL;
1173 }
1174
1175 r_warp_surfaces = NULL;
1176 r_alpha_surfaces = NULL;
1177 r_rscript_surfaces = NULL;
1178 r_flicker_surfaces = NULL;
1179 }
1180
1181 /*
1182 ================
1183 BSP_AddToTextureChain
1184
1185 Call this on a surface (and indicate whether it's an entity surface) and it
1186 will figure out which texture chain to add it to; this function is responsible
1187 for deciding if the surface is "ordinary" or somehow "special," whether it
1188 should be normalmapped and/or dynamically lit, etc.
1189
1190 This function will be repeatedly called on all the surfaces in the current
1191 brushmodel entity or in the world's static geometry, followed by a single call
1192 to BSP_DrawTextureChains to render them all in one fell swoop.
1193 ================
1194 */
1195 void BSP_UpdateSurfaceLightmap (msurface_t *surf);
BSP_AddToTextureChain(msurface_t * surf,qboolean forEnt)1196 void BSP_AddToTextureChain(msurface_t *surf, qboolean forEnt)
1197 {
1198 int map;
1199 rscript_t *rs_shader;
1200 qboolean is_dynamic = false;
1201
1202 // Special surfaces that need to be handled separately
1203
1204 if (surf->texinfo->flags & SURF_SKY)
1205 { // just adds to visible sky bounds
1206 R_AddSkySurface (surf);
1207 return;
1208 }
1209
1210 if (SurfaceIsTranslucent(surf) && !SurfaceIsAlphaBlended(surf))
1211 { // add to the translucent chain
1212 if (forEnt)
1213 {
1214 surf->texturechain = r_ent_alpha_surfaces;
1215 r_ent_alpha_surfaces = surf;
1216 }
1217 else
1218 {
1219 surf->texturechain = r_alpha_surfaces;
1220 r_alpha_surfaces = surf;
1221 }
1222 return;
1223 }
1224
1225 if (surf->iflags & ISURF_DRAWTURB)
1226 { // add to the warped surfaces chain
1227 if (forEnt)
1228 {
1229 surf->texturechain = r_ent_warp_surfaces;
1230 r_ent_warp_surfaces = surf;
1231 }
1232 else
1233 {
1234 surf->texturechain = r_warp_surfaces;
1235 r_warp_surfaces = surf;
1236 }
1237 return;
1238 }
1239
1240
1241 // The rest of the function handles most ordinary surfaces: normalmapped,
1242 // non-normalmapped, and dynamically lit surfaces. As these three cases
1243 // are the most common, they are the most optimized-- grouped by texinfo,
1244 // etc.
1245
1246 // XXX: we could require gl_bspnormalmaps here, but that would result in
1247 // weird inconsistency with only meshes lighting up. Better to fall back
1248 // on GLSL for dynamically lit surfaces, even with gl_bspnormalmaps 0.
1249 if(r_newrefdef.num_dlights && gl_state.glsl_shaders && gl_glsl_shaders->integer && gl_dynamic->integer)
1250 {
1251 // dynamic this frame or dynamic previously
1252 if ( ( surf->dlightframe == r_framecount ) )
1253 {
1254 if ( !SurfaceHasNoLightmap(surf) )
1255 is_dynamic = true;
1256 }
1257 }
1258
1259 // reviving the ancient lightstyle system
1260 if ( !SurfaceHasNoLightmap(surf) )
1261 {
1262 for ( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
1263 {
1264 // Chain of surfaces that may need to have their lightmaps updated
1265 // in future frames (for dealing with r_optimize)
1266 if (surf->styles[map] != 0)
1267 {
1268 if (!forEnt)
1269 {
1270 surf->flickerchain = r_flicker_surfaces;
1271 r_flicker_surfaces = surf;
1272 break;
1273 }
1274 if ( r_newrefdef.lightstyles[surf->styles[map]].white != surf->cached_light[map])
1275 {
1276 BSP_UpdateSurfaceLightmap (surf);
1277 break;
1278 }
1279 }
1280 }
1281 }
1282
1283 if(is_dynamic && surf->texinfo->has_normalmap
1284 && gl_state.glsl_shaders && gl_glsl_shaders->integer) //always glsl for dynamic if it has a normalmap
1285 {
1286 if (forEnt)
1287 {
1288 surf->texturechain = surf->texinfo->equiv->e_glsl_dynamic_surfaces;
1289 surf->texinfo->equiv->e_glsl_dynamic_surfaces = surf;
1290 }
1291 else
1292 {
1293 surf->texturechain = surf->texinfo->equiv->w_glsl_dynamic_surfaces;
1294 surf->texinfo->equiv->w_glsl_dynamic_surfaces = surf;
1295 }
1296 }
1297 else if(gl_bspnormalmaps->integer
1298 && surf->texinfo->has_heightmap
1299 && surf->texinfo->has_normalmap
1300 && gl_state.glsl_shaders && gl_glsl_shaders->integer)
1301 {
1302 if (forEnt)
1303 {
1304 surf->texturechain = surf->texinfo->equiv->e_glsl_surfaces;
1305 surf->texinfo->equiv->e_glsl_surfaces = surf;
1306 }
1307 else
1308 {
1309 surf->texturechain = surf->texinfo->equiv->w_glsl_surfaces;
1310 surf->texinfo->equiv->w_glsl_surfaces = surf;
1311 }
1312 }
1313 else
1314 {
1315 if (forEnt)
1316 {
1317 surf->texturechain = surf->texinfo->equiv->e_lightmap_surfaces;
1318 surf->texinfo->equiv->e_lightmap_surfaces = surf;
1319 }
1320 else
1321 {
1322 surf->texturechain = surf->texinfo->equiv->w_lightmap_surfaces;
1323 surf->texinfo->equiv->w_lightmap_surfaces = surf;
1324 }
1325 }
1326
1327 // Add to the rscript chain if there is actually a shader
1328 // TODO: investigate the possibility of doing this for brush models as
1329 // well-- might cause problems with caustics and brush models only half
1330 // submerged?
1331 if(!forEnt && r_shaders->integer)
1332 {
1333 rs_shader = (rscript_t *)surf->texinfo->image->script;
1334 if(rs_shader || (surf->iflags & ISURF_UNDERWATER))
1335 {
1336 surf->rscriptchain = r_rscript_surfaces;
1337 r_rscript_surfaces = surf;
1338 }
1339 }
1340 }
1341
1342 /*
1343 ================
1344 BSP_DrawTextureChains
1345
1346 Draw ALL surfaces for either the current entity or the world model. If drawing
1347 entity surfaces, reset the linked lists afterward.
1348 ================
1349 */
BSP_DrawTextureChains(qboolean forEnt)1350 void BSP_DrawTextureChains (qboolean forEnt)
1351 {
1352 msurface_t *flickersurf;
1353 int map;
1354
1355 if (!forEnt)
1356 {
1357 R_KillVArrays (); // TODO: check if necessary
1358
1359 for (flickersurf = r_flicker_surfaces; flickersurf != NULL; flickersurf = flickersurf->flickerchain)
1360 {
1361 for ( map = 0; map < MAXLIGHTMAPS && flickersurf->styles[map] != 255; map++ )
1362 {
1363 if ( r_newrefdef.lightstyles[flickersurf->styles[map]].white != flickersurf->cached_light[map])
1364 {
1365 BSP_UpdateSurfaceLightmap (flickersurf);
1366 break;
1367 }
1368 }
1369 }
1370 }
1371
1372 // Setup GL state for lightmap render
1373 // (TODO: only necessary for fixed-function pipeline?)
1374
1375 GL_EnableMultitexture( true );
1376
1377 GL_SelectTexture( GL_TEXTURE0);
1378
1379 if ( !gl_config.mtexcombine )
1380 {
1381 GL_TexEnv( GL_REPLACE );
1382 GL_SelectTexture( GL_TEXTURE1);
1383
1384 if ( gl_lightmap->integer )
1385 GL_TexEnv( GL_REPLACE );
1386 else
1387 GL_TexEnv( GL_MODULATE );
1388 }
1389 else
1390 {
1391 GL_TexEnv ( GL_COMBINE_EXT );
1392 qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE );
1393 qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
1394 qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE );
1395 qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
1396 GL_SelectTexture( GL_TEXTURE1 );
1397 GL_TexEnv ( GL_COMBINE_EXT );
1398
1399 if ( gl_lightmap->integer )
1400 {
1401 qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE );
1402 qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
1403 qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE );
1404 qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
1405 }
1406 else
1407 {
1408 qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE );
1409 qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
1410 qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT );
1411 qglTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE );
1412 qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
1413 qglTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PREVIOUS_EXT );
1414 }
1415
1416 if ( r_overbrightbits->value )
1417 qglTexEnvi ( GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, r_overbrightbits->value );
1418 }
1419
1420 // render all fixed-function surfaces
1421 BSP_DrawNonGLSLSurfaces(forEnt);
1422
1423 // render all GLSL surfaces, including normalmapped and dynamically lit
1424 if(gl_state.glsl_shaders && gl_glsl_shaders->integer)
1425 {
1426 glUseProgramObjectARB( g_programObj );
1427 glUniform3fARB( g_location_eyePos, r_origin[0], r_origin[1], r_origin[2] );
1428 glUniform1iARB( g_location_fog, map_fog);
1429 glUniform3fARB( g_location_staticLightPosition, r_worldLightVec[0], r_worldLightVec[1], r_worldLightVec[2]);
1430 BSP_DrawGLSLSurfaces(forEnt);
1431 BSP_DrawGLSLDynamicSurfaces(forEnt);
1432 glUseProgramObjectARB( 0 );
1433 }
1434
1435 // this has to come last because it messes with GL state
1436 BSP_DrawWarpSurfaces (forEnt);
1437
1438 GL_EnableMultitexture( false );
1439 }
1440
1441
1442
1443 /*
1444 =============================================================
1445
1446 BRUSH MODELS
1447
1448 =============================================================
1449 */
1450
1451 /*
1452 =================
1453 BSP_DrawInlineBModel
1454
1455 Picks which of the current entity's surfaces face toward the camera, and calls
1456 BSP_AddToTextureChain on those.
1457 =================
1458 */
BSP_DrawInlineBModel(void)1459 void BSP_DrawInlineBModel ( void )
1460 {
1461 int i;
1462 cplane_t *pplane;
1463 float dot;
1464 msurface_t *psurf;
1465
1466 R_PushDlightsForBModel ( currententity );
1467
1468 if ( currententity->flags & RF_TRANSLUCENT )
1469 {
1470 qglEnable (GL_BLEND);
1471 qglColor4f (1,1,1,0.25);
1472 GL_TexEnv( GL_MODULATE );
1473 }
1474
1475 psurf = ¤tmodel->surfaces[currentmodel->firstmodelsurface];
1476 for (i=0 ; i<currentmodel->nummodelsurfaces ; i++, psurf++)
1477 {
1478 if (psurf->texinfo->flags & SURF_NODRAW)
1479 continue; //can skip dot product stuff
1480 // TODO: remove these at load-time for inline models?
1481
1482 // find which side of the plane we are on
1483 pplane = psurf->plane;
1484 dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
1485
1486 // draw the polygon
1487 if (((psurf->iflags & ISURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
1488 (!(psurf->iflags & ISURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
1489 {
1490 // TODO: do this once at load time
1491 psurf->entity = currententity;
1492
1493 BSP_AddToTextureChain( psurf, true );
1494
1495 psurf->visframe = r_framecount;
1496 }
1497 }
1498
1499 BSP_DrawTextureChains (true);
1500
1501 qglDisable (GL_BLEND);
1502 qglColor4f (1,1,1,1);
1503 GL_TexEnv( GL_REPLACE );
1504
1505 R_KillVArrays ();
1506 }
1507
1508 /*
1509 =================
1510 R_DrawBrushModel
1511 =================
1512 */
R_DrawBrushModel(void)1513 void R_DrawBrushModel ( void )
1514 {
1515 vec3_t mins, maxs;
1516 int i;
1517 qboolean rotated;
1518
1519 if (currentmodel->nummodelsurfaces == 0)
1520 return;
1521
1522 gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
1523
1524 if (currententity->angles[0] || currententity->angles[1] || currententity->angles[2])
1525 {
1526 rotated = true;
1527 for (i=0 ; i<3 ; i++)
1528 {
1529 mins[i] = currententity->origin[i] - currentmodel->radius;
1530 maxs[i] = currententity->origin[i] + currentmodel->radius;
1531 }
1532 }
1533 else
1534 {
1535 rotated = false;
1536 VectorAdd (currententity->origin, currentmodel->mins, mins);
1537 VectorAdd (currententity->origin, currentmodel->maxs, maxs);
1538 }
1539
1540 if (R_CullBox (mins, maxs)) {
1541 return;
1542 }
1543
1544 qglColor3f (1,1,1);
1545
1546 VectorSubtract (r_newrefdef.vieworg, currententity->origin, modelorg);
1547
1548 if (rotated)
1549 {
1550 vec3_t temp;
1551 vec3_t forward, right, up;
1552
1553 VectorCopy (modelorg, temp);
1554 AngleVectors (currententity->angles, forward, right, up);
1555 modelorg[0] = DotProduct (temp, forward);
1556 modelorg[1] = -DotProduct (temp, right);
1557 modelorg[2] = DotProduct (temp, up);
1558 }
1559
1560 qglPushMatrix ();
1561 currententity->angles[0] = -currententity->angles[0]; // stupid quake bug
1562 currententity->angles[2] = -currententity->angles[2]; // stupid quake bug
1563 R_RotateForEntity (currententity);
1564 currententity->angles[0] = -currententity->angles[0]; // stupid quake bug
1565 currententity->angles[2] = -currententity->angles[2]; // stupid quake bug
1566
1567 BSP_DrawInlineBModel ();
1568
1569 qglPopMatrix ();
1570 }
1571
1572
1573
1574 /*
1575 =============================================================
1576
1577 WORLD MODEL
1578
1579 =============================================================
1580 */
1581
1582 /*
1583 =================
1584 R_CullBox
1585
1586 Returns true if the box is completely outside the frustum
1587
1588 Variant: uses clipflags
1589 =================
1590 */
R_CullBox_ClipFlags(vec3_t mins,vec3_t maxs,int clipflags)1591 qboolean R_CullBox_ClipFlags (vec3_t mins, vec3_t maxs, int clipflags)
1592 {
1593 int i;
1594 cplane_t *p;
1595
1596 for (i=0,p=frustum ; i<4; i++,p++)
1597 {
1598 if (!(clipflags & (1<<i)))
1599 continue;
1600 switch (p->signbits)
1601 {
1602 case 0:
1603 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1604 return true;
1605 break;
1606 case 1:
1607 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
1608 return true;
1609 break;
1610 case 2:
1611 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1612 return true;
1613 break;
1614 case 3:
1615 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
1616 return true;
1617 break;
1618 case 4:
1619 if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1620 return true;
1621 break;
1622 case 5:
1623 if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
1624 return true;
1625 break;
1626 case 6:
1627 if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1628 return true;
1629 break;
1630 case 7:
1631 if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
1632 return true;
1633 break;
1634 default:
1635 return false;
1636 }
1637 }
1638
1639 return false;
1640 }
1641
1642 /*
1643 ================
1644 BSP_RecursiveWorldNode
1645
1646 Goes through the entire world (the BSP tree,) picks out which surfaces should
1647 be drawn, and calls BSP_AddToTextureChain on each.
1648
1649 node: the BSP node to work on
1650 clipflags: indicate which planes of the frustum may intersect the node
1651
1652 Since each node is inside its parent in 3D space, if a frustum plane can be
1653 shown not to intersect a node at all, then it won't intersect either of its
1654 children.
1655 ================
1656 */
BSP_RecursiveWorldNode(mnode_t * node,int clipflags)1657 void BSP_RecursiveWorldNode (mnode_t *node, int clipflags)
1658 {
1659 int c, side;
1660 cplane_t *plane;
1661 msurface_t *surf, **mark;
1662 mleaf_t *pleaf;
1663 float dot;
1664
1665 if (node->contents == CONTENTS_SOLID)
1666 return; // solid
1667
1668 if (node->visframe != r_visframecount)
1669 return;
1670
1671 // if a leaf node, draw stuff (pt 1)
1672 c = 0;
1673 if (node->contents != -1)
1674 {
1675 pleaf = (mleaf_t *)node;
1676
1677 if (! (c = pleaf->nummarksurfaces) )
1678 return;
1679
1680 // check for door connected areas
1681 if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
1682 return; // not visible
1683
1684 mark = pleaf->firstmarksurface;
1685 }
1686
1687 if (!r_nocull->integer && clipflags)
1688 {
1689 int i, clipped;
1690 cplane_t *clipplane;
1691
1692 for (i=0,clipplane=frustum ; i<4 ; i++,clipplane++)
1693 {
1694 if (!(clipflags & (1<<i)))
1695 continue;
1696 clipped = BoxOnPlaneSide (node->minmaxs, node->minmaxs+3, clipplane);
1697
1698 if (clipped == 1)
1699 clipflags &= ~(1<<i); // node is entirely on screen
1700 else if (clipped == 2)
1701 return; // fully clipped
1702 }
1703 }
1704
1705 //if a leaf node, draw stuff (pt 2)
1706 if (c != 0)
1707 {
1708 do
1709 {
1710 (*mark++)->visframe = r_framecount;
1711 } while (--c);
1712
1713 return;
1714 }
1715
1716 // node is just a decision point, so go down the apropriate sides
1717
1718 // find which side of the node we are on
1719 plane = node->plane;
1720
1721 switch (plane->type)
1722 {
1723 case PLANE_X:
1724 dot = modelorg[0];
1725 break;
1726 case PLANE_Y:
1727 dot = modelorg[1];
1728 break;
1729 case PLANE_Z:
1730 dot = modelorg[2];
1731 break;
1732 default:
1733 dot = DotProduct (modelorg, plane->normal);
1734 break;
1735 }
1736
1737 side = dot < plane->dist;
1738
1739 // recurse down the children, front side first
1740 BSP_RecursiveWorldNode (node->children[side], clipflags);
1741
1742 // draw stuff
1743 for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++)
1744 {
1745 if (surf->visframe != r_framecount)
1746 continue;
1747
1748 /* XXX: this doesn't seem to cull any surfaces AT ALL when positioned
1749 * here! The surf->visframe check seems to catch any back-facing
1750 * surfaces, but the back-facing surface check seems to allow some
1751 * surfaces which are later caught by the surf->visframe check. So the
1752 * visframe check renders the planeback check redundant and useless.
1753 * I'm pretty sure it's because the map compiler structures the BSP
1754 * tree in such a way as to avoid back-facing surfaces being drawn.
1755 * -M
1756 if ( (surf->flags & SURF_PLANEBACK) != side )
1757 continue; // wrong side
1758 */
1759
1760 if (clipflags != 0 && !( surf->iflags & ISURF_DRAWTURB ))
1761 {
1762 if (R_CullBox_ClipFlags (surf->mins, surf->maxs, clipflags))
1763 continue;
1764 }
1765
1766 // the polygon is visible, so add it to the appropriate linked list
1767 // list
1768 BSP_AddToTextureChain( surf, false );
1769 }
1770
1771 // recurse down the back side
1772 BSP_RecursiveWorldNode (node->children[!side], clipflags);
1773 }
1774
1775 /*
1776 =============
1777 R_CalcWorldLights - this is the fallback for non deluxmapped bsp's
1778 =============
1779 */
R_CalcWorldLights(void)1780 void R_CalcWorldLights( void )
1781 {
1782 int i, j;
1783 vec3_t lightAdd, temp;
1784 float dist, weight;
1785 int numlights = 0;
1786
1787 if(gl_glsl_shaders->integer && gl_state.glsl_shaders)
1788 {
1789 //get light position relative to player's position
1790 VectorClear(lightAdd);
1791 for (i = 0; i < r_lightgroups; i++)
1792 {
1793 VectorSubtract(r_origin, LightGroups[i].group_origin, temp);
1794 dist = VectorLength(temp);
1795 if(dist == 0)
1796 dist = 1;
1797 dist = dist*dist;
1798 weight = (int)250000/(dist/(LightGroups[i].avg_intensity+1.0f));
1799 for(j = 0; j < 3; j++)
1800 lightAdd[j] += LightGroups[i].group_origin[j]*weight;
1801 numlights+=weight;
1802 }
1803
1804 if(numlights > 0.0)
1805 {
1806 for(i = 0; i < 3; i++)
1807 r_worldLightVec[i] = (lightAdd[i]/numlights + r_origin[i])/2.0;
1808 }
1809 }
1810 }
1811
1812 /*
1813 =============
1814 R_DrawWorldSurfs
1815 =============
1816 */
R_DrawWorldSurfs(void)1817 void R_DrawWorldSurfs (void)
1818 {
1819 if (!r_drawworld->integer)
1820 return;
1821
1822 if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
1823 return;
1824
1825 if (r_newrefdef.areabits == NULL)
1826 {
1827 Com_Printf ("WARN: No area bits!\n");
1828 return;
1829 }
1830
1831 qglColor3f (1,1,1);
1832
1833 BSP_DrawTextureChains ( false );
1834
1835 R_InitSun();
1836
1837 qglDepthMask(0);
1838 R_DrawSkyBox();
1839 qglDepthMask(1);
1840
1841 R_DrawRSSurfaces();
1842 }
1843
1844 /*
1845 ===============
1846 R_MarkLeaves
1847
1848 Mark the leaves and nodes that are in the PVS for the current
1849 cluster
1850 ===============
1851 */
R_MarkLeaves(void)1852 void R_MarkLeaves (void)
1853 {
1854 static byte *vis;
1855 static byte fatvis[MAX_MAP_LEAFS/8];
1856 mnode_t *node;
1857 int i, c;
1858 mleaf_t *leaf;
1859 int cluster;
1860 static int minleaf_allareas, maxleaf_allareas;
1861 int minleaf, maxleaf;
1862
1863 if ( r_oldviewcluster == r_viewcluster &&
1864 r_oldviewcluster2 == r_viewcluster2 &&
1865 !r_novis->integer && r_viewcluster != -1 &&
1866 !r_newrefdef.areabits_changed)
1867 return;
1868 r_newrefdef.areabits_changed = false;
1869
1870 // development aid to let you run around and see exactly where
1871 // the pvs ends
1872 if (gl_lockpvs->integer)
1873 return;
1874
1875 r_oldviewcluster = r_viewcluster;
1876 r_oldviewcluster2 = r_viewcluster2;
1877
1878 if (r_novis->integer || r_viewcluster == -1 || !r_worldmodel->vis)
1879 {
1880 r_visframecount++;
1881 // mark everything
1882 for (i=0 ; i<r_worldmodel->numleafs ; i++)
1883 r_worldmodel->leafs[i].visframe = r_visframecount;
1884 for (i=0 ; i<r_worldmodel->numnodes ; i++)
1885 r_worldmodel->nodes[i].visframe = r_visframecount;
1886 return;
1887 }
1888
1889 vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel);
1890 minleaf_allareas = r_viewleaf->minPVSleaf;
1891 maxleaf_allareas = r_viewleaf->maxPVSleaf;
1892 // may have to combine two clusters because of solid water boundaries
1893 if (r_viewcluster2 != r_viewcluster)
1894 {
1895 if (r_viewleaf2->minPVSleaf < minleaf_allareas)
1896 minleaf_allareas = r_viewleaf2->minPVSleaf;
1897 if (r_viewleaf2->maxPVSleaf > maxleaf_allareas)
1898 maxleaf_allareas = r_viewleaf2->maxPVSleaf;
1899 memcpy (fatvis, vis, (r_worldmodel->numleafs+7)/8);
1900 vis = Mod_ClusterPVS (r_viewcluster2, r_worldmodel);
1901 c = (r_worldmodel->numleafs+31)/32;
1902 for (i=0 ; i<c ; i++)
1903 ((int *)fatvis)[i] |= ((int *)vis)[i];
1904 vis = fatvis;
1905 }
1906
1907 r_visframecount++;
1908
1909 minleaf = minleaf_allareas;
1910 maxleaf = maxleaf_allareas;
1911
1912 //restrict leaf range further to the range leafs in connected areas.
1913 {
1914 int areamax = 0;
1915 int areamin = r_worldmodel->numleafs;
1916 for (i = 0; i < r_worldmodel->num_areas; i++)
1917 {
1918 if (r_newrefdef.areabits[i>>3] & (1<<(i&7)))
1919 {
1920 if (r_worldmodel->area_max_leaf[i] > areamax)
1921 areamax = r_worldmodel->area_max_leaf[i];
1922 if (r_worldmodel->area_min_leaf[i] < areamin)
1923 areamin = r_worldmodel->area_min_leaf[i];
1924 }
1925 }
1926 if (areamin < areamax)
1927 {
1928 if (areamin > minleaf)
1929 minleaf = areamin;
1930 if (areamax < maxleaf)
1931 maxleaf = areamax;
1932 }
1933 }
1934
1935 for (i=minleaf,leaf=r_worldmodel->leafs+minleaf ; i<=maxleaf ; i++, leaf++)
1936 {
1937 cluster = leaf->cluster;
1938 if (cluster == -1)
1939 continue;
1940 if (vis[cluster>>3] & (1<<(cluster&7)))
1941 {
1942 node = (mnode_t *)leaf;
1943 do
1944 {
1945 if (node->visframe == r_visframecount)
1946 break;
1947 node->visframe = r_visframecount;
1948 node = node->parent;
1949 } while (node);
1950 }
1951 }
1952 }
1953
1954 /*
1955 ===============
1956 R_MarkWorldSurfs
1957
1958 Mark all surfaces that will need to be drawn this frame
1959 ===============
1960 */
R_MarkWorldSurfs(void)1961 void R_MarkWorldSurfs (void)
1962 {
1963 static entity_t ent;
1964 static int old_visframecount, old_dlightcount, last_bsp_time;
1965 static vec3_t old_origin, old_angle;
1966 vec3_t delta_origin, delta_angle;
1967 qboolean do_bsp;
1968 int cur_ms;
1969
1970 if (!r_drawworld->integer)
1971 return;
1972
1973 if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
1974 return;
1975
1976 if (r_newrefdef.areabits == NULL)
1977 {
1978 Com_Printf ("WARN: No area bits!\n");
1979 return;
1980 }
1981
1982 R_MarkLeaves ();
1983
1984 currentmodel = r_worldmodel;
1985
1986 VectorCopy (r_newrefdef.vieworg, modelorg);
1987
1988 // auto cycle the world frame for texture animation
1989 memset (&ent, 0, sizeof(ent));
1990 ent.frame = (int)(r_newrefdef.time*2);
1991 currententity = &ent;
1992
1993 gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
1994
1995 R_CalcWorldLights();
1996
1997 // r_optimize: only re-recurse the BSP tree if the player has moved enough
1998 // to matter.
1999 VectorSubtract (r_origin, old_origin, delta_origin);
2000 VectorSubtract (r_newrefdef.viewangles, old_angle, delta_angle);
2001 do_bsp = old_visframecount != r_visframecount ||
2002 VectorLength (delta_origin) > 5.0 ||
2003 VectorLength (delta_angle) > 2.0 ||
2004 r_newrefdef.num_dlights != 0 ||
2005 old_dlightcount != 0 ||
2006 !r_optimize->integer || draw_sun;
2007
2008 cur_ms = Sys_Milliseconds ();
2009
2010 // After a certain amount of time, increase the sensitivity to movement
2011 // and angle. If we go too long without re-recursing the BSP tree, it
2012 // means the player is either moving very slowly or not moving at all. If
2013 // the player is moving slowly enough, it can catch the r_optimize code
2014 // napping and cause artefacts, so we should be extra vigilant just in
2015 // case. Something you basically have to do on purpose, but we go the
2016 // extra mile.
2017 if (r_optimize->integer && !do_bsp)
2018 {
2019 // be sure to handle integer overflow of the millisecond counter
2020 if (cur_ms < last_bsp_time || last_bsp_time+100 < cur_ms)
2021 do_bsp = VectorLength (delta_origin) > 0.5 ||
2022 VectorLength (delta_angle) > 0.2;
2023
2024 }
2025
2026 if (do_bsp)
2027 {
2028 R_ClearSkyBox ();
2029 BSP_ClearWorldTextureChains ();
2030 BSP_RecursiveWorldNode (r_worldmodel->nodes, 15);
2031
2032 old_visframecount = r_visframecount;
2033 VectorCopy (r_origin, old_origin);
2034 VectorCopy (r_newrefdef.viewangles, old_angle);
2035 last_bsp_time = cur_ms;
2036 }
2037 old_dlightcount = r_newrefdef.num_dlights;
2038 }
2039
2040
2041
2042 /*
2043 =============================================================================
2044
2045 LIGHTMAP ALLOCATION
2046
2047 TODO: move this to another file, this is load-time stuff that doesn't run
2048 every frame.
2049
2050 =============================================================================
2051 */
2052
LM_InitBlock(void)2053 static void LM_InitBlock (void)
2054 {
2055 memset( gl_lms.allocated, 0, sizeof( gl_lms.allocated ) );
2056 }
2057
2058 // Upload the current lightmap data to OpenGL, then clear it and prepare for
2059 // the next lightmap texture to be filled with data.
2060 // TODO: With HD lightmaps, are mipmaps a good idea here?
2061 // TODO: Opportunistically make lightmap texture smaller if not all is used?
2062 // Will require delaying lightmap texcoords for all surfaces until after
2063 // upload.
LM_UploadBlock(void)2064 static void LM_UploadBlock (void)
2065 {
2066 int texture = gl_lms.current_lightmap_texture;
2067
2068 GL_SelectTexture (GL_TEXTURE0);
2069 // FIXME: OH FFS this is so stupid: tell the GL_Bind batching mechanism
2070 // that texture unit 0 has been re-bound, as it most certainly has been.
2071 gl_state.currenttextures[gl_state.currenttmu] = -1;
2072 GL_Bind( gl_state.lightmap_textures + texture );
2073 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2074 qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2075
2076 qglTexImage2D( GL_TEXTURE_2D,
2077 0,
2078 GL_RGBA,
2079 LIGHTMAP_SIZE, LIGHTMAP_SIZE,
2080 0,
2081 GL_LIGHTMAP_FORMAT,
2082 GL_UNSIGNED_INT_8_8_8_8_REV,
2083 gl_lms.lightmap_buffer );
2084
2085 #if 0
2086 height = 0;
2087 for (i = 0; i < LIGHTMAP_SIZE; i++)
2088 {
2089 if (gl_lms.allocated[i] > height)
2090 height = gl_lms.allocated[i];
2091 }
2092
2093 Com_Printf (" LIGHTMAP %d HEIGHT %d\n", gl_lms.current_lightmap_texture, height);
2094 #endif
2095
2096 if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS )
2097 Com_Error( ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" );
2098 }
2099
2100 // LM_AllocBlock - given a certain size rectangle, allocates space inside the
2101 // lightmap texture atlas.
2102 // Returns a texture number and the position inside it.
2103 // TODO: there are some clever tricks I can think of to pack these more
2104 // tightly: opportunistically rotating lightmap textures by 90 degrees,
2105 // wrapping the lightmap textures around the edges of the atlas, and even
2106 // recognizing that not all surfaces are rectangular.
LM_AllocBlock(int w,int h,int * x,int * y)2107 static qboolean LM_AllocBlock (int w, int h, int *x, int *y)
2108 {
2109 int i, j;
2110 int best, best2;
2111
2112 best = LIGHTMAP_SIZE;
2113
2114 for (i=0 ; i<LIGHTMAP_SIZE-w ; i++)
2115 {
2116 best2 = 0;
2117
2118 for (j=0 ; j<w ; j++)
2119 {
2120 if (gl_lms.allocated[i+j] >= best)
2121 break;
2122 if (gl_lms.allocated[i+j] > best2)
2123 best2 = gl_lms.allocated[i+j];
2124 }
2125 if (j == w)
2126 { // this is a valid spot
2127 *x = i;
2128 *y = best = best2;
2129 }
2130 }
2131
2132 if (best + h > LIGHTMAP_SIZE)
2133 return false;
2134
2135 for (i=0 ; i<w ; i++)
2136 gl_lms.allocated[*x + i] = best + h;
2137
2138 return true;
2139 }
2140
2141 /*
2142 ================
2143 BSP_BuildPolygonFromSurface
2144 ================
2145 */
BSP_BuildPolygonFromSurface(msurface_t * fa,float xscale,float yscale,int light_s,int light_t,int firstedge,int lnumverts)2146 void BSP_BuildPolygonFromSurface(msurface_t *fa, float xscale, float yscale, int light_s, int light_t, int firstedge, int lnumverts)
2147 {
2148 int i, lindex;
2149 medge_t *r_pedge;
2150 float *vec;
2151 float s, t;
2152 glpoly_t *poly;
2153
2154 vec3_t surfmaxs = {-99999999, -99999999, -99999999};
2155 vec3_t surfmins = {99999999, 99999999, 99999999};
2156
2157 //
2158 // draw texture
2159 //
2160 poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float));
2161 poly->next = fa->polys;
2162 poly->numverts = lnumverts;
2163 fa->polys = poly;
2164
2165 for (i=0 ; i<lnumverts ; i++)
2166 {
2167 lindex = currentmodel->surfedges[firstedge + i];
2168
2169 if (lindex > 0)
2170 {
2171 r_pedge = ¤tmodel->edges[lindex];
2172 vec = currentmodel->vertexes[r_pedge->v[0]].position;
2173 }
2174 else
2175 {
2176 r_pedge = ¤tmodel->edges[-lindex];
2177 vec = currentmodel->vertexes[r_pedge->v[1]].position;
2178 }
2179
2180 s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
2181 s /= fa->texinfo->image->width;
2182
2183 t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
2184 t /= fa->texinfo->image->height;
2185
2186 VectorCopy (vec, poly->verts[i]);
2187 poly->verts[i][3] = s;
2188 poly->verts[i][4] = t;
2189
2190 // set bbox for the surf used for culling
2191 if (vec[0] > surfmaxs[0]) surfmaxs[0] = vec[0];
2192 if (vec[1] > surfmaxs[1]) surfmaxs[1] = vec[1];
2193 if (vec[2] > surfmaxs[2]) surfmaxs[2] = vec[2];
2194
2195 if (vec[0] < surfmins[0]) surfmins[0] = vec[0];
2196 if (vec[1] < surfmins[1]) surfmins[1] = vec[1];
2197 if (vec[2] < surfmins[2]) surfmins[2] = vec[2];
2198
2199 //
2200 // lightmap texture coordinates
2201 //
2202 s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
2203 s -= fa->texturemins[0];
2204 s += light_s*xscale;
2205 s += xscale/2.0;
2206 s /= LIGHTMAP_SIZE*xscale;
2207
2208 t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
2209 t -= fa->texturemins[1];
2210 t += light_t*yscale;
2211 t += yscale/2.0;
2212 t /= LIGHTMAP_SIZE*yscale;
2213
2214 poly->verts[i][5] = s;
2215 poly->verts[i][6] = t;
2216
2217 //to do - check if needed
2218 s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
2219 s /= 128;
2220
2221 t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
2222 t /= 128;
2223
2224 poly->verts[i][7] = s;
2225 poly->verts[i][8] = t;
2226
2227 }
2228 #if 0 //SO PRETTY and useful for checking how much lightmap data is used up
2229 if (lnumverts == 4)
2230 {
2231 poly->verts[0][5] = 1;
2232 poly->verts[0][6] = 1;
2233 poly->verts[1][5] = 1;
2234 poly->verts[1][6] = 0;
2235 poly->verts[2][5] = 0;
2236 poly->verts[2][6] = 0;
2237 poly->verts[3][5] = 0;
2238 poly->verts[3][6] = 1;
2239 }
2240 #endif
2241
2242 // store out the completed bbox
2243 VectorCopy (surfmins, fa->mins);
2244 VectorCopy (surfmaxs, fa->maxs);
2245 }
2246
2247 /*
2248 ========================
2249 BSP_CreateSurfaceLightmap
2250 ========================
2251 */
BSP_CreateSurfaceLightmap(msurface_t * surf,int smax,int tmax,int * light_s,int * light_t)2252 void BSP_CreateSurfaceLightmap (msurface_t *surf, int smax, int tmax, int *light_s, int *light_t)
2253 {
2254 byte *base;
2255
2256 if (!surf->samples)
2257 return;
2258
2259 if (surf->texinfo->flags & (SURF_SKY|SURF_WARP))
2260 return; //may not need this?
2261
2262 if ( !LM_AllocBlock( smax, tmax, light_s, light_t ) )
2263 {
2264 LM_UploadBlock( );
2265 LM_InitBlock();
2266 if ( !LM_AllocBlock( smax, tmax, light_s, light_t ) )
2267 {
2268 Com_Error( ERR_FATAL, "Consecutive calls to LM_AllocBlock(%d,%d) failed\n", smax, tmax );
2269 }
2270 }
2271
2272 surf->lightmaptexturenum = gl_lms.current_lightmap_texture;
2273
2274 surf->lightmins[0] = *light_s;
2275 surf->lightmins[1] = *light_t;
2276 surf->lightmaxs[0] = smax;
2277 surf->lightmaxs[1] = tmax;
2278
2279 base = gl_lms.lightmap_buffer;
2280 base += ((*light_t) * LIGHTMAP_SIZE + *light_s) * LIGHTMAP_BYTES;
2281
2282 R_SetCacheState( surf );
2283 R_BuildLightMap (surf, base, smax, tmax, LIGHTMAP_SIZE*LIGHTMAP_BYTES);
2284 }
2285
BSP_UpdateSurfaceLightmap(msurface_t * surf)2286 void BSP_UpdateSurfaceLightmap (msurface_t *surf)
2287 {
2288 R_SetCacheState (surf);
2289 R_BuildLightMap (surf, gl_lms.lightmap_buffer, surf->lightmaxs[0], surf->lightmaxs[1], surf->lightmaxs[0]*LIGHTMAP_BYTES);
2290
2291 GL_SelectTexture (GL_TEXTURE0);
2292 // FIXME: OH FFS this is so stupid: tell the GL_Bind batching mechanism
2293 // that texture unit 0 has been re-bound, as it most certainly has been.
2294 gl_state.currenttextures[gl_state.currenttmu] = -1;
2295 GL_Bind( gl_state.lightmap_textures + surf->lightmaptexturenum );
2296 qglTexSubImage2D( GL_TEXTURE_2D,
2297 0,
2298 surf->lightmins[0], surf->lightmins[1],
2299 surf->lightmaxs[0], surf->lightmaxs[1],
2300 GL_LIGHTMAP_FORMAT,
2301 GL_UNSIGNED_INT_8_8_8_8_REV,
2302 gl_lms.lightmap_buffer );
2303 }
2304
2305 /*
2306 ==================
2307 BSP_BeginBuildingLightmaps
2308 ==================
2309 */
BSP_BeginBuildingLightmaps(model_t * m)2310 void BSP_BeginBuildingLightmaps (model_t *m)
2311 {
2312 static lightstyle_t lightstyles[MAX_LIGHTSTYLES];
2313 int i;
2314
2315 memset( gl_lms.allocated, 0, sizeof(gl_lms.allocated) );
2316
2317 r_framecount = 1; // no dlightcache
2318
2319 GL_EnableMultitexture( true );
2320 GL_SelectTexture( GL_TEXTURE1);
2321
2322 /*
2323 ** setup the base lightstyles so the lightmaps won't have to be regenerated
2324 ** the first time they're seen
2325 */
2326 for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
2327 {
2328 lightstyles[i].rgb[0] = 1;
2329 lightstyles[i].rgb[1] = 1;
2330 lightstyles[i].rgb[2] = 1;
2331 lightstyles[i].white = 3;
2332 }
2333 r_newrefdef.lightstyles = lightstyles;
2334
2335 if (!gl_state.lightmap_textures)
2336 gl_state.lightmap_textures = TEXNUM_LIGHTMAPS;
2337
2338 gl_lms.current_lightmap_texture = 1;
2339
2340 }
2341
2342 /*
2343 =======================
2344 BSP_EndBuildingLightmaps
2345 =======================
2346 */
BSP_EndBuildingLightmaps(void)2347 void BSP_EndBuildingLightmaps (void)
2348 {
2349 LM_UploadBlock( );
2350 GL_EnableMultitexture( false );
2351 }
2352
2353
2354
2355 /*
2356 =============================================================================
2357
2358 MINI MAP
2359
2360 Draws a little 2D map in the corner of the HUD.
2361 TODO: do a bit more calculation at load time, right now this is a huge FPS
2362 hit.
2363
2364 =============================================================================
2365 */
2366
R_RecursiveRadarNode(mnode_t * node)2367 void R_RecursiveRadarNode (mnode_t *node)
2368 {
2369 int c, side;
2370 cplane_t *plane;
2371 msurface_t *surf, **mark;
2372 mleaf_t *pleaf;
2373 float dot,distance;
2374 glpoly_t *p;
2375 float *v;
2376 int i;
2377
2378 if (node->contents == CONTENTS_SOLID) return; // solid
2379
2380 if(r_minimap_zoom->value>=0.1) {
2381 distance = 1024.0/r_minimap_zoom->value;
2382 } else {
2383 distance = 1024.0;
2384 }
2385
2386
2387 if ( r_origin[0]+distance < node->minmaxs[0] ||
2388 r_origin[0]-distance > node->minmaxs[3] ||
2389 r_origin[1]+distance < node->minmaxs[1] ||
2390 r_origin[1]-distance > node->minmaxs[4] ||
2391 r_origin[2]+256 < node->minmaxs[2] ||
2392 r_origin[2]-256 > node->minmaxs[5]) return;
2393
2394 // if a leaf node, draw stuff
2395 if (node->contents != -1) {
2396 pleaf = (mleaf_t *)node;
2397 // check for door connected areas
2398 if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
2399 return; // not visible
2400 mark = pleaf->firstmarksurface;
2401 c = pleaf->nummarksurfaces;
2402
2403 if (c) {
2404 do {
2405 (*mark)->visframe = r_framecount;
2406 mark++;
2407 } while (--c);
2408 }
2409 return;
2410 }
2411
2412 // node is just a decision point, so go down the apropriate sides
2413 // find which side of the node we are on
2414 plane = node->plane;
2415
2416 switch (plane->type) {
2417 case PLANE_X:
2418 dot = modelorg[0] - plane->dist;
2419 break;
2420 case PLANE_Y:
2421 dot = modelorg[1] - plane->dist;
2422 break;
2423 case PLANE_Z:
2424 dot = modelorg[2] - plane->dist;
2425 break;
2426 default:
2427 dot = DotProduct (modelorg, plane->normal) - plane->dist;
2428 break;
2429 }
2430
2431 if (dot >= 0) {
2432 side = 0;
2433 } else {
2434 side = 1;
2435 }
2436
2437 // recurse down the children, front side first
2438 R_RecursiveRadarNode (node->children[side]);
2439
2440 if(plane->normal[2]) {
2441 // draw stuff
2442 if(plane->normal[2]>0) for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++)
2443 {
2444 if (surf->texinfo->flags & SURF_SKY){
2445 continue;
2446 }
2447
2448
2449 }
2450 } else {
2451 qglDisable(GL_TEXTURE_2D);
2452 for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++) {
2453 float sColor,C[4];
2454 if (surf->texinfo->flags & SURF_SKY) continue;
2455
2456 if (surf->texinfo->flags & (SURF_WARP|SURF_FLOWING|SURF_TRANS33|SURF_TRANS66)) {
2457 sColor=0.5;
2458 } else {
2459 sColor=0;
2460 }
2461
2462 for ( p = surf->polys; p; p = p->chain ) {
2463 v = p->verts[0];
2464 qglBegin(GL_LINE_STRIP);
2465 for (i=0 ; i< p->numverts; i++, v+= VERTEXSIZE) {
2466 C[3]= (v[2]-r_origin[2])/512.0;
2467 if (C[3]>0) {
2468
2469 C[0]=0.5;
2470 C[1]=0.5+sColor;
2471 C[2]=0.5;
2472 C[3]=1-C[3];
2473
2474 }
2475 else
2476 {
2477 C[0]=0.5;
2478 C[1]=sColor;
2479 C[2]=0;
2480 C[3]+=1;
2481
2482 }
2483
2484 if(C[3]<0) {
2485 C[3]=0;
2486
2487 }
2488 qglColor4fv(C);
2489 qglVertex3fv (v);
2490 }
2491
2492 qglEnd();
2493 }
2494 }
2495 qglEnable(GL_TEXTURE_2D);
2496
2497 }
2498 // recurse down the back side
2499 R_RecursiveRadarNode (node->children[!side]);
2500
2501
2502 }
2503
2504 int numRadarEnts=0;
2505 RadarEnt_t RadarEnts[MAX_RADAR_ENTS];
2506
R_DrawRadar(void)2507 void R_DrawRadar(void)
2508 {
2509 int i;
2510 float fS[4]={0,0,-1.0/512.0,0};
2511
2512 if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) return;
2513 if(!r_minimap->integer) return;
2514
2515 if (!r_newrefdef.areabits) return;
2516
2517 qglViewport ( r_newrefdef.x+r_newrefdef.width-r_minimap_size->value,
2518 vid.height-r_newrefdef.y-r_newrefdef.height,
2519 r_minimap_size->value, r_minimap_size->value);
2520
2521 qglDisable(GL_DEPTH_TEST);
2522 qglMatrixMode(GL_PROJECTION);
2523 qglPushMatrix();
2524 qglLoadIdentity ();
2525
2526
2527 if (r_minimap_style->integer) {
2528 qglOrtho(-1024,1024,-1024,1024,-256,256);
2529 } else {
2530 qglOrtho(-1024,1024,-512,1536,-256,256);
2531 }
2532
2533 qglMatrixMode(GL_MODELVIEW);
2534 qglPushMatrix();
2535 qglLoadIdentity ();
2536
2537
2538 {
2539 qglStencilMask(255);
2540 qglClear(GL_STENCIL_BUFFER_BIT);
2541 qglEnable(GL_STENCIL_TEST);
2542 qglStencilFunc(GL_ALWAYS,4,4);
2543 qglStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
2544
2545
2546 GLSTATE_ENABLE_ALPHATEST;
2547 qglAlphaFunc(GL_LESS,0.1);
2548 qglColorMask(0,0,0,0);
2549
2550 qglColor4f(1,1,1,1);
2551 if(r_around)
2552 GL_Bind(r_around->texnum);
2553 qglBegin(GL_TRIANGLE_FAN);
2554 if (r_minimap_style->integer){
2555 qglTexCoord2f(0,1); qglVertex3f(1024,-1024,1);
2556 qglTexCoord2f(1,1); qglVertex3f(-1024,-1024,1);
2557 qglTexCoord2f(1,0); qglVertex3f(-1024,1024,1);
2558 qglTexCoord2f(0,0); qglVertex3f(1024,1024,1);
2559 } else {
2560 qglTexCoord2f(0,1); qglVertex3f(1024,-512,1);
2561 qglTexCoord2f(1,1); qglVertex3f(-1024,-512,1);
2562 qglTexCoord2f(1,0); qglVertex3f(-1024,1536,1);
2563 qglTexCoord2f(0,0); qglVertex3f(1024,1536,1);
2564 }
2565 qglEnd();
2566
2567 qglColorMask(1,1,1,1);
2568 GLSTATE_DISABLE_ALPHATEST;
2569 qglAlphaFunc(GL_GREATER, 0.5);
2570 qglStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
2571 qglStencilFunc(GL_NOTEQUAL,4,4);
2572
2573 }
2574
2575 if(r_minimap_zoom->value>=0.1) {
2576 qglScalef(r_minimap_zoom->value,r_minimap_zoom->value,r_minimap_zoom->value);
2577 }
2578
2579 if (r_minimap_style->integer) {
2580 qglPushMatrix();
2581 qglRotatef (90-r_newrefdef.viewangles[1], 0, 0, -1);
2582
2583 qglDisable(GL_TEXTURE_2D);
2584 qglBegin(GL_TRIANGLES);
2585 qglColor4f(1,1,1,0.5);
2586 qglVertex3f(0,32,0);
2587 qglColor4f(1,1,0,0.5);
2588 qglVertex3f(24,-32,0);
2589 qglVertex3f(-24,-32,0);
2590 qglEnd();
2591
2592 qglPopMatrix();
2593 } else {
2594 qglDisable(GL_TEXTURE_2D);
2595 qglBegin(GL_TRIANGLES);
2596 qglColor4f(1,1,1,0.5);
2597 qglVertex3f(0,32,0);
2598 qglColor4f(1,1,0,0.5);
2599 qglVertex3f(24,-32,0);
2600 qglVertex3f(-24,-32,0);
2601 qglEnd();
2602
2603 qglRotatef (90-r_newrefdef.viewangles[1], 0, 0, 1);
2604 }
2605 qglTranslatef (-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]);
2606
2607 qglBegin(GL_QUADS);
2608 for(i=0;i<numRadarEnts;i++){
2609 float x=RadarEnts[i].org[0];
2610 float y=RadarEnts[i].org[1];
2611 float z=RadarEnts[i].org[2];
2612 qglColor4fv(RadarEnts[i].color);
2613
2614 qglVertex3f(x+9, y+9, z);
2615 qglVertex3f(x+9, y-9, z);
2616 qglVertex3f(x-9, y-9, z);
2617 qglVertex3f(x-9, y+9, z);
2618 }
2619 qglEnd();
2620
2621 qglEnable(GL_TEXTURE_2D);
2622
2623 if(r_radarmap)
2624 GL_Bind(r_radarmap->texnum);
2625 qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
2626 GLSTATE_ENABLE_BLEND;
2627 qglColor3f(1,1,1);
2628
2629 fS[3]=0.5+ r_newrefdef.vieworg[2]/512.0;
2630 qglTexGenf(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
2631
2632 GLSTATE_ENABLE_TEXGEN;
2633 qglTexGenfv(GL_S,GL_OBJECT_PLANE,fS);
2634
2635 // draw the stuff
2636 R_RecursiveRadarNode (r_worldmodel->nodes);
2637
2638 qglBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
2639 GLSTATE_DISABLE_TEXGEN;
2640
2641 qglPopMatrix();
2642
2643 qglViewport(0,0,vid.width,vid.height);
2644
2645 qglMatrixMode(GL_PROJECTION);
2646 qglPopMatrix();
2647 qglMatrixMode(GL_MODELVIEW);
2648 qglDisable(GL_STENCIL_TEST);
2649 GL_TexEnv( GL_REPLACE );
2650 GLSTATE_DISABLE_BLEND;
2651 qglEnable(GL_DEPTH_TEST);
2652 qglColor4f(1,1,1,1);
2653
2654 }
2655