Panda3D WebGL Port!

That is not a good idea as only cpython 3.11 began to support emscripten, and support is dropped in 3.13 this month.

i’d say 3.12 is the wasm stable version especially when compiled with GitHub - pygame-web/python-wasm-sdk: Tooling for building CPython+support libs on WebAssembly where most cpython requirements have been pre adjusted, and some critical fixes for emsdk (reviewed but still waiting for approval or merge)

i maintain Panda3D wheels for cpython-wasm ( a bit like pyodide but posix ) through pygame-web cdn. eg https://pygame-web.github.io/showroom/pypad.html#src/test_panda3d_cube.py

3.11 ( numpy also avail )

3.12 wheel for cpython-wasm archives/repo/pkg/panda3d-1.11.0-cp312-cp312-wasm32_bi_emscripten.whl at main · pygame-web/archives · GitHub ( no numpy )

for people who don’t want to rebuild the whole stuff ( it is indeed quite complicated ) and just want test against existing code and rewrite/test shaders

You can just package your game with pygbag tool, a bit of doc here pygame-web.github.io | Run python and pygame code in your html

srgb does not work for now so don’t be surprised, the whole is still very experimental and volatile so current help is on discord ( Help channel subthread WebBuilding )

@FRPS_Archy most of your linking problems come from 32/64 bits interface mistmatch. either remove bigint support on both cpython and panda ( making it MVP wasm 1.0 compliant) or add bigint to both ( that allows to reuse most 3.11 pyodide wheels )

another way when using an mvp cpython is to normalize python modules ( .so ) with wasm-emscripten-finalize -mvp before linking or dynamic loading

2 Likes

I think they changed the signature of these functions since I compiled Python. Recompiling Python from source should do the trick. As @pmpp says, you should probably update to Python 3.12.

If I find time, I’ll upload updated binaries with Python 3.12 sometime.

Hello community,
I wanted to use this guide to help me deploy my game to the web. The webgl branch seems like doesn’t exist anymore. Has the code been moved or what are other ways to deploy P3D game to the web ?

Now it has become part of the master branch.

This link is not available in 2024 https://github.com/panda3d/panda3d/tree/webgl-port.
How can we build panda3d application on web browser in 2024 ? I am using ubuntu 24.

1 Like

[ 33%] Building Interrogate database built/pandac/input/libp3parametrics.in
[ 34%] Building C++ object built/tmp/cpython-312-x86_64-linux-gnu/libp3parametrics_igate.o
[ 34%] Building C++ object built/tmp/p3pgui_composite1.o
[ 34%] Building C++ object built/tmp/p3pgui_composite2.o
[ 34%] Building Interrogate database built/pandac/input/libp3pgui.in
[ 34%] Building C++ object built/tmp/cpython-312-x86_64-linux-gnu/libp3pgui_igate.o
[ 35%] Building C++ object built/tmp/p3pnmimagetypes_composite1.o
[ 35%] Building C++ object built/tmp/p3pnmimagetypes_composite2.o
In file included from panda/src/pnmimagetypes/p3pnmimagetypes_composite2.cxx:8:
In function ‘void write_float(std::ostream*, float)’,
inlined from ‘virtual bool PNMFileTypeSoftImage::Writer::write_header()’ at panda/src/pnmimagetypes/pnmFileTypeSoftImage.cxx:668:14:
panda/src/pnmimagetypes/pnmFileTypeSoftImage.cxx:87:18: warning: array subscript ‘long int[0]’ is partly outside array bounds of ‘float [1]’ [-Warray-bounds=]
87 | pm_writebiglong(file, *(long )&x);
| ~^~~~~
panda/src/pnmimagetypes/pnmFileTypeSoftImage.cxx: In member function ‘virtual bool PNMFileTypeSoftImage::Writer::write_header()’:
panda/src/pnmimagetypes/pnmFileTypeSoftImage.cxx:664:6: note: object ‘x’ of size 4
664 | bool PNMFileTypeSoftImage::Writer::
| ^~~~~~~~~~~~~~~~~~~~
In function ‘void write_float(std::ostream
, float)’,
inlined from ‘virtual bool PNMFileTypeSoftImage::Writer::write_header()’ at panda/src/pnmimagetypes/pnmFileTypeSoftImage.cxx:676:14:
panda/src/pnmimagetypes/pnmFileTypeSoftImage.cxx:87:18: warning: array subscript ‘long int[0]’ is partly outside array bounds of ‘float [1]’ [-Warray-bounds=]
87 | pm_writebiglong(file, *(long *)&x);
| ~^~~~~
panda/src/pnmimagetypes/pnmFileTypeSoftImage.cxx: In member function ‘virtual bool PNMFileTypeSoftImage::Writer::write_header()’:
panda/src/pnmimagetypes/pnmFileTypeSoftImage.cxx:664:6: note: object ‘x’ of size 4
664 | bool PNMFileTypeSoftImage::Writer::
| ^~~~~~~~~~~~~~~~~~~~
[ 35%] Building C++ object built/tmp/p3recorder_composite1.o

