/** * @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); }
/* * @brief Initializes the null (default) image, used when the desired texture * is not available. */ static void R_InitNullImage(void) { r_image_state.null = (r_image_t *) R_AllocMedia("r_image_state.null", sizeof(r_image_t)); r_image_state.null->media.Retain = R_RetainImage; r_image_state.null->media.Free = R_FreeImage; r_image_state.null->width = r_image_state.null->height = 16; r_image_state.null->type = IT_NULL; byte data[16 * 16 * 3]; memset(&data, 0xff, sizeof(data)); R_UploadImage(r_image_state.null, GL_RGB, data); }
/** * @brief Allocate handles for the stainmap */ static void R_AllocStainmap_(const uint32_t width, const uint32_t height, r_stainmap_t *out) { out->image = R_AllocLightmap_(IT_STAINMAP, width, height); R_UploadImage(out->image, GL_RGBA, NULL); out->fb = R_CreateFramebuffer(va("%s_fb", out->image->media.name)); R_AttachFramebufferImage(out->fb, out->image); if (!R_FramebufferReady(out->fb)) { Com_Warn("Unable to allocate a stainmap framebuffer"); memset(out, 0, sizeof(r_stainmap_t)); } Matrix4x4_FromOrtho(&out->projection, 0.0, width, height, 0.0, -1.0, 1.0); R_BindFramebuffer(FRAMEBUFFER_DEFAULT); }
/* * @brief Loads the image by the specified name. */ r_image_t *R_LoadImage(const char *name, r_image_type_t type) { r_image_t *image; char key[MAX_QPATH]; if (!name || !name[0]) { Com_Error(ERR_DROP, "NULL name\n"); } StripExtension(name, key); if (!(image = (r_image_t *) R_FindMedia(key))) { SDL_Surface *surf; if (Img_LoadImage(key, &surf)) { // attempt to load the image image = (r_image_t *) R_AllocMedia(key, sizeof(r_image_t)); image->media.Retain = R_RetainImage; image->media.Free = R_FreeImage; image->width = surf->w; image->height = surf->h; image->type = type; if (image->type == IT_NORMALMAP) { R_LoadHeightmap(name, surf); } if (image->type & IT_MASK_FILTER) { R_FilterImage(image, GL_RGBA, surf->pixels); } R_UploadImage(image, GL_RGBA, surf->pixels); SDL_FreeSurface(surf); } else { Com_Debug("Couldn't load %s\n", key); image = r_image_state.null; } } return image; }
/* * @brief Initializes the warp texture, used by r_program_warp.c. */ static void R_InitWarpImage(void) { r_image_state.warp = (r_image_t *) R_AllocMedia("r_image_state.warp", sizeof(r_image_t)); r_image_state.warp->media.Retain = R_RetainImage; r_image_state.warp->media.Free = R_FreeImage; r_image_state.warp->width = r_image_state.warp->height = WARP_SIZE; r_image_state.warp->type = IT_PROGRAM; byte data[WARP_SIZE][WARP_SIZE][4]; r_pixel_t i, j; for (i = 0; i < WARP_SIZE; i++) { for (j = 0; j < WARP_SIZE; j++) { data[i][j][0] = Random() % 255; data[i][j][1] = Random() % 255; data[i][j][2] = Random() % 48; data[i][j][3] = Random() % 48; } } R_UploadImage(r_image_state.warp, GL_RGBA, (byte *) data); }