====== File Loading Interface ====== The SpeedTree SDK makes several reads from the host platform's file system (e.g. reading textures, tree models, and shaders), but every access is routed through an overrideable interface, giving the client application a chance to intercept the request and provide the file data through a custom implementation (while it is not ideal for a middleware product to make direct I/O calls, this can prove useful during early stage of development). Most commonly, games may have one or more large files that house a conglomeration of different files, compiled together when packaging the game's assets. Specifically, the following class interface is available to be overridden: /////////////////////////////////////////////////////////////////////// // class CFileSystem class CFileSystem { public: enum ETermHint { SHORT_TERM, LONG_TERM }; virtual st_bool FileExists(const st_char* pFilename); virtual size_t FileSize(const st_char* pFilename); // returns size in bytes virtual st_byte* LoadFile(const st_char* pFilename, ETermHint eTermHint = SHORT_TERM); virtual void Release(st_byte* pBuffer); virtual CFixedString CleanPlatformFilename(const st_char* pFilename); }; By default, the SDK provides definitions for these functions that implement standard file read()/open()-level functionality. Some notes about this interface class: * When a file is loaded via LoadFile(), a hint is passed about whether the SDK needs the returned memory block for long or short term. For example, a short term load might be a texture that's simply being uploaded to the GPU and flushed. A long term load might be an SRT file, depending on usage. * Note that because most of the SDK's resources use search paths, FileExists() may be called several times for a single load. This is the SDK's way of determining which of the search paths contains the requested file. * Use CleanPlatformFilename() to provide a filename formatted for a given platform. Some platforms, like the Xbox 360, can be very sensitive to mixed forward and backslashes, or not support "../". This overridable function attempts to create a clean filename for the compiled platform (#ifdefs are used internally to determine the platform). ---- ===== Using the Interface ===== The reference application contains a full example of how to override the CFileSystem interface in MyFileSystem.h. Once the class is defined, as in CMyFileSystem in the reference application, the SDK can be notified of it using the following approach: // create an object of the derived file system CMyFileSystem g_cMyFileSystem; // pass that object into the SDK's CFileSystemInterface SpeedTree::CFileSystemInterface g_cFileSystemInterface(&g_cMyFileSystem); A global variable is normally used like this to ensure that the interface is established as early as possible (before main() is invoked).