]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake3/q3map2/light_shadows.c
uncrustify! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / tools / quake3 / q3map2 / light_shadows.c
1 /*
2    Copyright (C) 1999-2007 id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #define LIGHT_SHADOWS_C
23
24 #include "light.h"
25 #include "inout.h"
26
27
28
29 /* -------------------------------------------------------------------------------
30
31    ydnar: this code deals with shadow volume bsps
32
33    ------------------------------------------------------------------------------- */
34
35 typedef struct shadowNode_s
36 {
37         vec4_t plane;
38         int children[ 2 ];
39 }
40 shadowNode_t;
41
42 int numShadowNodes;
43 shadowNode_t    *shadowNodes;
44
45
46
47 /*
48    AddShadow()
49    adds a shadow, returning the index into the shadow list
50  */
51
52
53
54 /*
55    MakeShadowFromPoints()
56    creates a shadow volume from 4 points (the first being the light origin)
57  */
58
59
60
61 /*
62    SetupShadows()
63    sets up the shadow volumes for all lights in the world
64  */
65
66 void SetupShadows( void ){
67         int i, j, s;
68         light_t         *light;
69         dleaf_t         *leaf;
70         dsurface_t      *ds;
71         surfaceInfo_t   *info;
72         shaderInfo_t    *si;
73         byte            *tested;
74
75
76         /* early out for weird cases where there are no lights */
77         if ( lights == NULL ) {
78                 return;
79         }
80
81         /* note it */
82         Sys_FPrintf( SYS_VRB, "--- SetupShadows ---\n" );
83
84         /* allocate a surface test list */
85         tested = safe_malloc( numDrawSurfaces / 8 + 1 );
86
87         /* walk the list of lights */
88         for ( light = lights; light != NULL; light = light->next )
89         {
90                 /* do some early out testing */
91                 if ( light->cluster < 0 ) {
92                         continue;
93                 }
94
95                 /* clear surfacetest list */
96                 memset( tested, 0, numDrawSurfaces / 8 + 1 );
97
98                 /* walk the bsp leaves */
99                 for ( i = 0, leaf = dleafs; i < numleafs; i++, leaf++ )
100                 {
101                         /* in pvs? */
102                         if ( ClusterVisible( light->cluster, leaf->cluster ) == qfalse ) {
103                                 continue;
104                         }
105
106                         /* walk the surface list for this leaf */
107                         for ( j = 0; j < leaf->numLeafSurfaces; j++ )
108                         {
109                                 /* don't filter a surface more than once */
110                                 s = dleafsurfaces[ leaf->firstLeafSurface + j ];
111                                 if ( tested[ s >> 3 ] & ( 1 << ( s & 7 ) ) ) {
112                                         continue;
113                                 }
114                                 tested[ s >> 3 ] |= ( 1 << ( s & 7 ) );
115
116                                 /* get surface and info */
117                                 ds = &drawSurfaces[ s ];
118                                 info = &surfaceInfos[ s ];
119                                 si = info->si;
120
121                                 /* don't create shadow volumes from translucent surfaces */
122                                 if ( si->contents & CONTENTS_TRANSLUCENT ) {
123                                         continue;
124                                 }
125                         }
126                 }
127         }
128 }