Game Development Reference
In-Depth Information
Listing 1-2. The Asset Converter Interface
class AssetConverter
{
public:
enum EType
{
eType_Unknown = 0,
eType_Compiler = 0>>1,
eType_Importer = 1>>1,
eType_ImporterCompiler
= (eType_Compiler | eType_Importer)
};
AssetConverter(){}
virtual ~AssetConverter(){};
virtual bool convert(const char* pSrcFilename, const char* pDestPath, const Args& rArgs) = 0; //
Args class is a command line argument parser, not shown here. Basically holds a list of arguments
and their values
virtual const char* supportedExtensions() const = 0;
virtual EType type() const = 0;
};
The asset converter has a type that represents what the converter does with the given input file: compiles or
converts. You make this distinction between compilers and converters because you would like to use compilers to
compile data from your intermediate format to the final platform-optimized format, and converters to convert from
third party formats to your intermediate format. An example of a compiler is cube.json (the intermediate format) to
cube.mesh (final optimized format); of a converter, cube.fbx to cube.json .
You can also have a compiler and a converter in one implementation ( flag eType_ImporterCompiler ) that can
handle third party and intermediate formats (for example, a TextureConverter that converts third party JPG/PNGs
and compiles to a custom format like .TEX ).
The convert method is the one called by the asset compiler executable when the given command-line arguments
are passed to it, and they match the file extensions returned by the supportedExtensions() method. This function
should return something like a file mask such as *.jpg , *.tga , *.png , or *.texture , so even a simple substring
matching test can select the right converter(s). The command line arguments are shared for all the converters; each
one can pick up its own arguments and their values.
By convention, the converters will be called first on the given assets, and after that you will call the compilers.
Since you (probably) generated/converted assets from the previous step, now you can compile those intermediate
formats into final binary optimized ones for specific platforms.
The main asset compiler executable will load all plug-in DLLs from either a specific folder or the same folder as
the executable. You can use any kind of plug-in loading scheme. For example, you can have those DLLs with their
extensions named .plugin, .converter, etc. In this way, you dynamically load only the eligible ones, skipping the
unsupported/unknown DLLs.
Once a plug-in is loaded, you retrieve the address of the DLL exported createAssetConverter() function and
instantiate the converter. Then, with all plug-ins loaded, you match each input asset filename with the return string
of the supportedExtensions() of each converter. If the match is true, then you call the converter to take care of that
file type. After that, you can continue to pass the filename to be handled by other matching converters, or you could
come up with a stop Boolean return value so the file will be handled only once by a single converter and not by further
matching converters if the return value is false. Even further, you could have some sort of dependency tree dictating
when converters would be called after others have finished converting assets.
Search WWH ::




Custom Search