Пример #1
0
CqImagersource::CqImagersource( const boost::shared_ptr<IqShader>& pShader, bool fActive ) :
		m_pShader( pShader ),
		m_pAttributes(), 
		m_pShaderExecEnv(IqShaderExecEnv::create(QGetRenderContextI()))
{
	m_pAttributes = QGetRenderContext()->pattrCurrent();
	m_pShader->SetType(Type_Imager);
}
Пример #2
0
CqLightsource::CqLightsource( const boost::shared_ptr<IqShader>& pShader, bool fActive ) :
		m_pShader( pShader ),
		m_pAttributes(),
		m_pTransform(),
		m_pShaderExecEnv(IqShaderExecEnv::create(QGetRenderContextI()))
{
	// Set a reference with the current attributes.
	m_pAttributes = QGetRenderContext() ->pattrCurrent();

	m_pShader->SetType(Type_Lightsource);
	m_pTransform = QGetRenderContext() ->ptransCurrent();
}
Пример #3
0
bool CqCurve::Diceable()
{
	// OK, here the CqCubicCurveSegment line has two options:
	//  1. split into two more lines
	//  2. turn into a bilinear patch for rendering
	// We don't want to go turning into a patch unless absolutely
	// necessary, since patches cost more.  We only want to become a patch
	// if the current curve is "best handled" as a patch.  For now, I'm
	// choosing to define that the curve is best handled as a patch under
	// one or more of the following two conditions:
	//  1. If the maximum width is a significant fraction of the length of
	//      the line (width greater than 0.75 x length; ignoring normals).
	//  2. If the length of the line (ignoring the width; cos' it's
	//      covered by point 1) is such that it's likely a bilinear
	//      patch would be diced immediately if we created one (so that
	//      patches don't have to get split!).
	//  3. If the curve crosses the eye plane (m_fDiceable == false).

	// find the length of the CqLinearCurveSegment line in raster space
	if( m_splitDecision == Split_Undecided )
	{
		// AGG - 31/07/04
		// well, if we follow the above statagy we end up splitting into
		// far too many grids (with roughly 1 mpg per grid). so after
		// profiling a few scenes, the fastest method seems to be just
		// to convert to a patch immediatly.
		// we really need a native dice for curves but until that time
		// i reckon this is best.
		//m_splitDecision = Split_Patch;

		CqMatrix matCtoR;
		QGetRenderContext() ->matSpaceToSpace(
									"camera", "raster",
									NULL, NULL,
									QGetRenderContextI()->Time(),
									matCtoR
									);
		// control hull
		CqVector2D hull[2] = {
			vectorCast<CqVector2D>(matCtoR * P()->pValue(0)[0]),
			vectorCast<CqVector2D>(matCtoR * P()->pValue(1)[0])
		};
		CqVector2D lengthVector = hull[ 1 ] - hull[ 0 ];
		TqFloat lengthraster = lengthVector.Magnitude();

		// find the approximate "length" of a diced patch in raster space
		TqFloat gridlength = GetGridLength();

		// decide whether to split into more curve segments or a patch
		if(( lengthraster < gridlength ) || ( !m_fDiceable ))
		{
			// split into a patch
			m_splitDecision = Split_Patch;
		}
		else
		{
			// split into smaller curves
			m_splitDecision = Split_Curve;
		}
	}

	return false;
}
Пример #4
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 ) );
}
Пример #5
0
void CqImageBuffer::PostSurface( const boost::shared_ptr<CqSurface>& pSurface )
{
	AQSIS_TIME_SCOPE(Post_surface);
	// Count the number of total gprims
	STATS_INC( GPR_created_total );

	// Bound the primitive in its current space (camera) space taking into account any motion specification.
	CqBound Bound;
	pSurface->Bound(&Bound);

	// Take into account the displacement bound extension.
	TqFloat db = 0.0f;
	CqString strCoordinateSystem( "object" );
	const TqFloat* pattrDispclacementBound = pSurface->pAttributes() ->GetFloatAttribute( "displacementbound", "sphere" );
	const CqString* pattrCoordinateSystem = pSurface->pAttributes() ->GetStringAttribute( "displacementbound", "coordinatesystem" );
	if ( pattrDispclacementBound != 0 )
		db = pattrDispclacementBound[ 0 ];
	if ( pattrCoordinateSystem != 0 )
		strCoordinateSystem = pattrCoordinateSystem[ 0 ];

	if ( db != 0.0f )
	{
		CqVector3D	vecDB( db, 0, 0 );
		const IqTransform* transShaderToWorld = NULL;
		// Default "shader" space to the displacement shader, unless there isn't one, in which
		// case use the surface shader.
		if ( pSurface->pAttributes() ->pshadDisplacement(QGetRenderContextI()->Time()) )
			transShaderToWorld = pSurface->pAttributes() ->pshadDisplacement(QGetRenderContextI()->Time()) ->getTransform();
		else if ( pSurface->pAttributes() ->pshadSurface(QGetRenderContextI()->Time()) )
			transShaderToWorld = pSurface->pAttributes() ->pshadSurface(QGetRenderContextI()->Time()) ->getTransform();
		CqMatrix mat;
		QGetRenderContext() ->matVSpaceToSpace( strCoordinateSystem.c_str(), "camera", transShaderToWorld, pSurface->pTransform().get(), QGetRenderContextI()->Time(), mat );
		vecDB = mat * vecDB;
		db = vecDB.Magnitude();

		Bound.vecMax() += db;
		Bound.vecMin() -= db;
	}

	// Check if the surface can be culled. (also adjusts for DOF and converts Bound to raster space).
	if ( CullSurface( Bound, pSurface ) )
	{
		STATS_INC( GPR_culled );
		return ;
	}

	// If the primitive has been marked as undiceable by the eyeplane check, then we cannot get a valid
	// bucket index from it as the projection of the bound would cross the camera plane and therefore give a false
	// result, so just put it back in the current bucket for further splitting.
	TqInt XMinb = 0;
	TqInt YMinb = 0;
	TqInt XMaxb = 0;
	TqInt YMaxb = 0;
	if (! pSurface->IsUndiceable() )
	{
		XMinb = static_cast<TqInt>( Bound.vecMin().x() ) / m_optCache.xBucketSize;
		YMinb = static_cast<TqInt>( Bound.vecMin().y() ) / m_optCache.yBucketSize;
		XMaxb = static_cast<TqInt>( Bound.vecMax().x() ) / m_optCache.xBucketSize;
		YMaxb = static_cast<TqInt>( Bound.vecMax().y() ) / m_optCache.yBucketSize;
	}
	XMinb = clamp( XMinb, m_bucketRegion.xMin(), m_bucketRegion.xMax()-1 );
	YMinb = clamp( YMinb, m_bucketRegion.yMin(), m_bucketRegion.yMax()-1 );
	XMaxb = clamp( XMaxb, m_bucketRegion.xMin(), m_bucketRegion.xMax()-1 );
	YMaxb = clamp( YMaxb, m_bucketRegion.yMin(), m_bucketRegion.yMax()-1 );

	// Sanity check we are not putting into a bucket that has already been processed.
	CqBucket* bucket = &Bucket( XMinb, YMinb );
	if ( bucket->IsProcessed() )
	{
		// Scan over the buckets that the bound touches, looking for the first one that isn't processed.
		TqInt yb = YMinb;
		TqInt xb = XMinb + 1;
		bool done = false;
		while(!done && yb <= YMaxb)
		{
			while(!done && xb <= XMaxb)
			{
				CqBucket& availBucket = Bucket(xb, yb);
				if(!availBucket.IsProcessed())
				{
					availBucket.AddGPrim(pSurface);
					done = true;
				}
				++xb;
			}
			xb = XMinb;
			++yb;
		}
	}
	else
	{
		bucket->AddGPrim( pSurface );
	}
}