//----------------------------------------------------------------------------- // Purpose: Generates a view matrix based on our current yaw, pitch, and roll. // The view matrix does not consider FOV or clip plane distances. //----------------------------------------------------------------------------- void CCamera::BuildViewMatrix() { // The camera transformation is produced by multiplying roll * yaw * pitch. // This will transform a point from world space into quake camera space, // which is exactly what we want for our view matrix. However, quake // camera space isn't the same as material system camera space, so // we're going to have to apply a transformation that goes from quake // camera space to material system camera space. CameraIdentityMatrix( m_ViewMatrix ); RotateAroundAxis(m_ViewMatrix, m_fPitch, 0 ); RotateAroundAxis(m_ViewMatrix, m_fRoll, 1); RotateAroundAxis(m_ViewMatrix, m_fYaw, 2); // Translate the viewpoint to the world origin. VMatrix TempMatrix; TempMatrix.Identity(); TempMatrix.SetTranslation( -m_ViewPoint ); m_ViewMatrix = m_ViewMatrix * TempMatrix; m_ViewProjMatrix = m_ProjMatrix * m_ViewMatrix; m_ViewProjMatrix.InverseGeneral( m_InvViewProjMatrix ); }
Vector UTIL_GetMouseAim( C_HL2WarsPlayer *pPlayer, int x, int y ) { Vector forward; // Remap x and y into -1 to 1 normalized space float xf, yf; xf = ( 2.0f * x / (float)(ScreenWidth()-1) ) - 1.0f; yf = ( 2.0f * y / (float)(ScreenHeight()-1) ) - 1.0f; // Flip y axis yf = -yf; const VMatrix &worldToScreen = engine->WorldToScreenMatrix(); VMatrix screenToWorld; MatrixInverseGeneral( worldToScreen, screenToWorld ); // Create two points at the normalized mouse x, y pos and at the near and far z planes (0 and 1 depth) Vector v1, v2; v1.Init( xf, yf, 0.0f ); v2.Init( xf, yf, 1.0f ); Vector o2; // Transform the two points by the screen to world matrix screenToWorld.V3Mul( v1, pPlayer->Weapon_ShootPosition() ); // ray start origin screenToWorld.V3Mul( v2, o2 ); // ray end origin VectorSubtract( o2, pPlayer->Weapon_ShootPosition(), forward ); forward.NormalizeInPlace(); return forward; }
void CEngineTool::CreatePickingRay( const CViewSetup &viewSetup, int x, int y, Vector& org, Vector& forward ) { // Remap x and y into -1 to 1 normalized space float xf, yf; xf = ( 2.0f * (float)x / (float)viewSetup.width ) - 1.0f; yf = ( 2.0f * (float)y / (float)viewSetup.height ) - 1.0f; // Flip y axis yf = -yf; VMatrix worldToScreen; GetWorldToScreenMatrixForView( viewSetup, &worldToScreen ); VMatrix screenToWorld; MatrixInverseGeneral( worldToScreen, screenToWorld ); // Create two points at the normalized mouse x, y pos and at the near and far z planes (0 and 1 depth) Vector v1, v2; v1.Init( xf, yf, 0.0f ); v2.Init( xf, yf, 1.0f ); Vector o2; // Transform the two points by the screen to world matrix screenToWorld.V3Mul( v1, org ); // ray start origin screenToWorld.V3Mul( v2, o2 ); // ray end origin VectorSubtract( o2, org, forward ); forward.NormalizeInPlace(); }
static void SetDepthFlashlightParams( CBaseVSShader *pShader, IShaderDynamicAPI *pShaderAPI, const VMatrix& worldToTexture, const FlashlightState_t& flashlightState ) { float atten[4], pos[4], tweaks[4]; atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors atten[1] = flashlightState.m_fLinearAtten; atten[2] = flashlightState.m_fQuadraticAtten; atten[3] = flashlightState.m_FarZ; pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 ); pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin pos[1] = flashlightState.m_vecLightOrigin[1]; pos[2] = flashlightState.m_vecLightOrigin[2]; pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 ); pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 ); // Tweaks associated with a given flashlight tweaks[0] = ShadowFilterFromState( flashlightState ); tweaks[1] = ShadowAttenFromState( flashlightState ); pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 ); // Dimensions of screen, used for screen-space noise map sampling float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; int nWidth, nHeight; pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); vScreenScale[0] = (float) nWidth / 32.0f; vScreenScale[1] = (float) nHeight / 32.0f; pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); if ( IsX360() ) { pShaderAPI->SetBooleanPixelShaderConstant( 0, &flashlightState.m_nShadowQuality, 1 ); } }
//----------------------------------------------------------------------------- // Computes the panel center to world transform //----------------------------------------------------------------------------- void C_VGuiScreen::ComputePanelToWorld() { // The origin is at the upper-left corner of the screen Vector vecOrigin, vecUR, vecLL; ComputeEdges( &vecOrigin, &vecUR, &vecLL ); m_PanelToWorld.SetupMatrixOrgAngles( vecOrigin, GetAbsAngles() ); }
void MatrixBuildOrtho( VMatrix& dst, double left, double top, double right, double bottom, double zNear, double zFar ) { // FIXME: This is being used incorrectly! Should read: // D3DXMatrixOrthoOffCenterRH( &matrix, left, right, bottom, top, zNear, zFar ); // Which is certainly why we need these extra -1 scales in y. Bleah // NOTE: The camera can be imagined as the following diagram: // /z // / // /____ x Z is going into the screen // | // | // |y // // (0,0,z) represents the upper-left corner of the screen. // Our projection transform needs to transform from this space to a LH coordinate // system that looks thusly: // // y| /z // | / // |/____ x Z is going into the screen // // Where x,y lies between -1 and 1, and z lies from 0 to 1 // This is because the viewport transformation from projection space to pixels // introduces a -1 scale in the y coordinates // D3DXMatrixOrthoOffCenterRH( &matrix, left, right, top, bottom, zNear, zFar ); dst.Init( 2.0f / ( right - left ), 0.0f, 0.0f, ( left + right ) / ( left - right ), 0.0f, 2.0f / ( bottom - top ), 0.0f, ( bottom + top ) / ( top - bottom ), 0.0f, 0.0f, 1.0f / ( zNear - zFar ), zNear / ( zNear - zFar ), 0.0f, 0.0f, 0.0f, 1.0f ); }
//----------------------------------------------------------------------------- // Returns the attachment render origin + origin //----------------------------------------------------------------------------- void C_VGuiScreen::GetAimEntOrigin( IClientEntity *pAttachedTo, Vector *pOrigin, QAngle *pAngles ) { C_BaseEntity *pEnt = pAttachedTo->GetBaseEntity(); const char* panelName = PanelName(); vgui::Panel panel = m_PanelWrapper.GetPanel(); if ( Q_strcmp(panelName, "health_screen") == 0 ) { QAngle weapAngles = pEnt->GetAbsAngles(); Vector weapForward, weapRight, weapUp; AngleVectors(weapAngles, &weapForward, &weapRight, &weapUp); VMatrix worldFromPanel; AngleMatrix(weapAngles, worldFromPanel.As3x4()); MatrixRotate(worldFromPanel, Vector(0, 0, 1), 180.f); MatrixRotate(worldFromPanel, Vector(1, 0, 0), -90.f); MatrixAngles(worldFromPanel.As3x4(), *pAngles); // move it right and over *pOrigin = pEnt->GetAbsOrigin() + weapRight*1.75 + weapUp*2.3 + weapForward*5; return; } //todo: set alpha per view ... m_PanelWrapper.GetPanel()->SetAlpha(200); if (pEnt && (m_nAttachmentIndex > 0)) { { C_BaseAnimating::AutoAllowBoneAccess boneaccess( true, true ); pEnt->GetAttachment( m_nAttachmentIndex, *pOrigin, *pAngles ); } if ( IsAttachedToViewModel() ) { FormatViewModelAttachment( *pOrigin, true ); } } else { BaseClass::GetAimEntOrigin( pAttachedTo, pOrigin, pAngles ); } // Msg("%s origin %.1f %.1f %.1f angles %.1f %.1f %.1f \n", PanelName(), pOrigin->x, pOrigin->y, pOrigin->z, pAngles->x, pAngles->y, pAngles->z); }
//----------------------------------------------------------------------------- // Purpose: Builds the matrix for a counterclockwise rotation about an arbitrary axis. // // | ax2 + (1 - ax2)cosQ axay(1 - cosQ) - azsinQ azax(1 - cosQ) + aysinQ | // Ra(Q) = | axay(1 - cosQ) + azsinQ ay2 + (1 - ay2)cosQ ayaz(1 - cosQ) - axsinQ | // | azax(1 - cosQ) - aysinQ ayaz(1 - cosQ) + axsinQ az2 + (1 - az2)cosQ | // // Input : mat - // vAxisOrRot - // angle - //----------------------------------------------------------------------------- void MatrixBuildRotationAboutAxis( VMatrix &dst, const Vector &vAxisOfRot, float angleDegrees ) { MatrixBuildRotationAboutAxis( vAxisOfRot, angleDegrees, dst.As3x4() ); dst[3][0] = 0; dst[3][1] = 0; dst[3][2] = 0; dst[3][3] = 1; }
void MatrixBuildPerspective( VMatrix &dst, float fovX, float fovY, float zNear, float zFar ) { // FIXME: collapse all of this into one matrix after we figure out what all should be in here. float width = 2 * zNear * tan( fovX * ( M_PI/180.0f ) * 0.5f ); float height = 2 * zNear * tan( fovY * ( M_PI/180.0f ) * 0.5f ); memset( dst.Base(), 0, sizeof( dst ) ); dst[0][0] = 2.0F * zNear / width; dst[1][1] = 2.0F * zNear / height; dst[2][2] = -zFar / ( zNear - zFar ); dst[3][2] = 1.0f; dst[2][3] = zNear * zFar / ( zNear - zFar ); // negate X and Y so that X points right, and Y points up. VMatrix negateXY; negateXY.Identity(); negateXY[0][0] = -1.0f; negateXY[1][1] = -1.0f; MatrixMultiply( negateXY, dst, dst ); VMatrix addW; addW.Identity(); addW[0][3] = 1.0f; addW[1][3] = 1.0f; addW[2][3] = 0.0f; MatrixMultiply( addW, dst, dst ); VMatrix scaleHalf; scaleHalf.Identity(); scaleHalf[0][0] = 0.5f; scaleHalf[1][1] = 0.5f; MatrixMultiply( scaleHalf, dst, dst ); }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- AngularImpulse WorldToLocalRotation( const VMatrix &localToWorld, const Vector &worldAxis, float rotation ) { // fix axes of rotation to match axes of vector Vector rot = worldAxis * rotation; // since the matrix maps local to world, do a transpose rotation to get world to local AngularImpulse ang = localToWorld.VMul3x3Transpose( rot ); return ang; }
void MatrixBuildPerspectiveX( VMatrix& dst, double flFovX, double flAspect, double flZNear, double flZFar ) { float flWidth = 2.0f * flZNear * tanf( flFovX * M_PI / 360.0f ); float flHeight = flWidth / flAspect; dst.Init( 2.0f * flZNear / flWidth, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f * flZNear/ flHeight, 0.0f, 0.0f, 0.0f, 0.0f, flZFar / ( flZNear - flZFar ), flZNear * flZFar / ( flZNear - flZFar ), 0.0f, 0.0f, -1.0f, 0.0f ); }
//----------------------------------------------------------------------------- // Computes the position of the canister //----------------------------------------------------------------------------- void CEnvHeadcrabCanisterShared::GetPositionAtTime( float flTime, Vector &vecPosition, QAngle &vecAngles ) { float flDeltaTime = flTime - m_flLaunchTime; if ( flDeltaTime > m_flFlightTime ) { flDeltaTime = m_flFlightTime; } VMatrix initToWorld; if ( m_bLaunchedFromWithinWorld || m_bInSkybox ) { VectorMA( m_vecStartPosition, flDeltaTime * m_flHorizSpeed, m_vecParabolaDirection, vecPosition ); vecPosition.z += m_flInitialZSpeed * flDeltaTime + 0.5f * m_flZAcceleration * flDeltaTime * flDeltaTime; Vector vecLeft; CrossProduct( m_vecParabolaDirection, Vector( 0, 0, 1 ), vecLeft ); Vector vecForward; VectorMultiply( m_vecParabolaDirection, -1.0f, vecForward ); vecForward.z = -(m_flInitialZSpeed + m_flZAcceleration * flDeltaTime) / m_flHorizSpeed; // This is -dz/dx. VectorNormalize( vecForward ); Vector vecUp; CrossProduct( vecForward, vecLeft, vecUp ); initToWorld.SetBasisVectors( vecForward, vecLeft, vecUp ); } else { flDeltaTime -= m_flWorldEnterTime; Vector vecVelocity; VectorMultiply( m_vecDirection, m_flFlightSpeed, vecVelocity ); VectorMA( m_vecEnterWorldPosition, flDeltaTime, vecVelocity, vecPosition ); MatrixFromAngles( m_vecStartAngles.Get(), initToWorld ); } VMatrix rotation; MatrixBuildRotationAboutAxis( rotation, Vector( 1, 0, 0 ), flDeltaTime * ROTATION_SPEED ); VMatrix newAngles; MatrixMultiply( initToWorld, rotation, newAngles ); MatrixToAngles( newAngles, vecAngles ); }
VMatrix VMatrix::NormalizeBasisVectors() const { Vector vecs[3]; VMatrix mRet; GetBasisVectors(vecs[0], vecs[1], vecs[2]); VectorNormalize( vecs[0] ); VectorNormalize( vecs[1] ); VectorNormalize( vecs[2] ); mRet.SetBasisVectors(vecs[0], vecs[1], vecs[2]); // Set everything but basis vectors to identity. mRet.m[3][0] = mRet.m[3][1] = mRet.m[3][2] = 0.0f; mRet.m[3][3] = 1.0f; return mRet; }
void CRenderManager::SetupProjectionMatrix( int nWidth, int nHeight, float flFOV ) { VMatrix proj; float flZNear = ZNEAR; float flZFar = ZFAR; float flApsectRatio = (nHeight != 0.0f) ? (float)nWidth / (float)nHeight : 100.0f; float halfWidth = tan( flFOV * M_PI / 360.0 ); float halfHeight = halfWidth / flApsectRatio; memset( proj.Base(), 0, sizeof( proj ) ); proj[0][0] = 1.0f / halfWidth; proj[1][1] = 1.0f / halfHeight; proj[2][2] = flZFar / ( flZNear - flZFar ); proj[3][2] = -1.0f; proj[2][3] = flZNear * flZFar / ( flZNear - flZFar ); CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); pRenderContext->MatrixMode( MATERIAL_PROJECTION ); pRenderContext->LoadMatrix( proj ); }
void CBaseVSShader::SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms ) { Assert( !IsSnapshotting() ); VMatrix worldToTexture; const FlashlightState_t &flashlightState = s_pShaderAPI->GetFlashlightState( worldToTexture ); // Set the flashlight origin float pos[4]; pos[0] = flashlightState.m_vecLightOrigin[0]; pos[1] = flashlightState.m_vecLightOrigin[1]; pos[2] = flashlightState.m_vecLightOrigin[2]; pos[3] = 1.0f / ( ( 0.6f * flashlightState.m_FarZ ) - flashlightState.m_FarZ ); // DX8 needs this s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, pos, 1 ); s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, worldToTexture.Base(), 4 ); // Set the flashlight attenuation factors float atten[4]; atten[0] = flashlightState.m_fConstantAtten; atten[1] = flashlightState.m_fLinearAtten; atten[2] = flashlightState.m_fQuadraticAtten; atten[3] = flashlightState.m_FarZAtten; s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, atten, 1 ); if ( bDetail ) { SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, BASETEXTURETRANSFORM, detailScaleVar ); } if( bSetTextureTransforms ) { SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, BASETEXTURETRANSFORM ); if( !bDetail && bBump && bumpTransformVar != -1 ) { SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, bumpTransformVar ); // aliased on top of detail transform } } }
void CStatueProp::VPhysicsUpdate( IPhysicsObject *pPhysics ) { BaseClass::VPhysicsUpdate( pPhysics ); if ( s_vcollide_wireframe->GetBool() ) { const CPhysCollide *pCollide = pPhysics->GetCollide(); Vector vecOrigin; QAngle angAngles; pPhysics->GetPosition( &vecOrigin, &angAngles ); if ( pCollide ) { Vector *outVerts; int vertCount = physcollision->CreateDebugMesh( pCollide, &outVerts ); int triCount = vertCount / 3; int vert = 0; VMatrix tmp = SetupMatrixOrgAngles( vecOrigin, angAngles ); int i; for ( i = 0; i < vertCount; i++ ) { outVerts[i] = tmp.VMul4x3( outVerts[i] ); } for ( i = 0; i < triCount; i++ ) { NDebugOverlay::Line( outVerts[ vert + 0 ], outVerts[ vert + 1 ], 0, 255, 255, false, 0.0f ); NDebugOverlay::Line( outVerts[ vert + 1 ], outVerts[ vert + 2 ], 0, 255, 255, false, 0.0f ); NDebugOverlay::Line( outVerts[ vert + 2 ], outVerts[ vert + 0 ], 0, 255, 255, false, 0.0f ); vert += 3; } physcollision->DestroyDebugMesh( vertCount, outVerts ); } } }
void CSplinePatch::SetupPatchQuery( float s, float t ) { m_is = (int)s; m_it = (int)t; if( m_is >= m_Width ) { m_is = m_Width - 1; m_fs = 1.0f; } else { m_fs = s - m_is; } if( m_it >= m_Height ) { m_it = m_Height - 1; m_ft = 1.0f; } else { m_ft = t - m_it; } ComputeIndices( ); // The patch equation is: // px = S * M * Gx * M^T * T^T // py = S * M * Gy * M^T * T^T // pz = S * M * Gz * M^T * T^T // where S = [s^3 s^2 s 1], T = [t^3 t^2 t 1] // M is the patch type matrix, in my case I'm using a catmull-rom // G is the array of control points. rows have constant t // We're gonna cache off S * M and M^T * T^T... Vector4D svec, tvec; float fs2 = m_fs * m_fs; svec[0] = fs2 * m_fs; svec[1] = fs2; svec[2] = m_fs; svec[3] = 1.0f; float ft2 = m_ft * m_ft; tvec[0] = ft2 * m_ft; tvec[1] = ft2; tvec[2] = m_ft; tvec[3] = 1.0f; // This sets up the catmull rom matrix based on the blend factor!! // we can go from linear to curvy! s_CatmullRom.Init( -0.5 * m_LinearFactor, 1.5 * m_LinearFactor, -1.5 * m_LinearFactor, 0.5 * m_LinearFactor, m_LinearFactor, -2.5 * m_LinearFactor, 2 * m_LinearFactor, -0.5 * m_LinearFactor, -0.5 * m_LinearFactor, -1 + m_LinearFactor, 1 - 0.5 * m_LinearFactor, 0, 0, 1, 0, 0 ); Vector4DMultiplyTranspose( s_CatmullRom, svec, m_SVec ); Vector4DMultiplyTranspose( s_CatmullRom, tvec, m_TVec ); }
void MatrixBuildPerspectiveOffCenterX( VMatrix& dst, double flFovX, double flAspect, double flZNear, double flZFar, double bottom, double top, double left, double right ) { float flWidth = 2.0f * flZNear * tanf( flFovX * M_PI / 360.0f ); float flHeight = flWidth / flAspect; // bottom, top, left, right are 0..1 so convert to -<val>/2..<val>/2 float flLeft = -(flWidth/2.0f) * (1.0f - left) + left * (flWidth/2.0f); float flRight = -(flWidth/2.0f) * (1.0f - right) + right * (flWidth/2.0f); float flBottom = -(flHeight/2.0f) * (1.0f - bottom) + bottom * (flHeight/2.0f); float flTop = -(flHeight/2.0f) * (1.0f - top) + top * (flHeight/2.0f); dst.Init( (2.0f * flZNear) / (flRight-flLeft), 0.0f, (flLeft+flRight)/(flRight-flLeft), 0.0f, 0.0f, 2.0f*flZNear/(flTop-flBottom), (flTop+flBottom)/(flTop-flBottom), 0.0f, 0.0f, 0.0f, flZFar/(flZNear-flZFar), flZNear*flZFar/(flZNear-flZFar), 0.0f, 0.0f, -1.0f, 0.0f ); }
//----------------------------------------------------------------------------- // Transform a plane //----------------------------------------------------------------------------- void MatrixTransformPlane( const VMatrix &src, const cplane_t &inPlane, cplane_t &outPlane ) { // What we want to do is the following: // 1) transform the normal into the new space. // 2) Determine a point on the old plane given by plane dist * plane normal // 3) Transform that point into the new space // 4) Plane dist = DotProduct( new normal, new point ) // An optimized version, which works if the plane is orthogonal. // 1) Transform the normal into the new space // 2) Realize that transforming the old plane point into the new space // is given by [ d * n'x + Tx, d * n'y + Ty, d * n'z + Tz ] // where d = old plane dist, n' = transformed normal, Tn = translational component of transform // 3) Compute the new plane dist using the dot product of the normal result of #2 // For a correct result, this should be an inverse-transpose matrix // but that only matters if there are nonuniform scale or skew factors in this matrix. Vector3DMultiply( src, inPlane.normal, outPlane.normal ); outPlane.dist = inPlane.dist * DotProduct( outPlane.normal, outPlane.normal ); outPlane.dist += DotProduct( outPlane.normal, src.GetTranslation() ); }
void VMatrix::MatrixMul( const VMatrix &vm, VMatrix &out ) const { out.Init( m[0][0]*vm.m[0][0] + m[0][1]*vm.m[1][0] + m[0][2]*vm.m[2][0] + m[0][3]*vm.m[3][0], m[0][0]*vm.m[0][1] + m[0][1]*vm.m[1][1] + m[0][2]*vm.m[2][1] + m[0][3]*vm.m[3][1], m[0][0]*vm.m[0][2] + m[0][1]*vm.m[1][2] + m[0][2]*vm.m[2][2] + m[0][3]*vm.m[3][2], m[0][0]*vm.m[0][3] + m[0][1]*vm.m[1][3] + m[0][2]*vm.m[2][3] + m[0][3]*vm.m[3][3], m[1][0]*vm.m[0][0] + m[1][1]*vm.m[1][0] + m[1][2]*vm.m[2][0] + m[1][3]*vm.m[3][0], m[1][0]*vm.m[0][1] + m[1][1]*vm.m[1][1] + m[1][2]*vm.m[2][1] + m[1][3]*vm.m[3][1], m[1][0]*vm.m[0][2] + m[1][1]*vm.m[1][2] + m[1][2]*vm.m[2][2] + m[1][3]*vm.m[3][2], m[1][0]*vm.m[0][3] + m[1][1]*vm.m[1][3] + m[1][2]*vm.m[2][3] + m[1][3]*vm.m[3][3], m[2][0]*vm.m[0][0] + m[2][1]*vm.m[1][0] + m[2][2]*vm.m[2][0] + m[2][3]*vm.m[3][0], m[2][0]*vm.m[0][1] + m[2][1]*vm.m[1][1] + m[2][2]*vm.m[2][1] + m[2][3]*vm.m[3][1], m[2][0]*vm.m[0][2] + m[2][1]*vm.m[1][2] + m[2][2]*vm.m[2][2] + m[2][3]*vm.m[3][2], m[2][0]*vm.m[0][3] + m[2][1]*vm.m[1][3] + m[2][2]*vm.m[2][3] + m[2][3]*vm.m[3][3], m[3][0]*vm.m[0][0] + m[3][1]*vm.m[1][0] + m[3][2]*vm.m[2][0] + m[3][3]*vm.m[3][0], m[3][0]*vm.m[0][1] + m[3][1]*vm.m[1][1] + m[3][2]*vm.m[2][1] + m[3][3]*vm.m[3][1], m[3][0]*vm.m[0][2] + m[3][1]*vm.m[1][2] + m[3][2]*vm.m[2][2] + m[3][3]*vm.m[3][2], m[3][0]*vm.m[0][3] + m[3][1]*vm.m[1][3] + m[3][2]*vm.m[2][3] + m[3][3]*vm.m[3][3] ); }
//----------------------------------------------------------------------------- // Setup a matrix from euler angles. //----------------------------------------------------------------------------- void MatrixFromAngles( const QAngle& vAngles, VMatrix& dst ) { dst.SetupMatrixOrgAngles( vec3_origin, vAngles ); }
void MatrixInverseTranspose( const VMatrix& src, VMatrix& dst ) { src.InverseGeneral( dst ); dst = dst.Transpose(); }
VMatrix SetupMatrixOrgAngles(const Vector &origin, const QAngle &vAngles) { VMatrix mRet; mRet.SetupMatrixOrgAngles( origin, vAngles ); return mRet; }
void Draw_Eyes_Refract_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bDrawFlashlightAdditivePass, Eye_Refract_Vars_t &info, VertexCompressionType_t vertexCompression ) { bool bDiffuseWarp = IS_PARAM_DEFINED( info.m_nDiffuseWarpTexture ); bool bIntro = IS_PARAM_DEFINED( info.m_nIntro ) ? ( params[info.m_nIntro]->GetIntValue() ? true : false ) : false; SHADOW_STATE { SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT ); pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Cornea normal pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Iris pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); // Cube reflection pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Ambient occlusion // Set stream format (note that this shader supports compression) unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; int nTexCoordCount = 1; int userDataSize = 0; pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); if ( bDiffuseWarp ) { pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Light warp } #if !defined( PLATFORM_X360 ) bool bWorldNormal = ( ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH == ( IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 ))); #endif int nShadowFilterMode = 0; if ( bDrawFlashlightAdditivePass == true ) { if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats } pShaderShadow->EnableDepthWrites( false ); pShaderShadow->EnableAlphaWrites( false ); pShader->EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); // Additive blending pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Flashlight cookie } else { pShaderShadow->EnableAlphaWrites( true ); } #ifndef _X360 if ( !g_pHardwareConfig->HasFastVertexTextures() ) #endif { DECLARE_STATIC_VERTEX_SHADER( eye_refract_vs20 ); SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); SET_STATIC_VERTEX_SHADER_COMBO( INTRO, bIntro ? 1 : 0 ); SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); SET_STATIC_VERTEX_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); SET_STATIC_VERTEX_SHADER_COMBO( WORLD_NORMAL, 0 ); SET_STATIC_VERTEX_SHADER( eye_refract_vs20 ); if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { bool bSphereTexKillCombo = IS_PARAM_DEFINED( info.m_nSphereTexKillCombo ) ? ( params[info.m_nSphereTexKillCombo]->GetIntValue() ? true : false ) : ( kDefaultSphereTexKillCombo ? true : false ); bool bRayTraceSphere = IS_PARAM_DEFINED( info.m_nRaytraceSphere ) ? ( params[info.m_nRaytraceSphere]->GetIntValue() ? true : false ) : ( kDefaultRaytraceSphere ? true : false ); DECLARE_STATIC_PIXEL_SHADER( eye_refract_ps20b ); SET_STATIC_PIXEL_SHADER_COMBO( SPHERETEXKILLCOMBO, bSphereTexKillCombo ? 1 : 0 ); SET_STATIC_PIXEL_SHADER_COMBO( RAYTRACESPHERE, bRayTraceSphere ? 1 : 0 ); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); SET_STATIC_PIXEL_SHADER_COMBO( WORLD_NORMAL, 0 ); SET_STATIC_PIXEL_SHADER( eye_refract_ps20b ); if ( bDrawFlashlightAdditivePass == true ) { pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Shadow depth map pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER6 ); pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Noise map } } else { DECLARE_STATIC_PIXEL_SHADER( eye_refract_ps20 ); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); SET_STATIC_PIXEL_SHADER_COMBO( WORLD_NORMAL, 0 ); SET_STATIC_PIXEL_SHADER( eye_refract_ps20 ); } } #ifndef _X360 else { pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // Screen space ambient occlusion // The vertex shader uses the vertex id stream SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_TESSELLATION ); DECLARE_STATIC_VERTEX_SHADER( eye_refract_vs30 ); SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ) ); SET_STATIC_VERTEX_SHADER_COMBO( INTRO, bIntro ? 1 : 0 ); SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); SET_STATIC_VERTEX_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); SET_STATIC_VERTEX_SHADER_COMBO( WORLD_NORMAL, bWorldNormal ); SET_STATIC_VERTEX_SHADER( eye_refract_vs30 ); bool bSphereTexKillCombo = IS_PARAM_DEFINED( info.m_nSphereTexKillCombo ) ? ( params[info.m_nSphereTexKillCombo]->GetIntValue() ? true : false ) : ( kDefaultSphereTexKillCombo ? true : false ); bool bRayTraceSphere = IS_PARAM_DEFINED( info.m_nRaytraceSphere ) ? ( params[info.m_nRaytraceSphere]->GetIntValue() ? true : false ) : ( kDefaultRaytraceSphere ? true : false ); DECLARE_STATIC_PIXEL_SHADER( eye_refract_ps30 ); SET_STATIC_PIXEL_SHADER_COMBO( SPHERETEXKILLCOMBO, bSphereTexKillCombo ? 1 : 0 ); SET_STATIC_PIXEL_SHADER_COMBO( RAYTRACESPHERE, bRayTraceSphere ? 1 : 0 ); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bDrawFlashlightAdditivePass ? 1 : 0 ); SET_STATIC_PIXEL_SHADER_COMBO( LIGHTWARPTEXTURE, bDiffuseWarp ? 1 : 0 ); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); SET_STATIC_PIXEL_SHADER_COMBO( WORLD_NORMAL, bWorldNormal ); SET_STATIC_PIXEL_SHADER( eye_refract_ps30 ); if ( bDrawFlashlightAdditivePass == true ) { pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Shadow depth map pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); // Noise map } } #endif // On DX9, get the gamma read and write correct //pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, false ); // Cornea normal pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // Iris pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); // Cube map reflection pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, true ); // Ambient occlusion pShaderShadow->EnableSRGBWrite( true ); if ( bDiffuseWarp ) { pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); // Light Warp } if ( bDrawFlashlightAdditivePass == true ) { pShaderShadow->EnableSRGBRead( SHADER_SAMPLER5, true ); // Flashlight cookie } // Fog if ( bDrawFlashlightAdditivePass == true ) { pShader->FogToBlack(); } else { pShader->FogToFogColor(); } // Per-instance state pShader->PI_BeginCommandBuffer(); if ( !bDrawFlashlightAdditivePass ) { pShader->PI_SetPixelShaderLocalLighting( PSREG_LIGHT_INFO_ARRAY ); } pShader->PI_SetVertexShaderAmbientLightCube(); pShader->PI_SetPixelShaderAmbientLightCubeLuminance( 10 ); pShader->PI_EndCommandBuffer(); } DYNAMIC_STATE { VMatrix worldToTexture; ITexture *pFlashlightDepthTexture = NULL; FlashlightState_t flashlightState; bool bFlashlightShadows = false; if ( bDrawFlashlightAdditivePass == true ) { flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); bFlashlightShadows = flashlightState.m_bEnableShadows; } bool bSinglePassFlashlight = false; pShader->BindTexture( SHADER_SAMPLER0, info.m_nCorneaTexture ); pShader->BindTexture( SHADER_SAMPLER1, info.m_nIris, info.m_nIrisFrame ); pShader->BindTexture( SHADER_SAMPLER2, info.m_nEnvmap ); pShader->BindTexture( SHADER_SAMPLER3, info.m_nAmbientOcclTexture ); if ( bDiffuseWarp ) { if ( r_lightwarpidentity.GetBool() ) { pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_IDENTITY_LIGHTWARP ); } else { pShader->BindTexture( SHADER_SAMPLER4, info.m_nDiffuseWarpTexture ); } } // On PC, we sample from ambient occlusion texture if ( IsPC() && g_pHardwareConfig->HasFastVertexTextures() ) { ITexture *pAOTexture = pShaderAPI->GetTextureRenderingParameter( TEXTURE_RENDERPARM_AMBIENT_OCCLUSION ); if ( pAOTexture ) { pShader->BindTexture( SHADER_SAMPLER8, pAOTexture ); } else { pShaderAPI->BindStandardTexture( SHADER_SAMPLER8, TEXTURE_WHITE ); } } if ( bDrawFlashlightAdditivePass == true ) pShader->BindTexture( SHADER_SAMPLER5, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame ); pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nEyeOrigin ); pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nIrisU ); pShader->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, info.m_nIrisV ); if ( bDrawFlashlightAdditivePass == true ) pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, flashlightState.m_vecLightOrigin.Base(), 1 ); LightState_t lightState = { 0, false, false }; if ( bDrawFlashlightAdditivePass == false ) { pShaderAPI->GetDX9LightState( &lightState ); } int nFixedLightingMode = pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ); #ifndef _X360 if ( !g_pHardwareConfig->HasFastVertexTextures() ) #endif { DECLARE_DYNAMIC_VERTEX_SHADER( eye_refract_vs20 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER_COMBO( TESSELLATION, 0 ); SET_DYNAMIC_VERTEX_SHADER( eye_refract_vs20 ); } #ifndef _X360 else { pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, VERTEX_SHADER_SHADER_SPECIFIC_CONST_11, SHADER_VERTEXTEXTURE_SAMPLER0 ); if ( nFixedLightingMode == ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH ) { float vEyeDir[4]; pShaderAPI->GetWorldSpaceCameraDirection( vEyeDir ); float flFarZ = pShaderAPI->GetFarZ(); vEyeDir[0] /= flFarZ; // Divide by farZ for SSAO algorithm vEyeDir[1] /= flFarZ; vEyeDir[2] /= flFarZ; pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, vEyeDir ); } TessellationMode_t nTessellationMode = pShaderAPI->GetTessellationMode(); if ( nTessellationMode != TESSELLATION_MODE_DISABLED ) { pShaderAPI->BindStandardVertexTexture( SHADER_VERTEXTEXTURE_SAMPLER1, TEXTURE_SUBDIVISION_PATCHES ); bool bHasDisplacement = false; // TODO float vSubDDimensions[4] = { 1.0f/pShaderAPI->GetSubDHeight(), bHasDisplacement && mat_displacementmap.GetBool() ? 1.0f : 0.0f, 0.0f, 0.0f }; pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, vSubDDimensions ); } DECLARE_DYNAMIC_VERTEX_SHADER( eye_refract_vs30 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DYNAMIC_LIGHT, lightState.HasDynamicLight() ); SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER_COMBO( TESSELLATION, nTessellationMode ); SET_DYNAMIC_VERTEX_SHADER( eye_refract_vs30 ); } #endif // Special constant for DX9 eyes: { Dilation, Glossiness, x, x }; float vPSConst[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; vPSConst[0] = IS_PARAM_DEFINED( info.m_nDilation ) ? params[info.m_nDilation]->GetFloatValue() : kDefaultDilation; vPSConst[1] = IS_PARAM_DEFINED( info.m_nGlossiness ) ? params[info.m_nGlossiness]->GetFloatValue() : kDefaultGlossiness; vPSConst[2] = 0.0f; // NOT USED vPSConst[3] = IS_PARAM_DEFINED( info.m_nCorneaBumpStrength ) ? params[info.m_nCorneaBumpStrength]->GetFloatValue() : kDefaultCorneaBumpStrength; pShaderAPI->SetPixelShaderConstant( 0, vPSConst, 1 ); pShaderAPI->SetPixelShaderConstant( 1, IS_PARAM_DEFINED( info.m_nEyeOrigin ) ? params[info.m_nEyeOrigin]->GetVecValue() : kDefaultEyeOrigin, 1 ); pShaderAPI->SetPixelShaderConstant( 2, IS_PARAM_DEFINED( info.m_nIrisU ) ? params[info.m_nIrisU]->GetVecValue() : kDefaultIrisU, 1 ); pShaderAPI->SetPixelShaderConstant( 3, IS_PARAM_DEFINED( info.m_nIrisV ) ? params[info.m_nIrisV]->GetVecValue() : kDefaultIrisV, 1 ); float vEyePos[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; pShaderAPI->GetWorldSpaceCameraPosition( vEyePos ); pShaderAPI->SetPixelShaderConstant( 4, vEyePos, 1 ); float vAmbientOcclusion[4] = { 0.33f, 0.33f, 0.33f, 0.0f }; if ( IS_PARAM_DEFINED( info.m_nAmbientOcclColor ) ) { params[info.m_nAmbientOcclColor]->GetVecValue( vAmbientOcclusion, 3 ); } vAmbientOcclusion[3] = IS_PARAM_DEFINED( info.m_nAmbientOcclusion ) ? params[info.m_nAmbientOcclusion]->GetFloatValue() : 0.0f; float vPackedConst6[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; //vPackedConst6[0] Unused vPackedConst6[1] = IS_PARAM_DEFINED( info.m_nEyeballRadius ) ? params[info.m_nEyeballRadius]->GetFloatValue() : kDefaultEyeballRadius; //vPackedConst6[2] = IS_PARAM_DEFINED( info.m_nRaytraceSphere ) ? params[info.m_nRaytraceSphere]->GetFloatValue() : kDefaultRaytraceSphere; vPackedConst6[3] = IS_PARAM_DEFINED( info.m_nParallaxStrength ) ? params[info.m_nParallaxStrength]->GetFloatValue() : kDefaultParallaxStrength; pShaderAPI->SetPixelShaderConstant( 6, vPackedConst6, 1 ); if ( bDrawFlashlightAdditivePass == true ) { SetFlashLightColorFromState( flashlightState, pShaderAPI, bSinglePassFlashlight ); if ( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows ) { pShader->BindTexture( SHADER_SAMPLER6, pFlashlightDepthTexture, 0 ); pShaderAPI->BindStandardTexture( SHADER_SAMPLER7, TEXTURE_SHADOW_NOISE_2D ); } } if ( nFixedLightingMode == ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH ) { float vEyeDir[4]; pShaderAPI->GetWorldSpaceCameraDirection( vEyeDir ); float flFarZ = pShaderAPI->GetFarZ(); vEyeDir[0] /= flFarZ; // Divide by farZ for SSAO algorithm vEyeDir[1] /= flFarZ; vEyeDir[2] /= flFarZ; pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, vEyeDir ); } // Flashlight tax #ifndef _X360 if ( !g_pHardwareConfig->HasFastVertexTextures() ) #endif { if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { DECLARE_DYNAMIC_PIXEL_SHADER( eye_refract_ps20b ); SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); SET_DYNAMIC_PIXEL_SHADER( eye_refract_ps20b ); } else // ps.2.0 { DECLARE_DYNAMIC_PIXEL_SHADER( eye_refract_ps20 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); SET_DYNAMIC_PIXEL_SHADER( eye_refract_ps20 ); } } #ifndef _X360 else { DECLARE_DYNAMIC_PIXEL_SHADER( eye_refract_ps30 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, nFixedLightingMode ? 0 : lightState.m_nNumLights ); SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, nFixedLightingMode ? false : bFlashlightShadows ); SET_DYNAMIC_PIXEL_SHADER_COMBO( UBERLIGHT, flashlightState.m_bUberlight ); SET_DYNAMIC_PIXEL_SHADER( eye_refract_ps30 ); // Set constant to enable translation of VPOS to render target coordinates in ps_3_0 pShaderAPI->SetScreenSizeForVPOS(); SetupUberlightFromState( pShaderAPI, flashlightState ); } #endif pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS ); if ( bDrawFlashlightAdditivePass == true ) { float atten[4], pos[4], tweaks[4]; atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors atten[1] = flashlightState.m_fLinearAtten; atten[2] = flashlightState.m_fQuadraticAtten; atten[3] = flashlightState.m_FarZAtten; pShaderAPI->SetPixelShaderConstant( 7, atten, 1 ); pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin pos[1] = flashlightState.m_vecLightOrigin[1]; pos[2] = flashlightState.m_vecLightOrigin[2]; pShaderAPI->SetPixelShaderConstant( 8, pos, 1 ); pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, worldToTexture.Base(), 4 ); // Tweaks associated with a given flashlight tweaks[0] = ShadowFilterFromState( flashlightState ); tweaks[1] = ShadowAttenFromState( flashlightState ); pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] ); pShaderAPI->SetPixelShaderConstant( 9, tweaks, 1 ); // Dimensions of screen, used for screen-space noise map sampling float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; int nWidth, nHeight; pShaderAPI->GetBackBufferDimensions( nWidth, nHeight ); int nTexWidth, nTexHeight; pShaderAPI->GetStandardTextureDimensions( &nTexWidth, &nTexHeight, TEXTURE_SHADOW_NOISE_2D ); vScreenScale[0] = (float) nWidth / nTexWidth; vScreenScale[1] = (float) nHeight / nTexHeight; pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 ); vAmbientOcclusion[3] *= flashlightState.m_flAmbientOcclusion; } vAmbientOcclusion[3] = MIN( MAX( vAmbientOcclusion[3], 0.0f ), 1.0f ); pShaderAPI->SetPixelShaderConstant( 5, vAmbientOcclusion, 1 ); // Intro tax if ( bIntro ) { float curTime = params[info.m_nWarpParam]->GetFloatValue(); float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; if ( IS_PARAM_DEFINED( info.m_nEntityOrigin ) ) { params[info.m_nEntityOrigin]->GetVecValue( timeVec, 3 ); } pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, timeVec, 1 ); } } pShader->Draw(); }
//----------------------------------------------------------------------------- // Draws the shader //----------------------------------------------------------------------------- void DrawVortWarp_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bVertexLitGeneric, bool hasFlashlight, VortWarp_DX9_Vars_t &info, VertexCompressionType_t vertexCompression ) { bool hasBaseTexture = params[info.m_nBaseTexture]->IsTexture(); bool hasBump = (info.m_nBumpmap != -1) && params[info.m_nBumpmap]->IsTexture(); bool hasDetailTexture = !hasBump && params[info.m_nDetail]->IsTexture(); bool hasNormalMapAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); bool hasVertexColor = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); bool hasVertexAlpha = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; bool hasSelfIllumInEnvMapMask = ( info.m_nSelfIllumEnvMapMask_Alpha != -1 ) && ( params[info.m_nSelfIllumEnvMapMask_Alpha]->GetFloatValue() != 0.0 ) ; bool bHasFlowMap = ( info.m_nFlowMap != -1 ) && params[info.m_nFlowMap]->IsTexture(); bool bHasSelfIllumMap = ( info.m_nSelfIllumMap != -1 ) && params[info.m_nSelfIllumMap]->IsTexture(); BlendType_t blendType; if ( params[info.m_nBaseTexture]->IsTexture() ) { blendType = pShader->EvaluateBlendRequirements( info.m_nBaseTexture, true ); } else { blendType = pShader->EvaluateBlendRequirements( info.m_nEnvmapMask, false ); } if( pShader->IsSnapshotting() ) { // look at color and alphamod stuff. // Unlit generic never uses the flashlight bool hasEnvmap = !hasFlashlight && params[info.m_nEnvmap]->IsTexture(); bool hasEnvmapMask = (hasSelfIllumInEnvMapMask || !hasFlashlight) && params[info.m_nEnvmapMask]->IsTexture(); bool bHasNormal = bVertexLitGeneric || hasEnvmap; if( hasFlashlight ) { hasEnvmapMask = false; } bool bHalfLambert = IS_FLAG_SET( MATERIAL_VAR_HALFLAMBERT ); // Alpha test: FIXME: shouldn't this be handled in CBaseVSShader::SetInitialShadowState pShaderShadow->EnableAlphaTest( bIsAlphaTested ); if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) { pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); } if( hasFlashlight ) { if (params[info.m_nBaseTexture]->IsTexture()) { pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true ); } else { pShader->SetAdditiveBlendingShadowState( info.m_nEnvmapMask, false ); } if( bIsAlphaTested ) { // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to // be the same on both the regular pass and the flashlight pass. pShaderShadow->EnableAlphaTest( false ); pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); } pShaderShadow->EnableBlending( true ); pShaderShadow->EnableDepthWrites( false ); } else { if (params[info.m_nBaseTexture]->IsTexture()) { pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true ); } else { pShader->SetDefaultBlendingShadowState( info.m_nEnvmapMask, false ); } } unsigned int flags = VERTEX_POSITION; int nTexCoordCount = 1; // texcoord0 : base texcoord int userDataSize = 0; if( bHasNormal ) { flags |= VERTEX_NORMAL; } if( hasBaseTexture ) { pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); } if( hasEnvmap ) { pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) { pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); } } if( hasFlashlight ) { pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); userDataSize = 4; // tangent S } if( hasDetailTexture ) { pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); } if( hasBump ) { pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); userDataSize = 4; // tangent S // Normalizing cube map pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); } if( hasEnvmapMask ) { pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); } if( hasVertexColor || hasVertexAlpha ) { flags |= VERTEX_COLOR; } pShaderShadow->EnableSRGBWrite( true ); if( bHasSelfIllumMap ) { pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); } if( bHasFlowMap ) { pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); } // This shader supports compressed vertices, so OR in that flag: flags |= VERTEX_FORMAT_COMPRESSED; pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); Assert( hasBump ); #ifndef _X360 if ( !g_pHardwareConfig->HasFastVertexTextures() ) #endif { DECLARE_STATIC_VERTEX_SHADER( vortwarp_vs20 ); SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert); SET_STATIC_VERTEX_SHADER( vortwarp_vs20 ); if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { DECLARE_STATIC_PIXEL_SHADER( vortwarp_ps20b ); SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, hasBaseTexture ); SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, hasEnvmap ); SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, !params[info.m_nUnlit]->GetIntValue() ); SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); SET_STATIC_PIXEL_SHADER_COMBO( TRANSLUCENT, blendType == BT_BLEND ); SET_STATIC_PIXEL_SHADER( vortwarp_ps20b ); } else { DECLARE_STATIC_PIXEL_SHADER( vortwarp_ps20 ); SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, hasBaseTexture ); SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, hasEnvmap ); SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, !params[info.m_nUnlit]->GetIntValue() ); SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); SET_STATIC_PIXEL_SHADER_COMBO( TRANSLUCENT, blendType == BT_BLEND ); SET_STATIC_PIXEL_SHADER( vortwarp_ps20 ); } } #ifndef _X360 else { // The vertex shader uses the vertex id stream SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); DECLARE_STATIC_VERTEX_SHADER( vortwarp_vs30 ); SET_STATIC_VERTEX_SHADER_COMBO( HALFLAMBERT, bHalfLambert); SET_STATIC_VERTEX_SHADER( vortwarp_vs30 ); DECLARE_STATIC_PIXEL_SHADER( vortwarp_ps30 ); SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, hasBaseTexture ); SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, hasEnvmap ); SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSELIGHTING, !params[info.m_nUnlit]->GetIntValue() ); SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); SET_STATIC_PIXEL_SHADER_COMBO( HALFLAMBERT, bHalfLambert); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); SET_STATIC_PIXEL_SHADER_COMBO( TRANSLUCENT, blendType == BT_BLEND ); SET_STATIC_PIXEL_SHADER( vortwarp_ps30 ); } #endif if( hasFlashlight ) { pShader->FogToBlack(); } else { pShader->DefaultFog(); } if( blendType == BT_BLEND ) { pShaderShadow->EnableBlending( true ); pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); pShaderShadow->EnableAlphaWrites( false ); } else { pShaderShadow->EnableAlphaWrites( true ); } } else { bool hasEnvmap = !hasFlashlight && params[info.m_nEnvmap]->IsTexture(); bool hasEnvmapMask = !hasFlashlight && params[info.m_nEnvmapMask]->IsTexture(); if( hasBaseTexture ) { pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); } if( hasEnvmap ) { pShader->BindTexture( SHADER_SAMPLER1, info.m_nEnvmap, info.m_nEnvmapFrame ); } if( hasDetailTexture ) { pShader->BindTexture( SHADER_SAMPLER2, info.m_nDetail, info.m_nDetailFrame ); } if( !g_pConfig->m_bFastNoBump ) { if( hasBump ) { pShader->BindTexture( SHADER_SAMPLER3, info.m_nBumpmap, info.m_nBumpFrame ); } } else { if( hasBump ) { pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALMAP_FLAT ); } } if( hasEnvmapMask ) { pShader->BindTexture( SHADER_SAMPLER4, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); } if( hasFlashlight ) { Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 ); pShader->BindTexture( SHADER_SAMPLER7, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame ); VMatrix worldToTexture; ITexture *pFlashlightDepthTexture; FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); SetFlashLightColorFromState( state, pShaderAPI ); } // Set up light combo state LightState_t lightState = {0, false, false}; if ( bVertexLitGeneric && !hasFlashlight ) { pShaderAPI->GetDX9LightState( &lightState ); } MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0; int numBones = pShaderAPI->GetCurrentNumBones(); Assert( hasBump ); #ifndef _X360 if ( !g_pHardwareConfig->HasFastVertexTextures() ) #endif { DECLARE_DYNAMIC_VERTEX_SHADER( vortwarp_vs20 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER( vortwarp_vs20 ); if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { DECLARE_DYNAMIC_PIXEL_SHADER( vortwarp_ps20b ); SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z && blendType != BT_BLENDADD && blendType != BT_BLEND && !bIsAlphaTested ); SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); float warpParam = params[info.m_nWarpParam]->GetFloatValue(); // float selfIllumTint = params[info.m_nSelfIllumTint]->GetFloatValue(); // DevMsg( 1, "warpParam: %f %f\n", warpParam, selfIllumTint ); SET_DYNAMIC_PIXEL_SHADER_COMBO( WARPINGIN, warpParam > 0.0f && warpParam < 1.0f ); SET_DYNAMIC_PIXEL_SHADER( vortwarp_ps20b ); } else { DECLARE_DYNAMIC_PIXEL_SHADER( vortwarp_ps20 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z && blendType != BT_BLENDADD && blendType != BT_BLEND && !bIsAlphaTested ); SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); float warpParam = params[info.m_nWarpParam]->GetFloatValue(); // float selfIllumTint = params[info.m_nSelfIllumTint]->GetFloatValue(); // DevMsg( 1, "warpParam: %f %f\n", warpParam, selfIllumTint ); SET_DYNAMIC_PIXEL_SHADER_COMBO( WARPINGIN, warpParam > 0.0f && warpParam < 1.0f ); SET_DYNAMIC_PIXEL_SHADER( vortwarp_ps20 ); } } #ifndef _X360 else { pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); DECLARE_DYNAMIC_VERTEX_SHADER( vortwarp_vs30 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER( vortwarp_vs30 ); DECLARE_DYNAMIC_PIXEL_SHADER( vortwarp_ps30 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights ); SET_DYNAMIC_PIXEL_SHADER_COMBO( AMBIENT_LIGHT, lightState.m_bAmbientLight ? 1 : 0 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z && blendType != BT_BLENDADD && blendType != BT_BLEND && !bIsAlphaTested ); SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); float warpParam = params[info.m_nWarpParam]->GetFloatValue(); // float selfIllumTint = params[info.m_nSelfIllumTint]->GetFloatValue(); // DevMsg( 1, "warpParam: %f %f\n", warpParam, selfIllumTint ); SET_DYNAMIC_PIXEL_SHADER_COMBO( WARPINGIN, warpParam > 0.0f && warpParam < 1.0f ); SET_DYNAMIC_PIXEL_SHADER( vortwarp_ps30 ); } #endif pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); if( hasDetailTexture ) { pShader->SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBaseTextureTransform, info.m_nDetailScale ); Assert( !hasBump ); } if( hasBump ) { pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform ); Assert( !hasDetailTexture ); } if( hasEnvmapMask ) { pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nEnvmapMaskTransform ); } if( hasEnvmap ) { pShader->SetEnvMapTintPixelShaderDynamicState( 0, info.m_nEnvmapTint, -1, true ); } if( ( info.m_nHDRColorScale != -1 ) && pShader->IsHDREnabled() ) { pShader->SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( 1, params[info.m_nHDRColorScale]->GetFloatValue() ); } else { pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); } pShader->SetPixelShaderConstant( 2, info.m_nEnvmapContrast ); pShader->SetPixelShaderConstant( 3, info.m_nEnvmapSaturation ); pShader->SetPixelShaderConstant( 4, info.m_nSelfIllumTint ); pShader->SetAmbientCubeDynamicStateVertexShader(); if( hasBump ) { pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); pShaderAPI->SetPixelShaderStateAmbientLightCube( 5 ); pShaderAPI->CommitPixelShaderLighting( 13 ); } if( bHasSelfIllumMap ) { pShader->BindTexture( SHADER_SAMPLER6, info.m_nSelfIllumMap, -1 ); } if( bHasFlowMap ) { pShader->BindTexture( SHADER_SAMPLER2, info.m_nFlowMap, -1 ); } float eyePos[4]; pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); pShaderAPI->SetPixelShaderConstant( 20, eyePos, 1 ); pShaderAPI->SetPixelShaderFogParams( 21 ); // dynamic drawing code that extends vertexlitgeneric float curTime = params[info.m_nWarpParam]->GetFloatValue(); float timeVec[4] = { 0.0f, 0.0f, 0.0f, curTime }; Assert( params[info.m_nEntityOrigin]->IsDefined() ); params[info.m_nEntityOrigin]->GetVecValue( timeVec, 3 ); pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, timeVec, 1 ); curTime = pShaderAPI->CurrentTime(); timeVec[0] = curTime; timeVec[1] = curTime; timeVec[2] = curTime; timeVec[3] = curTime; pShaderAPI->SetPixelShaderConstant( 22, timeVec, 1 ); // flashlightfixme: put this in common code. if( hasFlashlight ) { VMatrix worldToTexture; const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); // Set the flashlight attenuation factors float atten[4]; atten[0] = flashlightState.m_fConstantAtten; atten[1] = flashlightState.m_fLinearAtten; atten[2] = flashlightState.m_fQuadraticAtten; atten[3] = flashlightState.m_FarZ; pShaderAPI->SetPixelShaderConstant( 22, atten, 1 ); // Set the flashlight origin float pos[4]; pos[0] = flashlightState.m_vecLightOrigin[0]; pos[1] = flashlightState.m_vecLightOrigin[1]; pos[2] = flashlightState.m_vecLightOrigin[2]; pos[3] = 1.0f; pShaderAPI->SetPixelShaderConstant( 23, pos, 1 ); pShaderAPI->SetPixelShaderConstant( 24, worldToTexture.Base(), 4 ); } } pShader->Draw(); }
//----------------------------------------------------------------------------- // Purpose: Upon touching a non-filtered entity, CTriggerPortal teleports them to it's // remote portal location. // Input : *pOther - //----------------------------------------------------------------------------- void CTriggerPortal::Touch( CBaseEntity *pOther ) { // If we are enabled, and allowed to react to the touched entity if ( PassesTriggerFilters(pOther) ) { // If we somehow lost our pointer to the remote portal, get a new one if ( m_hRemotePortal == NULL ) { Disable(); return; } bool bDebug = portal_debug.GetBool(); if ( bDebug ) { Msg("%s TOUCH: for %s\n", GetDebugName(), pOther->GetDebugName() ); } // Don't touch entities that came through us and haven't left us yet. EHANDLE hHandle; hHandle = pOther; if ( m_hDisabledForEntities.Find(hHandle) != m_hDisabledForEntities.InvalidIndex() ) { Msg(" IGNORED\n", GetDebugName(), pOther->GetDebugName() ); return; } Pickup_ForcePlayerToDropThisObject( pOther ); // de-ground this entity pOther->SetGroundEntity( NULL ); // Build a this --> remote transformation VMatrix matMyModelToWorld, matMyInverse; matMyModelToWorld = this->EntityToWorldTransform(); MatrixInverseGeneral ( matMyModelToWorld, matMyInverse ); // Teleport our object VMatrix matRemotePortalTransform = m_hRemotePortal->EntityToWorldTransform(); Vector ptNewOrigin, vLook, vRight, vUp, vNewLook; pOther->GetVectors( &vLook, &vRight, &vUp ); // Move origin ptNewOrigin = matMyInverse * pOther->GetAbsOrigin(); ptNewOrigin = matRemotePortalTransform * Vector( ptNewOrigin.x, -ptNewOrigin.y, ptNewOrigin.z ); // Re-aim camera vNewLook = matMyInverse.ApplyRotation( vLook ); vNewLook = matRemotePortalTransform.ApplyRotation( Vector( -vNewLook.x, -vNewLook.y, vNewLook.z ) ); // Reorient the physics Vector vVelocity, vOldVelocity; pOther->GetVelocity( &vOldVelocity ); vVelocity = matMyInverse.ApplyRotation( vOldVelocity ); vVelocity = matRemotePortalTransform.ApplyRotation( Vector( -vVelocity.x, -vVelocity.y, vVelocity.z ) ); QAngle qNewAngles; VectorAngles( vNewLook, qNewAngles ); if ( pOther->IsPlayer() ) { ((CBasePlayer*)pOther)->SnapEyeAngles(qNewAngles); } Vector vecOldPos = pOther->WorldSpaceCenter(); if ( bDebug ) { NDebugOverlay::Box( pOther->GetAbsOrigin(), pOther->WorldAlignMins(), pOther->WorldAlignMaxs(), 255,0,0, 8, 20 ); NDebugOverlay::Axis( pOther->GetAbsOrigin(), pOther->GetAbsAngles(), 10.0f, true, 50 ); } // place player at the new destination CTriggerPortal *pPortal = m_hRemotePortal.Get(); pPortal->DisableForIncomingEntity( pOther ); pOther->Teleport( &ptNewOrigin, &qNewAngles, &vVelocity ); if ( bDebug ) { NDebugOverlay::Box( pOther->GetAbsOrigin(), pOther->WorldAlignMins(), pOther->WorldAlignMaxs(), 0,255,0, 8, 20 ); NDebugOverlay::Line( vecOldPos, pOther->WorldSpaceCenter(), 0,255,0, true, 20 ); NDebugOverlay::Axis( pOther->GetAbsOrigin(), pOther->GetAbsAngles(), 10.0f, true, 50 ); Msg("%s TELEPORTED: %s\n", GetDebugName(), pOther->GetDebugName() ); } // test collision on the new teleport location Vector vMin, vMax, vCenter; pOther->CollisionProp()->WorldSpaceAABB( &vMin, &vMax ); vCenter = (vMin + vMax) * 0.5f; vMin -= vCenter; vMax -= vCenter; Vector vStart, vEnd; vStart = ptNewOrigin; vEnd = ptNewOrigin; Ray_t ray; ray.Init( vStart, vEnd, vMin, vMax ); trace_t tr; pPortal->TestCollision( ray, pOther->PhysicsSolidMaskForEntity(), tr ); // Teleportation caused us to hit something, deal with it. if ( tr.DidHit() ) { } } }
void DrawCloakBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, CloakBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ) { bool bBumpMapping = ( !g_pConfig->UseBumpmapping() ) || ( info.m_nBumpmap == -1 ) || !params[info.m_nBumpmap]->IsTexture() ? 0 : 1; SHADOW_STATE { // Reset shadow state manually since we're drawing from two materials pShader->SetInitialShadowState( ); // Set stream format (note that this shader supports compression) unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; int nTexCoordCount = 1; int userDataSize = 0; pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); #ifndef _X360 if ( !g_pHardwareConfig->HasFastVertexTextures() ) #endif { // Vertex Shader DECLARE_STATIC_VERTEX_SHADER( cloak_blended_pass_vs20 ); SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, bBumpMapping ? 1 : 0 ); SET_STATIC_VERTEX_SHADER( cloak_blended_pass_vs20 ); // Pixel Shader if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { DECLARE_STATIC_PIXEL_SHADER( cloak_blended_pass_ps20b ); SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bBumpMapping ? 1 : 0 ); SET_STATIC_PIXEL_SHADER( cloak_blended_pass_ps20b ); } else { DECLARE_STATIC_PIXEL_SHADER( cloak_blended_pass_ps20 ); SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bBumpMapping ? 1 : 0 ); SET_STATIC_PIXEL_SHADER( cloak_blended_pass_ps20 ); } } #ifndef _X360 else { // The vertex shader uses the vertex id stream SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); // Vertex Shader DECLARE_STATIC_VERTEX_SHADER( cloak_blended_pass_vs30 ); SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, bBumpMapping ? 1 : 0 ); SET_STATIC_VERTEX_SHADER( cloak_blended_pass_vs30 ); // Pixel Shader DECLARE_STATIC_PIXEL_SHADER( cloak_blended_pass_ps30 ); SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bBumpMapping ? 1 : 0 ); SET_STATIC_PIXEL_SHADER( cloak_blended_pass_ps30 ); } #endif // Textures pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Refraction texture pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); if ( bBumpMapping ) { pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // Bump pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); // Not sRGB } pShaderShadow->EnableSRGBWrite( true ); // Blending pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); pShaderShadow->EnableAlphaWrites( false ); // !!! We need to turn this back on because EnableAlphaBlending() above disables it! pShaderShadow->EnableDepthWrites( true ); } DYNAMIC_STATE { // Reset render state manually since we're drawing from two materials pShaderAPI->SetDefaultState(); // Set Vertex Shader Constants if ( ( bBumpMapping ) && ( info.m_nBumpTransform != -1 ) ) { pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBumpTransform ); } #ifndef _X360 if ( !g_pHardwareConfig->HasFastVertexTextures() ) #endif { // Set Vertex Shader Combos DECLARE_DYNAMIC_VERTEX_SHADER( cloak_blended_pass_vs20 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER( cloak_blended_pass_vs20 ); // Set Pixel Shader Combos if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { DECLARE_DYNAMIC_PIXEL_SHADER( cloak_blended_pass_ps20b ); SET_DYNAMIC_PIXEL_SHADER( cloak_blended_pass_ps20b ); } else { DECLARE_DYNAMIC_PIXEL_SHADER( cloak_blended_pass_ps20 ); SET_DYNAMIC_PIXEL_SHADER( cloak_blended_pass_ps20 ); } } #ifndef _X360 else { pShader->SetHWMorphVertexShaderState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, VERTEX_SHADER_SHADER_SPECIFIC_CONST_7, SHADER_VERTEXTEXTURE_SAMPLER0 ); // Set Vertex Shader Combos DECLARE_DYNAMIC_VERTEX_SHADER( cloak_blended_pass_vs30 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( MORPHING, pShaderAPI->IsHWMorphingEnabled() ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER( cloak_blended_pass_vs30 ); // Set Pixel Shader Combos DECLARE_DYNAMIC_PIXEL_SHADER( cloak_blended_pass_ps30 ); SET_DYNAMIC_PIXEL_SHADER( cloak_blended_pass_ps30 ); } #endif // Bind textures pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); // Refraction Map if ( bBumpMapping ) { pShader->BindTexture( SHADER_SAMPLER1, info.m_nBumpmap, info.m_nBumpFrame ); } // Set Pixel Shader Constants float vEyePos[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; pShaderAPI->GetWorldSpaceCameraPosition( vEyePos ); pShaderAPI->SetPixelShaderConstant( 5, vEyePos, 1 ); float vPackedConst1[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; vPackedConst1[0] = IS_PARAM_DEFINED( info.m_nCloakFactor ) ? params[info.m_nCloakFactor]->GetFloatValue() : kDefaultCloakFactor; vPackedConst1[1] = IS_PARAM_DEFINED( info.m_nRefractAmount ) ? params[info.m_nRefractAmount]->GetFloatValue() : kDefaultRefractAmount; pShaderAPI->SetPixelShaderConstant( 6, vPackedConst1, 1 ); // Refract color tint pShaderAPI->SetPixelShaderConstant( 7, IS_PARAM_DEFINED( info.m_nCloakColorTint ) ? params[info.m_nCloakColorTint]->GetVecValue() : kDefaultCloakColorTint, 1 ); // Set c0 and c1 to contain first two rows of ViewProj matrix VMatrix mView, mProj; pShaderAPI->GetMatrix( MATERIAL_VIEW, mView.m[0] ); pShaderAPI->GetMatrix( MATERIAL_PROJECTION, mProj.m[0] ); VMatrix mViewProj = mView * mProj; mViewProj = mViewProj.Transpose3x3(); pShaderAPI->SetPixelShaderConstant( 0, mViewProj.m[0], 2 ); } pShader->Draw(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- int CSpriteTrail::DrawModel( int flags ) { VPROF_BUDGET( "CSpriteTrail::DrawModel", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); // Must have at least one point if ( m_nStepCount < 1 ) return 1; //See if we should draw if ( !IsVisible() || ( m_bReadyToDraw == false ) ) return 0; CEngineSprite *pSprite = Draw_SetSpriteTexture( GetModel(), m_flFrame, GetRenderMode() ); if ( pSprite == NULL ) return 0; // Specify all the segments. CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); CBeamSegDraw segDraw; segDraw.Start( pRenderContext, m_nStepCount + 1, pSprite->GetMaterial() ); // Setup the first point, always emanating from the attachment point TrailPoint_t *pLast = GetTrailPoint( m_nStepCount-1 ); TrailPoint_t currentPoint; currentPoint.m_flDieTime = gpGlobals->curtime + m_flLifeTime; ComputeScreenPosition( ¤tPoint.m_vecScreenPos ); currentPoint.m_flTexCoord = pLast->m_flTexCoord + currentPoint.m_vecScreenPos.DistTo(pLast->m_vecScreenPos) * m_flTextureRes; currentPoint.m_flWidthVariance = 0.0f; #if SCREEN_SPACE_TRAILS VMatrix viewMatrix; materials->GetMatrix( MATERIAL_VIEW, &viewMatrix ); viewMatrix = viewMatrix.InverseTR(); #endif TrailPoint_t *pPrevPoint = NULL; float flTailAlphaDist = m_flMinFadeLength; for ( int i = 0; i <= m_nStepCount; ++i ) { // This makes it so that we're always drawing to the current location TrailPoint_t *pPoint = (i != m_nStepCount) ? GetTrailPoint(i) : ¤tPoint; float flLifePerc = (pPoint->m_flDieTime - gpGlobals->curtime) / m_flLifeTime; flLifePerc = clamp( flLifePerc, 0.0f, 1.0f ); BeamSeg_t curSeg; curSeg.m_vColor.x = (float) m_clrRender->r / 255.0f; curSeg.m_vColor.y = (float) m_clrRender->g / 255.0f; curSeg.m_vColor.z = (float) m_clrRender->b / 255.0f; float flAlphaFade = flLifePerc; if ( flTailAlphaDist > 0.0f ) { if ( pPrevPoint ) { float flDist = pPoint->m_vecScreenPos.DistTo( pPrevPoint->m_vecScreenPos ); flTailAlphaDist -= flDist; } if ( flTailAlphaDist > 0.0f ) { float flTailFade = Lerp( (m_flMinFadeLength - flTailAlphaDist) / m_flMinFadeLength, 0.0f, 1.0f ); if ( flTailFade < flAlphaFade ) { flAlphaFade = flTailFade; } } } curSeg.m_flAlpha = ( (float) GetRenderBrightness() / 255.0f ) * flAlphaFade; #if SCREEN_SPACE_TRAILS curSeg.m_vPos = viewMatrix * pPoint->m_vecScreenPos; #else curSeg.m_vPos = pPoint->m_vecScreenPos; #endif if ( m_flEndWidth >= 0.0f ) { curSeg.m_flWidth = Lerp( flLifePerc, m_flEndWidth.Get(), m_flStartWidth.Get() ); } else { curSeg.m_flWidth = m_flStartWidth.Get(); } curSeg.m_flWidth += pPoint->m_flWidthVariance; if ( curSeg.m_flWidth < 0.0f ) { curSeg.m_flWidth = 0.0f; } curSeg.m_flTexCoord = pPoint->m_flTexCoord; segDraw.NextSeg( &curSeg ); // See if we're done with this bad boy if ( pPoint->m_flDieTime <= gpGlobals->curtime ) { // Push this back onto the top for use ++m_nFirstStep; --i; --m_nStepCount; } pPrevPoint = pPoint; } segDraw.End(); return 1; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFArrowPanel::Paint() { if ( !m_hEntity.Get() ) return; C_BaseEntity *pEnt = m_hEntity.Get(); IMaterial *pMaterial = m_NeutralMaterial; C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); // figure out what material we need to use if ( pEnt->GetTeamNumber() == TF_TEAM_RED ) { pMaterial = m_RedMaterial; if ( pLocalPlayer && ( pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) ) { // is our target a player? C_BaseEntity *pTargetEnt = pLocalPlayer->GetObserverTarget(); if ( pTargetEnt && pTargetEnt->IsPlayer() ) { // does our target have the flag and are they carrying the flag we're currently drawing? C_TFPlayer *pTarget = static_cast< C_TFPlayer* >( pTargetEnt ); if ( pTarget->HasTheFlag() && ( pTarget->GetItem() == pEnt ) ) { pMaterial = m_RedMaterialNoArrow; } } } } else if ( pEnt->GetTeamNumber() == TF_TEAM_BLUE ) { pMaterial = m_BlueMaterial; if ( pLocalPlayer && ( pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) ) { // is our target a player? C_BaseEntity *pTargetEnt = pLocalPlayer->GetObserverTarget(); if ( pTargetEnt && pTargetEnt->IsPlayer() ) { // does our target have the flag and are they carrying the flag we're currently drawing? C_TFPlayer *pTarget = static_cast< C_TFPlayer* >( pTargetEnt ); if ( pTarget->HasTheFlag() && ( pTarget->GetItem() == pEnt ) ) { pMaterial = m_BlueMaterialNoArrow; } } } } else if (pEnt->GetTeamNumber() == TF_TEAM_GREEN) { pMaterial = m_GreenMaterial; if (pLocalPlayer && (pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE)) { // is our target a player? C_BaseEntity *pTargetEnt = pLocalPlayer->GetObserverTarget(); if (pTargetEnt && pTargetEnt->IsPlayer()) { // does our target have the flag and are they carrying the flag we're currently drawing? C_TFPlayer *pTarget = static_cast< C_TFPlayer* >(pTargetEnt); if (pTarget->HasTheFlag() && (pTarget->GetItem() == pEnt)) { pMaterial = m_GreenMaterialNoArrow; } } } } else if (pEnt->GetTeamNumber() == TF_TEAM_YELLOW) { pMaterial = m_YellowMaterial; if (pLocalPlayer && (pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE)) { // is our target a player? C_BaseEntity *pTargetEnt = pLocalPlayer->GetObserverTarget(); if (pTargetEnt && pTargetEnt->IsPlayer()) { // does our target have the flag and are they carrying the flag we're currently drawing? C_TFPlayer *pTarget = static_cast< C_TFPlayer* >(pTargetEnt); if (pTarget->HasTheFlag() && (pTarget->GetItem() == pEnt)) { pMaterial = m_YellowMaterialNoArrow; } } } } int x = 0; int y = 0; ipanel()->GetAbsPos( GetVPanel(), x, y ); int nWidth = GetWide(); int nHeight = GetTall(); CMatRenderContextPtr pRenderContext( materials ); pRenderContext->MatrixMode( MATERIAL_MODEL ); pRenderContext->PushMatrix(); VMatrix panelRotation; panelRotation.Identity(); MatrixBuildRotationAboutAxis( panelRotation, Vector( 0, 0, 1 ), GetAngleRotation() ); // MatrixRotate( panelRotation, Vector( 1, 0, 0 ), 5 ); panelRotation.SetTranslation( Vector( x + nWidth/2, y + nHeight/2, 0 ) ); pRenderContext->LoadMatrix( panelRotation ); IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial ); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); meshBuilder.TexCoord2f( 0, 0, 0 ); meshBuilder.Position3f( -nWidth/2, -nHeight/2, 0 ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.AdvanceVertex(); meshBuilder.TexCoord2f( 0, 1, 0 ); meshBuilder.Position3f( nWidth/2, -nHeight/2, 0 ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.AdvanceVertex(); meshBuilder.TexCoord2f( 0, 1, 1 ); meshBuilder.Position3f( nWidth/2, nHeight/2, 0 ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.AdvanceVertex(); meshBuilder.TexCoord2f( 0, 0, 1 ); meshBuilder.Position3f( -nWidth/2, nHeight/2, 0 ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); pRenderContext->PopMatrix(); }
void DrawPass( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool hasFlashlight, VertexCompressionType_t vertexCompression ) { bool bSinglePassFlashlight = false; bool hasBump = params[BUMPMAP]->IsTexture(); bool hasDiffuseBumpmap = hasBump && (params[NODIFFUSEBUMPLIGHTING]->GetIntValue() == 0); bool hasBaseTexture = params[BASETEXTURE]->IsTexture(); bool hasDetailTexture = /*!hasBump && */params[DETAIL]->IsTexture(); bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) != 0; bool bHasDetailAlpha = params[DETAIL_ALPHA_MASK_BASE_TEXTURE]->GetIntValue() != 0; bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use bool bSeamlessMapping = params[SEAMLESS_SCALE]->GetFloatValue() != 0.0; bool bShaderSrgbRead = ( IsX360() && IS_PARAM_DEFINED( SHADERSRGBREAD360 ) && params[SHADERSRGBREAD360]->GetIntValue() ); SHADOW_STATE { int nShadowFilterMode = 0; // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState pShaderShadow->EnableAlphaTest( bIsAlphaTested ); if( hasFlashlight ) { if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats } SetAdditiveBlendingShadowState( BASETEXTURE, true ); pShaderShadow->EnableDepthWrites( false ); // Be sure not to write to dest alpha pShaderShadow->EnableAlphaWrites( false ); } else { SetDefaultBlendingShadowState( BASETEXTURE, true ); } unsigned int flags = VERTEX_POSITION; if( hasBaseTexture ) { pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, !bShaderSrgbRead ); } // if( hasLightmap ) { pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); } if( hasFlashlight ) { pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 ); flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T | VERTEX_NORMAL; } if( hasDetailTexture ) { pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); } if( hasBump ) { pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); } if( hasVertexColor ) { flags |= VERTEX_COLOR; } // Normalizing cube map pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // texcoord0 : base texcoord // texcoord1 : lightmap texcoord // texcoord2 : lightmap texcoord offset int numTexCoords = 2; if( hasBump ) { numTexCoords = 3; } pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); // Pre-cache pixel shaders bool hasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); pShaderShadow->EnableSRGBWrite( true ); int nLightingPreviewMode = IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 ); #ifndef _X360 if ( g_pHardwareConfig->HasFastVertexTextures() ) { DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs30 ); SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, false ); SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, false ); SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, hasFlashlight ); SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump ); SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, false ); SET_STATIC_VERTEX_SHADER_COMBO( PARALLAX_MAPPING, 0 ); //( bumpmap_variant == 2 )?1:0); SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); //( bumpmap_variant == 2 )?1:0); SET_STATIC_VERTEX_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); SET_STATIC_VERTEX_SHADER_COMBO( SELFILLUM, hasSelfIllum ); SET_STATIC_VERTEX_SHADER_COMBO( FANCY_BLENDING, false ); SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode != 0 ); SET_STATIC_VERTEX_SHADER( lightmappedgeneric_vs30 ); } else #endif { DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, false ); SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, false ); SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, hasFlashlight ); SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump ); SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, false ); SET_STATIC_VERTEX_SHADER_COMBO( PARALLAX_MAPPING, 0 ); //( bumpmap_variant == 2 )?1:0); SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); //( bumpmap_variant == 2 )?1:0); SET_STATIC_VERTEX_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); SET_STATIC_VERTEX_SHADER_COMBO( SELFILLUM, hasSelfIllum ); SET_STATIC_VERTEX_SHADER_COMBO( FANCY_BLENDING, false ); SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode != 0 ); #ifdef _X360 SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); #endif SET_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); } #ifndef _X360 if ( g_pHardwareConfig->HasFastVertexTextures() ) { DECLARE_STATIC_PIXEL_SHADER( worldtwotextureblend_ps30 ); SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, hasBump ); SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_ALPHA_MASK_BASE_TEXTURE, bHasDetailAlpha ); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead ); SET_STATIC_PIXEL_SHADER( worldtwotextureblend_ps30 ); } else #endif if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { DECLARE_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, hasBump ); SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_ALPHA_MASK_BASE_TEXTURE, bHasDetailAlpha ); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode ); SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead ); SET_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); } else { DECLARE_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, hasBump ); SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, hasVertexColor ); SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_ALPHA_MASK_BASE_TEXTURE, bHasDetailAlpha ); SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, hasFlashlight ); SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead ); SET_STATIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); } // HACK HACK HACK - enable alpha writes all the time so that we have them for // underwater stuff. // But only do it if we're not using the alpha already for translucency pShaderShadow->EnableAlphaWrites( bFullyOpaque ); if( hasFlashlight ) { FogToBlack(); } else { DefaultFog(); } PI_BeginCommandBuffer(); PI_SetModulationVertexShaderDynamicState( ); PI_EndCommandBuffer(); } DYNAMIC_STATE { if( hasBaseTexture ) { BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME ); } else { pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); } // if( hasLightmap ) { pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); } bool bFlashlightShadows = false; bool bUberlight = false; if( hasFlashlight ) { VMatrix worldToTexture; ITexture *pFlashlightDepthTexture; FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture ); bFlashlightShadows = state.m_bEnableShadows; bUberlight = state.m_bUberlight; SetFlashLightColorFromState( state, pShaderAPI, bSinglePassFlashlight ); BindTexture( SHADER_SAMPLER2, state.m_pSpotlightTexture, state.m_nSpotlightTextureFrame ); if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() ) { BindTexture( SHADER_SAMPLER7, pFlashlightDepthTexture ); } } if( hasDetailTexture ) { BindTexture( SHADER_SAMPLER3, DETAIL, DETAILFRAME ); } if( hasBump ) { if( !g_pConfig->m_bFastNoBump ) { BindTexture( SHADER_SAMPLER4, BUMPMAP, BUMPFRAME ); } else { pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALMAP_FLAT ); } } pShaderAPI->BindStandardTexture( SHADER_SAMPLER6, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED ); // If we don't have a texture transform, we don't have // to set vertex shader constants or run vertex shader instructions // for the texture transform. bool bHasTextureTransform = !( params[BASETEXTURETRANSFORM]->MatrixIsIdentity() && params[BUMPTRANSFORM]->MatrixIsIdentity() ); bool bVertexShaderFastPath = !bHasTextureTransform; if( params[DETAIL]->IsTexture() ) { bVertexShaderFastPath = false; } if( pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING) != 0 ) { bVertexShaderFastPath = false; } if( !bVertexShaderFastPath ) { if ( !bSeamlessMapping ) { SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM ); } if( hasBump && !bHasDetailAlpha ) { SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BUMPTRANSFORM ); Assert( !hasDetailTexture ); } } MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); if ( IsPC() ) { bool bWorldNormal = pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ) == ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH; if ( bWorldNormal ) { float vEyeDir[4]; pShaderAPI->GetWorldSpaceCameraDirection( vEyeDir ); float flFarZ = pShaderAPI->GetFarZ(); vEyeDir[0] /= flFarZ; // Divide by farZ for SSAO algorithm vEyeDir[1] /= flFarZ; vEyeDir[2] /= flFarZ; pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_12, vEyeDir ); } } #ifndef _X360 if (g_pHardwareConfig->HasFastVertexTextures() ) { DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs30 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); SET_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs30 ); } else #endif { DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); SET_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs20 ); } bool bWriteDepthToAlpha; bool bWriteWaterFogToAlpha; if( bFullyOpaque ) { bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); } else { //can't write a special value to dest alpha if we're actually using as-intended alpha bWriteDepthToAlpha = false; bWriteWaterFogToAlpha = false; } #ifndef _X360 if ( g_pHardwareConfig->HasFastVertexTextures() ) { DECLARE_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps30 ); // Don't write fog to alpha if we're using translucency SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); SET_DYNAMIC_PIXEL_SHADER_COMBO( UBERLIGHT, bUberlight ); SET_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps30 ); } else #endif if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { DECLARE_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); // Don't write fog to alpha if we're using translucency SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); SET_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20b ); } else { DECLARE_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); // Don't write fog to alpha if we're using translucency SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z) && (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !bIsAlphaTested ); SET_DYNAMIC_PIXEL_SHADER( worldtwotextureblend_ps20 ); } // always set the transform for detail textures since I'm assuming that you'll // always have a detailscale. if( hasDetailTexture ) { SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, BASETEXTURETRANSFORM, DETAILSCALE ); Assert( !( hasBump && !bHasDetailAlpha ) ); } SetPixelShaderConstantGammaToLinear( 7, SELFILLUMTINT ); float eyePos[4]; pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); pShaderAPI->SetPixelShaderConstant( 10, eyePos, 1 ); pShaderAPI->SetPixelShaderFogParams( 11 ); if ( bSeamlessMapping ) { float map_scale[4]={ params[SEAMLESS_SCALE]->GetFloatValue(),0,0,0}; pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, map_scale ); } if( hasFlashlight ) { VMatrix worldToTexture; const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture ); // Set the flashlight attenuation factors float atten[4]; atten[0] = flashlightState.m_fConstantAtten; atten[1] = flashlightState.m_fLinearAtten; atten[2] = flashlightState.m_fQuadraticAtten; atten[3] = flashlightState.m_FarZAtten; pShaderAPI->SetPixelShaderConstant( 20, atten, 1 ); // Set the flashlight origin float pos[4]; pos[0] = flashlightState.m_vecLightOrigin[0]; pos[1] = flashlightState.m_vecLightOrigin[1]; pos[2] = flashlightState.m_vecLightOrigin[2]; pos[3] = flashlightState.m_FarZ; // didn't have this in main. . probably need this? pShaderAPI->SetPixelShaderConstant( 15, pos, 1 ); pShaderAPI->SetPixelShaderConstant( 16, worldToTexture.Base(), 4 ); if ( IsPC() && g_pHardwareConfig->HasFastVertexTextures() ) { SetupUberlightFromState( pShaderAPI, flashlightState ); } } } Draw(); }