Browse Source

Merge branch 'master' into interrogate-overhaul

rdb 11 years ago
parent
commit
d43068b09a

+ 5 - 3
direct/src/directbase/ppython.cxx

@@ -7,6 +7,8 @@
 //
 //
 ///////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////
 
 
+#include "dtoolbase.h"
+
 #include <Python.h>
 #include <Python.h>
 #if PY_MAJOR_VERSION >= 3
 #if PY_MAJOR_VERSION >= 3
 #include <wchar.h>
 #include <wchar.h>
@@ -71,7 +73,7 @@ int main(int argc, char *argv[]) {
   char *path = getenv("PATH");
   char *path = getenv("PATH");
   char *result = strtok(path, ";");
   char *result = strtok(path, ";");
   while (result != NULL) {
   while (result != NULL) {
-    struct stat st;       
+    struct stat st;
     char *ppython = (char*) malloc(strlen(result) + 13);
     char *ppython = (char*) malloc(strlen(result) + 13);
     strcpy(ppython, result);
     strcpy(ppython, result);
     strcat(ppython, "\\ppython.exe");
     strcat(ppython, "\\ppython.exe");
@@ -79,13 +81,13 @@ int main(int argc, char *argv[]) {
       Py_SetPythonHome(result);
       Py_SetPythonHome(result);
       free(ppython);
       free(ppython);
       break;
       break;
-    }                                
+    }
     result = strtok(NULL, ";");
     result = strtok(NULL, ";");
     free(ppython);
     free(ppython);
   }
   }
 #endif
 #endif
 #endif
 #endif
