29 #include "../idlib/precompiled.h"
73 float *planeSide = (
float *) _alloca16( numFaces *
sizeof(
float ) );
79 cullInfo.
facing[ numFaces ] = 1;
102 for ( i = 0; i < 6; i++ ) {
113 if ( frontBits == ( ( 1 << 6 ) - 1 ) ) {
121 float *planeSide = (
float *) _alloca16( tri->
numVerts *
sizeof(
float ) );
123 for ( i = 0; i < 6; i++ ) {
125 if ( frontBits & ( 1 << i ) ) {
151 #define MAX_CLIPPED_POINTS 20
169 static int R_ChopWinding(
clipTri_t clipTris[2],
int inNum,
const idPlane plane ) {
179 in = &clipTris[inNum];
180 out = &clipTris[inNum^1];
181 counts[0] = counts[1] = counts[2] = 0;
185 for ( i = 0; i < in->
numVerts; i++ ) {
214 for ( i = 0 ; i < in->
numVerts ; i++ ) {
222 if ( sides[i+1] == sides[i] ) {
229 dot = dists[
i] / ( dists[
i] - dists[i+1] );
230 for ( j = 0; j < 3; j++ ) {
231 mid[
j] = p1[
j] + dot * ( p2[
j] - p1[
j] );
260 for ( i = 0 ; i < 6 ; i++ ) {
261 if ( planeBits & ( 1 << i ) ) {
262 p = R_ChopWinding( pingPong, p, frustum[i] );
263 if ( pingPong[p].numVerts < 1 ) {
290 bool includeBackFaces;
304 includeBackFaces =
true;
306 includeBackFaces =
false;
320 if ( !includeBackFaces ) {
330 if ( includeBackFaces ) {
346 for ( faceNum = i = 0; i < tri->
numIndexes; i += 3, faceNum++ ) {
347 if ( !facing[ faceNum ] ) {
351 indexes[numIndexes+0] = tri->
indexes[i+0];
352 indexes[numIndexes+1] = tri->
indexes[i+1];
353 indexes[numIndexes+2] = tri->
indexes[i+2];
374 for ( faceNum = i = 0; i < tri->
numIndexes; i += 3, faceNum++ ) {
379 if ( !includeBackFaces ) {
381 if ( !facing[ faceNum ] ) {
393 if ( cullBits[i1] & cullBits[i2] & cullBits[i3] ) {
401 if ( cullBits[i1] && cullBits[i2] && cullBits[i3] ) {
402 int cull = cullBits[
i1] | cullBits[
i2] | cullBits[i3];
410 indexes[numIndexes+0] =
i1;
411 indexes[numIndexes+1] =
i2;
412 indexes[numIndexes+2] = i3;
460 if ( !edef || !ldef ) {
461 common->
Error(
"idInteraction::AllocAndLink: NULL parm" );
504 common->
Error(
"idInteraction::AllocAndLink: non NULL table entry" );
596 common->
Error(
"idInteraction::UnlinkAndFree: interactionTable wasn't set" );
608 nextArea = area->
next;
780 if ( !frustum.IsValid() ) {
826 bool interactionGenerated;
845 if ( bounds[1][0] - bounds[0][0] > 3000 ) {
855 interactionGenerated =
false;
858 for (
int c = 0 ; c < model->
NumSurfaces() ; c++ ) {
904 interactionGenerated =
true;
924 interactionGenerated =
true;
935 if ( !interactionGenerated ) {
948 static bool R_PotentiallyInsideInfiniteShadow(
const srfTriangles_t *occluder,
959 float stretch = znear * 2;
960 exp[0][0] = occluder->
bounds[0][0] - stretch;
961 exp[0][1] = occluder->
bounds[0][1] - stretch;
962 exp[0][2] = occluder->
bounds[0][2] - stretch;
963 exp[1][0] = occluder->
bounds[1][0] + stretch;
964 exp[1][1] = occluder->
bounds[1][1] + stretch;
965 exp[1][2] = occluder->
bounds[1][2] + stretch;
977 idVec3 ray = localView - localLight;
980 for (
int axis = 0; axis < 3; axis++ ) {
984 if ( localLight[axis] < exp[0][axis] ) {
985 if ( localView[axis] < exp[0][axis] ) {
988 d = exp[0][axis] - localLight[axis];
989 frac = d / ray[axis];
990 hit = localLight + frac * ray;
991 hit[axis] = exp[0][axis];
992 }
else if ( localLight[axis] > exp[1][axis] ) {
993 if ( localView[axis] > exp[1][axis] ) {
996 d = exp[1][axis] - localLight[axis];
997 frac = d / ray[axis];
998 hit = localLight + frac * ray;
999 hit[axis] = exp[1][axis];
1061 if ( shadowScissor.
IsEmpty() ) {
1092 bool lightScissorsEmpty = lightScissor.
IsEmpty();
1161 vEntity,
lightDef, shader, lightScissor,
false );
1164 vEntity,
lightDef, shader, lightScissor,
false );
1167 vEntity,
lightDef, shader, lightScissor,
false );
1233 bool inside = R_PotentiallyInsideInfiniteShadow( sint->
ambientTris, localViewOrigin, localLightOrigin );
1237 shadowTris, vEntity,
lightDef,
NULL, shadowScissor, inside );
1240 shadowTris, vEntity,
lightDef,
NULL, shadowScissor, inside );
1254 int interactions = 0;
1255 int deferredInteractions = 0;
1256 int emptyInteractions = 0;
1258 int lightTriVerts = 0;
1259 int lightTriIndexes = 0;
1261 int shadowTriVerts = 0;
1262 int shadowTriIndexes = 0;
1278 if ( inter->IsDeferred() ) {
1279 deferredInteractions++;
1282 if ( inter->IsEmpty() ) {
1283 emptyInteractions++;
1287 for (
int j = 0; j < inter->numSurfaces; j++ ) {
1304 common->
Printf(
"%i entities with %i total interactions totalling %ik\n", entities, interactions, total / 1024 );
1305 common->
Printf(
"%i deferred interactions, %i empty interactions\n", deferredInteractions, emptyInteractions );
1306 common->
Printf(
"%5i indexes %5i verts in %5i light tris\n", lightTriIndexes, lightTriVerts, lightTris );
1307 common->
Printf(
"%5i indexes %5i verts in %5i shadow tris\n", shadowTriIndexes, shadowTriVerts, shadowTris );
idRenderWorldLocal * world
int numShadowIndexesNoFrontCaps
bool SurfaceCastsShadow(void) const
void R_CalcInteractionCullBits(const idRenderEntityLocal *ent, const srfTriangles_t *tri, const idRenderLightLocal *light, srfCullInfo_t &cullInfo)
bool LightEffectsBackSides() const
const idMaterial * lightShader
const idMaterial * shader
areaNumRef_t * frustumAreas
idCVar r_useShadowCulling("r_useShadowCulling","1", CVAR_RENDERER|CVAR_BOOL,"try to cull shadows from partially visible lights")
void R_CreatePrivateShadowCache(srfTriangles_t *tri)
const idVec3 & Normal(void) const
virtual bool IsStaticWorldModel() const =0
#define LIGHT_CULL_ALL_FRONT
idScreenRect R_ScreenRectFromViewFrustumBounds(const idBounds &bounds)
idInteraction * entityPrev
struct viewEntity_s * viewEntity
idCVar r_useIndexBuffers("r_useIndexBuffers","0", CVAR_RENDERER|CVAR_ARCHIVE|CVAR_INTEGER,"use ARB_vertex_buffer_object for indexes", 0, 1, idCmdSystem::ArgCompletion_Integer< 0, 1 >)
idInteraction * lightNext
idCVar r_showInteractionFrustums("r_showInteractionFrustums","0", CVAR_RENDERER|CVAR_INTEGER,"1 = show a frustum for each interaction, 2 = also draw lines to light origin, 3 = also draw entity bbox", 0, 3, idCmdSystem::ArgCompletion_Integer< 0, 3 >)
bool ReceivesLighting(void) const
void R_CalcInteractionFacing(const idRenderEntityLocal *ent, const srfTriangles_t *tri, const idRenderLightLocal *light, srfCullInfo_t &cullInfo)
float GetFloat(void) const
idCVar r_useInteractionScissors("r_useInteractionScissors","2", CVAR_RENDERER|CVAR_INTEGER,"1 = use a custom scissor rectangle for each shadow interaction, 2 = also crop using portal scissors",-2, 2, idCmdSystem::ArgCompletion_Integer<-2, 2 >)
idScreenRect & GetAreaScreenRect(int areaNum) const
#define MAX_CLIPPED_POINTS
idRenderModel * R_EntityDefDynamicModel(idRenderEntityLocal *def)
areaReference_t * entityRefs
bool R_GlobalShaderOverride(const idMaterial **shader)
idList< idRenderEntityLocal * > entityDefs
bool HasShadows(void) const
virtual void VPCALL CmpGE(byte *dst, const float *src0, const float constant, const int count)=0
const idMaterial * shader
bool IsDeferred(void) const
int suppressShadowInViewID
const struct drawSurf_s * localShadows
void Union(const idScreenRect &rect)
bool facePlanesCalculated
const struct drawSurf_s * globalInteractions
idRenderWorldLocal * primaryWorld
idRenderLightLocal * lightDef
idRenderLightLocal * lightDef
virtual void DebugBox(const idVec4 &color, const idBox &box, const int lifetime=0)
srfTriangles_t * R_AllocStaticTriSurf(void)
virtual void VPCALL Memset(void *dst, const int val, const int count)=0
idCVar r_useInteractionCulling("r_useInteractionCulling","1", CVAR_RENDERER|CVAR_BOOL,"1 = cull interactions")
struct vertCache_s * ambientCache
static idInteraction * AllocAndLink(idRenderEntityLocal *edef, idRenderLightLocal *ldef)
areaNumRef_t * FloodFrustumAreas(const idFrustum &frustum, areaNumRef_t *areas)
idInteraction * lightPrev
const idMaterial * customShader
idCVar r_skipSuppress("r_skipSuppress","0", CVAR_RENDERER|CVAR_BOOL,"ignore the per-view suppressions")
bool R_CullLocalBox(const idBounds &bounds, const float modelMatrix[16], int numPlanes, const idPlane *planes)
#define LIGHT_CLIP_EPSILON
struct srfTriangles_s * ambientSurface
void R_ReferenceStaticTriSurfVerts(srfTriangles_t *tri, const srfTriangles_t *reference)
idInteraction * lastInteraction
idVec3 verts[MAX_CLIPPED_POINTS]
bool LightCastsShadows() const
int suppressShadowInLightID
materialCoverage_t Coverage(void) const
idScreenRect R_CalcIntersectionScissor(const idRenderLightLocal *lightDef, const idRenderEntityLocal *entityDef, const viewDef_t *viewDef)
struct areaNumRef_s * next
idInteraction ** interactionTable
int dynamicModelFrameCount
virtual void VPCALL MinMax(float &min, float &max, const float *src, const int count)=0
virtual void VPCALL CmpLT(byte *dst, const float *src0, const float constant, const int count)=0
void R_CreateVertexProgramShadowCache(srfTriangles_t *tri)
srfTriangles_t * lightTris
idRenderWorldLocal * world
float PlaneDistance(const idPlane &plane) const
srfTriangles_t * geometry
const idDeclSkin * customSkin
void R_DeriveFacePlanes(srfTriangles_t *tri)
const idMaterial * R_RemapShaderBySkin(const idMaterial *shader, const idDeclSkin *skin, const idMaterial *customShader)
idInteraction * firstInteraction
int GetInteger(void) const
idPlane localClipPlanes[6]
struct areaReference_s * ownerNext
virtual const modelSurface_t * Surface(int surfaceNum) const =0
virtual void VPCALL Dot(float *dst, const idVec3 &constant, const idVec3 *src, const int count)=0
void Intersect(const idScreenRect &rect)
void R_FreeStaticTriSurf(srfTriangles_t *tri)
#define LIGHT_TRIS_DEFERRED
void AddActiveInteraction(void)
struct vertCache_s * lightingCache
void Touch(vertCache_t *buffer)
const struct drawSurf_s * translucentInteractions
shadowCache_t * shadowVertexes
void R_LinkLightSurf(const drawSurf_t **link, const srfTriangles_t *tri, const viewEntity_t *space, const idRenderLightLocal *light, const idMaterial *shader, const idScreenRect &scissor, bool viewInsideShadow)
idRenderEntityLocal * entityDef
struct vertCache_s * shadowCache
GLubyte GLubyte GLubyte a
virtual void Printf(const char *fmt,...) id_attribute((format(printf
idCVar r_znear("r_znear","3", CVAR_RENDERER|CVAR_FLOAT,"near Z clip plane distance", 0.001f, 200.0f)
virtual idBounds Bounds(const struct renderEntity_s *ent=NULL) const =0
idBlockAlloc< areaNumRef_t, 1024 > areaNumRefAllocator
idCVar r_showInteractionScissors("r_showInteractionScissors","0", CVAR_RENDERER|CVAR_INTEGER,"1 = show screen rectangle which contains the interaction frustum, 2 = also draw construction lines", 0, 2, idCmdSystem::ArgCompletion_Integer< 0, 2 >)
srfTriangles_t * R_CreateShadowVolume(const idRenderEntityLocal *ent, const srfTriangles_t *tri, const idRenderLightLocal *light, shadowGen_t optimize, srfCullInfo_t &cullInfo)
srfTriangles_t * frustumTris
void R_ReferenceStaticTriSurfIndexes(srfTriangles_t *tri, const srfTriangles_t *reference)
int numShadowIndexesNoCaps
enum idInteraction::@87 frustumState
void R_GlobalPointToLocal(const float modelMatrix[16], const idVec3 &in, idVec3 &out)
bool ClippedProjectionBounds(const idFrustum &frustum, const idBox &clipBox, idBounds &projectionBounds) const
idRenderModel * prelightModel
void R_ReallyFreeStaticTriSurf(srfTriangles_t *tri)
int dynamicModelFrameCount
const struct drawSurf_s * globalShadows
void * R_ClearedStaticAlloc(int bytes)
int interactionTableWidth
surfaceInteraction_t * surfaces
bool IsCleared(void) const
const struct drawSurf_s * localInteractions
idScreenRect CalcInteractionScissorRectangle(const idFrustum &viewFrustum)
void Alloc(void *data, int bytes, vertCache_t **buffer, bool indexBuffer=false)
void * R_StaticAlloc(int bytes)
bool CullInteractionByViewFrustum(const idFrustum &viewFrustum)
idInteraction * lastInteraction
idInteraction * entityNext
bool IntersectsFrustum(const idFrustum &frustum) const
bool R_CreateAmbientCache(srfTriangles_t *tri, bool needsLighting)
srfTriangles_t * ambientTris
bool ReceivesLightingOnBackSides(void) const
int suppressSurfaceInViewID
void R_FreeInteractionCullInfo(srfCullInfo_t &cullInfo)
void R_ShowInteractionMemory_f(const idCmdArgs &args)
bool TestMaterialFlag(const int flag) const
idVertexCache vertexCache
void R_AllocStaticTriSurfIndexes(srfTriangles_t *tri, int numIndexes)
idCVar r_usePreciseTriangleInteractions("r_usePreciseTriangleInteractions","0", CVAR_RENDERER|CVAR_BOOL,"1 = do winding clipping to determine if each ambiguous tri should be lit")
float dot(float a[], float b[])
srfTriangles_t * shadowTris
idInteraction * firstInteraction
idRenderWorldLocal * renderWorld
struct vertCache_s * indexCache
void R_StaticFree(void *data)
void R_ResizeStaticTriSurfIndexes(srfTriangles_t *tri, int numIndexes)
virtual void Error(const char *fmt,...) id_attribute((format(printf
idRenderEntityLocal * entityDef
int R_TriSurfMemory(const srfTriangles_t *tri)
idCVar r_useOptimizedShadows("r_useOptimizedShadows","1", CVAR_RENDERER|CVAR_BOOL,"use the dmap generated static shadow volumes")
bool ContainsPoint(const idVec3 &p) const
void R_ShowColoredScreenRect(const idScreenRect &rect, int colorIndex)
idCVar r_lightAllBackFaces("r_lightAllBackFaces","0", CVAR_RENDERER|CVAR_BOOL,"light all the back faces, even when they would be shadowed")
idBlockAlloc< idInteraction, 256 > interactionAllocator
void R_GlobalPlaneToLocal(const float modelMatrix[16], const idPlane &in, idPlane &out)
void CreateInteraction(const idRenderModel *model)
struct viewLight_s * viewLight
virtual void DebugFrustum(const idVec4 &color, const idFrustum &frustum, const bool showFromOrigin=false, const int lifetime=0)
bool R_CreateLightingCache(const idRenderEntityLocal *ent, const idRenderLightLocal *light, srfTriangles_t *tri)
size_t MemoryUsed(void) const
idSIMDProcessor * SIMDProcessor
virtual int NumSurfaces() const =0