void HwShaderExporter::setTexture (
        const PBBitmap * bitmap, 
        COLLADASW::Sampler& sampler
        )
    {
        if ( !bitmap )
        {
            //:TODO: retrieve default values from fx file
            return;
        }

        // Set the texture format.
        //:TODO: read from BitmapInfo::Type ()
        sampler.setFormat ( EffectTextureExporter::FORMAT );

        // Get the necessary exporters.
        EffectExporter* effectExporter = mDocumentExporter->getEffectExporter ();
        EffectTextureExporter* textureExporter = effectExporter->getTextureExporter();
        
        // The file name to connect to.
#ifdef UNICODE
		String fileName = bitmap->bi.Name() ? COLLADASW::URI::nativePathToUri( COLLADABU::StringUtils::wideString2utf8String(bitmap->bi.Name()) ) : "";
#else
        String fileName = bitmap->bi.Name() ? COLLADASW::URI::nativePathToUri( bitmap->bi.Name() ) : "";
#endif

        // Export, if we have a file name.
        if ( !fileName.empty () )
        {
            // Get the image path
            COLLADASW::URI shaderFxFileUri = mEffectProfile->getIncludeURI();

            // Take the filename for the unique image name
            COLLADASW::URI sourceFileUri ( shaderFxFileUri, fileName );
            if ( sourceFileUri.getScheme ().empty () )
                sourceFileUri.setScheme ( COLLADASW::URI::SCHEME_FILE );
            String maxImageId = /*DocumentExporter::mayaNameToColladaName*/ ( sourceFileUri.getPathFileBase().c_str () );

            // Get the image id of the maya image 
            String colladaImageId = textureExporter->findColladaImageId ( maxImageId );

            if ( colladaImageId.empty () )
            {
                colladaImageId = textureExporter->getImageIdList ().addId ( maxImageId );
                textureExporter->getMaxIdColladaImageId () [maxImageId] = colladaImageId;
            }

            // Export the image
            COLLADASW::Image* colladaImage = textureExporter->exportImage ( maxImageId, colladaImageId, sourceFileUri );

            // Get the image id of the exported collada image
            colladaImageId = colladaImage->getImageId();

            // Set the image reference
            sampler.setImageId ( colladaImageId );
        }
    }
    //---------------------------------------------------------------
    void EffectTextureExporter::exportTexture (
        COLLADASW::Texture* colladaTexture,
        String channelSemantic,
        const MObject& texture,
        int blendMode,
        const String& targetPath )
    {
        mAnimationTargetPath = targetPath;

        // Set the image name
        String colladaImageId = exportImage ( texture );
        colladaTexture->setImageId ( colladaImageId );
        colladaTexture->setTexcoord ( channelSemantic );

        // Get the current stream writer
        COLLADASW::StreamWriter* streamWriter = mDocumentExporter->getStreamWriter();

        // Create the sampler
        String samplerSid = colladaImageId + COLLADASW::Sampler::SAMPLER_SID_SUFFIX;
        String surfaceSid = colladaImageId + COLLADASW::Sampler::SURFACE_SID_SUFFIX;

        COLLADASW::Sampler sampler ( COLLADASW::Sampler::SAMPLER_TYPE_2D, samplerSid, surfaceSid );
        sampler.setFormat ( FORMAT );
        sampler.setImageId ( colladaImageId );

        colladaTexture->setSampler ( sampler );

        // Add 2D placement parameters
        add2DPlacement ( colladaTexture, texture );

        // Check for 3D projection node
        MObject colorReceiver = DagHelper::getSourceNodeConnectedTo ( texture, ATTR_OUT_COLOR );
        if ( colorReceiver != MObject::kNullObj && colorReceiver.apiType() == MFn::kProjection )
        {
            add3DProjection ( colladaTexture, colorReceiver );
        }

        // Add blend mode information
        String blendModeString = getBlendMode ( blendMode );
        colladaTexture->addExtraTechniqueParameter ( PROFILE_MAYA, MAYA_TEXTURE_BLENDMODE_PARAMETER, blendModeString );

        // Wrap elements
        switch ( colladaTexture->getSampler().getSamplerType() )
        {

        case COLLADASW::Sampler::SAMPLER_TYPE_1D:
            sampler.setWrapS ( COLLADASW::Sampler::WRAP_MODE_WRAP );
            break;

        case COLLADASW::Sampler::SAMPLER_TYPE_2D:
        {
            sampler.setWrapS ( COLLADASW::Sampler::WRAP_MODE_WRAP );
            sampler.setWrapT ( COLLADASW::Sampler::WRAP_MODE_WRAP );
        }
        break;

        case COLLADASW::Sampler::SAMPLER_TYPE_3D:
        case COLLADASW::Sampler::SAMPLER_TYPE_CUBE:
        {
            sampler.setWrapS ( COLLADASW::Sampler::WRAP_MODE_WRAP );
            sampler.setWrapT ( COLLADASW::Sampler::WRAP_MODE_WRAP );
            sampler.setWrapP ( COLLADASW::Sampler::WRAP_MODE_WRAP );
        }
        break;
        }

        sampler.setMinFilter ( COLLADASW::Sampler::SAMPLER_FILTER_NONE );
        sampler.setMagFilter ( COLLADASW::Sampler::SAMPLER_FILTER_NONE );
        sampler.setMipFilter ( COLLADASW::Sampler::SAMPLER_FILTER_NONE );
    }
    //---------------------------------------
    void MaterialExporter::setSetParamTexture (
        const cgfxAttrDef* attribute, 
        MObject texture, 
        COLLADASW::Sampler::SamplerType samplerType, 
        COLLADASW::ValueType::ColladaType samplerValueType )
    {
        // Get a pointer to the current stream writer.
        COLLADASW::StreamWriter* streamWriter = mDocumentExporter->getStreamWriter();

        // Get the image id
        MFnDependencyNode textureNode ( texture );
        String plugName = textureNode.name().asChar(); // file1

        // Get the file texture name
        MPlug filenamePlug = textureNode.findPlug ( ATTR_FILE_TEXTURE_NAME );
        MString mayaFileName;
        filenamePlug.getValue ( mayaFileName );
        if ( mayaFileName.length() == 0 ) return;
        String fileName = mayaFileName.asChar ();
        
        // Get the image path
        COLLADASW::URI shaderFxFileUri = getShaderFxFileUri ();

        // Take the filename for the unique image name 
        COLLADASW::URI sourceFileUri ( shaderFxFileUri, fileName );
        if ( sourceFileUri.getScheme ().empty () )
            sourceFileUri.setScheme ( COLLADASW::URI::SCHEME_FILE );
        String mayaImageId = DocumentExporter::mayaNameToColladaName ( sourceFileUri.getPathFileBase().c_str () );

        // Get the image id of the maya image 
        EffectExporter* effectExporter = mDocumentExporter->getEffectExporter ();
        String colladaImageId = effectExporter->findColladaImageId ( mayaImageId );
        if ( colladaImageId.empty () )
        {
            // Check if there is an extra attribute "colladaId" and use this as export id.
            MString attributeValue;
            DagHelper::getPlugValue ( texture, COLLADA_ID_ATTRIBUTE_NAME, attributeValue );
            if ( attributeValue != EMPTY_CSTRING )
            {
                // Generate a valid collada name, if necessary.
                colladaImageId = mDocumentExporter->mayaNameToColladaName ( attributeValue, false );
            }
            else
            {
                // Generate a COLLADA id for the new light object
                colladaImageId = DocumentExporter::mayaNameToColladaName ( textureNode.name() );
            }
            // Make the id unique and store it in a map for refernences.
            EffectTextureExporter* textureExporter = effectExporter->getTextureExporter ();
            colladaImageId = textureExporter->getImageIdList ().addId ( colladaImageId );
            textureExporter->getMayaIdColladaImageId () [mayaImageId] = colladaImageId;
        }

        // Export the image
        EffectTextureExporter* textureExporter = mDocumentExporter->getEffectExporter()->getTextureExporter();
        COLLADASW::Image* colladaImage = textureExporter->exportImage ( mayaImageId, colladaImageId, sourceFileUri );
        mayaImageId = colladaImage->getImageId();

        // Create the sampler and surface sid
        String samplerSid = mayaImageId + COLLADASW::Sampler::SAMPLER_SID_SUFFIX;
        String surfaceSid = mayaImageId + COLLADASW::Sampler::SURFACE_SID_SUFFIX;

        // Avoid export of dublicate sampler params
        if ( mSamplers.find ( samplerSid ) != mSamplers.end () ) return;
        mSamplers.insert ( samplerSid );

        // Create the sampler and add the sampler <setparam>
        COLLADASW::Sampler sampler ( samplerType, samplerSid, surfaceSid );
        sampler.setFormat ( EffectTextureExporter::FORMAT );
        sampler.setImageId ( colladaImage->getImageId() );
        sampler.addInSetParam ( streamWriter );
    }
    void HwShaderExporter::exportSampler ( 
        const TCHAR* paramName,
        const PBBitmap* bitmap
        )
    {
        COLLADASW::StreamWriter* streamWriter = &mDocumentExporter->getStreamWriter();

        // Name of the current texture
#ifdef UNICODE
		String stringParamName = COLLADABU::StringUtils::wideString2utf8String( paramName );
		const char* surfaceSid = stringParamName.c_str();
#else
		const char* surfaceSid = paramName;//cgGetParameterName( cgTextureParam );
#endif

        // Get the name of the current parameter
        //const char* samplerSid = cgGetParameterName ( cgParameter );
        char samplerSid[256];
        _snprintf_s( samplerSid, 256, "%sSampler", surfaceSid );

        // Create the collada sampler object
        COLLADASW::Sampler sampler ( COLLADASW::Sampler::SAMPLER_TYPE_UNSPECIFIED, samplerSid, surfaceSid );

        /*
        // Look for the wraps
        cgStateAssignment = cgGetNamedSamplerStateAssignment ( cgParameter, COLLADASW::CSWC::CSW_ELEMENT_WRAP_S.c_str() );
        if ( cgStateAssignment )
        {
            CGstate cgState = cgGetSamplerStateAssignmentState ( cgStateAssignment );
            const int* values = cgGetIntStateAssignmentValues ( cgStateAssignment, &valueCount );
            const char* cgStateEnum = cgGetStateEnumerantName ( cgState, values[0] );
            sampler.setWrapS ( COLLADASW::OPEN_GL::getWrapModeFromOpenGL ( cgStateEnum ) );
        }
        cgStateAssignment = cgGetNamedSamplerStateAssignment ( cgParameter, COLLADASW::CSWC::CSW_ELEMENT_WRAP_T.c_str() );
        if ( cgStateAssignment )
        {
            CGstate cgState = cgGetSamplerStateAssignmentState ( cgStateAssignment );
            const int* values = cgGetIntStateAssignmentValues ( cgStateAssignment, &valueCount );
            const char* cgStateEnum = cgGetStateEnumerantName ( cgState, values[0] );
            sampler.setWrapT ( COLLADASW::OPEN_GL::getWrapModeFromOpenGL ( cgStateEnum ) );
        }
        cgStateAssignment = cgGetNamedSamplerStateAssignment ( cgParameter, COLLADASW::CSWC::CSW_ELEMENT_WRAP_P.c_str() );
        if ( cgStateAssignment )
        {
            CGstate cgState = cgGetSamplerStateAssignmentState ( cgStateAssignment );
            const int* values = cgGetIntStateAssignmentValues ( cgStateAssignment, &valueCount );
            const char* cgStateEnum = cgGetStateEnumerantName ( cgState, values[0] );
            sampler.setWrapP ( COLLADASW::OPEN_GL::getWrapModeFromOpenGL ( cgStateEnum ) );
        }

        // Look for the filters
        cgStateAssignment = cgGetNamedSamplerStateAssignment ( cgParameter, COLLADASW::CSWC::CSW_ELEMENT_MAGFILTER.c_str() );
        if ( cgStateAssignment )
        {
            CGstate cgState = cgGetSamplerStateAssignmentState ( cgStateAssignment );
            const int* values = cgGetIntStateAssignmentValues ( cgStateAssignment, &valueCount );
            const char* cgStateEnum = cgGetStateEnumerantName ( cgState, values[0] );
            sampler.setMagFilter( COLLADASW::OPEN_GL::getSamplerFilterFromOpenGL ( cgStateEnum ) );
        }
        cgStateAssignment = cgGetNamedSamplerStateAssignment ( cgParameter, COLLADASW::CSWC::CSW_ELEMENT_MINFILTER.c_str() );
        if ( cgStateAssignment )
        {
            CGstate cgState = cgGetSamplerStateAssignmentState ( cgStateAssignment );
            const int* values = cgGetIntStateAssignmentValues ( cgStateAssignment, &valueCount );
            const char* cgStateEnum = cgGetStateEnumerantName ( cgState, values[0] );
            sampler.setMinFilter( COLLADASW::OPEN_GL::getSamplerFilterFromOpenGL ( cgStateEnum ) );
        }
        cgStateAssignment = cgGetNamedSamplerStateAssignment ( cgParameter, COLLADASW::CSWC::CSW_ELEMENT_MIPFILTER.c_str() );
        if ( cgStateAssignment )
        {
            CGstate cgState = cgGetSamplerStateAssignmentState ( cgStateAssignment );
            const int* values = cgGetIntStateAssignmentValues ( cgStateAssignment, &valueCount );
            const char* cgStateEnum = cgGetStateEnumerantName ( cgState, values[0] );
            sampler.setMipFilter( COLLADASW::OPEN_GL::getSamplerFilterFromOpenGL ( cgStateEnum ) );
        }

        // Look for the border color
        cgStateAssignment = cgGetNamedSamplerStateAssignment ( cgParameter, COLLADASW::CSWC::CSW_ELEMENT_BORDER_COLOR.c_str() );
        if ( cgStateAssignment )
        {
            CGstate cgState = cgGetSamplerStateAssignmentState ( cgStateAssignment );
            const float* values = cgGetFloatStateAssignmentValues ( cgStateAssignment, &valueCount );
            if ( valueCount == 3 )
                sampler.setBorderColor ( COLLADASW::Color ( values[0], values[1], values[2] ) );
            else if ( valueCount == 4 )
                sampler.setBorderColor ( COLLADASW::Color ( values[0], values[1], values[2], values[3] ) );
        }

        // Look for the mipmaps
        cgStateAssignment = cgGetNamedSamplerStateAssignment ( cgParameter, COLLADASW::CSWC::CSW_ELEMENT_MIPMAP_MAXLEVEL.c_str() );
        if ( cgStateAssignment )
        {
            CGstate cgState = cgGetSamplerStateAssignmentState ( cgStateAssignment );
            const int* values = cgGetIntStateAssignmentValues ( cgStateAssignment, &valueCount );
            sampler.setMipmapMaxlevel ( ( unsigned char ) ( values[0] ) );
        }
        cgStateAssignment = cgGetNamedSamplerStateAssignment ( cgParameter, COLLADASW::CSWC::CSW_ELEMENT_MIPMAP_BIAS.c_str() );
        if ( cgStateAssignment )
        {
            CGstate cgState = cgGetSamplerStateAssignmentState ( cgStateAssignment );
            const float* values = cgGetFloatStateAssignmentValues ( cgStateAssignment, &valueCount );
            sampler.setMipmapBias ( values[0] );
        }

        // TODO Look for extra tags
//        exportSamplerStateAssignments (cgParameter, cgTextureParam, surfaceType, samplerType, samplerValueType);
        */

        //:TODO: get sampler type from data
        COLLADASW::Sampler::SamplerType samplerType = COLLADASW::Sampler::SAMPLER_TYPE_2D;

        // Set the sampler type
        sampler.setSamplerType ( samplerType );

        // Add the texture, if exist
        setTexture ( bitmap, sampler );

        //if ( writeNewParam )
        {
            // Get the surface annotations.
            std::vector<COLLADASW::Annotation> surfaceAnnotations;
            //getAnnotations( surfaceAnnotations, cgTextureParam );

            // Get the sampler annotations.
            std::vector<COLLADASW::Annotation> samplerAnnotations;
            //getAnnotations( samplerAnnotations, cgParameter );

            // Add the parameter.
            sampler.addInNewParam ( streamWriter, &surfaceAnnotations, &samplerAnnotations );
        }
        /*
        else
        {
            // Add the parameter.
            sampler.addInSetParam ( streamWriter );
        }
        */
    }