/** Populates the initial values of the uniform, based on the size and type. */
void CC3GLSLUniform::populateInitialValue()
{
	for (GLint vIdx = 0 ; vIdx < _size; vIdx++) 
	{
		CC3Matrix3x3 m3x3;
		CC3Matrix4x4 m4x4;
		
		switch (_type) 
		{		
			case GL_FLOAT:
			case GL_FLOAT_VEC2:
			case GL_FLOAT_VEC3:
			case GL_FLOAT_VEC4:
				setVector4( CC3Vector4(0.0f, 0.0f, 0.0f, 1.0f), vIdx );
				return;
				
			case GL_FLOAT_MAT2:
				setVector4( CC3Vector4(1.0f, 0.0f, 0.0f, 1.0f), vIdx );
				return;
			case GL_FLOAT_MAT3:
				CC3Matrix3x3PopulateIdentity(&m3x3);
				setMatrix3x3( &m3x3, vIdx );
				return;
			case GL_FLOAT_MAT4:
				CC3Matrix4x4PopulateIdentity(&m4x4);
				setMatrix4x4( &m4x4, vIdx );
				return;
				
			case GL_INT:
			case GL_INT_VEC2:
			case GL_INT_VEC3:
			case GL_INT_VEC4:
			case GL_SAMPLER_2D:
			case GL_SAMPLER_CUBE:
			case GL_BOOL:
			case GL_BOOL_VEC2:
			case GL_BOOL_VEC3:
			case GL_BOOL_VEC4:
				setIntVector4( CC3IntVector4Make(0, 0, 0, 1), vIdx );
				return;
				
			default:
				CCAssert(false, "CC3GLSLUniform could not set value because type %s is not understood"/*,
						  stringFromGLEnum(_type).c_str()*/);
				return;
		}
	}
	
}
Exemple #2
0
// The direction of a light in a POD file is taken from the transform of the up direction!
CC3Vector4 CC3PODLight::getGlobalHomogeneousPosition()
{
	if (isDirectionalOnly()) 
		return CC3Vector4().fromCC3Vector(getGlobalUpDirection(), 0.0f);

	return super::getGlobalHomogeneousPosition();
}
/** Handles populating PVRShaman-specific content and delegates remainder to the standard population mechanisms.  */
bool CC3PVRShamanShaderSemantics::populateUniform( CC3GLSLUniform* uniform, CC3NodeDrawingVisitor* visitor )
{
	//LogTrace(@"%@ retrieving semantic value for %@", self, uniform.fullDescription);
	GLenum semantic = uniform->getSemantic();
	GLuint semanticIndex = uniform->getSemanticIndex();
	GLint uniformSize = uniform->getSize();
	CC3Viewport vp;

	if ( super::populateUniform( uniform, visitor ) )
		return true;
	
	switch (semantic)
	{
		// Sets a vec2, specific to PVRShaman, that combines the falloff angle (in degrees) and exponent
		case kCC3PVRShamanSemanticLightSpotFalloff:
			for (GLint i = 0; i < uniformSize; i++) 
			{
				CC3Light* light = visitor->getLightAt( semanticIndex + i );
				uniform->setPoint( ccp(light->getSpotCutoffAngle(), light->getSpotExponent()), i );
			}
			return true;
		case kCC3PVRShamanSemanticElapsedTimeLastFrame:
			// Time of last frame. Just subtract frame time from current time
			uniform->setFloat( visitor->getScene()->getElapsedTimeSinceOpened() - visitor->getDeltaTime() );
			return true;
		case kCC3PVRShamanSemanticViewportSize:
			vp = visitor->getRenderSurface()->getViewport();
			uniform->setPoint( ccp(vp.w, vp.h) );
			return true;
		case kCC3PVRShamanSemanticViewportClipping: 
			{
				// Applies the field of view angle to the narrower aspect.
				vp = visitor->getRenderSurface()->getViewport();
				GLfloat aspect = (GLfloat) vp.w / (GLfloat) vp.h;
				CC3Camera* cam = visitor->getCamera();
				GLfloat fovWidth, fovHeight;
				if (aspect >= 1.0f) {			// Landscape
					fovHeight = CC3DegToRad(cam->getEffectiveFieldOfView());
					fovWidth = fovHeight * aspect;
				} else {						// Portrait
					fovWidth = CC3DegToRad(cam->getEffectiveFieldOfView());
					fovHeight = fovWidth / aspect;
				}
				uniform->setVector4( CC3Vector4(cam->getNearClippingDistance(), cam->getFarClippingDistance(), fovWidth, fovHeight) );
				return true;
			}
		default: 
			return false;
	}
}
void CC3GLSLUniform::setIntVector4( const CC3IntVector4& value, GLuint index )
{
	CCAssert((GLint)index < _size, "CC3GLSLUniform could not set value because index %d is out of bounds"/*, index*/);
	
	switch (_type) 
	{		
		case GL_FLOAT:
		case GL_FLOAT_VEC2:
		case GL_FLOAT_VEC3:
		case GL_FLOAT_VEC4:
		case GL_FLOAT_MAT2:
			setVector4( CC3Vector4((GLfloat)value.x, (GLfloat)value.y, (GLfloat)value.z, (GLfloat)value.w), index );
			return;
			
		case GL_FLOAT_MAT3:
		case GL_FLOAT_MAT4:
			CCAssert(false, "CC3GLSLUniform attempted to set scalar or vector when matrix type %s expected."/*,
					 stringFromGLEnum(_type).c_str()*/);
			return;
			
		case GL_INT:
		case GL_BOOL:
		case GL_SAMPLER_2D:
		case GL_SAMPLER_CUBE:
			((GLint*)m_varValue)[index] = *(GLint*)&value;
			return;
		case GL_INT_VEC2:
		case GL_BOOL_VEC2:
			((CC3IntPoint*)m_varValue)[index] = *(CC3IntPoint*)&value;
			return;
		case GL_INT_VEC3:
		case GL_BOOL_VEC3:
			((CC3IntVector*)m_varValue)[index] = *(CC3IntVector*)&value;
			return;
		case GL_INT_VEC4:
		case GL_BOOL_VEC4:
			((CC3IntVector4*)m_varValue)[index] = value;
			return;
			
		default:
			CCAssert(false, "CC3GLSLUniform could not set value because type %s is not understood"/*,
					  stringFromGLEnum(_type).c_str()*/);
			return;
	}
	CC3_TRACE("CC3GLSLUniform setting value to (%d, %d, %d, %d)", value.x, value.y, value.z, value.w);
}
/**
 * Returns a 4D directional vector which can be added to each vertex when creating
 * the shadow volume vertices from the corresponding shadow caster vertices.
 *
 * The returned vector is in the local coordinate system of the shadow caster.
 *
 * The returned directional vector is a small offset vector in the direction away
 * from the light. A unit vector in that direction is scaled by both the distance
 * from the center of the shadow casting node to the camera and the
 * shadowVolumeVertexOffsetFactor property. Hence, if the shadow caster is farther
 * away from the camera, the returned value will be larger, to reduce the chance
 * of Z-fighting between the faces of the shadow volume and the shadow caster.
 */
