|
|
|
|
/*
|
|
|
|
|
This file is part of Magnum.
|
|
|
|
|
|
|
|
|
|
Copyright © 2010, 2011, 2012, 2013, 2014
|
|
|
|
|
Vladimír Vondruš <mosra@centrum.cz>
|
|
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
to deal in the Software without restriction, including without limitation
|
|
|
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
Software is furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included
|
|
|
|
|
in all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
|
DEALINGS IN THE SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
namespace Magnum {
|
|
|
|
|
/** @page plugins Loading and using plugins
|
|
|
|
|
@brief Extending Magnum with additional functionality
|
|
|
|
|
|
|
|
|
|
- Previous page: @ref transformations
|
|
|
|
|
- Next page: @ref shaders
|
|
|
|
|
|
|
|
|
|
The base Magnum library contains math support, scene graph implementation and
|
|
|
|
|
is able to interact with graphics and audio hardware. However, the base library
|
|
|
|
|
doesn't provide any functions for dealing with specific file formats, as there
|
|
|
|
|
are simply too many formats to have them included directly in the library.
|
|
|
|
|
Instead, the library provides plugin API and you can load plugin which will
|
|
|
|
|
then be able to read or write the particular file format.
|
|
|
|
|
|
|
|
|
|
@tableofcontents
|
|
|
|
|
|
|
|
|
|
The @ref building "Magnum repository" contains a few basic plugins for opening
|
|
|
|
|
the some formats, such as TGA images or WAV audio files. These plugins are
|
|
|
|
|
included because the file formats are so simple that no external library is
|
|
|
|
|
needed for loading their contents and thus they are suitable for quick demos
|
|
|
|
|
and prototyping without dealing with additional dependencies.
|
|
|
|
|
|
|
|
|
|
Additional plugins (such as importers for PNG and JPEG images, FreeType fonts
|
|
|
|
|
etc.) are available in @ref building-plugins "Magnum Plugins" repository.
|
|
|
|
|
Majority of these plugins depends on external libraries, thus some of them
|
|
|
|
|
might not be available on all platforms.
|
|
|
|
|
|
|
|
|
|
@section plugins-types Plugin interfaces
|
|
|
|
|
|
|
|
|
|
Magnum contains these plugin interfaces:
|
|
|
|
|
|
|
|
|
|
- @ref Trade::AbstractImporter -- importers for general 2D and 3D scene,
|
|
|
|
|
mesh, material, texture and image data. See `*Importer` classes in
|
|
|
|
|
@ref Trade namespace for available importer plugins. These are installed in
|
|
|
|
|
`MAGNUM_PLUGINS_IMPORTER_DIR` directory.
|
|
|
|
|
- @ref Trade::AbstractImageConverter -- conversion among various image
|
|
|
|
|
formats. See `*ImageConverter` classes in @ref Trade namespace for list of
|
|
|
|
|
available image converter plugins. These are installed in
|
|
|
|
|
`MAGNUM_PLUGINS_IMAGECONVERTER_DIR` directory.
|
|
|
|
|
- @ref Text::AbstractFont -- font loading and glyph layouting. See `*Font`
|
|
|
|
|
classes in @ref Text namespace for available font plugins. These are
|
|
|
|
|
installed in `MAGNUM_PLUGINS_FONT_DIR` directory.
|
|
|
|
|
- @ref Text::AbstractFontConverter -- font and glyph cache conversion. See
|
|
|
|
|
`*FontConverter` classes in @ref Text namespace for available font
|
|
|
|
|
converter plugins. These are installed in `MAGNUM_PLUGINS_FONTCONVERTER_DIR`
|
|
|
|
|
directory.
|
|
|
|
|
- @ref Audio::AbstractImporter -- importers for audio formats. See
|
|
|
|
|
`*Importer` classes in @ref Audio namespace for available audio importer
|
|
|
|
|
plugins. These are installed in `MAGNUM_PLUGINS_AUDIOIMPORTER_DIR`
|
|
|
|
|
directory.
|
|
|
|
|
|
|
|
|
|
@section plugins-loading Loading and instantiating the plugins
|
|
|
|
|
|
|
|
|
|
To load the plugins, you need to instantiate @ref Corrade::PluginManager::Manager
|
|
|
|
|
for given plugin interface, for example @ref Trade::AbstractImporter. You must
|
|
|
|
|
set particular plugin directory, from which the manager will load and
|
|
|
|
|
instantiate the plugins. To save you from hardcoding the value into your
|
|
|
|
|
application source, the plugin directory is provided as `MAGNUM_PLUGINS_DIR`
|
|
|
|
|
CMake variable. The default is set to Magnum install location, but you can
|
|
|
|
|
change it through CMake to anything else. The `MAGNUM_PLUGINS_IMPORTER_DIR`,
|
|
|
|
|
`MAGNUM_PLUGINS_IMAGECONVERTER_DIR`, `MAGNUM_PLUGINS_FONT_DIR`,
|
|
|
|
|
`MAGNUM_PLUGINS_FONTCONVERTER_DIR`, `MAGNUM_PLUGINS_AUDIOIMPORTER_DIR`
|
|
|
|
|
variables depend on `MAGNUM_PLUGINS_DIR`, so if you modify that variable, the
|
|
|
|
|
changes will be reflected in these variables too. See @ref cmake for additional
|
|
|
|
|
information.
|
|
|
|
|
|
|
|
|
|
You can provide the variable to your sources using CMake configuration file.
|
|
|
|
|
Create `configure.h.cmake` file in your source directory with contents similar
|
|
|
|
|
to these:
|
|
|
|
|
@code
|
|
|
|
|
#define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DIR}"
|
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
|
In case you are using multi-configuration build system (such as Visual Studio
|
|
|
|
|
or XCode), CMake cannot provide separate plugin directory for debug and release
|
|
|
|
|
build and you have to select between `MAGNUM_PLUGINS_*_DIR` and
|
|
|
|
|
`MAGNUM_PLUGINS_*_DEBUG_DIR` based on @ref corrade-cmake "CORRADE_IS_DEBUG_BUILD"
|
|
|
|
|
preprocessor variable. This will ensure that you use debug plugin directory for
|
|
|
|
|
debug build on multi-configuration build sytems and fall back to autodetection
|
|
|
|
|
for the rest:
|
|
|
|
|
@code
|
|
|
|
|
#ifdef CORRADE_IS_DEBUG_BUILD
|
|
|
|
|
#define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR}"
|
|
|
|
|
#else
|
|
|
|
|
#define MAGNUM_PLUGINS_IMPORTER_DIR "${MAGNUM_PLUGINS_IMPORTER_DIR}"
|
|
|
|
|
#endif
|
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
|
However, if you want to use only one (debug/release) plugin version for both
|
|
|
|
|
debug and release configurations of the application, you need to edit
|
|
|
|
|
`MAGNUM_PLUGINS_DIR` or `MAGNUM_PLUGINS_DEBUG_DIR` using CMake and point them
|
|
|
|
|
to directory containing desired plugin version.
|
|
|
|
|
|
|
|
|
|
Then process the file in your `CMakeLists.txt`. The result
|
|
|
|
|
(`${MAGNUM_PLUGINS_IMPORTER_DIR}` / `${MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR}` gets
|
|
|
|
|
replaced with the actual value) is put into build directory, so don't forget to
|
|
|
|
|
add it to include path:
|
|
|
|
|
@code
|
|
|
|
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake
|
|
|
|
|
${CMAKE_CURRENT_BINARY_DIR}/configure.h)
|
|
|
|
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
|
Then you can instantiate the manager, load particular plugin and create an
|
|
|
|
|
instance of it. Keep in mind that the manager instance must exist for whole
|
|
|
|
|
lifetime of all plugin instances created from it.
|
|
|
|
|
@code
|
|
|
|
|
#include "configure.h"
|
|
|
|
|
|
|
|
|
|
// ...
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
PluginManager::Manager<Trade::AbstractImporter> manager{MAGNUM_PLUGINS_IMPORTER_DIR};
|
|
|
|
|
std::unique_ptr<Trade::AbstractImporter> tgaImporter = manager.loadAndInstantiate("TgaImporter");
|
|
|
|
|
if(!tgaImporter) {
|
|
|
|
|
Error() << "Cannot load importer plugin from" << manager.pluginDirectory();
|
|
|
|
|
std::exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Use the plugin...
|
|
|
|
|
|
|
|
|
|
// At the end of the scope the tgaImporter instance gets deleted and then
|
|
|
|
|
// the manager automatically unloads the plugin on destruction
|
|
|
|
|
}
|
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
|
@section plugins-dependencies Plugin dependencies
|
|
|
|
|
|
|
|
|
|
Some plugins have dependencies, for example the @ref Text::MagnumFont "MagnumFont"
|
|
|
|
|
plugin needs to load the glyph atlas using @ref Trade::TgaImporter "TgaImporter"
|
|
|
|
|
plugin. The dependency loading is done automatically, but you need to create
|
|
|
|
|
instance of corresponding plugin manager in particular plugin dir so the
|
|
|
|
|
dependency can be found. Example:
|
|
|
|
|
@code
|
|
|
|
|
PluginManager::Manager<Trade::AbstractImporter> importerManager(MAGNUM_PLUGINS_IMPORTER_DIR);
|
|
|
|
|
PluginManager::Manager<Text::AbstractFont> fontManager(MAGNUM_PLUGINS_FONT_DIR);
|
|
|
|
|
|
|
|
|
|
// As a side effect TgaImporter is loaded by importerManager
|
|
|
|
|
fontManager.load("MagnumFont");
|
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
|
@section plugins-static Static plugins
|
|
|
|
|
|
|
|
|
|
By default all plugins are built as dynamic ones, i.e. they are separate
|
|
|
|
|
binary which gets linked in at runtime. This is good for reducing memory
|
|
|
|
|
consumption, as the code is loaded in memory only for the time it is needed.
|
|
|
|
|
However, if you want to port to platform which does not support dynamic linking
|
|
|
|
|
or you simply want to have the plugin loaded at all times, you can use static
|
|
|
|
|
plugins.
|
|
|
|
|
|
|
|
|
|
The plugins are built as static if `BUILD_STATIC` CMake parameter is enabled
|
|
|
|
|
(see @ref building and @ref building-plugins for more information). The actual
|
|
|
|
|
usage is basically the same as above, but you need to explicitly find the
|
|
|
|
|
plugin and link it into the executable in your `CMakeLists.txt`. See @ref cmake
|
|
|
|
|
and @ref cmake-plugins for additional information.
|
|
|
|
|
@code
|
|
|
|
|
find_package(Magnum REQUIRED TgaImporter)
|
|
|
|
|
|
|
|
|
|
add_executable(MyApp ...)
|
|
|
|
|
target_link_libraries(MyApp ... ${MAGNUM_TGAIMPORTER_LIBRARIES})
|
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
|
The only user-visible behavioral change will be that
|
|
|
|
|
@ref Corrade::PluginManager::AbstractManager::load() "PluginManager::Manager::load()"
|
|
|
|
|
will return @ref Corrade::PluginManager::LoadState::Static "PluginManager::LoadState::Static"
|
|
|
|
|
instead of @ref Corrade::PluginManager::LoadState::Loaded "PluginManager::LoadState::Loaded",
|
|
|
|
|
but there is no need to change the above code, as it will work for both dynamic
|
|
|
|
|
and static case.
|
|
|
|
|
|
|
|
|
|
If you link the plugin into dynamic library or executable, it will register
|
|
|
|
|
itself automatically, but if you want to link the plugin into static library,
|
|
|
|
|
you need to register it yourself with @ref CORRADE_PLUGIN_IMPORT() in some
|
|
|
|
|
function which will be executed before you use the plugin. See the macro
|
|
|
|
|
documentation for information about automatic importing and namespace issues.
|
|
|
|
|
@code
|
|
|
|
|
int main(int argc, char** argv) {
|
|
|
|
|
CORRADE_PLUGIN_IMPORT(TgaImporter)
|
|
|
|
|
|
|
|
|
|
// ...
|
|
|
|
|
}
|
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
|
|
@section plugins-develop Developing your own plugins
|
|
|
|
|
|
|
|
|
|
See class documentation of particular plugin interfaces for more information
|
|
|
|
|
about subclassing. The Corrade's @ref plugin-management "plugin management tutorial"
|
|
|
|
|
contains more information about plugin compilation and registering.
|
|
|
|
|
|
|
|
|
|
If you want to develop a plugin which depends on another, you need to find the
|
|
|
|
|
original plugin, add its include dirs to include path and link to it, similarly
|
|
|
|
|
to how static plugins are found above. See @ref cmake and @ref cmake-plugins
|
|
|
|
|
for more information.
|
|
|
|
|
|
|
|
|
|
- Previous page: @ref transformations
|
|
|
|
|
- Next page: @ref shaders
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
}
|