void R_DrawFills (void) { if (!r_fill_arrays.vert_index) return; R_EnableTexture(&texunit_diffuse, false); R_EnableColorArray(true); /* alter the array pointers */ R_BindArray(GL_COLOR_ARRAY, GL_UNSIGNED_BYTE, r_fill_arrays.colors); glVertexPointer(2, GL_SHORT, 0, r_fill_arrays.verts); R_DrawArrays(0, r_fill_arrays.vert_index / 2); refdef.batchCount++; /* and restore them */ R_BindDefaultArray(GL_VERTEX_ARRAY); R_BindDefaultArray(GL_COLOR_ARRAY); R_EnableColorArray(false); R_EnableTexture(&texunit_diffuse, true); r_fill_arrays.vert_index = r_fill_arrays.color_index = 0; R_Color(nullptr); }
void R_DrawChars (void) { if (!r_char_arrays.vert_index) return; R_BindTexture(draw_chars->texnum); R_EnableColorArray(true); /* alter the array pointers */ R_BindArray(GL_COLOR_ARRAY, GL_UNSIGNED_BYTE, r_char_arrays.colors); R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, r_char_arrays.texcoords); glVertexPointer(2, GL_SHORT, 0, r_char_arrays.verts); R_DrawArrays(0, r_char_arrays.vert_index / 2); refdef.batchCount++; r_char_arrays.color_index = 0; r_char_arrays.texcoord_index = 0; r_char_arrays.vert_index = 0; /* and restore them */ R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY); R_BindDefaultArray(GL_VERTEX_ARRAY); R_BindDefaultArray(GL_COLOR_ARRAY); R_EnableColorArray(false); }
/** * @brief Draws an animated, colored shell for the specified entity. */ static void R_DrawMeshShell_default(const r_entity_t *e) { R_SetMeshShellState_default(e); R_DrawArrays(GL_TRIANGLES, 0, e->model->num_elements); R_ResetMeshShellState_default(e); }
/** * @brief Draws a place-holder "white diamond" prism for the specified entity. */ static void R_DrawNullModel(const r_entity_t *e) { R_BindDiffuseTexture(r_image_state.null->texnum); R_RotateForEntity(e); R_DrawArrays(GL_TRIANGLES, 0, (GLsizei) r_model_state.null_elements_count); R_RotateForEntity(NULL); }
/** * @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); }
/** * @brief Flares are batched by their texture. Usually, this means one draw operation * for all flares in view. Flare visibility is calculated every few millis, and * flare alpha is ramped up or down depending on the results of the visibility * trace. Flares are also faded according to the angle of their surface to the * view origin. */ void R_DrawFlareSurfaces (const mBspSurfaces_t* surfs, glElementIndex_t* indexPtr) { const image_t* image; int i, j, k, l, m; vec3_t view, verts[4]; vec3_t right, up, upright, downright; float dot, dist, scale, alpha; bool visible; bool oldblend; if (!r_flares->integer) return; if (!surfs->count) return; oldblend = r_state.blend_enabled; R_EnableColorArray(true); R_ResetArrayState(); /** @todo better GL state handling */ glDisable(GL_DEPTH_TEST); R_EnableBlend(true); R_BlendFunc(GL_SRC_ALPHA, GL_ONE); image = r_flaretextures[0]; R_BindTexture(image->texnum); j = k = l = 0; for (i = 0; i < surfs->count; i++) { mBspSurface_t* surf = surfs->surfaces[i]; mBspFlare_t* f; if (surf->frame != r_locals.frame) continue; f = surf->flare; /* bind the flare's texture */ if (f->image != image) { R_DrawArrays(0, l / 3); j = k = l = 0; refdef.batchCount++; image = f->image; R_BindTexture(image->texnum); } /* periodically test visibility to ramp alpha */ if (refdef.time - f->time > 0.02) { if (refdef.time - f->time > 0.5) /* reset old flares */ f->alpha = 0; R_Trace(refdef.viewOrigin, f->origin, 0, MASK_SOLID); visible = refdef.trace.fraction == 1.0; f->alpha += (visible ? 0.03 : -0.15); /* ramp */ if (f->alpha > 0.75) /* clamp */ f->alpha = 0.75; else if (f->alpha < 0) f->alpha = 0.0; f->time = refdef.time; } VectorSubtract(f->origin, refdef.viewOrigin, view); dist = VectorNormalize(view); /* fade according to angle */ dot = DotProduct(surf->normal, view); if (dot > 0) continue; alpha = 0.1 + -dot * r_flares->value; if (alpha > 1.0) alpha = 1.0; alpha = f->alpha * alpha; /* scale according to distance */ scale = f->radius + (f->radius * dist * .0005); VectorScale(r_locals.right, scale, right); VectorScale(r_locals.up, scale, up); VectorAdd(up, right, upright); VectorSubtract(right, up, downright); VectorSubtract(f->origin, downright, verts[0]); VectorAdd(f->origin, upright, verts[1]); VectorAdd(f->origin, downright, verts[2]); VectorSubtract(f->origin, upright, verts[3]); for (m = 0; m < 4; m++) { /* duplicate color data to all 4 verts */ memcpy(&r_state.color_array[j], f->color, sizeof(vec3_t)); r_state.color_array[j + 3] = alpha; j += 4; } /* copy texcoord info */ memcpy(&texunit_diffuse.texcoord_array[k], default_texcoords, sizeof(vec2_t) * 4); k += sizeof(vec2_t) / sizeof(vec_t) * 4; /* and lastly copy the 4 verts */ memcpy(&r_state.vertex_array_3d[l], verts, sizeof(vec3_t) * 4); l += sizeof(vec3_t) / sizeof(vec_t) * 4; } R_DrawArrays(0, l / 3); refdef.batchCount++; R_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); R_EnableBlend(oldblend); glEnable(GL_DEPTH_TEST); R_EnableColorArray(false); R_Color(nullptr); }