Bläddra i källkod

Merge branch 'master' into deploy-ng

rdb 9 år sedan
förälder
incheckning
70386795f4
34 ändrade filer med 621 tillägg och 382 borttagningar
  1. 36 1
      direct/src/showbase/PythonUtil.py
  2. 1 0
      doc/ReleaseNotes
  3. 6 3
      dtool/src/cppparser/cppFunctionType.cxx
  4. 1 1
      dtool/src/cppparser/cppFunctionType.h
  5. 32 1
      dtool/src/cppparser/cppPreprocessor.cxx
  6. 3 0
      dtool/src/cppparser/cppPreprocessor.h
  7. 1 0
      dtool/src/cppparser/cppScope.cxx
  8. 18 37
      dtool/src/cppparser/cppStructType.cxx
  9. 1 0
      dtool/src/cppparser/cppType.cxx
  10. 25 3
      makepanda/installer.nsi
  11. 125 70
      makepanda/makepanda.py
  12. 51 6
      makepanda/makepandacore.py
  13. 10 1
      panda/src/bullet/bulletBodyNode.cxx
  14. 1 1
      panda/src/bullet/bulletGhostNode.cxx
  15. 0 1
      panda/src/bullet/bulletRigidBodyNode.I
  16. 8 12
      panda/src/bullet/bulletRigidBodyNode.cxx
  17. 1 1
      panda/src/bullet/bulletRigidBodyNode.h
  18. 3 1
      panda/src/display/frameBufferProperties.cxx
  19. 92 33
      panda/src/display/graphicsStateGuardian.cxx
  20. 18 2
      panda/src/dxgsg9/wdxGraphicsPipe9.cxx
  21. 1 0
      panda/src/egg2pg/save_egg_file.cxx
  22. 0 2
      panda/src/ffmpeg/ffmpegAudioCursor.cxx
  23. 0 5
      panda/src/ffmpeg/ffmpegAudioCursor.h
  24. 39 16
      panda/src/glstuff/glGraphicsStateGuardian_src.cxx
  25. 2 0
      panda/src/glstuff/glGraphicsStateGuardian_src.h
  26. 2 2
      panda/src/glstuff/glShaderContext_src.cxx
  27. 1 1
      panda/src/gobj/shader.cxx
  28. 19 0
      panda/src/gobj/texture.cxx
  29. 16 0
      panda/src/vision/openCVTexture.cxx
  30. 1 15
      panda/src/vision/openCVTexture.h
  31. 13 65
      panda/src/windisplay/winGraphicsPipe.cxx
  32. 0 11
      panda/src/windisplay/winGraphicsPipe.h
  33. 76 86
      panda/src/windisplay/winGraphicsWindow.cxx
  34. 18 5
      panda/src/windisplay/winGraphicsWindow.h

+ 36 - 1
direct/src/showbase/PythonUtil.py

@@ -38,7 +38,6 @@ import os
 import sys
 import random
 import time
-import importlib
 
 __report_indent = 3
 
