/** * @brief Allocates a new lightmap (or deluxemap) image handle. */ static r_image_t *R_AllocLightmap_(r_image_type_t type, const r_pixel_t width, const r_pixel_t height) { static uint32_t count; char name[MAX_QPATH]; const char *base; switch (type) { case IT_LIGHTMAP: default: base = "lightmap"; break; case IT_DELUXEMAP: base = "deluxemap"; break; case IT_STAINMAP: base = "stainmap"; break; } g_snprintf(name, sizeof(name), "%s %u", base, count++); r_image_t *image = (r_image_t *) R_AllocMedia(name, sizeof(r_image_t), MEDIA_IMAGE); image->media.Free = R_FreeLightmap; image->type = type; image->width = width; image->height = height; return image; }
/** * @brief Creates a blank state for an atlas and returns it. */ r_atlas_t *R_CreateAtlas(const char *name) { r_atlas_t *atlas = (r_atlas_t *) R_AllocMedia(name, sizeof(r_atlas_t), MEDIA_ATLAS); atlas->image.media.Free = R_FreeAtlas; atlas->image.type = IT_ATLAS_MAP; g_strlcpy(atlas->image.media.name, name, sizeof(atlas->image.media.name)); if (r_atlas->value) { atlas->images = g_array_new(false, true, sizeof(r_atlas_image_t)); atlas->hash = g_hash_table_new(g_direct_hash, g_direct_equal); } return atlas; }
/* * @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 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); }
/* * @brief Loads the model by the specified name. */ r_model_t *R_LoadModel(const char *name) { r_model_t *mod; char key[MAX_QPATH]; size_t i; if (!name || !name[0]) { Com_Error(ERR_DROP, "R_LoadModel: NULL name\n"); } if (*name == '*') { g_snprintf(key, sizeof(key), "%s#%s", r_model_state.world->media.name, name + 1); } else { StripExtension(name, key); } if (!(mod = (r_model_t *) R_FindMedia(key))) { void *buf; const r_model_format_t *format = r_model_formats; for (i = 0; i < lengthof(r_model_formats); i++, format++) { StripExtension(name, key); strcat(key, format->extension); if (Fs_Load(key, &buf) != -1) break; } if (i == lengthof(r_model_formats)) { // not found if (strstr(name, "players/")) { Com_Debug("Failed to load player %s\n", name); } else { Com_Warn("Failed to load %s\n", name); } return NULL; } StripExtension(name, key); mod = (r_model_t *) R_AllocMedia(key, sizeof(r_model_t)); mod->media.Register = R_RegisterModel; mod->media.Free = R_FreeModel; mod->type = format->type; // load the materials first, so that we can resolve surfaces lists R_LoadMaterials(mod); // load it format->Load(mod, buf); // free the file Fs_Free(buf); // assemble vertex buffer objects from static arrays R_LoadVertexBuffers(mod); // calculate an approximate radius from the bounding box vec3_t tmp; VectorSubtract(mod->maxs, mod->mins, tmp); mod->radius = VectorLength(tmp) / 2.0; R_RegisterMedia((r_media_t *) mod); } return mod; }