CUGL 3.0
Cornell University Game Library
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | Friends | List of all members
cugl::scene3::MtlLoader Class Reference

#include <CUMtlLoader.h>

Inheritance diagram for cugl::scene3::MtlLoader:
cugl::Loader< Material > cugl::BaseLoader

Public Member Functions

 MtlLoader ()
 
void dispose () override
 
bool init () override
 
bool init (const std::shared_ptr< ThreadPool > &threads) override
 
std::shared_ptr< MaterialLibgetLibrary (std::string key)
 
- Public Member Functions inherited from cugl::Loader< Material >
 Loader ()
 
std::shared_ptr< Material > get (const std::string key) const
 
std::shared_ptr< Material > operator[] (const std::string key) const
 
size_t loadCount () const override
 
size_t inFlight () const override
 
void enqueue (const std::string key)
 
void unloadAll () override
 
virtual std::vector< std::string > keys () override
 
bool purgeKey (const std::string key) override
 
bool verify (const std::string key) const override
 
- Public Member Functions inherited from cugl::BaseLoader
 BaseLoader ()
 
 ~BaseLoader ()
 
virtual void dispose ()
 
virtual bool init ()
 
virtual bool init (const std::shared_ptr< ThreadPool > &threads)
 
std::shared_ptr< BaseLoadergetHook ()
 
std::shared_ptr< ThreadPoolgetThreadPool () const
 
void setThreadPool (const std::shared_ptr< ThreadPool > &threads)
 
void setManager (AssetManager *manager)
 
const AssetManagergetManager () const
 
void setJsonKey (const std::string key)
 
const std::string getJsonKey () const
 
void setPriority (Uint32 priority)
 
const Uint32 getPriority () const
 
bool load (const std::string key, const std::string source)
 
bool load (const std::shared_ptr< JsonValue > &json)
 
void loadAsync (const std::string key, const std::string source, LoaderCallback callback)
 
void loadAsync (const std::shared_ptr< JsonValue > &json, LoaderCallback callback)
 
bool unload (const std::string key)
 
bool unload (const std::shared_ptr< JsonValue > &json)
 
virtual void unloadAll ()
 
virtual std::vector< std::string > keys ()
 
bool contains (const std::string key) const
 
void reserve (size_t amount)
 
virtual size_t loadCount () const
 
size_t waitCount () const
 
virtual size_t inFlight () const
 
bool complete () const
 
float progress () const
 

Static Public Member Functions

static std::shared_ptr< MtlLoaderalloc ()
 
static std::shared_ptr< MtlLoaderalloc (const std::shared_ptr< ThreadPool > &threads)
 

Protected Member Functions

void preloadTexture (const std::shared_ptr< TextureInfo > &info, const std::shared_ptr< graphics::TextureLoader > &loader)
 
std::shared_ptr< graphics::TexturematerializeTexture (const std::shared_ptr< TextureInfo > &info, const std::shared_ptr< graphics::TextureLoader > &loader)
 
std::shared_ptr< MaterialLibpreload (const std::string key, const std::string source)
 
std::shared_ptr< MaterialLibpreload (const std::shared_ptr< JsonValue > &json)
 
bool materialize (const std::string key, const std::shared_ptr< MaterialLib > &lib, LoaderCallback callback)
 
virtual bool read (const std::string key, const std::string source, LoaderCallback callback, bool async) override
 
virtual bool read (const std::shared_ptr< JsonValue > &json, LoaderCallback callback, bool async) override
 
virtual bool purgeJson (const std::shared_ptr< JsonValue > &json) override
 
virtual bool read (const std::string key, const std::string source, LoaderCallback callback, bool async)
 
virtual bool read (const std::shared_ptr< JsonValue > &json, LoaderCallback callback, bool async)
 
virtual bool purgeKey (const std::string key)
 
virtual bool purgeJson (const std::shared_ptr< JsonValue > &json)
 
virtual bool verify (const std::string key) const
 

Protected Attributes

std::shared_ptr< ObjParser_parser
 
std::unordered_map< std::string, SDL_Surface * > _surfaces
 
std::unordered_map< std::string, std::shared_ptr< MaterialLib > > _libraries
 
- Protected Attributes inherited from cugl::Loader< Material >
std::unordered_map< std::string, std::shared_ptr< Material > > _assets
 
std::unordered_set< std::string > _queue
 
- Protected Attributes inherited from cugl::BaseLoader
std::string _jsonKey
 
Uint32 _priority
 
size_t _reserved
 
std::shared_ptr< ThreadPool_loader
 
