void R_DrawSpecialEntities (const entity_t* ents) { const entity_t* e; if (!ents) return; e = ents; R_EnableBlend(true); R_EnableDrawAsGlow(true); while (e) { if (e->flags & RF_BOX) { R_DrawBox(e); } else if (e->flags & RF_PATH) { R_DrawFloor(e); } else if (e->flags & RF_ARROW) { R_DrawArrow(e); } e = e->next; } R_EnableDrawAsGlow(false); R_EnableBlend(false); }
/** * @brief Draws the field marker entity is specified in CL_AddTargeting * @sa CL_AddTargeting * @sa RF_BOX */ static void R_DrawBox (const entity_t * e) { const vec4_t color = {e->color[0], e->color[1], e->color[2], e->alpha}; glDisable(GL_TEXTURE_2D); R_Color(color); R_EnableDrawAsGlow(qtrue); if (VectorNotEmpty(e->mins) && VectorNotEmpty(e->maxs)) { R_DrawBoundingBox(e->mins, e->maxs); } else { vec3_t points[] = { { e->oldorigin[0], e->oldorigin[1], e->oldorigin[2] }, { e->oldorigin[0], e->origin[1], e->oldorigin[2] }, { e->origin[0], e->origin[1], e->oldorigin[2] }, { e->origin[0], e->oldorigin[1], e->oldorigin[2] } }; glLineWidth(2.0f); R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points); /** @todo fill one array */ glDrawArrays(GL_LINE_LOOP, 0, 4); refdef.batchCount++; points[0][2] = e->origin[2]; points[1][2] = e->origin[2]; points[2][2] = e->origin[2]; points[3][2] = e->origin[2]; glDrawArrays(GL_LINE_LOOP, 0, 4); refdef.batchCount++; points[0][2] = e->oldorigin[2]; points[1][1] = e->oldorigin[1]; points[2][2] = e->oldorigin[2]; points[3][1] = e->origin[1]; glDrawArrays(GL_LINES, 0, 4); refdef.batchCount++; points[0][0] = e->origin[0]; points[1][0] = e->origin[0]; points[2][0] = e->oldorigin[0]; points[3][0] = e->oldorigin[0]; glDrawArrays(GL_LINES, 0, 4); refdef.batchCount++; R_BindDefaultArray(GL_VERTEX_ARRAY); } glEnable(GL_TEXTURE_2D); R_Color(NULL); R_EnableDrawAsGlow(qfalse); }
/** * @brief Draws shadow and highlight effects for the entities (actors) * @note The origins are already transformed */ void R_DrawEntityEffects (void) { const int mask = r_stencilshadows->integer ? RF_BLOOD : (RF_SHADOW | RF_BLOOD); GLint oldDepthFunc; glGetIntegerv(GL_DEPTH_FUNC, &oldDepthFunc); R_EnableBlend(true); if (actorIndicator == nullptr) { selectedActorIndicator = R_FindImage("pics/sfx/actor_selected", it_effect); actorIndicator = R_FindImage("pics/sfx/actor", it_effect); } for (int i = 0; i < refdef.numEntities; i++) { const entity_t* e = &r_entities[i]; if (e->flags <= RF_BOX) continue; glPushMatrix(); glMultMatrixf(e->transform.matrix); if (e->flags & mask) { const vec3_t points[] = { { -18.0, 14.0, -28.5 }, { 10.0, 14.0, -28.5 }, { 10.0, -14.0, -28.5 }, { -18.0, -14.0, -28.5 } }; /** @todo use default_texcoords */ const vec2_t texcoords[] = { { 0.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 0.0 }, { 0.0, 0.0 } }; if (e->flags & RF_SHADOW) { R_BindTexture(shadow->texnum); } else { assert(e->texture); R_BindTexture(e->texture->texnum); } R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, texcoords); R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY); R_BindDefaultArray(GL_VERTEX_ARRAY); refdef.batchCount++; } if (e->flags & RF_ACTOR) { const float size = 15.0; int texnum; /* draw the circles for team-members and allied troops */ vec4_t color = {1, 1, 1, 1}; const vec3_t points[] = { { -size, size, -SELECTION_DELTA }, { size, size, -SELECTION_DELTA }, { size, -size, -SELECTION_DELTA }, { -size, -size, -SELECTION_DELTA } }; /** @todo use default_texcoords */ const vec2_t texcoords[] = { { 0.0, 1.0 }, { 1.0, 1.0 }, { 1.0, 0.0 }, { 0.0, 0.0 } }; if (e->flags & RF_SELECTED) Vector4Set(color, 0, 1, 0, 0.5); else if (e->flags & RF_MEMBER) Vector4Set(color, 0, 0.8, 0, 0.5); else if (e->flags & RF_ALLIED) Vector4Set(color, 0, 1, 0.5, 0.5); else if (e->flags & RF_NEUTRAL) Vector4Set(color, 1, 1, 0, 0.5); else if (e->flags & RF_OPPONENT) Vector4Set(color, 1, 0, 0, 0.5); else Vector4Set(color, 0.3, 0.3, 0.3, 0.5); if (e->flags & RF_SELECTED) texnum = selectedActorIndicator->texnum; else texnum = actorIndicator->texnum; R_BindTexture(texnum); R_Color(color); R_EnableDrawAsGlow(true); /* circle points */ R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, texcoords); R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, points); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); refdef.batchCount++; /* add transparency when something is in front of the circle */ color[3] *= 0.25; R_Color(color); glDepthFunc(GL_GREATER); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDepthFunc(oldDepthFunc); refdef.batchCount++; R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY); R_BindDefaultArray(GL_VERTEX_ARRAY); R_Color(nullptr); R_EnableDrawAsGlow(false); } glPopMatrix(); } }