/bg2-io

bg2 engine native binary file input/output tools

Primary LanguageC++

bg2 file input/output

Standalone C++ library for reading and writing .bg2 files, the native file format of the graphics engine bg2 engine.

Build and debug

This project is ready for build with Visual Studio Code on Linux. Select the appropiate debug and/or build task to build it.

You will need the Microsoft extensions for C++.

For macOS, there is a Xcode project.

For Windows, there is a project for Visual Studio.

However, the code does not have any dependencies, nor does it require any macros to be configured. You can make it work in any other environment by simply adding the C files to the building system or IDE of your choice. To use the library:

  • If you want to use only bg2-io, you must compile the C files inside src/bg2-io directory. You'll have to also add this directory to the header search paths in your IDE/Makefiles/Cmake/Whatever
  • If you want to use bg2-scene, you also need to add the src/bg2-scene directory to the header search paths, and compile all the C++ files included in that folder.

Note for Xcode users: you probably want to disable the "Documentation Comments" warnings in build settings.

WebAssembly JavaScript library

You need to install and configure emscripten and nodejs in your system. The build script is prepared for work on macOS, Linux and WSL, but you probably can create a Windows command line bat script, based on src/wasm/build.sh. However, I recommend using WSL if you are on Windows. Note that the resulting code will be platform independent.

cd src/wasm
npm ci
npm run build

This will generate the following output files:

  • bin/wasm/bg2io/ Distribution package |- bg2io.js |- bg2io.wasm |- Bg2ioBrowser.js |- Bg2ioModule.cjs |- Bg2ioModule.wasm |- Bg2ioWrapper.mjs
  • bin/wasm |- example-browser.js |- index.html Example website

Test example on web browser

You can open index.html using a local web server (for example, using the Live Server Visual Studio Code extension) to test the example on the browser. Open de JavaScript console to view the example output.

If you want to create a website using webpack/rollup/gulp/whatever, you need to import the Bg2ioBrowser.js in your code, but its important to distribute also the bg2io.js and bg2io.wasm files with the rest of your code. These files must be placed next to the main JavaScript file generated by webpack/rollup. If not, you must pass the path to these files when you are going to use the library:

import Bg2ioBrowser from 'path/to/Bg2ioBrowser.js'

const wrapper = await Bg2ioBrowser({ wasmPath: 'path/to/bg2io/files' });
...

The included browser example places the bg2io.* files in another directory on purpose, so you can see a working example if this is your case. If you place all js and wasm files in the same location, you don't need to pass the wasmPath parameter.

Test example with Node.js

Note: You can run the node example AFTER running the build script.

cd src/wasm
node example-node.js

The files required to use Bg2io in a Node application are the following:

  • Bg2ioModule.cjs
  • Bg2ioModule.wasm
  • Bg2ioWrapper.mjs

The wasm file will probably contain the same code as the browser version, but this may not be the case, as optimization flags may be modified differently for each environment.

Unlike in the browser version, in the case of the Node.js application it is necessary to import the WebAssembly module and the wrapper separately. However, once the wrapper is created, the rest of the code will be identical. Obviously, there are other aspects of the code that will be different between the browser and a Node.js application: for example, in the browser we load the file with a fetch call, while for the Node.js application we use a readFileSync call. In both cases, the result is a buffer that can be used identically with the wrapper.

Below you can compare the two ways to get the bg2io wrapper from a browser or from Node.js:

Browser:

import Bg2ioWrapper from 'bg2io/Bg2ioBrowser.js' // you probably need to customize this path

const wrapper = await Bg2ioWrapper();
...

Node.js:

import Bg2ioWrapper from '../../bin/wasm/bg2io/Bg2ioWrapper.mjs';
import Bg2ioModule from '../../bin/wasm/bg2io/Bg2ioModule.cjs';

// Create the WebAssembly module instance
const moduleInstance = await Bg2ioModule();
// Create the wrapper
const wrapper = new Bg2ioWrapper({ instance: moduleInstance });
...

As you can see, once you get the bg2io wrapper, the differences in the code only have to do with the way to get the resources in the browser or in Node.js:

Browser:

...
const response = await fetch(modelPath);
if (!response.ok) {
    throw new Error("Could not load model");
}
const buffer = await response.arrayBuffer();

// From here it is the same in both environments.
const bg2File = wrapper.loadBg2File(buffer);
const header = bg2File.getBg2FileHeader(bg2File);
for (let i = 0; i<header.numberOfPlist; ++i) {
    const plist = wrapper.getPolyList(bg2File, i);
    console.log(plist);
}
wrapper.freeBg2File(bg2File);

Node.js:

...
const buffer = fs.readFileSync(modelPath);

// From here it is the same in both environments.
const bg2File = wrapper.loadBg2File(buffer);
const header = bg2File.getBg2FileHeader(bg2File);
for (let i = 0; i<header.numberOfPlist; ++i) {
    const plist = wrapper.getPolyList(bg2File, i);
    console.log(plist);
}
wrapper.freeBg2File(bg2File);