Demeter Terrain Engine >> Documentation >> Loaders

Home

News

Forums

Help
General
Mailing List
Screenshots
Documentation
Dependencies
Project Architecture
Core Library
Loaders
Building Demeter
Common Tasks
API Reference

Downloads

Consulting

Contribute

Report a Bug
Make a Request

CVS Access

Browse CVS tree

License

Loaders

Elevation Loaders

Using Elevation Loaders
Interface Specification
GDALElevationLoader
DemeterElevationLoader

Texture Loaders

Overall Terrain Textures
Common Terrain Textures
Shared Textures
Using Texture Loaders
Interface Specification
SDLTextureLoader
DemeterTextureLoader

Elevation Loaders and Texture Loaders are simply shared objects (DLL’s on Windows) that are able to load data from some data source and pass that data to the Demeter core library on your behalf. Loaders are loaded dynamically at runtime if and when your application requests that they load elevation or texture data. Demeter bundles several elevation and texture loaders for your use and it is a trivial matter for you to develop your own Loaders.

Loaders are kept separate in this way in order to reduce your application’s dependency on 3rd party libraries and to make Demeter extensible. Since most Loaders make use of 3rd party libraries (such as image manipulation libraries, terrain data libraries, etc.) you are able to choose which, if any, of those dependencies are required for your particular application by using only the Loaders that you need.

For any Elevation Loader or Texture Loader to work in your application, it must be installed properly on the end user’s system. In Windows, you may place the Loader’s DLL in the same directory as your application or in the user’s path or in one of the system folders. In UN!X’es, you must either place the Loader in a standard library directory such as /usr/lib or /usr/local/lib, or you must have your user edit his LD_LIBRARY_PATH to include your application’s directory.

For those Loaders that take filenames as parameters, they generally use a concept called the “media path.” Loaders will automatically prepend the global “media path” to any filenames that you pass to them. Therefore, you must use the Settings class to specify where your elevation and texture files will be loaded from (the “media path”) before attempting to use the Loader object. For example:

#ifdef _WIN32
    Settings::GetInstance()->SetMediaPath("..\\data\\");
#else
    Settings::GetInstance()->SetMediaPath("../data/");
#endif

This Code snippet specifies that elevation files will be loaded from the “data” directory of the application, which is presumed to be a peer directory of the application’s working directory.

If you are adamantly opposed to use of the “media path”, then you can pass an absolute filename to the Loader instead, and as long as it is a well-behaved Loader, it will not prepend the media path.


Elevation Loaders

Elevation Loaders provide instances of the Terrain class with digital elevation data. An Elevation Loader simply does work that you could have done for yourself via the core library, which is to call the SetAllElevations() method of the Terrain class with an array of floats representing terrain vertices. Elevation Loaders derive these arrays of floats from data sources such as digital elevation files on your behalf.

Using Elevation Loaders

Access to Elevation Loaders is provided through a Singleton object called Loader. The Loader object automatically loads the shared object or DLL that your application is requesting service from and passes your request along to the loaded library. To use an Elevation Loader, first construct an instance of the Terrain class and then tell the Loader object to load elevation data into your instance of Terrain. For example:

Terrain* pTerrain = new Terrain();
Loader::GetInstance()->LoadElevations("GDALEvationLoader", "LlanoElev.png,20.0,3.0", pTerrain);

From the example above, you can see that the Loader object’s LoadElevations() method takes 3 parameters:
const char* szLoaderName: this parameter specifies the name of the Elevation Loader from which you’re requesting service. In this example, the GDAL Elevation Loader that is bundled with Demeter is being used. On a UN!X system, this will cause the shared object libGDALElevationLoader.so to be dynamically loaded. On Windows systems, the DLL GDALElevationLoader.dll will be loaded.
const char* szLoaderParams: this parameter is a string that described to the Elevation Loader what the data source for elevation data is. Every Elevation Loader has its own unique set of parameters. The only way to know what to pass for this szLoaderParams parameter is to consult the documentation for the particular Elevation Loader being used. In this example, you can see that the GDAL Elevation Loader expects 3 parameters: an elevation filename, a vertex spacing, and an elevation scale (these are described fully in the section on the GDAL Elevation Loader.) Other Elevation Loaders might take a different set of parameters, but they are always passed as a single comma-delimited string to the Loader object.
Terrain* pTerrain: this parameter tells the Loader object which Terrain object is to be loaded with terrain vertex data.