The building process is taking a lot of time > 1hr is this deu to dependency error?

No, add --threads 4 to make it go 4x as fast.

1 Like

Thanks a lot for your help Sir, the build was successful.

Now I am facing difficulty in running the script in browser.

(panda3d_env) animesh@animesh-Aspire-A515-45:~/web-panda3d/samples/asteroids/build/manylinux2014_x86_64$ ls
array.cpython-312-x86_64-linux-gnu.so
asteroids
binascii.cpython-312-x86_64-linux-gnu.so
_bisect.cpython-312-x86_64-linux-gnu.so
_blake2.cpython-312-x86_64-linux-gnu.so
_bz2.so
_codecs_cn.so
_codecs_hk.so
_codecs_iso2022.so
_codecs_jp.so
_codecs_kr.so
_codecs_tw.so
_contextvars.so
_csv.cpython-312-x86_64-linux-gnu.so
_datetime.cpython-312-x86_64-linux-gnu.so
_decimal.so
fcntl.cpython-312-x86_64-linux-gnu.so
grp.cpython-312-x86_64-linux-gnu.so
_hashlib.so
_heapq.cpython-312-x86_64-linux-gnu.so
libbz2.so.1
libCgGL.so
libCg.so
liblzma.so.5
libp3direct.so.1.10
libp3dtoolconfig.so.1.10
libp3dtool.so.1.10
libp3interrogatedb.so.1.10
libp3openal_audio.so
libpandaexpress.so.1.10
libpandagl.so
libpanda.so.1.10
_lzma.so
math.cpython-312-x86_64-linux-gnu.so
_md5.cpython-312-x86_64-linux-gnu.so
models
_multibytecodec.so
_opcode.cpython-312-x86_64-linux-gnu.so
panda3d.core.so
panda3d.direct.so
_pickle.cpython-312-x86_64-linux-gnu.so
_posixsubprocess.cpython-312-x86_64-linux-gnu.so
_random.cpython-312-x86_64-linux-gnu.so
select.cpython-312-x86_64-linux-gnu.so
_sha1.cpython-312-x86_64-linux-gnu.so
_sha2.cpython-312-x86_64-linux-gnu.so
_sha3.cpython-312-x86_64-linux-gnu.so
_socket.cpython-312-x86_64-linux-gnu.so
_statistics.cpython-312-x86_64-linux-gnu.so
_struct.cpython-312-x86_64-linux-gnu.so
textures
unicodedata.cpython-312-x86_64-linux-gnu.so
zlib.cpython-312-x86_64-linux-gnu.so
(panda3d_env) animesh@animesh-Aspire-A515-45:~/web-panda3d/samples/asteroids/build/manylinux2014_x86_64$