AssetManager_manager
 

Friends

class ObjLoader
 

Detailed Description

This class is a specific implementation of Loader<Material>

This asset loader allows us to allocate materials from the associated MTL and graphics::Texture files. While most MTL files package their texture files in the same directory, that is not required. Using the JSON specification, it is possible to put these in different directories.

Note that an MTL loader is only responsible for materials. It is NOT responsible for loading graphics::Texture files. If a MTL uses any textures, there should be a graphics::TextureLoader associated with the AssetManager for loading these textures. If there is no such loader, then textures will fail to load.

In addition, an MTL file often has multiple materials inside of it. See the description of read for how this loader handles MTL files with multiple materials.

This implementation uses a two phase loading system. First, it loads as much of the asset as possible without using OpenGL. This allows us to load the model in a separate thread. It then finishes off the remainder of asset loading using Application#schedule. This is a good template for asset loaders in general.

As with all of our loaders, this loader is designed to be attached to an asset manager. Use the method getHook() to get the appropriate pointer for attaching the loader.

Constructor & Destructor Documentation

◆ MtlLoader()

cugl::scene3::MtlLoader::MtlLoader ( )
inline

Creates a new, uninitialized MTL loader

NEVER USE A CONSTRUCTOR WITH NEW. If you want to allocate a loader on the heap, use one of the static constructors instead.

Member Function Documentation

◆ alloc() [1/2]

static std::shared_ptr< MtlLoader > cugl::scene3::MtlLoader::alloc ( )
inlinestatic

Returns a newly allocated MTL loader.

This method bootstraps the loader with any initial resources that it needs to load assets. In particular, the OpenGL context must be active. Attempts to load an asset before this method is called will fail.

This loader will have no associated threads. That means any asynchronous loading will fail until a thread is provided via setThreadPool.

Returns
a newly allocated OBJ loader.

◆ alloc() [2/2]

static std::shared_ptr< MtlLoader > cugl::scene3::MtlLoader::alloc ( const std::shared_ptr< ThreadPool > &  threads)
inlinestatic

Returns a newly allocated MTL loader.

This method bootstraps the loader with any initial resources that it needs to load assets. In particular, the OpenGL context must be active. Attempts to load an asset before this method is called will fail.

Parameters
threadsThe thread pool for asynchronous loading
Returns
a newly allocated OBJ loader.

◆ dispose()

void cugl::scene3::MtlLoader::dispose ( )
inlineoverridevirtual

Disposes all resources and assets of this loader

Any assets loaded by this object will be immediately released by the loader. However, a texture may still be available if it is referenced by another smart pointer.

Once the loader is disposed, any attempts to load a new asset will fail. You must reinitialize the loader to begin loading assets again.

Reimplemented from cugl::BaseLoader.

◆ getLibrary()

std::shared_ptr< MaterialLib > cugl::scene3::MtlLoader::getLibrary ( std::string  key)

Returns a material library associated with the given key

While this loader is designed to only load materials, they are typically packaged in material libraries. This method exposes that organization. This method will return nullptr if no library for the given key has finished loading.

Parameters
keyThe key to identify the material library
Returns
a material library associated with the given key

◆ init() [1/2]

bool cugl::scene3::MtlLoader::init ( )
inlineoverridevirtual

Initializes a new MTL loader.

This method bootstraps the loader with any initial resources that it needs to load assets. Attempts to load an asset before this method is called will fail.

This loader will have no associated threads. That means any asynchronous loading will fail until a thread is provided via setThreadPool.

Returns
true if the asset loader was initialized successfully

Reimplemented from cugl::BaseLoader.

◆ init() [2/2]

bool cugl::scene3::MtlLoader::init ( const std::shared_ptr< ThreadPool > &  threads)
inlineoverridevirtual

Initializes a new MTL loader.

This method bootstraps the loader with any initial resources that it needs to load assets. Attempts to load an asset before this method is called will fail.

Parameters
threadsThe thread pool for asynchronous loading support
Returns
true if the asset loader was initialized successfully

Reimplemented from cugl::BaseLoader.

◆ materialize()

bool cugl::scene3::MtlLoader::materialize ( const std::string  key,
const std::shared_ptr< MaterialLib > &  lib,
LoaderCallback  callback 
)
protected

Finishes allocation of the material and assigns it the given key.

This method finishes the asset loading started in preload. This step is not safe to be done in a separate thread. Instead, it takes place in the main CUGL thread via Application#schedule.

