/* =================== CG_AllocMark Will always succeed, even if it requires freeing an old active mark =================== */ markPoly_t *CG_AllocMark() { markPoly_t *le; int time; if ( !cg_freeMarkPolys ) { // no free entities, so free the one at the end of the chain // remove the oldest active entity time = cg_activeMarkPolys.prevMark->time; while ( cg_activeMarkPolys.prevMark && time == cg_activeMarkPolys.prevMark->time ) { CG_FreeMarkPoly( cg_activeMarkPolys.prevMark ); } } le = cg_freeMarkPolys; cg_freeMarkPolys = cg_freeMarkPolys->nextMark; memset( le, 0, sizeof( *le ) ); // link into the active list le->nextMark = cg_activeMarkPolys.nextMark; le->prevMark = &cg_activeMarkPolys; cg_activeMarkPolys.nextMark->prevMark = le; cg_activeMarkPolys.nextMark = le; return le; }
/* =================== CG_AllocMark Will allways succeed, even if it requires freeing an old active mark =================== */ markPoly_t *CG_AllocMark(int endTime) { markPoly_t *le; //, *trav, *lastTrav; if (!cg_freeMarkPolys) { int time = cg_activeMarkPolys.prevMark->time; // no free entities, so free the one at the end of the chain // remove the oldest active entity while (cg_activeMarkPolys.prevMark && time == cg_activeMarkPolys.prevMark->time) { CG_FreeMarkPoly(cg_activeMarkPolys.prevMark); } } le = cg_freeMarkPolys; cg_freeMarkPolys = cg_freeMarkPolys->nextMark; memset(le, 0, sizeof(*le)); // TODO: sort this, so the list is always sorted by longest duration -> shortest duration, // this way the shortest duration mark will always get overwritten first //for (trav = cg_activeMarkPolys.nextMark; (trav->duration + trav->time > endTime) && (trav != cg_activeMarkPolys.prevMark) ; lastTrav = trav, trav++ ) { // Respect the FOR loop //} // link into the active list le->nextMark = cg_activeMarkPolys.nextMark; le->prevMark = &cg_activeMarkPolys; cg_activeMarkPolys.nextMark->prevMark = le; cg_activeMarkPolys.nextMark = le; return le; }
void CG_AddMarks() { int j; markPoly_t *mp, *next; int t; int fade; if ( !cg_addMarks.integer ) { return; } mp = cg_activeMarkPolys.nextMark; for ( ; mp != &cg_activeMarkPolys; mp = next ) { // grab next now, so if the local entity is freed we // still have it next = mp->nextMark; // see if it is time to completely remove it if ( cg.time > mp->time + MARK_TOTAL_TIME ) { CG_FreeMarkPoly( mp ); continue; } // fade all marks out with time t = mp->time + MARK_TOTAL_TIME - cg.time; if ( t < MARK_FADE_TIME ) { fade = 255 * t / MARK_FADE_TIME; if ( mp->alphaFade ) { for ( j = 0; j < mp->poly.numVerts; j++ ) { mp->verts[ j ].modulate[ 3 ] = fade; } } else { for ( j = 0; j < mp->poly.numVerts; j++ ) { mp->verts[ j ].modulate[ 0 ] = mp->color[ 0 ] * fade; mp->verts[ j ].modulate[ 1 ] = mp->color[ 1 ] * fade; mp->verts[ j ].modulate[ 2 ] = mp->color[ 2 ] * fade; } } } trap_R_AddPolyToScene( mp->markShader, mp->poly.numVerts, mp->verts ); } }
/* =============== CG_AddMarks =============== */ void CG_AddMarks(void) { int j; markPoly_t *mp, *next; int t; int fade; if (!cg_markTime.integer) { return; } mp = cg_activeMarkPolys.nextMark; for ( ; mp != &cg_activeMarkPolys ; mp = next) { // grab next now, so if the local entity is freed we // still have it next = mp->nextMark; // see if it is time to completely remove it if (cg.time > mp->time + mp->duration) { CG_FreeMarkPoly(mp); continue; } // fade all marks out with time t = mp->time + mp->duration - cg.time; if (t < (float)mp->duration / 2.0) { fade = (int)(255.0 * (float)t / ((float)mp->duration / 2.0)); if (mp->alphaFade) { for (j = 0 ; j < mp->poly.numVerts ; j++) { mp->verts[j].modulate[3] = fade; } } else { for (j = 0 ; j < mp->poly.numVerts ; j++) { mp->verts[j].modulate[0] = mp->color[0] * fade; mp->verts[j].modulate[1] = mp->color[1] * fade; mp->verts[j].modulate[2] = mp->color[2] * fade; } } } trap_R_AddPolyToScene(mp->markShader, mp->poly.numVerts, mp->verts); } }
void CG_AddMarks( void ) { int j; markPoly_t *mp, *next; int t; int fade; if ( !cg_marks->boolean ) { return; } mp = cg_activeMarkPolys.nextMark; for ( ; mp != &cg_activeMarkPolys ; mp = next ) { // grab next now, so if the local entity is freed we // still have it next = mp->nextMark; // see if it is time to completely remove it if ( cg.time > mp->time + MARK_TOTAL_TIME ) { CG_FreeMarkPoly( mp ); continue; } // fade out the energy bursts if ( mp->markShader == cgs.media.energyMarkShader ) { fade = (int)(450 - 450 * ( (cg.time - mp->time ) / 3000.0f )); if ( fade < 255 ) { if ( fade < 0 ) { fade = 0; } if ( mp->verts[0].modulate[0] != 0 ) { for ( j = 0 ; j < mp->poly.numVerts ; j++ ) { mp->verts[j].modulate[0] = (byte)(mp->color[0] * fade); mp->verts[j].modulate[1] = (byte)(mp->color[1] * fade); mp->verts[j].modulate[2] = (byte)(mp->color[2] * fade); } } } } // fade all marks out with time t = mp->time + MARK_TOTAL_TIME - cg.time; if ( t < MARK_FADE_TIME ) { fade = 255 * t / MARK_FADE_TIME; if ( mp->alphaFade ) { for ( j = 0 ; j < mp->poly.numVerts ; j++ ) { mp->verts[j].modulate[3] = (byte)fade; } } else { for ( j = 0 ; j < mp->poly.numVerts ; j++ ) { mp->verts[j].modulate[0] = (byte)(mp->color[0] * fade); mp->verts[j].modulate[1] = (byte)(mp->color[1] * fade); mp->verts[j].modulate[2] = (byte)(mp->color[2] * fade); } } } trap->R_AddPolysToScene( mp->markShader, mp->poly.numVerts, mp->verts, 1 ); } }
void CG_AddMarks( void ) { int j, k; markPoly_t *mp, *next; int t; int fade; if ( !cg_addMarks.integer ) { return; } mp = cg_activeMarkPolys.nextMark; for ( ; mp != &cg_activeMarkPolys ; mp = next ) { // grab next now, so if the local entity is freed we // still have it next = mp->nextMark; // see if it is time to completely remove it if ( cg.time > mp->time + MARK_TOTAL_TIME ) { CG_FreeMarkPoly( mp ); continue; } // fade out the energy bursts -- eh... don't /* if ( mp->markShader == cgs.media.energyMarkShader ) { fade = 450 - 450 * ( (cg.time - mp->time ) / 3000.0 ); if ( fade < 255 ) { if ( fade < 0 ) { fade = 0; } if ( mp->verts[0].modulate[0] != 0 ) { for ( j = 0 ; j < mp->poly.numVerts ; j++ ) { mp->verts[j].modulate[0] = mp->color[0] * fade; mp->verts[j].modulate[1] = mp->color[1] * fade; mp->verts[j].modulate[2] = mp->color[2] * fade; } } } } */ // trippy marks :) if ( mp->markShader == cgs.media.energyMarkShader && cgs.valkyrMode ) { k = ( mp->time / 4 + cg.time / 4 ) % 256; for ( j = 0 ; j < mp->poly.numVerts ; j++ ) { mp->verts[j].modulate[0] = trippyColors[k].red; mp->verts[j].modulate[1] = trippyColors[k].green; mp->verts[j].modulate[2] = trippyColors[k].blue; } } // fade all marks out with time t = mp->time + MARK_TOTAL_TIME - cg.time; if ( t < MARK_FADE_TIME ) { fade = 255 * t / MARK_FADE_TIME; if ( mp->alphaFade ) { for ( j = 0 ; j < mp->poly.numVerts ; j++ ) { mp->verts[j].modulate[3] = fade; } } else { for ( j = 0 ; j < mp->poly.numVerts ; j++ ) { mp->verts[j].modulate[0] = mp->color[0] * fade; mp->verts[j].modulate[1] = mp->color[1] * fade; mp->verts[j].modulate[2] = mp->color[2] * fade; } } } trap_R_AddPolyToScene( mp->markShader, mp->poly.numVerts, mp->verts ); } }
void CG_ImpactMark( qhandle_t markShader, const vec3_t origin, const vec3_t dir, float orientation, float red, float green, float blue, float alpha, qboolean alphaFade, float radius, qboolean temporary ) { vec3_t axis[3]; float texCoordScale; vec3_t originalPoints[4]; byte colors[4]; int i, j; int numFragments; markFragment_t markFragments[MAX_MARK_FRAGMENTS], *mf; vec3_t markPoints[MAX_MARK_POINTS]; vec3_t projection; markPoly_t *mp, *next; vec3_t delta; if ( !cg_addMarks.integer ) { return; } if ( radius <= 0 ) { CG_Error( "CG_ImpactMark called with <= 0 radius" ); } //if ( markTotal >= MAX_MARK_POLYS ) { // return; //} // HERBY: Bubble G overdraw fix mp = cg_activeMarkPolys.nextMark; for ( ; mp != &cg_activeMarkPolys; mp = next ) { next = mp->nextMark; if(temporary) break; // keep all marks if the new one is just the shadow if(mp->markShader == cgs.media.SchaumShader) continue;//die slick-ents einfach übergehen VectorSubtract( mp->origin, origin, delta ); if ( radius <= mp->radius + 4 && VectorLength( delta ) < ( radius + mp->radius ) * MIN_MARK_DISTANCE ) { CG_FreeMarkPoly( mp ); } } // create the texture axis VectorNormalize2( dir, axis[0] ); PerpendicularVector( axis[1], axis[0] ); RotatePointAroundVector( axis[2], axis[0], axis[1], orientation ); CrossProduct( axis[0], axis[2], axis[1] ); texCoordScale = 0.5 * 1.0 / radius; // create the full polygon for ( i = 0 ; i < 3 ; ++i ) { originalPoints[0][i] = origin[i] - radius * axis[1][i] - radius * axis[2][i]; originalPoints[1][i] = origin[i] + radius * axis[1][i] - radius * axis[2][i]; originalPoints[2][i] = origin[i] + radius * axis[1][i] + radius * axis[2][i]; originalPoints[3][i] = origin[i] - radius * axis[1][i] + radius * axis[2][i]; } // get the fragments VectorScale( dir, -20, projection ); numFragments = trap_CM_MarkFragments( 4, (void *)originalPoints, projection, MAX_MARK_POINTS, markPoints[0], MAX_MARK_FRAGMENTS, markFragments ); if(!numFragments && markShader == cgs.media.SchaumShader) { numFragments = 1; markFragments->firstPoint = 0; markFragments->numPoints = 4; for(i=0;i<4;++i) VectorCopy(originalPoints[i],markPoints[i]); } colors[0] = red * 255; colors[1] = green * 255; colors[2] = blue * 255; colors[3] = alpha * 255; for ( i = 0, mf = markFragments ; i < numFragments ; i++, mf++ ) { polyVert_t *v; polyVert_t verts[MAX_VERTS_ON_POLY]; markPoly_t *mark; // we have an upper limit on the complexity of polygons // that we store persistantly if ( mf->numPoints > MAX_VERTS_ON_POLY ) { mf->numPoints = MAX_VERTS_ON_POLY; } for ( j = 0, v = verts ; j < mf->numPoints ; j++, v++ ) { vec3_t delta; VectorCopy( markPoints[mf->firstPoint + j], v->xyz ); VectorSubtract( v->xyz, origin, delta ); v->st[0] = 0.5 + DotProduct( delta, axis[1] ) * texCoordScale; v->st[1] = 0.5 + DotProduct( delta, axis[2] ) * texCoordScale; *(int *)v->modulate = *(int *)colors; } // if it is a temporary (shadow) mark, add it immediately and forget about it if ( temporary ) { trap_R_AddPolyToScene( markShader, mf->numPoints, verts ); continue; } // otherwise save it persistantly mark = CG_AllocMark(); mark->time = cg.time; mark->alphaFade = alphaFade; mark->markShader = markShader; mark->poly.numVerts = mf->numPoints; mark->color[0] = red; mark->color[1] = green; mark->color[2] = blue; mark->color[3] = alpha; mark->radius = radius; VectorCopy( origin, mark->origin ); memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) ); markTotal++; } }
void CG_AddMarks( void ) { int j; markPoly_t *mp, *next; int t; int fade; if ( !cg_addMarks.integer ) { return; } mp = cg_activeMarkPolys.nextMark; for ( ; mp != &cg_activeMarkPolys ; mp = next ) { // grab next now, so if the local entity is freed we // still have it next = mp->nextMark; // see if it is time to completely remove it if ( cg.time > mp->time + MARK_TOTAL_TIME ) { CG_FreeMarkPoly( mp ); continue; } // fade out the energy bursts #ifdef IOQ3ZTM // IOQ3BUGFIX: Use alphaFade instead of shader num (As only energyMark used alphaFade) if ( mp->alphaFade ) #else if ( mp->markShader == cgs.media.energyMarkShader ) #endif { fade = 450 - 450 * ( (cg.time - mp->time ) / 3000.0 ); if ( fade < 255 ) { if ( fade < 0 ) { fade = 0; } if ( mp->verts[0].modulate[0] != 0 ) { for ( j = 0 ; j < mp->numVerts ; j++ ) { mp->verts[j].modulate[0] = mp->color[0] * fade; mp->verts[j].modulate[1] = mp->color[1] * fade; mp->verts[j].modulate[2] = mp->color[2] * fade; } } } } // fade all marks out with time t = mp->time + MARK_TOTAL_TIME - cg.time; if ( t < MARK_FADE_TIME ) { fade = 255 * t / MARK_FADE_TIME; if ( mp->alphaFade ) { for ( j = 0 ; j < mp->numVerts ; j++ ) { mp->verts[j].modulate[3] = fade; } } else { for ( j = 0 ; j < mp->numVerts ; j++ ) { mp->verts[j].modulate[0] = mp->color[0] * fade; mp->verts[j].modulate[1] = mp->color[1] * fade; mp->verts[j].modulate[2] = mp->color[2] * fade; } } } trap_R_AddPolyToScene( mp->markShader, mp->numVerts, mp->verts, mp->bmodelNum, 0 ); } }