I ran

python setup.py build_apps

for asteroid but could not find .wasm .js and .HTML files.

There’s no build_apps support for WebGL. There’s no easy way to build for WebGL right now. There are some instructions here:

https://rdb.name/panda3d-webgl.md

1 Like

I have used the https://rdb.name/panda3d-webgl.md.html to compile my own Panda3D WebGL port. At present, I use emsdk 3.1.54 (which is the last version that supports -init-memory-file flag), panda3d latest checkout from github, python 3.8.10 by pyenv. I download the dependency. When compiling editor, there are the signature mismatch warning.

There are some missing modules: ['_overlapped', '_scproxy', '_sysconfigdata__linux_amd64-linux-gnu', 'dummy.Process', 'multiprocessing.AuthenticationError', 'multiprocessing.BufferTooShort', 'multiprocessing.TimeoutError', 'multiprocessing.get_context', 'multiprocessing.get_start_method', 'multiprocessing.set_start_method', 'panda3d.core', 'panda3d.direct', 'panda3d.physics', 'win32evtlog', 'win32evtlogutil']
emcc -O3 -g -fno-exceptions -fno-rtti -c -o editor.o editor.c -I/work/panda3d-github/thirdparty/emscripten-libs/python/include/python3.8
emcc --bind -O3 -g  -sSTACK_SIZE=209715200 -s TOTAL_MEMORY=419430400 -s ASSERTIONS=2 -s MAX_WEBGL_VERSION=2 -s NO_EXIT_RUNTIME=1 -fno-exceptions -fno-rtti -o editor.js editor.o   /work/panda3d-github/thirdparty/emscripten-libs/python/lib/libpython3.8.a  /work/panda3d-github/built/lib/libpy.panda3d.core.a /work/panda3d-github/built/lib/libpy.panda3d.direct.a /work/panda3d-github/built/lib/libp3interrogatedb.a /work/panda3d-github/built/lib/libpanda.a /work/panda3d-github/built/lib/libpandaexpress.a /work/panda3d-github/built/lib/libp3dtool.a /work/panda3d-github/built/lib/libp3dtoolconfig.a /work/panda3d-github/built/lib/libp3webgldisplay.a /work/panda3d-github/built/lib/libp3direct.a /work/panda3d-github/built/lib/libp3openal_audio.a -I/work/panda3d-github/built/include -s USE_ZLIB=1 -s USE_VORBIS=1 -s USE_LIBPNG=1 -s USE_FREETYPE=1 -s USE_HARFBUZZ=1 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s DISABLE_EXCEPTION_THROWING=0  -s 'EXPORTED_RUNTIME_METHODS=["cwrap"]' --preload-file models/panda-model.bam --preload-file models/panda-walk4.bam --preload-file music/musicbox.ogg --preload-file models/MusicBox.bam --preload-file models/box.jpg --preload-file models/panda.jpg --preload-file models/plane.bam --preload-file textures/asteroid1.png --preload-file textures/asteroid2.png --preload-file textures/asteroid2.png --preload-file textures/asteroid3.png --preload-file textures/bullet.png --preload-file textures/ship.png 
wasm-ld: warning: function signature mismatch: time
>>> defined as (i32) -> i32 in /work/panda3d-github/thirdparty/emscripten-libs/python/lib/libpython3.8.a(timemodule.o)
>>> defined as (i32) -> i64 in /work/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libc-debug.a(emscripten_time.o)

wasm-ld: warning: function signature mismatch: mktime
>>> defined as (i32) -> i32 in /work/panda3d-github/thirdparty/emscripten-libs/python/lib/libpython3.8.a(timemodule.o)
>>> defined as (i32) -> i64 in /work/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libc-debug.a(mktime.o)

emcc: warning: running limited binaryen optimizations because DWARF info requested (or indirectly required) [-Wlimited-postlink-optimizations]