Any additional textures loaded by the MTL file will be materialized at this time. This method will only work if all of the textures are in the same directory as the MTL file.

This method supports an optional callback function which reports whether the asset was successfully materialized.

Parameters
keyThe key to access the asset after loading
libThe material library to materialize
callbackAn optional callback for asynchronous loading
Returns
true if materialization was successful

◆ materializeTexture()

std::shared_ptr< graphics::Texture > cugl::scene3::MtlLoader::materializeTexture ( const std::shared_ptr< TextureInfo > &  info,
const std::shared_ptr< graphics::TextureLoader > &  loader 
)
protected

Creates a texture from the given information.

For best performance, all MTL textures should be loaded in a previous pass. However, if that is not the case, then this method can load any additional textures that are needed. This method uses the materialize pass of graphics::TextureLoader.

Parameters
infoThe texture information
loaderThe texture loader for the parent asset manager

◆ preload() [1/2]

std::shared_ptr< MaterialLib > cugl::scene3::MtlLoader::preload ( const std::shared_ptr< JsonValue > &  json)
protected

Loads the portion of this asset that is safe to load outside the main thread.

It is not safe to create an OpenGL buffer in a separate thread. However, it is generally safe to create a Material, as – aside from its textures – it does not require OpenGL for asset creation.

If the MTL file has any associated textures, this method will create a thread-safe instance using graphics::TextureLoader#preload. Those textures will be materialized the same time the Material is materialized on the main thread.

A MTL JSON entry can have several forms. In the simplest case, a MTL entry can just be a string. In that case, it is assumed to be a path to a MTL file. If that MTL file has any associated textures, they are loaded implicitly (and they must be in the same directory as the MTL file).

On the other hand, if the MTL entry is itself a JSON object, then it typically has the following values:

 "file":         The path to the MTL file
 "textures":     An object of key:value pairs defining textures

The "textures" entry is optional. For each texture, the key should match the name of the texture in the MTL file. Any missing textures will attempt to be loaded using the associated graphics::TextureLoader.

The values for the texture entries should be strings or JSONs. If they are string, they should be either be a key referencing a previously loaded texture, or a path the texture file (the loader interprets it as a path only if there is no key with that name). If it is a JSON, then the JSON should follow the same rules as graphics::TextureLoader.

Note that a MTL file can have multiple materials inside of it. For that reason, you should always access materials with key.name where name is the name of the material. You may only use the key by itself if there only one material in the file.

Finally, it is also possible for the JSON entry to define the material explicitly. In that case, it would have the following values:

 "name":             The texture name
 "ambient color":    The diffuse color
 "ambient map":      The diffuse texture
 "diffuse color":    The diffuse color
 "diffuse map":      The diffuse texture
 "specular color":   The specular color
 "specular map":     The specular texture

Any other material properties currently require an MTL file. The maps should follow the same rules as textures; either they are a key of a previously loaded texture, or they are the path to a texture file. The colors are either a four-element integer array (values 0..255) or a string. Any string should be a web color or a Tkinter color name. Materials loaded this way are referred to directly by their key. They do not have any associated MTL library.

Parameters
jsonThe JSON entry specifying the asset
Returns
the incomplete OBJ model

◆ preload() [2/2]

std::shared_ptr< MaterialLib > cugl::scene3::MtlLoader::preload ( const std::string  key,
const std::string  source 
)
protected

Loads the portion of this asset that is safe to load outside the main thread.

It is not safe to create an OpenGL buffer in a separate thread. However, it is generally safe to create a Material, as – aside from its textures – it does not require OpenGL for asset creation.

If the MTL file has any associated textures, this method will create a thread-safe instance using graphics::TextureLoader#preload. Those textures will be materialized the same time the Material is materialized on the main thread.

Note that MTL files may have more than one material in them. For that reason, you should access each material with key.name where name is the name of the material. You may only use the key by itself if there only one material in the file.

Parameters
keyThe key to access the asset after loading
sourceThe pathname to the asset
Returns
the incomplete material

◆ preloadTexture()

void cugl::scene3::MtlLoader::preloadTexture ( const std::shared_ptr< TextureInfo > &  info,
const std::shared_ptr< graphics::TextureLoader > &  loader 
)
protected

Loads the portion of the texture that is safe to load outside the main thread.

For best performance, all MTL textures should be loaded in a previous pass. However, if that is not the case, then this method can load any additional textures that are needed. This method uses the preload pass of graphics::TextureLoader.

Parameters
infoThe texture information
loaderThe texture loader for the parent asset manager

◆ purgeJson()

