/* ================= R_AddIQMInteractions ================= */ void R_AddIQMInteractions( trRefEntity_t *ent, trRefLight_t *light, interactionType_t iaType ) { int i; IQModel_t *model; srfIQModel_t *surface; shader_t *shader = 0; bool personalModel; byte cubeSideBits = CUBESIDE_CLIPALL; // cull the entire model if merged bounding box of both frames // is outside the view frustum and we don't care about proper shadowing if ( ent->cull == cullResult_t::CULL_OUT ) { iaType = (interactionType_t) (iaType & ~IA_LIGHT); if( !iaType ) { return; } } // avoid drawing of certain objects #if defined( USE_REFENTITY_NOSHADOWID ) if ( light->l.inverseShadows ) { if ( (iaType & IA_SHADOW) && ( light->l.noShadowID && ( light->l.noShadowID != ent->e.noShadowID ) ) ) { return; } } else { if ( (iaType & IA_SHADOW) && ( light->l.noShadowID && ( light->l.noShadowID == ent->e.noShadowID ) ) ) { return; } } #endif // don't add third_person objects if not in a portal personalModel = ( ent->e.renderfx & RF_THIRD_PERSON ) && !tr.viewParms.isPortal; model = tr.currentModel->iqm; // do a quick AABB cull if ( !BoundsIntersect( light->worldBounds[ 0 ], light->worldBounds[ 1 ], ent->worldBounds[ 0 ], ent->worldBounds[ 1 ] ) ) { tr.pc.c_dlightSurfacesCulled += model->num_surfaces; return; } // do a more expensive and precise light frustum cull if ( !r_noLightFrustums->integer ) { if ( R_CullLightWorldBounds( light, ent->worldBounds ) == cullResult_t::CULL_OUT ) { tr.pc.c_dlightSurfacesCulled += model->num_surfaces; return; } } cubeSideBits = R_CalcLightCubeSideBits( light, ent->worldBounds ); // generate interactions with all surfaces for ( i = 0, surface = model->surfaces; i < model->num_surfaces; i++, surface++ ) { if ( ent->e.customShader ) { shader = R_GetShaderByHandle( ent->e.customShader ); } else if ( ent->e.customSkin > 0 && ent->e.customSkin < tr.numSkins ) { skin_t *skin; skin = R_GetSkinByHandle( ent->e.customSkin ); // match the surface name to something in the skin file shader = tr.defaultShader; // FIXME: replace MD3_MAX_SURFACES for skin_t::surfaces if ( i >= 0 && i < skin->numSurfaces && skin->surfaces[ i ] ) { shader = skin->surfaces[ i ]->shader; } if ( shader == tr.defaultShader ) { Log::Warn("no shader for surface %i in skin %s", i, skin->name ); } else if ( shader->defaultShader ) { Log::Warn("shader %s in skin %s not found", shader->name, skin->name ); } } else { shader = R_GetShaderByHandle( surface->shader->index ); } // skip all surfaces that don't matter for lighting only pass if ( shader->isSky || ( !shader->interactLight && shader->noShadows ) ) { continue; } // we will add shadows even if the main object isn't visible in the view // don't add third_person objects if not viewing through a portal if ( !personalModel ) { R_AddLightInteraction( light, ( surfaceType_t * ) surface, shader, cubeSideBits, iaType ); tr.pc.c_dlightSurfaces++; } } }
/* ================= R_AddMD5Interactions ================= */ void R_AddMD5Interactions(trRefEntity_t * ent, trRefLight_t * light) { int i; md5Model_t *model; md5Surface_t *surface; shader_t *shader = 0; qboolean personalModel; byte cubeSideBits = CUBESIDE_CLIPALL; interactionType_t iaType = IA_DEFAULT; // cull the entire model if merged bounding box of both frames // is outside the view frustum and we don't care about proper shadowing if(ent->cull == CULL_OUT) { if(r_shadows->integer <= SHADOWING_BLOB || light->l.noShadows) return; else iaType = IA_SHADOWONLY; } // avoid drawing of certain objects #if defined(USE_REFENTITY_NOSHADOWID) if(light->l.inverseShadows) { if(iaType != IA_LIGHTONLY && (light->l.noShadowID && (light->l.noShadowID != ent->e.noShadowID))) return; } else { if(iaType != IA_LIGHTONLY && (light->l.noShadowID && (light->l.noShadowID == ent->e.noShadowID))) return; } #endif // don't add third_person objects if not in a portal personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal; model = tr.currentModel->md5; // do a quick AABB cull if(!BoundsIntersect(light->worldBounds[0], light->worldBounds[1], ent->worldBounds[0], ent->worldBounds[1])) { tr.pc.c_dlightSurfacesCulled += model->numSurfaces; return; } // do a more expensive and precise light frustum cull if(!r_noLightFrustums->integer) { if(R_CullLightWorldBounds(light, ent->worldBounds) == CULL_OUT) { tr.pc.c_dlightSurfacesCulled += model->numSurfaces; return; } } cubeSideBits = R_CalcLightCubeSideBits(light, ent->worldBounds); if(!r_vboModels->integer || !model->numVBOSurfaces || (!glConfig2.vboVertexSkinningAvailable && ent->e.skeleton.type == SK_ABSOLUTE)) { // generate interactions with all surfaces for(i = 0, surface = model->surfaces; i < model->numSurfaces; i++, surface++) { if(ent->e.customShader) { shader = R_GetShaderByHandle(ent->e.customShader); } else if(ent->e.customSkin > 0 && ent->e.customSkin < tr.numSkins) { skin_t *skin; skin = R_GetSkinByHandle(ent->e.customSkin); // match the surface name to something in the skin file shader = tr.defaultShader; // FIXME: replace MD3_MAX_SURFACES for skin_t::surfaces if(i >= 0 && i < skin->numSurfaces && skin->surfaces[i]) { shader = skin->surfaces[i]->shader; } if(shader == tr.defaultShader) { ri.Printf(PRINT_DEVELOPER, "WARNING: no shader for surface %i in skin %s\n", i, skin->name); } else if(shader->defaultShader) { ri.Printf(PRINT_DEVELOPER, "WARNING: shader %s in skin %s not found\n", shader->name, skin->name); } } else { shader = R_GetShaderByHandle(surface->shaderIndex); } // skip all surfaces that don't matter for lighting only pass if(shader->isSky || (!shader->interactLight && shader->noShadows)) continue; // we will add shadows even if the main object isn't visible in the view // don't add third_person objects if not viewing through a portal if(!personalModel) { R_AddLightInteraction(light, (void *)surface, shader, cubeSideBits, iaType); tr.pc.c_dlightSurfaces++; } } } else { int i; srfVBOMD5Mesh_t *vboSurface; shader_t *shader; for(i = 0; i < model->numVBOSurfaces; i++) { vboSurface = model->vboSurfaces[i]; if(ent->e.customShader) { shader = R_GetShaderByHandle(ent->e.customShader); } else if(ent->e.customSkin > 0 && ent->e.customSkin < tr.numSkins) { skin_t *skin; skin = R_GetSkinByHandle(ent->e.customSkin); // match the surface name to something in the skin file shader = tr.defaultShader; // FIXME: replace MD3_MAX_SURFACES for skin_t::surfaces if(i >= 0 && i < skin->numSurfaces && skin->surfaces[i]) { shader = skin->surfaces[i]->shader; } if(shader == tr.defaultShader) { ri.Printf(PRINT_DEVELOPER, "WARNING: no shader for surface %i in skin %s\n", i, skin->name); } else if(shader->defaultShader) { ri.Printf(PRINT_DEVELOPER, "WARNING: shader %s in skin %s not found\n", shader->name, skin->name); } } else { shader = vboSurface->shader; } // skip all surfaces that don't matter for lighting only pass if(shader->isSky || (!shader->interactLight && shader->noShadows)) continue; // don't add third_person objects if not viewing through a portal if(!personalModel) { R_AddLightInteraction(light, (void *)vboSurface, shader, cubeSideBits, iaType); tr.pc.c_dlightSurfaces++; } } } }
/** * @brief R_AddMDVInteractions * @param[in] ent * @param[in] light */ void R_AddMDVInteractions(trRefEntity_t *ent, trRefLight_t *light) { int i; mdvModel_t *model = 0; mdvSurface_t *mdvSurface = 0; shader_t *shader = 0; int lod; qboolean personalModel; byte cubeSideBits; interactionType_t iaType = IA_DEFAULT; // cull the entire model if merged bounding box of both frames // is outside the view frustum and we don't care about proper shadowing if (ent->cull == CULL_OUT) { if (r_shadows->integer <= SHADOWING_BLOB || light->l.noShadows) { return; } else { iaType = IA_SHADOWONLY; } } // avoid drawing of certain objects #if defined(USE_REFENTITY_NOSHADOWID) if (light->l.inverseShadows) { if (iaType != IA_LIGHTONLY && (light->l.noShadowID && (light->l.noShadowID != ent->e.noShadowID))) { return; } } else { if (iaType != IA_LIGHTONLY && (light->l.noShadowID && (light->l.noShadowID == ent->e.noShadowID))) { return; } } #endif // don't add third_person objects if not in a portal personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal; // compute LOD lod = R_ComputeLOD(ent); model = tr.currentModel->mdv[lod]; // do a quick AABB cull if (!BoundsIntersect(light->worldBounds[0], light->worldBounds[1], ent->worldBounds[0], ent->worldBounds[1])) { tr.pc.c_dlightSurfacesCulled += model->numSurfaces; return; } // do a more expensive and precise light frustum cull if (!r_noLightFrustums->integer) { if (R_CullLightWorldBounds(light, ent->worldBounds) == CULL_OUT) { tr.pc.c_dlightSurfacesCulled += model->numSurfaces; return; } } cubeSideBits = R_CalcLightCubeSideBits(light, ent->worldBounds); // generate interactions with all surfaces if (r_vboModels->integer && model->numVBOSurfaces) { // new brute force method: just render everthing with static VBOs int i; srfVBOMDVMesh_t *vboSurface; shader_t *shader; // static VBOs are fine for lighting and shadow mapping for (i = 0; i < model->numVBOSurfaces; i++) { vboSurface = model->vboSurfaces[i]; mdvSurface = vboSurface->mdvSurface; shader = GetMDVSurfaceShader(ent, mdvSurface); // skip all surfaces that don't matter for lighting only pass if (shader->isSky || (!shader->interactLight && shader->noShadows)) { continue; } // we will add shadows even if the main object isn't visible in the view // don't add third_person objects if not viewing through a portal if (!personalModel) { R_AddLightInteraction(light, (surfaceType_t *)vboSurface, shader, cubeSideBits, iaType); tr.pc.c_dlightSurfaces++; } } } else { for (i = 0, mdvSurface = model->surfaces; i < model->numSurfaces; i++, mdvSurface++) { shader = GetMDVSurfaceShader(ent, mdvSurface); // skip all surfaces that don't matter for lighting only pass if (shader->isSky || (!shader->interactLight && shader->noShadows)) { continue; } // we will add shadows even if the main object isn't visible in the view // don't add third_person objects if not viewing through a portal if (!personalModel) { R_AddLightInteraction(light, (surfaceType_t *)mdvSurface, shader, cubeSideBits, iaType); tr.pc.c_dlightSurfaces++; } } } }