These warning leads to the runtime error in the brower when using python -m http.server to start the editor.html

editor.wasm:0x231c6 Uncaught RuntimeError: unreachable
    at editor.wasm.signature_mismatch:time (editor.wasm:0x231c6)
    at editor.wasm.PyInit_time (editor.wasm:0x18f61b)
    at editor.wasm._imp_create_builtin (editor.wasm:0x1256c9)
    at editor.wasm.cfunction_vectorcall_O (editor.wasm:0x786bd)
    at editor.wasm.PyVectorcall_Call (editor.wasm:0x3f617)
    at editor.wasm.PyCFunction_Call (editor.wasm:0x401fc)
    at editor.wasm._PyEval_EvalFrameDefault (editor.wasm:0xe6c8b)
    at editor.wasm._PyEval_EvalCodeWithName (editor.wasm:0xe21ca)
    at editor.wasm._PyFunction_Vectorcall (editor.wasm:0x3fed9)
    at editor.wasm.call_function (editor.wasm:0xe936d)

Does anyone know how to sovle this problem?
Thanks.

I find the wasm32-unknown-emscripten is only supported in Python 3.11 and 3.12. I use the ./Tools/wasm/wasm_build.py build and ./Tools/wasm/wasm_build.py emscripten-browser to build the Python3.11.10 and the correpsonding wasm version. It succeded.

As stated in https://rdb.name/panda3d-webgl.md.html , the thirdparty/emscripten-libs/python has include and lib directories. I made soft links for these, as include -> /usr/local/include/python3.11, and libpython3.11.a -> /python-wasm/cpython/builddir/emscripten-browser/libpython3.11.a.

When I compile panda3d again, using the command python3.11 makepanda/makepanda.py --nothing --use-python --use-vorbis --use-bullet --use-zlib --use-freetype --use-harfbuzz --use-openal --no-png --use-direct --use-gles2 --optimize 4 --static --target emscripten --verbose, the link error occured:

thirdparty/emscripten-libs/python/include/pylifecycle.h:37:1: note: 'Py_SetProgramName' has been explicitly marked deprecated here
Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetProgramName(const wchar_t *);
^
thirdparty/emscripten-libs/python/include/pyport.h:340:54: note: expanded from macro 'Py_DEPRECATED'
#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                     ^
pandatool/src/deploy-stub/deploy-stub.c:487:5: warning: 'PySys_SetArgv' is deprecated [-Wdeprecated-declarations]
    PySys_SetArgv(argc, argv_copy);
    ^
thirdparty/emscripten-libs/python/include/sysmodule.h:13:1: note: 'PySys_SetArgv' has been explicitly marked deprecated here
Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **);
^
thirdparty/emscripten-libs/python/include/pyport.h:340:54: note: expanded from macro 'Py_DEPRECATED'
#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
                                                     ^