When the call to LoadElevations() returns, your Terrain object is now loaded with elevation data so it can be used for rendering, picking, line-of-sight testing, etc. Most applications, however, will want to also load the Terrain object with textures before rendering it.

Interface Specification

If you wish to implement your own Elevation Loader, you must create a shared object that exports the following function:

extern "C" TERRAIN_API void LoadElevations(int argc, const char** argv, Terrain* pTerrain)

As in the main() function of any C program, the argc and argv arguments tell you what parameters have been passed to your Loader. Your function is obligated to set all of the vertices of the passed in Terrain object (typically by loading or generating some kind of data and using it to call the Terrain object’s SetAllElevations() method).

GDALElevationLoader

This Elevation Loader is bundled with Demeter. It uses the GDAL library, which is an open source digital elevation I/O library led by Frank Warmerdam. You can find GDAL at http://www.remotesensing.org/gdal/. It enables your application to read an incredible variety of files. Using this Elevation Loader, you can load your Terrain object with everything from simple grayscale image files to real digital elevation data files. As of GDAL 1.1.7, supported file formats are:

Arc/Info ASCII Grid
Arc/Info Binary Grid (.adf)
BSB Nautical Chart Format (.kap)
CEOS (Spot for instance)
First Generation USGS DOQ (.doq)
New Labelled USGS DOQ (.doq)
Military Elevation Data (.dt0, .dt1)
Eosat Fast Format
ERMapper Compressed Wavelets (.ecw)
ESRI .hdr Labelled
ENVI .hdr Labelled Raster
Envisat Image Product (.n1)
FITS (.fits)
Graphics Interchange Format (.gif)
Arc/Info Binary Grid (.adf)
GRASS Rasters
TIFF / GeoTIFF (.tif)
Erdas Imagine (.img)
Atlantis MFF2e
Japanese DEM (.mem)
JPEG JFIF (.jpg)
Atlantis MFF
OGDI Bridge
PCI .aux Labeled
Portable Network Graphics (.png)
Netpbm (.ppm,.pgm)
USGS SDTS DEM (*CATD.DDF)
SAR CEOS
USGS ASCII DEM (.dem)
X11 Pixmap (.xpm)
NOAA Polar Orbiter Level 1b Data Set (AVHRR)
Hierarchical Data Format Release 4 (HDF4)
EOSAT FAST Format

The GDAL Elevation Loader takes 3 parameters: the filename to load, the distance in world units between vertices in the resultant terrain, and a vertical scaling factor to be applied to the elevation of each loaded vertex. This Elevation Loader will guarantee that the Terrain being loaded is the requisite power of 2 in width and height by zero-filling to the next power of 2 in both directions. Therefore, if you have a choice, try to make sure that the elevation data you’re loading is already a power of 2 in width and height to avoid waste.

The bundled sample application called SampleGDALApplication demonstrates use of the GDALElevationLoader.

DemeterElevationLoader

This Elevation Loader only loads a single type of file: those generated by the Demeter Texture Editor application. If you use the Demeter Texture Editor to create a detail-painted terrain, you can use this Loader in your application to load it at runtime. There is also a corresponding DemeterTextureLoader that you will want to use in this scenario.

This Elevation Loader takes only a single parameter: the filename of the terrain to load (this is the name you choice when you saved the terrain in the Demeter Texture Editor application).

The bundled sample application called SampleDemeterApplication demonstrates use of the DemeterElevationLoader.


Texture Loaders

Texture Loaders provide image data which can be used for three purposes: as overall terrain textures, as “common” terrain textures, or as “shared” textures that can be used for detail painting on a terrain’s surface.

All images loaded by Texture Loaders MUST be a power of 2 in width and height and they must be at least 64x64 pixels in size. In general, you will want to use images that are 24-bits or 32-bits in color depth.

