瀏覽代碼

Get the Python sample programs working in emscripten

rdb 10 年之前
父節點
當前提交
b3ad5c82d3

+ 51 - 30
makepanda/makepanda.py

@@ -735,7 +735,6 @@ if (COMPILER=="GCC"):
 
     #         Name         pkg-config   libs, include(dir)s
     if (not RUNTIME):
-        SmartPkgEnable("EIGEN",     "eigen3",    (), ("Eigen/Dense",), target_pkg = 'ALWAYS')
         SmartPkgEnable("ARTOOLKIT", "",          ("AR"), "AR/ar.h")
         SmartPkgEnable("FCOLLADA",  "",          ChooseLib(fcollada_libs, "FCOLLADA"), ("FCollada", "FCollada/FCollada.h"))
         SmartPkgEnable("ASSIMP",    "assimp", ("assimp"), "assimp")
@@ -747,11 +746,8 @@ if (COMPILER=="GCC"):
         SmartPkgEnable("FREETYPE",  "freetype2", ("freetype"), ("freetype2", "freetype2/freetype/freetype.h"))
         SmartPkgEnable("GL",        "gl",        ("GL"), ("GL/gl.h"), framework = "OpenGL")
         SmartPkgEnable("GLES",      "glesv1_cm", ("GLESv1_CM"), ("GLES/gl.h"), framework = "OpenGLES")
-        SmartPkgEnable("GLES2",     "glesv2",    ("GLESv2"), ("GLES2/gl2.h")) #framework = "OpenGLES"?
-        SmartPkgEnable("EGL",       "egl",       ("EGL"), ("EGL/egl.h"))
         SmartPkgEnable("NVIDIACG",  "",          ("Cg"), "Cg/cg.h", framework = "Cg")
         SmartPkgEnable("ODE",       "",          ("ode"), "ode/ode.h", tool = "ode-config")
-        SmartPkgEnable("OPENAL",    "openal",    ("openal"), "AL/al.h", framework = "OpenAL")
         SmartPkgEnable("SQUISH",    "",          ("squish"), "squish.h")
         SmartPkgEnable("TIFF",      "libtiff-4", ("tiff"), "tiff.h")
         SmartPkgEnable("VRPN",      "",          ("vrpn", "quat"), ("vrpn", "quat.h", "vrpn/vrpn_Types.h"))
@@ -760,6 +756,14 @@ if (COMPILER=="GCC"):
         SmartPkgEnable("JPEG",      "",          ("jpeg"), "jpeglib.h")
         SmartPkgEnable("PNG",       "libpng",    ("png"), "png.h", tool = "libpng-config")
 
+        if GetTarget() != 'emscripten':
+            SmartPkgEnable("EIGEN", "eigen3",    (), ("Eigen/Dense",), target_pkg = 'ALWAYS')
+            SmartPkgEnable("OPENAL","openal",    ("openal"), "AL/al.h", framework = "OpenAL")
+            SmartPkgEnable("GLES2", "glesv2",    ("GLESv2"), ("GLES2/gl2.h")) #framework = "OpenGLES"?
+            SmartPkgEnable("EGL",   "egl",       ("EGL"), ("EGL/egl.h"))
+        else:
+            PkgDisable("EIGEN")
+
         if GetTarget() == "darwin" and not PkgSkip("FFMPEG"):
             LibName("FFMPEG", "-Wl,-read_only_relocs,suppress")
             LibName("FFMPEG", "-framework VideoDecodeAcceleration")
@@ -783,6 +787,8 @@ if (COMPILER=="GCC"):
         if not PkgSkip("PYTHON"):
             if GetTarget() == "darwin" and not RTDIST and not PkgHasCustomLocation("PYTHON"):
                 LibName("PYTHON", "-framework Python")
+            elif GetTarget() == "emscripten":
+                SmartPkgEnable("PYTHON", "", "", (SDK["PYTHONVERSION"], SDK["PYTHONVERSION"] + "/Python.h"))
             else:
                 SmartPkgEnable("PYTHON", "", SDK["PYTHONVERSION"], (SDK["PYTHONVERSION"], SDK["PYTHONVERSION"] + "/Python.h"), tool = SDK["PYTHONVERSION"] + "-config")
 
@@ -794,7 +800,7 @@ if (COMPILER=="GCC"):
         SmartPkgEnable("WX", tool = "wx-config")
         SmartPkgEnable("FLTK", "", ("fltk"), ("FL/Fl.H"), tool = "fltk-config")
 
