/* * R_DrawCoronas */ void R_DrawCoronas( void ) { unsigned int i; float dist; dlight_t *light; rtrace_t tr; if( r_dynamiclight->integer != 2 ) return; for( i = 0; i < rsc.numDlights; i++ ) { light = rsc.dlights + i; dist = rn.viewAxis[AXIS_FORWARD+0] * ( light->origin[0] - rn.viewOrigin[0] ) + rn.viewAxis[AXIS_FORWARD+1] * ( light->origin[1] - rn.viewOrigin[1] ) + rn.viewAxis[AXIS_FORWARD+2] * ( light->origin[2] - rn.viewOrigin[2] ); if( dist < 24.0f ) continue; dist -= light->intensity; R_TraceLine( &tr, light->origin, rn.viewOrigin, SURF_NONSOLID ); if( tr.fraction != 1.0f ) continue; R_AddDSurfToDrawList( rsc.worldent, R_FogForSphere( light->origin, 1 ), r_coronaShader, Distance( rn.viewOrigin, light->origin ), 0, NULL, &r_coronaSurfs[i] ); } }
/* * R_RenderDebugSurface */ static void R_RenderDebugSurface( const refdef_t *fd ) { rtrace_t tr; vec3_t forward; vec3_t start, end; msurface_t *surf; if( fd->rdflags & RDF_NOWORLDMODEL ) return; if( r_speeds->integer != 4 && r_speeds->integer != 5 ) return; VectorCopy( &fd->viewaxis[AXIS_FORWARD], forward ); VectorCopy( fd->vieworg, start ); VectorMA( start, 4096, forward, end ); surf = R_TraceLine( &tr, start, end, 0 ); if( surf && surf->drawSurf && !r_showtris->integer ) { R_ClearDrawList(); if( !R_AddDSurfToDrawList( R_NUM2ENT(tr.ent), NULL, surf->shader, 0, 0, NULL, surf->drawSurf ) ) { return; } rsc.debugSurface = surf; if( r_speeds->integer == 5 ) { // VBO debug mode R_AddVBOSlice( surf->drawSurf - rsh.worldBrushModel->drawSurfaces, surf->drawSurf->vbo->numVerts, surf->drawSurf->vbo->numElems, 0, 0 ); } else { // classic mode (showtris for individual surface) R_AddVBOSlice( surf->drawSurf - rsh.worldBrushModel->drawSurfaces, surf->mesh->numVerts, surf->mesh->numElems, surf->firstDrawSurfVert, surf->firstDrawSurfElem ); } R_DrawOutlinedSurfaces(); } }
/* * R_DrawPolys */ void R_DrawPolys( void ) { unsigned int i; drawSurfacePoly_t *p; mfog_t *fog; if( rn.renderFlags & RF_NOENTS ) return; for( i = 0; i < rsc.numPolys; i++ ) { p = rsc.polys + i; if( p->fogNum <= 0 || (unsigned)p->fogNum > rsh.worldBrushModel->numfogs ) fog = NULL; else fog = rsh.worldBrushModel->fogs + p->fogNum - 1; if( !R_AddDSurfToDrawList( rsc.worldent, fog, p->shader, 0, i, NULL, p ) ) { continue; } } }
/* * R_AddSkyToDrawList */ void R_AddSkyToDrawList( const msurface_t *fa ) { int i; vec3_t *vert; elem_t *elem; mesh_t *mesh; vec3_t verts[4]; // calculate vertex values for sky box r_warpFace = fa; r_warpFaceVis = qfalse; mesh = fa->mesh; elem = mesh->elems; vert = mesh->xyzArray; for( i = 0; i < mesh->numElems; i += 3, elem += 3 ) { VectorSubtract( vert[elem[0]], rn.viewOrigin, verts[0] ); VectorSubtract( vert[elem[1]], rn.viewOrigin, verts[1] ); VectorSubtract( vert[elem[2]], rn.viewOrigin, verts[2] ); ClipSkyPolygon( 3, verts[0], 0 ); } if( r_warpFaceVis ) { if( fa->fog ) { rn.skyFog = fa->fog; } else if( r_worldbrushmodel->globalfog ) { rn.skyFog = r_worldbrushmodel->globalfog; } // there should be only one sky drawSurf in the list if( !rn.skyShader ) { rn.skyShader = fa->shader; R_AddDSurfToDrawList( rsc.worldent, NULL, fa->shader, 0, r_warpFaceAxis, NULL, &r_skySurf ); } } }
/* * R_AddSurfaceToDrawList */ static void R_AddSurfaceToDrawList( const entity_t *e, const msurface_t *surf, const mfog_t *fog, unsigned int clipFlags, unsigned int dlightBits, unsigned shadowBits, float dist ) { int order = 0; shader_t *shader; drawSurfaceBSP_t *drawSurf; if( R_CullSurface( e, surf, clipFlags ) ) { return; } if( r_drawworld->integer == 2 ) { shader = rsh.envShader; } else { shader = surf->shader; if( shader->flags & SHADER_SKY ) { if( !R_FASTSKY() ) { R_AddSkyToDrawList( surf ); rn.numVisSurfaces++; } return; } } drawSurf = surf->drawSurf; if( drawSurf->visFrame != rf.frameCount ) { portalSurface_t *portalSurface = NULL; if( shader->flags & SHADER_PORTAL ) { // draw portals in front-to-back order dist = 1024 - dist / 100.0f; if( dist < 1 ) dist = 1; portalSurface = R_AddPortalSurface( e, surf->mesh, surf->mins, surf->maxs, shader ); } drawSurf->visFrame = rf.frameCount; if( !R_AddDSurfToDrawList( e, fog, shader, dist, order, portalSurface, drawSurf ) ) { return; } } // keep track of the actual vbo chunk we need to render R_AddVBOSlice( drawSurf - rsh.worldBrushModel->drawSurfaces, surf->mesh->numVerts, surf->mesh->numElems, surf->firstDrawSurfVert, surf->firstDrawSurfElem ); // dynamic lights that affect the surface if( dlightBits && R_SurfPotentiallyLit( surf ) ) { // ignore dlights that have already been marked as affectors if( drawSurf->dlightFrame == rsc.frameCount ) { drawSurf->dlightBits |= dlightBits; } else { drawSurf->dlightBits = dlightBits; drawSurf->dlightFrame = rsc.frameCount; } } // shadows that are projected onto the surface if( shadowBits && R_SurfPotentiallyShadowed( surf ) ) { // ignore shadows that have already been marked as affectors if( drawSurf->shadowFrame == rsc.frameCount ) { drawSurf->shadowBits |= shadowBits; } else { drawSurf->shadowBits = shadowBits; drawSurf->shadowFrame = rsc.frameCount; } } rf.stats.c_brush_polys++; rn.numVisSurfaces++; }
/* * R_AddSkeletalModelToDrawList */ qboolean R_AddSkeletalModelToDrawList( const entity_t *e ) { int i; const mfog_t *fog; const model_t *mod; const shader_t *shader; const mskmesh_t *mesh; const mskmodel_t *skmodel; vec3_t mins, maxs; float radius; float distance; int clipped; mod = R_SkeletalModelLOD( e ); if( !( skmodel = ( ( mskmodel_t * )mod->extradata ) ) || !skmodel->nummeshes ) return qfalse; radius = R_SkeletalModelLerpBBox( e, mod, mins, maxs ); clipped = R_CullModelEntity( e, mins, maxs, radius, qtrue ); if( clipped ) return qfalse; // never render weapon models or non-occluders into shadowmaps if( rn.renderFlags & RF_SHADOWMAPVIEW ) { if( e->renderfx & RF_WEAPONMODEL ) { return qtrue; } if( rsc.entShadowGroups[R_ENT2NUM(e)] != rn.shadowGroup->id ) { return qtrue; } } // make sure weapon model is always closest to the viewer if( e->renderfx & RF_WEAPONMODEL ) { distance = 0; } else { distance = Distance( e->origin, rn.viewOrigin ) + 1; } fog = R_FogForSphere( e->origin, radius ); #if 0 if( !( e->flags & RF_WEAPONMODEL ) && fog ) { R_SkeletalModelLerpBBox( e, mod ); if( R_CompletelyFogged( fog, e->origin, skm_radius ) ) return qfalse; } #endif for( i = 0, mesh = skmodel->meshes; i < (int)skmodel->nummeshes; i++, mesh++ ) { shader = NULL; if( e->customSkin ) { shader = R_FindShaderForSkinFile( e->customSkin, mesh->name ); } else if( e->customShader ) { shader = e->customShader; } else { shader = mesh->skin.shader; } if( shader ) { R_AddDSurfToDrawList( e, fog, shader, distance, 0, NULL, skmodel->drawSurfs + i ); } } return qtrue; }
/* * R_AddSurfaceToDrawList */ static void R_AddSurfaceToDrawList( const entity_t *e, const msurface_t *surf, const mfog_t *fog, unsigned int clipFlags, unsigned int dlightBits, unsigned shadowBits, float dist ) { int order = 0; shader_t *shader; drawSurfaceBSP_t *drawSurf; if( R_CullSurface( e, surf, clipFlags ) ) { return; } if( r_drawworld->integer == 2 ) { shader = rf.envShader; } else { shader = surf->shader; if( shader->flags & SHADER_SKY ) { if( !R_FASTSKY() ) { R_AddSkyToDrawList( surf ); } // fallthrough, but add with skyclip shader, writing to depthbuffer // that will mask our skydome and prevent world geometry from // bleeding through it fog = NULL; shader = rf.skyclipShader; order = 1000; } } drawSurf = surf->drawSurf; if( drawSurf->visFrame != r_framecount ) { portalSurface_t *portalSurface = NULL; if( shader->flags & SHADER_PORTAL ) { portalSurface = R_AddPortalSurface( e, surf->mesh, surf->mins, surf->maxs, shader ); } drawSurf->visFrame = r_framecount; if( !R_AddDSurfToDrawList( e, fog, shader, dist, order, portalSurface, drawSurf ) ) { return; } } // keep track of the actual vbo chunk we need to render R_AddVBOSlice( drawSurf - r_worldbrushmodel->drawSurfaces, surf->mesh->numVerts, surf->mesh->numElems, surf->firstDrawSurfVert, surf->firstDrawSurfElem ); // dynamic lights that affect the surface if( dlightBits && R_SurfPotentiallyLit( surf ) ) { // ignore dlights that have already been marked as affectors if( drawSurf->dlightFrame == rf.sceneFrameCount ) { drawSurf->dlightBits |= dlightBits; } else { drawSurf->dlightBits = dlightBits; drawSurf->dlightFrame = rf.sceneFrameCount; } } // shadows that are projected onto the surface if( shadowBits && R_SurfPotentiallyShadowed( surf ) ) { // ignore shadows that have already been marked as affectors if( drawSurf->shadowFrame == rf.sceneFrameCount ) { drawSurf->shadowBits |= shadowBits; } else { drawSurf->shadowBits = shadowBits; drawSurf->shadowFrame = rf.sceneFrameCount; } } c_brush_polys++; rn.numVisSurfaces++; }