Overall Terrain Textures

An overall terrain texture is a single image that will be draped across the entire surface of a single terrain. Therefore, these are generally large images (on the order of 2048x2048 or larger in size). Demeter will automatically chop these large images into smaller images that can be managed as textures on the user’s 3D accelerator hardware.

Common Terrain Textures

A “common” texture is an inexpensive, easy, but inferior, alternative to using shared textures. A common texture is simply a small texture, usually on the order of 256x256 pixels, that is repeated infinitely across a terrain’s surface. This “common” texture is blended with the overall texture on the terrain’s surface. The purpose of the common texture is to provide the user with the impression of detail when the camera gets very close to the ground in the scene.

The Achilles’ Heel of this approach is that the entire terrain is covered with the same common texture, which is hardly ever a realistic depiction of ground.

Shared Textures

A superior, but more expensive, alternative to using a common texture, shared textures allow you to actually blend any number of unique, ground-specific textures at different places on a terrain’s surface. For example, in the areas that are grassy, you can use a shared grass texture and blend a high-detail grass texture with the overall terrain texture in those areas. In other areas that are dirt instead of grass, you can blend in a high-detail dirt texture, etc. With this approach, when the camera gets close to the ground, the user sees the appropriate kind of detail rather than a generic texture as you would get by using the “common” texture approach.

Shared textures perform very well on modern 3D accelerators, but if your application must support older 3D hardware, then you may be limited to the use of a “common” texture.

Using Texture Loaders

The API for accessing Texture Loaders is very similar to that of using Elevation Loaders. The main difference is that where the Loader singleton only offers a single method for Elevation Loaders called LoadElevations(), it offers 3 methods for Texture Loaders: LoadTerrainTexture(), LoadCommonTerrainTexture(), and LoadTexture(). These 3 methods correspond to the above sections on overall terrain textures, common terrain textures, and shared textures, respectively.

This Code snippet demonstrates how to load an overall terrain texture and a common terrain texture onto a terrain using the SDLTextureLoader:

Terrain* pTerrain = new Terrain();
Loader::GetInstance()->LoadElevations("GDALEvevationLoader", "LlanoElev.png,20.0,3.0", pTerrain);
Loader::GetInstance()->LoadTerrainTexture("SDLTextureLoader", "LlanoTex.jpg", pTerrain);
Loader::GetInstance()->LoadCommonTerrainTexture("SDLTextureLoader", "dirt2.jpg", pTerrain);

To load a shared texture, call the Loader object’s LoadTexture() method. This method returns a pointer to a Texture object. You can use this Texture object in calls to your Terrain object’s Paint() method to paint the texture onto the terrain’s surface, like so:

Texture* pTexture = Loader::GetInstance()->LoadTexture("SDLTextureLoader", "mug.png,false,false,true");
paintTextureID = pTerrain->GetTextureSet()->AddTexture(pTexture);
pTerrain->Paint(paintTextureID, 20, 0.25f, 1.0f, flase, x, y);

See the bundled sample application called SamplePaintApplication.cpp to see how this works.

Interface Specification

Implementing your own Texture Loaders is very similar to implementing Elevation Loaders. Simply make sure that your shared object exports the following functions:

extern "C" TERRAIN_API void LoadTerrainTexture(int argc, const char** argv, Terrain* pTerrain)
extern "C" TERRAIN_API void LoadCommonTerrainTexture(int argc, const char** argv, Terrain* pTerrain)
extern "C" TERRAIN_API Texture* LoadTexture(int argc, const char** argv)

SDLTextureLoader

This Texture Loader is bundled with Demeter and uses the SDL and SDL_image libraries to load image files. SDL and SDL_image are open source libraries led by Sam Lantinga. You can get them both at http://www.libsdl.org. Be sure to get the development versions of these libraries in order to build the SDLTextureLoader.

DemeterTextureLoader

This Texture Loader loads textures from a terrain file that was saved from the Demeter Texture Editor application. See the bundled sample SampleDemeterApplication.cpp to see this Loader in action.

SourceForge.net Logo Copyright ©2002 Clay Fowler