示例#1
0
/*
 * @brief Register event listener for models.
 */
static void R_RegisterModel(r_media_t *self) {
	r_model_t *mod = (r_model_t *) self;

	if (mod->type == MOD_BSP) {
		uint16_t i;

		const r_bsp_texinfo_t *t = mod->bsp->texinfo;

		for (i = 0; i < mod->bsp->num_texinfo; i++, t++) {
			R_RegisterDependency(self, (r_media_t *) t->material);
		}

		const r_bsp_surface_t *s = mod->bsp->surfaces;

		for (i = 0; i < mod->bsp->num_surfaces; i++, s++) {
			R_RegisterDependency(self, (r_media_t *) s->lightmap);
			R_RegisterDependency(self, (r_media_t *) s->deluxemap);
		}

		// keep a reference to the world model
		r_model_state.world = mod;

	} else if (IS_MESH_MODEL(mod)) {
		R_RegisterDependency(self, (r_media_t *) mod->mesh->material);
	}
}
示例#2
0
/**
 * @brief Performs a frustum-cull of all entities. This is performed in a separate
 * thread while the renderer draws the world. Mesh entities which pass a frustum
 * cull will also have their lighting information updated.
 */
void R_CullEntities(void) {

	r_entity_t *e = r_view.entities;
	for (uint16_t i = 0; i < r_view.num_entities; i++, e++) {

		r_entities_t *ents = &r_sorted_entities.null_entities;

		if (IS_BSP_INLINE_MODEL(e->model)) {

			if (R_CullBspInlineModel(e)) {
				continue;
			}

			ents = &r_sorted_entities.bsp_inline_entities;
		} else if (IS_MESH_MODEL(e->model)) {

			if (R_CullMeshModel(e)) {
				continue;
			}

			R_UpdateMeshModelLighting(e);

			ents = &r_sorted_entities.mesh_entities;
		}

		R_ENTITY_TO_ENTITIES(ents, e); // append to the appropriate draw list

		R_SetMatrixForEntity(e); // set the transform matrix
	}

	// sort the mesh entities list by model to allow object instancing

	r_entities_t *mesh = &r_sorted_entities.mesh_entities;
	qsort(mesh, mesh->count, sizeof(r_entity_t *), R_CullEntities_compare);
}
示例#3
0
/**
 * @brief Applies any configuration and tag alignment, populating the model-view
 * matrix for the entity in the process.
 */
void R_SetMatrixForEntity(r_entity_t *e) {

	if (e->parent) {
		vec3_t forward;

		if (!IS_MESH_MODEL(e->model)) {
			Com_Warn("Invalid model for linked entity\n");
			return;
		}

		const r_entity_t *p = e->parent;
		while (p->parent) {
			p = p->parent;
		}

		AngleVectors(p->angles, forward, NULL, NULL);

		VectorClear(e->origin);
		VectorClear(e->angles);

		Matrix4x4_CreateFromEntity(&e->matrix, e->origin, e->angles, e->scale);

		R_ApplyMeshModelTag(e);

		R_ApplyMeshModelConfig(e);

		Matrix4x4_Invert_Simple(&e->inverse_matrix, &e->matrix);

		Matrix4x4_Transform(&e->matrix, vec3_origin, e->origin);
		Matrix4x4_Transform(&e->matrix, vec3_forward, forward);

		VectorAngles(forward, e->angles);
		return;
	}

	Matrix4x4_CreateFromEntity(&e->matrix, e->origin, e->angles, e->scale);

	if (IS_MESH_MODEL(e->model)) {
		R_ApplyMeshModelConfig(e);
	}

	Matrix4x4_Invert_Simple(&e->inverse_matrix, &e->matrix);
}
示例#4
0
/*
 * @brief Allocates and populates static VBO's for the specified r_model_t.
 */
