/// <summary> /// R_BuildLightMap /// Combine and scale multiple lightmaps into the 8.8 format in blocklights /// </summary> static void BuildLightMap(msurface_t surf, ByteArraySegment dest, int stride) { surf.cached_dlight = (surf.dlightframe == _FrameCount); int smax = (surf.extents[0] >> 4) + 1; int tmax = (surf.extents[1] >> 4) + 1; int size = smax * tmax; int srcOffset = surf.sampleofs; byte[] lightmap = surf.sample_base;// surf.samples; // set to full bright if no light data if (_FullBright.Value != 0 || Client.cl.worldmodel.lightdata == null) { for (int i = 0; i < size; i++) { _BlockLights[i] = 255 * 256; } } else { // clear to no light for (int i = 0; i < size; i++) { _BlockLights[i] = 0; } // add all the lightmaps if (lightmap != null) { for (int maps = 0; maps < BspFile.MAXLIGHTMAPS && surf.styles[maps] != 255; maps++) { int scale = _LightStyleValue[surf.styles[maps]]; surf.cached_light[maps] = scale; // 8.8 fraction for (int i = 0; i < size; i++) { _BlockLights[i] += (uint)(lightmap[srcOffset + i] * scale); } srcOffset += size; // lightmap += size; // skip to next lightmap } } // add all the dynamic lights if (surf.dlightframe == _FrameCount) { AddDynamicLights(surf); } } // bound, invert, and shift //store: int blOffset = 0; int destOffset = dest.StartIndex; byte[] data = dest.Data; switch (Drawer.LightMapFormat) { case PixelFormat.Rgba: stride -= (smax << 2); for (int i = 0; i < tmax; i++, destOffset += stride) // dest += stride { for (int j = 0; j < smax; j++) { uint t = _BlockLights[blOffset++]; // *bl++; t >>= 7; if (t > 255) { t = 255; } data[destOffset + 3] = (byte)(255 - t); //dest[3] = 255 - t; destOffset += 4; } } break; case PixelFormat.Alpha: case PixelFormat.Luminance: //case GL_INTENSITY: for (int i = 0; i < tmax; i++, destOffset += stride) { for (int j = 0; j < smax; j++) { uint t = _BlockLights[blOffset++]; // *bl++; t >>= 7; if (t > 255) { t = 255; } data[destOffset + j] = (byte)(255 - t); // dest[j] = 255 - t; } } break; default: Sys.Error("Bad lightmap format"); break; } }