Esempio n. 1
0
/*
 * @brief Uploads the specified image to the OpenGL implementation. Images that
 * do not have a GL texture reserved (which is most diffuse textures) will have
 * one generated for them. This flexibility allows for explicitly managed
 * textures (such as lightmaps) to be here as well.
 */
void R_UploadImage(r_image_t *image, GLenum format, byte *data) {

	if (!image || !data) {
		Com_Error(ERR_DROP, "NULL image or data\n");
	}

	if (!image->texnum) {
		glGenTextures(1, &(image->texnum));
	}

	R_BindTexture(image->texnum);

	if (image->type & IT_MASK_MIPMAP) {
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, r_image_state.filter_min);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, r_image_state.filter_mag);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, r_image_state.anisotropy);
		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
	} else {
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, r_image_state.filter_mag);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, r_image_state.filter_mag);
		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
	}

	glTexImage2D(GL_TEXTURE_2D, 0, format, image->width, image->height, 0, format,
			GL_UNSIGNED_BYTE, data);

	R_RegisterMedia((r_media_t *) image);

	R_GetError(image->media.name);
}
Esempio n. 2
0
/*
 * @brief Resolves the specified media if it is already known. The returned
 * media is re-registered for convenience.
 *
 * @return r_media_t The media, or NULL.
 */
r_media_t *R_FindMedia(const char *name) {
	r_media_t *media;

	if ((media = g_hash_table_lookup(r_media_state.media, name))) {
		R_RegisterMedia(media);
	}

	return media;
}
Esempio n. 3
0
/*
 * @brief Establishes a dependency from the specified dependent to the given
 * dependency. Dependencies in use by registered media are never freed.
 */
void R_RegisterDependency(r_media_t *dependent, r_media_t *dependency) {

	if (dependent) {
		if (dependency) {
			if (!g_list_find(dependent->dependencies, dependency)) {
				Com_Debug("%s -> %s\n", dependent->name, dependency->name);
				dependent->dependencies = g_list_prepend(dependent->dependencies, dependency);

				R_RegisterMedia(dependency);
			}
		} else {
			// Com_Debug("Invalid dependency for %s\n", dependent->name);
		}
	} else {
		Com_Warn("Invalid dependent\n");
	}
}
Esempio n. 4
0
/*
 * @brief Inserts the specified media into the shared table, re-registering all
 * of its dependencies as well.
 */
void R_RegisterMedia(r_media_t *media) {

	// check to see if we're already seeded
	if (media->seed != r_media_state.seed) {
		r_media_t *m;

		if ((m = g_hash_table_lookup(r_media_state.media, media->name))) {
			if (m != media) { // the old instance will eventually be freed
				Com_Debug("Replacing %s\n", media->name);
				R_FreeMedia_(NULL, m, m);
				g_hash_table_replace(r_media_state.media, media->name, media);
			} else {
				Com_Debug("Retaining %s\n", media->name);
			}
		} else {
			Com_Debug("Inserting %s\n", media->name);
			g_hash_table_insert(r_media_state.media, media->name, media);
		}

		r_media_state.keys = g_list_insert_sorted(r_media_state.keys, media->name,
				R_RegisterMedia_Compare);

		// re-seed the media to retain it
		media->seed = r_media_state.seed;
	}

	// call the implementation-specific register function
	if (media->Register) {
		media->Register(media);
	}

	// and finally re-register all dependencies
	GList *d = media->dependencies;
	while (d) {
		R_RegisterMedia((r_media_t *) d->data);
		d = d->next;
	}
}
Esempio n. 5
0
/*
 * @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;
}