/* ============= R_MarkLights ============= */ void R_MarkLights (dlight_t *light, int bit, mnode_t *node) { cplane_t *splitplane; float dist; int i; if (node->contents >= 0) { // This is a leaf, so check displacement surfaces and leaf faces R_MarkLightsLeaf( light, bit, (mleaf_t*)node ); return; } splitplane = node->plane; dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; if (dist > light->radius) { R_MarkLights (light, bit, node->children[0]); return; } if (dist < -light->radius) { R_MarkLights (light, bit, node->children[1]); return; } // mark the polygons int surfID = node->firstsurface; for (i=0 ; i<node->numsurfaces ; i++, surfID++) { // Don't redo all this work if we already hit this surface and decided it's lit by this light. msurfacelighting_t *pLighting = SurfaceLighting( surfID ); if(R_IsDLightAlreadyMarked( pLighting, bit)) continue; R_TryLightMarkSurface( light, pLighting, surfID, bit ); } R_MarkLights( light, bit, node->children[0] ); R_MarkLights( light, bit, node->children[1] ); }
void R_MarkDLightsOnSurface( mnode_t* pNode ) { if (!pNode || !g_bActiveDlights) return; dlight_t *l = cl_dlights; for (int i=0 ; i<MAX_DLIGHTS ; i++, l++) { if (l->die < cl.GetTime() || !l->IsRadiusGreaterThanZero() ) continue; if (l->flags & DLIGHT_NO_WORLD_ILLUMINATION) continue; R_MarkLights ( l, 1<<i, pNode ); } }
void R_MarkDLightsOnSurface( mnode_t* pNode ) { if (!pNode) return; dlight_t *l = cl_dlights; for (int i=0 ; i<MAX_DLIGHTS ; i++, l++) { if (l->die < cl.gettime() || !l->radius) continue; if (l->flags & DLIGHT_NO_WORLD_ILLUMINATION) continue; R_MarkLights ( l, 1<<i, pNode ); } }
/* * @brief Main entry point for drawing the scene (world and entities). */ void R_DrawView(void) { R_UpdateFrustum(); R_UpdateVis(); R_MarkBspSurfaces(); R_EnableFog(true); R_DrawSkyBox(); // wait for the client to populate our lights array Thread_Wait(&r_view.thread); // now dispatch another thread to cull entities while we draw the world r_view.thread = Thread_Create(R_CullEntities, NULL); R_MarkLights(); const r_sorted_bsp_surfaces_t *surfs = r_model_state.world->bsp->sorted_surfaces; R_DrawOpaqueBspSurfaces(&surfs->opaque); R_DrawOpaqueWarpBspSurfaces(&surfs->opaque_warp); R_DrawAlphaTestBspSurfaces(&surfs->alpha_test); R_EnableBlend(true); R_DrawBackBspSurfaces(&surfs->back); R_DrawMaterialBspSurfaces(&surfs->material); R_DrawFlareBspSurfaces(&surfs->flare); R_EnableBlend(false); R_DrawBspNormals(); // ensure the thread has finished culling entities Thread_Wait(&r_view.thread); // now dispatch another thread to update particles while we draw entities r_view.thread = Thread_Create(R_UpdateParticles, NULL); R_DrawEntities(); R_EnableBlend(true); R_DrawBspLights(); R_DrawBlendBspSurfaces(&surfs->blend); R_DrawBlendWarpBspSurfaces(&surfs->blend_warp); // ensure the thread has finished updating particles Thread_Wait(&r_view.thread); R_DrawParticles(); R_EnableFog(false); R_DrawCoronas(); R_DrawBspLeafs(); R_EnableBlend(false); R_ResetArrayState(); }
void R_DrawBrushModel(entity_t *e) { int k; vec3_t mins, maxs; model_t *clmodel; bool rotated; int i; extern vec3_t lightcolor; int lnum; vec3_t dist; float add; float modelorg[3]; clmodel = e->model; if (e->angles[0] || e->angles[1] || e->angles[2]) { rotated = true; for (i = 0; i < 3; i++) { mins[i] = e->origin[i] - clmodel->radius; maxs[i] = e->origin[i] + clmodel->radius; } } else { rotated = false; VectorAdd(e->origin, clmodel->mins, mins); VectorAdd(e->origin, clmodel->maxs, maxs); } if (R_CullBox(mins, maxs)) return; //Lighting for model //dynamic lights for non lightmaped bmodels if (clmodel->firstmodelsurface == 0) { R_LightPoint(e->origin); for (lnum = 0; lnum < MAX_DLIGHTS; lnum++) { if (cl_dlights[lnum].die >= cl.time) { VectorSubtract(e->origin, cl_dlights[lnum].origin, dist); add = cl_dlights[lnum].radius - VectorLength(dist); if (add > 0) { lightcolor[0] += add * cl_dlights[lnum].colour[0]; lightcolor[1] += add * cl_dlights[lnum].colour[1]; lightcolor[2] += add * cl_dlights[lnum].colour[2]; } } } VectorScale(lightcolor, 1.0f / 100.0f, lightcolor); if (gl_ammoflash.getBool()) { lightcolor[0] += sin(2 * cl.time * M_PI) / 4; lightcolor[1] += sin(2 * cl.time * M_PI) / 4; lightcolor[2] += sin(2 * cl.time * M_PI) / 4; } glColor3fv(lightcolor); } else { glColor3f(1.0, 1.0, 1.0); memset(lightmap_polys, 0, sizeof (lightmap_polys)); } VectorSubtract(r_refdef.vieworg, e->origin, modelorg); if (rotated) { vec3_t temp; vec3_t forward, right, up; VectorCopy(modelorg, temp); AngleVectors(e->angles, forward, right, up); modelorg[0] = DotProduct(temp, forward); modelorg[1] = -DotProduct(temp, right); modelorg[2] = DotProduct(temp, up); } glPushMatrix(); e->angles[0] = -e->angles[0]; // stupid quake bug R_RotateForEntity(e); e->angles[0] = -e->angles[0]; // stupid quake bug // calculate dynamic lighting for bmodel if it's not an // instanced model if (clmodel->firstmodelsurface != 0 && !gl_flashblend.getBool()) { for (k = 0; k < MAX_DLIGHTS; k++) { if ((cl_dlights[k].die < cl.time) || (!cl_dlights[k].radius)) continue; R_MarkLights(&cl_dlights[k], 1 << k, clmodel->nodes + clmodel->hulls[0].firstclipnode); } } R_DrawBrush(clmodel, &modelorg[0]); glPopMatrix(); }
/* * @brief Main entry point for drawing the scene (world and entities). */ void R_DrawView(void) { R_UpdateFrustum(); R_UpdateVis(); R_MarkBspSurfaces(); R_EnableFog(true); R_DrawSkyBox(); // wait for the client to fully populate the scene Thread_Wait(r_view.thread); // dispatch threads to cull entities and sort elements while we draw the world thread_t *cull_entities = Thread_Create(R_CullEntities, NULL); thread_t *sort_elements = Thread_Create(R_SortElements, NULL); R_MarkLights(); const r_sorted_bsp_surfaces_t *surfs = r_model_state.world->bsp->sorted_surfaces; R_DrawOpaqueBspSurfaces(&surfs->opaque); R_DrawOpaqueWarpBspSurfaces(&surfs->opaque_warp); R_DrawAlphaTestBspSurfaces(&surfs->alpha_test); R_EnableBlend(true); R_DrawBackBspSurfaces(&surfs->back); R_DrawMaterialBspSurfaces(&surfs->material); R_DrawFlareBspSurfaces(&surfs->flare); R_EnableBlend(false); // wait for entity culling to complete Thread_Wait(cull_entities); R_DrawEntities(); R_EnableBlend(true); // wait for element sorting to complete Thread_Wait(sort_elements); R_DrawElements(); R_EnableFog(false); R_DrawDeveloperTools(); R_DrawCoronas(); R_EnableBlend(false); R_ResetArrayState(); #if 0 vec3_t tmp; VectorMA(r_view.origin, MAX_WORLD_DIST, r_view.forward, tmp); cm_trace_t tr = Cl_Trace(r_view.origin, tmp, NULL, NULL, cl.client_num + 1, MASK_SOLID); if (tr.fraction > 0.0 && tr.fraction < 1.0) { Com_Print("%s: %d: %s\n", tr.surface->name, tr.plane.num, vtos(tr.plane.normal)); } #endif }