/* * R_LoadBspSurfaces */ static void R_LoadBspSurfaces(const d_bsp_lump_t *l) { const d_bsp_face_t *in; r_bsp_surface_t *out; int i, count, surf_num; int plane_num, side; int ti; in = (const void *) (mod_base + l->file_ofs); if (l->file_len % sizeof(*in)) { Com_Error(ERR_DROP, "R_LoadBspSurfaces: Funny lump size in %s.", r_load_model->name); } count = l->file_len / sizeof(*in); out = R_HunkAlloc(count * sizeof(*out)); r_load_model->surfaces = out; r_load_model->num_surfaces = count; R_BeginBuildingLightmaps(); for (surf_num = 0; surf_num < count; surf_num++, in++, out++) { out->first_edge = LittleLong(in->first_edge); out->num_edges = LittleShort(in->num_edges); // resolve plane plane_num = LittleShort(in->plane_num); out->plane = r_load_model->planes + plane_num; // and sidedness side = LittleShort(in->side); if (side) { out->flags |= R_SURF_SIDE_BACK; VectorNegate(out->plane->normal, out->normal); } else VectorCopy(out->plane->normal, out->normal); // then texinfo ti = LittleShort(in->texinfo); if (ti < 0 || ti >= r_load_model->num_texinfo) { Com_Error(ERR_DROP, "R_LoadBspSurfaces: Bad texinfo number: %d.", ti); } out->texinfo = r_load_model->texinfo + ti; if (!(out->texinfo->flags & (SURF_WARP | SURF_SKY))) out->flags |= R_SURF_LIGHTMAP; // and size, texcoords, etc R_SetupBspSurface(out); // lastly lighting info i = LittleLong(in->light_ofs); if (i != -1) out->samples = r_load_model->lightmap_data + i; else out->samples = NULL; // create lightmaps R_CreateSurfaceLightmap(out); // and flare R_CreateSurfaceFlare(out); } R_EndBuildingLightmaps(); }
/** * @brief Specifies the model that will be used as the world * @param[in] tiles The tiles string can be only one map or a list of space * seperated map tiles for random assembly. In case of random assembly we also * need the @c pos string. Every tile needs an entry in the @c pos string, too. * @param[in] day Load the day lightmap * @param[in] pos In case of a random map assembly this is the string that holds * the world grid positions of the tiles. The positions are x, y and z values. * They are just written one after another for every tile in the @c tiles string * and every of the three components must exists for every tile. * @param[in] mapName The mapname that the get from the server (used to identify * the correct name for the materials in case of a random assembly). * @sa R_ModAddMapTile * @sa CM_LoadMap * @note This function is called for listen servers, too. This loads the bsp * struct for rendering it. The @c CM_LoadMap code only loads the collision * and pathfinding stuff. * @sa UI_BuildRadarImageList */ void R_ModBeginLoading (const char *tiles, qboolean day, const char *pos, const char *mapName) { char name[MAX_VAR]; char base[MAX_QPATH]; ipos3_t sh; int i; assert(mapName); R_FreeWorldImages(); /* clear any lights leftover in the active list from previous maps */ R_ClearActiveLights(); /* init */ R_BeginBuildingLightmaps(); r_numModelsInline = 0; r_numMapTiles = 0; /* load tiles */ while (tiles) { /* get tile name */ const char *token = Com_Parse(&tiles); if (!tiles) { /* finish */ R_ModEndLoading(mapName); return; } /* get base path */ if (token[0] == '-') { Q_strncpyz(base, token + 1, sizeof(base)); continue; } /* get tile name */ if (token[0] == '+') Com_sprintf(name, sizeof(name), "%s%s", base, token + 1); else Q_strncpyz(name, token, sizeof(name)); if (pos && pos[0]) { /* get grid position and add a tile */ for (i = 0; i < 3; i++) { token = Com_Parse(&pos); if (!pos) Com_Error(ERR_DROP, "R_ModBeginLoading: invalid positions\n"); sh[i] = atoi(token); } if (sh[0] <= -(PATHFINDING_WIDTH / 2) || sh[0] >= PATHFINDING_WIDTH / 2) Com_Error(ERR_DROP, "R_ModBeginLoading: invalid x position given: %i\n", sh[0]); if (sh[1] <= -(PATHFINDING_WIDTH / 2) || sh[1] >= PATHFINDING_WIDTH / 2) Com_Error(ERR_DROP, "R_ModBeginLoading: invalid y position given: %i\n", sh[1]); if (sh[2] >= PATHFINDING_HEIGHT) Com_Error(ERR_DROP, "R_ModBeginLoading: invalid z position given: %i\n", sh[2]); R_ModAddMapTile(name, day, sh[0], sh[1], sh[2]); } else { /* load only a single tile, if no positions are specified */ R_ModAddMapTile(name, day, 0, 0, 0); R_ModEndLoading(mapName); return; } } Com_Error(ERR_DROP, "R_ModBeginLoading: invalid tile names\n"); }
/** * @brief Re-initializes OpenGL state machine, all textures and renderer variables, this needed when application is put to background on Android. */ void R_ReinitOpenglContext (void) { /* De-allocate old GL state, these functinos will call glDeleteTexture(), so they should go before everything else */ R_FontCleanCache(); R_ShutdownFBObjects(); R_ShutdownPrograms(); R_BeginBuildingLightmaps(); /* This function will also call glDeleteTexture() */ /* Re-initialize GL state */ R_SetDefaultState(); R_InitPrograms(); /* Re-upload all textures */ R_InitMiscTexture(); R_ReloadImages(); /* Re-upload other GL stuff */ R_InitFBObjects(); R_UpdateDefaultMaterial("", "", "", NULL); /* Re-upload the battlescape terrain geometry */ if (!qglBindBuffer) return; for (int tile = 0; tile < r_numMapTiles; tile++) { model_t *mod = r_mapTiles[tile]; int vertind = 0, coordind = 0, tangind = 0; mBspSurface_t *surf = mod->bsp.surfaces; for (int i = 0; i < mod->bsp.numsurfaces; i++, surf++) { vertind += 3 * surf->numedges; coordind += 2 * surf->numedges; tangind += 4 * surf->numedges; } qglGenBuffers(1, &mod->bsp.vertex_buffer); qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.vertex_buffer); qglBufferData(GL_ARRAY_BUFFER, vertind * sizeof(GLfloat), mod->bsp.verts, GL_STATIC_DRAW); qglGenBuffers(1, &mod->bsp.texcoord_buffer); qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.texcoord_buffer); qglBufferData(GL_ARRAY_BUFFER, coordind * sizeof(GLfloat), mod->bsp.texcoords, GL_STATIC_DRAW); qglGenBuffers(1, &mod->bsp.lmtexcoord_buffer); qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.lmtexcoord_buffer); qglBufferData(GL_ARRAY_BUFFER, coordind * sizeof(GLfloat), mod->bsp.lmtexcoords, GL_STATIC_DRAW); qglGenBuffers(1, &mod->bsp.normal_buffer); qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.normal_buffer); qglBufferData(GL_ARRAY_BUFFER, vertind * sizeof(GLfloat), mod->bsp.normals, GL_STATIC_DRAW); qglGenBuffers(1, &mod->bsp.tangent_buffer); qglBindBuffer(GL_ARRAY_BUFFER, mod->bsp.tangent_buffer); qglBufferData(GL_ARRAY_BUFFER, tangind * sizeof(GLfloat), mod->bsp.tangents, GL_STATIC_DRAW); qglGenBuffers(1, &mod->bsp.index_buffer); qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mod->bsp.index_buffer); qglBufferData(GL_ELEMENT_ARRAY_BUFFER, mod->bsp.numIndexes * sizeof(GLushort), mod->bsp.indexes, GL_STATIC_DRAW); qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); for (int i = 0; i < mod->bsp.numsurfaces; i++) R_CreateSurfaceLightmap(&mod->bsp.surfaces[i]); } R_EndBuildingLightmaps(); qglBindBuffer(GL_ARRAY_BUFFER, 0); }