/** * @brief Primary entry point for drawing all entities. * @sa R_RenderFrame */ void R_GetEntityLists (void) { int i; entity_t** chain; if (!r_drawentities->integer) return; r_opaque_mesh_entities = r_special_entities = r_blend_mesh_entities = r_null_entities = nullptr; for (i = 0; i < refdef.numEntities; i++) { entity_t* e = &r_entities[i]; /* frustum cull check */ if (R_CullEntity(e)) continue; R_CalcTransform(e); if (!e->model) { if ((e->flags & RF_BOX) || (e->flags & RF_PATH) || (e->flags & RF_ARROW)) chain = &r_special_entities; else chain = &r_null_entities; } else { const image_t* skin; switch (e->model->type) { case mod_bsp_submodel: R_AddBspRRef(&(e->model->bsp), e->origin, e->angles, true); continue; case mod_alias_md2: case mod_alias_md3: case mod_obj: skin = R_AliasModelState(e->model, &e->as.mesh, &e->as.frame, &e->as.oldframe, &e->skinnum); if (skin == nullptr || skin->texnum == 0) Com_Error(ERR_DROP, "Model '%s' has no skin assigned", e->model->name); if (skin->has_alpha || (e->flags & RF_TRANSLUCENT)) chain = &r_blend_mesh_entities; else chain = &r_opaque_mesh_entities; break; default: if (e->model->loaded) Com_Error(ERR_DROP, "Unknown model type in R_GetEntityLists entity chain: %i (%s)", e->model->type, e->model->name); return; } } e->next = *chain; *chain = e; } }
/** * @sa R_BeginFrame * @sa R_EndFrame */ void R_RenderFrame (void) { R_Setup3D(); /* activate wire mode */ if (r_wire->integer) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); if (!(refdef.rendererFlags & RDF_NOWORLDMODEL)) { int tile; if (r_threads->integer) { while (r_threadstate.state != THREAD_RENDERER) Sys_Sleep(0); r_threadstate.state = THREAD_CLIENT; } else { R_SetupFrustum(); /* draw brushes on current worldlevel */ R_GetLevelSurfaceLists(); } R_UpdateSustainedLights(); R_CheckError(); for (tile = 0; tile < r_numMapTiles; tile++) { const model_t *mapTile = r_mapTiles[tile]; const mBspModel_t *bsp = &mapTile->bsp; R_AddBspRRef(bsp, vec3_origin, vec3_origin, false); } R_GetEntityLists(); R_EnableFog(true); R_RenderOpaqueBspRRefs(); R_RenderOpaqueWarpBspRRefs(); R_DrawOpaqueMeshEntities(r_opaque_mesh_entities); R_RenderAlphaTestBspRRefs(); R_EnableBlend(true); R_RenderMaterialBspRRefs(); R_EnableFog(false); R_RenderBlendBspRRefs(); R_RenderBlendWarpBspRRefs(); R_DrawBlendMeshEntities(r_blend_mesh_entities); R_EnableFog(true); R_RenderFlareBspRRefs(); R_EnableFog(false); if (r_debug_lights->integer) { int i; for (i = 0; i < refdef.numStaticLights; i++) { const light_t *l = &refdef.staticLights[i]; R_AddCorona(l->origin, l->radius, l->color); } for (i = 0; i < refdef.numDynamicLights; i++) { const light_t *l = &refdef.dynamicLights[i]; R_AddCorona(l->origin, l->radius, l->color); } } R_DrawCoronas(); R_EnableBlend(false); for (tile = 0; tile < r_numMapTiles; tile++) { R_DrawBspNormals(tile); } R_Color(NULL); R_DrawSpecialEntities(r_special_entities); R_DrawNullEntities(r_null_entities); R_DrawEntityEffects(); } else { glClear(GL_DEPTH_BUFFER_BIT); R_GetEntityLists(); R_RenderOpaqueBspRRefs(); R_RenderOpaqueWarpBspRRefs(); R_DrawOpaqueMeshEntities(r_opaque_mesh_entities); R_RenderAlphaTestBspRRefs(); R_EnableBlend(true); R_RenderMaterialBspRRefs(); R_RenderBlendBspRRefs(); R_RenderBlendWarpBspRRefs(); R_DrawBlendMeshEntities(r_blend_mesh_entities); R_RenderFlareBspRRefs(); R_EnableBlend(false); R_Color(NULL); R_DrawSpecialEntities(r_special_entities); R_DrawNullEntities(r_null_entities); R_DrawEntityEffects(); } R_EnableBlend(true); R_DrawParticles(); R_EnableBlend(false); /* leave wire mode again */ if (r_wire->integer) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); R_DrawBloom(); R_DrawBoundingBoxes(); R_ResetArrayState(); /* go back into 2D mode for hud and the like */ R_Setup2D(); R_CheckError(); }