void FXTrail::Draw( void ) { vec3_t lineDir, cross, viewDir; polyVert_t verts[4]; float scale; VectorSubtract( m_oldorigin, m_origin, lineDir ); VectorSubtract( m_oldorigin, cg.refdef.vieworg, viewDir ); CrossProduct( lineDir, viewDir, cross ); VectorNormalize( cross ); scale = m_scale * 0.5; //Construct the oriented quad VectorMA( m_origin, -scale, cross, verts[0].xyz ); verts[0].st[0] = 0.0f; verts[0].st[1] = 0.0f; verts[0].modulate[0] = m_RGB[0] * 255; verts[0].modulate[1] = m_RGB[1] * 255; verts[0].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin, scale, cross, verts[1].xyz ); verts[1].st[0] = 1.0f; verts[1].st[1] = 0.0f; verts[1].modulate[0] = m_RGB[0] * 255; verts[1].modulate[1] = m_RGB[1] * 255; verts[1].modulate[2] = m_RGB[2] * 255; VectorMA( m_oldorigin, scale, cross, verts[2].xyz ); verts[2].st[0] = 1.0f; verts[2].st[1] = 1.0f; verts[2].modulate[0] = m_RGB[0] * 255; verts[2].modulate[1] = m_RGB[1] * 255; verts[2].modulate[2] = m_RGB[2] * 255; VectorMA( m_oldorigin, -scale, cross, verts[3].xyz ); verts[3].st[0] = 0.0f; verts[3].st[1] = 1.0f; verts[3].modulate[0] = m_RGB[0] * 255; verts[3].modulate[1] = m_RGB[1] * 255; verts[3].modulate[2] = m_RGB[2] * 255; if ( m_flags & FXF_USE_ALPHA_CHAN ) { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = (byte)(m_alpha * 255); } else { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = 255; } cgi_R_AddPolyToScene( m_shader, 4, verts ); }
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 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 { float f = (float)t / MARK_FADE_TIME; for ( j = 0 ; j < mp->poly.numVerts ; j++ ) { mp->verts[j].modulate[0] = mp->color[0] * f; mp->verts[j].modulate[1] = mp->color[1] * f; mp->verts[j].modulate[2] = mp->color[2] * f; } } } else { for ( j = 0 ; j < mp->poly.numVerts ; j++ ) { mp->verts[j].modulate[0] = mp->color[0]; mp->verts[j].modulate[1] = mp->color[1]; mp->verts[j].modulate[2] = mp->color[2]; } } cgi_R_AddPolyToScene( mp->markShader, mp->poly.numVerts, mp->verts ); } }
void FXTri::Draw( void ) { polyVert_t verts[3]; //Construct the tri VectorCopy( m_origin, verts[0].xyz ); verts[0].st[0] = 0.0f; verts[0].st[1] = 0.0f; verts[0].modulate[0] = m_RGB[0] * 255; verts[0].modulate[1] = m_RGB[1] * 255; verts[0].modulate[2] = m_RGB[2] * 255; VectorCopy( m_origin2, verts[1].xyz ); verts[1].st[0] = 1.0f; verts[1].st[1] = 0.0f; verts[1].modulate[0] = m_RGB[0] * 255; verts[1].modulate[1] = m_RGB[1] * 255; verts[1].modulate[2] = m_RGB[2] * 255; VectorCopy( m_origin3, verts[2].xyz ); verts[2].st[0] = 1.0f; verts[2].st[1] = 1.0f; verts[2].modulate[0] = m_RGB[0] * 255; verts[2].modulate[1] = m_RGB[1] * 255; verts[2].modulate[2] = m_RGB[2] * 255; if ( m_flags & FXF_USE_ALPHA_CHAN ) { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = (byte)(m_alpha * 255); } else { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = 255; } cgi_R_AddPolyToScene( m_shader, 3, verts ); }
void FXParticle::Draw( void ) { polyVert_t verts[4]; vec3_t axis[3]; float scale; int i; if ( m_flags & FXF_NODRAW ) return; scale = m_scale * 0.5f; for ( i = 0; i < 3; i++ ) VectorCopy( cg.refdef.viewaxis[i], axis[i] ); //This is done to spare non-rolling particles the odd angle snapping <?> if (m_roll) RotateAroundDirection( axis, m_roll ); for ( i = 0; i < 4; i++ ) { VectorMA( m_origin, sprite_template[i][0] * scale, axis[1], verts[i].xyz ); VectorMA( verts[i].xyz, sprite_template[i][1] * scale, axis[2], verts[i].xyz ); //Setup the UVs verts[i].st[0] = sprite_texture_template[i][0]; verts[i].st[1] = sprite_texture_template[i][1]; //Setup the vertex modulation verts[i].modulate[0] = (byte)(m_RGB[0] * 255); verts[i].modulate[1] = (byte)(m_RGB[1] * 255); verts[i].modulate[2] = (byte)(m_RGB[2] * 255); if ( m_flags & FXF_USE_ALPHA_CHAN ) verts[i].modulate[3] = (byte)(m_alpha * 255); else verts[i].modulate[3] = 255; } //Add it into the renderer cgi_R_AddPolyToScene( m_shader, 4, verts ); }
// create a sprite that doesn't use a refEnt. Currently only for use with the DebugNav drawing so it doesn't have to use fx //------------------------------------------ static void CG_AddSprite( localEntity_t *le ) { polyVert_t verts[4]; VectorCopy( le->refEntity.origin, verts[0].xyz ); VectorMA( verts[0].xyz, -le->radius, cg.refdef.viewaxis[2], verts[0].xyz ); VectorMA( verts[0].xyz, -le->radius, cg.refdef.viewaxis[1], verts[0].xyz ); verts[0].st[0] = 0; verts[0].st[1] = 0; for ( int i = 0; i < 4; i++ ) { verts[i].modulate[0] = le->color[0]; verts[i].modulate[1] = le->color[1]; verts[i].modulate[2] = le->color[2]; verts[i].modulate[3] = le->color[3]; } VectorCopy( le->refEntity.origin, verts[1].xyz ); VectorMA( verts[1].xyz, -le->radius, cg.refdef.viewaxis[2], verts[1].xyz ); VectorMA( verts[1].xyz, le->radius, cg.refdef.viewaxis[1], verts[1].xyz ); verts[1].st[0] = 0; verts[1].st[1] = 1; VectorCopy( le->refEntity.origin, verts[2].xyz ); VectorMA( verts[2].xyz, le->radius, cg.refdef.viewaxis[2], verts[2].xyz ); VectorMA( verts[2].xyz, le->radius, cg.refdef.viewaxis[1], verts[2].xyz ); verts[2].st[0] = 1; verts[2].st[1] = 1; VectorCopy( le->refEntity.origin, verts[3].xyz ); VectorMA( verts[3].xyz, le->radius, cg.refdef.viewaxis[2], verts[3].xyz ); VectorMA( verts[3].xyz, -le->radius, cg.refdef.viewaxis[1], verts[3].xyz ); verts[3].st[0] = 1; verts[3].st[1] = 0; cgi_R_AddPolyToScene( le->refEntity.customShader, 4, verts ); }
// create a quad that doesn't use a refEnt. Currently only for use with the DebugNav drawing so it doesn't have to use fx //------------------------------------------ static void CG_AddQuad( localEntity_t *le ) { polyVert_t verts[4]; VectorCopy( le->refEntity.origin, verts[0].xyz ); verts[0].xyz[0] -= le->radius; verts[0].xyz[1] -= le->radius; verts[0].st[0] = 0; verts[0].st[1] = 0; for ( int i = 0; i < 4; i++ ) { verts[i].modulate[0] = le->color[0]; verts[i].modulate[1] = le->color[1]; verts[i].modulate[2] = le->color[2]; verts[i].modulate[3] = le->color[3]; } VectorCopy( le->refEntity.origin, verts[1].xyz ); verts[1].xyz[0] -= le->radius; verts[1].xyz[1] += le->radius; verts[1].st[0] = 0; verts[1].st[1] = 1; VectorCopy( le->refEntity.origin, verts[2].xyz ); verts[2].xyz[0] += le->radius; verts[2].xyz[1] += le->radius; verts[2].st[0] = 1; verts[2].st[1] = 1; VectorCopy( le->refEntity.origin, verts[3].xyz ); verts[3].xyz[0] += le->radius; verts[3].xyz[1] -= le->radius; verts[3].st[0] = 1; verts[3].st[1] = 0; cgi_R_AddPolyToScene( le->refEntity.customShader, 4, verts ); }
void FXQuad::Draw( void ) { polyVert_t verts[NUM_QUADVERTS]; vec3_t vr, vu; vec3_t axis[3]; float scale; int i; scale = m_scale * 0.5f; MakeNormalVectors( m_normal, vr, vu ); VectorCopy( m_normal, axis[0] ); VectorCopy( vr, axis[1] ); VectorCopy( vu, axis[2] ); RotateAroundDirection( axis, m_roll ); //Construct the quad for ( i = 0; i < NUM_QUADVERTS; i++ ) { VectorMA( m_origin, quad_template[i][0] * ( scale ), axis[1], verts[i].xyz ); VectorMA( verts[i].xyz, quad_template[i][1] * ( scale ), axis[2], verts[i].xyz ); verts[i].modulate[0] = m_RGB[0] * 255; verts[i].modulate[1] = m_RGB[1] * 255; verts[i].modulate[2] = m_RGB[2] * 255; if ( m_flags & FXF_USE_ALPHA_CHAN ) verts[i].modulate[3] = (byte)(m_alpha * 255); else verts[i].modulate[3] = 255; verts[i].st[0] = quad_st_template[i][0]; verts[i].st[1] = quad_st_template[i][1]; } cgi_R_AddPolyToScene( m_shader, NUM_QUADVERTS, verts ); }
//------------------------------------------------------ void SFxHelper::AddPolyToScene( int shader, int count, polyVert_t *verts ) { cgi_R_AddPolyToScene( shader, count, verts ); }
//---------------------------- inline void CBezier::DrawSegment( vec3_t start, vec3_t end, float texcoord1, float texcoord2 ) { vec3_t lineDir, cross, viewDir; static vec3_t lastEnd[2]; polyVert_t verts[4]; float scale; VectorSubtract( end, start, lineDir ); VectorSubtract( end, cg.refdef.vieworg, viewDir ); CrossProduct( lineDir, viewDir, cross ); VectorNormalize( cross ); scale = mRefEnt.radius * 0.5f; //Construct the oriented quad if ( mInit ) { VectorCopy( lastEnd[0], verts[0].xyz ); VectorCopy( lastEnd[1], verts[1].xyz ); } else { VectorMA( start, -scale, cross, verts[0].xyz ); VectorMA( start, scale, cross, verts[1].xyz ); } verts[0].st[0] = 0.0f; verts[0].st[1] = texcoord1; verts[0].modulate[0] = mRefEnt.shaderRGBA[0] * ( 1.0f - texcoord1 ); verts[0].modulate[1] = mRefEnt.shaderRGBA[1] * ( 1.0f - texcoord1 ); verts[0].modulate[2] = mRefEnt.shaderRGBA[2] * ( 1.0f - texcoord1 ); verts[0].modulate[3] = mRefEnt.shaderRGBA[3]; verts[1].st[0] = 1.0f; verts[1].st[1] = texcoord1; verts[1].modulate[0] = mRefEnt.shaderRGBA[0] * ( 1.0f - texcoord1 ); verts[1].modulate[1] = mRefEnt.shaderRGBA[1] * ( 1.0f - texcoord1 ); verts[1].modulate[2] = mRefEnt.shaderRGBA[2] * ( 1.0f - texcoord1 ); verts[1].modulate[3] = mRefEnt.shaderRGBA[3]; if ( texcoord1 == 0.0f ) { verts[0].modulate[0] = 0; verts[0].modulate[1] = 0; verts[0].modulate[2] = 0; verts[0].modulate[3] = 0; verts[1].modulate[0] = 0; verts[1].modulate[1] = 0; verts[1].modulate[2] = 0; verts[1].modulate[3] = 0; } VectorMA( end, scale, cross, verts[2].xyz ); verts[2].st[0] = 1.0f; verts[2].st[1] = texcoord2; verts[2].modulate[0] = mRefEnt.shaderRGBA[0] * ( 1.0f - texcoord2 ); verts[2].modulate[1] = mRefEnt.shaderRGBA[1] * ( 1.0f - texcoord2 ); verts[2].modulate[2] = mRefEnt.shaderRGBA[2] * ( 1.0f - texcoord2 ); verts[2].modulate[3] = mRefEnt.shaderRGBA[3]; VectorMA( end, -scale, cross, verts[3].xyz ); verts[3].st[0] = 0.0f; verts[3].st[1] = texcoord2; verts[3].modulate[0] = mRefEnt.shaderRGBA[0] * ( 1.0f - texcoord2 ); verts[3].modulate[1] = mRefEnt.shaderRGBA[1] * ( 1.0f - texcoord2 ); verts[3].modulate[2] = mRefEnt.shaderRGBA[2] * ( 1.0f - texcoord2 ); verts[3].modulate[3] = mRefEnt.shaderRGBA[3]; cgi_R_AddPolyToScene( mRefEnt.customShader, 4, verts ); VectorCopy( verts[2].xyz, lastEnd[1] ); VectorCopy( verts[3].xyz, lastEnd[0] ); mInit = true; }
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; if ( !cg_addMarks.integer ) { return; } if ( radius <= 0 ) { CG_Error( "CG_ImpactMark called with <= 0 radius" ); } // 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 = cgi_CM_MarkFragments( 4, (const float (*)[3])originalPoints, projection, MAX_MARK_POINTS, markPoints[0], MAX_MARK_FRAGMENTS, markFragments ); 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; for ( int k = 0; k < 4; k++ ) { v->modulate[k] = colors[k]; } } // if it is a temporary (shadow) mark, add it immediately and forget about it if ( temporary ) { cgi_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] = colors[0];//red; mark->color[1] = colors[1];//green; mark->color[2] = colors[2];//blue; mark->color[3] = colors[3];//alpha; memcpy( mark->verts, verts, mf->numPoints * sizeof( verts[0] ) ); } }
void FXLine::Draw( void ) { vec3_t lineDir, cross, viewDir, neworg; polyVert_t verts[4]; float scale; VectorSubtract( m_origin2, m_origin, lineDir ); VectorSubtract( m_origin2, cg.refdef.vieworg, viewDir ); CrossProduct( lineDir, viewDir, cross ); VectorNormalize( cross ); scale = m_scale * 0.5; //Construct the oriented quad VectorMA( m_origin, -scale, cross, verts[0].xyz ); verts[0].st[0] = 0.0f; verts[0].st[1] = 0.0f; verts[0].modulate[0] = m_RGB[0] * 255; verts[0].modulate[1] = m_RGB[1] * 255; verts[0].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin, scale, cross, verts[1].xyz ); verts[1].st[0] = 1.0f; verts[1].st[1] = 0.0f; verts[1].modulate[0] = m_RGB[0] * 255; verts[1].modulate[1] = m_RGB[1] * 255; verts[1].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin2, scale, cross, verts[2].xyz ); verts[2].st[0] = 1.0f; verts[2].st[1] = m_stScale; verts[2].modulate[0] = m_RGB[0] * 255; verts[2].modulate[1] = m_RGB[1] * 255; verts[2].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin2, -scale, cross, verts[3].xyz ); verts[3].st[0] = 0.0f; verts[3].st[1] = m_stScale; verts[3].modulate[0] = m_RGB[0] * 255; verts[3].modulate[1] = m_RGB[1] * 255; verts[3].modulate[2] = m_RGB[2] * 255; if ( m_flags & FXF_USE_ALPHA_CHAN ) { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = (byte)(m_alpha * 255); } else { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = 255; } cgi_R_AddPolyToScene( m_shader, 4, verts ); //Cap the lines if ( m_flags & FXF_DRAWCAPS ) { //Construct an oriented quad for the endcap VectorMA( m_origin, scale, cross, verts[0].xyz ); verts[0].st[0] = 0.0f; verts[0].st[1] = 0.02f; verts[0].modulate[0] = m_RGB[0] * 255; verts[0].modulate[1] = m_RGB[1] * 255; verts[0].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin, -scale, cross, verts[1].xyz ); verts[1].st[0] = 1.0f; verts[1].st[1] = 0.1f; verts[1].modulate[0] = m_RGB[0] * 255; verts[1].modulate[1] = m_RGB[1] * 255; verts[1].modulate[2] = m_RGB[2] * 255; VectorNormalize( lineDir ); VectorMA( m_origin, -scale * 2, lineDir, neworg ); VectorMA( neworg, -scale, cross, verts[2].xyz ); verts[2].st[0] = 1.0f; verts[2].st[1] = 0.9f; verts[2].modulate[0] = m_RGB[0] * 255; verts[2].modulate[1] = m_RGB[1] * 255; verts[2].modulate[2] = m_RGB[2] * 255; VectorMA( neworg, scale, cross, verts[3].xyz ); verts[3].st[0] = 0.0f; verts[3].st[1] = 0.9f; verts[3].modulate[0] = m_RGB[0] * 255; verts[3].modulate[1] = m_RGB[1] * 255; verts[3].modulate[2] = m_RGB[2] * 255; if ( m_flags & FXF_USE_ALPHA_CHAN ) { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = (byte)(m_alpha * 255); } else { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = 255; } cgi_R_AddPolyToScene( m_endcap_shader, 4, verts ); //Construct an oriented quad for the endcap VectorMA( m_origin2, -scale, cross, verts[0].xyz ); verts[0].st[0] = 0.0f; verts[0].st[1] = 0.1f; verts[0].modulate[0] = m_RGB[0] * 255; verts[0].modulate[1] = m_RGB[1] * 255; verts[0].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin2, scale, cross, verts[1].xyz ); verts[1].st[0] = 1.0f; verts[1].st[1] = 0.05f; verts[1].modulate[0] = m_RGB[0] * 255; verts[1].modulate[1] = m_RGB[1] * 255; verts[1].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin2, scale * 2, lineDir, neworg ); VectorMA( neworg, scale, cross, verts[2].xyz ); verts[2].st[0] = 1.0f; verts[2].st[1] = 0.9f; verts[2].modulate[0] = m_RGB[0] * 255; verts[2].modulate[1] = m_RGB[1] * 255; verts[2].modulate[2] = m_RGB[2] * 255; VectorMA( neworg, -scale, cross, verts[3].xyz ); verts[3].st[0] = 0.0f; verts[3].st[1] = 0.9f; verts[3].modulate[0] = m_RGB[0] * 255; verts[3].modulate[1] = m_RGB[1] * 255; verts[3].modulate[2] = m_RGB[2] * 255; if ( m_flags & FXF_USE_ALPHA_CHAN ) { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = (byte)(m_alpha * 255); } else { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = 255; } cgi_R_AddPolyToScene( m_endcap_shader, 4, verts ); } }
inline void FXElectricity::DrawSegment( vec3_t start, vec3_t end, float scale, float tcStart, float tcEnd ) { vec3_t lineDir, cross, viewDir; polyVert_t verts[4]; VectorSubtract( end, start, lineDir ); VectorSubtract( end, cg.refdef.vieworg, viewDir ); CrossProduct( lineDir, viewDir, cross ); VectorNormalize( cross ); scale *= 0.5; //Construct the oriented quad if ( m_init ) VectorCopy( m_lastEnd[0], verts[0].xyz ); else VectorMA( start, -scale, cross, verts[0].xyz ); verts[0].st[0] = 0.0f; verts[0].st[1] = tcStart; verts[0].modulate[0] = m_RGB[0] * 255; verts[0].modulate[1] = m_RGB[1] * 255; verts[0].modulate[2] = m_RGB[2] * 255; if ( m_init ) VectorCopy( m_lastEnd[1], verts[1].xyz ); else VectorMA( start, scale, cross, verts[1].xyz ); verts[1].st[0] = 1.0f; verts[1].st[1] = tcStart; verts[1].modulate[0] = m_RGB[0] * 255; verts[1].modulate[1] = m_RGB[1] * 255; verts[1].modulate[2] = m_RGB[2] * 255; VectorMA( end, scale, cross, verts[2].xyz ); verts[2].st[0] = 1.0f; verts[2].st[1] = tcEnd; verts[2].modulate[0] = m_RGB[0] * 255; verts[2].modulate[1] = m_RGB[1] * 255; verts[2].modulate[2] = m_RGB[2] * 255; VectorMA( end, -scale, cross, verts[3].xyz ); verts[3].st[0] = 0.0f; verts[3].st[1] = tcEnd; verts[3].modulate[0] = m_RGB[0] * 255; verts[3].modulate[1] = m_RGB[1] * 255; verts[3].modulate[2] = m_RGB[2] * 255; if ( m_flags & FXF_USE_ALPHA_CHAN ) { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = (byte)(m_alpha * 255); } else { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = 255; } cgi_R_AddPolyToScene( m_shader, 4, verts ); VectorCopy( verts[2].xyz, m_lastEnd[1] ); VectorCopy( verts[3].xyz, m_lastEnd[0] ); m_init = true; }
void FXCylinder::Draw( void ) { polyVert_t lower_points[NUM_CYLINDER_SEGMENTS], upper_points[NUM_CYLINDER_SEGMENTS], verts[4]; vec3_t vr, vu, vu2, midpoint, origin2; float detail, length; int i; int segments; // allow for overriding the LOD mechanism, not recommended, but hey, flexibility is often cool... if ( m_flags & FXF_NO_LOD ) { segments = NUM_CYLINDER_SEGMENTS; } else { //Work out the detail level of this cylinder VectorMA( m_origin, m_height * 0.5, m_normal, midpoint ); VectorSubtract( midpoint, cg.refdef.vieworg, midpoint ); length = VectorLengthSquared( midpoint ); detail = 1 - (length / (1024.0*1024.0) ); // FIXME: the bias doesn't really work all that great //Cylinder bias is simply implemented as a multiplier segments = NUM_CYLINDER_SEGMENTS * detail * m_bias; // 3 is the absolute minimum, but the pop between 3, 4 and 5 is too noticeable if ( segments < 7 ) { segments = 7; } if ( segments > NUM_CYLINDER_SEGMENTS ) { segments = NUM_CYLINDER_SEGMENTS; } } //Get the direction vector MakeNormalVectors( m_normal, vr, vu ); VectorScale( vu, m_scale2 * 0.5, vu2 ); VectorScale( vu, m_scale * 0.5, vu ); VectorMA( m_origin, m_height, m_normal, origin2 ); // Calculate the step around the cylinder detail = 360.0 / (float)segments; for ( i = 0; i < segments ; i++ ) { //Upper ring RotatePointAroundVector( upper_points[i].xyz, m_normal, vu, detail * i ); VectorAdd( upper_points[i].xyz, m_origin, upper_points[i].xyz ); //Lower ring RotatePointAroundVector( lower_points[i].xyz, m_normal, vu2, detail * i ); VectorAdd( lower_points[i].xyz, origin2, lower_points[i].xyz ); } // Calculate the texture coords so the texture can wrap around the whole cylinder if ( m_flags & FXF_WRAP ) { if ( m_flags & FXF_STRETCH ) detail = 1.0f / (float)segments; else detail = m_stScale / (float)segments; } for ( i = 0; i < segments ; i++ ) { int nextSegment = ( i + 1 == segments ) ? 0 : i + 1; if ( m_flags & FXF_WRAP ) { verts[0].st[0] = detail * i; verts[1].st[0] = detail * i; verts[2].st[0] = detail * ( i + 1 ); verts[3].st[0] = detail * ( i + 1 ); } else { verts[0].st[0] = 0.0f; verts[1].st[0] = 0.0f; verts[2].st[0] = m_stScale; verts[3].st[0] = m_stScale; } if( m_flags & FXF_STRETCH ) { verts[0].st[1] = m_stScale; verts[1].st[1] = 0.0f; verts[2].st[1] = 0.0f; verts[3].st[1] = m_stScale; } else { verts[0].st[1] = 1.0f; verts[1].st[1] = 0.0f; verts[2].st[1] = 0.0f; verts[3].st[1] = 1.0f; } VectorCopy( upper_points[i].xyz, verts[0].xyz ); verts[0].modulate[0] = m_RGB[0] * 255; verts[0].modulate[1] = m_RGB[1] * 255; verts[0].modulate[2] = m_RGB[2] * 255; VectorCopy( lower_points[i].xyz, verts[1].xyz ); verts[1].modulate[0] = m_RGB[0] * 255; verts[1].modulate[1] = m_RGB[1] * 255; verts[1].modulate[2] = m_RGB[2] * 255; VectorCopy( lower_points[nextSegment].xyz, verts[2].xyz ); verts[2].modulate[0] = m_RGB[0] * 255; verts[2].modulate[1] = m_RGB[1] * 255; verts[2].modulate[2] = m_RGB[2] * 255; VectorCopy( upper_points[nextSegment].xyz, verts[3].xyz ); verts[3].modulate[0] = m_RGB[0] * 255; verts[3].modulate[1] = m_RGB[1] * 255; verts[3].modulate[2] = m_RGB[2] * 255; if ( m_flags & FXF_USE_ALPHA_CHAN ) { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = (byte)(m_alpha * 255); } else { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = 255; } cgi_R_AddPolyToScene( m_shader, 4, verts ); } }
void FXLine2::Draw( void ) { #if 0 vec3_t lineDir, cross, viewDir; polyVert_t verts[4]; float scale, scale2; VectorSubtract( m_origin2, m_origin, lineDir ); VectorSubtract( m_origin2, cg.refdef.vieworg, viewDir ); CrossProduct( lineDir, viewDir, cross ); VectorNormalize( cross ); scale = m_scale * 0.5f; scale2 = m_scale2 * 0.5f; //Construct the oriented quad VectorMA( m_origin, -scale, cross, verts[0].xyz ); verts[0].st[0] = 0.0f; verts[0].st[1] = 0.0f; verts[0].modulate[0] = m_RGB[0] * 255; verts[0].modulate[1] = m_RGB[1] * 255; verts[0].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin, scale, cross, verts[1].xyz ); verts[1].st[0] = 1.0f; verts[1].st[1] = 0.0f; verts[1].modulate[0] = m_RGB[0] * 255; verts[1].modulate[1] = m_RGB[1] * 255; verts[1].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin2, scale2, cross, verts[2].xyz ); verts[2].st[0] = 1.0f; verts[2].st[1] = m_stScale; verts[2].modulate[0] = m_RGB[0] * 255; verts[2].modulate[1] = m_RGB[1] * 255; verts[2].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin2, -scale2, cross, verts[3].xyz ); verts[3].st[0] = 0.0f; verts[3].st[1] = m_stScale; verts[3].modulate[0] = m_RGB[0] * 255; verts[3].modulate[1] = m_RGB[1] * 255; verts[3].modulate[2] = m_RGB[2] * 255; if ( m_flags & FXF_USE_ALPHA_CHAN ) { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = (byte)(m_alpha * 255); } else { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = 255; } cgi_R_AddPolyToScene( m_shader, 4, verts ); #else vec3_t lineDir, cross, viewDir; polyVert_t verts[4]; float scale, scale2; VectorSubtract( m_origin2, m_origin, lineDir ); VectorSubtract( m_origin2, cg.refdef.vieworg, viewDir ); CrossProduct( lineDir, viewDir, cross ); VectorNormalize( cross ); scale = m_scale * 0.5f; scale2 = m_scale2 * 0.5f; if ( m_flags & FXF_USE_ALPHA_CHAN ) { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = (byte)(m_alpha * 255); } else { verts[0].modulate[3] = verts[1].modulate[3] = verts[2].modulate[3] = verts[3].modulate[3] = 255; } //Construct the tapered, oriented quad, we have to use 3 tris to do this though VectorCopy( m_origin, verts[0].xyz ); verts[0].st[0] = 0.5f; verts[0].st[1] = 0.0f; verts[0].modulate[0] = m_RGB[0] * 255; verts[0].modulate[1] = m_RGB[1] * 255; verts[0].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin2, -scale2, cross, verts[1].xyz ); verts[1].st[0] = 1.0f; verts[1].st[1] = m_stScale; verts[1].modulate[0] = m_RGB[0] * 255; verts[1].modulate[1] = m_RGB[1] * 255; verts[1].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin2, scale2, cross, verts[2].xyz ); verts[2].st[0] = 0.0f; verts[2].st[1] = m_stScale; verts[2].modulate[0] = m_RGB[0] * 255; verts[2].modulate[1] = m_RGB[1] * 255; verts[2].modulate[2] = m_RGB[2] * 255; cgi_R_AddPolyToScene( m_shader, 3, verts ); VectorCopy( m_origin, verts[0].xyz ); verts[0].st[0] = 0.5f; verts[0].st[1] = 0.0f; VectorMA( m_origin2, -scale2, cross, verts[1].xyz ); verts[1].st[0] = 0.0f; verts[1].st[1] = m_stScale; VectorMA( m_origin, -scale, cross, verts[2].xyz ); verts[2].st[0] = 0.0f; verts[2].st[1] = m_stScale; cgi_R_AddPolyToScene( m_shader, 3, verts ); VectorCopy( m_origin, verts[0].xyz ); verts[0].st[0] = 0.5f; verts[0].st[1] = 0.0f; VectorMA( m_origin2, scale2, cross, verts[1].xyz ); verts[1].st[0] = 0.0f; verts[1].st[1] = m_stScale; VectorMA( m_origin, scale, cross, verts[2].xyz ); verts[2].st[0] = 0.0f; verts[2].st[1] = m_stScale; cgi_R_AddPolyToScene( m_shader, 3, verts ); /* VectorMA( m_origin, scale, cross, verts[1].xyz ); verts[1].st[0] = 1.0f; verts[1].st[1] = 0.0f; verts[1].modulate[0] = m_RGB[0] * 255; verts[1].modulate[1] = m_RGB[1] * 255; verts[1].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin2, scale2, cross, verts[2].xyz ); verts[2].st[0] = 1.0f; verts[2].st[1] = m_stScale; verts[2].modulate[0] = m_RGB[0] * 255; verts[2].modulate[1] = m_RGB[1] * 255; verts[2].modulate[2] = m_RGB[2] * 255; VectorMA( m_origin2, -scale2, cross, verts[3].xyz ); verts[3].st[0] = 0.0f; verts[3].st[1] = m_stScale; verts[3].modulate[0] = m_RGB[0] * 255; verts[3].modulate[1] = m_RGB[1] * 255; verts[3].modulate[2] = m_RGB[2] * 255; cgi_R_AddPolyToScene( m_shader, 4, verts ); */ #endif }