-    if GetTarget() != 'darwin':
+    if GetTarget() not in ('darwin', 'emscripten'):
         # CgGL is covered by the Cg framework, and we don't need X11 components on OSX
         if not PkgSkip("NVIDIACG") and not RUNTIME:
             SmartPkgEnable("CGGL", "", ("CgGL"), "Cg/cgGL.h")
@@ -1217,7 +1223,7 @@ def CompileCxx(obj,src,opts):
                 cmd += ' -mfpu=neon'
 
         elif GetTarget() == 'emscripten':
-            cmd += " -s WARN_ON_UNDEFINED_SYMBOLS=1"
+            cmd += " -s WARN_ON_UNDEFINED_SYMBOLS=1 -s NO_FILESYSTEM=1"
 
         else:
             cmd += " -pthread"
@@ -1228,6 +1234,8 @@ def CompileCxx(obj,src,opts):
                 cmd += " -fexceptions"
             else:
                 cmd += " -fno-exceptions"
+                if GetTarget() == 'emscripten':
+                    cmd += " -s DISABLE_EXCEPTION_CATCHING=1"
 
             if 'RTTI' not in opts:
                 # We always disable RTTI on Android for memory usage reasons.
@@ -1358,6 +1366,9 @@ def CompileIgate(woutd,wsrc,opts):
         else:
             cmd += ' -D__i386__'
 
+    if GetTarget() == "emscripten":
+        cmd += ' -D__EMSCRIPTEN__'
+
     optlevel = GetOptimizeOption(opts)
     if (optlevel==1): cmd += ' -D_DEBUG'
     if (optlevel==2): cmd += ' -D_DEBUG'
@@ -1398,10 +1409,8 @@ def CompileIgate(woutd,wsrc,opts):
 def CompileImod(wobj, wsrc, opts):
     module = GetValueOption(opts, "IMOD:")
     library = GetValueOption(opts, "ILIB:")
-    if (COMPILER=="MSVC"):
-        woutc = wobj[:-4]+".cxx"
-    if (COMPILER=="GCC"):
-        woutc = wobj[:-2]+".cxx"
+    woutc = os.path.splitext(wobj)[0] + ".cxx"
+
     if (PkgSkip("PYTHON")):
         WriteFile(woutc, "")
         CompileCxx(wobj, woutc, opts)
@@ -1642,6 +1651,8 @@ def CompileLink(dll, obj, opts):
 
         elif GetTarget() == 'emscripten':
             cmd += " -s WARN_ON_UNDEFINED_SYMBOLS=1"
+            if GetOrigExt(dll) == ".exe":
+                cmd += " --memory-init-file 0"
 
         else:
             cmd += " -pthread"
@@ -1655,9 +1666,10 @@ def CompileLink(dll, obj, opts):
         for (opt, dir) in FRAMEWORKDIRECTORIES:
             if (opt=="ALWAYS") or (opt in opts):
                 cmd += ' -F' + BracketNameWithQuotes(dir)
-        for (opt, name) in LIBNAMES:
-            if (opt=="ALWAYS") or (opt in opts):
-                cmd += ' ' + BracketNameWithQuotes(name)
+        if GetOrigExt(dll) == ".exe" or GetTarget() != 'emscripten':
+            for (opt, name) in LIBNAMES:
+                if (opt=="ALWAYS") or (opt in opts):
+                    cmd += ' ' + BracketNameWithQuotes(name)
 
         if GetTarget() not in ('freebsd', 'emscripten'):
             cmd += " -ldl"
@@ -1982,7 +1994,7 @@ def CompileAnything(target, inputs, opts, progress = None):
                 if target.lower().endswith(".dylib"):
                     target = target[:-5] + MAJOR_VERSION + ".dylib"
                     SetOrigExt(target, origsuffix)
-            elif tplatform != "windows" and tplatform != "android":
+            elif tplatform not in ("windows", "android", "emscripten"):
                 # On Linux, libraries are named like libpanda.so.1.2
                 target += "." + MAJOR_VERSION
                 SetOrigExt(target, origsuffix)
@@ -2280,6 +2292,8 @@ def WriteConfigSettings():
         dtool_config["HAVE_POSIX_THREADS"] = 'UNDEF'
         dtool_config["IS_LINUX"] = 'UNDEF'
         dtool_config["HAVE_VIDEO4LINUX"] = 'UNDEF'