CC3Vector4 CC3ShadowVolumeMeshNode::getShadowVolumeVertexOffsetForLightAt( const CC3Vector4& localLightPos )
{
	CC3Vector scLoc = getShadowCaster()->getLocalContentCenterOfGeometry();
	CC3Vector lgtLoc = localLightPos.cc3Vector();
	CC3Vector camLoc = getShadowCaster()->getGlobalTransformMatrixInverted()->transformLocation( getActiveCamera()->getGlobalLocation() );	

	// Get a unit offset vector in the direction away from the light
	CC3Vector offsetDir = (_light->isDirectionalOnly()
												? lgtLoc.negate() 
												: scLoc.difference( lgtLoc )).normalize();

	// Get the distance from the shadow caster CoG and the camera, and scale the
	// unit offset vector by that distance and the shadowVolumeVertexOffsetFactor
	GLfloat camDist = scLoc.distance( camLoc );
	CC3Vector offset = offsetDir.scaleUniform( camDist * _shadowVolumeVertexOffsetFactor );
	CC3_TRACE("CC3ShadowVolumeMeshNode nudging vertices by %s", offset.stringfy().c_str());

	// Create and return a 4D directional vector from the offset
	return CC3Vector4().fromDirection(offset);
}
void CC3GLSLUniform::setColor4F( const ccColor4F& value, GLuint index )
{
	switch (_type) 
	{		
		case GL_FLOAT:
		case GL_FLOAT_VEC2:
		case GL_FLOAT_VEC3:
		case GL_FLOAT_VEC4:
		case GL_FLOAT_MAT2:
			setVector4( CC3Vector4(value.r, value.g, value.b, value.a), index );
			return;

		case GL_FLOAT_MAT3:
		case GL_FLOAT_MAT4:
			CCAssert(false, "CC3GLSLUniform attempted to set color when matrix type %s expected."/*,
					 stringFromGLEnum(_type).c_str()*/);
			return;

		case GL_INT:
		case GL_BOOL:
		case GL_INT_VEC2:
		case GL_BOOL_VEC2:
		case GL_INT_VEC3:
		case GL_BOOL_VEC3:
		case GL_INT_VEC4:
		case GL_BOOL_VEC4:
		case GL_SAMPLER_2D:
		case GL_SAMPLER_CUBE:
			setColor4B( CCC4BFromCCC4F(value) );
			return;

		default:
			CCAssert(false, "CC3GLSLUniform could not set value because type %s is not understood"/*,
					  stringFromGLEnum(_type).c_str()*/ );
			return;
	}
}
void CC3GLSLUniform::setVector( const CC3Vector& value, GLuint index )
{
	setVector4( CC3Vector4(value.x, value.y, value.z, 1.0f), index );
}
void CC3GLSLUniform::setPoint( const CCPoint& value, GLuint index )
{
	setVector4( CC3Vector4(value.x, value.y, 0.0f, 1.0f), index );
}
void CC3GLSLUniform::setFloat( GLfloat value, GLuint index )
{
	setVector4( CC3Vector4(value, 0.0f, 0.0f, 1.0f), index );
}
Exemple #10
0
// Overridden to take into consideration the isDirectionalOnly property
CC3Vector4 CC3Light::getGlobalHomogeneousPosition()
{
	return (isDirectionalOnly()
			? CC3Vector4().fromDirection(getGlobalLocation())
			: CC3Vector4().fromLocation(getGlobalLocation()));
}
Exemple #11
0
CC3Vector4 CC3MeshNode::getGlobalLightPosition()
{
	return (_material && _material->hasBumpMap())
				? getGlobalTransformMatrix()->transformHomogeneousVector( CC3Vector4().fromDirection(_material->getLightDirection()) )
				: super::getGlobalLightPosition();
}