Skip to content

Latest commit

 

History

History

01.EmbedResource

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Table of contents

This example is part of OpenSceneGraph cross-platform examples.

In this example we embed box.osgt model (a binary resource) into application. Embedding binary resources unifies data loading for platforms with different file system requirements and constraints like desktop, Android, iOS, and web.

xxd can represent any binary file as unsigned char[], a C array that you can use as is in C/C++ applications.

Generate box.osgt.h C header from box.osgt model by running the following command:

xxd -i box.osgt > box.osgt.h

Generated box.osgt.h file looks like this:

unsigned char box_osgt[] = {
  0x23, 0x41, 0x73, 0x63, 0x69, 0x69, 0x20, 0x53, 0x63, 0x65, 0x6e, 0x65,
  0x0a, 0x23, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x39, 0x32,
  0x0a, 0x23, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x20,
  0x6f, 0x73, 0x67, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x30, 0x2e,
  0x31, 0x33, 0x2e, 0x30, 0x0a, 0x0a, 0x6f, 0x73, 0x67, 0x3a, 0x3a, 0x47,
  - - - - trimmed for brevity - - - -
  0x20, 0x20, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x30, 0x2e,
  0x30, 0x30, 0x30, 0x30, 0x30, 0x20, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x30,
  0x30, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a,
  0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x0a
};
unsigned int box_osgt_len = 32058;

As you can see, xxd created two variables:

  • unsigned char box_osgt[], an array of raw bytes
  • unsigned int box_osgt_len, size of the array

Both variables start with box_osgt, which is derived from box.osgt filename.

First, reference box.osgt.h(source code):

#include "box.osgt.h"

Second, make sure CMakeLists.txt includes the directory with box.osgt.h (source code):

INCLUDE_DIRECTORIES(${OSGCPE_DIR}/data)

In order to let OpenSceneGraph access the data from a C array, we have to represent it as std::istream.

To simplify resource management in code, we introduce two classes:

  • Resource to hold generated contents
  • ResourceStreamBuffer to provide C array contents as std::streambuf, which can be converted to std::istream

Note: ResourceStreamBuffer::seekoff() implementation is crucial for OpenSceneGraph plugins to correctly load resources.

First, create Resource instance to work with (source code):

resource::Resource box("models", "box.osgt", box_osgt, box_osgt_len);

Second, load the model. To load the model from std::istream, we:

  • find a reader that is capable of reading the model (such a reader can be located by providing file extension)
  • let the reader create a node with the model

Here's how the crucial part of the implementation looks like (source code):

- - - -
auto reader = osgDB::Registry::instance()->getReaderWriterForExtension(extension);
if (reader)
{
    ResourceStreamBuffer buf(box);
    std::istream in(&buf);
    auto result = reader->readNode(in, 0);
    if (result.success())
    {
        node = result.getNode();
    }
- - - -

Third, reference plugin capable of loading .osgt (source code):

USE_OSGPLUGIN(osg2)
USE_SERIALIZER_WRAPPER_LIBRARY(osg)

Screenshot

Here's a web build of the example.