4 warnings generated.
[ 99%] Linking executable built/bin/deploy-stub.js
em++ -o built/bin/deploy-stub.js -Lbuilt/lib -Lbuilt/tmp built/tmp/cpython-311/deploy-stub.o -s WARN_ON_UNDEFINED_SYMBOLS=1 --memory-init-file 0 -s EXIT_RUNTIME=1 thirdparty/emscripten-libs/python/lib/libpython3.11.a -s USE_ZLIB=1 -s USE_BZIP2=1 -s USE_SQLITE3=1 -O3
ports:INFO: retrieving port: bzip2 from https://github.com/emscripten-ports/bzip2/archive/1.0.6.zip
ports:INFO: unpacking port: bzip2
cache:INFO: generating port: sysroot/lib/wasm32-emscripten/libbz2.a... (this will be cached in "/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libbz2.a" for subsequent builds)
system_libs:INFO: compiled 7 inputs
cache:INFO:  - ok
ports:INFO: retrieving port: sqlite3 from https://www.sqlite.org/2022/sqlite-amalgamation-3390000.zip
ports:INFO: unpacking port: sqlite3
cache:INFO: generating port: sysroot/lib/wasm32-emscripten/libsqlite3.a... (this will be cached in "/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libsqlite3.a" for subsequent builds)
root:INFO: building port: libsqlite3
system_libs:INFO: compiled 1 inputs
cache:INFO:  - ok
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_mallocfunc
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_reallocfunc
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_callocfunc
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_free
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_traphandler
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_round_string
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_round_string
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_round_string
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_round_string
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_round_string
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_round_string
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_round_string
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_round_string
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_free
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_free
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_free
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_free
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_free
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_free
wasm-ld: error: thirdparty/emscripten-libs/python/lib/libpython3.11.a(_decimal.o): undefined symbol: mpd_free
wasm-ld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
em++: error: '/emsdk/upstream/bin/wasm-ld -o built/bin/deploy-stub.wasm -Lbuilt/lib -Lbuilt/tmp built/tmp/cpython-311/deploy-stub.o thirdparty/emscripten-libs/python/lib/libpython3.11.a -L/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten /emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libsqlite3.a /emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libz.a /emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libbz2.a -lGL -lal -lhtml5 -lstubs -lc -ldlmalloc -lcompiler_rt -lc++-noexcept -lc++abi-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --import-undefined --strip-debug --export-if-defined=main --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=__main_argc_argv --export-if-defined=fflush --export=stackSave --export=stackRestore --export=stackAlloc --export=__wasm_call_ctors --export=__errno_location --export=__get_temp_ret --export=__set_temp_ret --export=__funcs_on_exit --export=malloc --export=emscripten_builtin_memalign --export=ntohs --export=htons --export=__dl_seterr --export=htonl --export-table -z stack-size=5242880 --initial-memory=16777216 --no-entry --max-memory=16777216 --global-base=1024' failed (returned 1)
Process exited with exit status 0 and signal code 1
Storing dependency cache.
Elapsed Time: 10 min 50 sec
The following command returned a non-zero value: em++ -o built/bin/deploy-stub.js -Lbuilt/lib -Lbuilt/tmp built/tmp/cpython-311/deploy-stub.o -s WARN_ON_UNDEFINED_SYMBOLS=1 --memory-init-file 0 -s EXIT_RUNTIME=1 thirdparty/emscripten-libs/python/lib/libpython3.11.a -s USE_ZLIB=1 -s USE_BZIP2=1 -s USE_SQLITE3=1 -O3
Build terminated.

Any suggestions?

you will need to link the static version of expat / Hacl_Hash_SHA2 and mpdec modules they should be found in the Modules folder of cpython build.

Another way is use ubuntu 22.04 + an automated build of emscripten + cpython-wasm you can find here , which can compile Panda3D out of the box (well almost … proof : https://pygame-web.github.io/showroom/pythongit.html?cpython3.12#src/test_panda3d_cube.py )

I’ve just updated the instructions and the zip file with the pre-built Python for the latest stable version of emscripten and Python 3.12.7.

The online playground has also been rebuilt.

1 Like

I made some changes to improve canvas focus handling. The window now gets focused by default, and you can now call win.request_properties(foreground=True) to force the canvas to get focus. This can help prevent issues with keyboard input not working when the canvas loses focus. You can check this on a click event for example.

You still need to make sure you have something like tabindex=-1 on the <canvas> element to make it focusable to begin with.

New update: canvas size is now synced with the CSS size of the element.

Also, added support for playing videos. This does not work via MovieTexture but via a new HTMLVideoTexture which creates an invisible <video> element to have the browser decode the video and then uses the special WebGL support for displaying this directly into a texture. This means it’s not necessary to compile in ffmpeg.

To use it, just use loader.loadTexture with the name of the video file. It is recommended not to preload/package the video file, but rather load it directly from the server, since that allows the browser to stream it.

2 Likes