The SpeedTree pipeline is built for flexibility which can add a little more complexity to the export/import process. When an .stsdk file is exported from the SpeedTree Modeler application, the user selects which texture packer will be used. References:
.stsdk files contain only texture filenames, not the actual texture data.
The following code illustrates how to load an .stsdk file and query its materials and associated textures.
#include "Core/Core.h" // speedtree types using SpeedTree::st_uint32; using SpeedTree::st_float16; using SpeedTree::st_uint8; using SpeedTree::st_uint16; void MyErrorCallback(const char* pMsg) { fprintf(stderr, "SpeedTree SDK Error: [%s]\n", pMsg); } void ShowMaterialAccess(const char* pFilename) { // set up error callback SpeedTree::Callbacks::Error( ) = MyErrorCallback; // parameters needed to load SpeedTree::CCore::SLoadConfig sLoadConfig; sLoadConfig.m_strFilename = pFilename; sLoadConfig.m_bGrassModel = false; // create a model to hold and read the stsdk file SpeedTree::CCore cModel; if (cModel.LoadTree(sLoadConfig)) { st_uint32 uiNumMaterials = cModel.Materials( ).Count( ); for (st_uint32 i = 0; i < uiNumMaterials; ++i) { // get next material, prine name SpeedTree::CFileMaterial cMaterial = cModel.Materials( )[i]; printf("material[%d] \"%s\"\n", i, cMaterial.Name( ).Data( )); // each material has keeps its own count, but the SDK is configured to // copy no more than ST_MAX_NUM_STSDK_MATERIAL_MAPS for (st_uint32 j = 0; j < cMaterial.Maps( ).Count( ) && j < ST_MAX_NUM_STSDK_MATERIAL_MAPS; ++j) { printf("\tmap[%d] filename: \"%s\"\n", j, cMaterial.Maps( )[j].Path( ).Data( )); } // the SDK does not have an enumeration defining what type of material each map defines // (e.g. 0 = ALBEDO, 1 = NORMAL) because this is determined by the texture packer in the // Modeler application; each user/team sets their own pipeline } } }