Ejemplo n.º 1
0
static void faceTwiddling(int face, TextureHostSharedPtr const& texImage)
{
  if ( face == 0 || face == 1 || face == 4 || face == 5 ) // px, nx, pz, nz
  {
    texImage->mirrorY(face);
  }
  else
  {
    texImage->mirrorX(face);
  }
}
Ejemplo n.º 2
0
bool ILTexSaver::save( const TextureHostSharedPtr & image, const string & fileName )
{
  DP_ASSERT(image);
  
  // set locale temporarily to standard "C" locale
  dp::util::Locale tl("C");

  bool isCube;
  unsigned int imageID;

  ilGenImages( 1, (ILuint *) &imageID );
  ilBindImage( imageID );  

  string ext = dp::util::getFileExtension( fileName );
  bool isDDS = !_stricmp(".DDS", ext.c_str());   // .dds needs special handling

  if ( isDDS )
  {      
    // DirectDraw Surfaces have their origin at upper left
    ilEnable( IL_ORIGIN_SET );
    ilOriginFunc( IL_ORIGIN_UPPER_LEFT );
  }
  else
  {
    ilDisable( IL_ORIGIN_SET );
  }

  // DevIL does not know how to handle .jps and .pns. Since those formats are just renamed .jpgs and .pngs
  // pass over filename.(jps|pns).(jpg|png) and rename the file after saving it.
  // FIXME Sent bug report to DevIL. Remove this once jps/pns is added to DevIL.
  bool isStereoFormat = false;
  std::string devilFilename = fileName;
  
  if (!_stricmp(".JPS", ext.c_str()))
  {
    isStereoFormat = true;
    devilFilename += ".JPG";
    
  }
  else if (!_stricmp(".PNS", ext.c_str()))
  {
    isStereoFormat = true;
    devilFilename += ".PNG";
  }

  unsigned int numImages = image->getNumberOfImages();
  isCube = image->isCubeMap();
  unsigned char * pixels = NULL;

  // we only handle these cases properly
  DP_ASSERT(isCube == (numImages==6));
  DP_ASSERT(!isCube == (numImages==1));

  for ( unsigned int i = 0; i < numImages; ++i )
  {
    // for DDS cube maps we need to juggle with the faces 
    // to get them into the right order for DDS formats
    int face = determineImage( i, isDDS, isCube );
   
    ilBindImage(imageID);
    ilActiveImage(0);
    ilActiveFace(face);

    DP_ASSERT(IL_NO_ERROR == ilGetError());

    // TODO: Do not know how to handle paletted! This information is already destroyed
    //    // pixel format
    //    unsigned int format = ilGetInteger(IL_IMAGE_FORMAT);
    //    if ( IL_COLOR_INDEX == format )
    //    {
    //      // convert color index to whatever the base type of the palette is
    //      if ( !ilConvertImage(ilGetInteger(IL_PALETTE_BASE_TYPE), IL_UNSIGNED_BYTE) )
    //      {
    //        DP_TRACE_OUT("ERROR: conversion from color index format failed!\n");        
    //        INVOKE_CALLBACK(onInvalidFile(fileName, "DevIL Loadable Color-Indexed Image"));
    //        goto ERROREXIT;
    //      }
    //      // now query format of the converted image
    //      format = ilGetInteger(IL_IMAGE_FORMAT);
    //    }
    //

    // Determine the Pixel Format and type
    ILenum ilFormat = determineILFormat(image->getFormat());
    ILenum ilType = determineILType(image->getType());
    
    // Retrieve the image dimensions
    unsigned int width = image->getWidth(i);
    unsigned int height = image->getHeight(i);
    unsigned int depth = image->getDepth(i);

    // If assertion fires, something is wrong
    DP_ASSERT( (width > 0) && (height > 0) && (depth > 0) );
    

    // again some twiddling for DDS format necessary prior to 
    // specify the IL image
    if ( isDDS && isCube )
    {
      faceTwiddling( face, image );
    }

    // temporary cache to retrieve SceniX' TextureHost pixels
    pixels = new unsigned char[image->getNumberOfBytes()];

    // specify the IL image
    image->getSubImagePixels(i, 0, 0, 0, 0, width, height, depth, pixels);
    ilTexImage( width, height, depth, dp::sg::core::numberOfComponents( image->getFormat() ), ilFormat, ilType, NULL  );
    void* destpixels = ilGetData();
    memcpy(destpixels, pixels, image->getNumberOfBytes());

    // done with the temporary pixel cache
    delete[] pixels;
    

    DP_ASSERT(IL_NO_ERROR == ilGetError());

    // undo the face twiddling from before
    if ( isDDS && isCube )
    {
      faceTwiddling( face, image );
    }
  }

  // By default, always overwrite
  ilEnable(IL_FILE_OVERWRITE);
  if ( ilSaveImage( (const ILstring)devilFilename.c_str() ) )
  {
    // For stereo formats rename the file to the original filename
    if (isStereoFormat)
    {
      // Windows will not rename a file if the destination filename already does exist.
      remove( fileName.c_str() );
      rename( devilFilename.c_str(), fileName.c_str() );
    }

    ilDeleteImages(1, &imageID);
    DP_ASSERT(IL_NO_ERROR == ilGetError());
    return true;
  }
  else
  {
#if 0
    DP_TRACE_OUT("ERROR: save image failed!\n");      
#endif

    // clean up errors
    while( ilGetError() != IL_NO_ERROR )
    {}
       
    // report that an error has occured
    INVOKE_CALLBACK( onInvalidFile( fileName, "saving image file failed!") );

  }
  // free all resources associated with the DevIL image
  ilDeleteImages(1, &imageID);
  return false;
}
Ejemplo n.º 3
0
const ParameterGroupDataSharedPtr & StackedAtlasManager::submitTexture( const std::string & file
                                                                            , const std::string & attrString
                                                                            , int & layer )
{
  //
  // see if we have seen this texture before
  //
  std::map< std::string, std::pair<std::string,int> >::iterator fiter = m_cachedFiles.find( file );

  if ( fiter != m_cachedFiles.end() )
  {
    // it is in the list, return the right atlas
    std::map< std::string, StackedAtlas * >::iterator saiter = m_atlases.find( (*fiter).second.first );

    layer = (*fiter).second.second;
    return (*saiter).second->getTexture();
  }

  // we have not seen this one before, go looking for the file
  static ParameterGroupDataSharedPtr nullTexture;

  TextureHostSharedPtr tex = dp::sg::io::loadTextureHost( file, m_searchPaths );
  if( tex )
  {
    std::stringstream ss;

    bool forceMipmaps = false;
    if( m_rescale )
    {
      // rescale to width, height
      if( m_width != tex->getWidth() || m_height != tex->getHeight() )
      {
        tex->scale( 0, m_width, m_height, 1 );

        forceMipmaps = true;
      }
    }

    // we create mipmaps if there were none
    if( m_createMipmaps || forceMipmaps )
    {
      if( forceMipmaps || tex->getNumberOfMipmaps() < 1 )
      {
        tex->createMipmaps();
      }
    }

    // convert everything to bgra - more efficient for the hardware
    // anyway.
    tex->convertPixelFormat( Image::IMG_BGRA );

    // concatenate width, height and attribute string
    ss << tex->getWidth() << "x" << tex->getHeight() << attrString
      << "-" << numberOfComponents( tex->getFormat() );

    // see if we already have a stack like this
    std::map< std::string, StackedAtlas * >::iterator saiter = m_atlases.find( ss.str() );

    StackedAtlas * atlas = 0;

    if( saiter != m_atlases.end() && (*saiter).second->getCount() < m_maxSlices )
    {
      atlas = (*saiter).second;
    }
    else
    {
      // we either don't have one like this, or it is full, make a new one
      atlas = new StackedAtlas( tex->getWidth(), tex->getHeight() );
      // add to list
      m_atlases[ ss.str() ] = atlas;
    }

    const ParameterGroupDataSharedPtr & texture = atlas->addTexture( tex, layer );

    if ( texture )
    {
      // mark it as being cached
      m_cachedFiles[ file ] = std::make_pair(ss.str(),layer);

      return( texture );
    }
    else
    {
      return( nullTexture );
    }
  }
  else
  {
    // unable to find file...
    return( nullTexture );
  }
}
Ejemplo n.º 4
0
      void ParameterGroupData::initData( const dp::fx::ParameterGroupDataSharedPtr & data )
      {
        // fill the data area with the defaults from the spec
        for ( ParameterGroupSpec::iterator it = m_parameterGroupSpec->beginParameterSpecs() ; it != m_parameterGroupSpec->endParameterSpecs() ; ++it )
        {
          // If the parameter is a sampler it needs to be initialized.
          // For GLSL to silence the OpenGL driver debug output warning that a sampler is not assigned.

          // Both the undefined and the default filename initialization should be done via some scene graph global texture cache.
          if ( ( it->first.getType() & PT_POINTER_TYPE_MASK ) == PT_SAMPLER_PTR )
          {
            if ( it->first.getDefaultValue() )
            {
              // If a sampler has a default value it must be a texture image filename.
              const char * name = static_cast<const char *>( data->getParameter( it ) );
              TextureFileSharedPtr texture = TextureFile::create( name, textureTypeToTarget( it->first.getType() ) );
              DP_ASSERT( texture );
              if ( texture )
              {
                texture->incrementMipmapUseCount();

                SamplerSharedPtr sampler = Sampler::create( texture );

                std::string extension = dp::util::getFileExtension( name );
                boost::algorithm::to_lower(extension);
                if ( extension == ".mbsdf" )
                {
                  sampler->setName( it->first.getName() );
                  sampler->setMagFilterMode( TFM_MAG_NEAREST );
                  sampler->setMinFilterMode( TFM_MIN_NEAREST );
                  sampler->setWrapModes( TWM_CLAMP_TO_EDGE, TWM_CLAMP_TO_EDGE, TWM_CLAMP_TO_EDGE );
                }
                else
                {
                  sampler->setName( it->first.getName() );
                  sampler->setMagFilterMode( TFM_MAG_LINEAR );
                  sampler->setMinFilterMode( TFM_MIN_LINEAR_MIPMAP_LINEAR );
                }
                setParameter( it, sampler );
              }
            }
            else
            {
              // If the sampler has no default initialization, find out their type and assign a matching default texture.
              // DAR FIXME Support for "sampler" in standardMaterialEffect standardTextureParameters for now.
              // 2x2 RGBA8 red, green, blue, yellow default texture.
              static const unsigned char texel[] = 
              {
                0xFF, 0x00, 0x00, 0xFF, 
                0x00, 0xFF, 0x00, 0xFF, 
                0x00, 0x00, 0xFF, 0xFF, 
                0xFF, 0xFF, 0x00, 0xFF 
              };
              TextureHostSharedPtr textureHost = TextureHost::create();
              DP_ASSERT( textureHost );
              textureHost->setCreationFlags( TextureHost::F_PRESERVE_IMAGE_DATA_AFTER_UPLOAD );
              unsigned int index = textureHost->addImage( 2, 2, 1, Image::IMG_RGBA, Image::IMG_UNSIGNED_BYTE );
              DP_ASSERT( index != -1 );
              textureHost->setImageData( index, (const void *) &texel[0] );
              textureHost->setTextureTarget( TT_TEXTURE_2D );

              SamplerSharedPtr sampler = Sampler::create( textureHost );
              DP_ASSERT( sampler );
              sampler->setName( "default_sampler2D" );
              sampler->setMagFilterMode( TFM_MAG_NEAREST );
              sampler->setMinFilterMode( TFM_MIN_NEAREST );
              setParameter( it, sampler );
            }
          }
          else
          {
            // No other pointer types than samplers are supported inside the EffectLibrary so far.
            DP_ASSERT( ( it->first.getType() & PT_POINTER_TYPE_MASK ) == 0 );

            if ( it->first.getDefaultValue() )
            {
              setParameter( it, data->getParameter( it ) );
            }
          }
        }
      }