• 09/11/03 09:43 AM
    Sign in to follow this  

    Loading a Texture From a Zip File in DirectX 9

    General and Gameplay Programming

    Myopic Rhino

    Introduction

    This is a simple article on how to load textures from .ZIP files. I am using DirectX 9 (with the D3DX utility library) and unzip.h by Gilles Vollant (his work uses / is based on zlib). This code is for those programmers who might be interested in loading their images (or any file for that matter) from a .ZIP file for either compression or archival purposes (or both).

    Why not just include the images as resources into your .EXE? Well, first of all, including many large images as resources can increase your .EXE size and compilation time. Plus, .ZIP files are cool and practically everyone already has a compression program that can create them. Just think of all the space you'll save.

    The Code

    Using D3DX and the included unzip code makes everything easy. The idea is to use the unzip functions to open the zip file, find which file we want, and load it into memory. After we have it in memory, we can use D3DXCreateTextureFromFileInMemory() to load the image (which can be in .bmp, .dds, .dib, .jpg, .png, or .tga format). I do not claim that this code is the right way, nor the fastest or best way to do this. That being said, here is a function that wraps up all the .ZIP handling and texture creation code into one little package:

    // CreateTextureFromFileInZip()
    //  pDevice   The D3D9 device
    //  szZip     The .zip file
    //  szFile    The image file within the .zip
    //  ppTexture A pointer to the newly created texture
    //
    //  Return values:
    //  S_OK      Everything went ok.
    //  E_FAIL    Everything did not go ok. :-)
    //  E_OUTOFMEMORY  I'll let you guess on this one.
    
    HRESULT CreateTextureFromFileInZip( LPDIRECT3DDEVICE9 pDevice, LPCSTR szZip,
                                        LPCSTR szFile, LPDIRECT3DTEXTURE9 *ppTexture )
    {
      // open ZIP
      unzFile zip = unzOpen( szZip );
    
      if( !zip )
        return E_FAIL;
      
      // locate the file and open it (1 means case sensitive comparison)
      unzLocateFile( zip, szFile, 1 );
      
      if( unzOpenCurrentFile( zip ) != UNZ_OK )
        return E_FAIL;
      
      // find current file info (we are looking for uncompressed file size)
      unz_file_info info;
      unzGetCurrentFileInfo( zip, &info, NULL, 0, NULL, 0, NULL, 0 );
      
      // create a buffer big enough to hold uncompressed file in memory
      void *buffer = malloc( info.uncompressed_size );
    
      if( !buffer )
      {
        unzCloseCurrentFile( zip );
        unzClose( zip );
    
        return E_OUTOFMEMORY;
      }
      
      // load into memory
      unzReadCurrentFile( zip, buffer, info.uncompressed_size );
      
      unzCloseCurrentFile( zip );
      unzClose( zip );
    
      // use D3DX utility library to load our texture now.
      if( FAILED( D3DXCreateTextureFromFileInMemory( pDevice, buffer,
            info.uncompressed_size, ppTexture ) ) )
      {
        free( buffer );
        return E_FAIL;
      }
    
      free( buffer );
      return S_OK;
    }
    

    Notes & Improvements

    The CreateTextureFromFileInZip() function (whew! long name!) is rather easy to use. However, it is not the most efficient thing in the world. You may want to modify the code so if you are loading multiple files from the same .ZIP, you only need to load the .ZIP once. As it is, opening and closing the .ZIP file for each image is rather redundant. And of course, the wonderful call to malloc is regarded by some as evil. You could perhaps create a static buffer that is big enough to hold your largest image (uncompressed) and just reuse the same buffer for all your image loading. This would eliminate the need for malloc()/free(). However, D3DXCreateTextureFromFileInMemory() probably uses malloc() anyways, right?

    The included MSVC++ workspace and code demonstrate how to use this function. Nothing too fancy.

    Conclusion

    Thanks for reading and I hope somebody found this article to be of use.



      Report Article
    Sign in to follow this  


    User Feedback

    Create an account or sign in to leave a review

    You need to be a member in order to leave a review

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

    There are no reviews to display.