static void R_LoadVertexBuffers(r_model_t *mod) {

	if (!qglGenBuffers)
		return;

	if (IS_MESH_MODEL(mod) && mod->mesh->num_frames > 1) // animated models don't use VBO
		return;

	const GLsizei v = mod->num_verts * 3 * sizeof(GLfloat);
	const GLsizei st = mod->num_verts * 2 * sizeof(GLfloat);
	const GLsizei t = mod->num_verts * 4 * sizeof(GLfloat);

	// load the vertex buffer objects
	qglGenBuffers(1, &mod->vertex_buffer);
	qglBindBuffer(GL_ARRAY_BUFFER, mod->vertex_buffer);
	qglBufferData(GL_ARRAY_BUFFER, v, mod->verts, GL_STATIC_DRAW);

	qglGenBuffers(1, &mod->texcoord_buffer);
	qglBindBuffer(GL_ARRAY_BUFFER, mod->texcoord_buffer);
	qglBufferData(GL_ARRAY_BUFFER, st, mod->texcoords, GL_STATIC_DRAW);

	qglGenBuffers(1, &mod->normal_buffer);
	qglBindBuffer(GL_ARRAY_BUFFER, mod->normal_buffer);
	qglBufferData(GL_ARRAY_BUFFER, v, mod->normals, GL_STATIC_DRAW);

	qglGenBuffers(1, &mod->tangent_buffer);
	qglBindBuffer(GL_ARRAY_BUFFER, mod->tangent_buffer);
	qglBufferData(GL_ARRAY_BUFFER, t, mod->tangents, GL_STATIC_DRAW);

	if (mod->lightmap_texcoords) {
		qglGenBuffers(1, &mod->lightmap_texcoord_buffer);
		qglBindBuffer(GL_ARRAY_BUFFER, mod->lightmap_texcoord_buffer);
		qglBufferData(GL_ARRAY_BUFFER, st, mod->lightmap_texcoords, GL_STATIC_DRAW);
	}

	qglBindBuffer(GL_ARRAY_BUFFER, 0);

	R_GetError(mod->media.name);
}
示例#5
0
/**
 * @brief Draws bounding boxes for all non-linked entities in `ents`.
 */
static void R_DrawEntityBounds(const r_entities_t *ents, const vec4_t color) {

	if (!r_draw_entity_bounds->value) {
		return;
	}

	if (ents->count == 0) {
		return;
	}

	R_BindDiffuseTexture(r_image_state.null->texnum);

	R_EnableColorArray(true);

	R_BindAttributeInterleaveBuffer(&r_model_state.bound_vertice_buffer, R_ARRAY_MASK_ALL);
	R_BindAttributeBuffer(R_ARRAY_ELEMENTS, &r_model_state.bound_element_buffer);

	u8vec4_t bc;
	ColorDecompose(color, bc);

	for (int32_t i = 0; i < 8; ++i) {
		Vector4Set(r_model_state.bound_vertices[i].color, bc[0], bc[1], bc[2], bc[3]);
	}

	static matrix4x4_t mat, modelview;

	R_GetMatrix(R_MATRIX_MODELVIEW, &modelview);

	for (size_t i = 0; i < ents->count; i++) {
		const r_entity_t *e = ents->entities[i];

		if (e->parent || (e->effects & EF_WEAPON) || !IS_MESH_MODEL(e->model)) {
			continue;
		}

		VectorSet(r_model_state.bound_vertices[0].position, e->mins[0], e->mins[1], e->mins[2]);
		VectorSet(r_model_state.bound_vertices[1].position, e->maxs[0], e->mins[1], e->mins[2]);
		VectorSet(r_model_state.bound_vertices[2].position, e->maxs[0], e->maxs[1], e->mins[2]);
		VectorSet(r_model_state.bound_vertices[3].position, e->mins[0], e->maxs[1], e->mins[2]);

		VectorSet(r_model_state.bound_vertices[4].position, e->mins[0], e->mins[1], e->maxs[2]);
		VectorSet(r_model_state.bound_vertices[5].position, e->maxs[0], e->mins[1], e->maxs[2]);
		VectorSet(r_model_state.bound_vertices[6].position, e->maxs[0], e->maxs[1], e->maxs[2]);
		VectorSet(r_model_state.bound_vertices[7].position, e->mins[0], e->maxs[1], e->maxs[2]);

		R_UploadToBuffer(&r_model_state.bound_vertice_buffer, sizeof(r_bound_interleave_vertex_t) * 8,
		                 r_model_state.bound_vertices);

		// draw box
		const vec_t *origin;

		if (e->effects & EF_BOB) {
			origin = e->termination;
		} else {
			origin = e->origin;
		}

		Matrix4x4_CreateFromEntity(&mat, origin, vec3_origin, e->scale);

		Matrix4x4_Concat(&mat, &modelview, &mat);

		R_SetMatrix(R_MATRIX_MODELVIEW, &mat);

		R_DrawArrays(GL_LINES, 0, (GLint) r_model_state.bound_element_count - 6);

		// draw origin
		Matrix4x4_CreateFromEntity(&mat, origin, e->angles, e->scale);

		Matrix4x4_Concat(&mat, &modelview, &mat);

		R_SetMatrix(R_MATRIX_MODELVIEW, &mat);

		R_DrawArrays(GL_LINES, (GLint) r_model_state.bound_element_count - 6, 6);
	}

	R_SetMatrix(R_MATRIX_MODELVIEW, &modelview);

	R_UnbindAttributeBuffer(R_ARRAY_ELEMENTS);

	R_EnableColorArray(false);

	R_Color(NULL);
}