diff --git a/direct/src/showbase/PythonUtil.py b/direct/src/showbase/PythonUtil.py index ebf8bce63f..0c850f51a0 100644 --- a/direct/src/showbase/PythonUtil.py +++ b/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" diff --git a/doc/ReleaseNotes b/doc/ReleaseNotes index 157a20b2bf..b7462a97d6 100644 --- a/doc/ReleaseNotes +++ b/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 ------------------------ diff --git a/dtool/src/cppparser/cppFunctionType.cxx b/dtool/src/cppparser/cppFunctionType.cxx index 371b714c2d..1872ea11f5 100644 --- a/dtool/src/cppparser/cppFunctionType.cxx +++ b/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; } diff --git a/dtool/src/cppparser/cppFunctionType.h b/dtool/src/cppparser/cppFunctionType.h index f08de51e45..1e44681f13 100644 --- a/dtool/src/cppparser/cppFunctionType.h +++ b/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; diff --git a/dtool/src/cppparser/cppPreprocessor.cxx b/dtool/src/cppparser/cppPreprocessor.cxx index 5df779fc1d..83050d3c41 100644 --- a/dtool/src/cppparser/cppPreprocessor.cxx +++ b/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); + } + } } /** diff --git a/dtool/src/cppparser/cppPreprocessor.h b/dtool/src/cppparser/cppPreprocessor.h index 74ff8edcf1..e375b259dd 100644 --- a/dtool/src/cppparser/cppPreprocessor.h +++ b/dtool/src/cppparser/cppPreprocessor.h @@ -72,6 +72,9 @@ public: typedef map Manifests; Manifests _manifests; + typedef pvector ManifestStack; + map _manifest_stack; + pvector _quote_include_kind; DSearchPath _quote_include_path; DSearchPath _angle_include_path; diff --git a/dtool/src/cppparser/cppScope.cxx b/dtool/src/cppparser/cppScope.cxx index a340a5a709..a873cfa3cf 100644 --- a/dtool/src/cppparser/cppScope.cxx +++ b/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" diff --git a/dtool/src/cppparser/cppStructType.cxx b/dtool/src/cppparser/cppStructType.cxx index f33112d686..afb03dd463 100644 --- a/dtool/src/cppparser/cppStructType.cxx +++ b/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); diff --git a/dtool/src/cppparser/cppType.cxx b/dtool/src/cppparser/cppType.cxx index 780ebfc0ef..801c571add 100644 --- a/dtool/src/cppparser/cppType.cxx +++ b/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 diff --git a/makepanda/installer.nsi b/makepanda/installer.nsi index a1f364910d..d14cb44da9 100755 --- a/makepanda/installer.nsi +++ b/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" "" diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 2302e177a2..db99f4a483 100755 --- a/makepanda/makepanda.py +++ b/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 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) - 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") + #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() diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index 29ecf9f06d..2eb4342b06 100644 --- a/makepanda/makepandacore.py +++ b/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. diff --git a/panda/src/bullet/bulletBodyNode.cxx b/panda/src/bullet/bulletBodyNode.cxx index 6580c79722..cb4d39c444 100644 --- a/panda/src/bullet/bulletBodyNode.cxx +++ b/panda/src/bullet/bulletBodyNode.cxx @@ -45,7 +45,16 @@ BulletBodyNode(const BulletBodyNode ©) : _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(); diff --git a/panda/src/bullet/bulletGhostNode.cxx b/panda/src/bullet/bulletGhostNode.cxx index 8f8c783943..ddead41067 100644 --- a/panda/src/bullet/bulletGhostNode.cxx +++ b/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(); diff --git a/panda/src/bullet/bulletRigidBodyNode.I b/panda/src/bullet/bulletRigidBodyNode.I index 6be1af948f..de1d5eea05 100644 --- a/panda/src/bullet/bulletRigidBodyNode.I +++ b/panda/src/bullet/bulletRigidBodyNode.I @@ -18,7 +18,6 @@ INLINE BulletRigidBodyNode:: ~BulletRigidBodyNode() { delete _rigid; - delete _motion; } /** diff --git a/panda/src/bullet/bulletRigidBodyNode.cxx b/panda/src/bullet/bulletRigidBodyNode.cxx index 23c6d17afd..5c5e722785 100644 --- a/panda/src/bullet/bulletRigidBodyNode.cxx +++ b/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 ©) : - 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(); } /** diff --git a/panda/src/bullet/bulletRigidBodyNode.h b/panda/src/bullet/bulletRigidBodyNode.h index 42b2495aff..ea59c9202c 100644 --- a/panda/src/bullet/bulletRigidBodyNode.h +++ b/panda/src/bullet/bulletRigidBodyNode.h @@ -124,7 +124,7 @@ private: bool _was_dirty; }; - MotionState *_motion; + MotionState _motion; btRigidBody *_rigid; public: diff --git a/panda/src/display/frameBufferProperties.cxx b/panda/src/display/frameBufferProperties.cxx index 51120fbec1..98b8341322 100644 --- a/panda/src/display/frameBufferProperties.cxx +++ b/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 }, diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index ad532c5643..67fbdb2f6c 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/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() * diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index 8174105f39..c3c0ee0099 100644 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/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() < 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() <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)); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 3c93fcd174..fe8cff8b59 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/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 diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 3e1fe026f9..b02ec341df 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/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; diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index d9cf151e83..e067c18582 100644 --- a/panda/src/gobj/shader.cxx +++ b/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; diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index a3ce86c7dd..8fa7226806 100644 --- a/panda/src/gobj/texture.cxx +++ b/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); diff --git a/panda/src/vision/openCVTexture.cxx b/panda/src/vision/openCVTexture.cxx index 34c70284b1..7d09636b0c 100644 --- a/panda/src/vision/openCVTexture.cxx +++ b/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 +// #include +#include + +#else +#include +#include +#include + +#endif // OPENCV_VER_23 + TypeHandle OpenCVTexture::_type_handle; /** diff --git a/panda/src/vision/openCVTexture.h b/panda/src/vision/openCVTexture.h index ad898e51a8..1ad8e11a7a 100644 --- a/panda/src/vision/openCVTexture.h +++ b/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 -// #include -#include - -#else -#include -#include -#include - -#endif // OPENCV_VER_23 +struct CvCapture; /** * A specialization on VideoTexture that takes its input using the CV library, diff --git a/panda/src/windisplay/winGraphicsPipe.cxx b/panda/src/windisplay/winGraphicsPipe.cxx index 01d9ab4068..3d584de226 100644 --- a/panda/src/windisplay/winGraphicsPipe.cxx +++ b/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; + 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; + 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() < 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 - }; + TRACKMOUSEEVENT tme = { + sizeof(TRACKMOUSEEVENT), + TME_LEAVE, + hwnd, + 0 + }; - // tell win32 to post WM_MOUSELEAVE msgs - BOOL bSucceeded = winpipe->_pfnTrackMouseEvent(&tme); + // tell win32 to post WM_MOUSELEAVE msgs + BOOL bSucceeded = TrackMouseEvent(&tme); - if ((!bSucceeded) && windisplay_cat.is_debug()) { - windisplay_cat.debug() - << "TrackMouseEvent failed!, LastError=" << GetLastError() << endl; - } - - _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 } diff --git a/panda/src/windisplay/winGraphicsWindow.h b/panda/src/windisplay/winGraphicsWindow.h index 798218052a..ec7e1217ff 100644 --- a/panda/src/windisplay/winGraphicsWindow.h +++ b/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 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().