Esempio n. 1
0
/** Initialise the environment for the specified grid size.
 * \param iGridRes Integer grid resolution.
 * \param iGridRes Integer grid resolution.
 */
void CqLightsource::Initialise( TqInt uGridRes, TqInt vGridRes, TqInt microPolygonCount, TqInt shadingPointCount, bool hasValidDerivatives )
{
	TqInt Uses = gDefLightUses;
	if ( m_pShader )
	{
		Uses |= m_pShader->Uses();
		m_pShaderExecEnv->Initialise( uGridRes, vGridRes, microPolygonCount, shadingPointCount, hasValidDerivatives, m_pAttributes, boost::shared_ptr<IqTransform>(), m_pShader.get(), Uses );
	}

	if ( m_pShader )
		m_pShader->Initialise( uGridRes, vGridRes, shadingPointCount, m_pShaderExecEnv.get() );

	if ( USES( Uses, EnvVars_L ) )
		L() ->Initialise( shadingPointCount );
	if ( USES( Uses, EnvVars_Cl ) )
		Cl() ->Initialise( shadingPointCount );

	// Initialise the geometric parameters in the shader exec env.
	if ( USES( Uses, EnvVars_P ) )
	{
		CqMatrix mat;
		QGetRenderContext() ->matSpaceToSpace( "shader", "current", m_pShader->getTransform(), NULL, QGetRenderContextI()->Time(), mat );
		P() ->SetPoint( mat * CqVector3D( 0.0f, 0.0f, 0.0f ) );
	}
	if ( USES( Uses, EnvVars_u ) )
		u() ->SetFloat( 0.0f );
	if ( USES( Uses, EnvVars_v ) )
		v() ->SetFloat( 0.0f );
	if ( USES( Uses, EnvVars_du ) )
		du() ->SetFloat( 0.0f );
	if ( USES( Uses, EnvVars_dv ) )
		dv() ->SetFloat( 0.0f );
	if ( USES( Uses, EnvVars_s ) )
		s() ->SetFloat( 0.0f );
	if ( USES( Uses, EnvVars_t ) )
		t() ->SetFloat( 0.0f );
	if ( USES( Uses, EnvVars_N ) )
		N() ->SetNormal( CqVector3D( 0.0f, 0.0f, 0.0f ) );
}
/****************************************************************************++

Routine Description:

    Wrapper fro CryptDestroyKey

Arguments:

    hKey - handle to the key to destroy

Notes:

    -

Return Value:

    - VOID

--*****************************************************************************/
VOID
DestroyKey(
    IN      HCRYPTKEY       hKey)
{
    if (NULL != hKey)
    {
        //
        // this is quite counter-intuitive API
        // CryptDestroyKey just releases the handle to the key, but only in case of
        // private/public key pairs.
        //
        if (!CryptDestroyKey(hKey))
        {
            HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
            USES(hr);
            //
            // should never happen, unless handle is invalid
            //
        }
    }
}
/****************************************************************************++

Routine Description:

    Releases the handle to the CSP

Arguments:

    hCryptProv - handle to the CSP

Notes:

    - handles the NULL CSP gracefully

Return Value:

    - VOID

--*****************************************************************************/
VOID
ReleaseCryptProv(
    IN      HCRYPTPROV      hCryptProv)
{
    if (NULL != hCryptProv)
    {
        if (!CryptReleaseContext(hCryptProv, 0))
        {
            //
            // one reason why this could fail (at least it failed a couple of times already) i s
            // that some certifcate store was opened using this CSP, but
            // CERT_STORE_NO_CRYPT_RELEASE_FLAG was not specified, so that
            // when cert store is released the provider is released as well.
            //
            // verify that all stores that were ever used, specify this flag
            //

            HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
            USES(hr);
        }
    }
}
Esempio n. 4
0
void CqShaderExecEnv::Initialise( const TqInt uGridRes, const TqInt vGridRes, 
								TqInt microPolygonCount, TqInt shadingPointCount, 
								bool hasValidDerivatives,
								const IqConstAttributesPtr& pAttr, 
								const IqConstTransformPtr& pTrans, 
								IqShader* pShader, 
								TqInt Uses )
{
	m_uGridRes = uGridRes;
	m_vGridRes = vGridRes;

	m_microPolygonCount = microPolygonCount;
	m_shadingPointCount = shadingPointCount;
	m_hasValidDerivatives = hasValidDerivatives;
	m_LocalIndex = 0;

	// Store a pointer to the attributes definition.
	m_pAttributes = pAttr;

	// Store a pointer to the transform.
	m_pTransform = pTrans;

	m_li = 0;
	m_Illuminate = 0;
	m_IlluminanceCacheValid = false;

	// Initialise the state bitvectors
	m_CurrentState.SetSize( m_shadingPointCount );
	m_RunningState.SetSize( m_shadingPointCount );
	m_RunningState.SetAll( true );
	m_isRunning = true;


	if ( pShader )
	{
		if ( USES( Uses, EnvVars_P ) && m_apVariables[ EnvVars_P ] == 0 )
			m_apVariables[ EnvVars_P ] = pShader->CreateVariable( type_point, class_varying, gVariableNames[ EnvVars_P ] );
		if ( USES( Uses, EnvVars_Cs ) && m_apVariables[ EnvVars_Cs ] == 0 )
			m_apVariables[ EnvVars_Cs ] = pShader->CreateVariable( type_color, class_varying, gVariableNames[ EnvVars_Cs ] );
		if ( USES( Uses, EnvVars_Os ) && m_apVariables[ EnvVars_Os ] == 0 )
			m_apVariables[ EnvVars_Os ] = pShader->CreateVariable( type_color, class_varying, gVariableNames[ EnvVars_Os ] );
		if ( USES( Uses, EnvVars_Ng ) && m_apVariables[ EnvVars_Ng ] == 0 )
			m_apVariables[ EnvVars_Ng ] = pShader->CreateVariable( type_normal, class_varying, gVariableNames[ EnvVars_Ng ] );
		if ( USES( Uses, EnvVars_du ) && m_apVariables[ EnvVars_du ] == 0 )
			m_apVariables[ EnvVars_du ] = pShader->CreateVariable( type_float, class_varying, gVariableNames[ EnvVars_du ] );
		if ( USES( Uses, EnvVars_dv ) && m_apVariables[ EnvVars_dv ] == 0 )
			m_apVariables[ EnvVars_dv ] = pShader->CreateVariable( type_float, class_varying, gVariableNames[ EnvVars_dv ] );
		if ( USES( Uses, EnvVars_L ) && m_apVariables[ EnvVars_L ] == 0 )
			m_apVariables[ EnvVars_L ] = pShader->CreateVariable( type_vector, class_varying, gVariableNames[ EnvVars_L ] );
		if ( USES( Uses, EnvVars_Cl ) && m_apVariables[ EnvVars_Cl ] == 0 )
			m_apVariables[ EnvVars_Cl ] = pShader->CreateVariable( type_color, class_varying, gVariableNames[ EnvVars_Cl ] );
		if ( USES( Uses, EnvVars_Ol ) && m_apVariables[ EnvVars_Ol ] == 0 )
			m_apVariables[ EnvVars_Ol ] = pShader->CreateVariable( type_color, class_varying, gVariableNames[ EnvVars_Ol ] );
		if ( USES( Uses, EnvVars_dPdu ) && m_apVariables[ EnvVars_dPdu ] == 0 )
			m_apVariables[ EnvVars_dPdu ] = pShader->CreateVariable( type_vector, class_varying, gVariableNames[ EnvVars_dPdu ] );
		if ( USES( Uses, EnvVars_dPdv ) && m_apVariables[ EnvVars_dPdv ] == 0 )
			m_apVariables[ EnvVars_dPdv ] = pShader->CreateVariable( type_vector, class_varying, gVariableNames[ EnvVars_dPdv ] );
		if ( USES( Uses, EnvVars_N ) && m_apVariables[ EnvVars_N ] == 0 )
			m_apVariables[ EnvVars_N ] = pShader->CreateVariable( type_normal, class_varying, gVariableNames[ EnvVars_N ] );
		if ( USES( Uses, EnvVars_u ) && m_apVariables[ EnvVars_u ] == 0 )
			m_apVariables[ EnvVars_u ] = pShader->CreateVariable( type_float, class_varying, gVariableNames[ EnvVars_u ] );
		if ( USES( Uses, EnvVars_v ) && m_apVariables[ EnvVars_v ] == 0 )
			m_apVariables[ EnvVars_v ] = pShader->CreateVariable( type_float, class_varying, gVariableNames[ EnvVars_v ] );
		if ( USES( Uses, EnvVars_s ) && m_apVariables[ EnvVars_s ] == 0 )
			m_apVariables[ EnvVars_s ] = pShader->CreateVariable( type_float, class_varying, gVariableNames[ EnvVars_s ] );
		if ( USES( Uses, EnvVars_t ) && m_apVariables[ EnvVars_t ] == 0 )
			m_apVariables[ EnvVars_t ] = pShader->CreateVariable( type_float, class_varying, gVariableNames[ EnvVars_t ] );
		if ( USES( Uses, EnvVars_I ) && m_apVariables[ EnvVars_I ] == 0 )
			m_apVariables[ EnvVars_I ] = pShader->CreateVariable( type_vector, class_varying, gVariableNames[ EnvVars_I ] );
		if ( USES( Uses, EnvVars_Ci ) && m_apVariables[ EnvVars_Ci ] == 0 )
			m_apVariables[ EnvVars_Ci ] = pShader->CreateVariable( type_color, class_varying, gVariableNames[ EnvVars_Ci ] );
		if ( USES( Uses, EnvVars_Oi ) && m_apVariables[ EnvVars_Oi ] == 0 )
			m_apVariables[ EnvVars_Oi ] = pShader->CreateVariable( type_color, class_varying, gVariableNames[ EnvVars_Oi ] );
		if ( USES( Uses, EnvVars_Ps ) && m_apVariables[ EnvVars_Ps ] == 0 )
			m_apVariables[ EnvVars_Ps ] = pShader->CreateVariable( type_point, class_varying, gVariableNames[ EnvVars_Ps ] );
		if ( USES( Uses, EnvVars_E ) && m_apVariables[ EnvVars_E ] == 0 )
			m_apVariables[ EnvVars_E ] = pShader->CreateVariable( type_point, class_uniform, gVariableNames[ EnvVars_E ] );
		if ( USES( Uses, EnvVars_ncomps ) && m_apVariables[ EnvVars_ncomps ] == 0 )
			m_apVariables[ EnvVars_ncomps ] = pShader->CreateVariable( type_float, class_uniform, gVariableNames[ EnvVars_ncomps ] );
		if ( USES( Uses, EnvVars_time ) && m_apVariables[ EnvVars_time ] == 0 )
			m_apVariables[ EnvVars_time ] = pShader->CreateVariable( type_float, class_uniform, gVariableNames[ EnvVars_time ] );
		if ( USES( Uses, EnvVars_alpha ) && m_apVariables[ EnvVars_alpha ] == 0 )
			m_apVariables[ EnvVars_alpha ] = pShader->CreateVariable( type_float, class_varying, gVariableNames[ EnvVars_alpha ] );
		if ( USES( Uses, EnvVars_Ns ) && m_apVariables[ EnvVars_Ns ] == 0 )
			m_apVariables[ EnvVars_Ns ] = pShader->CreateVariable( type_normal, class_varying, gVariableNames[ EnvVars_Ns ] );
	}

	TqInt i;
	for ( i = 0; i < EnvVars_Last; i++ )
	{
		if ( m_apVariables[ i ] && USES( Uses, i ) )
			m_apVariables[ i ] ->Initialise( shadingPointCount );
	}

	if( USES( Uses, EnvVars_time ) )
	{
		// First try setting this to the shutter open time
		// @todo: Think about an algorithm which distributes samples in time

		const TqFloat* shutter = getRenderContext()->GetFloatOption( "System", "Shutter" );
		if( shutter )
		{
			const TqFloat* shutteroffset = getRenderContext()->GetFloatOption( "shutter", "offset" );
			float offset = 0;
			if( shutteroffset != 0 )
			{
				offset = *shutteroffset;
			}

			// insert the open time plus shutter offset
			m_apVariables[ EnvVars_time ]->SetFloat(  shutter[ 0 ] + offset );
		}
	}

	m_diffUidx.resize(shadingPointCount);
	m_diffVidx.resize(shadingPointCount);
	TqInt uSize = uGridRes+1;
	TqInt vSize = vGridRes+1;
	if(hasValidDerivatives)
	{
		// Precompute lookup tables from the shading index to u,v indices, to
		// avoid costly modulo and integer operations in derivative functions.
		for(TqInt v = 0, i = 0; v < vSize; ++v)
		{
			for(TqInt u = 0; u < uSize; ++u, ++i)
			{
				m_diffUidx[i] = u;
				m_diffVidx[i] = v;
			}
		}
	}

	// Determine whether to use centred differences or not.
	bool useCentred = true;
	if(pAttr)
	{
		if(const TqInt* centred = pAttr->GetIntegerAttribute("derivatives", "centered"))
			useCentred = (centred[0] == 1);
		else
			useCentred = (pAttr->GetIntegerAttribute("System", "ShadingInterpolation")[0]
						== ShadingInterp_Smooth);
	}

	m_diff.reset(uSize, vSize, !hasValidDerivatives, !hasValidDerivatives,
				 useCentred);
}
/****************************************************************************++

Routine Description:

    Creates a handle to the CSP

Arguments:

    pwzContainerName - name of the container to be created. if NULL, GUID is generated
                      for the name of the container

    fCreateNewKeys   - forces new keys to be created

    phCryptProv      - pointer to the location, where handle should be returned

Notes:

    -

Return Value:

    - S_OK

      - or -

    - CAPI error returned by CryptAcquireContextW

--*****************************************************************************/
HRESULT
CreateCryptProv(
    IN      PCWSTR          pwzContainerName,
    IN      BOOL            fCreateNewKeys,
    OUT     HCRYPTPROV*     phCryptProv)
{

    HRESULT         hr = S_OK;
    HCRYPTKEY       hKey = NULL;
    RPC_STATUS      status =  RPC_S_OK;
    BOOL            fCreatedContainer = FALSE;
    WCHAR*          pwzNewContainerName = NULL;

    *phCryptProv = NULL;

    if (NULL == pwzContainerName)
    {
         UUID    uuid;
         BOOL   fServiceAccount = FALSE;

        //
        // generate container name from the UUID
        //
        status = UuidCreate(&uuid);
        hr = HRESULT_FROM_RPCSTATUS(status);
        if (FAILED(hr))
        {
            goto Cleanup;
        }

        status = UuidToStringW(&uuid, (unsigned short**)&pwzNewContainerName);
        hr = HRESULT_FROM_RPCSTATUS(status);
        if (FAILED(hr))
        {
            goto Cleanup;
        }

        pwzContainerName = pwzNewContainerName;

        hr = IsServiceAccount(&fServiceAccount);
        if (FAILED(hr))
        {
            goto Cleanup;
        }

        //
        // open the clean key container
        //
        // note: CRYPT_NEW_KEYSET is not creating new keys, it just
        // creates new key container. duh.
        //
        if (!CryptAcquireContextW(phCryptProv,
                                pwzNewContainerName,
                                NULL,               // default provider name
                                DEFAULT_PROV_TYPE,
                                fServiceAccount ?
                                    (CRYPT_SILENT | CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET) :
                                    (CRYPT_SILENT | CRYPT_NEWKEYSET)))
        {
            hr = HRESULT_FROM_WIN32(GetLastError());

            //
            // we are seeing that CryptAcquireContextW returns NTE_FAIL under low
            // memory condition, so we just mask the error
            //
            if (NTE_FAIL == hr)
            {
                hr = E_OUTOFMEMORY;
            }

            goto Cleanup;
        }

        fCreatedContainer = TRUE;

    }
    else
    {
        BOOL    fServiceAccount = FALSE;

        hr = IsServiceAccount(&fServiceAccount);
        if (FAILED(hr))
        {
            goto Cleanup;
        }

        //
        // open the provider first, create the keys too
        //
        if (!CryptAcquireContextW(phCryptProv,
                            pwzContainerName,
                            NULL,               // default provider name
                            DEFAULT_PROV_TYPE,
                            fServiceAccount ?
                                (CRYPT_SILENT | CRYPT_MACHINE_KEYSET) :
                                (CRYPT_SILENT)))
        {
            hr = HRESULT_FROM_WIN32(GetLastError());

            //
            // we are seeing that CryptAcquireContextW returns NTE_FAIL under low
            // memory condition, so we just mask the error
            //
            if (NTE_FAIL == hr)
            {
                hr = E_OUTOFMEMORY;
            }

            goto Cleanup;
        }
    }

    if (fCreateNewKeys)
    {
        //
        // make sure keys exist
        //
        if (!CryptGetUserKey(*phCryptProv,
                            DEFAULT_KEY_SPEC,
                            &hKey))
        {
            hr = HRESULT_FROM_WIN32(GetLastError());

            // if key does not exist, create it
            if (HRESULT_FROM_WIN32((unsigned long)NTE_NO_KEY) == hr)
            {
                hr = S_OK;

                if (!CryptGenKey(*phCryptProv,
                                  DEFAULT_KEY_SPEC,
                                  CRYPT_EXPORTABLE,
                                  &hKey))
                {
                    hr = HRESULT_FROM_WIN32(GetLastError());

                    //
                    // we are seeing that CryptGenKey returns ERROR_CANTOPEN under low
                    // memory condition, so we just mask the error
                    //
                    if (HRESULT_FROM_WIN32(ERROR_CANTOPEN) == hr)
                    {
                        hr = E_OUTOFMEMORY;
                    }

                    goto Cleanup;
                }

            }
            else
            {
                // failed to get user key by some misterious reason, so bail out
                goto Cleanup;
            }
        }
    }

Cleanup:

    DestroyKey(hKey);

    if (FAILED(hr))
    {

        //
        // release the context
        //
        ReleaseCryptProv(*phCryptProv);
        *phCryptProv = NULL;

        //
        // delete the keys, if we created them
        //
        if (fCreatedContainer)
        {
            DeleteKeys(pwzContainerName);
        }
    }

    if (NULL != pwzNewContainerName)
    {
        // this always returns RPC_S_OK
        status = RpcStringFreeW((unsigned short**)&pwzNewContainerName);
        USES(status);
    }

    return hr;
}