1 /* 2 Copyright (c) 2008-2009 NetAllied Systems GmbH 3 4 This file is part of COLLADASaxFrameworkLoader. 5 6 Licensed under the MIT Open Source License, 7 for details please see LICENSE file or the website 8 http://www.opensource.org/licenses/mit-license.php 9 */ 10 11 #include "COLLADASaxFWLStableHeaders.h" 12 #include "COLLADASaxFWLLibraryEffectsLoader.h" 13 #include "COLLADASaxFWLFileLoader.h" 14 15 #include "COLLADAFWIWriter.h" 16 #include "COLLADAFWEffect.h" 17 #include "COLLADAFWImage.h" 18 19 20 namespace COLLADASaxFWL 21 { 22 23 //------------------------------ LibraryEffectsLoader(IFilePartLoader * callingFilePartLoader)24 LibraryEffectsLoader::LibraryEffectsLoader( IFilePartLoader* callingFilePartLoader ) 25 : LibraryImagesLoader(callingFilePartLoader) 26 , mCurrentEffect(0) 27 , mTransparency(1) 28 , mOpaqueMode(UNSPECIFIED_OPAQUE) 29 , mCurrentProfile(PROFILE_NONE) 30 , mCurrentShaderParameterType(UNKNOWN_SHADER_TYPE) 31 , mCurrentColorValueIndex(0) 32 , mCurrentSamplerWrapS(COLLADAFW::Sampler::WRAP_MODE_WRAP) 33 , mCurrentSamplerWrapT(COLLADAFW::Sampler::WRAP_MODE_WRAP) 34 , mCurrentSampler(0) 35 , mNextSamplerIndex(0) 36 , mInProfileCommonTechnique (false) 37 , mInTexture (false) 38 , mInSurface (false) 39 , mSurfaceIndex (0) 40 , mInSampler2D (false) 41 { 42 } 43 44 //------------------------------ ~LibraryEffectsLoader()45 LibraryEffectsLoader::~LibraryEffectsLoader() 46 { 47 } 48 49 //------------------------------ setCommonEffectShaderType(COLLADAFW::EffectCommon::ShaderType shaderType)50 bool LibraryEffectsLoader::setCommonEffectShaderType( COLLADAFW::EffectCommon::ShaderType shaderType ) 51 { 52 switch ( mCurrentProfile ) 53 { 54 case PROFILE_COMMON: 55 mCurrentEffect->getCommonEffects().back()->setShaderType( shaderType ); 56 break; 57 default: 58 break; 59 } 60 return true; 61 } 62 63 //------------------------------ getCurrentColorOrTexture(const bool forTexture)64 COLLADAFW::ColorOrTexture* LibraryEffectsLoader::getCurrentColorOrTexture ( const bool forTexture /*= false*/) 65 { 66 switch ( mCurrentShaderParameterType ) 67 { 68 case SHADER_PARAMETER_EMISSION: 69 { 70 return &mCurrentEffect->getCommonEffects().back()->getEmission(); 71 } 72 case SHADER_PARAMETER_AMBIENT: 73 { 74 return &mCurrentEffect->getCommonEffects().back()->getAmbient(); 75 } 76 case SHADER_PARAMETER_DIFFUSE: 77 { 78 return &mCurrentEffect->getCommonEffects().back()->getDiffuse(); 79 } 80 case SHADER_PARAMETER_SPECULAR: 81 { 82 return &mCurrentEffect->getCommonEffects().back()->getSpecular(); 83 } 84 case SHADER_PARAMETER_REFLECTIVE: 85 { 86 return &mCurrentEffect->getCommonEffects().back()->getReflective(); 87 } 88 case SHADER_PARAMETER_TRANSPARENT: 89 { 90 if ( forTexture ) 91 return &mCurrentEffect->getCommonEffects().back()->getOpacity(); 92 else 93 return &mTransparent; 94 } 95 default: 96 return 0; 97 } 98 } 99 100 //------------------------------ handleColorData(const float * data,size_t length)101 bool LibraryEffectsLoader::handleColorData( const float* data, size_t length ) 102 { 103 switch ( mCurrentProfile ) 104 { 105 case PROFILE_COMMON: 106 { 107 COLLADAFW::ColorOrTexture* colorOrTexture = getCurrentColorOrTexture(); 108 colorOrTexture->setType(COLLADAFW::ColorOrTexture::COLOR); 109 handleColorData(data, length, colorOrTexture->getColor()); 110 111 break; 112 } 113 default: 114 break; 115 } 116 return true; 117 118 } 119 120 //------------------------------ handleColorData(const float * data,size_t length,COLLADAFW::Color & color)121 bool LibraryEffectsLoader::handleColorData( const float* data, size_t length, COLLADAFW::Color& color ) 122 { 123 for ( size_t i = 0; i < length; ++i) 124 { 125 switch ( mCurrentColorValueIndex ) 126 { 127 case 0: 128 color.setRed(data[i]); 129 break; 130 case 1: 131 color.setGreen(data[i]); 132 break; 133 case 2: 134 color.setBlue(data[i]); 135 break; 136 case 3: 137 color.setAlpha(data[i]); 138 break; 139 } 140 mCurrentColorValueIndex++; 141 } 142 return true; 143 } 144 145 146 //------------------------------ handleTexture(const texture__AttributeData & attributeData)147 bool LibraryEffectsLoader::handleTexture( const texture__AttributeData& attributeData ) 148 { 149 bool success = true; 150 switch ( mCurrentProfile ) 151 { 152 case PROFILE_COMMON: 153 { 154 // Get the current color or texture element. 155 COLLADAFW::ColorOrTexture* colorOrTexture = getCurrentColorOrTexture ( true ); 156 157 // Check if the texture is referenced. 158 String textureSid = (const char *)attributeData.texture; 159 SidSamplerInfoMap::const_iterator it = mEffectProfileSidSamplerInfoMap.find(textureSid); 160 if ( it == mEffectProfileSidSamplerInfoMap.end() ) 161 { 162 it = mEffectSidSamplerInfoMap.find((const char*)attributeData.texture); 163 if ( it == mEffectSidSamplerInfoMap.end() ) 164 { 165 String msg("Texture with sid \"" + textureSid + "\" not found"); 166 if ( mCurrentEffect ) 167 { 168 msg += " in effect with id \"" + mCurrentEffect->getOriginalId() + "\""; 169 } 170 msg += "."; 171 success = handleFWLError ( SaxFWLError::ERROR_UNRESOLVED_REFERENCE, msg ); 172 break; 173 } 174 } 175 176 // Push the texture sid of the current sampler in the list of used samplers 177 // of the current effect profile. 178 size_t samplerIndex = 0; 179 StringIndexMap::const_iterator samplerIt = mEffectProfileSamplersMap.find(textureSid); 180 if ( samplerIt == mEffectProfileSamplersMap.end() ) 181 { 182 // This sid has not been used before. Add to map with next index 183 samplerIndex = mNextSamplerIndex; 184 mEffectProfileSamplersMap.insert(std::make_pair(textureSid, mNextSamplerIndex++)); 185 } 186 else 187 { 188 // This sid is already in the map. Use its index 189 samplerIndex = samplerIt->second; 190 } 191 192 // Initialize the texture element. 193 /* const SamplerInfo& samplerInfo = it->second; */ /* UNUSED */ 194 colorOrTexture->setType(COLLADAFW::ColorOrTexture::TEXTURE); 195 COLLADAFW::Texture& texture = colorOrTexture->getTexture(); 196 texture.setUniqueId ( createUniqueId(COLLADAFW::Texture::ID()) ); 197 texture.setSamplerId( samplerIndex ); 198 if ( attributeData.texcoord ) 199 { 200 texture.setTextureMapId( getTextureMapIdBySematic( attributeData.texcoord) ); 201 texture.setTexcoord(attributeData.texcoord); 202 } 203 204 break; 205 } 206 /* 207 PROFILE_BRIDGE, 208 PROFILE_CG, 209 PROFILE_GLES, 210 PROFILE_GLES2, 211 PROFILE_GLSL, 212 PROFILE_COMMON, 213 PROFILE_NONE 214 */ 215 default: 216 break; 217 } 218 return success; 219 220 } 221 222 //------------------------------ handleExtraEffectTextures(const COLLADAFW::PointerArray<COLLADAFW::TextureAttributes> & effectTextures)223 bool LibraryEffectsLoader::handleExtraEffectTextures( const COLLADAFW::PointerArray<COLLADAFW::TextureAttributes>& effectTextures ) 224 { 225 bool success = true; 226 227 size_t countExtraTextures = effectTextures.getCount(); 228 if( countExtraTextures == 0 ) 229 return success; 230 231 // switch ( mCurrentProfile ) 232 // { 233 // case PROFILE_COMMON: 234 // { 235 236 for( size_t iTexture = 0; iTexture < countExtraTextures; ++iTexture ) 237 { 238 COLLADAFW::TextureAttributes* textureAttributes = effectTextures[iTexture]; 239 if( textureAttributes == 0 ) 240 continue; 241 242 // Check if the texture is referenced. 243 const String& textureSid = textureAttributes->textureSampler; 244 SidSamplerInfoMap::const_iterator it = mEffectProfileSidSamplerInfoMap.find(textureSid); 245 if ( it == mEffectProfileSidSamplerInfoMap.end() ) 246 { 247 it = mEffectSidSamplerInfoMap.find( textureSid ); 248 if ( it == mEffectSidSamplerInfoMap.end() ) 249 { 250 String msg("Texture with sid \"" + textureSid + "\" not found"); 251 if ( mCurrentEffect ) 252 { 253 msg += " in effect with id \"" + mCurrentEffect->getOriginalId() + "\""; 254 } 255 msg += "."; 256 success = handleFWLError ( SaxFWLError::ERROR_UNRESOLVED_REFERENCE, msg ); 257 continue;; 258 } 259 } 260 261 // Push the texture sid of the current sampler in the list of used samplers 262 // of the current effect profile. 263 size_t samplerIndex = 0; 264 StringIndexMap::const_iterator samplerIt = mEffectProfileSamplersMap.find(textureSid); 265 if ( samplerIt == mEffectProfileSamplersMap.end() ) 266 { 267 // This sid has not been used before. Add to map with next index 268 samplerIndex = mNextSamplerIndex; 269 mEffectProfileSamplersMap.insert(std::make_pair(textureSid, mNextSamplerIndex++)); 270 } 271 else 272 { 273 // This sid is already in the map. Use its index 274 samplerIndex = samplerIt->second; 275 } 276 277 // Initialize the texture element. 278 //bumpMap.setUniqueId ( createUniqueId(COLLADAFW::Texture::ID()) ); //texture id? 279 textureAttributes->samplerId = samplerIndex; 280 if ( !(textureAttributes->texCoord.empty()) ) 281 textureAttributes->textureMapId = getTextureMapIdBySematic( textureAttributes->texCoord ); 282 } 283 284 // break; 285 // } 286 // } 287 return success; 288 } 289 290 //------------------------------ calculateLuminance(const COLLADAFW::Color & color)291 double LibraryEffectsLoader::calculateLuminance ( const COLLADAFW::Color& color ) 292 { 293 return ( (color.getRed () * 0.212671) + (color.getGreen () * 0.715160) + (color.getBlue () * 0.072169) ); 294 } 295 296 //------------------------------ calculateOpacity()297 void LibraryEffectsLoader::calculateOpacity () 298 { 299 // If we have already a texture as opacity, we don't need to calculate the opacity color. 300 COLLADAFW::ColorOrTexture& opacity = mCurrentEffect->getCommonEffects ().back ()->getOpacity (); 301 if ( opacity.isTexture () ) return; 302 303 // Calculate the opacity. 304 if ( mTransparent.isColor () ) 305 { 306 opacity.setType ( COLLADAFW::ColorOrTexture::COLOR ); 307 COLLADAFW::Color& opaqueColor = opacity.getColor (); 308 309 COLLADAFW::Color& transparentColor = mTransparent.getColor (); 310 switch ( mOpaqueMode ) 311 { 312 case LibraryEffectsLoader::A_ZERO: 313 { 314 opaqueColor.setRed ( 1 - transparentColor.getAlpha () * mTransparency.getFloatValue () ); 315 opaqueColor.setGreen ( 1 - transparentColor.getAlpha () * mTransparency.getFloatValue () ); 316 opaqueColor.setBlue ( 1 - transparentColor.getAlpha () * mTransparency.getFloatValue () ); 317 opaqueColor.setAlpha ( 1 - transparentColor.getAlpha () * mTransparency.getFloatValue () ); 318 break; 319 } 320 case LibraryEffectsLoader::RGB_ONE: 321 { 322 opaqueColor.setRed ( transparentColor.getRed () * mTransparency.getFloatValue () ); 323 opaqueColor.setGreen ( transparentColor.getGreen () * mTransparency.getFloatValue () ); 324 opaqueColor.setBlue ( transparentColor.getBlue () * mTransparency.getFloatValue () ); 325 opaqueColor.setAlpha ( calculateLuminance ( transparentColor ) * mTransparency.getFloatValue () ); 326 break; 327 } 328 case LibraryEffectsLoader::RGB_ZERO: 329 { 330 opaqueColor.setRed ( 1 - transparentColor.getRed () * mTransparency.getFloatValue () ); 331 opaqueColor.setGreen ( 1 - transparentColor.getGreen () * mTransparency.getFloatValue () ); 332 opaqueColor.setBlue ( 1 - transparentColor.getBlue () * mTransparency.getFloatValue () ); 333 opaqueColor.setAlpha ( 1 - calculateLuminance ( transparentColor ) * mTransparency.getFloatValue () ); 334 break; 335 } 336 case LibraryEffectsLoader::A_ONE: 337 case LibraryEffectsLoader::UNSPECIFIED_OPAQUE: 338 default: 339 { 340 // A_ONE is the default: 341 opaqueColor.setRed ( transparentColor.getAlpha () * mTransparency.getFloatValue () ); 342 opaqueColor.setGreen ( transparentColor.getAlpha () * mTransparency.getFloatValue () ); 343 opaqueColor.setBlue ( transparentColor.getAlpha () * mTransparency.getFloatValue () ); 344 opaqueColor.setAlpha ( transparentColor.getAlpha () * mTransparency.getFloatValue () ); 345 break; 346 } 347 } 348 349 350 // Reset the transparent color. 351 transparentColor.set (-1,-1,-1,-1); 352 } 353 else 354 { 355 opacity.setType ( COLLADAFW::ColorOrTexture::COLOR ); 356 COLLADAFW::Color& opaqueColor = opacity.getColor (); 357 358 switch ( mOpaqueMode ) 359 { 360 case LibraryEffectsLoader::A_ONE: 361 case LibraryEffectsLoader::RGB_ONE: 362 { 363 opaqueColor.set ( mTransparency.getFloatValue (), mTransparency.getFloatValue (), mTransparency.getFloatValue (), mTransparency.getFloatValue () ); 364 break; 365 } 366 case LibraryEffectsLoader::A_ZERO: 367 case LibraryEffectsLoader::RGB_ZERO: 368 { 369 opaqueColor.set ( 1-mTransparency.getFloatValue (), 1-mTransparency.getFloatValue (), 1-mTransparency.getFloatValue (), 1-mTransparency.getFloatValue () ); 370 break; 371 } 372 case LibraryEffectsLoader::UNSPECIFIED_OPAQUE: 373 default: 374 { 375 // A_ONE is the default: 376 opaqueColor.set ( mTransparency.getFloatValue (), mTransparency.getFloatValue (), mTransparency.getFloatValue (), mTransparency.getFloatValue () ); 377 break; 378 } 379 } 380 } 381 382 // Reset the transparent, transparency and opaque values. 383 mTransparency = 1; 384 mTransparent.setType ( COLLADAFW::ColorOrTexture::UNSPECIFIED ); 385 mOpaqueMode = LibraryEffectsLoader::UNSPECIFIED_OPAQUE; 386 } 387 388 //------------------------------ begin__effect(const effect__AttributeData & attributeData)389 bool LibraryEffectsLoader::begin__effect( const effect__AttributeData& attributeData ) 390 { 391 mCurrentEffect = FW_NEW COLLADAFW::Effect(createUniqueIdFromId(attributeData.id, COLLADAFW::Effect::ID())); 392 393 if ( attributeData.name ) 394 mCurrentEffect->setName ( (const char*)attributeData.name ); 395 else if ( attributeData.id ) 396 mCurrentEffect->setName ( (const char*)attributeData.id ); 397 398 if ( attributeData.id ) 399 mCurrentEffect->setOriginalId ( (const char*)attributeData.id ); 400 401 addToSidTree( attributeData.id, 0); 402 403 return true; 404 } 405 406 //------------------------------ end__effect()407 bool LibraryEffectsLoader::end__effect() 408 { 409 COLLADASaxFWL::FileLoader* fileLoader = getFileLoader(); 410 fileLoader->addEffect(mCurrentEffect); 411 412 mCurrentEffect = 0; 413 SidSamplerInfoMap::iterator samplerIt = mEffectSidSamplerInfoMap.begin(); 414 for ( ; samplerIt != mEffectSidSamplerInfoMap.end(); ++samplerIt) 415 { 416 SamplerInfo& samplerInfo = samplerIt->second; 417 delete samplerInfo.sampler; 418 } 419 mEffectSidSamplerInfoMap.clear(); 420 mEffectSidSurfaceMap.clear(); 421 422 moveUpInSidTree(); 423 424 return true; 425 } 426 427 //------------------------------ begin__profile_COMMON(const profile_COMMON__AttributeData & attributeData)428 bool LibraryEffectsLoader::begin__profile_COMMON( const profile_COMMON__AttributeData& attributeData ) 429 { 430 mCurrentProfile = PROFILE_COMMON; 431 mCurrentEffect->getCommonEffects().append(FW_NEW COLLADAFW::EffectCommon() ); 432 addToSidTree( attributeData.id, 0); 433 434 if ( attributeData.id ) 435 mCurrentEffect->getCommonEffects ().back ()->setOriginalId ( (const char*)attributeData.id ); 436 437 return true; 438 } 439 440 //------------------------------ end__profile_COMMON()441 bool LibraryEffectsLoader::end__profile_COMMON() 442 { 443 // Store values original transparency and transparent values 444 mCurrentEffect->getCommonEffects ().back ()->setTransparent (mTransparent); 445 mCurrentEffect->getCommonEffects ().back ()->setTransparency(mTransparency); 446 mCurrentEffect->getCommonEffects ().back ()->setOpaqueMode((COLLADAFW::EffectCommon::OpaqueMode)mOpaqueMode); 447 448 // Calculate the opacity value. 449 calculateOpacity (); 450 451 const COLLADAFW::PointerArray<COLLADAFW::TextureAttributes>& effectTextures = mCurrentEffect->getExtraTextures(); 452 handleExtraEffectTextures( effectTextures ); 453 454 // Fill the array of samplers of the current profile. 455 if ( !fillSamplerArray() ) 456 return false; 457 458 SidSamplerInfoMap::iterator samplerIt = mEffectProfileSidSamplerInfoMap.begin(); 459 for ( ; samplerIt != mEffectProfileSidSamplerInfoMap.end(); ++samplerIt) 460 { 461 SamplerInfo& samplerInfo = samplerIt->second; 462 delete samplerInfo.sampler; 463 } 464 mEffectProfileSidSamplerInfoMap.clear(); 465 mEffectProfileSidSurfaceMap.clear(); 466 mEffectProfileSamplersMap.clear (); 467 mNextSamplerIndex = 0; 468 469 mTransparent.getColor ().set ( -1, -1, -1, -1 ); 470 mCurrentProfile = PROFILE_NONE; 471 472 moveUpInSidTree(); 473 474 return true; 475 } 476 477 //------------------------------ begin__surface____fx_surface_common(const surface____fx_surface_common__AttributeData & attributeData)478 bool LibraryEffectsLoader::begin__surface____fx_surface_common( const surface____fx_surface_common__AttributeData& attributeData ) 479 { 480 mInSurface = true; 481 ++mSurfaceIndex; 482 483 mCurrentSurface.surfaceType = attributeData.type; 484 return true; 485 } 486 487 //------------------------------ end__surface____fx_surface_common()488 bool LibraryEffectsLoader::end__surface____fx_surface_common() 489 { 490 // Check if we have a surface defined directly under an effect or under an effect profile. 491 if ( mCurrentProfile == PROFILE_NONE ) 492 mEffectSidSurfaceMap.insert(std::make_pair(mCurrentNewParamSid, mCurrentSurface)); 493 else 494 mEffectProfileSidSurfaceMap.insert(std::make_pair(mCurrentNewParamSid, mCurrentSurface)); 495 496 mInSurface = false; 497 498 return true; 499 } 500 501 //------------------------------ begin__init_from____fx_surface_init_from_common(const init_from____fx_surface_init_from_common__AttributeData & attributeData)502 bool LibraryEffectsLoader::begin__init_from____fx_surface_init_from_common( const init_from____fx_surface_init_from_common__AttributeData& attributeData ) { 503 mCurrentSurfaceInitFrom.clear(); 504 return true; 505 } 506 507 //------------------------------ end__init_from____fx_surface_init_from_common()508 bool LibraryEffectsLoader::end__init_from____fx_surface_init_from_common() 509 { 510 mCurrentSurface.imageUniqueId = createUniqueIdFromId((const ParserChar*)mCurrentSurfaceInitFrom.c_str(), COLLADAFW::Image::ID()); 511 return true; 512 } 513 514 //------------------------------ data__init_from____fx_surface_init_from_common(const ParserChar * data,size_t length)515 bool LibraryEffectsLoader::data__init_from____fx_surface_init_from_common( const ParserChar* data, size_t length ) 516 { 517 mCurrentSurfaceInitFrom.append((const char* )data, length); 518 return true; 519 } 520 521 //------------------------------ begin__instance_image(const instance_image__AttributeData & attributeData)522 bool LibraryEffectsLoader::begin__instance_image( const instance_image__AttributeData& attributeData ) 523 { 524 if ( (attributeData.present_attributes & instance_image__AttributeData::ATTRIBUTE_URL_PRESENT) == instance_image__AttributeData::ATTRIBUTE_URL_PRESENT ) 525 { 526 mCurrentSampler->setSource(createUniqueIdFromUrl(attributeData.url, COLLADAFW::Image::ID())); 527 } 528 return true; 529 } 530 531 //------------------------------ begin__newparam____fx_newparam_common(const newparam____fx_newparam_common__AttributeData & attributeData)532 bool LibraryEffectsLoader::begin__newparam____fx_newparam_common( const newparam____fx_newparam_common__AttributeData& attributeData ) 533 { 534 if ( attributeData.sid ) 535 mCurrentNewParamSid = (const char *)attributeData.sid; 536 return true; 537 } 538 539 //------------------------------ end__newparam____fx_newparam_common()540 bool LibraryEffectsLoader::end__newparam____fx_newparam_common() 541 { 542 mCurrentNewParamSid.clear(); 543 return true; 544 } 545 546 //------------------------------ begin__newparam____cg_newparam(const newparam____cg_newparam__AttributeData & attributeData)547 bool LibraryEffectsLoader::begin__newparam____cg_newparam( const newparam____cg_newparam__AttributeData& attributeData ) 548 { 549 addToSidTree( 0, (const char *) attributeData.sid ); 550 return true; 551 } 552 553 //------------------------------ begin__newparam____common_newparam_type(const newparam____common_newparam_type__AttributeData & attributeData)554 bool LibraryEffectsLoader::begin__newparam____common_newparam_type( const newparam____common_newparam_type__AttributeData& attributeData ) 555 { 556 if ( attributeData.sid ) 557 mCurrentNewParamSid = (const char *)attributeData.sid; 558 return true; 559 } 560 561 //------------------------------ end__newparam____common_newparam_type()562 bool LibraryEffectsLoader::end__newparam____common_newparam_type() 563 { 564 mCurrentNewParamSid.clear(); 565 return true; 566 } 567 568 //------------------------------ begin__sampler2D____fx_sampler2D_common()569 bool LibraryEffectsLoader::begin__sampler2D____fx_sampler2D_common() 570 { 571 mCurrentSamplerSource.clear(); 572 mInSampler2D = true; 573 mCurrentSampler = new COLLADAFW::Sampler( createUniqueId (COLLADAFW::Sampler::ID())); 574 mCurrentSampler->setSamplerType( COLLADAFW::Sampler::SAMPLER_TYPE_2D ); 575 return true; 576 } 577 578 //------------------------------ end__sampler2D____fx_sampler2D_common()579 bool LibraryEffectsLoader::end__sampler2D____fx_sampler2D_common() 580 { 581 SamplerInfo samplerInfo; 582 samplerInfo.sampler = mCurrentSampler; 583 samplerInfo.id = 0; 584 samplerInfo.surfaceSid = mCurrentSamplerSource; 585 586 samplerInfo.sampler->setWrapS(mCurrentSamplerWrapS); 587 samplerInfo.sampler->setWrapT(mCurrentSamplerWrapT); 588 589 // Check if we have a sampler defined directly under an effect or under an effect profile. 590 if ( mCurrentProfile == PROFILE_NONE ) 591 mEffectSidSamplerInfoMap.insert(std::make_pair(mCurrentNewParamSid, samplerInfo)); 592 else 593 mEffectProfileSidSamplerInfoMap.insert(std::make_pair(mCurrentNewParamSid, samplerInfo)); 594 595 mCurrentSampler = 0; 596 mCurrentSamplerSource.clear(); 597 598 mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_WRAP; 599 mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_WRAP; 600 601 mInSampler2D = false; 602 603 return true; 604 } 605 606 //------------------------------ data__source____NCName(const ParserChar * data,size_t length)607 bool LibraryEffectsLoader::data__source____NCName( const ParserChar* data, size_t length ) 608 { 609 mCurrentSamplerSource.append((const char* )data, length); 610 return true; 611 } 612 data__wrap_s____fx_sampler_wrap_common(const ENUM__fx_sampler_wrap_common value)613 bool LibraryEffectsLoader::data__wrap_s____fx_sampler_wrap_common( const ENUM__fx_sampler_wrap_common value ) 614 { 615 switch (value) 616 { 617 case ENUM__fx_sampler_wrap_common__CLAMP: 618 mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_CLAMP; 619 break; 620 621 case ENUM__fx_sampler_wrap_common__MIRROR: 622 mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_MIRROR; 623 break; 624 625 case ENUM__fx_sampler_wrap_common__WRAP: 626 mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_WRAP; 627 break; 628 629 case ENUM__fx_sampler_wrap_common__BORDER: 630 mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_BORDER; 631 break; 632 633 case ENUM__fx_sampler_wrap_common__NONE: 634 mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_NONE; 635 break; 636 637 case ENUM__fx_sampler_wrap_common__NOT_PRESENT: 638 mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_UNSPECIFIED; 639 break; 640 default: 641 break; 642 } 643 644 return true; 645 } 646 data__wrap_t____fx_sampler_wrap_common(const ENUM__fx_sampler_wrap_common value)647 bool LibraryEffectsLoader::data__wrap_t____fx_sampler_wrap_common( const ENUM__fx_sampler_wrap_common value ) 648 { 649 switch (value) 650 { 651 case ENUM__fx_sampler_wrap_common__CLAMP: 652 mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_CLAMP; 653 break; 654 655 case ENUM__fx_sampler_wrap_common__MIRROR: 656 mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_MIRROR; 657 break; 658 659 case ENUM__fx_sampler_wrap_common__WRAP: 660 mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_WRAP; 661 break; 662 663 case ENUM__fx_sampler_wrap_common__BORDER: 664 mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_BORDER; 665 break; 666 667 case ENUM__fx_sampler_wrap_common__NONE: 668 mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_NONE; 669 break; 670 671 case ENUM__fx_sampler_wrap_common__NOT_PRESENT: 672 mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_UNSPECIFIED; 673 break; 674 default: 675 break; 676 } 677 678 return true; 679 } 680 681 //------------------------------ begin__profile_COMMON__technique(const profile_COMMON__technique__AttributeData & attributeData)682 bool LibraryEffectsLoader::begin__profile_COMMON__technique( const profile_COMMON__technique__AttributeData& attributeData ) 683 { 684 mInProfileCommonTechnique = true; 685 686 addToSidTree( attributeData.id, attributeData.sid ); 687 688 return true; 689 } 690 691 //------------------------------ end__profile_COMMON__technique()692 bool LibraryEffectsLoader::end__profile_COMMON__technique() 693 { 694 moveUpInSidTree(); 695 696 mInProfileCommonTechnique = false; 697 698 return true; 699 } 700 701 //------------------------------ begin__profile_COMMON__technique__constant()702 bool LibraryEffectsLoader::begin__profile_COMMON__technique__constant() 703 { 704 return setCommonEffectShaderType(COLLADAFW::EffectCommon::SHADER_CONSTANT); 705 } 706 707 //------------------------------ begin__lambert()708 bool LibraryEffectsLoader::begin__lambert() 709 { 710 return setCommonEffectShaderType(COLLADAFW::EffectCommon::SHADER_LAMBERT); 711 } 712 713 //------------------------------ begin__blinn()714 bool LibraryEffectsLoader::begin__blinn() 715 { 716 return setCommonEffectShaderType(COLLADAFW::EffectCommon::SHADER_BLINN); 717 } 718 719 720 //------------------------------ begin__phong()721 bool LibraryEffectsLoader::begin__phong() 722 { 723 return setCommonEffectShaderType(COLLADAFW::EffectCommon::SHADER_PHONG); 724 } 725 726 //------------------------------ end__library_effects()727 bool LibraryEffectsLoader::end__library_effects() 728 { 729 moveUpInSidTree(); 730 finish(); 731 return true; 732 } 733 734 //------------------------------ begin__common_color_or_texture_type____color(const common_color_or_texture_type____color__AttributeData & attributeData)735 bool LibraryEffectsLoader::begin__common_color_or_texture_type____color( const common_color_or_texture_type____color__AttributeData& attributeData ) 736 { 737 COLLADAFW::ColorOrTexture* colorOrTexture = getCurrentColorOrTexture(); 738 addToSidTree( 0, attributeData.sid, &colorOrTexture->getColor() ); 739 return true; 740 } 741 742 //------------------------------ end__common_color_or_texture_type____color()743 bool LibraryEffectsLoader::end__common_color_or_texture_type____color() 744 { 745 mCurrentColorValueIndex = 0; 746 moveUpInSidTree(); 747 return true; 748 } 749 750 //------------------------------ data__common_color_or_texture_type____color(const float * data,size_t length)751 bool LibraryEffectsLoader::data__common_color_or_texture_type____color( const float* data, size_t length ) 752 { 753 return handleColorData(data, length); 754 } 755 756 //------------------------------ begin__texture(const texture__AttributeData & attributeData)757 bool LibraryEffectsLoader::begin__texture( const texture__AttributeData& attributeData ) 758 { 759 mInTexture = true; 760 761 return handleTexture( attributeData); 762 } 763 764 //------------------------------ end__texture()765 bool LibraryEffectsLoader::end__texture () 766 { 767 mInTexture = false; 768 769 return true; 770 } 771 772 //------------------------------ begin__common_float_or_param_type____float(const common_float_or_param_type____float__AttributeData & attributeData)773 bool LibraryEffectsLoader::begin__common_float_or_param_type____float ( const common_float_or_param_type____float__AttributeData& attributeData ) 774 { 775 switch ( mCurrentShaderParameterType) 776 { 777 case SHADER_PARAMETER_SHININESS: 778 addToSidTree( 0, attributeData.sid, &mCurrentEffect->getCommonEffects().back()->getShininess() ); 779 break; 780 case SHADER_PARAMETER_REFLECTIVITY: 781 addToSidTree( 0, attributeData.sid, &mCurrentEffect->getCommonEffects().back()->getReflectivity() ); 782 break; 783 case SHADER_PARAMETER_INDEX_OF_REFRACTION: 784 addToSidTree( 0, attributeData.sid, &mCurrentEffect->getCommonEffects().back()->getIndexOfRefraction() ); 785 break; 786 case SHADER_PARAMETER_TRANSPARENCY: 787 addToSidTree( 0, attributeData.sid, &mTransparency ); 788 break; 789 default: 790 break; 791 } 792 return true; 793 } 794 795 //------------------------------ end__common_float_or_param_type____float()796 bool LibraryEffectsLoader::end__common_float_or_param_type____float () 797 { 798 moveUpInSidTree(); 799 return true; 800 } 801 802 //------------------------------ data__common_float_or_param_type____float(float value)803 bool LibraryEffectsLoader::data__common_float_or_param_type____float( float value ) 804 { 805 switch ( mCurrentShaderParameterType) 806 { 807 case SHADER_PARAMETER_SHININESS: 808 mCurrentEffect->getCommonEffects().back()->setShininess(value); 809 break; 810 case SHADER_PARAMETER_REFLECTIVITY: 811 mCurrentEffect->getCommonEffects().back()->setReflectivity(value); 812 break; 813 case SHADER_PARAMETER_INDEX_OF_REFRACTION: 814 mCurrentEffect->getCommonEffects().back()->setIndexOfRefraction(value); 815 break; 816 case SHADER_PARAMETER_TRANSPARENCY: 817 mTransparency.setFloatValue (value); 818 break; 819 default: 820 break; 821 } 822 823 return true; 824 } 825 826 //------------------------------ begin__emission()827 bool LibraryEffectsLoader::begin__emission() 828 { 829 mCurrentShaderParameterType = SHADER_PARAMETER_EMISSION; 830 return true; 831 } 832 833 //------------------------------ end__emission()834 bool LibraryEffectsLoader::end__emission() 835 { 836 mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE; 837 return true; 838 } 839 840 //------------------------------ begin__ambient____common_color_or_texture_type()841 bool LibraryEffectsLoader::begin__ambient____common_color_or_texture_type() 842 { 843 mCurrentShaderParameterType = SHADER_PARAMETER_AMBIENT; 844 return true; 845 } 846 847 //------------------------------ end__ambient____common_color_or_texture_type()848 bool LibraryEffectsLoader::end__ambient____common_color_or_texture_type() 849 { 850 mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE; 851 return true; 852 } 853 854 //------------------------------ begin__diffuse()855 bool LibraryEffectsLoader::begin__diffuse() 856 { 857 mCurrentShaderParameterType = SHADER_PARAMETER_DIFFUSE; 858 return true; 859 } 860 861 //------------------------------ end__diffuse()862 bool LibraryEffectsLoader::end__diffuse() 863 { 864 mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE; 865 return true; 866 } 867 868 //------------------------------ begin__specular()869 bool LibraryEffectsLoader::begin__specular() 870 { 871 mCurrentShaderParameterType = SHADER_PARAMETER_SPECULAR; 872 return true; 873 } 874 875 //------------------------------ end__specular()876 bool LibraryEffectsLoader::end__specular() 877 { 878 mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE; 879 return true; 880 } 881 882 //------------------------------ begin__shininess()883 bool LibraryEffectsLoader::begin__shininess() 884 { 885 mCurrentShaderParameterType = SHADER_PARAMETER_SHININESS; 886 return true; 887 } 888 889 //------------------------------ end__shininess()890 bool LibraryEffectsLoader::end__shininess() 891 { 892 mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE; 893 return true; 894 } 895 896 //------------------------------ begin__reflective()897 bool LibraryEffectsLoader::begin__reflective() 898 { 899 mCurrentShaderParameterType = SHADER_PARAMETER_REFLECTIVE; 900 return true; 901 } 902 903 //------------------------------ end__reflective()904 bool LibraryEffectsLoader::end__reflective() 905 { 906 mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE; 907 return true; 908 } 909 910 //------------------------------ begin__reflectivity()911 bool LibraryEffectsLoader::begin__reflectivity() 912 { 913 mCurrentShaderParameterType = SHADER_PARAMETER_REFLECTIVITY; 914 return true; 915 } 916 917 //------------------------------ end__reflectivity()918 bool LibraryEffectsLoader::end__reflectivity() 919 { 920 mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE; 921 return true; 922 } 923 924 //------------------------------ begin__transparent(const transparent__AttributeData & attributeData)925 bool LibraryEffectsLoader::begin__transparent ( const transparent__AttributeData& attributeData ) 926 { 927 ENUM__fx_opaque opaque = attributeData.opaque; 928 switch ( opaque ) 929 { 930 case ENUM__fx_opaque__A_ZERO: 931 mOpaqueMode = A_ZERO; 932 break; 933 case ENUM__fx_opaque__A_ONE: 934 mOpaqueMode = A_ONE; 935 break; 936 case ENUM__fx_opaque__RGB_ZERO: 937 mOpaqueMode = RGB_ZERO; 938 break; 939 case ENUM__fx_opaque__RGB_ONE: 940 mOpaqueMode = RGB_ONE; 941 break; 942 default: 943 mOpaqueMode = UNSPECIFIED_OPAQUE; 944 break; 945 } 946 mCurrentShaderParameterType = SHADER_PARAMETER_TRANSPARENT; 947 return true; 948 } 949 950 951 //------------------------------ end__transparent()952 bool LibraryEffectsLoader::end__transparent() 953 { 954 mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE; 955 return true; 956 } 957 958 //------------------------------ begin__transparency()959 bool LibraryEffectsLoader::begin__transparency() 960 { 961 mCurrentShaderParameterType = SHADER_PARAMETER_TRANSPARENCY; 962 return true; 963 } 964 965 //------------------------------ end__transparency()966 bool LibraryEffectsLoader::end__transparency() 967 { 968 mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE; 969 return true; 970 } 971 972 //------------------------------ begin__index_of_refraction()973 bool LibraryEffectsLoader::begin__index_of_refraction() 974 { 975 mCurrentShaderParameterType = SHADER_PARAMETER_INDEX_OF_REFRACTION; 976 return true; 977 } 978 979 //------------------------------ end__index_of_refraction()980 bool LibraryEffectsLoader::end__index_of_refraction() 981 { 982 mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE; 983 return true; 984 } 985 986 //------------------------------ fillSamplerArray()987 bool LibraryEffectsLoader::fillSamplerArray () 988 { 989 COLLADAFW::EffectCommon& commonEffect = *mCurrentEffect->getCommonEffects().back(); 990 COLLADAFW::SamplerPointerArray& samplerArray = commonEffect.getSamplerPointerArray(); 991 992 // Iterate over the list of used samplers in the current effect profile 993 // and push them in the sampler array. 994 size_t samplerCount = mEffectProfileSamplersMap.size(); 995 samplerArray.reallocMemory(samplerCount); 996 samplerArray.setCount(samplerCount); 997 StringIndexMap::const_iterator it = mEffectProfileSamplersMap.begin (); 998 while ( it != mEffectProfileSamplersMap.end () ) 999 { 1000 String samplerSid = it->first; 1001 size_t samplerIndex = it->second; 1002 1003 bool validSampler = false; 1004 SidSamplerInfoMap::iterator samplerIt = mEffectProfileSidSamplerInfoMap.find ( samplerSid ); 1005 1006 if ( samplerIt == mEffectProfileSidSamplerInfoMap.end () ) 1007 { 1008 samplerIt = mEffectSidSamplerInfoMap.find ( samplerSid ); 1009 if ( samplerIt != mEffectSidSamplerInfoMap.end () ) validSampler = true; 1010 } 1011 else validSampler = true; 1012 1013 if ( validSampler ) 1014 { 1015 SamplerInfo& samplerInfo = samplerIt->second; 1016 samplerInfo.id = samplerArray.getCount(); 1017 COLLADAFW::Sampler* sampler = samplerInfo.sampler; 1018 sampler->setSid(samplerSid); 1019 if ( !sampler->getSourceImage().isValid() ) 1020 { 1021 bool validSurface = false; 1022 SidSurfaceMap::const_iterator surfaceIt = mEffectProfileSidSurfaceMap.find( samplerInfo.surfaceSid ); 1023 if ( surfaceIt == mEffectProfileSidSurfaceMap.end() ) 1024 { 1025 surfaceIt = mEffectSidSurfaceMap.find( samplerInfo.surfaceSid ); 1026 if ( surfaceIt != mEffectSidSurfaceMap.end() ) validSurface = true; 1027 } 1028 else validSurface = true; 1029 if ( validSurface ) 1030 { 1031 const Surface& surface = surfaceIt->second; 1032 sampler->setSource(surface.imageUniqueId); 1033 1034 // copy sampler into common effect 1035 samplerArray[samplerIndex] = sampler->clone(); 1036 } 1037 } 1038 else 1039 { 1040 samplerArray[samplerIndex] = sampler->clone(); 1041 } 1042 } 1043 else 1044 { 1045 // we a null sampler here, to ensure the index of all of the following sampler remain correct 1046 samplerArray[samplerIndex] = 0; 1047 1048 if ( !handleFWLError ( SaxFWLError::ERROR_UNRESOLVED_REFERENCE, "No sampler for texture \"" + samplerSid + "\" defined!" )) 1049 return false; 1050 } 1051 ++it; 1052 } 1053 1054 return true; 1055 } 1056 data__minfilter(const ENUM__fx_sampler_filter_common value)1057 bool LibraryEffectsLoader::data__minfilter( const ENUM__fx_sampler_filter_common value ) 1058 { 1059 COLLADAFW::Sampler::SamplerFilter filter = COLLADAFW::Sampler::SAMPLER_FILTER_UNSPECIFIED; 1060 if ( mCurrentSampler ) { 1061 switch (value) { 1062 case ENUM__fx_sampler_filter_common__NOT_PRESENT: 1063 case ENUM__fx_sampler_filter_common__COUNT: 1064 case ENUM__fx_sampler_filter_common__NONE: 1065 filter = COLLADAFW::Sampler::SAMPLER_FILTER_NONE; 1066 break; 1067 case ENUM__fx_sampler_filter_common__NEAREST: 1068 filter = COLLADAFW::Sampler::SAMPLER_FILTER_NEAREST; 1069 break; 1070 case ENUM__fx_sampler_filter_common__LINEAR: 1071 filter = COLLADAFW::Sampler::SAMPLER_FILTER_LINEAR; 1072 break; 1073 case ENUM__fx_sampler_filter_common__NEAREST_MIPMAP_NEAREST: 1074 filter = COLLADAFW::Sampler::SAMPLER_FILTER_NEAREST_MIPMAP_NEAREST; 1075 break; 1076 case ENUM__fx_sampler_filter_common__LINEAR_MIPMAP_NEAREST: 1077 filter = COLLADAFW::Sampler::SAMPLER_FILTER_LINEAR_MIPMAP_NEAREST; 1078 break; 1079 case ENUM__fx_sampler_filter_common__NEAREST_MIPMAP_LINEAR: 1080 filter = COLLADAFW::Sampler::SAMPLER_FILTER_NEAREST_MIPMAP_LINEAR; 1081 break; 1082 case ENUM__fx_sampler_filter_common__LINEAR_MIPMAP_LINEAR: 1083 filter = COLLADAFW::Sampler::SAMPLER_FILTER_LINEAR_MIPMAP_LINEAR; 1084 break; 1085 } 1086 mCurrentSampler->setMinFilter(filter); 1087 } 1088 1089 return true; 1090 } 1091 1092 1093 //------------------------------ getUniqueId()1094 const COLLADAFW::UniqueId& LibraryEffectsLoader::getUniqueId () 1095 { 1096 if ( mCurrentSampler ) 1097 return mCurrentSampler->getUniqueId (); 1098 else if ( mCurrentEffect ) 1099 return mCurrentEffect->getUniqueId (); 1100 return COLLADAFW::UniqueId::INVALID; 1101 } 1102 1103 //------------------------------ getObject()1104 COLLADAFW::Object* LibraryEffectsLoader::getObject() 1105 { 1106 if ( mCurrentSampler ) 1107 return mCurrentSampler; 1108 else if ( mCurrentEffect ) 1109 return mCurrentEffect; 1110 return 0; 1111 } 1112 1113 } // namespace COLLADASaxFWL 1114