+        dtool_config["HAVE_NET"] = 'UNDEF'
+        dtool_config["LINK_ALL_STATIC"] = '1'
 
     if (GetOptimize() <= 2 and GetTarget() == "windows"):
         dtool_config["USE_DEBUG_PYTHON"] = '1'
@@ -3329,7 +3343,7 @@ if (not RUNTIME):
 # DIRECTORY: panda/src/nativenet/
 #
 
-if (not RUNTIME):
+if (not RUNTIME and GetTarget() != 'emscripten'):
   OPTS=['DIR:panda/src/nativenet', 'OPENSSL', 'BUILDING:PANDA']
   TargetAdd('p3nativenet_composite1.obj', opts=OPTS, input='p3nativenet_composite1.cxx')
 
@@ -3343,7 +3357,7 @@ if (not RUNTIME):
 # DIRECTORY: panda/src/net/
 #
 
-if (not RUNTIME):
+if (not RUNTIME and GetTarget() != 'emscripten'):
   OPTS=['DIR:panda/src/net', 'BUILDING:PANDA']
   TargetAdd('p3net_composite1.obj', opts=OPTS, input='p3net_composite1.cxx')
   TargetAdd('p3net_composite2.obj', opts=OPTS, input='p3net_composite2.cxx')
@@ -3754,9 +3768,6 @@ if (not RUNTIME):
   TargetAdd('libpanda.dll', input='p3audio_composite1.obj')
   TargetAdd('libpanda.dll', input='p3pgui_composite1.obj')
   TargetAdd('libpanda.dll', input='p3pgui_composite2.obj')
-  TargetAdd('libpanda.dll', input='p3net_composite1.obj')
-  TargetAdd('libpanda.dll', input='p3net_composite2.obj')
-  TargetAdd('libpanda.dll', input='p3nativenet_composite1.obj')
   TargetAdd('libpanda.dll', input='p3pandabase_pandabase.obj')
   TargetAdd('libpanda.dll', input='libpandaexpress.dll')
   TargetAdd('libpanda.dll', input='p3dxml_composite1.obj')
@@ -3764,6 +3775,9 @@ if (not RUNTIME):
   TargetAdd('libpanda.dll', input='libp3dtool.dll')
 
   if GetTarget() != "emscripten":
+    TargetAdd('libpanda.dll', input='p3net_composite1.obj')
+    TargetAdd('libpanda.dll', input='p3net_composite2.obj')
+    TargetAdd('libpanda.dll', input='p3nativenet_composite1.obj')
     TargetAdd('libpanda.dll', input='p3pnmimage_convert_srgb_sse2.obj')
 
   if PkgSkip("FREETYPE")==0:
@@ -3799,12 +3813,14 @@ if (not RUNTIME):
   TargetAdd('core_module.obj', input='libp3tform.in')
   TargetAdd('core_module.obj', input='libp3putil.in')
   TargetAdd('core_module.obj', input='libp3audio.in')
-  TargetAdd('core_module.obj', input='libp3nativenet.in')
-  TargetAdd('core_module.obj', input='libp3net.in')
   TargetAdd('core_module.obj', input='libp3pgui.in')
   TargetAdd('core_module.obj', input='libp3movies.in')
   TargetAdd('core_module.obj', input='libp3dxml.in')
 
+  if GetTarget() != "emscripten":
+    TargetAdd('core_module.obj', input='libp3nativenet.in')
+    TargetAdd('core_module.obj', input='libp3net.in')
+
   if PkgSkip("FREETYPE")==0:
     TargetAdd('core_module.obj', input='libp3pnmtext.in')
 
@@ -3839,10 +3855,12 @@ if (not RUNTIME):
   TargetAdd('core.pyd', input='libp3putil_igate.obj')
   TargetAdd('core.pyd', input='libp3audio_igate.obj')
   TargetAdd('core.pyd', input='libp3pgui_igate.obj')
-  TargetAdd('core.pyd', input='libp3net_igate.obj')
-  TargetAdd('core.pyd', input='libp3nativenet_igate.obj')
   TargetAdd('core.pyd', input='libp3dxml_igate.obj')
 
+  if GetTarget() != "emscripten":
+    TargetAdd('core.pyd', input='libp3net_igate.obj')
+    TargetAdd('core.pyd', input='libp3nativenet_igate.obj')
+
   if PkgSkip("FREETYPE")==0:
     TargetAdd('core.pyd', input="libp3pnmtext_igate.obj")
 