-  
+
   Py_Initialize();
   Py_Initialize();
 
 
   if (Py_VerboseFlag) {
   if (Py_VerboseFlag) {

+ 5 - 7
direct/src/directscripts/eggcacher.py

@@ -9,15 +9,15 @@
 ##############################################################################
 ##############################################################################
 
 
 import os,sys,gc
 import os,sys,gc
-from pandac.PandaModules import *
+from panda3d.core import *
 
 
 class EggCacher:
 class EggCacher:
     def __init__(self, args):
     def __init__(self, args):
         maindir = Filename.fromOsSpecific(os.getcwd()).getFullpath()
         maindir = Filename.fromOsSpecific(os.getcwd()).getFullpath()
         ExecutionEnvironment.setEnvironmentVariable("MAIN_DIR", maindir)
         ExecutionEnvironment.setEnvironmentVariable("MAIN_DIR", maindir)
         self.bamcache = BamCache.getGlobalPtr()
         self.bamcache = BamCache.getGlobalPtr()
-        self.pandaloader = PandaLoader()
-        self.loaderopts = LoaderOptions()
+        self.pandaloader = Loader()
+        self.loaderopts = LoaderOptions(LoaderOptions.LF_no_ram_cache)
         if (self.bamcache.getActive() == 0):
         if (self.bamcache.getActive() == 0):
             print "The model cache is not currently active."
             print "The model cache is not currently active."
             print "You must set a model-cache-dir in your config file."
             print "You must set a model-cache-dir in your config file."
@@ -69,12 +69,12 @@ class EggCacher:
 
 
     def processFiles(self, files):
     def processFiles(self, files):
         total = 0
         total = 0
-        for (path,size) in files:
+        for (path, size) in files:
             total += size
             total += size
         progress = 0
         progress = 0
         for (path,size) in files:
         for (path,size) in files:
             fn = Filename.fromOsSpecific(path)
             fn = Filename.fromOsSpecific(path)
-            cached = self.bamcache.lookup(fn,"bam")
+            cached = self.bamcache.lookup(fn, "bam")
             percent = (progress * 100) / total
             percent = (progress * 100) / total
             report = path
             report = path
             if (self.concise): report = os.path.basename(report)
             if (self.concise): report = os.path.basename(report)
@@ -87,6 +87,4 @@ class EggCacher:
             TexturePool.releaseAllTextures()
             TexturePool.releaseAllTextures()
             progress += size
             progress += size
 
 
-
 cacher = EggCacher(sys.argv[1:])
 cacher = EggCacher(sys.argv[1:])
-

+ 1276 - 0
makepanda/installer.nsi

@@ -0,0 +1,1276 @@
+; Panda3D installation script for the Nullsoft Installation System (NSIS).
+; Jon Parise <[email protected]>
+; with Ben Johnson <[email protected]>
+; with Jason Pratt <[email protected]>
+; mangled by Josh Yelon <[email protected]>
+; Heavily restructured by rdb
+
+; Caller needs to define these variables:
+;
+;   COMPRESSOR    - either zlib or lzma
+;   TITLE         - title                         (eg. "Panda3D SDK 1.9.0")
+;   INSTALLDIR    - default install location      (eg. "C:\Panda3D-1.9.0-x64")
+;   OUTFILE       - where to put the output file  (eg. "..\nsis-output.exe")
+;
+;   BUILT         - location of panda install tree.
+;   SOURCE        - location of the panda source-tree if available, OR location of panda install tree.
+;   PYVER         - version of Python that Panda was built with (ie, "2.7")
+;   PYEXTRAS      - directory containing python extras, if any.
+;   REGVIEW       - either 32 or 64, depending on the build architecture.
+;
+
+Name "${TITLE}"
+InstallDir "${INSTALLDIR}"
+OutFile "${OUTFILE}"
+
+RequestExecutionLevel user
+
+SetCompress auto
+SetCompressor ${COMPRESSOR}
+
+!include "MUI2.nsh"
+!include "Sections.nsh"
+!include "WinMessages.nsh"
+!include "WordFunc.nsh"
+
+!define MUI_WELCOMEFINISHPAGE_BITMAP "panda-install.bmp"
+!define MUI_UNWELCOMEFINISHPAGE_BITMAP "panda-install.bmp"
+
+!define MUI_ABORTWARNING
+!define MUI_FINISHPAGE_NOREBOOTSUPPORT
+!define MUI_FINISHPAGE_RUN
+!define MUI_FINISHPAGE_RUN_FUNCTION runFunction
+!define MUI_FINISHPAGE_RUN_TEXT "Visit the Panda3D Manual"
+
+!insertmacro MUI_PAGE_WELCOME
+!insertmacro MUI_PAGE_LICENSE "../doc/LICENSE"
+!insertmacro MUI_PAGE_DIRECTORY
+
+!define MUI_PAGE_CUSTOMFUNCTION_LEAVE ConfirmPythonSelection
+!insertmacro MUI_PAGE_COMPONENTS
+
+!insertmacro MUI_PAGE_INSTFILES
+!insertmacro MUI_PAGE_FINISH
+
+!insertmacro MUI_UNPAGE_WELCOME
+!insertmacro MUI_UNPAGE_CONFIRM
+!insertmacro MUI_UNPAGE_INSTFILES
+!insertmacro MUI_UNPAGE_FINISH
+
+!insertmacro MUI_LANGUAGE "English"
+
+ShowInstDetails hide
+ShowUninstDetails hide
+
+LicenseData "${LICENSE}"
+
+InstType "Full (Recommended)"
+InstType "Minimal"
+
+LangString DESC_SecCore ${LANG_ENGLISH} "The Panda3D core libraries, configuration files and models/textures that are needed to use Panda3D."
+LangString DESC_SecOpenGL ${LANG_ENGLISH} "The OpenGL graphics back-end is the most well-supported renderer."
+LangString DESC_SecDirect3D9 ${LANG_ENGLISH} "The optional Direct3D 9 renderer."
+LangString DESC_SecOpenAL ${LANG_ENGLISH} "Support for playing audio via the OpenAL library.  You need either OpenAL or FMOD to be able to play audio."
+LangString DESC_SecFMOD ${LANG_ENGLISH} "Support for decoding and playing audio via the FMOD Ex library.  You need either OpenAL or FMOD to be able to play audio."
+LangString DESC_SecFFMpeg ${LANG_ENGLISH} "Support for decoding video and audio via the FFMpeg library.  Without this option, Panda3D will only be able to play .wav and .ogg audio files."
+LangString DESC_SecBullet ${LANG_ENGLISH} "Support for the Bullet physics engine."
+LangString DESC_SecODE ${LANG_ENGLISH} "Support for the Open Dynamics Engine to implement physics."
+LangString DESC_SecPhysX ${LANG_ENGLISH} "Support for NVIDIA PhysX to implement physics."
+LangString DESC_SecRocket ${LANG_ENGLISH} "Support for the libRocket GUI library.  This is an optional library that offers an HTML/CSS-like approach to creating user interfaces."
+LangString DESC_SecTools ${LANG_ENGLISH} "Useful tools and model converters to help with Panda3D development.  Recommended."
+LangString DESC_SecPyBindings ${LANG_ENGLISH} "Contains the Python modules that allow use of Panda3D using Python.  These will only work with a ${REGVIEW}-bit version of Python ${PYVER}."
+LangString DESC_SecPython ${LANG_ENGLISH} "Contains a ${REGVIEW}-bit copy of Python ${PYVER} preconfigured to make use of Panda3D."
+LangString DESC_SecHeadersLibs ${LANG_ENGLISH} "Headers and libraries needed for C++ development with Panda3D."
+LangString DESC_SecSamples ${LANG_ENGLISH} "The sample programs demonstrate how to make Python applications with Panda3D."
+LangString DESC_SecMaxPlugins ${LANG_ENGLISH} "Plug-ins for Autodesk 3ds Max (${REGVIEW}-bit) that can be used to export models to Panda3D."
+LangString DESC_SecMayaPlugins ${LANG_ENGLISH} "Plug-ins and scripts for Autodesk Maya (${REGVIEW}-bit) that can be used to export models to Panda3D."
+
+var READABLE
+var MANPAGE
+
+; See http://nsis.sourceforge.net/Check_if_a_file_exists_at_compile_time for documentation
+!macro !defineifexist _VAR_NAME _FILE_NAME
+    !tempfile _TEMPFILE
+    !ifdef NSIS_WIN32_MAKENSIS
+        ; Windows - cmd.exe
+        !system 'if exist "${_FILE_NAME}" echo !define ${_VAR_NAME} > "${_TEMPFILE}"'
+    !else
+        ; Posix - sh
+        !system 'if [ -e "${_FILE_NAME}" ]; then echo "!define ${_VAR_NAME}" > "${_TEMPFILE}"; fi'
+    !endif
+    !include '${_TEMPFILE}'
+    !delfile '${_TEMPFILE}'
+    !undef _TEMPFILE
+!macroend
+
+!insertmacro !defineifexist HAVE_GL "${BUILT}\bin\libpandagl.dll"
+!insertmacro !defineifexist HAVE_DX9 "${BUILT}\bin\libpandadx9.dll"
+!insertmacro !defineifexist HAVE_OPENAL "${BUILT}\bin\libp3openal_audio.dll"
+!insertmacro !defineifexist HAVE_FMOD "${BUILT}\bin\libp3fmod_audio.dll"
+!insertmacro !defineifexist HAVE_FFMPEG "${BUILT}\bin\libp3ffmpeg.dll"
+!insertmacro !defineifexist HAVE_BULLET "${BUILT}\bin\libpandabullet.dll"
+!insertmacro !defineifexist HAVE_ODE "${BUILT}\bin\libpandaode.dll"
+!insertmacro !defineifexist HAVE_PHYSX "${BUILT}\bin\libpandaphysx.dll"
+!insertmacro !defineifexist HAVE_ROCKET "${BUILT}\bin\libp3rocket.dll"
+!insertmacro !defineifexist HAVE_PYTHON "${BUILT}\python"
+!insertmacro !defineifexist HAVE_SAMPLES "${SOURCE}\samples"
+!insertmacro !defineifexist HAVE_MAX_PLUGINS "${BUILT}\plugins\*.dlo"
+!insertmacro !defineifexist HAVE_MAYA_PLUGINS "${BUILT}\plugins\*.mll"
+
+Function runFunction
+    ExecShell "open" "$SMPROGRAMS\${TITLE}\Panda3D Manual.lnk"
+FunctionEnd
+
+SectionGroup "Panda3D Libraries"
+    Section "Core Libraries" SecCore
+        SectionIn 1 2 RO
+
+        SetShellVarContext current
+        SetOverwrite try
+
+        SetDetailsPrint both
+        DetailPrint "Installing Panda3D libraries..."
+        SetDetailsPrint listonly
+
+        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 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\*"
+
+        SetDetailsPrint both
+        DetailPrint "Installing models..."
+        SetDetailsPrint listonly
+
+        SetOutPath $INSTDIR\models
+        File /r /x CVS "${BUILT}\models\*"
+
+        RMDir /r "$SMPROGRAMS\${TITLE}"
+        CreateDirectory "$SMPROGRAMS\${TITLE}"
+    SectionEnd
+
+    !ifdef HAVE_GL
+    Section "OpenGL" SecOpenGL
+        SectionIn 1 2 RO
+
+        SetOutPath "$INSTDIR\bin"
+        File "${BUILT}\bin\libpandagl.dll"
+    SectionEnd
+    !endif
+
+    !ifdef HAVE_DX9
+    Section "Direct3D 9" SecDirect3D9
+        SectionIn 1
+
+        SetOutPath "$INSTDIR\bin"
+        File "${BUILT}\bin\libpandadx9.dll"
+        File /nonfatal /r "${BUILT}\bin\cgD3D9.dll"
+    SectionEnd
+    !endif
+
+    !ifdef HAVE_OPENAL
+    Section "OpenAL Audio" SecOpenAL
+        SectionIn 1 2
+
+        SetOutPath "$INSTDIR\bin"
+        File "${BUILT}\bin\libp3openal_audio.dll"
+        File /nonfatal /r "${BUILT}\bin\OpenAL32.dll"
+        File /nonfatal /r "${BUILT}\bin\*_oal.dll"
+    SectionEnd
+    !endif
+
+    !ifdef HAVE_FMOD
+    Section "FMOD Audio" SecFMOD
+        SectionIn 1
+
+        SetOutPath "$INSTDIR\bin"
+        File "${BUILT}\bin\libp3fmod_audio.dll"
+        File /r "${BUILT}\bin\fmodex*.dll"
+    SectionEnd
+    !endif
+
+    !ifdef HAVE_FFMPEG
+    Section "FFMpeg" SecFFMpeg
+        SectionIn 1
+
+        SetOutPath "$INSTDIR\bin"
+        File "${BUILT}\bin\libp3ffmpeg.dll"
+        File /nonfatal /r "${BUILT}\bin\av*.dll"
+        File /nonfatal /r "${BUILT}\bin\swscale*.dll"
+        File /nonfatal /r "${BUILT}\bin\swresample*.dll"
+        File /nonfatal /r "${BUILT}\bin\postproc*.dll"
+    SectionEnd
+    !endif
+
+    !ifdef HAVE_BULLET
+    Section "Bullet Physics" SecBullet
+        SectionIn 1
+
+        SetOutPath "$INSTDIR\bin"
+        File "${BUILT}\bin\libpandabullet.dll"
+    SectionEnd
+    !endif
+
+    !ifdef HAVE_ODE
+    Section "ODE Physics" SecODE
+        SectionIn 1
+
+        SetOutPath "$INSTDIR\bin"
+        File "${BUILT}\bin\libpandaode.dll"
+    SectionEnd
+    !endif
+
+    !ifdef HAVE_ROCKET
+    Section "libRocket GUI" SecRocket
+        SectionIn 1
+
+        SetOutPath "$INSTDIR\bin"
+        File "${BUILT}\bin\libp3rocket.dll"
+        File /nonfatal /r "${BUILT}\bin\Rocket*.dll"
+        File /nonfatal /r "${BUILT}\bin\_rocket*.pyd"
+        File /nonfatal /r "${BUILT}\bin\boost_python*.dll"
+    SectionEnd
+    !endif
+SectionGroupEnd
+
+Section "Tools and utilities" SecTools
+    SectionIn 1 2
+
+    SetDetailsPrint both
+    DetailPrint "Installing utilities..."
+    SetDetailsPrint listonly
+
+    SetOutPath "$INSTDIR\bin"
+    File /r "${BUILT}\bin\*.exe"
+    File /nonfatal /r "${BUILT}\bin\*.p3d"
+    SetOutPath "$INSTDIR\NSIS"
+    File /r /x CVS "${NSISDIR}\*"
+SectionEnd
+
+SectionGroup "Python support"
+    Section "Python bindings" SecPyBindings
+        SectionIn 1 2
+
+        SetDetailsPrint both
+        DetailPrint "Installing Panda3D Python modules..."
+        SetDetailsPrint listonly
+
+        SetOutPath "$INSTDIR\bin"
+        File /nonfatal /r "${BUILT}\bin\*.pyd"
+
+        SetOutPath $INSTDIR\direct\directscripts
+        File /r /x CVS /x Opt?-Win32 "${BUILT}\direct\directscripts\*"
+        SetOutPath $INSTDIR\direct\filter
+        File /r /x CVS /x Opt?-Win32 "${BUILT}\direct\filter\*.sha"
+        SetOutPath $INSTDIR\direct
+        File /r /x CVS /x Opt?-Win32 "${BUILT}\direct\*.py"
+
+        Delete "$INSTDIR\panda3d.py"
+        Delete "$INSTDIR\panda3d.pyc"
+        Delete "$INSTDIR\panda3d.pyo"
+        SetOutPath $INSTDIR\pandac
+        File /r "${BUILT}\pandac\*.py"
+        SetOutPath $INSTDIR\panda3d
+        File /r "${BUILT}\panda3d\*.py"
+
+        File /r /x bullet.pyd /x ode.pyd /x physx.pyd /x rocket.pyd "${BUILT}\panda3d\*.pyd"
+
+        !ifdef HAVE_BULLET
+            SectionGetFlags ${SecBullet} $R0
+            IntOp $R0 $R0 & ${SF_SELECTED}
+            StrCmp $R0 ${SF_SELECTED} 0 SkipBulletPyd
+            File /nonfatal /r "${BUILT}\panda3d\bullet.pyd"
+            SkipBulletPyd:
+        !endif
+
+        !ifdef HAVE_ODE
+            SectionGetFlags ${SecODE} $R0
+            IntOp $R0 $R0 & ${SF_SELECTED}
+            StrCmp $R0 ${SF_SELECTED} 0 SkipODEPyd
+            File /nonfatal /r "${BUILT}\panda3d\ode.pyd"
+            SkipODEPyd:
+        !endif
+
+        !ifdef HAVE_PHYSX
+            SectionGetFlags ${SecPhysX} $R0
+            IntOp $R0 $R0 & ${SF_SELECTED}
+            StrCmp $R0 ${SF_SELECTED} 0 SkipPhysXPyd
+            File /nonfatal /r "${BUILT}\panda3d\physx.pyd"
+            SkipPhysXPyd:
+        !endif
+
+        !ifdef HAVE_ROCKET
+            SectionGetFlags ${SecRocket} $R0
+            IntOp $R0 $R0 & ${SF_SELECTED}
+            StrCmp $R0 ${SF_SELECTED} 0 SkipRocketPyd
+            File /nonfatal /r "${BUILT}\panda3d\rocket.pyd"
+            SkipRocketPyd:
+        !endif
+
+        SetOutPath $INSTDIR\pandac\input
+        File /r "${BUILT}\pandac\input\*"
+        SetOutPath $INSTDIR\Pmw
+        File /r /x CVS "${BUILT}\Pmw\*"
+
+        ; Check for a user installation of Python.
+        ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
+        StrCmp $0 "$INSTDIR\python" CheckSystemWidePython 0
+        StrCmp $0 "" CheckSystemWidePython 0
+        IfFileExists "$0\ppython.exe" CheckSystemWidePython 0
+        IfFileExists "$0\python.exe" AskExternalPth 0
+
+        ; Check for a system-wide Python installation.
+        CheckSystemWidePython:
+        ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
+        StrCmp $0 "$INSTDIR\python" SkipExternalPth 0
+        StrCmp $0 "" SkipExternalPth 0
+        IfFileExists "$0\ppython.exe" SkipExternalPth 0
+        IfFileExists "$0\python.exe" AskExternalPth SkipExternalPth
+
+        AskExternalPth:
+        MessageBox MB_YESNO|MB_ICONQUESTION \
+            "Your system already has a ${REGVIEW}-bit copy of Python ${PYVER} installed in:$\r$\n$0$\r$\nWould you like to configure it to be able to use the Panda3D libraries?$\r$\nIf you choose no, you will only be able to use Panda3D's own copy of Python." \
+            IDNO SkipExternalPth
+
+        FileOpen $1 "$0\Lib\site-packages\panda.pth" w
+        FileWrite $1 "$INSTDIR$\r$\n"
+        FileWrite $1 "$INSTDIR\bin$\r$\n"
+        FileClose $1
+        SkipExternalPth:
+    SectionEnd
+
+    !ifdef HAVE_PYTHON
+    Section "Python ${PYVER}" SecPython
+        SectionIn 1 2
+
+        !ifdef REGVIEW
+        SetRegView ${REGVIEW}
+        !endif
+
+        SetDetailsPrint both
+        DetailPrint "Installing Python ${PYVER} (${REGVIEW}-bit)..."
+        SetDetailsPrint listonly
+
+        SetOutPath "$INSTDIR\bin"
+        File /nonfatal "${BUILT}\bin\python*.dll"
+
+        SetOutPath "$INSTDIR\python"
+        File /r "${BUILT}\python\*"
+
+        !ifdef PYEXTRAS
+        SetOutPath "$INSTDIR\python\lib"
+        File /nonfatal /r "${PYEXTRAS}\*"
+        !endif
+
+        SetDetailsPrint both
+        DetailPrint "Adding registry keys for Python..."
+        SetDetailsPrint listonly
+
+        ; Check if a copy of Python is installed for this user.
+        ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
+        StrCmp "$0" "$INSTDIR\python" RegPath 0
+        StrCmp "$0" "" SkipFileCheck 0
+        IfFileExists "$0\python.exe" AskRegPath 0
+        SkipFileCheck:
+
+        ; Check if a system-wide copy of Python is installed.
+        ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
+        StrCmp "$0" "$INSTDIR\python" RegPath 0
+        StrCmp "$0" "" RegPath 0
+        IfFileExists "$0\python.exe" AskRegPath RegPath
+
+        AskRegPath:
+        MessageBox MB_YESNO|MB_ICONQUESTION \
+            "Your system already has a ${REGVIEW}-bit copy of Python ${PYVER} installed in:$\r$\n$0$\r$\n$\r$\nPanda3D installs its own copy of Python ${PYVER}, which will install alongside your existing copy.  Would you like to make Panda's copy the default Python for your user account?" \
+            IDNO SkipRegPath
+
+        RegPath:
+        WriteRegStr HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" "" "$INSTDIR\python"
+        SkipRegPath:
+
+    SectionEnd
+    !endif
+SectionGroupEnd
+
+Function ConfirmPythonSelection
+    ; Check the current state of the "Python" section selection.
+    SectionGetFlags ${SecPython} $R0
+    IntOp $R1 $R0 & ${SF_SELECTED}
+
+    ; Is the "Python" selection deselected?
+    StrCmp $R1 ${SF_SELECTED} SkipCheck 0
+
+    ; Maybe the user just doesn't want Python support at all?
+    SectionGetFlags ${SecPyBindings} $R1
+    IntOp $R1 $R1 & ${SF_SELECTED}
+    StrCmp $R1 ${SF_SELECTED} 0 SkipCheck
+
+    ; Check for a user installation of Python.
+    ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
+    StrCmp $0 "$INSTDIR\python" CheckSystemWidePython 0
+    StrCmp $0 "" CheckSystemWidePython 0
+    IfFileExists "$0\ppython.exe" CheckSystemWidePython 0
+    IfFileExists "$0\python.exe" SkipCheck CheckSystemWidePython
+
+    ; Check for a system-wide Python installation.
+    CheckSystemWidePython:
+    ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
+    StrCmp $0 "$INSTDIR\python" AskConfirmation 0
+    StrCmp $0 "" AskConfirmation 0
+    IfFileExists "$0\ppython.exe" AskConfirmation 0
+    IfFileExists "$0\python.exe" SkipCheck AskConfirmation
+
+    ; No compatible Python version found (that wasn't shipped as part
+    ; of a different Panda3D build.)  Ask the user if he's sure about this.
+    AskConfirmation:
+    MessageBox MB_YESNO|MB_ICONQUESTION \
+        "You do not appear to have a ${REGVIEW}-bit version of Python ${PYVER} installed that is compatible with Panda3D.  Are you sure you don't want Panda to install a compatible copy of Python?$\r$\n$\r$\nIf you choose Yes, you will not be able to do Python development with Panda3D until you install a ${REGVIEW}-bit version of Python ${PYVER} and manually configure it to be able to use Panda3D." \
+        IDYES SkipCheck
+
+    ; User clicked no, so re-enable the select box and abort.
+    IntOp $R0 $R0 | ${SF_SELECTED}
+    SectionSetFlags ${SecPython} $R0
+    Abort
+
+    SkipCheck:
+FunctionEnd
+
+Section "C++ support" SecHeadersLibs
+    SectionIn 1
+
+    SetDetailsPrint both
+    DetailPrint "Installing header files..."
+    SetDetailsPrint listonly
+
+    SetOutPath $INSTDIR\include
+    File /r /x *.exp "${BUILT}\include\*"
+
+    SetDetailsPrint both
+    DetailPrint "Installing library archives..."
+    SetDetailsPrint listonly
+
+    SetOutPath $INSTDIR\lib
+    File /r /x *.exp "${BUILT}\lib\*"
+SectionEnd
+
+!ifdef HAVE_SAMPLES
+Section "Sample programs" SecSamples
+    SectionIn 1
+
+    ; Necessary for proper start menu shortcut installation
+    SetShellVarContext current
+
+    SetDetailsPrint both
+    DetailPrint "Installing sample programs..."
+    SetDetailsPrint listonly
+
+    SetOutPath $INSTDIR\samples
+    File /nonfatal /r /x CVS "${SOURCE}\samples\*"
+
+    SetDetailsPrint both
+    DetailPrint "Creating shortcuts..."
+    SetDetailsPrint listonly
+
+    SetOutPath $INSTDIR
+    WriteINIStr $INSTDIR\Website.url "InternetShortcut" "URL" "https://www.panda3d.org/"
+    WriteINIStr $INSTDIR\Manual.url "InternetShortcut" "URL" "https://www.panda3d.org/manual/index.php"
+    WriteINIStr $INSTDIR\Samples.url "InternetShortcut" "URL" "https://www.panda3d.org/manual/index.php/Sample_Programs_in_the_Distribution"
+    SetOutPath $INSTDIR
+    CreateShortCut "$SMPROGRAMS\${TITLE}\Panda3D Manual.lnk" "$INSTDIR\Manual.url" "" "$INSTDIR\bin\eggcacher.exe" 0 "" "" "Panda3D Manual"
+    CreateShortCut "$SMPROGRAMS\${TITLE}\Panda3D Website.lnk" "$INSTDIR\Website.url" "" "$INSTDIR\bin\eggcacher.exe" 0 "" "" "Panda3D Website"
+    CreateShortCut "$SMPROGRAMS\${TITLE}\Sample Program Manual.lnk" "$INSTDIR\Samples.url" "" "$INSTDIR\bin\eggcacher.exe" 0 "" "" "Sample Program Manual"
+
+    FindFirst $0 $1 $INSTDIR\samples\*
+    loop:
+        StrCmp $1 "" done
+        StrCmp $1 "." next
+        StrCmp $1 ".." next
+        Push $1
+        Push "-"
+        Push " "
+        Call StrRep
+        Call Capitalize
+        Pop $R0
+        StrCpy $READABLE $R0
+        Push $1
+        Push "-"
+        Push "_"
+        Call StrRep
+        Pop $R0
+        StrCpy $MANPAGE $R0
+        DetailPrint "Creating shortcuts for sample program $READABLE"
+        CreateDirectory "$SMPROGRAMS\${TITLE}\Sample Programs\$READABLE"
+        SetOutPath $INSTDIR\samples\$1
+        WriteINIStr $INSTDIR\samples\$1\ManualPage.url "InternetShortcut" "URL" "http://panda3d.org/wiki/index.php/Sample_Programs:_$MANPAGE"
+        CreateShortCut "$SMPROGRAMS\${TITLE}\Sample Programs\$READABLE\Manual Page.lnk" "$INSTDIR\samples\$1\ManualPage.url" "" "$INSTDIR\bin\eggcacher.exe" 0 "" "" "Manual Entry on this Sample Program"
+        CreateShortCut "$SMPROGRAMS\${TITLE}\Sample Programs\$READABLE\View Source Code.lnk" "$INSTDIR\samples\$1"
+        FindFirst $2 $3 $INSTDIR\samples\$1\*.py
+        iloop:
+            StrCmp $3 "" idone
+            CreateShortCut "$SMPROGRAMS\${TITLE}\Sample Programs\$READABLE\Run $3.lnk" "$INSTDIR\python\python.exe" "-E $3" "$INSTDIR\bin\eggcacher.exe" 0 SW_SHOWMINIMIZED "" "Run $3"
+            CreateShortCut "$INSTDIR\samples\$1\Run $3.lnk" "$INSTDIR\python\python.exe" "-E $3" "$INSTDIR\bin\eggcacher.exe" 0 SW_SHOWMINIMIZED "" "Run $3"
+            FindNext $2 $3
+            goto iloop
+        idone:
+    next:
+        FindNext $0 $1
+        Goto loop
+    done:
+SectionEnd
+!endif
+
+!ifdef HAVE_MAX_PLUGINS
+Section "3ds Max plug-ins" SecMaxPlugins
+    SectionIn 1 3
+
+    SetDetailsPrint both
+    DetailPrint "Installing Autodesk 3ds Max plug-ins..."
+    SetDetailsPrint listonly
+
+    SetOutPath $INSTDIR\plugins
+    File /nonfatal /r "${BUILT}\plugins\*.dle"
+    File /nonfatal /r "${BUILT}\plugins\*.dlo"
+    File "${SOURCE}\doc\INSTALLING-PLUGINS.TXT"
+SectionEnd
+!endif
+
+!ifdef HAVE_MAYA_PLUGINS
+Section "Maya plug-ins" SecMayaPlugins
+    SectionIn 1 3
+
+    SetDetailsPrint both
+    DetailPrint "Installing Autodesk Maya plug-ins..."
+    SetDetailsPrint listonly
+
+    SetOutPath $INSTDIR\plugins
+    File /nonfatal /r "${BUILT}\plugins\*.mll"
+    File /nonfatal /r "${BUILT}\plugins\*.mel"
+    File /nonfatal /r "${BUILT}\plugins\*.ms"
+    File "${SOURCE}\doc\INSTALLING-PLUGINS.TXT"
+SectionEnd
+!endif
+
+Section -post
+    !ifdef REGVIEW
+    SetRegView ${REGVIEW}
+    !endif
+
+    ; Run eggcacher.  We can't do this in SecCore because we haven't
+    ; installed eggcacher at that point yet.
+    SetDetailsPrint both
+    DetailPrint "Preloading .egg files into the model cache..."
+    SetDetailsPrint listonly
+
+    ; We need to set the $PATH for eggcacher.
+    SetOutPath $INSTDIR
+    ReadEnvStr $R0 "PATH"
+    StrCpy $R0 "$INSTDIR\python;$INSTDIR\bin;$R0"
+    System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("PATH", R0).r2'
+
+    nsExec::ExecToLog '"$INSTDIR\bin\eggcacher.exe" --concise models samples'
+
+    SetDetailsPrint both
+    DetailPrint "Writing the uninstaller ..."
+    SetDetailsPrint listonly
+
+    Delete "$INSTDIR\uninst.exe"
+    WriteUninstaller "$INSTDIR\uninst.exe"
+    WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${TITLE}" "DisplayName" "${TITLE}"
+    WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${TITLE}" "UninstallString" '"$INSTDIR\uninst.exe"'
+    SetOutPath $INSTDIR
+    CreateShortcut "$SMPROGRAMS\${TITLE}\Uninstall ${TITLE}.lnk" "$INSTDIR\uninst.exe" ""
+
+    SetDetailsPrint both
+    DetailPrint "Adding directories to system PATH..."
+    SetDetailsPrint listonly
+
+    # Add the "bin" directory to the PATH.
+    Push "$INSTDIR\python"
+    Call RemoveFromPath
+    Push "$INSTDIR\python\Scripts"
+    Call RemoveFromPath
+    Push "$INSTDIR\bin"
+    Call RemoveFromPath
+    Push "$INSTDIR\python"
+    Call AddToPath
+    Push "$INSTDIR\python\Scripts"
+    Call AddToPath
+    Push "$INSTDIR\bin"
+    Call AddToPath
+
+    # This is needed for the environment variable changes to take effect.
+    DetailPrint "Broadcasting WM_WININICHANGE message..."
+    SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=500
+
+SectionEnd
+
+Section Uninstall
+    SetDetailsPrint listonly
+
+    SetShellVarContext current
+    !ifdef REGVIEW
+    SetRegView ${REGVIEW}
+    !endif
+
+    SetDetailsPrint both
+    DetailPrint "Removing registry entries..."
+    SetDetailsPrint listonly
+
+    DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${TITLE}"
+    DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\${TITLE}"
+
+    ReadRegStr $0 HKLM "Software\Python\PythonCore\${PYVER}\InstallPath" ""
+    StrCmp $0 "$INSTDIR\python" 0 SkipUnRegHKLM
+    DeleteRegKey HKLM "Software\Python\PythonCore\${PYVER}"
+    SkipUnRegHKLM:
+
+    ReadRegStr $0 HKCU "Software\Python\PythonCore\${PYVER}\InstallPath" ""
+    StrCmp $0 "$INSTDIR\python" 0 SkipUnRegHKCU
+    DeleteRegKey HKCU "Software\Python\PythonCore\${PYVER}"
+    SkipUnRegHKCU:
+
+    SetDetailsPrint both
+    DetailPrint "Deleting files..."
+    SetDetailsPrint listonly
+
+    Delete "$INSTDIR\uninst.exe"
+    RMDir /r "$INSTDIR"
+
+    SetDetailsPrint both
+    DetailPrint "Removing Start Menu entries..."
+    SetDetailsPrint listonly
+
+    SetShellVarContext current
+    RMDir /r "$SMPROGRAMS\${TITLE}"
+    SetShellVarContext all
+    RMDir /r "$SMPROGRAMS\${TITLE}"
+
+    SetDetailsPrint both
+    DetailPrint "Removing entries from PATH..."
+    SetDetailsPrint listonly
+
+    Push "$INSTDIR\python"
+    Call un.RemoveFromPath
+    Push "$INSTDIR\python\Scripts"
+    Call un.RemoveFromPath
+    Push "$INSTDIR\bin"
+    Call un.RemoveFromPath
+
+    # This is needed for the environment variable changes to take effect.
+    DetailPrint "Broadcasting WM_WININICHANGE message..."
+    SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=500
+
+SectionEnd
+
+!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
+  !insertmacro MUI_DESCRIPTION_TEXT ${SecCore} $(DESC_SecCore)
+  !ifdef HAVE_GL
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenGL} $(DESC_SecOpenGL)
+  !endif
+  !ifdef HAVE_DX9
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecDirect3D9} $(DESC_SecDirect3D9)
+  !endif
+  !ifdef HAVE_OPENAL
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenAL} $(DESC_SecOpenAL)
+  !endif
+  !ifdef HAVE_FMOD
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecFMOD} $(DESC_SecFMOD)
+  !endif
+  !ifdef HAVE_FFMPEG
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecFFMpeg} $(DESC_SecFFMpeg)
+  !endif
+  !ifdef HAVE_BULLET
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecBullet} $(DESC_SecBullet)
+  !endif
+  !ifdef HAVE_ODE
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecODE} $(DESC_SecODE)
+  !endif
+  !ifdef HAVE_PHYSX
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecPhysX} $(DESC_SecPhysX)
+  !endif
+  !ifdef HAVE_ROCKET
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecRocket} $(DESC_SecRocket)
+  !endif
+  !insertmacro MUI_DESCRIPTION_TEXT ${SecTools} $(DESC_SecTools)
+  !insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings} $(DESC_SecPyBindings)
+  !insertmacro MUI_DESCRIPTION_TEXT ${SecPython} $(DESC_SecPython)
+  !insertmacro MUI_DESCRIPTION_TEXT ${SecHeadersLibs} $(DESC_SecHeadersLibs)
+  !insertmacro MUI_DESCRIPTION_TEXT ${SecSamples} $(DESC_SecSamples)
+  !ifdef HAVE_MAX_PLUGINS
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecMaxPlugins} $(DESC_SecMaxPlugins)
+  !endif
+  !ifdef HAVE_MAYA_PLUGINS
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecMayaPlugins} $(DESC_SecMayaPlugins)
+  !endif
+!insertmacro MUI_FUNCTION_DESCRIPTION_END
+
+# --[ Utility Functions ]------------------------------------------------------
+
+; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
+Function IsNT
+        Push $0
+        ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
+        StrCmp $0 "" 0 IsNT_yes
+        ; we are not NT.
+        Pop $0
+        Push 0
+        Return
+        IsNT_yes:
+                ; NT!!!
+                Pop $0
+                Push 1
+FunctionEnd
+
+; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
+Function un.IsNT
+        Push $0
+        ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
+        StrCmp $0 "" 0 unIsNT_yes
+        ; we are not NT.
+        Pop $0
+        Push 0
+        Return
+        unIsNT_yes:
+                ; NT!!!
+                Pop $0
+                Push 1
+FunctionEnd
+
+; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
+Function StrStr
+        Push $0
+        Exch
+        Pop $0 ; $0 now have the string to find
+        Push $1
+        Exch 2
+        Pop $1 ; $1 now have the string to find in
+        Exch
+        Push $2
+        Push $3
+        Push $4
+        Push $5
+        StrCpy $2 -1
+        StrLen $3 $0
+        StrLen $4 $1
+        IntOp $4 $4 - $3
+        unStrStr_loop:
+                IntOp $2 $2 + 1
+                IntCmp $2 $4 0 0 unStrStrReturn_notFound
+                StrCpy $5 $1 $3 $2
+                StrCmp $5 $0 unStrStr_done unStrStr_loop
+        unStrStrReturn_notFound:
+                StrCpy $2 -1
+        unStrStr_done:
+                Pop $5
+                Pop $4
+                Pop $3
+                Exch $2
+                Exch 2
+                Pop $0
+                Pop $1
+FunctionEnd
+
+; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
+Function un.StrStr
+        Push $0
+        Exch
+        Pop $0 ; $0 now have the string to find
+        Push $1
+        Exch 2
+        Pop $1 ; $1 now have the string to find in
+        Exch
+        Push $2
+        Push $3
+        Push $4
+        Push $5
+        StrCpy $2 -1
+        StrLen $3 $0
+        StrLen $4 $1
+        IntOp $4 $4 - $3
+        unStrStr_loop:
+                IntOp $2 $2 + 1
+                IntCmp $2 $4 0 0 unStrStrReturn_notFound
+                StrCpy $5 $1 $3 $2
+                StrCmp $5 $0 unStrStr_done unStrStr_loop
+        unStrStrReturn_notFound:
+                StrCpy $2 -1
+        unStrStr_done:
+                Pop $5
+                Pop $4
+                Pop $3
+                Exch $2
+                Exch 2
+                Pop $0
+                Pop $1
+FunctionEnd
+
+; Capitalizes the first letter of every word.
+Function Capitalize
+        Exch $R0
+        Push $0
+        Push $1
+        Push $2
+
+        StrCpy $0 0
+
+        capNext:
+        ; Grab the next character.
+        StrCpy $1 $R0 1 $0
+        StrCmp $1 '' end
+
+        ; Capitalize it.
+        ${StrFilter} '$1' '+eng' '' '' $1
+        ${StrFilter} '$1' '+rus' '' '' $1
+
+        ; Splice it into the string.
+        StrCpy $2 $R0 $0
+        IntOp $0 $0 + 1
+        StrCpy $R0 $R0 '' $0
+        StrCpy $R0 '$2$1$R0'
+
+        ; Keep looping through the characters until we find a
+        ; delimiter or reach the end of the string.
+        loop:
+        StrCpy $1 $R0 1 $0
+        IntOp $0 $0 + 1
+        StrCmp $1 '' end
+        StrCmp $1 ' ' capNext
+        StrCmp $1 '_' capNext
+        StrCmp $1 '-' capNext
+        StrCmp $1 '(' capNext
+        StrCmp $1 '[' capNext
+        Goto loop
+
+        end:
+        Pop $2
+        Pop $1
+        Pop $0
+        Exch $R0
+FunctionEnd
+
+; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
+; Commentary and smarter ';' checking by Jon Parise <[email protected]>
+Function AddToPath
+        Exch $0
+        Push $1
+        Push $2
+        Push $3
+        Call IsNT
+        Pop $1
+
+        DetailPrint "Adding to PATH: $0"
+
+        StrCmp $1 1 AddToPath_NT
+                ; We're not on NT, so modify the AUTOEXEC.BAT file.
+                StrCpy $1 $WINDIR 2
+                FileOpen $1 "$1\autoexec.bat" a
+                FileSeek $1 0 END
+                GetFullPathName /SHORT $0 $0
+                FileWrite $1 "$\r$\nSET PATH=%PATH%;$0$\r$\n"
+                FileClose $1
+                Goto AddToPath_done
+
+        AddToPath_NT:
+                ReadRegStr $1 HKCU "Environment" "PATH"
+                Call IsUserAdmin
+                Pop $3
+                ; If this is an Admin user, use the System env. variable instead of the user's env. variable
+                StrCmp $3 1 0 +2
+                        ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
+
+                ; If the PATH string is empty, jump over the mangling routines.
+                StrCmp $1 "" AddToPath_NTdoIt
+
+                ; Pull off the last character of the PATH string.  If it's a semicolon,
+                ; we don't need to add another one, so jump to the section where we
+                ; append the new PATH component(s).
+                StrCpy $2 $1 1 -1
+                StrCmp $2 ";" AddToPath_NTAddPath AddToPath_NTAddSemi
+
+                AddToPath_NTAddSemi:
+                        StrCpy $1 "$1;"
+                        Goto AddToPath_NTAddPath
+                AddToPath_NTAddPath:
+                        StrCpy $0 "$1$0"
+                        Goto AddToPath_NTdoIt
+                AddToPath_NTdoIt:
+                        Call IsUserAdmin
+                        Pop $3
+                        StrCmp $3 1 0 NotAdmin
+                                WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $0
+                                Goto AddToPath_done
+
+                        NotAdmin:
+                                WriteRegExpandStr HKCU "Environment" "PATH" $0
+        AddToPath_done:
+                Pop $3
+                Pop $2
+                Pop $1
+                Pop $0
+FunctionEnd
+
+; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
+Function RemoveFromPath
+        Exch $0
+        Push $1
+        Push $2
+        Push $3
+        Push $4
+        Push $5
+        Call IsNT
+        Pop $1
+
+        DetailPrint "Removing from PATH: $0"
+
+        StrCmp $1 1 unRemoveFromPath_NT
+                ; Not on NT
+                StrCpy $1 $WINDIR 2
+                FileOpen $1 "$1\autoexec.bat" r
+                GetTempFileName $4
+                FileOpen $2 $4 w
+                GetFullPathName /SHORT $0 $0
+                StrCpy $0 "SET PATH=%PATH%;$0"
+                SetRebootFlag true
+                Goto unRemoveFromPath_dosLoop
+
+                unRemoveFromPath_dosLoop:
+                        FileRead $1 $3
+                        StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoop
+                        StrCmp $3 "$0$\n" unRemoveFromPath_dosLoop
+                        StrCmp $3 "$0" unRemoveFromPath_dosLoop
+                        StrCmp $3 "" unRemoveFromPath_dosLoopEnd
+                        FileWrite $2 $3
+                        Goto unRemoveFromPath_dosLoop
+
+                unRemoveFromPath_dosLoopEnd:
+                        FileClose $2
+                        FileClose $1
+                        StrCpy $1 $WINDIR 2
+                        Delete "$1\autoexec.bat"
+                        CopyFiles /SILENT $4 "$1\autoexec.bat"
+                        Delete $4
+                        Goto unRemoveFromPath_done
+
+                unRemoveFromPath_NT:
+                        StrLen $2 $0
+                        Call IsUserAdmin
+                        Pop $5
+                        StrCmp $5 1 0 NotAdmin
+                                ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
+                                Push $1
+                                Push $0
+                                Call StrStr ; Find $0 in $1
+                                Pop $0 ; pos of our dir
+                                IntCmp $0 -1 unRemoveFromPath_done
+                                        ; else, it is in path
+                                        StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
+                                        IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
+                                        IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
+                                        StrLen $0 $1
+                                        StrCpy $1 $1 $0 $2
+                                        StrCpy $3 "$3$1"
+                                        WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3
+                                        Goto unRemoveFromPath_done
+
+
+                        NotAdmin:
+                                ReadRegStr $1 HKCU "Environment" "PATH"
+                                Push $1
+                                Push $0
+                                Call StrStr ; Find $0 in $1
+                                Pop $0 ; pos of our dir
+                                IntCmp $0 -1 unRemoveFromPath_done
+                                        ; else, it is in path
+                                        StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
+                                        IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
+                                        IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
+                                        StrLen $0 $1
+                                        StrCpy $1 $1 $0 $2
+                                        StrCpy $3 "$3$1"
+                                        WriteRegExpandStr HKCU "Environment" "PATH" $3
+
+                unRemoveFromPath_done:
+                        Pop $5
+                        Pop $4
+                        Pop $3
+                        Pop $2
+                        Pop $1
+                        Pop $0
+FunctionEnd
+
+; From: http://nsis.sourceforge.net/archive/viewpage.php?pageid=91
+Function un.RemoveFromPath
+        Exch $0
+        Push $1
+        Push $2
+        Push $3
+        Push $4
+        Push $5
+        Call un.IsNT
+        Pop $1
+        StrCmp $1 1 unRemoveFromPath_NT
+                ; Not on NT
+                StrCpy $1 $WINDIR 2
+                FileOpen $1 "$1\autoexec.bat" r
+                GetTempFileName $4
+                FileOpen $2 $4 w
+                GetFullPathName /SHORT $0 $0
+                StrCpy $0 "SET PATH=%PATH%;$0"
+                SetRebootFlag true
+                Goto unRemoveFromPath_dosLoop
+
+                unRemoveFromPath_dosLoop:
+                        FileRead $1 $3
+                        StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoop
+                        StrCmp $3 "$0$\n" unRemoveFromPath_dosLoop
+                        StrCmp $3 "$0" unRemoveFromPath_dosLoop
+                        StrCmp $3 "" unRemoveFromPath_dosLoopEnd
+                        FileWrite $2 $3
+                        Goto unRemoveFromPath_dosLoop
+
+                unRemoveFromPath_dosLoopEnd:
+                        FileClose $2
+                        FileClose $1
+                        StrCpy $1 $WINDIR 2
+                        Delete "$1\autoexec.bat"
+                        CopyFiles /SILENT $4 "$1\autoexec.bat"
+                        Delete $4
+                        Goto unRemoveFromPath_done
+
+                unRemoveFromPath_NT:
+                        StrLen $2 $0
+                        Call un.IsUserAdmin
+                        Pop $5
+                        StrCmp $5 1 0 NotAdmin
+                                ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
+                                Push $1
+                                Push $0
+                                Call un.StrStr ; Find $0 in $1
+                                Pop $0 ; pos of our dir
+                                IntCmp $0 -1 unRemoveFromPath_done
+                                        ; else, it is in path
+                                        StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
+                                        IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
+                                        IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
+                                        StrLen $0 $1
+                                        StrCpy $1 $1 $0 $2
+                                        StrCpy $3 "$3$1"
+                                        WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3
+                                        Goto unRemoveFromPath_done
+
+
+                        NotAdmin:
+                                ReadRegStr $1 HKCU "Environment" "PATH"
+                                Push $1
+                                Push $0
+                                Call un.StrStr ; Find $0 in $1
+                                Pop $0 ; pos of our dir
+                                IntCmp $0 -1 unRemoveFromPath_done
+                                        ; else, it is in path
+                                        StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
+                                        IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
+                                        IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
+                                        StrLen $0 $1
+                                        StrCpy $1 $1 $0 $2
+                                        StrCpy $3 "$3$1"
+                                        WriteRegExpandStr HKCU "Environment" "PATH" $3
+
+                unRemoveFromPath_done:
+                        Pop $5
+                        Pop $4
+                        Pop $3
+                        Pop $2
+                        Pop $1
+                        Pop $0
+FunctionEnd
+
+; From: http://nsis.sourceforge.net/archive/nsisweb.php?page=329&instances=0,11
+; Localized by Ben Johnson ([email protected])
+Function IsUserAdmin
+        Push $0
+        Push $1
+        Push $2
+        Push $3
+        Call IsNT
+        Pop $1
+
+        ClearErrors
+        UserInfo::GetName
+        ;IfErrors Win9x
+        Pop $2
+        UserInfo::GetAccountType
+        Pop $3
+
+        ; Compare results of IsNT with "1"
+        StrCmp $1 1 0 NotNT
+                ;This is NT
+
+
+                StrCmp $3 "Admin" 0 NotAdmin
+                        ; Observation: I get here when running Win98SE. (Lilla)
+                        ; The functions UserInfo.dll looks for are there on Win98 too,
+                        ; but just don't work. So UserInfo.dll, knowing that admin isn't required
+                        ; on Win98, returns admin anyway. (per kichik)
+                        ; MessageBox MB_OK 'User "$R1" is in the Administrators group'
+                        Pop $3
+                        Pop $2
+                        Pop $1
+                        Pop $0
+
+                        Push 1
+                        Return
+
+                NotAdmin:
+                        ; You should still check for an empty string because the functions
+                        ; UserInfo.dll looks for may not be present on Windows 95. (per kichik)
+
+                        #StrCmp $2 "" Win9x
+                        #StrCpy $0 0
+                        ;MessageBox MB_OK 'User "$2" is in the "$3" group'
+                        Pop $3
+                        Pop $2
+                        Pop $1
+                        Pop $0
+
+                        Push 0
+                        Return
+
+        ;Because we use IsNT, this is redundant.
+        #Win9x:
+        #       ; comment/message below is by UserInfo.nsi author:
+        #       ; This one means you don't need to care about admin or
+        #       ; not admin because Windows 9x doesn't either
+        #       ;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!"
+        #       StrCpy $0 0
+
+        NotNT:
+                ;We are not NT
+                ;Win9x doesn't have "admin" users.
+                ;Let the user do whatever.
+                Pop $3
+                Pop $2
+                Pop $1
+                Pop $0
+
+                Push 1
+
+FunctionEnd
+
+Function un.IsUserAdmin
+        Push $0
+        Push $1
+        Push $2
+        Push $3
+        Call un.IsNT
+        Pop $1
+
+        ClearErrors
+        UserInfo::GetName
+        ;IfErrors Win9x
+        Pop $2
+        UserInfo::GetAccountType
+        Pop $3
+
+        ; Compare results of IsNT with "1"
+        StrCmp $1 1 0 NotNT
+                ;This is NT
+
+
+                StrCmp $3 "Admin" 0 NotAdmin
+                        ; Observation: I get here when running Win98SE. (Lilla)
+                        ; The functions UserInfo.dll looks for are there on Win98 too,
+                        ; but just don't work. So UserInfo.dll, knowing that admin isn't required
+                        ; on Win98, returns admin anyway. (per kichik)
+                        ; MessageBox MB_OK 'User "$R1" is in the Administrators group'
+                        Pop $3
+                        Pop $2
+                        Pop $1
+                        Pop $0
+
+                        Push 1
+                        Return
+
+                NotAdmin:
+                        ; You should still check for an empty string because the functions
+                        ; UserInfo.dll looks for may not be present on Windows 95. (per kichik)
+
+                        #StrCmp $2 "" Win9x
+                        #StrCpy $0 0
+                        ;MessageBox MB_OK 'User "$2" is in the "$3" group'
+                        Pop $3
+                        Pop $2
+                        Pop $1
+                        Pop $0
+
+                        Push 0
+                        Return
+
+        ;Because we use IsNT, this is redundant.
+        #Win9x:
+        #       ; comment/message below is by UserInfo.nsi author:
+        #       ; This one means you don't need to care about admin or
+        #       ; not admin because Windows 9x doesn't either
+        #       ;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!"
+        #       StrCpy $0 0
+
+        NotNT:
+                ;We are not NT
+                ;Win9x doesn't have "admin" users.
+                ;Let the user do whatever.
+                Pop $3
+                Pop $2
+                Pop $1
+                Pop $0
+
+                Push 1
+
+FunctionEnd
+
+Function StrRep
+
+  ;Written by dirtydingus 2003-02-20 04:30:09
+  ; USAGE
+  ;Push String to do replacement in (haystack)
+  ;Push String to replace (needle)
+  ;Push Replacement
+  ;Call StrRep
+  ;Pop $R0 result
+  ;StrCpy $Result STR $R0
+
+  Exch $R4 ; $R4 = Replacement String
+  Exch
+  Exch $R3 ; $R3 = String to replace (needle)
+  Exch 2
+  Exch $R1 ; $R1 = String to do replacement in (haystack)
+  Push $R2 ; Replaced haystack
+  Push $R5 ; Len (needle)
+  Push $R6 ; len (haystack)
+  Push $R7 ; Scratch reg
+  StrCpy $R2 ""
+  StrLen $R5 $R3
+  StrLen $R6 $R1
+loop:
+  StrCpy $R7 $R1 $R5
+  StrCmp $R7 $R3 found
+  StrCpy $R7 $R1 1 ; - optimization can be removed if U know len needle=1
+  StrCpy $R2 "$R2$R7"
+  StrCpy $R1 $R1 $R6 1
+  StrCmp $R1 "" done loop
+found:
+  StrCpy $R2 "$R2$R4"
+  StrCpy $R1 $R1 $R6 $R5
+  StrCmp $R1 "" done loop
+done:
+  StrCpy $R3 $R2
+  Pop $R7
+  Pop $R6
+  Pop $R5
+  Pop $R2
+  Pop $R1
+  Pop $R4
+  Exch $R3
+
+FunctionEnd

