/** 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; } } }
// 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 ); }
// Overridden to take into consideration the isDirectionalOnly property CC3Vector4 CC3Light::getGlobalHomogeneousPosition() { return (isDirectionalOnly() ? CC3Vector4().fromDirection(getGlobalLocation()) : CC3Vector4().fromLocation(getGlobalLocation())); }
CC3Vector4 CC3MeshNode::getGlobalLightPosition() { return (_material && _material->hasBumpMap()) ? getGlobalTransformMatrix()->transformHomogeneousVector( CC3Vector4().fromDirection(_material->getLightDirection()) ) : super::getGlobalLightPosition(); }