@@ -210,10 +210,9 @@ static void R_AddDynamicLights(msurface_t *surf)
210
210
}
211
211
212
212
//Combine and scale multiple lightmaps into the 8.8 format in blocklights
213
- static void R_BuildLightMap (msurface_t * surf , byte * dest , int stride )
213
+ static void R_BuildLightMap (msurface_t * surf , byte * dest , int stride , uint32_t flags )
214
214
{
215
215
int smax , tmax , i , j , size , blocksize , maps ;
216
- byte * lightmap ;
217
216
unsigned scale , * bl ;
218
217
qbool fullbright = false;
219
218
@@ -225,7 +224,6 @@ static void R_BuildLightMap(msurface_t *surf, byte *dest, int stride)
225
224
tmax = (surf -> extents [1 ] >> surf -> lmshift ) + 1 ;
226
225
size = smax * tmax ;
227
226
blocksize = size * 3 ;
228
- lightmap = surf -> samples ;
229
227
230
228
// check for full bright or no light data
231
229
fullbright = (R_FullBrightAllowed () || !cl .worldmodel || !cl .worldmodel -> lightdata );
@@ -241,16 +239,37 @@ static void R_BuildLightMap(msurface_t *surf, byte *dest, int stride)
241
239
}
242
240
243
241
// add all the lightmaps
244
- for (maps = 0 ; maps < MAXLIGHTMAPS && surf -> styles [maps ] != 255 ; maps ++ ) {
245
- scale = d_lightstylevalue [surf -> styles [maps ]];
246
- surf -> cached_light [maps ] = scale ; // 8.8 fraction
247
-
248
- if (!fullbright && lightmap ) {
242
+ if (flags & MOD_HDRLIGHTING ) {
243
+ uint32_t * lightmap = (uint32_t * )surf -> samples ;
244
+ for (maps = 0 ; maps < MAXLIGHTMAPS && surf -> styles [maps ] != 255 ; maps ++ ) {
245
+ scale = d_lightstylevalue [surf -> styles [maps ]];
246
+ surf -> cached_light [maps ] = scale ; // 8.8 fraction
247
+ // it sucks that blocklights is an int array. we can still massively
248
+ // overbright though, just not underbright quite as accurately
249
+ // (still quite a bit more than rgb8 precision there).
249
250
bl = blocklights ;
250
- for (i = 0 ; i < blocksize ; i ++ ) {
251
- * bl ++ += lightmap [i ] * scale ;
251
+ for (i = 0 ; i < size ; i ++ ) {
252
+ uint32_t e5bgr9 = * lightmap ++ ;
253
+ //we're converting to a scale that holds overbrights, so 1->128, its 2->255ish
254
+ float e = rgb9e5tab [e5bgr9 >>27 ] * (1 <<7 ) * scale ;
255
+ * bl ++ += e * ((e5bgr9 >> 0 )& 0x1ff ); //red
256
+ * bl ++ += e * ((e5bgr9 >> 9 )& 0x1ff ); //green
257
+ * bl ++ += e * ((e5bgr9 >>18 )& 0x1ff ); //blue
258
+ }
259
+ }
260
+ } else {
261
+ byte * lightmap = surf -> samples ;
262
+ for (maps = 0 ; maps < MAXLIGHTMAPS && surf -> styles [maps ] != 255 ; maps ++ ) {
263
+ scale = d_lightstylevalue [surf -> styles [maps ]];
264
+ surf -> cached_light [maps ] = scale ; // 8.8 fraction
265
+
266
+ if (!fullbright && lightmap ) {
267
+ bl = blocklights ;
268
+ for (i = 0 ; i < blocksize ; i ++ ) {
269
+ * bl ++ += lightmap [i ] * scale ;
270
+ }
271
+ lightmap += blocksize ; // skip to next lightmap
252
272
}
253
- lightmap += blocksize ; // skip to next lightmap
254
273
}
255
274
}
256
275
@@ -392,7 +411,7 @@ void R_RenderDynamicLightmaps(msurface_t *fa, qbool world)
392
411
theRect -> h = fa -> light_t - theRect -> t + tmax ;
393
412
}
394
413
base = lm -> rawdata + (fa -> light_t * LIGHTMAP_WIDTH + fa -> light_s ) * 4 ;
395
- R_BuildLightMap (fa , base , LIGHTMAP_WIDTH * 4 );
414
+ R_BuildLightMap (fa , base , LIGHTMAP_WIDTH * 4 , world ? cl . worldmodel -> flags : 0 );
396
415
}
397
416
398
417
void R_LightmapFrameInit (void )
@@ -749,7 +768,6 @@ static void R_BuildSurfaceDisplayList(model_t* currentmodel, msurface_t *fa)
749
768
static void R_BuildLightmapData (msurface_t * surf , int surfnum )
750
769
{
751
770
lightmap_data_t * lm = & lightmaps [surf -> lightmaptexturenum ];
752
- byte * lightmap = surf -> samples ;
753
771
unsigned int smax = (surf -> extents [0 ] >> surf -> lmshift ) + 1 ;
754
772
unsigned int tmax = (surf -> extents [1 ] >> surf -> lmshift ) + 1 ;
755
773
unsigned int lightmap_flags ;
@@ -775,20 +793,35 @@ static void R_BuildLightmapData(msurface_t* surf, int surfnum)
775
793
source [0 ] = source [1 ] = source [2 ] = 0 ;
776
794
source [3 ] = lightmap_flags ;
777
795
778
- if (lightmap ) {
779
- for (maps = 0 ; maps < MAXLIGHTMAPS && surf -> styles [maps ] != 255 ; maps ++ ) {
780
- size_t lightmap_index = (maps * smax * tmax + t * smax + s ) * 3 ;
781
-
782
- source [0 ] |= ((unsigned int )lightmap [lightmap_index + 0 ]) << (8 * maps );
783
- source [1 ] |= ((unsigned int )lightmap [lightmap_index + 1 ]) << (8 * maps );
784
- source [2 ] |= ((unsigned int )lightmap [lightmap_index + 2 ]) << (8 * maps );
796
+ if (surf -> samples ) {
797
+ if (surfnum != -1 && cl .worldmodel -> flags & MOD_HDRLIGHTING ) {
798
+ uint32_t * lightmap = (uint32_t * )surf -> samples ;
799
+ for (maps = 0 ; maps < MAXLIGHTMAPS && surf -> styles [maps ] != 255 ; maps ++ ) {
800
+ size_t lightmap_index = (maps * smax * tmax + t * smax + s );
801
+ uint32_t e5bgr9 = lightmap [lightmap_index ];
802
+ //we're converting to a scale that holds overbrights, so 1->128, its 2->255ish
803
+ float e = rgb9e5tab [e5bgr9 >>27 ] * (1 <<7 );
804
+ // should not clamp here, but changing the light compute shader can be done later
805
+ source [0 ] += (unsigned int )bound (0 , e * ((e5bgr9 >> 0 )& 0x1ff ), 0xff ) << (8 * maps );
806
+ source [1 ] += (unsigned int )bound (0 , e * ((e5bgr9 >> 9 )& 0x1ff ), 0xff ) << (8 * maps );
807
+ source [2 ] += (unsigned int )bound (0 , e * ((e5bgr9 >>18 )& 0x1ff ), 0xff ) << (8 * maps );
808
+ }
809
+ } else {
810
+ byte * lightmap = surf -> samples ;
811
+ for (maps = 0 ; maps < MAXLIGHTMAPS && surf -> styles [maps ] != 255 ; maps ++ ) {
812
+ size_t lightmap_index = (maps * smax * tmax + t * smax + s ) * 3 ;
813
+
814
+ source [0 ] |= ((unsigned int )lightmap [lightmap_index + 0 ]) << (8 * maps );
815
+ source [1 ] |= ((unsigned int )lightmap [lightmap_index + 1 ]) << (8 * maps );
816
+ source [2 ] |= ((unsigned int )lightmap [lightmap_index + 2 ]) << (8 * maps );
817
+ }
785
818
}
786
819
}
787
820
}
788
821
}
789
822
}
790
823
791
- static void R_LightmapCreateForSurface (msurface_t * surf , int surfnum )
824
+ static void R_LightmapCreateForSurface (msurface_t * surf , int surfnum , uint32_t flags )
792
825
{
793
826
int smax , tmax ;
794
827
byte * base ;
@@ -811,7 +844,7 @@ static void R_LightmapCreateForSurface(msurface_t *surf, int surfnum)
811
844
base = lightmaps [surf -> lightmaptexturenum ].rawdata + (surf -> light_t * LIGHTMAP_WIDTH + surf -> light_s ) * 4 ;
812
845
numdlights = 0 ;
813
846
R_BuildLightmapData (surf , surfnum );
814
- R_BuildLightMap (surf , base , LIGHTMAP_WIDTH * 4 );
847
+ R_BuildLightMap (surf , base , LIGHTMAP_WIDTH * 4 , flags );
815
848
}
816
849
817
850
static int R_LightmapSurfaceSortFunction (const void * lhs_ , const void * rhs_ )
@@ -917,7 +950,7 @@ void R_BuildLightmaps(void)
917
950
qbool isTurb = (surfaces [i ]-> flags & SURF_DRAWTURB );
918
951
919
952
if (!isTurb ) {
920
- R_LightmapCreateForSurface (surfaces [i ], m -> isworldmodel ? surfaces [i ]-> surfacenum : -1 );
953
+ R_LightmapCreateForSurface (surfaces [i ], m -> isworldmodel ? surfaces [i ]-> surfacenum : -1 , m -> flags );
921
954
}
922
955
R_BuildSurfaceDisplayList (m , surfaces [i ]);
923
956
}
@@ -939,7 +972,7 @@ void R_BuildLightmaps(void)
939
972
}
940
973
941
974
if (!isTurb || !(m -> surfaces [i ].texinfo -> flags & TEX_SPECIAL )) {
942
- R_LightmapCreateForSurface (m -> surfaces + i , m -> isworldmodel ? m -> surfaces [i ].surfacenum : -1 );
975
+ R_LightmapCreateForSurface (m -> surfaces + i , m -> isworldmodel ? m -> surfaces [i ].surfacenum : -1 , m -> flags );
943
976
}
944
977
R_BuildSurfaceDisplayList (m , m -> surfaces + i );
945
978
}
0 commit comments