+ 10 - 16
makepanda/makepanda.py

@@ -6171,7 +6171,7 @@ except:
 #
 #
 ##########################################################################################
 ##########################################################################################
 
 
-def MakeInstallerNSIS(file, fullname, smdirectory, installdir):
+def MakeInstallerNSIS(file, title, installdir):
     if (os.path.isfile(file)):
     if (os.path.isfile(file)):
         os.remove(file)
         os.remove(file)
     elif (os.path.isdir(file)):
     elif (os.path.isdir(file)):
@@ -6199,7 +6199,7 @@ def MakeInstallerNSIS(file, fullname, smdirectory, installdir):
         shutil.move("direct\\src\\plugin_installer\\p3d-setup.exe", file)
         shutil.move("direct\\src\\plugin_installer\\p3d-setup.exe", file)
         return
         return
 
 
-    print("Building "+fullname+" installer. This can take up to an hour.")
+    print("Building "+title+" installer. This can take up to an hour.")
     if (COMPRESSOR != "lzma"):
     if (COMPRESSOR != "lzma"):
         print("Note: you are using zlib, which is faster, but lzma gives better compression.")
         print("Note: you are using zlib, which is faster, but lzma gives better compression.")
     if (os.path.exists("nsis-output.exe")):
     if (os.path.exists("nsis-output.exe")):
