/** * @sa R_ModLoadSurfaces */ void R_CreateSurfaceLightmap (mBspSurface_t * surf) { int smax, tmax; byte *samples, *directions; if (!(surf->flags & MSURF_LIGHTMAP)) return; smax = (surf->stextents[0] / surf->lightmap_scale) + 1; tmax = (surf->stextents[1] / surf->lightmap_scale) + 1; if (!R_AllocLightmapBlock(smax, tmax, &surf->light_s, &surf->light_t)) { /* upload the last block */ R_UploadLightmapBlock(); if (!R_AllocLightmapBlock(smax, tmax, &surf->light_s, &surf->light_t)) Com_Error(ERR_DROP, "R_CreateSurfaceLightmap: Consecutive calls to R_AllocLightmapBlock(%d,%d) failed (lightmap_scale: %i, stextends: %f %f)\n", smax, tmax, surf->lightmap_scale, surf->stextents[0], surf->stextents[1]); } surf->lightmap_texnum = r_lightmaps.lightmap_texnums[r_lightmaps.lightmap_count]; surf->deluxemap_texnum = r_lightmaps.deluxemap_texnums[r_lightmaps.deluxemap_count]; samples = r_lightmaps.sample_buffer; samples += (surf->light_t * r_lightmaps.size + surf->light_s) * LIGHTMAP_BLOCK_BYTES; directions = r_lightmaps.direction_buffer; directions += (surf->light_t * r_lightmaps.size + surf->light_s) * DELUXEMAP_BLOCK_BYTES; if (!surf->samples) /* make it fullbright */ R_BuildDefaultLightmap(surf, samples, directions, r_lightmaps.size * LIGHTMAP_BLOCK_BYTES); else /* or light it properly */ R_BuildLightmap(surf, samples, directions, r_lightmaps.size * LIGHTMAP_BLOCK_BYTES); }
/** * @brief Uploads sorted lightmaps from start to (end - 1) and * puts them in the new maps sized to width/height */ static void R_UploadPackedLightmaps(uint32_t width, uint32_t height, r_bsp_model_t *bsp, GSList *start, GSList *end) { // edge case, no blocks left if (!width || !height || !start) { return; } // allocate the image r_image_t *lightmap = R_AllocLightmap(width, height); r_image_t *deluxemap = R_AllocDeluxemap(width, height); r_image_t *stainmap = NULL; if (r_stainmap->integer) { stainmap = R_AllocStainmap(width, height); } // temp buffers byte *sample_buffer = Mem_Malloc(width * height * 3); byte *direction_buffer = Mem_Malloc(width * height * 3); do { r_bsp_surface_t *surf = (r_bsp_surface_t *) start->data; const size_t stride = width * 3; const size_t lightmap_offset = (surf->lightmap_t *width + surf->lightmap_s) * 3; byte *sout = sample_buffer + lightmap_offset; byte *dout = direction_buffer + lightmap_offset; if (surf->lightmap_input) { byte *stout = NULL; if (r_stainmap->integer) { surf->stainmap = stainmap; stout = surf->stainmap_buffer = Mem_LinkMalloc(surf->lightmap_size[0] * surf->lightmap_size[1] * 3, bsp); } R_BuildLightmap(bsp, surf, surf->lightmap_input, sout, dout, stout, stride); } else { R_BuildDefaultLightmap(bsp, surf, sout, dout, stride); } surf->lightmap = lightmap; surf->deluxemap = deluxemap; start = start->next; } while (start != end); // upload! R_UploadImage(lightmap, GL_RGB, sample_buffer); R_UploadImage(deluxemap, GL_RGB, direction_buffer); // copy to the stainmap if (r_stainmap->integer) { R_UploadImage(stainmap, GL_RGB, sample_buffer); } Mem_Free(sample_buffer); Mem_Free(direction_buffer); }