Getting cross platform rendering with Babylon Native and GLFW

Setup the Git repo

In order to make the project cross platform we will be creating a CMake based C++ project. This allows us to integrate nicely with Babylon Native and GLFW(which both use CMake). This is also good for cross platform development since it will generate a native solution (a Visual Studio project on Windows, an XCode project on Mac, etc.). More information on CMake can be found on their documentation page (CMake).

git clone https://github.com/SergioRZMasson/BabylonNativeGLFW.git
cd BabylonNativeGLFW
npm install
mkdir build
cd build
cmake .. -G PLATFORM_GENERATOR

Setting up GLFW

GLFW is a cross platform API for handling window management as well as input. It is very easy to use and provides support for Windows Mac and Linux. It also provides support for many rendering backends.

#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#if TARGET_PLATFORM_LINUX
#define GLFW_EXPOSE_NATIVE_X11
#elif TARGET_PLATFORM_OSX
#define GLFW_EXPOSE_NATIVE_COCOA
#elif TARGET_PLATFORM_WINDOWS
#define GLFW_EXPOSE_NATIVE_WIN32
#endif#include <GLFW/glfw3native.h>
static void *glfwNativeWindowHandle(GLFWwindow *_window)
{
#if TARGET_PLATFORM_LINUX
return (void *)(uintptr_t)glfwGetX11Window(_window);
#elif TARGET_PLATFORM_OSX
return ((NSWindow *)glfwGetCocoaWindow(_window)).contentView;
#elif TARGET_PLATFORM_WINDOWS
return glfwGetWin32Window(_window);
#endif // TARGET_PLATFORM_
}
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);auto window = glfwCreateWindow(INITIAL_WIDTH, INITIAL_HEIGHT, "Simple example", NULL, NULL);

Initializing Babylon Native Graphics

Babylon Native hides its graphics infrastructure under two main objects Babylon::Graphics::Device and Babylon::Graphics::DeviceUpdate. The first one is used to handle integration with bgfx, and the second will be used to sync the rendering loop with the engine Babylon.js running in the JavaScript thread.

Babylon::Graphics::WindowConfiguration graphicsConfig{};graphicsConfig.Window = glfwNativeWindowHandle(window);
graphicsConfig.Width = width;
graphicsConfig.Height = height;
graphicsConfig.MSAASamples = 4;
device = Babylon::Graphics::Device::Create(graphicsConfig);update = std::make_unique<Babylon::Graphics::DeviceUpdate>(device
->GetUpdate("update"));
device->StartRenderingCurrentFrame();
update->Start();

Initializing Javascript runtime

The Babylon::AppRuntime allows us to interact with the Javascript runtime. It is required for initializing other components, but it also can be used to call JavaScript functions and objects directly from C++.

runtime = std::make_unique<Babylon::AppRuntime>();
runtime->Dispatch([](Napi::Env env)
{
device->AddToJavaScript(env);

//Initialize more Plugins here...

Babylon::Plugins::NativeEngine::Initialize(env);
});

Render!

Having everything setup we can finally start rendering our scene. On the glfw update loop we just need 4 lines of code:

while (!glfwWindowShouldClose(window))
{
if (device)
{
update->Finish();
device->FinishRenderingCurrentFrame();
device->StartRenderingCurrentFrame();
update->Start();
}
glfwPollEvents();
}
device->FinishRenderingCurrentFrame();
device->StartRenderingCurrentFrame();
update->Start();

Imgui

Sometimes it can be useful to have a GUI API that can be called from C++ side independently from the Javascript runtime. This can be used for dynamically loading scripts for example or resetting the JavaScript runtime to get the changes made to the JavaScript files.

Imgui controls integrated with Babylon Native GLFW

Final thoughts

Babylon Native can be an amazing option for projects that are interested in doing cross platform 3D rendering. It brings compatibility with javascript code development for Babylon.js on the browser, allowing native rendering to match the one done on the web.

References

Babylon Native: The Journey So Far | by Babylon.js | Medium

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Babylon.js

Babylon.js

1.4K Followers

Babylon.js: Powerful, Beautiful, Simple, Open — Web-Based 3D At Its Best. https://www.babylonjs.com/