@@ -6210,19 +6210,13 @@ def MakeInstallerNSIS(file, fullname, smdirectory, installdir):
 
 
     nsis_defs = {
     nsis_defs = {
         'COMPRESSOR'  : COMPRESSOR,
         'COMPRESSOR'  : COMPRESSOR,
-        'NAME'        : fullname,
-        'SMDIRECTORY' : smdirectory,
+        'TITLE'       : title,
         'INSTALLDIR'  : installdir,
         'INSTALLDIR'  : installdir,
         'OUTFILE'     : os.path.join(psource, 'nsis-output.exe'),
         'OUTFILE'     : os.path.join(psource, 'nsis-output.exe'),
         'LICENSE'     : os.path.join(panda, 'LICENSE'),
         'LICENSE'     : os.path.join(panda, 'LICENSE'),
-        'LANGUAGE'    : "English",
-        'RUNTEXT'     : "Visit the Panda Manual",
-        'IBITMAP'     : "panda-install.bmp",
-        'UBITMAP'     : "panda-install.bmp",
-        'PANDA'       : panda,
+        'BUILT'       : panda,
+        'SOURCE'      : psource,
         'PYVER'       : SDK["PYTHONVERSION"][6:9],
         'PYVER'       : SDK["PYTHONVERSION"][6:9],
-        'PANDACONF'   : os.path.join(panda, 'etc'),
-        'PSOURCE'     : psource,
         'PYEXTRAS'    : os.path.join(os.path.abspath(GetThirdpartyBase()), 'win-extras'),
         'PYEXTRAS'    : os.path.join(os.path.abspath(GetThirdpartyBase()), 'win-extras'),
         'REGVIEW'     : regview,
         'REGVIEW'     : regview,
     }
     }