virtual bool cugl::scene3::MtlLoader::purgeJson ( const std::shared_ptr< JsonValue > &  json)
overrideprotectedvirtual

Unloads the asset for the given directory entry

An asset may still be available if it is referenced by a smart pointer. See the description of the specific implementation for how assets are released.

This method clears the internal buffers of any materials or textures associated with this model.

Parameters
jsonThe directory entry for the asset
Returns
true if the asset was successfully unloaded

Reimplemented from cugl::BaseLoader.

◆ read() [1/2]

virtual bool cugl::scene3::MtlLoader::read ( const std::shared_ptr< JsonValue > &  json,
LoaderCallback  callback,
bool  async 
)
overrideprotectedvirtual

Internal method to support asset loading.

This method supports either synchronous or asynchronous loading, as specified by the given parameter. If the loading is asynchronous, the user may specify an optional callback function.

This method will split the loading across the preload and materialize methods. This ensures that asynchronous loading is safe.

An MTL entries can have several forms. In the simplest case, an MTL entry can just be a string. In that case, it is assumed to be a path to a MTL file. If that MTL file has any associated textures, they are loaded implicitly (and they must be in the same directory as the MTL file).

Note that a MTL file can have multiple materials inside of it. For that reason, this asset loader associates each material with the key that is the key of the MTL file, followed by a period and the name of the material. So if the MTL file with key "fire" has two materials "bright" and "dim", they would be refered to as "fire.bright" and "fire.dim".

If a MTL entry is a JSON object, then it typically has the following values:

 "file":         The path to the MTL file
 "textures":     An object of key:value pairs defining textures

The "textures" entry is optional. For each texture, the key should match the name of the texture in the MTL file. Any missing textures will attempt to be loaded using the associated graphics::TextureLoader.

The values for the texture entries should be strings or JSONs. If they are string, they should be either be a key referencing a previously loaded texture, or a path the texture file (the loader interprets it as a path only if there is no key with that name). If it is a JSON, then the JSON should follow the same rules as graphics::TextureLoader.

Finally, it is also possible for the JSON entry to define the material explicitly. In that case, it would have the following values:

 "name":             The texture name
 "ambient color":    The diffuse color
 "ambient map":      The diffuse texture
 "diffuse color":    The diffuse color
 "diffuse map":      The diffuse texture
 "specular color":   The specular color
 "specular map":     The specular texture

Any other material properties currently require an MTL file. The maps should follow the same rules as textures; either they are a key of a previously loaded texture, or they are the path to a texture file. The colors are either a four-element integer array (values 0..255) or a string. Any string should be a web color or a Tkinter color name. Materials loaded this way are referred to directly by their key. They do not have any associated MTL library.

Parameters
jsonThe directory entry for the asset
callbackAn optional callback for asynchronous loading
asyncWhether the asset was loaded asynchronously
Returns
true if the asset was successfully loaded

Reimplemented from cugl::BaseLoader.

◆ read() [2/2]

virtual bool cugl::scene3::MtlLoader::read ( const std::string  key,
const std::string  source,
LoaderCallback  callback,
bool  async 
)
overrideprotectedvirtual

Internal method to support asset loading.

This method supports either synchronous or asynchronous loading, as specified by the given parameter. If the loading is asynchronous, the user may specify an optional callback function.

This method will split the loading across the preload and materialize methods. This ensures that asynchronous loading is safe.

This method will only work if all of the textures are in the same directory as the MTL file.

Note that MTL files may have more than one material in them. For that reason, you should access each material with key.name where name is the name of the material. You may only use the key by itself if there only one material in the file.

Parameters
keyThe key to access the asset after loading
sourceThe pathname to the asset
callbackAn optional callback for asynchronous loading
asyncWhether the asset was loaded asynchronously
Returns
true if the asset was successfully loaded

Reimplemented from cugl::BaseLoader.

Friends And Related Symbol Documentation

◆ ObjLoader

friend class ObjLoader
friend

These two loaders go together

Member Data Documentation

◆ _libraries

std::unordered_map<std::string,std::shared_ptr<MaterialLib> > cugl::scene3::MtlLoader::_libraries
protected

Keep track of material libraries

◆ _parser

std::shared_ptr<ObjParser> cugl::scene3::MtlLoader::_parser
protected

Integrated parser for finding objects and materials

◆ _surfaces

std::unordered_map<std::string,SDL_Surface*> cugl::scene3::MtlLoader::_surfaces
protected

Any textures that must be loaded on the fly


The documentation for this class was generated from the following file: