Building bgfx Emscripten application

In this note I will describe a way to build bgfx applications for the web (WebAssembly) via Emscripten.

The installation platform is Linux x86-64, such as Arch Linux.

First, install Emscripten version 3.1.51, otherwise you won’t succeed, all because of the change in the type of dynamic libraries in the latest version of Emscripten. You can read more here:
https://github.com/bkaradzic/bgfx/discussions/3266

It’s done like this:


git clone https://github.com/emscripten-core/emsdk.git



cd emsdk



./emsdk install 3.1.51



./emsdk activate 3.1.51



source ./emsdk_env.sh



Let’s assemble bgfx for WebAssembly – Emscripten:


mkdir bgfx-build-test



cd bgfx-build-test



git clone https://github.com/bkaradzic/bx.git



git clone https://github.com/bkaradzic/bimg.git



git clone https://github.com/bkaradzic/bgfx.git



cd bgfx



emmake make wasm-debug



As a result, in the .build folder you will have bitcode files with the .bc extension, which you will need to link with your bgfx application.
There should be bgfx.bc, bx.bc, bimg.bc; different builds have different names for these files, depending on the build type (release/debug)

Add a link to .bc files to the CMakeLists.txt file, for example, absolute paths to files from the bgfx-experiments project:


target_link_libraries(${PROJECT_NAME} SDL2 GL /home/demensdeum_stream/Sources/bgfx-build/bgfx/.build/wasm/bin/bgfxDebug.bc /home/demensdeum_stream/Sources/bgfx-build/bgfx/.build/wasm/bin/bxDebug.bc /home/demensdeum_stream/Sources/bgfx-build/bgfx/.build/wasm/bin/bimgDebug.bc)



Now change the native window handle in platform data on bgfx initialization:


bgfx::PlatformData platformData{};



platformData.context = NULL;



platformData.backBuffer = NULL;



platformData.backBufferDS = NULL;



platformData.nwh = (void*)"#canvas";



You also need to change the render type to OpenGL:


bgfx::Init init;



init.type = bgfx::RendererType::OpenGL;







init.resolution.width = screenWidth;



init.resolution.height = screenHeight;



init.resolution.reset = BGFX_RESET_VSYNC;



init.platformData = platformData;







if (!bgfx::init(init))



{



    throw std::runtime_error("Failed to initialize bgfx");



}



Recompile GLSL shaders for 120:


shaderc -f "VertexShader.vs" -o "VertexShader.glsl" --type "v" -p "120"



shaderc -f "FragmentShader.fs" -o "FragmentShader.glsl" --type "f" -p "120"



Of course, .glsl files need to be added to CMakeLists.txt as –preload-file:


set(CMAKE_CXX_FLAGS ... <Остальная часть>



--preload-file VertexShader.glsl \



--preload-file FragmentShader.glsl \



All that’s left is to replace the main render loop in your app with while and call the function via emscripten_set_main_loop.

You can read about it here:
https ://demensdeum.com/blog/ru/2017/03/29/porting-sdl-c-game-to-html5-emscripten/

Then build your Emscripten project as usual, everything should work.
Interestingly – it seems that the Emscripten 3.1.51 build lacks OpenAL (or maybe it’s just me).

Source code of the project that builds correctly with bgfx and Emscripten:
https://github.com/demensdeum/ bgfx-experiments/tree/main/2-emscripten-build

Sources

https://github.com/bkaradzic/bgfx/discussions/3266
https://bkaradzic.github.io/bgfx/build.html
https://emscripten.org/docs/getting_started/downloads.html
https ://demensdeum.com/blog/ru/2017/03/29/porting-sdl-c-game-to-html5-emscripten/
https://llvm.org/docs/BitCodeFormat.html

Leave a Comment

Your email address will not be published. Required fields are marked *