MaterialPtr AmbientOcclusionScene::createAmbientOcclusionMaterial( const QString& diffuse, const QString& aoFactors ) const { MaterialPtr material( new Material ); // Setup the shaders material->setShaders( ":/shaders/ambientocclusion.vert", ":/shaders/ambientocclusion.frag" ); // Create a diffuse texture TexturePtr diffuseTexture( new Texture( Texture::Texture2D ) ); diffuseTexture->create(); diffuseTexture->bind(); diffuseTexture->setImage( QImage( diffuse ) ); // Create the ambient occlusion factors texture TexturePtr aoTexture( new Texture( Texture::Texture2D ) ); aoTexture->create(); aoTexture->bind(); aoTexture->setImage( QImage( aoFactors ) ); #if !defined(Q_OS_MAC) // Create a sampler. This can be shared by both textures SamplerPtr sampler( new Sampler ); sampler->create(); sampler->setWrapMode( Sampler::DirectionS, GL_CLAMP_TO_EDGE ); sampler->setWrapMode( Sampler::DirectionT, GL_CLAMP_TO_EDGE ); sampler->setMinificationFilter( GL_LINEAR ); sampler->setMagnificationFilter( GL_LINEAR ); // We associate the diffuse texture with texture unit 0 and // the ao factors texture with unit 1 material->setTextureUnitConfiguration( 0, diffuseTexture, sampler, "diffuseTexture" ); material->setTextureUnitConfiguration( 1, aoTexture, sampler, "ambientOcclusionTexture" ); #else diffuseTexture->bind(); diffuseTexture->setWrapMode( Texture::DirectionS, GL_CLAMP_TO_EDGE ); diffuseTexture->setWrapMode( Texture::DirectionT, GL_CLAMP_TO_EDGE ); diffuseTexture->setMinificationFilter( GL_LINEAR ); diffuseTexture->setMagnificationFilter( GL_LINEAR ); aoTexture->bind(); aoTexture->setWrapMode( Texture::DirectionS, GL_CLAMP_TO_EDGE ); aoTexture->setWrapMode( Texture::DirectionT, GL_CLAMP_TO_EDGE ); aoTexture->setMinificationFilter( GL_LINEAR ); aoTexture->setMagnificationFilter( GL_LINEAR ); // We associate the diffuse texture with texture unit 0 and // the ao factors texture with unit 1 material->setTextureUnitConfiguration( 0, diffuseTexture, "diffuseTexture" ); material->setTextureUnitConfiguration( 1, aoTexture, "ambientOcclusionTexture" ); #endif return material; }
bool LightingShader::asFragmentProcessor(GrContext* context, const SkPaint& paint, const SkMatrix& viewM, const SkMatrix* localMatrix, GrColor* color, GrProcessorDataManager*, GrFragmentProcessor** fp) const { // we assume diffuse and normal maps have same width and height // TODO: support different sizes SkASSERT(fDiffuseMap.width() == fNormalMap.width() && fDiffuseMap.height() == fNormalMap.height()); SkMatrix matrix; matrix.setIDiv(fDiffuseMap.width(), fDiffuseMap.height()); SkMatrix lmInverse; if (!this->getLocalMatrix().invert(&lmInverse)) { return false; } if (localMatrix) { SkMatrix inv; if (!localMatrix->invert(&inv)) { return false; } lmInverse.postConcat(inv); } matrix.preConcat(lmInverse); // Must set wrap and filter on the sampler before requesting a texture. In two places below // we check the matrix scale factors to determine how to interpret the filter quality setting. // This completely ignores the complexity of the drawVertices case where explicit local coords // are provided by the caller. GrTextureParams::FilterMode textureFilterMode = GrTextureParams::kBilerp_FilterMode; switch (paint.getFilterQuality()) { case kNone_SkFilterQuality: textureFilterMode = GrTextureParams::kNone_FilterMode; break; case kLow_SkFilterQuality: textureFilterMode = GrTextureParams::kBilerp_FilterMode; break; case kMedium_SkFilterQuality:{ SkMatrix matrix; matrix.setConcat(viewM, this->getLocalMatrix()); if (matrix.getMinScale() < SK_Scalar1) { textureFilterMode = GrTextureParams::kMipMap_FilterMode; } else { // Don't trigger MIP level generation unnecessarily. textureFilterMode = GrTextureParams::kBilerp_FilterMode; } break; } case kHigh_SkFilterQuality: default: SkErrorInternals::SetError(kInvalidPaint_SkError, "Sorry, I don't understand the filtering " "mode you asked for. Falling back to " "MIPMaps."); textureFilterMode = GrTextureParams::kMipMap_FilterMode; break; } // TODO: support other tile modes GrTextureParams params(kClamp_TileMode, textureFilterMode); SkAutoTUnref<GrTexture> diffuseTexture(GrRefCachedBitmapTexture(context, fDiffuseMap, ¶ms)); if (!diffuseTexture) { SkErrorInternals::SetError(kInternalError_SkError, "Couldn't convert bitmap to texture."); return false; } SkAutoTUnref<GrTexture> normalTexture(GrRefCachedBitmapTexture(context, fNormalMap, ¶ms)); if (!normalTexture) { SkErrorInternals::SetError(kInternalError_SkError, "Couldn't convert bitmap to texture."); return false; } GrColor lightColor = GrColorPackRGBA(SkColorGetR(fLight.fColor), SkColorGetG(fLight.fColor), SkColorGetB(fLight.fColor), SkColorGetA(fLight.fColor)); GrColor ambientColor = GrColorPackRGBA(SkColorGetR(fAmbientColor), SkColorGetG(fAmbientColor), SkColorGetB(fAmbientColor), SkColorGetA(fAmbientColor)); *fp = SkNEW_ARGS(LightingFP, (diffuseTexture, normalTexture, matrix, fLight.fDirection, lightColor, ambientColor)); *color = GrColorPackA4(paint.getAlpha()); return true; }