User Tools

Site Tools


Example: Materials Only

This is a straightforward example that focuses on pulling material definitions only. It does not query any geometry. Most queries are set up similarly to this example. The general set up is:

  1. Make sure the callbacks are set (done once per application lifetime).
  2. Allocate a new SSteEngine object.
  3. Load the SpeedTree Model file (STE or SPM).
  4. Create, init, and set the query options using SSteGeometryOptions.
  5. Call SteGetGeometry to force a compute and return the SSteGeometry object.
  6. Pull needed data from SSteGeometry object.
  7. Clean up by deleting the SSteGeometry and SSteEngine objects.
#include <cstdio>
#include "speedtree_engine.h"
 
///////////////////////////////////////////////////////////////////////
//  SpeedTree Engine API error callback
 
static void MyEngineApiErrorCallback(const char* pError)
{
    fprintf(stderr, "    **[Error Report from SpeedTree Engine API]**: %s\n", pError);
}
 
 
///////////////////////////////////////////////////////////////////////
//  SpeedTree Engine API message callback
 
static void MyEngineApiMessageCallback(const char* pMessage)
{
    fprintf(stderr, "    [Message from SpeedTree Engine API]: %s\n", pMessage);
}
 
 
///////////////////////////////////////////////////////////////////////
//  Example_MaterialsOnly
 
bool Example_MaterialsOnly(const char* pModelFilename)
{
    bool bSuccess = false;
 
    // register callback message functions; when api calls fail, messages will be sent here
    SteSetErrorFunction(MyEngineApiErrorCallback);
    SteSetMessageFunction(MyEngineApiMessageCallback);
 
    // uses a C interface -- objects are created and initialized through function calls
    SSteEngine* pEngine = SteNew( );
    if (pEngine)
    {
        // this causes the model file to be loaded and parsed, but nothing is computed yet
        if (SteLoadSpeedTreeFile(pEngine, pModelFilename) == STE_SUCCESS)
        {
            // 'geometry' is used in a lot of these function names, but the materials are
            // the only part we're interested in in this example
 
            // use SSteGeometryOptions to isolate just materials
            SSteGeometryOptions sQueryOptions;
            SteInitGeometryOptions(pEngine, &sQueryOptions);
 
            // SteInitGeometryOptions is mostly fine, but we don't need geometry here
            sQueryOptions.m_bExport3dGeometry = false;
 
            // causes a tree compute to make the data avaialble
            SSteGeometry* pGeometry = SteGetGeometry(pEngine, &sQueryOptions);
            if (pGeometry)
            {
                // report a few things about the materials now that have them
                printf("# of materials: %d\n\n", pGeometry->m_nNumMaterials);
 
                for (int i = 0; i < pGeometry->m_nNumMaterials; ++i)
                {
                    printf("material %d (id: %d) is called '%s' and has color map: [%s], two-sided: %d\n", i,
                           pGeometry->m_pMaterials[i].m_nID,
                           pGeometry->m_pMaterials[i].m_szName,
                           pGeometry->m_pMaterials[i].m_aMaps[STE_MAP_COLOR].m_szFilename,
                           pGeometry->m_pMaterials[i].m_bTwoSided);
                }
 
                // using C, so no destructors
                SteDeleteGeometry(pGeometry);
 
                bSuccess = true;
            }
            else
            {
                // if there's a failure, a message will be sent via the callback
            }
        }
        else
        {
            // if there's a failure, a message will be sent via the callback
        }
 
        // using C, so no destructors
        SteDelete(pEngine);
    }
 
    return bSuccess;
}