@@ -6236,7 +6230,7 @@ def MakeInstallerNSIS(file, fullname, smdirectory, installdir):
         for item in nsis_defs.items():
         for item in nsis_defs.items():
             cmd += ' -D%s="%s"' % item
             cmd += ' -D%s="%s"' % item
 
 
-    cmd += ' "%s"' % (os.path.join(psource, 'direct', 'src', 'directscripts', 'packpanda.nsi'))
+    cmd += ' "%s"' % (os.path.join(psource, 'makepanda', 'installer.nsi'))
     oscmd(cmd)
     oscmd(cmd)
     os.rename("nsis-output.exe", file)
     os.rename("nsis-output.exe", file)
 
 
@@ -6761,14 +6755,14 @@ try:
             if (GetOptimize() <= 2): dbg = "-dbg"
             if (GetOptimize() <= 2): dbg = "-dbg"
             if GetTargetArch() == 'x64':
             if GetTargetArch() == 'x64':
                 if (RUNTIME):
                 if (RUNTIME):
-                    MakeInstallerNSIS("Panda3D-Runtime-"+VERSION+dbg+"-x64.exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION+"-x64")
+                    MakeInstallerNSIS("Panda3D-Runtime-"+VERSION+dbg+"-x64.exe", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION+"-x64")
                 else:
                 else:
-                    MakeInstallerNSIS("Panda3D-"+VERSION+dbg+"-x64.exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION+"-x64")
+                    MakeInstallerNSIS("Panda3D-"+VERSION+dbg+"-x64.exe", "Panda3D SDK "+VERSION, "C:\\Panda3D-"+VERSION+"-x64")
             else:
             else:
                 if (RUNTIME):
                 if (RUNTIME):
-                    MakeInstallerNSIS("Panda3D-Runtime-"+VERSION+dbg+".exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION)
+                    MakeInstallerNSIS("Panda3D-Runtime-"+VERSION+dbg+".exe", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION)
                 else:
                 else:
-                    MakeInstallerNSIS("Panda3D-"+VERSION+dbg+".exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION)
+                    MakeInstallerNSIS("Panda3D-"+VERSION+dbg+".exe", "Panda3D SDK "+VERSION, "C:\\Panda3D-"+VERSION)
         elif (target == 'linux'):
         elif (target == 'linux'):
             MakeInstallerLinux()
             MakeInstallerLinux()
         elif (target == 'darwin'):
         elif (target == 'darwin'):

+ 0 - 0
direct/src/directscripts/panda-install.bmp → makepanda/panda-install.bmp


+ 7 - 7
panda/src/egldisplay/eglGraphicsBuffer.cxx

@@ -1,5 +1,5 @@
 // Filename: eglGraphicsBuffer.cxx
 // Filename: eglGraphicsBuffer.cxx
-// Created by:  pro-rsoft (13Jun09)
+// Created by:  rdb (13Jun09)
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //
 //
@@ -28,7 +28,7 @@ TypeHandle eglGraphicsBuffer::_type_handle;
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 eglGraphicsBuffer::
 eglGraphicsBuffer::
-eglGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe, 
+eglGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
                   const string &name,
                   const string &name,
                   const FrameBufferProperties &fb_prop,
                   const FrameBufferProperties &fb_prop,
                   const WindowProperties &win_prop,
                   const WindowProperties &win_prop,
@@ -187,7 +187,7 @@ open_buffer() {
       _gsg = eglgsg;
       _gsg = eglgsg;
     }
     }
   }
   }
-  
+
   if (eglgsg->_fbconfig == None) {
   if (eglgsg->_fbconfig == None) {
     // If we didn't use an fbconfig to create the GSG, we can't create
     // If we didn't use an fbconfig to create the GSG, we can't create
     // a PBuffer.
     // a PBuffer.
@@ -195,11 +195,11 @@ open_buffer() {
   }
   }
 
 
   int attrib_list[] = {
   int attrib_list[] = {
-    EGL_WIDTH, _x_size,
-    EGL_HEIGHT, _y_size,
+    EGL_WIDTH, _size.get_x(),
+    EGL_HEIGHT, _size.get_y(),
     EGL_NONE
     EGL_NONE
   };
   };
-  
+
   _pbuffer = eglCreatePbufferSurface(eglgsg->_egl_display, eglgsg->_fbconfig, attrib_list);
   _pbuffer = eglCreatePbufferSurface(eglgsg->_egl_display, eglgsg->_fbconfig, attrib_list);
 
 
   if (_pbuffer == EGL_NO_SURFACE) {
   if (_pbuffer == EGL_NO_SURFACE) {
@@ -224,7 +224,7 @@ open_buffer() {
     return false;
     return false;
   }
   }
   _fb_properties = eglgsg->get_fb_properties();
   _fb_properties = eglgsg->get_fb_properties();
-  
+
   _is_valid = true;
   _is_valid = true;
   return true;
   return true;
 }
 }

+ 1 - 1
panda/src/egldisplay/eglGraphicsBuffer.h

@@ -1,5 +1,5 @@
 // Filename: eglGraphicsBuffer.h
 // Filename: eglGraphicsBuffer.h
-// Created by:  pro-rsoft (13Jun09)
+// Created by:  rdb (13Jun09)
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //
 //

+ 7 - 7
panda/src/egldisplay/eglGraphicsPixmap.cxx

@@ -1,5 +1,5 @@
 // Filename: eglGraphicsPixmap.cxx
 // Filename: eglGraphicsPixmap.cxx
-// Created by:  pro-rsoft (13Jun09)
+// Created by:  rdb (13Jun09)
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //
 //
@@ -29,7 +29,7 @@ TypeHandle eglGraphicsPixmap::_type_handle;
 //  Description:
 //  Description:
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 eglGraphicsPixmap::
 eglGraphicsPixmap::
-eglGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe, 
+eglGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe,
                   const string &name,
                   const string &name,
                   const FrameBufferProperties &fb_prop,
                   const FrameBufferProperties &fb_prop,
                   const WindowProperties &win_prop,
                   const WindowProperties &win_prop,
@@ -105,7 +105,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
     }
     }
     clear_cube_map_selection();
     clear_cube_map_selection();
   }
   }
-  
+
   _gsg->set_current_properties(&get_fb_properties());
   _gsg->set_current_properties(&get_fb_properties());
   return _gsg->begin_frame(current_thread);
   return _gsg->begin_frame(current_thread);
 }
 }
@@ -195,7 +195,7 @@ open_buffer() {
       _gsg = eglgsg;
       _gsg = eglgsg;
     }
     }
   }
   }
-  
+
   if (eglgsg->_fbconfig == None) {
   if (eglgsg->_fbconfig == None) {
     // If we didn't use an fbconfig to create the GSG, we can't create
     // If we didn't use an fbconfig to create the GSG, we can't create
     // a PBuffer.
     // a PBuffer.
@@ -221,8 +221,8 @@ open_buffer() {
     }
     }
   }
   }
 
 
-  _x_pixmap = XCreatePixmap(_display, _drawable, 
-                            _x_size, _y_size, visual_info->depth);
+  _x_pixmap = XCreatePixmap(_display, _drawable,
+                            _size.get_x(), _size.get_y(), visual_info->depth);
   if (_x_pixmap == None) {
   if (_x_pixmap == None) {
     egldisplay_cat.error()
     egldisplay_cat.error()
       << "Failed to create X pixmap.\n";
       << "Failed to create X pixmap.\n";
@@ -253,7 +253,7 @@ open_buffer() {
     return false;
     return false;
   }
   }
   _fb_properties = eglgsg->get_fb_properties();
   _fb_properties = eglgsg->get_fb_properties();
-  
+
   _is_valid = true;
   _is_valid = true;
   return true;
   return true;
 }
 }

+ 2 - 2
panda/src/egldisplay/eglGraphicsPixmap.h

@@ -1,5 +1,5 @@
 // Filename: eglGraphicsPixmap.h
 // Filename: eglGraphicsPixmap.h
-// Created by:  pro-rsoft (13Jun09)
+// Created by:  rdb (13Jun09)
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //
 //
@@ -29,7 +29,7 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class eglGraphicsPixmap : public GraphicsBuffer {
 class eglGraphicsPixmap : public GraphicsBuffer {
 public:
 public:
-  eglGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe, 
+  eglGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe,
                     const string &name,
                     const string &name,
                     const FrameBufferProperties &fb_prop,
                     const FrameBufferProperties &fb_prop,
                     const WindowProperties &win_prop,
                     const WindowProperties &win_prop,

+ 12 - 13
panda/src/gles2gsg/gles2gsg.h

@@ -57,7 +57,7 @@
 //  #include <GLES2/gl2ext.h>
 //  #include <GLES2/gl2ext.h>
 #endif
 #endif
 
 
-#include "panda_esgl2ext.h" 
+#include "panda_esgl2ext.h"
 
 
 // This helps to keep the source clean of hundreds of #ifdefs.
 // This helps to keep the source clean of hundreds of #ifdefs.
 typedef char GLchar;
 typedef char GLchar;
@@ -100,20 +100,19 @@ typedef char GLchar;
 #define GL_RGBA16F GL_RGBA16F_EXT
 #define GL_RGBA16F GL_RGBA16F_EXT
 #define GL_RGB32F GL_RGB32F_EXT
 #define GL_RGB32F GL_RGB32F_EXT
 #define GL_RGBA32F GL_RGBA32F_EXT
 #define GL_RGBA32F GL_RGBA32F_EXT
-#define GL_DEBUG_SEVERITY_HIGH GL_DEBUG_SEVERITY_HIGH_KHR
-#define GL_DEBUG_SEVERITY_MEDIUM GL_DEBUG_SEVERITY_MEDIUM_KHR
-#define GL_DEBUG_SEVERITY_LOW GL_DEBUG_SEVERITY_LOW_KHR
-#define GL_DEBUG_SEVERITY_NOTIFICATION GL_DEBUG_SEVERITY_NOTIFICATION_KHR
-#define GL_DEBUG_OUTPUT_SYNCHRONOUS GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR
-#define GL_FRAMEBUFFER_SRGB GL_FRAMEBUFFER_SRGB_EXT
 #define GL_SRGB GL_SRGB_EXT
 #define GL_SRGB GL_SRGB_EXT
 #define GL_SRGB_ALPHA GL_SRGB_ALPHA_EXT
 #define GL_SRGB_ALPHA GL_SRGB_ALPHA_EXT
-#define GL_SRGB8 GL_SRGB8_EXT
-#define GL_SRGB8_ALPHA GL_SRGB8_ALPHA_EXT
-#define GL_SLUMINANCE GL_SLUMINANCE_NV
-#define GL_SLUMINANCE_ALPHA GL_SLUMINANCE_ALPHA_NV
-#define GL_SLUMINANCE8 GL_SLUMINANCE8_NV
-#define GL_SLUMINANCE8_ALPHA GL_SLUMINANCE8_ALPHA_NV
+#define GL_SRGB8_ALPHA8 GL_SRGB8_ALPHA8_EXT
+#define GL_RGBA8 GL_RGBA8_OES
+#define GL_R8 GL_R8_EXT
+#define GL_RG8 GL_RG8_EXT
+#define GL_ALPHA8 GL_ALPHA8_OES
+#define GL_LUMINANCE8 GL_LUMINANCE8_OES
+#define GL_LUMINANCE8_ALPHA8 GL_LUMINANCE8_ALPHA8_EXT
+#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT
+#define GL_R32F GL_R32F_EXT
+#define GL_RG32F GL_RG32F_EXT
+#define GL_RGB8 GL_RGB8_OES
 
 
 #undef SUPPORT_IMMEDIATE_MODE
 #undef SUPPORT_IMMEDIATE_MODE
 #define APIENTRY
 #define APIENTRY

+ 3 - 0
panda/src/glesgsg/glesgsg.h

@@ -115,6 +115,9 @@
 #define GL_RGBA16F GL_RGBA16F_EXT
 #define GL_RGBA16F GL_RGBA16F_EXT
 #define GL_RGB32F GL_RGB32F_EXT
 #define GL_RGB32F GL_RGB32F_EXT
 #define GL_RGBA32F GL_RGBA32F_EXT
 #define GL_RGBA32F GL_RGBA32F_EXT
+#define GL_ALPHA8 GL_ALPHA8_EXT
+#define GL_LUMINANCE8 GL_LUMINANCE8_EXT
+#define GL_LUMINANCE8_ALPHA8 GL_LUMINANCE8_ALPHA8_EXT
 
 
 #undef SUPPORT_IMMEDIATE_MODE
 #undef SUPPORT_IMMEDIATE_MODE
 #define APIENTRY
 #define APIENTRY

+ 1 - 1
panda/src/glstuff/glGraphicsBuffer_src.cxx

@@ -1674,7 +1674,7 @@ resolve_multisamples() {
                               GL_NEAREST);
                               GL_NEAREST);
   }
   }
   // Now handle the other color buffers.
   // Now handle the other color buffers.