@@ -3857,7 +3875,7 @@ if (not RUNTIME):
   TargetAdd('core.pyd', input='p3display_pythonGraphicsWindowProc.obj')
 
   TargetAdd('core.pyd', input='core_module.obj')
-  TargetAdd('core.pyd', input='libp3tinyxml.ilb')
+  #TargetAdd('core.pyd', input='libp3tinyxml.ilb')
   TargetAdd('core.pyd', input=COMMON_PANDA_LIBS)
   TargetAdd('core.pyd', opts=['PYTHON', 'WINSOCK2'])
 
@@ -4777,7 +4795,7 @@ if (PkgSkip("DIRECT")==0):
 # DIRECTORY: direct/src/distributed/
 #
 
-if (PkgSkip("DIRECT")==0):
+if not PkgSkip("DIRECT") and GetTarget() != 'emscripten':
   OPTS=['DIR:direct/src/distributed', 'DIR:direct/src/dcparser', 'WITHINPANDA', 'BUILDING:DIRECT', 'OPENSSL']
   TargetAdd('p3distributed_config_distributed.obj', opts=OPTS, input='config_distributed.cxx')
   TargetAdd('p3distributed_cConnectionRepository.obj', opts=OPTS, input='cConnectionRepository.cxx')
@@ -4838,9 +4856,10 @@ if (PkgSkip("DIRECT")==0):
     TargetAdd('libp3direct.dll', input='p3showbase_showBase_assist.obj')
   TargetAdd('libp3direct.dll', input='p3deadrec_composite1.obj')
   TargetAdd('libp3direct.dll', input='p3interval_composite1.obj')
-  TargetAdd('libp3direct.dll', input='p3distributed_config_distributed.obj')
-  TargetAdd('libp3direct.dll', input='p3distributed_cConnectionRepository.obj')
-  TargetAdd('libp3direct.dll', input='p3distributed_cDistributedSmoothNodeBase.obj')
+  if GetTarget() != 'emscripten':
+    TargetAdd('libp3direct.dll', input='p3distributed_config_distributed.obj')
+    TargetAdd('libp3direct.dll', input='p3distributed_cConnectionRepository.obj')
+    TargetAdd('libp3direct.dll', input='p3distributed_cDistributedSmoothNodeBase.obj')
   TargetAdd('libp3direct.dll', input=COMMON_PANDA_LIBS)
   TargetAdd('libp3direct.dll', opts=['ADVAPI',  'OPENSSL', 'WINUSER', 'WINGDI'])
 
@@ -4849,7 +4868,8 @@ if (PkgSkip("DIRECT")==0):
   TargetAdd('direct_module.obj', input='libp3showbase.in')
   TargetAdd('direct_module.obj', input='libp3deadrec.in')
   TargetAdd('direct_module.obj', input='libp3interval.in')
-  TargetAdd('direct_module.obj', input='libp3distributed.in')
+  if GetTarget() != 'emscripten':
+    TargetAdd('direct_module.obj', input='libp3distributed.in')
   TargetAdd('direct_module.obj', opts=OPTS)
   TargetAdd('direct_module.obj', opts=['IMOD:panda3d.direct', 'ILIB:direct', 'IMPORT:panda3d.core'])
 
@@ -4857,7 +4877,8 @@ if (PkgSkip("DIRECT")==0):
   TargetAdd('direct.pyd', input='libp3showbase_igate.obj')
   TargetAdd('direct.pyd', input='libp3deadrec_igate.obj')
   TargetAdd('direct.pyd', input='libp3interval_igate.obj')
-  TargetAdd('direct.pyd', input='libp3distributed_igate.obj')
+  if GetTarget() != 'emscripten':
+    TargetAdd('direct.pyd', input='libp3distributed_igate.obj')
 
   TargetAdd('direct.pyd', input='direct_module.obj')
   TargetAdd('direct.pyd', input='libp3direct.dll')

+ 2 - 5
makepanda/makepandacore.py

