void CEngineSprite::SetFrame( RenderMode_t nRenderMode, int nFrame ) { if ( IsAVI() ) { avi->SetFrame( m_hAVIMaterial, nFrame ); return; } #if !defined( _X360 ) || defined( BINK_ENABLED_FOR_X360 ) if ( IsBIK() ) { bik->SetFrame( m_hBIKMaterial, nFrame ); return; } #endif IMaterial *pMaterial = m_material[nRenderMode]; if ( !pMaterial ) return; IMaterialVar* pFrameVar = pMaterial->FindVarFast( "$frame", &frameCache ); if ( pFrameVar ) { pFrameVar->SetIntValue( nFrame ); } }
IMaterial *CEngineSprite::GetMaterial( RenderMode_t nRenderMode, int nFrame ) { if ( nRenderMode == kRenderNone || nRenderMode == kRenderEnvironmental ) return NULL; if ( IsAVI() ) { avi->SetFrame( m_hAVIMaterial, nFrame ); return m_material[ 0 ]; // render mode is ignored for avi } #if !defined( _X360 ) || defined( BINK_ENABLED_FOR_X360 ) if ( IsBIK() ) { bik->SetFrame( m_hBIKMaterial, nFrame ); return m_material[ 0 ]; // render mode is ignored for bink } #endif IMaterial *pMaterial = m_material[nRenderMode]; Assert( pMaterial ); if ( pMaterial == NULL ) return NULL; IMaterialVar* pFrameVar = pMaterial->FindVarFast( "$frame", &frameCache ); if ( pFrameVar ) { pFrameVar->SetIntValue( nFrame ); } return pMaterial; }
void CEngineSprite::SetFrame( RenderMode_t nRenderMode, int nFrame ) { if ( IsVideo() ) { m_VideoMaterial->SetFrame( nFrame ); return; } IMaterial *pMaterial = m_material[nRenderMode]; if ( !pMaterial ) return; IMaterialVar* pFrameVar = pMaterial->FindVarFast( "$frame", &frameCache ); if ( pFrameVar ) { pFrameVar->SetIntValue( nFrame ); } }
IMaterial *CEngineSprite::GetMaterial( RenderMode_t nRenderMode, int nFrame ) { if ( nRenderMode == kRenderNone || nRenderMode == kRenderEnvironmental ) return NULL; if ( IsVideo() ) { m_VideoMaterial->SetFrame( nFrame ); } IMaterial *pMaterial = m_material[nRenderMode]; IMaterialVar* pFrameVar = pMaterial->FindVarFast( "$frame", &frameCache ); if ( pFrameVar ) { pFrameVar->SetIntValue( nFrame ); } return pMaterial; }
void DrawSpriteModel( IClientEntity *baseentity, CEngineSprite *psprite, const Vector &origin, float fscale, float frame, int rendermode, int r, int g, int b, int a, const Vector& forward, const Vector& right, const Vector& up, float flHDRColorScale ) { float scale; IMaterial *material; // don't even bother culling, because it's just a single // polygon without a surface cache if ( fscale > 0 ) scale = fscale; else scale = 1.0f; if ( rendermode == kRenderNormal ) { render->SetBlend( 1.0f ); } material = psprite->GetMaterial( (RenderMode_t)rendermode, frame ); if ( !material ) return; CMatRenderContextPtr pRenderContext( materials ); if ( ShouldDrawInWireFrameMode() || r_drawsprites.GetInt() == 2 ) { IMaterial *pMaterial = materials->FindMaterial( "debug/debugspritewireframe", TEXTURE_GROUP_OTHER ); pRenderContext->Bind( pMaterial, NULL ); } else { pRenderContext->Bind( material, (IClientRenderable*)baseentity ); } unsigned char color[4]; color[0] = r; color[1] = g; color[2] = b; color[3] = a; IMaterialVar *pHDRColorScaleVar = material->FindVarFast( "$HDRCOLORSCALE", &s_nHDRColorScaleCache ); if( pHDRColorScaleVar ) { pHDRColorScaleVar->SetVecValue( flHDRColorScale, flHDRColorScale, flHDRColorScale ); } Vector point; IMesh* pMesh = pRenderContext->GetDynamicMesh(); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); Vector vec_a; Vector vec_b; Vector vec_c; Vector vec_d; // isolate common terms VectorMA( origin, psprite->GetDown() * scale, up, vec_a ); VectorScale( right, psprite->GetLeft() * scale, vec_b ); VectorMA( origin, psprite->GetUp() * scale, up, vec_c ); VectorScale( right, psprite->GetRight() * scale, vec_d ); float flMinU, flMinV, flMaxU, flMaxV; psprite->GetTexCoordRange( &flMinU, &flMinV, &flMaxU, &flMaxV ); meshBuilder.Color4ubv( color ); meshBuilder.TexCoord2f( 0, flMinU, flMaxV ); VectorAdd( vec_a, vec_b, point ); meshBuilder.Position3fv( point.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Color4ubv( color ); meshBuilder.TexCoord2f( 0, flMinU, flMinV ); VectorAdd( vec_c, vec_b, point ); meshBuilder.Position3fv( point.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Color4ubv( color ); meshBuilder.TexCoord2f( 0, flMaxU, flMinV ); VectorAdd( vec_c, vec_d, point ); meshBuilder.Position3fv( point.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Color4ubv( color ); meshBuilder.TexCoord2f( 0, flMaxU, flMaxV ); VectorAdd( vec_a, vec_d, point ); meshBuilder.Position3fv( point.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); }
//----------------------------------------------------------------------------- // Purpose: // Input : noise_divisions - // *prgNoise - // *spritemodel - // frame - // rendermode - // source - // delta - // flags - // *color - // fadescale - //----------------------------------------------------------------------------- void DrawSegs( int noise_divisions, float *prgNoise, const model_t* spritemodel, float frame, int rendermode, const Vector& source, const Vector& delta, float startWidth, float endWidth, float scale, float freq, float speed, int segments, int flags, float* color, float fadeLength, float flHDRColorScale ) { int i, noiseIndex, noiseStep; float div, length, fraction, factor, vLast, vStep, brightness; Assert( fadeLength >= 0.0f ); CEngineSprite *pSprite = Draw_SetSpriteTexture( spritemodel, frame, rendermode ); if ( !pSprite ) return; if ( segments < 2 ) return; IMaterial *pMaterial = pSprite->GetMaterial( (RenderMode_t)rendermode ); if( pMaterial ) { static unsigned int nHDRColorScaleCache = 0; IMaterialVar *pHDRColorScaleVar = pMaterial->FindVarFast( "$hdrcolorscale", &nHDRColorScaleCache ); if( pHDRColorScaleVar ) { pHDRColorScaleVar->SetFloatValue( flHDRColorScale ); } } length = VectorLength( delta ); float flMaxWidth = MAX(startWidth, endWidth) * 0.5f; div = 1.0 / (segments-1); if ( length*div < flMaxWidth * 1.414 ) { // Here, we have too many segments; we could get overlap... so lets have less segments segments = (int)(length / (flMaxWidth * 1.414)) + 1; if ( segments < 2 ) { segments = 2; } } if ( segments > noise_divisions ) // UNDONE: Allow more segments? { segments = noise_divisions; } div = 1.0 / (segments-1); length *= 0.01; // UNDONE: Expose texture length scale factor to control "fuzziness" if ( flags & FBEAM_NOTILE ) { // Don't tile vStep = div; } else { // Texture length texels per space pixel vStep = length*div; } // UNDONE: Expose this paramter as well(3.5)? Texture scroll rate along beam vLast = fmod(freq*speed,1); // Scroll speed 3.5 -- initial texture position, scrolls 3.5/sec (1.0 is entire texture) if ( flags & FBEAM_SINENOISE ) { if ( segments < 16 ) { segments = 16; div = 1.0 / (segments-1); } scale *= 100; length = segments * (1.0/10); } else { scale *= length; } // Iterator to resample noise waveform (it needs to be generated in powers of 2) noiseStep = (int)((float)(noise_divisions-1) * div * 65536.0f); noiseIndex = 0; if ( flags & FBEAM_SINENOISE ) { noiseIndex = 0; } brightness = 1.0; if ( flags & FBEAM_SHADEIN ) { brightness = 0; } // What fraction of beam should be faded Assert( fadeLength >= 0.0f ); float fadeFraction = fadeLength/ delta.Length(); // BUGBUG: This code generates NANs when fadeFraction is zero! REVIST! fadeFraction = clamp(fadeFraction,1.e-6f,1.f); // Choose two vectors that are perpendicular to the beam Vector perp1; ComputeBeamPerpendicular( delta, &perp1 ); // Specify all the segments. CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); CBeamSegDraw segDraw; segDraw.Start( pRenderContext, segments, NULL ); for ( i = 0; i < segments; i++ ) { Assert( noiseIndex < (noise_divisions<<16) ); BeamSeg_t curSeg; curSeg.m_flAlpha = 1; fraction = i * div; // Fade in our out beam to fadeLength if ( (flags & FBEAM_SHADEIN) && (flags & FBEAM_SHADEOUT) ) { if (fraction < 0.5) { brightness = 2*(fraction/fadeFraction); } else { brightness = 2*(1.0 - (fraction/fadeFraction)); } } else if ( flags & FBEAM_SHADEIN ) { brightness = fraction/fadeFraction; } else if ( flags & FBEAM_SHADEOUT ) { brightness = 1.0 - (fraction/fadeFraction); } // clamps if (brightness < 0 ) { brightness = 0; } else if (brightness > 1) { brightness = 1; } VectorScale( *((Vector*)color), brightness, curSeg.m_vColor ); // UNDONE: Make this a spline instead of just a line? VectorMA( source, fraction, delta, curSeg.m_vPos ); // Distort using noise if ( scale != 0 ) { factor = prgNoise[noiseIndex>>16] * scale; if ( flags & FBEAM_SINENOISE ) { float s, c; SinCos( fraction*M_PI*length + freq, &s, &c ); VectorMA( curSeg.m_vPos, factor * s, CurrentViewUp(), curSeg.m_vPos ); // Rotate the noise along the perpendicluar axis a bit to keep the bolt from looking diagonal VectorMA( curSeg.m_vPos, factor * c, CurrentViewRight(), curSeg.m_vPos ); } else { VectorMA( curSeg.m_vPos, factor, perp1, curSeg.m_vPos ); } } // Specify the next segment. if( endWidth == startWidth ) { curSeg.m_flWidth = startWidth * 2; } else { curSeg.m_flWidth = ((fraction*(endWidth-startWidth))+startWidth) * 2; } curSeg.m_flTexCoord = vLast; segDraw.NextSeg( &curSeg ); vLast += vStep; // Advance texture scroll (v axis only) noiseIndex += noiseStep; }
IMaterial* CStudioRender::R_StudioSetupSkinAndLighting( IMatRenderContext *pRenderContext, int index, IMaterial **ppMaterials, int materialFlags, void /*IClientRenderable*/ *pClientRenderable, ColorMeshInfo_t *pColorMeshes, StudioModelLighting_t &lighting ) { VPROF( "R_StudioSetupSkin" ); IMaterial *pMaterial = NULL; bool bCheckForConVarDrawTranslucentSubModels = false; if( m_pRC->m_Config.bWireframe && !m_pRC->m_pForcedMaterial ) { if ( m_pRC->m_Config.bDrawZBufferedWireframe ) pMaterial = m_pMaterialMRMWireframeZBuffer; else pMaterial = m_pMaterialMRMWireframe; } else if( m_pRC->m_Config.bShowEnvCubemapOnly ) { pMaterial = m_pMaterialModelEnvCubemap; } else { if ( !m_pRC->m_pForcedMaterial && ( m_pRC->m_nForcedMaterialType != OVERRIDE_DEPTH_WRITE ) ) { pMaterial = ppMaterials[index]; if ( !pMaterial ) { Assert( 0 ); return 0; } } else { materialFlags = 0; pMaterial = m_pRC->m_pForcedMaterial; if (m_pRC->m_nForcedMaterialType == OVERRIDE_BUILD_SHADOWS) { // Connect the original material up to the shadow building material // Also bind the original material so its proxies are in the correct state static unsigned int translucentCache = 0; IMaterialVar* pOriginalMaterialVar = pMaterial->FindVarFast( "$translucent_material", &translucentCache ); Assert( pOriginalMaterialVar ); IMaterial *pOriginalMaterial = ppMaterials[index]; if ( pOriginalMaterial ) { // Disable any alpha modulation on the original material that was left over from when it was last rendered pOriginalMaterial->AlphaModulate( 1.0f ); pRenderContext->Bind( pOriginalMaterial, pClientRenderable ); if ( pOriginalMaterial->IsTranslucent() || pOriginalMaterial->IsAlphaTested() ) { pOriginalMaterialVar->SetMaterialValue( pOriginalMaterial ); } else { pOriginalMaterialVar->SetMaterialValue( NULL ); } } else { pOriginalMaterialVar->SetMaterialValue( NULL ); } } else if( m_pRC->m_nForcedMaterialType == OVERRIDE_DEPTH_WRITE ) { // Disable any alpha modulation on the original material that was left over from when it was last rendered ppMaterials[index]->AlphaModulate( 1.0f ); // Bail if the material is still considered translucent after setting the AlphaModulate to 1.0 if ( ppMaterials[index]->IsTranslucent() ) { return NULL; } static unsigned int originalTextureVarCache = 0; IMaterialVar *pOriginalTextureVar = ppMaterials[index]->FindVarFast( "$basetexture", &originalTextureVarCache ); // Select proper override material int nAlphaTest = (int) ( ppMaterials[index]->IsAlphaTested() && pOriginalTextureVar->IsTexture() ); // alpha tested base texture int nNoCull = (int) ppMaterials[index]->IsTwoSided(); pMaterial = m_pDepthWrite[nAlphaTest][nNoCull]; // If we're alpha tested, we should set up the texture variables from the original material if ( nAlphaTest != 0 ) { static unsigned int originalTextureFrameVarCache = 0; IMaterialVar *pOriginalTextureFrameVar = ppMaterials[index]->FindVarFast( "$frame", &originalTextureFrameVarCache ); static unsigned int originalAlphaRefCache = 0; IMaterialVar *pOriginalAlphaRefVar = ppMaterials[index]->FindVarFast( "$AlphaTestReference", &originalAlphaRefCache ); static unsigned int textureVarCache = 0; IMaterialVar *pTextureVar = pMaterial->FindVarFast( "$basetexture", &textureVarCache ); static unsigned int textureFrameVarCache = 0; IMaterialVar *pTextureFrameVar = pMaterial->FindVarFast( "$frame", &textureFrameVarCache ); static unsigned int alphaRefCache = 0; IMaterialVar *pAlphaRefVar = pMaterial->FindVarFast( "$AlphaTestReference", &alphaRefCache ); if ( pOriginalTextureVar->IsTexture() ) // If $basetexture is defined { if( pTextureVar && pOriginalTextureVar ) { pTextureVar->SetTextureValue( pOriginalTextureVar->GetTextureValue() ); } if( pTextureFrameVar && pOriginalTextureFrameVar ) { pTextureFrameVar->SetIntValue( pOriginalTextureFrameVar->GetIntValue() ); } if( pAlphaRefVar && pOriginalAlphaRefVar ) { pAlphaRefVar->SetFloatValue( pOriginalAlphaRefVar->GetFloatValue() ); } } } } } // Set this bool to check after the bind below bCheckForConVarDrawTranslucentSubModels = true; if ( m_pRC->m_nForcedMaterialType != OVERRIDE_DEPTH_WRITE ) { // Try to set the alpha based on the blend pMaterial->AlphaModulate( m_pRC->m_AlphaMod ); // Try to set the color based on the colormod pMaterial->ColorModulate( m_pRC->m_ColorMod[0], m_pRC->m_ColorMod[1], m_pRC->m_ColorMod[2] ); } } lighting = R_StudioComputeLighting( pMaterial, materialFlags, pColorMeshes ); if ( lighting == LIGHTING_MOUTH ) { if ( !m_pRC->m_Config.bTeeth || !R_TeethAreVisible() ) return NULL; // skin it and light it, but only if we need to. if ( m_pRC->m_Config.m_bSupportsVertexAndPixelShaders ) { R_MouthSetupVertexShader( pMaterial ); } } pRenderContext->Bind( pMaterial, pClientRenderable ); if ( bCheckForConVarDrawTranslucentSubModels ) { bool translucent = pMaterial->IsTranslucent(); if (( m_bDrawTranslucentSubModels && !translucent ) || ( !m_bDrawTranslucentSubModels && translucent )) { m_bSkippedMeshes = true; return NULL; } } return pMaterial; }