/** * @brief */ void R_MatricesChanged_default(void) { r_default_program_t *p = &r_default_program; if (r_state.active_program->matrix_dirty[R_MATRIX_MODELVIEW]) { // recalculate normal matrix if the modelview has changed. static matrix4x4_t normalMatrix; R_GetMatrix(R_MATRIX_MODELVIEW, &normalMatrix); Matrix4x4_Invert_Full(&normalMatrix, &normalMatrix); Matrix4x4_Transpose(&normalMatrix, &normalMatrix); R_ProgramParameterMatrix4fv(&p->normal_mat, (const GLfloat *) normalMatrix.m); } }
/** * @brief Applies translation, rotation, and scale for the specified entity. */ void R_RotateForEntity(const r_entity_t *e) { if (!e) { R_PopMatrix(R_MATRIX_MODELVIEW); return; } R_PushMatrix(R_MATRIX_MODELVIEW); matrix4x4_t modelview; R_GetMatrix(R_MATRIX_MODELVIEW, &modelview); Matrix4x4_Concat(&modelview, &modelview, &e->matrix); R_SetMatrix(R_MATRIX_MODELVIEW, &modelview); }
/** * @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); }