@@ -61,6 +60,42 @@ def Functor(function, *args, **kArgs):
     return functor
 """
 
+try:
+    import importlib
+except ImportError:
+    # Backward compatibility for Python 2.6.
+    def _resolve_name(name, package, level):
+        if not hasattr(package, 'rindex'):
+            raise ValueError("'package' not set to a string")
+        dot = len(package)
+        for x in xrange(level, 1, -1):
+            try:
+                dot = package.rindex('.', 0, dot)
+            except ValueError:
+                raise ValueError("attempted relative import beyond top-level "
+                                  "package")
+        return "%s.%s" % (package[:dot], name)
+
+    def import_module(name, package=None):
+        if name.startswith('.'):
+            if not package:
+                raise TypeError("relative imports require the 'package' argument")
+            level = 0
+            for character in name:
+                if character != '.':
+                    break
+                level += 1
+            name = _resolve_name(name[level:], package, level)
+        __import__(name)
+        return sys.modules[name]
+
+    imp = import_module('imp')
+    importlib = imp.new_module("importlib")
+    importlib._resolve_name = _resolve_name
+    importlib.import_module = import_module
+    sys.modules['importlib'] = importlib
+
+
 class Functor:
     def __init__(self, function, *args, **kargs):
         assert callable(function), "function should be a callable obj"

+ 1 - 0
doc/ReleaseNotes

@@ -47,6 +47,7 @@ This issue fixes several bugs that were still found in 1.9.2.
 * Fix compilation errors with Bullet 2.84
 * Fix exception when trying to pickle NodePathCollection objects
 * Fix error when trying to raise vectors to a power
+* GLSL: fix error when legacy matrix generator inputs are mat3
 
 ------------------------  RELEASE 1.9.2  ------------------------
 

+ 6 - 3
dtool/src/cppparser/cppFunctionType.cxx

@@ -326,14 +326,17 @@ as_function_type() {
  * This is similar to is_equal(), except it is more forgiving: it considers
  * the functions to be equivalent only if the return type and the types of all
  * parameters match.
+ *
+ * Note that this isn't symmetric to account for covariant return types.
  */
 bool CPPFunctionType::
-is_equivalent_function(const CPPFunctionType &other) const {
-  if (!_return_type->is_equivalent(*other._return_type)) {
+match_virtual_override(const CPPFunctionType &other) const {
+  if (!_return_type->is_equivalent(*other._return_type) &&
+      !_return_type->is_convertible_to(other._return_type)) {
     return false;
   }
 
-  if (_flags != other._flags) {
+  if (((_flags ^ other._flags) & ~(F_override | F_final)) != 0) {
     return false;
   }
 

+ 1 - 1
dtool/src/cppparser/cppFunctionType.h

@@ -84,7 +84,7 @@ public:
 
   virtual CPPFunctionType *as_function_type();
 
-  bool is_equivalent_function(const CPPFunctionType &other) const;
+  bool match_virtual_override(const CPPFunctionType &other) const;
 
   CPPIdentifier *_class_owner;
 

+ 32 - 1
dtool/src/cppparser/cppPreprocessor.cxx

@@ -1461,7 +1461,6 @@ handle_define_directive(const string &args, const YYLTYPE &loc) {
       CPPManifest *other = result.first->second;
       warning("redefinition of macro '" + manifest->_name + "'", loc);
       warning("previous definition is here", other->_loc);
-      delete other;
       result.first->second = manifest;
     }
   }
@@ -1679,6 +1678,38 @@ handle_pragma_directive(const string &args, const YYLTYPE &loc) {
     assert(it != _parsed_files.end());
     it->_pragma_once = true;
   }
+
+  char macro[64];
+  if (sscanf(args.c_str(), "push_macro ( \"%63[^\"]\" )", macro) == 1) {
+    // We just mark it as pushed for now, so that the next time someone tries
+    // to override it, we save the old value.
+    Manifests::iterator mi = _manifests.find(macro);
+    if (mi != _manifests.end()) {
+      _manifest_stack[macro].push_back(mi->second);
+    } else {
+      _manifest_stack[macro].push_back(NULL);
+    }
+
+  } else if (sscanf(args.c_str(), "pop_macro ( \"%63[^\"]\" )", macro) == 1) {
+    ManifestStack &stack = _manifest_stack[macro];
+    if (stack.size() > 0) {
+      CPPManifest *manifest = stack.back();
+      stack.pop_back();
+      Manifests::iterator mi = _manifests.find(macro);
+      if (manifest == NULL) {
+        // It was undefined when it was pushed, so make it undefined again.
+        if (mi != _manifests.end()) {
+          _manifests.erase(mi);
+        }
+      } else if (mi != _manifests.end()) {
+        mi->second = manifest;
+      } else {
+        _manifests.insert(Manifests::value_type(macro, manifest));
+      }
+    } else {
+      warning("pop_macro without matching push_macro", loc);
+    }
+  }
 }
 
 /**

+ 3 - 0
dtool/src/cppparser/cppPreprocessor.h

@@ -72,6 +72,9 @@ public:
   typedef map<string, CPPManifest *> Manifests;
   Manifests _manifests;
 
+  typedef pvector<CPPManifest *> ManifestStack;
+  map<string, ManifestStack> _manifest_stack;
+
   pvector<CPPFile::Source> _quote_include_kind;
   DSearchPath _quote_include_path;
   DSearchPath _angle_include_path;

+ 1 - 0
dtool/src/cppparser/cppScope.cxx

@@ -28,6 +28,7 @@
 #include "cppTemplateScope.h"
 #include "cppClassTemplateParameter.h"
 #include "cppFunctionType.h"
+#include "cppConstType.h"
 #include "cppUsing.h"
 #include "cppBisonDefs.h"
 #include "indent.h"

+ 18 - 37
dtool/src/cppparser/cppStructType.cxx

@@ -13,6 +13,7 @@
 
 #include "cppStructType.h"
 #include "cppTypedefType.h"
+#include "cppReferenceType.h"
 #include "cppScope.h"
 #include "cppTypeProxy.h"
 #include "cppTemplateScope.h"
@@ -377,6 +378,10 @@ is_constructible(const CPPType *given_type) const {
     }
   }
 
+  if (is_abstract()) {
+    return false;
+  }
+
   // Check for a different constructor.
   CPPFunctionGroup *fgroup = get_constructor();
   if (fgroup != (CPPFunctionGroup *)NULL) {
@@ -443,6 +448,10 @@ is_destructible() const {
  */
 bool CPPStructType::
 is_default_constructible(CPPVisibility min_vis) const {
+  if (is_abstract()) {
+    return false;
+  }
+
   CPPInstance *constructor = get_default_constructor();
   if (constructor != (CPPInstance *)NULL) {
     // It has a default constructor.
@@ -497,24 +506,6 @@ is_default_constructible(CPPVisibility min_vis) const {
     }
   }
 
-  // Check that we don't have pure virtual methods.
-  CPPScope::Functions::const_iterator fi;
-  for (fi = _scope->_functions.begin();
-       fi != _scope->_functions.end();
-       ++fi) {
-    CPPFunctionGroup *fgroup = (*fi).second;
-    CPPFunctionGroup::Instances::const_iterator ii;
-    for (ii = fgroup->_instances.begin();
-         ii != fgroup->_instances.end();
-         ++ii) {
-      CPPInstance *inst = (*ii);
-      if (inst->_storage_class & CPPInstance::SC_pure_virtual) {
-        // Here's a pure virtual function.
-        return false;
-      }
-    }
-  }
-
   return true;
 }
 
@@ -523,6 +514,10 @@ is_default_constructible(CPPVisibility min_vis) const {
  */
 bool CPPStructType::
 is_copy_constructible(CPPVisibility min_vis) const {
+  if (is_abstract()) {
+    return false;
+  }
+
   CPPInstance *constructor = get_copy_constructor();
   if (constructor != (CPPInstance *)NULL) {
     // It has a copy constructor.
@@ -580,24 +575,6 @@ is_copy_constructible(CPPVisibility min_vis) const {
     }
   }
 
-  // Check that we don't have pure virtual methods.
-  CPPScope::Functions::const_iterator fi;
-  for (fi = _scope->_functions.begin();
-       fi != _scope->_functions.end();
-       ++fi) {
-    CPPFunctionGroup *fgroup = (*fi).second;
-    CPPFunctionGroup::Instances::const_iterator ii;
-    for (ii = fgroup->_instances.begin();
-         ii != fgroup->_instances.end();
-         ++ii) {
-      CPPInstance *inst = (*ii);
-      if (inst->_storage_class & CPPInstance::SC_pure_virtual) {
-        // Here's a pure virtual function.
-        return false;
-      }
-    }
-  }
-
   return true;
 }
 
@@ -619,6 +596,10 @@ is_move_constructible(CPPVisibility min_vis) const {
       return false;
     }
 
+    if (is_abstract()) {
+      return false;
+    }
+
     return true;
   }
 
@@ -1213,7 +1194,7 @@ get_virtual_funcs(VFunctions &funcs) const {
           CPPFunctionType *new_ftype = new_inst->_type->as_function_type();
           assert(new_ftype != (CPPFunctionType *)NULL);
 
-          if (new_ftype->is_equivalent_function(*base_ftype)) {
+          if (new_ftype->match_virtual_override(*base_ftype)) {
             // It's a match!  We now know it's virtual.  Erase this function
             // from the list, so we can add it back in below.
             funcs.erase(vfi);

+ 1 - 0
dtool/src/cppparser/cppType.cxx

@@ -16,6 +16,7 @@
 #include "cppPointerType.h"
 #include "cppReferenceType.h"
 #include "cppStructType.h"
+#include "cppTypedefType.h"
 #include "cppExtensionType.h"
 #include <algorithm>
 

+ 25 - 3
makepanda/installer.nsi

@@ -31,6 +31,7 @@ SetCompressor ${COMPRESSOR}
 !include "Sections.nsh"
 !include "WinMessages.nsh"
 !include "WordFunc.nsh"
+!include "x64.nsh"
 
 !define MUI_WELCOMEFINISHPAGE_BITMAP "panda-install.bmp"
 !define MUI_UNWELCOMEFINISHPAGE_BITMAP "panda-install.bmp"
@@ -120,6 +121,14 @@ Function runFunction
     ExecShell "open" "$SMPROGRAMS\${TITLE}\Panda3D Manual.lnk"
 FunctionEnd
 
+Function .onInit
+    ${If} ${REGVIEW} = 64
+    ${AndIfNot} ${RunningX64}
+        MessageBox MB_OK|MB_ICONEXCLAMATION "You are attempting to install the 64-bit version of Panda3D on a 32-bit version of Windows.  Please download and install the 32-bit version of Panda3D instead."
+        Abort
+    ${EndIf}
+FunctionEnd
+
 SectionGroup "Panda3D Libraries"
     Section "Core Libraries" SecCore
         SectionIn 1 2 RO
@@ -134,12 +143,22 @@ SectionGroup "Panda3D Libraries"
         SetOutPath "$INSTDIR"
         File "${BUILT}\LICENSE"
         File /r /x CVS "${BUILT}\ReleaseNotes"
-        SetOutPath $INSTDIR\bin
-        File /r /x libpandagl.dll /x libpandadx9.dll /x cgD3D*.dll /x python*.dll /x libpandaode.dll /x libp3fmod_audio.dll /x fmodex*.dll /x libp3ffmpeg.dll /x av*.dll /x postproc*.dll /x swscale*.dll /x swresample*.dll /x NxCharacter*.dll /x cudart*.dll /x PhysX*.dll /x libpandaphysx.dll /x libp3rocket.dll /x boost_python*.dll /x Rocket*.dll /x _rocket*.pyd /x libpandabullet.dll /x OpenAL32.dll /x *_oal.dll /x libp3openal_audio.dll "${BUILT}\bin\*.dll"
-        File /nonfatal /r "${BUILT}\bin\Microsoft.*.manifest"
+
         SetOutPath $INSTDIR\etc
         File /r "${BUILT}\etc\*"
 
+        SetOutPath $INSTDIR\bin
+        File /r /x api-ms-win-*.dll /x ucrtbase.dll /x libpandagl.dll /x libpandadx9.dll /x cgD3D*.dll /x python*.dll /x libpandaode.dll /x libp3fmod_audio.dll /x fmodex*.dll /x libp3ffmpeg.dll /x av*.dll /x postproc*.dll /x swscale*.dll /x swresample*.dll /x NxCharacter*.dll /x cudart*.dll /x PhysX*.dll /x libpandaphysx.dll /x libp3rocket.dll /x boost_python*.dll /x Rocket*.dll /x _rocket*.pyd /x libpandabullet.dll /x OpenAL32.dll /x *_oal.dll /x libp3openal_audio.dll "${BUILT}\bin\*.dll"
+        File /nonfatal /r "${BUILT}\bin\Microsoft.*.manifest"
+
+        ; Before Windows 10, we need these stubs for the UCRT as well.
+        ReadRegDWORD $0 HKLM "Software\Microsoft\Windows NT\CurrentVersion" "CurrentMajorVersionNumber"
+        ${If} $0 < 10
+            ClearErrors
+            File /nonfatal /r "${BUILT}\bin\api-ms-win-*.dll"
+            File /nonfatal "${BUILT}\bin\ucrtbase.dll"
+        ${Endif}
+
         SetDetailsPrint both
         DetailPrint "Installing models..."
         SetDetailsPrint listonly
@@ -634,6 +653,9 @@ Section -post
     WriteRegStr HKCU "Software\Classes\.pz" "PerceivedType" "compressed"
     WriteRegStr HKCU "Software\Classes\.mf" "" "Panda3D.Multifile"
     WriteRegStr HKCU "Software\Classes\.mf" "PerceivedType" "compressed"
+    WriteRegStr HKCU "Software\Classes\.prc" "" "inifile"
+    WriteRegStr HKCU "Software\Classes\.prc" "Content Type" "text/plain"
+    WriteRegStr HKCU "Software\Classes\.prc" "PerceivedType" "text"
 
     ; For convenience, if nobody registered .pyd, we will.
     ReadRegStr $0 HKCR "Software\Classes\.pyd" ""

+ 125 - 70
makepanda/makepanda.py

@@ -94,7 +94,6 @@ PkgListSet(["PYTHON", "DIRECT",                        # Python support
   "PANDAPARTICLESYSTEM",                               # Built in particle system
   "CONTRIB",                                           # Experimental
   "SSE2", "NEON",                                      # Compiler features
-  "TOUCHINPUT",                                        # Touchinput interface (requires Windows 7)
 ])
 
 CheckPandaSourceTree()
@@ -170,7 +169,8 @@ def parseopts(args):
         "version=","lzma","no-python","threads=","outputdir=","override=",
         "static","host=","debversion=","rpmrelease=","p3dsuffix=","rtdist-version=",
         "directx-sdk=", "windows-sdk=", "msvc-version=", "clean", "use-icl",
-        "universal", "target=", "arch=", "git-commit="]
+        "universal", "target=", "arch=", "git-commit=",
+        "use-touchinput", "no-touchinput"]
     anything = 0
     optimize = ""
     target = None
@@ -316,18 +316,6 @@ def parseopts(args):
             print("No Windows SDK version specified. Defaulting to '7.1'.")
             WINDOWS_SDK = '7.1'
 
-        is_win7 = False
-        if sys.platform == 'win32':
-            # Note: not available in cygwin.
-            winver = sys.getwindowsversion()
-            if winver[0] >= 6 and winver[1] >= 1:
-                is_win7 = True
-
-        if RUNTIME or not is_win7:
-            PkgDisable("TOUCHINPUT")
-    else:
-        PkgDisable("TOUCHINPUT")
-
     if clean_build and os.path.isdir(GetOutputDir()):
         print("Deleting %s" % (GetOutputDir()))
         shutil.rmtree(GetOutputDir())
@@ -1055,11 +1043,12 @@ def CompileCxx(obj,src,opts):
                 cmd += "/favor:blend "
             cmd += "/wd4996 /wd4275 /wd4273 "
 
-            # Enable Windows 7 interfaces if we need Touchinput.
-            if PkgSkip("TOUCHINPUT") == 0:
-                cmd += "/DWINVER=0x601 "
-            else:
-                cmd += "/DWINVER=0x501 "
+            # We still target Windows XP.
+            cmd += "/DWINVER=0x501 "
+            # Work around a WinXP/2003 bug when using VS 2015+.
+            if SDK.get("VISUALSTUDIO_VERSION") == '14.0':
+                cmd += "/Zc:threadSafeInit- "
+
             cmd += "/Fo" + obj + " /nologo /c"
             if GetTargetArch() != 'x64' and (not PkgSkip("SSE2") or 'SSE2' in opts):
                 cmd += " /arch:SSE2"
@@ -1109,12 +1098,7 @@ def CompileCxx(obj,src,opts):
             if GetTargetArch() == 'x64':
                 cmd += "/favor:blend "
             cmd += "/wd4996 /wd4275 /wd4267 /wd4101 /wd4273 "
-
-            # Enable Windows 7 interfaces if we need Touchinput.
-            if PkgSkip("TOUCHINPUT") == 0:
-                cmd += "/DWINVER=0x601 "
-            else:
-                cmd += "/DWINVER=0x501 "
+            cmd += "/DWINVER=0x501 "
             cmd += "/Fo" + obj + " /c"
             for x in ipath: cmd += " /I" + x
             for (opt,dir) in INCDIRECTORIES:
@@ -1682,11 +1666,7 @@ def CompileLink(dll, obj, opts):
                 if 'NOARCH:' + arch.upper() not in opts:
                     cmd += " -arch %s" % arch
 
-        if "SYSROOT" in SDK:
-            cmd += " --sysroot=%s -no-canonical-prefixes" % (SDK["SYSROOT"])
-
-        # Android-specific flags.
-        if GetTarget() == 'android':
+        elif GetTarget() == 'android':
             cmd += " -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now"
             if GetTargetArch() == 'armv7a':
                 cmd += " -march=armv7-a -Wl,--fix-cortex-a8"
@@ -1694,6 +1674,9 @@ def CompileLink(dll, obj, opts):
         else:
             cmd += " -pthread"
 
+        if "SYSROOT" in SDK:
+            cmd += " --sysroot=%s -no-canonical-prefixes" % (SDK["SYSROOT"])
+
         if LDFLAGS != "":
             cmd += " " + LDFLAGS
 
@@ -2126,7 +2109,6 @@ DTOOL_CONFIG=[
     ("REPORT_OPENSSL_ERRORS",          '1',                      '1'),
     ("USE_PANDAFILESTREAM",            '1',                      '1'),
     ("USE_DELETED_CHAIN",              '1',                      '1'),
-    ("HAVE_WIN_TOUCHINPUT",            'UNDEF',                  'UNDEF'),
     ("HAVE_GLX",                       'UNDEF',                  '1'),
     ("HAVE_WGL",                       '1',                      'UNDEF'),
     ("HAVE_DX9",                       'UNDEF',                  'UNDEF'),
@@ -2233,11 +2215,7 @@ DTOOL_CONFIG=[
     ("HAVE_CG",                        'UNDEF',                  'UNDEF'),
     ("HAVE_CGGL",                      'UNDEF',                  'UNDEF'),
     ("HAVE_CGDX9",                     'UNDEF',                  'UNDEF'),
-    ("HAVE_FFMPEG",                    'UNDEF',                  'UNDEF'),
-    ("HAVE_SWSCALE",                   'UNDEF',                  'UNDEF'),
-    ("HAVE_SWRESAMPLE",                'UNDEF',                  'UNDEF'),
     ("HAVE_ARTOOLKIT",                 'UNDEF',                  'UNDEF'),
-    ("HAVE_OPENCV",                    'UNDEF',                  'UNDEF'),
     ("HAVE_DIRECTCAM",                 'UNDEF',                  'UNDEF'),
     ("HAVE_SQUISH",                    'UNDEF',                  'UNDEF'),
     ("HAVE_CARBON",                    'UNDEF',                  'UNDEF'),
@@ -2292,9 +2270,6 @@ def WriteConfigSettings():
             else:
                 dtool_config["HAVE_"+x] = 'UNDEF'
 
-    if not PkgSkip("OPENCV"):
-        dtool_config["OPENCV_VER_23"] = '1' if OPENCV_VER_23 else 'UNDEF'
-
     dtool_config["HAVE_NET"] = '1'
 
     if (PkgSkip("NVIDIACG")==0):
@@ -2351,9 +2326,6 @@ def WriteConfigSettings():
     if (PkgSkip("PYTHON") != 0):
         dtool_config["HAVE_ROCKET_PYTHON"] = 'UNDEF'
 
-    if (PkgSkip("TOUCHINPUT") == 0 and GetTarget() == "windows"):
-        dtool_config["HAVE_WIN_TOUCHINPUT"] = '1'
-
     if (GetOptimize() <= 3):
         dtool_config["HAVE_ROCKET_DEBUGGER"] = '1'
 
@@ -2781,8 +2753,13 @@ if (GetTarget() == 'darwin'):
     # OpenAL is not yet working well on OSX for us, so let's do this for now.
     configprc = configprc.replace("p3openal_audio", "p3fmod_audio")
 
-ConditionalWriteFile(GetOutputDir()+"/etc/Config.prc", configprc)
-ConditionalWriteFile(GetOutputDir()+"/etc/Confauto.prc", confautoprc)
+if GetTarget() == 'windows':
+    # Convert to Windows newlines.
+    ConditionalWriteFile(GetOutputDir()+"/etc/Config.prc", configprc, newline='\r\n')
+    ConditionalWriteFile(GetOutputDir()+"/etc/Confauto.prc", confautoprc, newline='\r\n')
+else:
+    ConditionalWriteFile(GetOutputDir()+"/etc/Config.prc", configprc)
+    ConditionalWriteFile(GetOutputDir()+"/etc/Confauto.prc", confautoprc)
 
 ##########################################################################################
 #
@@ -2879,22 +2856,75 @@ if tp_dir is not None:
 
     if GetTarget() == 'windows':
         CopyAllFiles(GetOutputDir() + "/bin/", tp_dir + "extras/bin/")
-        if not PkgSkip("PYTHON"):
-            pydll = "/" + SDK["PYTHONVERSION"].replace(".", "")
-            if (GetOptimize() <= 2): pydll += "_d.dll"
-            else: pydll += ".dll"
-            CopyFile(GetOutputDir() + "/bin" + pydll, SDK["PYTHON"] + pydll)
-
-            for fn in glob.glob(SDK["PYTHON"] + "/vcruntime*.dll"):
-                CopyFile(GetOutputDir() + "/bin/", fn)
-
-            if not RTDIST:
-                CopyTree(GetOutputDir() + "/python", SDK["PYTHON"])
-                if not os.path.isfile(SDK["PYTHON"] + "/ppython.exe") and os.path.isfile(SDK["PYTHON"] + "/python.exe"):
-                    CopyFile(GetOutputDir() + "/python/ppython.exe", SDK["PYTHON"] + "/python.exe")
-                if not os.path.isfile(SDK["PYTHON"] + "/ppythonw.exe") and os.path.isfile(SDK["PYTHON"] + "/pythonw.exe"):
-                    CopyFile(GetOutputDir() + "/python/ppythonw.exe", SDK["PYTHON"] + "/pythonw.exe")
-                ConditionalWriteFile(GetOutputDir() + "/python/panda.pth", "..\n../bin\n")
+
+        if not PkgSkip("PYTHON") and not RTDIST:
+            #XXX rdb I don't think we need to copy over the Python DLL, do we?
+            #pydll = "/" + SDK["PYTHONVERSION"].replace(".", "")
+            #if (GetOptimize() <= 2): pydll += "_d.dll"
+            #else: pydll += ".dll"
+            #CopyFile(GetOutputDir() + "/bin" + pydll, SDK["PYTHON"] + pydll)
+
+            #for fn in glob.glob(SDK["PYTHON"] + "/vcruntime*.dll"):
+            #    CopyFile(GetOutputDir() + "/bin/", fn)
+
+            # Copy the whole Python directory.
+            CopyTree(GetOutputDir() + "/python", SDK["PYTHON"])
+
+            # NB: Python does not always ship with the correct manifest/dll.
+            # Figure out the correct one to ship, and grab it from WinSxS dir.
+            manifest = GetOutputDir() + '/tmp/python.manifest'
+            if os.path.isfile(manifest):
+                os.unlink(manifest)
+            oscmd('mt -inputresource:"%s\\python.exe";#1 -out:"%s" -nologo' % (SDK["PYTHON"], manifest), True)
+
+            if os.path.isfile(manifest):
+                import xml.etree.ElementTree as ET
+                tree = ET.parse(manifest)
+                idents = tree.findall('./{urn:schemas-microsoft-com:asm.v1}dependency/{urn:schemas-microsoft-com:asm.v1}dependentAssembly/{urn:schemas-microsoft-com:asm.v1}assemblyIdentity')
+            else:
+                idents = ()
+
+            for ident in tree.findall('./{urn:schemas-microsoft-com:asm.v1}dependency/{urn:schemas-microsoft-com:asm.v1}dependentAssembly/{urn:schemas-microsoft-com:asm.v1}assemblyIdentity'):
+                sxs_name = '_'.join([
+                    ident.get('processorArchitecture'),
+                    ident.get('name').lower(),
+                    ident.get('publicKeyToken'),
+                    ident.get('version'),
+                ])
+
+                # Find the manifest matching these parameters.
+                pattern = os.path.join('C:' + os.sep, 'Windows', 'WinSxS', 'Manifests', sxs_name + '_*.manifest')
+                manifests = glob.glob(pattern)
+                if not manifests:
+                    print("%sWARNING:%s Could not locate manifest %s.  You may need to reinstall the Visual C++ Redistributable." % (GetColor("red"), GetColor(), pattern))
+                    continue
+
+                CopyFile(GetOutputDir() + "/python/" + ident.get('name') + ".manifest", manifests[0])
+
+                # Also copy the corresponding msvcr dll.
+                pattern = os.path.join('C:' + os.sep, 'Windows', 'WinSxS', sxs_name + '_*', 'msvcr*.dll')
+                for file in glob.glob(pattern):
+                    CopyFile(GetOutputDir() + "/python/", file)
+
+            # Copy python.exe to ppython.exe.
+            if not os.path.isfile(SDK["PYTHON"] + "/ppython.exe") and os.path.isfile(SDK["PYTHON"] + "/python.exe"):
+                CopyFile(GetOutputDir() + "/python/ppython.exe", SDK["PYTHON"] + "/python.exe")
+            if not os.path.isfile(SDK["PYTHON"] + "/ppythonw.exe") and os.path.isfile(SDK["PYTHON"] + "/pythonw.exe"):
+                CopyFile(GetOutputDir() + "/python/ppythonw.exe", SDK["PYTHON"] + "/pythonw.exe")
+            ConditionalWriteFile(GetOutputDir() + "/python/panda.pth", "..\n../bin\n")
+
+# Copy over the MSVC runtime.
+if GetTarget() == 'windows' and "VISUALSTUDIO" in SDK:
+    vcver = SDK["VISUALSTUDIO_VERSION"].replace('.', '')
+    crtname = "Microsoft.VC%s.CRT" % (vcver)
+    dir = os.path.join(SDK["VISUALSTUDIO"], "VC", "redist", GetTargetArch(), crtname)
+
+    if os.path.isfile(os.path.join(dir, "msvcr" + vcver + ".dll")):
+        CopyFile(GetOutputDir() + "/bin/", os.path.join(dir, "msvcr" + vcver + ".dll"))
+    if os.path.isfile(os.path.join(dir, "msvcp" + vcver + ".dll")):
+        CopyFile(GetOutputDir() + "/bin/", os.path.join(dir, "msvcp" + vcver + ".dll"))
+    if os.path.isfile(os.path.join(dir, "vcruntime" + vcver + ".dll")):
+        CopyFile(GetOutputDir() + "/bin/", os.path.join(dir, "vcruntime" + vcver + ".dll"))
 
 ########################################################################
 ##
@@ -2902,8 +2932,14 @@ if tp_dir is not None:
 ##
 ########################################################################
 
-CopyFile(GetOutputDir()+"/", "doc/LICENSE")
-CopyFile(GetOutputDir()+"/", "doc/ReleaseNotes")
+if GetTarget() == 'windows':
+    # Convert to Windows newlines so they can be opened by notepad.
+    WriteFile(GetOutputDir() + "/LICENSE", ReadFile("doc/LICENSE"), newline='\r\n')
+    WriteFile(GetOutputDir() + "/ReleaseNotes", ReadFile("doc/ReleaseNotes"), newline='\r\n')
+else:
+    CopyFile(GetOutputDir()+"/", "doc/LICENSE")
+    CopyFile(GetOutputDir()+"/", "doc/ReleaseNotes")
+
 if (PkgSkip("PANDATOOL")==0):
     CopyAllFiles(GetOutputDir()+"/plugins/",  "pandatool/src/scripts/", ".mel")
     CopyAllFiles(GetOutputDir()+"/plugins/",  "pandatool/src/scripts/", ".ms")
@@ -4061,8 +4097,20 @@ if (not RUNTIME):
 #
 
 if (PkgSkip("VISION") == 0) and (not RUNTIME):
+  # We want to know whether we have ffmpeg so that we can override the .avi association.
+  if not PkgSkip("FFMPEG"):
+    DefSymbol("OPENCV", "HAVE_FFMPEG")
+  if not PkgSkip("OPENCV"):
+    DefSymbol("OPENCV", "HAVE_OPENCV")
+    if OPENCV_VER_23:
+        DefSymbol("OPENCV", "OPENCV_VER_23")
+
   OPTS=['DIR:panda/src/vision', 'BUILDING:VISION', 'ARTOOLKIT', 'OPENCV', 'DX9', 'DIRECTCAM', 'JPEG', 'EXCEPTIONS']
-  TargetAdd('p3vision_composite1.obj', opts=OPTS, input='p3vision_composite1.cxx')
+  TargetAdd('p3vision_composite1.obj', opts=OPTS, input='p3vision_composite1.cxx', dep=[
+    'dtool_have_ffmpeg.dat',
+    'dtool_have_opencv.dat',
+    'dtool_have_directcam.dat',
+  ])
 
   TargetAdd('libp3vision.dll', input='p3vision_composite1.obj')
   TargetAdd('libp3vision.dll', input=COMMON_PANDA_LIBS)
@@ -4251,8 +4299,15 @@ if (PkgSkip("VRPN")==0 and not RUNTIME):
 # DIRECTORY: panda/src/ffmpeg
 #
 if PkgSkip("FFMPEG") == 0 and not RUNTIME:
+  if not PkgSkip("SWSCALE"):
+    DefSymbol("FFMPEG", "HAVE_SWSCALE")
+  if not PkgSkip("SWRESAMPLE"):
+    DefSymbol("FFMPEG", "HAVE_SWRESAMPLE")
+
   OPTS=['DIR:panda/src/ffmpeg', 'BUILDING:FFMPEG', 'FFMPEG', 'SWSCALE', 'SWRESAMPLE']
-  TargetAdd('p3ffmpeg_composite1.obj', opts=OPTS, input='p3ffmpeg_composite1.cxx')
+  TargetAdd('p3ffmpeg_composite1.obj', opts=OPTS, input='p3ffmpeg_composite1.cxx', dep=[
+    'dtool_have_swscale.dat', 'dtool_have_swresample.dat'])
+
   TargetAdd('libp3ffmpeg.dll', input='p3ffmpeg_composite1.obj')
   TargetAdd('libp3ffmpeg.dll', input=COMMON_PANDA_LIBS)
   TargetAdd('libp3ffmpeg.dll', opts=OPTS)
@@ -4532,7 +4587,7 @@ if (GetTarget() == 'darwin' and PkgSkip("COCOA")==0 and PkgSkip("GL")==0 and not
   if (PkgSkip('PANDAFX')==0):
     TargetAdd('libpandagl.dll', input='libpandafx.dll')
   TargetAdd('libpandagl.dll', input=COMMON_PANDA_LIBS)
-  TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'NVIDIACG', 'CGGL', 'COCOA'])
+  TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'NVIDIACG', 'CGGL', 'COCOA', 'CARBON'])
 
 #
 # DIRECTORY: panda/src/osxdisplay/
@@ -6792,9 +6847,9 @@ def MakeInstallerLinux():
         txt = txt.replace("VERSION", DEBVERSION).replace("ARCH", pkg_arch).replace("PV", PV).replace("MAJOR", MAJOR_VERSION)
         txt = txt.replace("INSTSIZE", str(GetDirectorySize("targetroot") / 1024))
         oscmd("mkdir --mode=0755 -p targetroot/DEBIAN")
-        oscmd("cd targetroot ; (find usr -type f -exec md5sum {} \;) >  DEBIAN/md5sums")
+        oscmd("cd targetroot && (find usr -type f -exec md5sum {} ;) > DEBIAN/md5sums")
         if (not RUNTIME):
-          oscmd("cd targetroot ; (find etc -type f -exec md5sum {} \;) >> DEBIAN/md5sums")
+          oscmd("cd targetroot && (find etc -type f -exec md5sum {} ;) >> DEBIAN/md5sums")
           WriteFile("targetroot/DEBIAN/conffiles","/etc/Config.prc\n")
         WriteFile("targetroot/DEBIAN/postinst","#!/bin/sh\necho running ldconfig\nldconfig\n")
         oscmd("cp targetroot/DEBIAN/postinst targetroot/DEBIAN/postrm")
@@ -6822,7 +6877,7 @@ def MakeInstallerLinux():
 
         if RUNTIME:
             # The runtime doesn't export any useful symbols, so just query the dependencies.
-            oscmd("cd targetroot; %(dpkg_shlibdeps)s -x%(pkg_name)s %(lib_pattern)s %(bin_pattern)s*" % locals())
+            oscmd("cd targetroot && %(dpkg_shlibdeps)s -x%(pkg_name)s %(lib_pattern)s %(bin_pattern)s*" % locals())
             depends = ReadFile("targetroot/debian/substvars").replace("shlibs:Depends=", "").strip()
             recommends = ""
         else:
@@ -6830,12 +6885,12 @@ def MakeInstallerLinux():
             pkg_dir = "debian/panda3d" + MAJOR_VERSION
 
             # Generate a symbols file so that other packages can know which symbols we export.
-            oscmd("cd targetroot; dpkg-gensymbols -q -ODEBIAN/symbols -v%(pkg_version)s -p%(pkg_name)s -e%(lib_pattern)s" % locals())
+            oscmd("cd targetroot && dpkg-gensymbols -q -ODEBIAN/symbols -v%(pkg_version)s -p%(pkg_name)s -e%(lib_pattern)s" % locals())
 
             # Library dependencies are required, binary dependencies are recommended.
             # We explicitly exclude libphysx-extras since we don't want to depend on PhysX.
-            oscmd("cd targetroot; LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_dep --ignore-missing-info -x%(pkg_name)s -xlibphysx-extras %(lib_pattern)s" % locals())
-            oscmd("cd targetroot; LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_rec --ignore-missing-info -x%(pkg_name)s %(bin_pattern)s" % locals())
+            oscmd("cd targetroot && LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_dep --ignore-missing-info -x%(pkg_name)s -xlibphysx-extras %(lib_pattern)s" % locals())
+            oscmd("cd targetroot && LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_rec --ignore-missing-info -x%(pkg_name)s %(bin_pattern)s" % locals())
 
             # Parse the substvars files generated by dpkg-shlibdeps.
             depends = ReadFile("targetroot/debian/substvars_dep").replace("shlibs:Depends=", "").strip()

+ 51 - 6
makepanda/makepandacore.py

@@ -396,10 +396,16 @@ def CrossCompiling():
     return GetTarget() != GetHost()
 
 def GetCC():
-    return os.environ.get('CC', TOOLCHAIN_PREFIX + 'gcc')
+    if TARGET == 'darwin':
+        return os.environ.get('CC', TOOLCHAIN_PREFIX + 'clang')
+    else:
+        return os.environ.get('CC', TOOLCHAIN_PREFIX + 'gcc')
 
 def GetCXX():
-    return os.environ.get('CXX', TOOLCHAIN_PREFIX + 'g++')
+    if TARGET == 'darwin':
+        return os.environ.get('CXX', TOOLCHAIN_PREFIX + 'clang++')
+    else:
+        return os.environ.get('CXX', TOOLCHAIN_PREFIX + 'g++')
 
 def GetStrip():
     # Hack
@@ -512,6 +518,7 @@ def oscmd(cmd, ignoreError = False):
             exit("Cannot find "+exe+" on search path")
         res = os.spawnl(os.P_WAIT, exe_path, cmd)
     else:
+        cmd = cmd.replace(';', '\\;')
         res = subprocess.call(cmd, shell=True)
         sig = res & 0x7F
         if (GetVerbose() and res != 0):
@@ -966,7 +973,12 @@ def ReadBinaryFile(wfile):
         ex = sys.exc_info()[1]
         exit("Cannot read %s: %s" % (wfile, ex))
 
-def WriteFile(wfile, data):
+def WriteFile(wfile, data, newline=None):
+    if newline is not None:
+        data = data.replace('\r\n', '\n')
+        data = data.replace('\r', '\n')
+        data = data.replace('\n', newline)
+
     try:
         dsthandle = open(wfile, "w")
         dsthandle.write(data)
@@ -984,18 +996,24 @@ def WriteBinaryFile(wfile, data):
         ex = sys.exc_info()[1]
         exit("Cannot write to %s: %s" % (wfile, ex))
 
-def ConditionalWriteFile(dest, desiredcontents):
+def ConditionalWriteFile(dest, data, newline=None):
+    if newline is not None:
+        data = data.replace('\r\n', '\n')
+        data = data.replace('\r', '\n')
+        data = data.replace('\n', newline)
+
     try:
         rfile = open(dest, 'r')
         contents = rfile.read(-1)
         rfile.close()
     except:
         contents = 0
-    if contents != desiredcontents:
+
+    if contents != data:
         if VERBOSE:
             print("Writing %s" % (dest))
         sys.stdout.flush()
-        WriteFile(dest, desiredcontents)
+        WriteFile(dest, data)
 
 def DeleteVCS(dir):
     if dir == "": dir = "."
@@ -1984,6 +2002,11 @@ def SdkLocatePython(prefer_thirdparty_python=False):
          SDK["PYTHONVERSION"] = "python" + ver
          SDK["PYTHONEXEC"] = "/System/Library/Frameworks/Python.framework/Versions/" + ver + "/bin/python" + ver
 
+         # Avoid choosing the one in the thirdparty package dir.
+         PkgSetCustomLocation("PYTHON")
+         IncDirectory("PYTHON", py_fwx + "/include")
+         LibDirectory("PYTHON", "%s/usr/lib" % (SDK.get("MACOSX", "")))
+
          if sys.version[:3] != ver:
              print("Warning: building with Python %s instead of %s since you targeted a specific Mac OS X version." % (ver, sys.version[:3]))
 
@@ -2057,6 +2080,10 @@ def SdkLocateWindows(version = '7.1'):
         # Choose the latest version of the Windows 10 SDK.
         platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10")
 
+        # Fallback in case we can't read the registry.
+        if not platsdk or not os.path.isdir(platsdk):
+            platsdk = "C:\\Program Files (x86)\\Windows Kits\\10\\"
+
         if platsdk and os.path.isdir(platsdk):
             incdirs = glob.glob(os.path.join(platsdk, 'Include', version + '.*.*'))
             max_version = ()
@@ -2089,6 +2116,10 @@ def SdkLocateWindows(version = '7.1'):
         # We chose a specific version of the Windows 10 SDK.  Verify it exists.
         platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10")
 
+        # Fallback in case we can't read the registry.
+        if not platsdk or not os.path.isdir(platsdk):
+            platsdk = "C:\\Program Files (x86)\\Windows Kits\\10\\"
+
         if version.count('.') == 2:
             version += '.0'
 
@@ -2098,6 +2129,10 @@ def SdkLocateWindows(version = '7.1'):
     elif version == '8.1':
         platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot81")
 
+        # Fallback in case we can't read the registry.
+        if not platsdk or not os.path.isdir(platsdk):
+            platsdk = "C:\\Program Files (x86)\\Windows Kits\\8.1\\"
+
     elif version == '8.0':
         platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot")
 
@@ -2403,9 +2438,19 @@ def SetupVisualStudioEnviron():
     # with Visual Studio 2015 requires use of the Universal CRT.
     if winsdk_ver == '7.1' and SDK["VISUALSTUDIO_VERSION"] == '14.0':
         win_kit = GetRegistryKey("SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10")
+
+        # Fallback in case we can't read the registry.
+        if not win_kit or not os.path.isdir(win_kit):
+            win_kit = "C:\\Program Files (x86)\\Windows Kits\\10\\"
+        elif not win_kit.endswith('\\'):
+            win_kit += '\\'
+
         AddToPathEnv("LIB", win_kit + "Lib\\10.0.10150.0\\ucrt\\" + arch)
         AddToPathEnv("INCLUDE", win_kit + "Include\\10.0.10150.0\\ucrt")
 
+        # Copy the DLLs to the bin directory.
+        CopyAllFiles(GetOutputDir() + "/bin/", win_kit + "Redist\\ucrt\\DLLs\\" + arch + "\\")
+
 ########################################################################
 #
 # Include and Lib directories.

+ 10 - 1
panda/src/bullet/bulletBodyNode.cxx

@@ -45,7 +45,16 @@ BulletBodyNode(const BulletBodyNode &copy) :
   _shapes(copy._shapes)
 {
   if (copy._shape && copy._shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) {
-    _shape = new btCompoundShape(copy._shape);
+    // btCompoundShape does not define a copy constructor.  Manually copy.
+    btCompoundShape *shape = new btCompoundShape;
+    _shape = shape;
+
+    btCompoundShape *copy_shape = (btCompoundShape *)copy._shape;
+    int num_children = copy_shape->getNumChildShapes();
+    for (int i = 0; i < num_children; ++i) {
+      shape->addChildShape(copy_shape->getChildTransform(i),
+                           copy_shape->getChildShape(i));
+    }
   }
   else if (copy._shape && copy._shape->getShapeType() == EMPTY_SHAPE_PROXYTYPE) {
     _shape = new btEmptyShape();

+ 1 - 1
panda/src/bullet/bulletGhostNode.cxx

@@ -55,7 +55,7 @@ void BulletGhostNode::
 parents_changed() {
 
   Parents parents = get_parents();
-  for (int i=0; i < parents.get_num_parents(); ++i) {
+  for (size_t i = 0; i < parents.get_num_parents(); ++i) {
     PandaNode *parent = parents.get_parent(i);
     TypeHandle type = parent->get_type();
 

+ 0 - 1
panda/src/bullet/bulletRigidBodyNode.I

@@ -18,7 +18,6 @@ INLINE BulletRigidBodyNode::
 ~BulletRigidBodyNode() {
 
   delete _rigid;
-  delete _motion;
 }
 
 /**

+ 8 - 12
panda/src/bullet/bulletRigidBodyNode.cxx

@@ -21,16 +21,12 @@ TypeHandle BulletRigidBodyNode::_type_handle;
  */
 BulletRigidBodyNode::
 BulletRigidBodyNode(const char *name) : BulletBodyNode(name) {
-
-  // Motion state
-  _motion = new MotionState();
-
   // Mass properties
   btScalar mass(0.0);
   btVector3 inertia(0, 0, 0);
 
   // construction info
-  btRigidBody::btRigidBodyConstructionInfo ci(mass, _motion, _shape, inertia);
+  btRigidBody::btRigidBodyConstructionInfo ci(mass, &_motion, _shape, inertia);
 
   // Additional damping
   if (bullet_additional_damping) {
@@ -52,13 +48,13 @@ BulletRigidBodyNode(const char *name) : BulletBodyNode(name) {
  */
 BulletRigidBodyNode::
 BulletRigidBodyNode(const BulletRigidBodyNode &copy) :
-  BulletBodyNode(copy)
+  BulletBodyNode(copy),
+  _motion(copy._motion)
 {
-  _motion = new MotionState(*copy._motion);
   _rigid = new btRigidBody(*copy._rigid);
   _rigid->setUserPointer(this);
   _rigid->setCollisionShape(_shape);
-  _rigid->setMotionState(_motion);
+  _rigid->setMotionState(&_motion);
 }
 
 /**
@@ -280,7 +276,7 @@ apply_central_impulse(const LVector3 &impulse) {
 void BulletRigidBodyNode::
 transform_changed() {
 
-  if (_motion->sync_disabled()) return;
+  if (_motion.sync_disabled()) return;
 
   NodePath np = NodePath::any_path((PandaNode *)this);
   CPT(TransformState) ts = np.get_net_transform();
@@ -290,7 +286,7 @@ transform_changed() {
   // transform within the motion state.  For dynamic bodies we need to store
   // the net scale within the motion state, since Bullet might update the
   // transform via MotionState::setWorldTransform.
-  _motion->set_net_transform(ts);
+  _motion.set_net_transform(ts);
 
   // For dynamic or static bodies we directly apply the new transform.
   if (!is_kinematic()) {
@@ -334,7 +330,7 @@ sync_p2b() {
 void BulletRigidBodyNode::
 sync_b2p() {
 
-  _motion->sync_b2p((PandaNode *)this);
+  _motion.sync_b2p((PandaNode *)this);
 }
 
 /**
@@ -589,7 +585,7 @@ pick_dirty_flag() {
 bool BulletRigidBodyNode::
 pick_dirty_flag() {
 
-  return _motion->pick_dirty_flag();
+  return _motion.pick_dirty_flag();
 }
 
 /**

+ 1 - 1
panda/src/bullet/bulletRigidBodyNode.h

@@ -124,7 +124,7 @@ private:
     bool _was_dirty;
   };
 
-  MotionState *_motion;
+  MotionState _motion;
   btRigidBody *_rigid;
 
 public:

+ 3 - 1
panda/src/display/frameBufferProperties.cxx

@@ -659,7 +659,7 @@ setup_color_texture(Texture *tex) const {
   // as the below one would be generated dynamically by the GSG to reflect the
   // formats that are supported for render-to-texture.
 
-  static const int num_formats = 15;
+  static const int num_formats = 17;
   static const struct {
     unsigned char color_bits, red_bits, green_bits, blue_bits, alpha_bits;
     bool has_float;
@@ -669,6 +669,8 @@ setup_color_texture(Texture *tex) const {
     {  1,  1,  1,  0,  0, false, Texture::F_rg },
     {  1,  1,  1,  1,  0, false, Texture::F_rgb },
     {  1,  1,  1,  1,  1, false, Texture::F_rgba },
+    {  8,  8,  0,  0,  0, false, Texture::F_red },
+    { 16,  8,  8,  0,  0, false, Texture::F_rg },
     { 24,  8,  8,  8,  0, false, Texture::F_rgb8 },
     { 32,  8,  8,  8,  8, false, Texture::F_rgba8 },
     { 16, 16,  0,  0,  0,  true, Texture::F_r16 },

+ 92 - 33
panda/src/display/graphicsStateGuardian.cxx

@@ -1363,8 +1363,18 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
       }
     }
 
-    // TODO: dummy light
-    nassertr(false, &LMatrix4::ident_mat());
+    // Apply the default OpenGL lights otherwise.
+    // Special exception for light 0, which defaults to white.
+    if (index == 0) {
+      string basename = name->get_basename();
+      if (basename == "color" || basename == "diffuse") {
+        t.set_row(3, _light_color_scale);
+        return &t;
+      } else if (basename == "specular") {
+        return &LMatrix4::ones_mat();
+      }
+    }
+    return fetch_specified_member(NodePath(), name, t);
   }
   default:
     nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
@@ -1395,8 +1405,16 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
   static const CPT_InternalName IN_quadraticAttenuation("quadraticAttenuation");
   static const CPT_InternalName IN_shadowMatrix("shadowMatrix");
 
+  PandaNode *node = NULL;
+  if (!np.is_empty()) {
+    node = np.node();
+  }
+
   if (attrib == IN_color) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     LColor c = light->get_color();
     c.componentwise_mult(_light_color_scale);
@@ -1404,9 +1422,12 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     return &t;
 
   } else if (attrib == IN_ambient) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (node->is_of_type(AmbientLight::get_class_type())) {
       LColor c = light->get_color();
       c.componentwise_mult(_light_color_scale);
       t.set_row(3, c);
@@ -1417,9 +1438,12 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     return &t;
 
   } else if (attrib == IN_diffuse) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no diffuse color.
       t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
     } else {
@@ -1430,19 +1454,25 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     return &t;
 
   } else if (attrib == IN_specular) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
     t.set_row(3, light->get_specular_color());
     return &t;
 
   } else if (attrib == IN_position) {
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (np.is_empty()) {
+      t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0);
+      return &t;
+    } else if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no position.
       t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
       return &t;
-    } else if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
+    } else if (node->is_of_type(DirectionalLight::get_class_type())) {
       DirectionalLight *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
 
       CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
       LVector3 dir = -(light->get_direction() * transform->get_mat());
@@ -1451,7 +1481,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
       return &t;
     } else {
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
@@ -1466,13 +1496,16 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
 
   } else if (attrib == IN_halfVector) {
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (np.is_empty()) {
+      t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0);
+      return &t;
+    } else if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no half-vector.
       t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
       return &t;
-    } else if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
+    } else if (node->is_of_type(DirectionalLight::get_class_type())) {
       DirectionalLight *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
 
       CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
       LVector3 dir = -(light->get_direction() * transform->get_mat());
@@ -1484,7 +1517,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
       return &t;
     } else {
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
@@ -1502,13 +1535,16 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
 
   } else if (attrib == IN_spotDirection) {
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (node == (PandaNode *)NULL) {
+      t.set_row(3, LVector3(0.0f, 0.0f, -1.0f));
+      return &t;
+    } else if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no spot direction.
       t.set_row(3, LVector3(0.0f, 0.0f, 0.0f));
       return &t;
     } else {
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
@@ -1523,9 +1559,10 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
 
   } else if (attrib == IN_spotCutoff) {
-    if (np.node()->is_of_type(Spotlight::get_class_type())) {
+    if (node != (PandaNode *)NULL &&
+        node->is_of_type(Spotlight::get_class_type())) {
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
@@ -1539,9 +1576,10 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
 
   } else if (attrib == IN_spotCosCutoff) {
-    if (np.node()->is_of_type(Spotlight::get_class_type())) {
+    if (node != (PandaNode *)NULL &&
+        node->is_of_type(Spotlight::get_class_type())) {
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
@@ -1553,51 +1591,72 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
       t.set_row(3, LVecBase4(-1));
       return &t;
     }
+
   } else if (attrib == IN_spotExponent) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::zeros_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
 
     t.set_row(3, LVecBase4(light->get_exponent()));
     return &t;
 
   } else if (attrib == IN_attenuation) {
-    Light *light = np.node()->as_light();
-    nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
+    if (node != (PandaNode *)NULL) {
+      Light *light = node->as_light();
+      nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
 
-    t.set_row(3, LVecBase4(light->get_attenuation(), 0));
+      t.set_row(3, LVecBase4(light->get_attenuation(), 0));
+    } else {
+      t.set_row(3, LVecBase4(1, 0, 0, 0));
+    }
     return &t;
 
   } else if (attrib == IN_constantAttenuation) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ones_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
 
     t.set_row(3, LVecBase4(light->get_attenuation()[0]));
     return &t;
 
   } else if (attrib == IN_linearAttenuation) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::zeros_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
 
     t.set_row(3, LVecBase4(light->get_attenuation()[1]));
     return &t;
 
   } else if (attrib == IN_quadraticAttenuation) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::zeros_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
 
     t.set_row(3, LVecBase4(light->get_attenuation()[2]));
     return &t;
 
   } else if (attrib == IN_shadowMatrix) {
-    LensNode *lnode;
-    DCAST_INTO_R(lnode, np.node(), &LMatrix4::ident_mat());
-    Lens *lens = lnode->get_lens();
-
     static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f,
                                   0.0f, 0.5f, 0.0f, 0.0f,
                                   0.0f, 0.0f, 0.5f, 0.0f,
                                   0.5f, 0.5f, 0.5f, 1.0f);
 
+    if (node == (PandaNode *)NULL) {
+      return &biasmat;
+    }
+
+    LensNode *lnode;
+    DCAST_INTO_R(lnode, node, &LMatrix4::ident_mat());
+    Lens *lens = lnode->get_lens();
+
     t = get_external_transform()->get_mat() *
       get_scene()->get_camera_transform()->get_mat() *
       np.get_net_transform()->get_inverse()->get_mat() *

+ 18 - 2
panda/src/dxgsg9/wdxGraphicsPipe9.cxx

@@ -19,6 +19,16 @@
 
 TypeHandle wdxGraphicsPipe9::_type_handle;
 
+static bool MyGetProcAddr(HINSTANCE hDLL, FARPROC *pFn, const char *szExportedFnName) {
+  *pFn = (FARPROC) GetProcAddress(hDLL, szExportedFnName);
+  if (*pFn == NULL) {
+    wdxdisplay9_cat.error()
+      << "GetProcAddr failed for " << szExportedFnName << ", error=" << GetLastError() <<endl;
+    return false;
+  }
+  return true;
+}
+
 #define LOWVIDMEMTHRESHOLD 5700000  // 4MB cards should fall below this
 #define CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD 1000000  // if # is > 1MB, card is lying and I cant tell what it is
 #define UNKNOWN_VIDMEM_SIZE 0xFFFFFFFF
@@ -154,7 +164,10 @@ make_output(const string &name,
  */
 bool wdxGraphicsPipe9::
 init() {
-  if (!MyLoadLib(_hDDrawDLL, "ddraw.dll")) {
+  _hDDrawDLL = LoadLibrary("ddraw.dll");
+  if (_hDDrawDLL == NULL) {
+    wdxdisplay9_cat.error()
+      << "LoadLibrary failed for ddraw.dll, error=" << GetLastError() <<endl;
     goto error;
   }
 
@@ -166,7 +179,10 @@ init() {
     goto error;
   }
 
-  if (!MyLoadLib(_hD3D9_DLL, "d3d9.dll")) {
+  _hD3D9_DLL = LoadLibrary("d3d9.dll");
+  if (_hD3D9_DLL == NULL) {
+    wdxdisplay9_cat.error()
+      << "LoadLibrary failed for d3d9.dll, error=" << GetLastError() <<endl;
     goto error;
   }
 

+ 1 - 0
panda/src/egg2pg/save_egg_file.cxx

@@ -14,6 +14,7 @@
 #include "save_egg_file.h"
 #include "eggSaver.h"
 #include "config_egg2pg.h"
+#include "modelRoot.h"
 #include "sceneGraphReducer.h"
 #include "virtualFileSystem.h"
 #include "config_util.h"

+ 0 - 2
panda/src/ffmpeg/ffmpegAudioCursor.cxx

@@ -50,9 +50,7 @@ FfmpegAudioCursor(FfmpegAudio *src) :
   _packet_data(0),
   _format_ctx(0),
   _audio_ctx(0),
-#ifdef HAVE_SWRESAMPLE
   _resample_ctx(0),
-#endif
   _buffer(0),
   _buffer_alloc(0),
   _frame(0)

+ 0 - 5
panda/src/ffmpeg/ffmpegAudioCursor.h

@@ -31,10 +31,7 @@ struct AVFormatContext;
 struct AVCodecContext;
 struct AVStream;
 struct AVPacket;
-
-#ifdef HAVE_SWRESAMPLE
 struct SwrContext;
-#endif
 
 /**
  * A stream that generates a sequence of audio samples.
@@ -72,9 +69,7 @@ protected:
   int       _buffer_head;
   int       _buffer_tail;
 
-#ifdef HAVE_SWRESAMPLE
   SwrContext *_resample_ctx;
-#endif
 
 public:
   static TypeHandle get_class_type() {

+ 39 - 16
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -1356,6 +1356,8 @@ reset() {
       get_extension_func("glMapBuffer");
     _glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)
       get_extension_func("glUnmapBuffer");
+    _glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)
+      get_extension_func("glGetBufferSubData");
 #endif
   }
 #ifndef OPENGLES_1
@@ -1376,6 +1378,8 @@ reset() {
       get_extension_func("glMapBufferARB");
     _glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)
       get_extension_func("glUnmapBufferARB");
+    _glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)
+      get_extension_func("glGetBufferSubDataARB");
   }
 #endif  // OPENGLES_1
 
@@ -12644,20 +12648,26 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
   GLint minfilter, magfilter;
   GLfloat border_color[4];
 
-  glGetTexParameteriv(target, GL_TEXTURE_WRAP_S, &wrap_u);
-  glGetTexParameteriv(target, GL_TEXTURE_WRAP_T, &wrap_v);
-  wrap_w = GL_REPEAT;
+#ifdef OPENGLES
+  if (true) {
+#else
+  if (target != GL_TEXTURE_BUFFER) {
+#endif
+    glGetTexParameteriv(target, GL_TEXTURE_WRAP_S, &wrap_u);
+    glGetTexParameteriv(target, GL_TEXTURE_WRAP_T, &wrap_v);
+    wrap_w = GL_REPEAT;
 #ifndef OPENGLES_1
-  if (_supports_3d_texture) {
-    glGetTexParameteriv(target, GL_TEXTURE_WRAP_R, &wrap_w);
-  }
+    if (_supports_3d_texture) {
+      glGetTexParameteriv(target, GL_TEXTURE_WRAP_R, &wrap_w);
+    }
 #endif
-  glGetTexParameteriv(target, GL_TEXTURE_MIN_FILTER, &minfilter);
-  glGetTexParameteriv(target, GL_TEXTURE_MAG_FILTER, &magfilter);
+    glGetTexParameteriv(target, GL_TEXTURE_MIN_FILTER, &minfilter);
+    glGetTexParameteriv(target, GL_TEXTURE_MAG_FILTER, &magfilter);
 
 #ifndef OPENGLES
-  glGetTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
+    glGetTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
 #endif
+  }
 
   GLenum page_target = target;
   if (target == GL_TEXTURE_CUBE_MAP) {
@@ -13122,14 +13132,20 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
   tex->set_component_type(type);
   tex->set_format(format);
 
-  tex->set_wrap_u(get_panda_wrap_mode(wrap_u));
-  tex->set_wrap_v(get_panda_wrap_mode(wrap_v));
-  tex->set_wrap_w(get_panda_wrap_mode(wrap_w));
-  tex->set_border_color(LColor(border_color[0], border_color[1],
-                               border_color[2], border_color[3]));
+#ifdef OPENGLES
+  if (true) {
+#else
+  if (target != GL_TEXTURE_BUFFER) {
+#endif
+    tex->set_wrap_u(get_panda_wrap_mode(wrap_u));
+    tex->set_wrap_v(get_panda_wrap_mode(wrap_v));
+    tex->set_wrap_w(get_panda_wrap_mode(wrap_w));
+    tex->set_border_color(LColor(border_color[0], border_color[1],
+                                 border_color[2], border_color[3]));
 
-  tex->set_minfilter(get_panda_filter_type(minfilter));
-  // tex->set_magfilter(get_panda_filter_type(magfilter));
+    tex->set_minfilter(get_panda_filter_type(minfilter));
+    //tex->set_magfilter(get_panda_filter_type(magfilter));
+  }
 
   PTA_uchar image;
   size_t page_size = 0;
@@ -13216,6 +13232,13 @@ extract_texture_image(PTA_uchar &image, size_t &page_size,
       }
     }
 
+#ifndef OPENGLES
+  } else if (target == GL_TEXTURE_BUFFER) {
+    // In the case of a buffer texture, we need to get it from the buffer.
+    image = PTA_uchar::empty_array(tex->get_expected_ram_mipmap_image_size(n));
+    _glGetBufferSubData(target, 0, image.size(), image.p());
+#endif
+
   } else if (compression == Texture::CM_off) {
     // An uncompressed 1-d, 2-d, or 3-d texture.
     image = PTA_uchar::empty_array(tex->get_expected_ram_mipmap_image_size(n));

+ 2 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -247,6 +247,7 @@ typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VPROC) (GLuint index, const GLuin
 typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VPROC) (GLuint index, GLenum pname, GLuint64EXT *params);
 typedef void *(APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
 typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data);
 #endif  // OPENGLES
 #endif  // __EDG__
 
@@ -801,6 +802,7 @@ public:
 #ifndef OPENGLES
   PFNGLMAPBUFFERPROC _glMapBuffer;
   PFNGLUNMAPBUFFERPROC _glUnmapBuffer;
+  PFNGLGETBUFFERSUBDATAPROC _glGetBufferSubData;
 #endif
 
 #ifdef OPENGLES

+ 2 - 2
panda/src/glstuff/glShaderContext_src.cxx

@@ -901,7 +901,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       bind._func = Shader::SMF_first;
       bind._part[0] = Shader::SMO_attr_material;
       bind._arg[0] = NULL;
-      bind._dep[0] = Shader::SSD_general | Shader::SSD_material;
+      bind._dep[0] = Shader::SSD_general | Shader::SSD_material | Shader::SSD_frame;
       bind._part[1] = Shader::SMO_identity;
       bind._arg[1] = NULL;
       bind._dep[1] = Shader::SSD_NONE;
@@ -2446,8 +2446,8 @@ update_shader_texture_bindings(ShaderContext *prev) {
         if (gtc != (TextureContext*)NULL) {
           input._gtc = gtc;
 
-          gl_tex = gtc->_index;
           _glgsg->update_texture(gtc, true);
+          gl_tex = gtc->_index;
 
           if (gtc->needs_barrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT)) {
             barriers |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;

+ 1 - 1
panda/src/gobj/shader.cxx

@@ -376,7 +376,7 @@ cp_dependency(ShaderMatInput inp) {
     return SSD_NONE;
   }
   if (inp == SMO_attr_material || inp == SMO_attr_material2) {
-    dep |= SSD_material;
+    dep |= SSD_material | SSD_frame;
   }
   if (inp == SMO_attr_color) {
     dep |= SSD_color;

+ 19 - 0
panda/src/gobj/texture.cxx

@@ -7411,6 +7411,9 @@ do_set_simple_ram_image(CData *cdata, CPTA_uchar image, int x_size, int y_size)
  */
 int Texture::
 do_get_expected_num_mipmap_levels(const CData *cdata) const {
+  if (cdata->_texture_type == Texture::TT_buffer_texture) {
+    return 1;
+  }
   int size = max(cdata->_x_size, cdata->_y_size);
   if (cdata->_texture_type == Texture::TT_3d_texture) {
     size = max(size, cdata->_z_size);
@@ -10126,6 +10129,14 @@ do_fillin_body(CData *cdata, DatagramIterator &scan, BamReader *manager) {
     cdata->_simple_image_date_generated = scan.get_int32();
 
     size_t u_size = scan.get_uint32();
+
+    // Protect against large allocation.
+    if (u_size > scan.get_remaining_size()) {
+      gobj_cat.error()
+        << "simple RAM image extends past end of datagram, is texture corrupt?\n";
+      return;
+    }
+
     PTA_uchar image = PTA_uchar::empty_array(u_size, get_class_type());
     scan.extract_bytes(image.p(), u_size);
 
@@ -10180,6 +10191,14 @@ do_fillin_rawdata(CData *cdata, DatagramIterator &scan, BamReader *manager) {
 
     // fill the cdata->_image buffer with image data
     size_t u_size = scan.get_uint32();
+
+    // Protect against large allocation.
+    if (u_size > scan.get_remaining_size()) {
+      gobj_cat.error()
+        << "RAM image " << n << " extends past end of datagram, is texture corrupt?\n";
+      return;
+    }
+
     PTA_uchar image = PTA_uchar::empty_array(u_size, get_class_type());
     scan.extract_bytes(image.p(), u_size);
 

+ 16 - 0
panda/src/vision/openCVTexture.cxx

@@ -21,6 +21,22 @@
 #include "bamReader.h"
 #include "bamCacheRecord.h"
 
+// This symbol is predefined by the Panda3D build system to select whether we
+// are using the OpenCV 2.3 or later interface, or if it is not defined, we
+// are using the original interface.
+#ifdef OPENCV_VER_23
+
+#include <opencv2/core/core.hpp>
+// #include <opencv2videovideo.hpp>
+#include <opencv2/highgui/highgui.hpp>
+
+#else
+#include <cv.h>
+#include <cxcore.h>
+#include <highgui.h>
+
+#endif  // OPENCV_VER_23
+
 TypeHandle OpenCVTexture::_type_handle;
 
 /**

+ 1 - 15
panda/src/vision/openCVTexture.h

@@ -19,21 +19,7 @@
 
 #include "videoTexture.h"
 
-// This symbol is predefined by the Panda3D build system to select whether we
-// are using the OpenCV 2.3 or later interface, or if it is not defined, we
-// are using the original interface.
-#ifdef OPENCV_VER_23
-
-#include <opencv2/core/core.hpp>
-// #include <opencv2videovideo.hpp>
-#include <opencv2/highgui/highgui.hpp>
-
-#else
-#include <cv.h>
-#include <cxcore.h>
-#include <highgui.h>
-
-#endif  // OPENCV_VER_23
+struct CvCapture;
 
 /**
  * A specialization on VideoTexture that takes its input using the CV library,

+ 13 - 65
panda/src/windisplay/winGraphicsPipe.cxx

@@ -47,15 +47,12 @@ typedef struct _PROCESSOR_POWER_INFORMATION {
 } PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
 
 typedef BOOL (WINAPI *GetProcessMemoryInfoType) (HANDLE Process, PROCESS_MEMORY_COUNTERS *ppsmemCounters, DWORD cb);
-typedef BOOL (WINAPI *GlobalMemoryStatusExType) (LPMEMORYSTATUSEX lpBuffer);
 typedef long (__stdcall *CallNtPowerInformationType) (POWER_INFORMATION_LEVEL information_level, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength);
 
 static int initialize = false;
 static HMODULE psapi_dll = 0;
-static HMODULE kernel32_dll = 0;
 static HMODULE power_dll = 0;
 static GetProcessMemoryInfoType GetProcessMemoryInfoFunction = 0;
-static GlobalMemoryStatusExType GlobalMemoryStatusExFunction = 0;
 static CallNtPowerInformationType CallNtPowerInformationFunction = 0;
 
 void get_memory_information (DisplayInformation *display_information) {
@@ -65,39 +62,19 @@ void get_memory_information (DisplayInformation *display_information) {
       GetProcessMemoryInfoFunction = (GetProcessMemoryInfoType) GetProcAddress(psapi_dll, "GetProcessMemoryInfo");
     }
 
-    kernel32_dll = LoadLibrary("kernel32.dll");
-    if (kernel32_dll) {
-      GlobalMemoryStatusExFunction = (GlobalMemoryStatusExType) GetProcAddress(kernel32_dll, "GlobalMemoryStatusEx");
-    }
-
     initialize = true;
   }
 
-  if (GlobalMemoryStatusExFunction) {
-    MEMORYSTATUSEX memory_status;
-
-    memory_status.dwLength = sizeof(MEMORYSTATUSEX);
-    if (GlobalMemoryStatusExFunction(&memory_status)) {
-      display_information->_physical_memory = memory_status.ullTotalPhys;
-      display_information->_available_physical_memory = memory_status.ullAvailPhys;
-      display_information->_page_file_size = memory_status.ullTotalPageFile;
-      display_information->_available_page_file_size = memory_status.ullAvailPageFile;
-      display_information->_process_virtual_memory = memory_status.ullTotalVirtual;
-      display_information->_available_process_virtual_memory = memory_status.ullAvailVirtual;
-      display_information->_memory_load = memory_status.dwMemoryLoad;
-    }
-  } else {
-    MEMORYSTATUS memory_status;
-
-    memory_status.dwLength = sizeof(MEMORYSTATUS);
-    GlobalMemoryStatus (&memory_status);
-
-    display_information->_physical_memory = memory_status.dwTotalPhys;
-    display_information->_available_physical_memory = memory_status.dwAvailPhys;
-    display_information->_page_file_size = memory_status.dwTotalPageFile;
-    display_information->_available_page_file_size = memory_status.dwAvailPageFile;
-    display_information->_process_virtual_memory = memory_status.dwTotalVirtual;
-    display_information->_available_process_virtual_memory = memory_status.dwAvailVirtual;
+  MEMORYSTATUSEX memory_status;
+
+  memory_status.dwLength = sizeof(MEMORYSTATUSEX);
+  if (GlobalMemoryStatusEx(&memory_status)) {
+    display_information->_physical_memory = memory_status.ullTotalPhys;
+    display_information->_available_physical_memory = memory_status.ullAvailPhys;
+    display_information->_page_file_size = memory_status.ullTotalPageFile;
+    display_information->_available_page_file_size = memory_status.ullAvailPageFile;
+    display_information->_process_virtual_memory = memory_status.ullTotalVirtual;
+    display_information->_available_process_virtual_memory = memory_status.ullAvailVirtual;
     display_information->_memory_load = memory_status.dwMemoryLoad;
   }
 
@@ -687,19 +664,12 @@ WinGraphicsPipe() {
 
   _supported_types = OT_window | OT_fullscreen_window;
 
-  // these fns arent defined on win95, so get dynamic ptrs to them to avoid
-  // ugly DLL loader failures on w95
-  _pfnTrackMouseEvent = NULL;
-
-  _hUser32 = (HINSTANCE)LoadLibrary("user32.dll");
-  if (_hUser32 != NULL) {
-    _pfnTrackMouseEvent =
-      (PFN_TRACKMOUSEEVENT)GetProcAddress(_hUser32, "TrackMouseEvent");
-
+  HMODULE user32 = GetModuleHandleA("user32.dll");
+  if (user32 != NULL) {
     if (dpi_aware) {
       typedef HRESULT (WINAPI *PFN_SETPROCESSDPIAWARENESS)(Process_DPI_Awareness);
       PFN_SETPROCESSDPIAWARENESS pfnSetProcessDpiAwareness =
-        (PFN_SETPROCESSDPIAWARENESS)GetProcAddress(_hUser32, "SetProcessDpiAwarenessInternal");
+        (PFN_SETPROCESSDPIAWARENESS)GetProcAddress(user32, "SetProcessDpiAwarenessInternal");
 
       if (pfnSetProcessDpiAwareness == NULL) {
         if (windisplay_cat.is_debug()) {
@@ -908,26 +878,4 @@ lookup_cpu_data() {
  */
 WinGraphicsPipe::
 ~WinGraphicsPipe() {
-  if (_hUser32 != NULL) {
-    FreeLibrary(_hUser32);
-    _hUser32 = NULL;
-  }
-}
-
-bool MyGetProcAddr(HINSTANCE hDLL, FARPROC *pFn, const char *szExportedFnName) {
-  *pFn = (FARPROC) GetProcAddress(hDLL, szExportedFnName);
-  if (*pFn == NULL) {
-    windisplay_cat.error() << "GetProcAddr failed for " << szExportedFnName << ", error=" << GetLastError() <<endl;
-    return false;
-  }
-  return true;
-}
-
-bool MyLoadLib(HINSTANCE &hDLL, const char *DLLname) {
-  hDLL = LoadLibrary(DLLname);
-  if(hDLL == NULL) {
-    windisplay_cat.error() << "LoadLibrary failed for " << DLLname << ", error=" << GetLastError() <<endl;
-    return false;
-  }
-  return true;
 }

+ 0 - 11
panda/src/windisplay/winGraphicsPipe.h

@@ -34,12 +34,6 @@ public:
 
   virtual void lookup_cpu_data();
 
-private:
-  HINSTANCE _hUser32;
-
-  typedef BOOL (WINAPI *PFN_TRACKMOUSEEVENT)(LPTRACKMOUSEEVENT);
-  PFN_TRACKMOUSEEVENT _pfnTrackMouseEvent;
-
 public:
   static TypeHandle get_class_type() {
     return _type_handle;
@@ -56,13 +50,8 @@ public:
 
 private:
   static TypeHandle _type_handle;
-
-  friend class WinGraphicsWindow;
 };
 
-extern EXPCL_PANDAWIN bool MyLoadLib(HINSTANCE &hDLL, const char *DLLname);
-extern EXPCL_PANDAWIN bool MyGetProcAddr(HINSTANCE hDLL, FARPROC *pFn, const char *szExportedFnName);
-
 #include "winGraphicsPipe.I"
 
 #endif

+ 76 - 86
panda/src/windisplay/winGraphicsWindow.cxx

@@ -29,6 +29,17 @@
 #define WM_DPICHANGED 0x02E0
 #endif
 
+#ifndef WM_TOUCH
+#define WM_TOUCH 0x0240
+#endif
+
+#if WINVER < 0x0601
+// Not used on Windows XP, but we still need to define it.
+#define TOUCH_COORD_TO_PIXEL(l) ((l) / 100)
+
+DECLARE_HANDLE(HTOUCHINPUT);
+#endif
+
 TypeHandle WinGraphicsWindow::_type_handle;
 TypeHandle WinGraphicsWindow::WinWindowHandle::_type_handle;
 
@@ -56,22 +67,15 @@ int WinGraphicsWindow::_window_class_index = 0;
 
 static const char * const errorbox_title = "Panda3D Error";
 
-// These static variables contain pointers to the Raw Input functions, which
+// These static variables contain pointers to the touch input functions, which
 // are dynamically extracted from USER32.DLL
+typedef WINUSERAPI BOOL (WINAPI *PFN_REGISTERTOUCHWINDOW)(IN HWND hWnd, IN ULONG ulFlags);
+typedef WINUSERAPI BOOL (WINAPI *PFN_GETTOUCHINPUTINFO)(IN HTOUCHINPUT hTouchInput, IN UINT cInputs, OUT PTOUCHINPUT pInputs, IN int cbSize);
+typedef WINUSERAPI BOOL (WINAPI *PFN_CLOSETOUCHINPUTHANDLE)(IN HTOUCHINPUT hTouchInput);
 
-typedef WINUSERAPI UINT (WINAPI *tGetRawInputDeviceList)
-  (OUT PRAWINPUTDEVICELIST pRawInputDeviceList, IN OUT PUINT puiNumDevices, IN UINT cbSize);
-typedef WINUSERAPI UINT(WINAPI *tGetRawInputData)
-  (IN HRAWINPUT hRawInput, IN UINT uiCommand, OUT LPVOID pData, IN OUT PUINT pcbSize, IN UINT cbSizeHeader);
-typedef WINUSERAPI UINT(WINAPI *tGetRawInputDeviceInfoA)
-  (IN HANDLE hDevice, IN UINT uiCommand, OUT LPVOID pData, IN OUT PUINT pcbSize);
-typedef WINUSERAPI BOOL (WINAPI *tRegisterRawInputDevices)
-  (IN PCRAWINPUTDEVICE pRawInputDevices, IN UINT uiNumDevices, IN UINT cbSize);
-
-static tGetRawInputDeviceList    pGetRawInputDeviceList;
-static tGetRawInputData          pGetRawInputData;
-static tGetRawInputDeviceInfoA   pGetRawInputDeviceInfoA;
-static tRegisterRawInputDevices  pRegisterRawInputDevices;
+static PFN_REGISTERTOUCHWINDOW pRegisterTouchWindow = 0;
+static PFN_GETTOUCHINPUTINFO pGetTouchInputInfo = 0;
+static PFN_CLOSETOUCHINPUTHANDLE pCloseTouchInputHandle = 0;
 
 /**
  *
@@ -100,9 +104,7 @@ WinGraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
   _lalt_down = false;
   _ralt_down = false;
   _hparent = NULL;
-#ifdef HAVE_WIN_TOUCHINPUT
-  _numTouches = 0;
-#endif
+  _num_touches = 0;
 }
 
 /**
@@ -512,13 +514,13 @@ open_window() {
   }
 
   // Registers to receive the WM_INPUT messages
-  if ((pRegisterRawInputDevices)&&(_input_devices.size() > 1)) {
+  if (_input_devices.size() > 1) {
     RAWINPUTDEVICE Rid;
     Rid.usUsagePage = 0x01;
     Rid.usUsage = 0x02;
     Rid.dwFlags = 0;// RIDEV_NOLEGACY;   // adds HID mouse and also ignores legacy mouse messages
     Rid.hwndTarget = _hWnd;
-    pRegisterRawInputDevices(&Rid, 1, sizeof (Rid));
+    RegisterRawInputDevices(&Rid, 1, sizeof (Rid));
   }
 
   // Create a WindowHandle for ourselves
@@ -535,10 +537,23 @@ open_window() {
   // set us as the focus window for keyboard input
   set_focus();
 
+  // Try initializing the touch function pointers.
+  static bool initialized = false;
+  if (!initialized) {
+    initialized = true;
+    HMODULE user32 = GetModuleHandleA("user32.dll");
+    if (user32) {
+      // Introduced in Windows 7.
+      pRegisterTouchWindow = (PFN_REGISTERTOUCHWINDOW)GetProcAddress(user32, "RegisterTouchWindow");
+      pGetTouchInputInfo = (PFN_GETTOUCHINPUTINFO)GetProcAddress(user32, "GetTouchInputInfo");
+      pCloseTouchInputHandle = (PFN_CLOSETOUCHINPUTHANDLE)GetProcAddress(user32, "CloseTouchInputHandle");
+    }
+  }
+
   // Register for Win7 touch events.
-#ifdef HAVE_WIN_TOUCHINPUT
-  RegisterTouchWindow(_hWnd, 0);
-#endif
+  if (pRegisterTouchWindow != NULL) {
+    pRegisterTouchWindow(_hWnd, 0);
+  }
 
   return true;
 }
@@ -563,45 +578,35 @@ initialize_input_devices() {
     GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
   add_input_device(device);
 
-  // Try initializing the Raw Input function pointers.
-  if (pRegisterRawInputDevices==0) {
-    HMODULE user32 = LoadLibrary("user32.dll");
-    if (user32) {
-      pRegisterRawInputDevices = (tRegisterRawInputDevices)GetProcAddress(user32,"RegisterRawInputDevices");
-      pGetRawInputDeviceList   = (tGetRawInputDeviceList)  GetProcAddress(user32,"GetRawInputDeviceList");
-      pGetRawInputDeviceInfoA  = (tGetRawInputDeviceInfoA) GetProcAddress(user32,"GetRawInputDeviceInfoA");
-      pGetRawInputData         = (tGetRawInputData)        GetProcAddress(user32,"GetRawInputData");
-    }
-  }
-
-  if (pRegisterRawInputDevices==0) return;
-  if (pGetRawInputDeviceList==0) return;
-  if (pGetRawInputDeviceInfoA==0) return;
-  if (pGetRawInputData==0) return;
-
   // Get the number of devices.
-  if (pGetRawInputDeviceList(NULL, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) != 0)
+  if (GetRawInputDeviceList(NULL, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) != 0) {
     return;
+  }
 
   // Allocate the array to hold the DeviceList
   pRawInputDeviceList = (PRAWINPUTDEVICELIST)alloca(sizeof(RAWINPUTDEVICELIST) * nInputDevices);
-  if (pRawInputDeviceList==0) return;
+  if (pRawInputDeviceList==0) {
+    return;
+  }
 
   // Fill the Array
-  if (pGetRawInputDeviceList(pRawInputDeviceList, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) == -1)
+  if (GetRawInputDeviceList(pRawInputDeviceList, &nInputDevices, sizeof(RAWINPUTDEVICELIST)) == -1) {
     return;
+  }
 
   // Loop through all raw devices and find the raw mice
   for (int i = 0; i < (int)nInputDevices; i++) {
     if (pRawInputDeviceList[i].dwType == RIM_TYPEMOUSE) {
       // Fetch information about specified mouse device.
       UINT nSize;
-      if (pGetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)0, &nSize) != 0)
+      if (GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)0, &nSize) != 0) {
         return;
+      }
       char *psName = (char*)alloca(sizeof(TCHAR) * nSize);
       if (psName == 0) return;
-      if (pGetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)psName, &nSize) < 0)
+      if (GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, (LPVOID)psName, &nSize) < 0) {
         return;
+      }
 
       // If it's not an RDP mouse, add it to the list of raw mice.
       if (strncmp(psName,"\\??\\Root#RDP_MOU#0000#",22)!=0) {
@@ -1215,31 +1220,25 @@ adjust_z_order(WindowProperties::ZOrder last_z_order,
  */
 void WinGraphicsWindow::
 track_mouse_leaving(HWND hwnd) {
-  // Note: could use _TrackMouseEvent in comctrl32.dll (part of IE 3.0+) which
-  // emulates TrackMouseEvent on w95, but that requires another 500K of memory
-  // to hold that DLL, which is lame just to support w95, which probably has
-  // other issues anyway
   WinGraphicsPipe *winpipe;
   DCAST_INTO_V(winpipe, _pipe);
 
-  if (winpipe->_pfnTrackMouseEvent != NULL) {
-    TRACKMOUSEEVENT tme = {
-      sizeof(TRACKMOUSEEVENT),
-      TME_LEAVE,
-      hwnd,
-      0
-    };
-
-    // tell win32 to post WM_MOUSELEAVE msgs
-    BOOL bSucceeded = winpipe->_pfnTrackMouseEvent(&tme);
+  TRACKMOUSEEVENT tme = {
+    sizeof(TRACKMOUSEEVENT),
+    TME_LEAVE,
+    hwnd,
+    0
+  };
 
-    if ((!bSucceeded) && windisplay_cat.is_debug()) {
-      windisplay_cat.debug()
-        << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl;
-    }
+  // tell win32 to post WM_MOUSELEAVE msgs
+  BOOL bSucceeded = TrackMouseEvent(&tme);
 
-    _tracking_mouse_leaving = true;
+  if (!bSucceeded && windisplay_cat.is_debug()) {
+    windisplay_cat.debug()
+      << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl;
   }
+
+  _tracking_mouse_leaving = true;
 }
 
 /**
@@ -2067,15 +2066,16 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
     }
     break;
 
-#ifdef HAVE_WIN_TOUCHINPUT
   case WM_TOUCH:
-        _numTouches = LOWORD(wparam);
-        if(_numTouches > MAX_TOUCHES)
-            _numTouches = MAX_TOUCHES;
-        GetTouchInputInfo((HTOUCHINPUT)lparam, _numTouches, _touches, sizeof(TOUCHINPUT));
-        CloseTouchInputHandle((HTOUCHINPUT)lparam);
+    _num_touches = LOWORD(wparam);
+    if (_num_touches > MAX_TOUCHES) {
+      _num_touches = MAX_TOUCHES;
+    }
+    if (pGetTouchInputInfo != 0) {
+      pGetTouchInputInfo((HTOUCHINPUT)lparam, _num_touches, _touches, sizeof(TOUCHINPUT));
+      pCloseTouchInputHandle((HTOUCHINPUT)lparam);
+    }
     break;
-#endif
   }
 
   // do custom messages processing if any has been set
@@ -2607,7 +2607,7 @@ handle_raw_input(HRAWINPUT hraw) {
   if (hraw == 0) {
     return;
   }
-  if (pGetRawInputData(hraw, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)) == -1) {
+  if (GetRawInputData(hraw, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)) == -1) {
     return;
   }
 
@@ -2616,7 +2616,7 @@ handle_raw_input(HRAWINPUT hraw) {
     return;
   }
 
-  if (pGetRawInputData(hraw, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) {
+  if (GetRawInputData(hraw, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) {
     return;
   }
 
@@ -2973,12 +2973,8 @@ bool WinGraphicsWindow::supports_window_procs() const{
  *
  */
 bool WinGraphicsWindow::
-is_touch_event(GraphicsWindowProcCallbackData* callbackData){
-#ifdef HAVE_WIN_TOUCHINPUT
+is_touch_event(GraphicsWindowProcCallbackData *callbackData) {
   return callbackData->get_msg() == WM_TOUCH;
-#else
-  return false;
-#endif
 }
 
 /**
@@ -2987,11 +2983,7 @@ is_touch_event(GraphicsWindowProcCallbackData* callbackData){
  */
 int WinGraphicsWindow::
 get_num_touches(){
-#ifdef HAVE_WIN_TOUCHINPUT
-  return _numTouches;
-#else
-  return 0;
-#endif
+  return _num_touches;
 }
 
 /**
@@ -2999,8 +2991,9 @@ get_num_touches(){
  *
  */
 TouchInfo WinGraphicsWindow::
-get_touch_info(int index){
-#ifdef HAVE_WIN_TOUCHINPUT
+get_touch_info(int index) {
+  nassertr(index >= 0 && index < MAX_TOUCHES, TouchInfo());
+
   TOUCHINPUT ti = _touches[index];
   POINT point;
   point.x = TOUCH_COORD_TO_PIXEL(ti.x);
@@ -3013,7 +3006,4 @@ get_touch_info(int index){
   ret.set_id(ti.dwID);
   ret.set_flags(ti.dwFlags);
   return ret;
-#else
-  return TouchInfo();
-#endif
 }

+ 18 - 5
panda/src/windisplay/winGraphicsWindow.h

@@ -34,8 +34,23 @@ typedef struct {
   int y;
   int width;
   int height;
-}
-WINDOW_METRICS;
+} WINDOW_METRICS;
+
+#if WINVER < 0x0601
+// Not used on Windows XP, but we still need to define it.
+typedef struct tagTOUCHINPUT {
+  LONG x;
+  LONG y;
+  HANDLE hSource;
+  DWORD dwID;
+  DWORD dwFlags;
+  DWORD dwMask;
+  DWORD dwTime;
+  ULONG_PTR dwExtraInfo;
+  DWORD cxContact;
+  DWORD cyContact;
+} TOUCHINPUT, *PTOUCHINPUT;
+#endif
 
 /**
  * An abstract base class for glGraphicsWindow and dxGraphicsWindow (and, in
@@ -177,10 +192,8 @@ private:
   typedef pset<GraphicsWindowProc*> WinProcClasses;
   WinProcClasses _window_proc_classes;
 
-#ifdef HAVE_WIN_TOUCHINPUT
-  UINT _numTouches;
+  UINT _num_touches;
   TOUCHINPUT _touches[MAX_TOUCHES];
-#endif
 
 private:
   // We need this map to support per-window calls to window_proc().