@@ -1484,9 +1484,6 @@ def SmartPkgEnable(pkg, pkgconfig = None, libs = None, incs = None, defs = None,
         for d in olddefs:
             defs[d] = ""
 
-    if GetTarget() == "emscripten":
-        libs = ()
-
     custom_loc = PkgHasCustomLocation(pkg)
 
     if pkg.lower() == "swscale" and os.path.isfile(GetThirdpartyDir() + "ffmpeg/include/libswscale/swscale.h"):
@@ -1566,7 +1563,7 @@ def SmartPkgEnable(pkg, pkgconfig = None, libs = None, incs = None, defs = None,
             if (have_all_pkgs):
                 return
 
-    if pkgconfig is not None and not incs:
+    if pkgconfig is not None and not libs:
         # pkg-config is all we can do, abort if it wasn't found.
         if pkg in PkgListGet():
             print("%sWARNING:%s Could not locate pkg-config package %s, excluding from build" % (GetColor("red"), GetColor(), pkgconfig))
@@ -2771,7 +2768,7 @@ def CalcLocation(fn, ipath):
     elif (target == 'emscripten'):
         if (fn.endswith(".obj")):   return OUTPUTDIR+"/tmp/"+fn[:-4]+".bc"
         if (fn.endswith(".dll")):   return OUTPUTDIR+"/lib/"+fn[:-4]+".bc"
-        if (fn.endswith(".pyd")):   return OUTPUTDIR+"/panda3d/"+fn[:-4]+".js"
+        if (fn.endswith(".pyd")):   return OUTPUTDIR+"/panda3d/"+fn[:-4]+".bc"
         if (fn.endswith(".mll")):   return OUTPUTDIR+"/plugins/"+fn
         if (fn.endswith(".plugin")):return OUTPUTDIR+"/plugins/"+fn[:-7]+dllext+".js"
         if (fn.endswith(".exe")):   return OUTPUTDIR+"/bin/"+fn[:-4]+".js"

+ 13 - 0
panda/src/event/asyncTaskManager.cxx

@@ -733,3 +733,16 @@ make_global_ptr() {
   _global_ptr = new AsyncTaskManager("TaskManager");
   _global_ptr->ref();
 }
+
+#ifdef __EMSCRIPTEN__
+
+extern "C" void task_manager_poll();
+
+void task_manager_poll() {
+  AsyncTaskManager *mgr = AsyncTaskManager::get_global_ptr();
+  nassertv_always(mgr != NULL);
+
+  mgr->poll();
+}
+
+#endif

+ 1 - 1
panda/src/framework/pandaFramework.cxx

@@ -35,7 +35,7 @@
 #ifdef __EMSCRIPTEN__
 #include <emscripten.h>
 
-void em_do_frame(void *arg) {
+static void em_do_frame(void *arg) {
   PandaFramework *fwx = (PandaFramework *)arg;
   nassertv_always(fwx != NULL);
 

+ 2 - 0
panda/src/net/connectionManager.cxx

@@ -591,6 +591,8 @@ scan_interfaces() {
 #elif defined(ANDROID)
   // TODO: implementation using netlink_socket?
 
+#elif defined(__EMSCRIPTEN__)
+
 #else  // WIN32_VC
   struct ifaddrs *ifa;
   if (getifaddrs(&ifa) != 0) {

+ 19 - 2
panda/src/webgldisplay/webGLGraphicsWindow.cxx

@@ -381,6 +381,22 @@ on_keyboard_event(int type, const EmscriptenKeyboardEvent *event, void *user_dat
       handle = KeyboardButton::caps_lock();
       break;
 
+    case 37:
+      handle = KeyboardButton::left();
+      break;
+
+    case 38:
+      handle = KeyboardButton::up();
+      break;
+
+    case 39:
+      handle = KeyboardButton::right();
+      break;
+
+    case 40:
+      handle = KeyboardButton::down();
+      break;
+
     case 186:
       handle = KeyboardButton::ascii_key(';');
       break;
@@ -419,14 +435,15 @@ on_keyboard_event(int type, const EmscriptenKeyboardEvent *event, void *user_dat
 
     if (handle != ButtonHandle::none()) {
       if (type == EMSCRIPTEN_EVENT_KEYUP) {
-        webgldisplay_cat.info() << "button up " << handle << "\n";
+        //webgldisplay_cat.info() << "button up " << handle << "\n";
         device->button_up(handle);
       } else if (event->repeat) {
         device->button_resume_down(handle);
       } else {
-        webgldisplay_cat.info() << "button down " << handle << "\n";
+        //webgldisplay_cat.info() << "button down " << handle << "\n";
         device->button_down(handle);
       }
+      return true;
     } else {
       webgldisplay_cat.info() << "button event code " << event->which << "\n";
     }