-#ifndef OPENGLES_1
+#ifndef OPENGLES
   int next = GL_COLOR_ATTACHMENT1_EXT;
   int next = GL_COLOR_ATTACHMENT1_EXT;
   if (_fb_properties.is_stereo()) {
   if (_fb_properties.is_stereo()) {
     glReadBuffer(next);
     glReadBuffer(next);

+ 6 - 1
panda/src/glstuff/glGraphicsStateGuardian_src.I

@@ -745,9 +745,12 @@ call_glTexParameterfv(GLenum target, GLenum pname, const LVecBase4 &value) {
 //       Access: Public
 //       Access: Public
 //  Description: Convert index to gl light id
 //  Description: Convert index to gl light id
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE GLenum CLP(GraphicsStateGuardian)::get_light_id(int index) const {
+INLINE GLenum CLP(GraphicsStateGuardian)::
+get_light_id(int index) const {
 #ifndef OPENGLES_2
 #ifndef OPENGLES_2
   return GL_LIGHT0 + index;
   return GL_LIGHT0 + index;
+#else
+  return 0;
 #endif
 #endif
 }
 }
 
 
@@ -760,6 +763,8 @@ INLINE GLenum CLP(GraphicsStateGuardian)::
 get_clip_plane_id(int index) const {
 get_clip_plane_id(int index) const {
 #ifndef OPENGLES_2
 #ifndef OPENGLES_2
   return GL_CLIP_PLANE0 + index;
   return GL_CLIP_PLANE0 + index;
+#else
+  return 0;
 #endif
 #endif
 }
 }
 
 

+ 93 - 81
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -127,16 +127,16 @@ null_glBlendColor(GLclampf, GLclampf, GLclampf, GLclampf) {
 // a fixed-function pipeline.
 // a fixed-function pipeline.
 // This default shader just outputs a red color, telling
 // This default shader just outputs a red color, telling
 // the user that something went wrong.
 // the user that something went wrong.
-CPT(Shader::ShaderFile) default_shader_name = new Shader::ShaderFile("default-shader");
-CPT(Shader::ShaderFile) default_shader_body = new Shader::ShaderFile("\
-uniform mediump mat4 p3d_ModelViewProjectionMatrix;\
-attribute highp vec4 p3d_Vertex;\
-void main(void) {\
-  gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\
-}\n",
-"void main(void) {\
-  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\
-}\n", "", "", "");
+static const string default_vshader =
+  "uniform mediump mat4 p3d_ModelViewProjectionMatrix;\n"
+  "attribute highp vec4 p3d_Vertex;\n"
+  "void main(void) {\n"
+  "  gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\n"
+  "}\n";
+static const string default_fshader =
+  "void main(void) {\n"
+  "  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
+  "}\n";
 #endif
 #endif
 
 
 
 
@@ -1370,7 +1370,7 @@ reset() {
   // if it failed to compile. This default shader just outputs
   // if it failed to compile. This default shader just outputs
   // a red color, indicating that something went wrong.
   // a red color, indicating that something went wrong.
   if (_default_shader == NULL) {
   if (_default_shader == NULL) {
-    _default_shader = new Shader(default_shader_name, default_shader_body, Shader::SL_GLSL);
+    _default_shader = Shader::load(Shader::SL_GLSL, default_vshader, default_fshader);
   }
   }
 #endif
 #endif
 
 
@@ -1915,6 +1915,8 @@ reset() {
   }
   }
 
 
   _supports_sampler_objects = false;
   _supports_sampler_objects = false;
+
+#ifndef OPENGLES
   if (gl_support_sampler_objects &&
   if (gl_support_sampler_objects &&
       ((is_at_least_gl_version(3, 3) || has_extension("GL_ARB_sampler_objects")))) {
       ((is_at_least_gl_version(3, 3) || has_extension("GL_ARB_sampler_objects")))) {
     _glGenSamplers = (PFNGLGENSAMPLERSPROC) get_extension_func("glGenSamplers");
     _glGenSamplers = (PFNGLGENSAMPLERSPROC) get_extension_func("glGenSamplers");
@@ -1935,6 +1937,7 @@ reset() {
       _supports_sampler_objects = true;
       _supports_sampler_objects = true;
     }
     }
   }
   }
+#endif  // OPENGLES
 
 
   // Check availability of multi-bind functions.
   // Check availability of multi-bind functions.
   _supports_multi_bind = false;
   _supports_multi_bind = false;
@@ -1944,10 +1947,12 @@ reset() {
     _glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)
     _glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)
       get_extension_func("glBindImageTextures");
       get_extension_func("glBindImageTextures");
 
 
+#ifndef OPENGLES
     if (_supports_sampler_objects) {
     if (_supports_sampler_objects) {
       _glBindSamplers = (PFNGLBINDSAMPLERSPROC)
       _glBindSamplers = (PFNGLBINDSAMPLERSPROC)
         get_extension_func("glBindSamplers");
         get_extension_func("glBindSamplers");
     }
     }
+#endif  // OPENGLES
 
 
     if (_glBindTextures != NULL && _glBindImageTextures != NULL) {
     if (_glBindTextures != NULL && _glBindImageTextures != NULL) {
       _supports_multi_bind = true;
       _supports_multi_bind = true;
@@ -2011,14 +2016,18 @@ reset() {
 
 
   _supports_stencil_wrap =
   _supports_stencil_wrap =
     has_extension("GL_EXT_stencil_wrap") || has_extension("GL_OES_stencil_wrap");
     has_extension("GL_EXT_stencil_wrap") || has_extension("GL_OES_stencil_wrap");
-  _supports_two_sided_stencil = has_extension("GL_EXT_stencil_two_side");
-  if (_supports_two_sided_stencil) {
+
+
+  _supports_two_sided_stencil = false;
+#ifndef OPENGLES
+  if (has_extension("GL_EXT_stencil_two_side")) {
     _glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)
     _glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)
       get_extension_func("glActiveStencilFaceEXT");
       get_extension_func("glActiveStencilFaceEXT");
-  }
-  else {
+    _supports_two_sided_stencil = true;
+  } else {
     _glActiveStencilFaceEXT = 0;
     _glActiveStencilFaceEXT = 0;
   }
   }
+#endif
 
 
 #ifndef OPENGLES
 #ifndef OPENGLES
   // Some drivers expose one, some expose the other. ARB seems to be the newer one.
   // Some drivers expose one, some expose the other. ARB seems to be the newer one.
@@ -2618,9 +2627,11 @@ clear_before_callback() {
 
 
   // Clear the bound sampler object, so that we do not inadvertently
   // Clear the bound sampler object, so that we do not inadvertently
   // override the callback's desired sampler settings.
   // override the callback's desired sampler settings.
+#ifndef OPENGLES
   if (_supports_sampler_objects) {
   if (_supports_sampler_objects) {
     _glBindSampler(0, 0);
     _glBindSampler(0, 0);
   }
   }
+#endif
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -2761,7 +2772,7 @@ begin_frame(Thread *current_thread) {
   }*/
   }*/
 #endif
 #endif
 
 
-#ifndef OPENGLES_1
+#ifndef OPENGLES
   if (_current_properties->get_srgb_color()) {
   if (_current_properties->get_srgb_color()) {
     glEnable(GL_FRAMEBUFFER_SRGB);
     glEnable(GL_FRAMEBUFFER_SRGB);
   }
   }
@@ -2819,7 +2830,7 @@ void CLP(GraphicsStateGuardian)::
 end_frame(Thread *current_thread) {
 end_frame(Thread *current_thread) {
   report_my_gl_errors();
   report_my_gl_errors();
 
 
-#ifndef OPENGLES_1
+#ifndef OPENGLES
   if (_current_properties->get_srgb_color()) {
   if (_current_properties->get_srgb_color()) {
     glDisable(GL_FRAMEBUFFER_SRGB);
     glDisable(GL_FRAMEBUFFER_SRGB);
   }
   }
@@ -4521,8 +4532,10 @@ prepare_sampler(const SamplerState &sampler) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 void CLP(GraphicsStateGuardian)::
 release_sampler(SamplerContext *sc) {
 release_sampler(SamplerContext *sc) {
+#ifndef OPENGLES
   CLP(SamplerContext) *gsc = DCAST(CLP(SamplerContext), sc);
   CLP(SamplerContext) *gsc = DCAST(CLP(SamplerContext), sc);
   delete gsc;
   delete gsc;
+#endif
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -5205,7 +5218,7 @@ make_geom_munger(const RenderState *state, Thread *current_thread) {
 //               from the camera plane.  The point is assumed to be
 //               from the camera plane.  The point is assumed to be
 //               in the GSG's internal coordinate system.
 //               in the GSG's internal coordinate system.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-PN_stdfloat GLGraphicsStateGuardian::
+PN_stdfloat CLP(GraphicsStateGuardian)::
 compute_distance_to(const LPoint3 &point) const {
 compute_distance_to(const LPoint3 &point) const {
   return -point[2];
   return -point[2];
 }
 }
@@ -7447,7 +7460,7 @@ get_external_image_format(Texture *tex) const {
       break;
       break;
 
 
     case Texture::CM_dxt1:
     case Texture::CM_dxt1:
-#ifndef OPENGLES_1
+#ifndef OPENGLES
       if (format == Texture::F_srgb_alpha) {
       if (format == Texture::F_srgb_alpha) {
         return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
         return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
       } else if (format == Texture::F_srgb) {
       } else if (format == Texture::F_srgb) {
@@ -7484,13 +7497,13 @@ get_external_image_format(Texture *tex) const {
 
 
 #else
 #else
     case Texture::CM_pvr1_2bpp:
     case Texture::CM_pvr1_2bpp:
-#ifndef OPENGLES_1
+#ifndef OPENGLES
       if (format == Texture::F_srgb_alpha) {
       if (format == Texture::F_srgb_alpha) {
         return GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT;
         return GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT;
       } else if (format == Texture::F_srgb) {
       } else if (format == Texture::F_srgb) {
         return GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT;
         return GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT;
       } else
       } else
-#endif  // OPENGLES_1
+#endif  // OPENGLES
       if (Texture::has_alpha(format)) {
       if (Texture::has_alpha(format)) {
         return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
         return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
       } else {
       } else {
@@ -7498,13 +7511,13 @@ get_external_image_format(Texture *tex) const {
       }
       }
 
 
     case Texture::CM_pvr1_4bpp:
     case Texture::CM_pvr1_4bpp:
-#ifndef OPENGLES_1
+#ifndef OPENGLES
       if (format == Texture::F_srgb_alpha) {
       if (format == Texture::F_srgb_alpha) {
         return GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT;
         return GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT;
       } else if (format == Texture::F_srgb) {
       } else if (format == Texture::F_srgb) {
         return GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT;
         return GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT;
       } else
       } else
-#endif  // OPENGLES_1
+#endif  // OPENGLES
       if (Texture::has_alpha(format)) {
       if (Texture::has_alpha(format)) {
         return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
         return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
       } else {
       } else {
@@ -7762,7 +7775,7 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
 #endif
 #endif
 
 
     case Texture::CM_dxt1:
     case Texture::CM_dxt1:
-#ifndef OPENGLES_1
+#ifndef OPENGLES
       if (format == Texture::F_srgb_alpha) {
       if (format == Texture::F_srgb_alpha) {
         return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
         return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
       } else if (format == Texture::F_srgb) {
       } else if (format == Texture::F_srgb) {
@@ -7798,13 +7811,6 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
       }
       }
 #else
 #else
     case Texture::CM_pvr1_2bpp:
     case Texture::CM_pvr1_2bpp:
-#ifndef OPENGLES_1
-      if (format == Texture::F_srgb_alpha) {
-        return GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT;
-      } else if (format == Texture::F_srgb) {
-        return GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT;
-      } else
-#endif  // OPENGLES_1
       if (Texture::has_alpha(format)) {
       if (Texture::has_alpha(format)) {
         return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
         return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
       } else {
       } else {
@@ -7812,13 +7818,6 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
       }
       }
 
 
     case Texture::CM_pvr1_4bpp:
     case Texture::CM_pvr1_4bpp:
-#ifndef OPENGLES_1
-      if (format == Texture::F_srgb_alpha) {
-        return GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT;
-      } else if (format == Texture::F_srgb) {
-        return GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT;
-      } else
-#endif  // OPENGLES_1
       if (Texture::has_alpha(format)) {
       if (Texture::has_alpha(format)) {
         return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
         return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
       } else {
       } else {
@@ -7843,7 +7842,7 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
 
 
   case Texture::F_depth_stencil:
   case Texture::F_depth_stencil:
     if (_supports_depth_stencil) {
     if (_supports_depth_stencil) {
-#ifndef OPENGLES_1
+#ifndef OPENGLES
       if (tex->get_component_type() == Texture::T_float) {
       if (tex->get_component_type() == Texture::T_float) {
         return GL_DEPTH32F_STENCIL8;
         return GL_DEPTH32F_STENCIL8;
       } else
       } else
@@ -7903,7 +7902,10 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
     if (tex->get_component_type() == Texture::T_float) {
     if (tex->get_component_type() == Texture::T_float) {
       return GL_RGBA16F;
       return GL_RGBA16F;
-    } else if (tex->get_component_type() == Texture::T_unsigned_short) {
+    } else
+#endif
+#ifndef OPENGLES
+    if (tex->get_component_type() == Texture::T_unsigned_short) {
       return GL_RGBA16;
       return GL_RGBA16;
     } else
     } else
 #endif
 #endif
@@ -7949,7 +7951,7 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
   case Texture::F_rgba12:
   case Texture::F_rgba12:
     return GL_RGBA12;
     return GL_RGBA12;
 #endif  // OPENGLES
 #endif  // OPENGLES
-#ifndef OPENGLES_1
+#ifndef OPENGLES
   case Texture::F_rgba16:
   case Texture::F_rgba16:
     if (tex->get_component_type() == Texture::T_float) {
     if (tex->get_component_type() == Texture::T_float) {
       return GL_RGBA16F;
       return GL_RGBA16F;
@@ -8040,26 +8042,36 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
     return force_sized ? GL_ALPHA8 : GL_ALPHA;
     return force_sized ? GL_ALPHA8 : GL_ALPHA;
 
 
   case Texture::F_luminance:
   case Texture::F_luminance:
+#ifndef OPENGLES
     if (tex->get_component_type() == Texture::T_float) {
     if (tex->get_component_type() == Texture::T_float) {
       return GL_LUMINANCE16F_ARB;
       return GL_LUMINANCE16F_ARB;
     } else if (tex->get_component_type() == Texture::T_unsigned_short) {
     } else if (tex->get_component_type() == Texture::T_unsigned_short) {
       return GL_LUMINANCE16;
       return GL_LUMINANCE16;
-    } else {
+    } else
+#endif  // OPENGLES
+    {
       return force_sized ? GL_LUMINANCE8 : GL_LUMINANCE;
       return force_sized ? GL_LUMINANCE8 : GL_LUMINANCE;
     }
     }
   case Texture::F_luminance_alpha:
   case Texture::F_luminance_alpha:
   case Texture::F_luminance_alphamask:
   case Texture::F_luminance_alphamask:
+#ifndef OPENGLES
     if (tex->get_component_type() == Texture::T_float || tex->get_component_type() == Texture::T_unsigned_short) {
     if (tex->get_component_type() == Texture::T_float || tex->get_component_type() == Texture::T_unsigned_short) {
       return GL_LUMINANCE_ALPHA16F_ARB;
       return GL_LUMINANCE_ALPHA16F_ARB;
-    } else {
+    } else
+#endif  // OPENGLES
+    {
       return force_sized ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA;
       return force_sized ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA;
     }
     }
 
 
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
   case Texture::F_srgb:
   case Texture::F_srgb:
+#ifndef OPENGLES
     return GL_SRGB8;
     return GL_SRGB8;
+#endif
   case Texture::F_srgb_alpha:
   case Texture::F_srgb_alpha:
     return GL_SRGB8_ALPHA8;
     return GL_SRGB8_ALPHA8;
+#endif
+#ifndef OPENGLES
   case Texture::F_sluminance:
   case Texture::F_sluminance:
     return GL_SLUMINANCE8;
     return GL_SLUMINANCE8;
   case Texture::F_sluminance_alpha:
   case Texture::F_sluminance_alpha:
@@ -9043,7 +9055,7 @@ set_state_and_transform(const RenderState *target,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 void CLP(GraphicsStateGuardian)::
 free_pointers() {
 free_pointers() {
-#ifdef HAVE_CG
+#if defined(HAVE_CG) && !defined(OPENGLES)
   if (_cg_context != 0) {
   if (_cg_context != 0) {
     cgDestroyContext(_cg_context);
     cgDestroyContext(_cg_context);
     _cg_context = 0;
     _cg_context = 0;
@@ -10081,6 +10093,7 @@ bool CLP(GraphicsStateGuardian)::
 apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc) {
 apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc) {
   CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
   CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
 
 
+#ifndef OPENGLES
   if (_supports_sampler_objects) {
   if (_supports_sampler_objects) {
     // We support sampler objects.  Prepare the sampler object and
     // We support sampler objects.  Prepare the sampler object and
     // bind it to the indicated texture unit.
     // bind it to the indicated texture unit.
@@ -10097,7 +10110,9 @@ apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc) {
         << "bind " << unit << " " << sampler << "\n";
         << "bind " << unit << " " << sampler << "\n";
     }
     }
 
 
-  } else {
+  } else
+#endif  // OPENGLES
+  {
     // We don't support sampler objects.  We'll have to bind the
     // We don't support sampler objects.  We'll have to bind the
     // texture and change the texture parameters if they don't match.
     // texture and change the texture parameters if they don't match.
     if (gtc->_active_sampler != sampler) {
     if (gtc->_active_sampler != sampler) {
@@ -10678,6 +10693,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
           if (tex->has_clear_color()) {
           if (tex->has_clear_color()) {
             // The texture has a clear color, so we should fill this mipmap
             // The texture has a clear color, so we should fill this mipmap
             // level to a solid color.
             // level to a solid color.
+#ifndef OPENGLES
             if (_supports_clear_texture) {
             if (_supports_clear_texture) {
               // We can do that with the convenient glClearTexImage function.
               // We can do that with the convenient glClearTexImage function.
               string clear_data = tex->get_clear_data();
               string clear_data = tex->get_clear_data();
@@ -10685,12 +10701,13 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
               _glClearTexImage(gtc->_index, n - mipmap_bias, external_format,
               _glClearTexImage(gtc->_index, n - mipmap_bias, external_format,
                                component_type, (void *)clear_data.data());
                                component_type, (void *)clear_data.data());
               continue;
               continue;
-            } else {
-              // Ask the Texture class to create the mipmap level in RAM.
-              // It'll fill it in with the correct clear color, which we
-              // can then upload.
-              ptimage = tex->make_ram_mipmap_image(n);
             }
             }
+#endif  // OPENGLES
+            // Ask the Texture class to create the mipmap level in RAM.
+            // It'll fill it in with the correct clear color, which we
+            // can then upload.
+            ptimage = tex->make_ram_mipmap_image(n);
+
           } else {
           } else {
             // No clear color and no more images.
             // No clear color and no more images.
             break;
             break;
@@ -10726,13 +10743,8 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
       _data_transferred_pcollector.add_level(view_size);
       _data_transferred_pcollector.add_level(view_size);
 #endif
 #endif
       switch (texture_target) {
       switch (texture_target) {
-#ifdef OPENGLES_2
-      case GL_TEXTURE_3D_OES:
-#endif
-#ifndef OPENGLES
-      case GL_TEXTURE_3D:
-#endif
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
+      case GL_TEXTURE_3D:
         if (_supports_3d_texture) {
         if (_supports_3d_texture) {
           if (image_compression == Texture::CM_off) {
           if (image_compression == Texture::CM_off) {
             _glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
             _glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
@@ -10746,7 +10758,9 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
           return false;
           return false;
         }
         }
         break;
         break;
+#endif  // OPENGLES_1
 
 
+#ifndef OPENGLES
       case GL_TEXTURE_1D:
       case GL_TEXTURE_1D:
         if (image_compression == Texture::CM_off) {
         if (image_compression == Texture::CM_off) {
           glTexSubImage1D(page_target, n - mipmap_bias, 0, width,
           glTexSubImage1D(page_target, n - mipmap_bias, 0, width,
@@ -10756,7 +10770,8 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
                                      external_format, view_size, image_ptr);
                                      external_format, view_size, image_ptr);
         }
         }
         break;
         break;
-#endif
+#endif  // OPENGLES
+
 #ifndef OPENGLES
 #ifndef OPENGLES
       case GL_TEXTURE_2D_ARRAY_EXT:
       case GL_TEXTURE_2D_ARRAY_EXT:
         if (_supports_2d_texture_array) {
         if (_supports_2d_texture_array) {
@@ -10772,7 +10787,8 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
           return false;
           return false;
         }
         }
         break;
         break;
-#endif
+#endif  // OPENGLES
+
       default:
       default:
         if (image_compression == Texture::CM_off) {
         if (image_compression == Texture::CM_off) {
           if (n==0) {
           if (n==0) {
@@ -11319,7 +11335,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
     type = Texture::T_unsigned_int_24_8;
     type = Texture::T_unsigned_int_24_8;
     format = Texture::F_depth_stencil;
     format = Texture::F_depth_stencil;
     break;
     break;
-#ifndef OPENGLES_1
+#ifndef OPENGLES
   case GL_DEPTH32F_STENCIL8:
   case GL_DEPTH32F_STENCIL8:
     type = Texture::T_float;
     type = Texture::T_float;
     format = Texture::F_depth_stencil;
     format = Texture::F_depth_stencil;
@@ -11483,26 +11499,34 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
     format = Texture::F_alpha;
     format = Texture::F_alpha;
     break;
     break;
   case GL_LUMINANCE:
   case GL_LUMINANCE:
+#ifndef OPENGLES
   case GL_LUMINANCE16:
   case GL_LUMINANCE16:
   case GL_LUMINANCE16F_ARB:
   case GL_LUMINANCE16F_ARB:
+#endif
   case 1:
   case 1:
     format = Texture::F_luminance;
     format = Texture::F_luminance;
     break;
     break;
   case GL_LUMINANCE_ALPHA:
   case GL_LUMINANCE_ALPHA:
+#ifndef OPENGLES
   case GL_LUMINANCE_ALPHA16F_ARB:
   case GL_LUMINANCE_ALPHA16F_ARB:
+#endif
   case 2:
   case 2:
     format = Texture::F_luminance_alpha;
     format = Texture::F_luminance_alpha;
     break;
     break;
 
 
 #ifndef OPENGLES_1
 #ifndef OPENGLES_1
   case GL_SRGB:
   case GL_SRGB:
+#ifndef OPENGLES
   case GL_SRGB8:
   case GL_SRGB8:
+#endif
     format = Texture::F_srgb;
     format = Texture::F_srgb;
     break;
     break;
   case GL_SRGB_ALPHA:
   case GL_SRGB_ALPHA:
   case GL_SRGB8_ALPHA8:
   case GL_SRGB8_ALPHA8:
     format = Texture::F_srgb_alpha;
     format = Texture::F_srgb_alpha;
     break;
     break;
+#endif  // OPENGLES_1
+#ifndef OPENGLES
   case GL_SLUMINANCE:
   case GL_SLUMINANCE:
   case GL_SLUMINANCE8:
   case GL_SLUMINANCE8:
     format = Texture::F_sluminance;
     format = Texture::F_sluminance;
@@ -11511,7 +11535,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
   case GL_SLUMINANCE8_ALPHA8:
   case GL_SLUMINANCE8_ALPHA8:
     format = Texture::F_sluminance_alpha;
     format = Texture::F_sluminance_alpha;
     break;
     break;
-#endif
+#endif  // OPENGLES
 
 
 #ifndef OPENGLES
 #ifndef OPENGLES
   case GL_COMPRESSED_RGB:
   case GL_COMPRESSED_RGB:
@@ -11561,7 +11585,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
     format = Texture::F_rgbm;
     format = Texture::F_rgbm;
     compression = Texture::CM_dxt1;
     compression = Texture::CM_dxt1;
     break;
     break;
-#ifndef OPENGLES_1
+#ifndef OPENGLES
   case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
   case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
     format = Texture::F_srgb;
     format = Texture::F_srgb;
     compression = Texture::CM_dxt1;
     compression = Texture::CM_dxt1;
@@ -11572,25 +11596,6 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
     break;
     break;
 #endif
 #endif
 
 
-#ifdef OPENGLES_2
-  case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
-    format = Texture::F_srgb;
-    compression = Texture::CM_pvr1_2bpp;
-    break;
-  case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
-    format = Texture::F_srgb_alpha;
-    compression = Texture::CM_pvr1_2bpp;
-    break;
-  case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
-    format = Texture::F_srgb;
-    compression = Texture::CM_pvr1_4bpp;
-    break;
-  case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:
-    format = Texture::F_srgb_alpha;
-    compression = Texture::CM_pvr1_4bpp;
-    break;
-#endif  // OPENGLES_2
-
 #ifdef OPENGLES
 #ifdef OPENGLES
   case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
   case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
     format = Texture::F_rgb;
     format = Texture::F_rgb;
@@ -11963,6 +11968,7 @@ do_issue_stencil() {
                     << "SRS_back_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) << "\n";
                     << "SRS_back_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) << "\n";
     }
     }
 
 
+#ifndef OPENGLES
     if (_supports_two_sided_stencil) {
     if (_supports_two_sided_stencil) {
       //TODO: add support for OpenGL 2.0-style glStencilFuncSeparate.
       //TODO: add support for OpenGL 2.0-style glStencilFuncSeparate.
       unsigned int back_compare;
       unsigned int back_compare;
@@ -11989,6 +11995,7 @@ do_issue_stencil() {
 
 
       _glActiveStencilFaceEXT(GL_FRONT);
       _glActiveStencilFaceEXT(GL_FRONT);
     }
     }
+#endif  // OPENGLES
 
 
     unsigned int front_compare;
     unsigned int front_compare;
     front_compare = stencil->get_render_state(StencilAttrib::SRS_front_comparison_function);
     front_compare = stencil->get_render_state(StencilAttrib::SRS_front_comparison_function);
@@ -12018,9 +12025,11 @@ do_issue_stencil() {
     }
     }
   } else {
   } else {
     glDisable(GL_STENCIL_TEST);
     glDisable(GL_STENCIL_TEST);
+#ifndef OPENGLES
     if (_supports_two_sided_stencil) {
     if (_supports_two_sided_stencil) {
       glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
       glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
     }
     }
+#endif  // OPENGLES
   }
   }
 }
 }
 
 
@@ -12067,9 +12076,12 @@ do_issue_scissor() {
     if (_scissor_array.size() > 0) {
     if (_scissor_array.size() > 0) {
       // Scissoring is enabled on the display region.
       // Scissoring is enabled on the display region.
       // Revert to the scissor state specified in the DisplayRegion.
       // Revert to the scissor state specified in the DisplayRegion.
+#ifndef OPENGLES
       if (_supports_viewport_arrays) {
       if (_supports_viewport_arrays) {
         _glScissorArrayv(0, _scissor_array.size(), _scissor_array[0].get_data());
         _glScissorArrayv(0, _scissor_array.size(), _scissor_array[0].get_data());
-      } else {
+      } else
+#endif  // OPENGLES
+      {
         const LVecBase4i sr = _scissor_array[0];
         const LVecBase4i sr = _scissor_array[0];
         glScissor(sr[0], sr[1], sr[2], sr[3]);
         glScissor(sr[0], sr[1], sr[2], sr[3]);
       }
       }

+ 4 - 0
panda/src/glstuff/glSamplerContext_src.cxx

@@ -14,6 +14,8 @@
 
 
 #include "pnotify.h"
 #include "pnotify.h"
 
 
+#ifndef OPENGLES
+
 TypeHandle CLP(SamplerContext)::_type_handle;
 TypeHandle CLP(SamplerContext)::_type_handle;
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -81,3 +83,5 @@ reset_data() {
   // re-load the sampler later.
   // re-load the sampler later.
   //glGenSamplers(1, &_index);
   //glGenSamplers(1, &_index);
 }
 }
+
+#endif  // OPENGLES

+ 4 - 0
panda/src/glstuff/glSamplerContext_src.h

@@ -12,6 +12,8 @@
 //
 //
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
+#ifndef OPENGLES
+
 #include "pandabase.h"
 #include "pandabase.h"
 #include "samplerContext.h"
 #include "samplerContext.h"
 #include "deletedChain.h"
 #include "deletedChain.h"
@@ -56,3 +58,5 @@ public:
 private:
 private:
   static TypeHandle _type_handle;
   static TypeHandle _type_handle;
 };
 };
+
+#endif  // OPENGLES

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

@@ -412,6 +412,20 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
             s->_mat_spec.push_back(bind);
             s->_mat_spec.push_back(bind);
             continue;
             continue;
           }
           }
+          if (noprefix == "Color") {
+            Shader::ShaderMatSpec bind;
+            bind._id = arg_id;
+            bind._piece = Shader::SMP_row3;
+            bind._func = Shader::SMF_first;
+            bind._part[0] = Shader::SMO_attr_color;
+            bind._arg[0] = NULL;
+            bind._dep[0] = Shader::SSD_general | Shader::SSD_color;
+            bind._part[1] = Shader::SMO_identity;
+            bind._arg[1] = NULL;
+            bind._dep[1] = Shader::SSD_NONE;
+            s->_mat_spec.push_back(bind);
+            continue;
+          }
           if (noprefix == "ClipPlane") {
           if (noprefix == "ClipPlane") {
             for (int i = 0; i < param_size; ++i) {
             for (int i = 0; i < param_size; ++i) {
               Shader::ShaderMatSpec bind;
               Shader::ShaderMatSpec bind;
@@ -821,10 +835,12 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
                        param_type == GL_INT_VEC2 ||
                        param_type == GL_INT_VEC2 ||
                        param_type == GL_INT_VEC3 ||
                        param_type == GL_INT_VEC3 ||
                        param_type == GL_INT_VEC4 ||
                        param_type == GL_INT_VEC4 ||
-                       param_type == GL_UNSIGNED_INT ||
+#ifndef OPENGLES
                        param_type == GL_UNSIGNED_INT_VEC2 ||
                        param_type == GL_UNSIGNED_INT_VEC2 ||
                        param_type == GL_UNSIGNED_INT_VEC3 ||
                        param_type == GL_UNSIGNED_INT_VEC3 ||
-                       param_type == GL_UNSIGNED_INT_VEC4);
+                       param_type == GL_UNSIGNED_INT_VEC4 ||
+#endif
+                       param_type == GL_UNSIGNED_INT );
 
 
       if (noprefix.empty()) {
       if (noprefix.empty()) {
         // Arbitrarily named attribute.
         // Arbitrarily named attribute.
@@ -863,12 +879,16 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
       // Get the number of bind points.
       // Get the number of bind points.
       switch (param_type) {
       switch (param_type) {
       case GL_FLOAT_MAT3:
       case GL_FLOAT_MAT3:
+#ifndef OPENGLES
       case GL_DOUBLE_MAT3:
       case GL_DOUBLE_MAT3:
+#endif
         bind._elements = 3 * param_size;
         bind._elements = 3 * param_size;
         break;
         break;
 
 
       case GL_FLOAT_MAT4:
       case GL_FLOAT_MAT4:
+#ifndef OPENGLES
       case GL_DOUBLE_MAT4:
       case GL_DOUBLE_MAT4:
+#endif
         bind._elements = 4 * param_size;
         bind._elements = 4 * param_size;
         break;
         break;
 
 

+ 2 - 0
panda/src/glstuff/glmisc_src.cxx

@@ -283,7 +283,9 @@ void CLP(init_classes)() {
   CLP(ShaderContext)::init_type();
   CLP(ShaderContext)::init_type();
 #endif
 #endif
   CLP(TextureContext)::init_type();
   CLP(TextureContext)::init_type();
+#ifndef OPENGLES
   CLP(SamplerContext)::init_type();
   CLP(SamplerContext)::init_type();
+#endif
   CLP(VertexBufferContext)::init_type();
   CLP(VertexBufferContext)::init_type();
   CLP(GraphicsBuffer)::init_type();
   CLP(GraphicsBuffer)::init_type();
 
 

+ 4 - 4
panda/src/pgraph/loader.cxx

@@ -343,11 +343,11 @@ try_load_file(const Filename &pathname, const LoaderOptions &options,
         return result;
         return result;
       }
       }
     }
     }
-  }
 
 
-  if (loader_cat.is_debug()) {
-    loader_cat.debug()
-      << "Model " << pathname << " not found in cache.\n";
+    if (loader_cat.is_debug()) {
+      loader_cat.debug()
+        << "Model " << pathname << " not found in cache.\n";
+    }
   }
   }
 
 
   bool cache_only = (options.get_flags() & LoaderOptions::LF_cache_only) != 0;
   bool cache_only = (options.get_flags() & LoaderOptions::LF_cache_only) != 0;

+ 20 - 10
panda/src/putil/bamCache.cxx

@@ -43,7 +43,7 @@ BamCache() :
   _index_stale_since(0)
   _index_stale_since(0)
 {
 {
   ConfigVariableFilename model_cache_dir
   ConfigVariableFilename model_cache_dir
-    ("model-cache-dir", Filename(), 
+    ("model-cache-dir", Filename(),
      PRC_DESC("The full path to a directory, local to this computer, in which "
      PRC_DESC("The full path to a directory, local to this computer, in which "
               "model and texture files will be cached on load.  If a directory "
               "model and texture files will be cached on load.  If a directory "
               "name is specified here, files may be loaded from the cache "
               "name is specified here, files may be loaded from the cache "
@@ -51,7 +51,7 @@ BamCache() :
               "especially if you are loading egg files instead of bam files, "
               "especially if you are loading egg files instead of bam files, "
               "or if you are loading models from a shared network drive.  "
               "or if you are loading models from a shared network drive.  "
               "If this is the empty string, no cache will be used."));
               "If this is the empty string, no cache will be used."));
-  
+
   ConfigVariableInt model_cache_flush
   ConfigVariableInt model_cache_flush
     ("model-cache-flush", 30,
     ("model-cache-flush", 30,
      PRC_DESC("This is the amount of time, in seconds, between automatic "
      PRC_DESC("This is the amount of time, in seconds, between automatic "
@@ -138,7 +138,7 @@ set_root(const Filename &root) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: BamCache::lookup
 //     Function: BamCache::lookup
 //       Access: Published
 //       Access: Published
-//  Description: Looks up a file in the cache.  
+//  Description: Looks up a file in the cache.
 //
 //
 //               If the file is cacheable, then regardless of whether
 //               If the file is cacheable, then regardless of whether
 //               the file is found in the cache or not, this returns a
 //               the file is found in the cache or not, this returns a
@@ -163,7 +163,7 @@ lookup(const Filename &source_filename, const string &cache_extension) {
   consider_flush_index();
   consider_flush_index();
 
 
   VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
   VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
-  
+
   Filename source_pathname(source_filename);
   Filename source_pathname(source_filename);
   source_pathname.make_absolute(vfs->get_cwd());
   source_pathname.make_absolute(vfs->get_cwd());
 
 
@@ -200,7 +200,7 @@ store(BamCacheRecord *record) {
   if (_read_only) {
   if (_read_only) {
     return false;
     return false;
   }
   }
-  
+
   consider_flush_index();
   consider_flush_index();
 
 
 #ifndef NDEBUG
 #ifndef NDEBUG
@@ -231,7 +231,7 @@ store(BamCacheRecord *record) {
     emergency_read_only();
     emergency_read_only();
     return false;
     return false;
   }
   }
-  
+
   if (!dout.write_header(_bam_header)) {
   if (!dout.write_header(_bam_header)) {
     util_cat.error()
     util_cat.error()
       << "Unable to write to " << temp_pathname << "\n";
       << "Unable to write to " << temp_pathname << "\n";
@@ -247,7 +247,7 @@ store(BamCacheRecord *record) {
       vfs->delete_file(temp_pathname);
       vfs->delete_file(temp_pathname);
       return false;
       return false;
     }
     }
-    
+
     TypeRegistry *type_registry = TypeRegistry::ptr();
     TypeRegistry *type_registry = TypeRegistry::ptr();
     TypeHandle texture_type = type_registry->find_type("Texture");
     TypeHandle texture_type = type_registry->find_type("Texture");
     if (record->get_data()->is_of_type(texture_type)) {
     if (record->get_data()->is_of_type(texture_type)) {
@@ -257,14 +257,14 @@ store(BamCacheRecord *record) {
       // Any other kinds of objects write texture references.
       // Any other kinds of objects write texture references.
       writer.set_file_texture_mode(BamWriter::BTM_fullpath);
       writer.set_file_texture_mode(BamWriter::BTM_fullpath);
     }
     }
-    
+
     if (!writer.write_object(record)) {
     if (!writer.write_object(record)) {
       util_cat.error()
       util_cat.error()
         << "Unable to write object to " << temp_pathname << "\n";
         << "Unable to write object to " << temp_pathname << "\n";
       vfs->delete_file(temp_pathname);
       vfs->delete_file(temp_pathname);
       return false;
       return false;
     }
     }
-    
+
     if (!writer.write_object(record->get_data())) {
     if (!writer.write_object(record->get_data())) {
       util_cat.error()
       util_cat.error()
         << "Unable to write object data to " << temp_pathname << "\n";
         << "Unable to write object data to " << temp_pathname << "\n";
@@ -354,7 +354,7 @@ flush_index() {
       emergency_read_only();
       emergency_read_only();
       return;
       return;
     }
     }
-    
+
     // Now atomically write the name of this index file to the index
     // Now atomically write the name of this index file to the index
     // reference file.
     // reference file.
     VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
     VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
@@ -385,6 +385,16 @@ flush_index() {
   check_cache_size();
   check_cache_size();
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: BamCache::list_index
+//       Access: Published
+//  Description: Writes the contents of the index to standard output.
+////////////////////////////////////////////////////////////////////
+void BamCache::
+list_index(ostream &out, int indent_level) const {
+  _index->write(out, indent_level);
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: BamCache::read_index
 //     Function: BamCache::read_index
 //       Access: Private
 //       Access: Private

+ 6 - 4
panda/src/putil/bamCache.h

@@ -73,13 +73,15 @@ PUBLISHED:
   INLINE void set_read_only(bool ro);
   INLINE void set_read_only(bool ro);
   INLINE bool get_read_only() const;
   INLINE bool get_read_only() const;
 
 
-  PT(BamCacheRecord) lookup(const Filename &source_filename, 
+  PT(BamCacheRecord) lookup(const Filename &source_filename,
                             const string &cache_extension);
                             const string &cache_extension);
   bool store(BamCacheRecord *record);
   bool store(BamCacheRecord *record);
 
 
   void consider_flush_index();
   void consider_flush_index();
   void flush_index();
   void flush_index();
-  
+
+  void list_index(ostream &out, int indent_level = 0) const;
+
   INLINE static BamCache *get_global_ptr();
   INLINE static BamCache *get_global_ptr();
 
 
 private:
 private:
@@ -96,7 +98,7 @@ private:
   void check_cache_size();
   void check_cache_size();
 
 
   void emergency_read_only();
   void emergency_read_only();
-  
+
   static BamCacheIndex *do_read_index(const Filename &index_pathname);
   static BamCacheIndex *do_read_index(const Filename &index_pathname);
   static bool do_write_index(const Filename &index_pathname, const BamCacheIndex *index);
   static bool do_write_index(const Filename &index_pathname, const BamCacheIndex *index);
 
 
@@ -105,7 +107,7 @@ private:
   PT(BamCacheRecord) read_record(const Filename &source_pathname,
   PT(BamCacheRecord) read_record(const Filename &source_pathname,
                                  const Filename &cache_filename,
                                  const Filename &cache_filename,
                                  int pass);
                                  int pass);
-  static PT(BamCacheRecord) do_read_record(const Filename &cache_pathname, 
+  static PT(BamCacheRecord) do_read_record(const Filename &cache_pathname,
                                            bool read_data);
                                            bool read_data);
 
 
   static string hash_filename(const string &filename);
   static string hash_filename(const string &filename);