Browse Source

Eliminated Cg references in gobj/shaderContext

Josh Yelon 20 years ago
parent
commit
ba74d9a772

+ 60 - 40
doc/makepanda/makepanda.py

@@ -40,7 +40,7 @@ PACKAGES=["PYTHON","ZLIB","PNG","JPEG","TIFF","VRPN","FMOD","NVIDIACG","HELIX","
           "BISON","FLEX","OPENCV","PANDATOOL","PANDAAPP","DX8","DX9"]
 OMIT=PACKAGES[:]
 WARNINGS=[]
-DIRECTXSDK = None
+DIRECTXSDK = {}
 MAYASDK = {}
 MAXSDK = {}
 MAXSDKCS = {}
@@ -52,6 +52,7 @@ FILEDATECACHE = {}
 CXXINCLUDECACHE = {}
 SLAVEBUILD=0
 THREADCOUNT=0
+DXVERSIONS=["8","9"]
 MAYAVERSIONS=["6","65","7"]
 MAXVERSIONS=["6","7","8"]
 
@@ -124,6 +125,19 @@ def xpaths(prefix,base,suffix):
 
 if sys.platform == "win32":
     import _winreg
+
+    def ListRegistryKeys(path):
+        result=[]
+        index=0
+        try:
+            key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, path, 0, _winreg.KEY_READ)
+            while (1):
+                result.append(_winreg.EnumKey(key, index))
+                index = index + 1
+        except: pass
+        if (key!=0): _winreg.CloseKey(key)
+        return result
+
     def GetRegistryKey(path, subkey):
         k1=0
         key=0
@@ -359,7 +373,7 @@ def usage(problem):
 
 def parseopts(args):
     global COMPILER,OPTIMIZE,OMIT,INSTALLER,GENMAN,SLAVEBUILD
-    global VERSION,COMPRESSOR,DIRECTXSDK,VERBOSE,SLAVEFILE,THREADCOUNT
+    global VERSION,COMPRESSOR,VERBOSE,SLAVEFILE,THREADCOUNT
     longopts = [
         "help","package-info","compiler=","directx-sdk=","slavebuild=",
         "optimize=","everything","nothing","installer","quiet","verbose",
@@ -373,7 +387,6 @@ def parseopts(args):
             if (option=="--help"): raise "usage"
             elif (option=="--package-info"): raise "package-info"
             elif (option=="--compiler"): COMPILER=value
-            elif (option=="--directx-sdk"): DIRECTXSDK=value
             elif (option=="--optimize"): OPTIMIZE=value
             elif (option=="--quiet"): VERBOSE-=1
             elif (option=="--verbose"): VERBOSE+=1
@@ -434,7 +447,8 @@ os.chdir(PANDASOURCE)
 ########################################################################
 
 if (os.path.isdir("sdks")):
-    DIRECTXSDK="sdks/directx"
+#    DIRECTXSDK["DX8"] = "sdks/directx8"
+#    DIRECTXSDK["DX9"] = "sdks/directx9"
     MAXSDKCS["MAX6"] = "sdks/maxsdk6"
     MAXSDKCS["MAX7"] = "sdks/maxsdk7"
     MAXSDKCS["MAX8"] = "sdks/maxsdk8"
@@ -449,24 +463,33 @@ if (os.path.isdir("sdks")):
 ##
 ## Locate the DirectX SDK
 ##
+## Microsoft keeps changing the &*#$*& registry key for the DirectX SDK.
+## The only way to reliably find it is to search through the installer's
+## uninstall-directories, look in each one, and see if it contains the
+## relevant files.
+##
 ########################################################################
 
-if sys.platform == "win32" and DIRECTXSDK is None:
-    dxdir = GetRegistryKey("SOFTWARE\\Microsoft\\DirectX SDK", "DX9SDK Samples Path")
-    if (dxdir != 0): DIRECTXSDK = os.path.dirname(dxdir)
-    else:
-        dxdir = GetRegistryKey("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment","DXSDK_DIR")
-        if (dxdir != 0): DIRECTXSDK=dxdir
+if sys.platform == "win32":
+    uninstaller = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+    for subdir in ListRegistryKeys(uninstaller):
+        if (subdir[0]=="{"):
+            dir = GetRegistryKey(uninstaller+"\\"+subdir, "InstallLocation")
+            if (dir != 0):
+                for ver in DXVERSIONS:
+                    if ((DIRECTXSDK.has_key("DX"+ver)==0) and
+                        (os.path.isfile(dir+"\\Include\\d3d"+ver+".h")) and
+                        (os.path.isfile(dir+"\\Include\\d3dx"+ver+".h")) and
+                        (os.path.isfile(dir+"\\Lib\\x86\\d3d"+ver+".lib")) and
+                        (os.path.isfile(dir+"\\Lib\\x86\\d3dx"+ver+".lib"))):
+                        DIRECTXSDK["DX"+ver] = dir.replace("\\", "/").rstrip("/")
+    for ver in DXVERSIONS:
+        if (DIRECTXSDK.has_key("DX"+ver)==0) and (OMIT.count("DX"+ver)==0):
+            WARNINGS.append("I cannot locate SDK for DX"+ver)
+            WARNINGS.append("I have automatically added this command-line option: --no-dx"+ver)
+            OMIT.append("DX"+ver)
         else:
-            dxdir = GetRegistryKey("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment","DXSDKROOT")
-            if dxdir != 0:
-                if dxdir[-2:]=="/.":
-                    DIRECTXSDK=dxdir[:-1]
-                else:
-                    DIRECTXSDK=dxdir
-            else:
-                exit("The registry does not appear to contain a pointer to the DirectX 9.0 SDK.")
-    DIRECTXSDK=DIRECTXSDK.replace("\\", "/").rstrip("/")
+            WARNINGS.append("Using DX"+ver+" sdk: "+DIRECTXSDK["DX"+ver])
 
 ########################################################################
 ##
@@ -597,11 +620,9 @@ def LocateVisualStudio():
         AddToVisualStudioPath("PATH", vcdir + "\\bin")
         AddToVisualStudioPath("INCLUDE", platsdk + "\\include")
         AddToVisualStudioPath("INCLUDE", vcdir + "\\include")
-        AddToVisualStudioPath("INCLUDE", DIRECTXSDK + "\\include")
         AddToVisualStudioPath("LIB",     platsdk + "\\lib")
         AddToVisualStudioPath("LIB",     vcdir + "\\lib")
         AddToVisualStudioPath("LIB",     "thirdparty\\win-libs-vc7\\extras\\lib")
-        AddToVisualStudioPath("INCLUDE", DIRECTXSDK + "\\lib")
         return
 
     # Give up
@@ -719,7 +740,6 @@ def printStatus(header,warnings):
         print "Makepanda: Optimize:",OPTIMIZE
         print "Makepanda: Keep Pkg:",tkeep
         print "Makepanda: Omit Pkg:",tomit
-        print "Makepanda: DirectX SDK dir:",DIRECTXSDK
         print "Makepanda: Verbose vs. Quiet Level:",VERBOSE
         if (GENMAN): print "Makepanda: Generate API reference manual"
         else       : print "Makepanda: Don't generate API reference manual"
@@ -971,7 +991,9 @@ def CopyTree(dstdir,srcdir):
 def CompileCxxMSVC7(wobj,fullsrc,ipath,opts):
     cmd = "cl /Fo" + wobj + " /nologo /c"
     if (OMIT.count("PYTHON")==0): cmd = cmd + " /Ibuilt/python/include"
-    if (opts.count("DXSDK")): cmd = cmd + ' /I"' + DIRECTXSDK + '/include"'
+    for ver in DXVERSIONS:
+        if (PkgSelected(opts,"DX"+ver)):
+            cmd = cmd + ' /I"' + DIRECTXSDK["DX"+ver] + '/include"'
     for ver in MAYAVERSIONS:
         if (PkgSelected(opts,"MAYA"+ver)):
             cmd = cmd + ' /I"' + MAYASDK["MAYA"+ver] + '/include"'
@@ -979,7 +1001,7 @@ def CompileCxxMSVC7(wobj,fullsrc,ipath,opts):
         if (PkgSelected(opts,"MAX"+ver)):
             cmd = cmd + ' /I"' + MAXSDK["MAX"+ver] + '/include" /I"' + MAXSDKCS["MAX"+ver] + '" /DMAX' + ver
     for pkg in PACKAGES:
-        if (pkg[:4] != "MAYA") and (pkg[:3]!="MAX") and PkgSelected(opts,pkg):
+        if (pkg[:4] != "MAYA") and (pkg[:3]!="MAX") and (pkg[:2]!="DX") and PkgSelected(opts,pkg):
             cmd = cmd + " /Ithirdparty/win-libs-vc7/" + pkg.lower() + "/include"
     for x in ipath: cmd = cmd + " /I" + x
     if (opts.count('NOFLOATWARN')): cmd = cmd + ' /wd4244 /wd4305'
@@ -1143,7 +1165,9 @@ def CompileIgateMSVC7(ipath,opts,outd,outc,wobj,src,module,library,files):
         if (building): cmd = cmd + " -DBUILDING_"+building
         if (opts.count("WITHINPANDA")): cmd = cmd + " -DWITHIN_PANDA"
         cmd = cmd + ' -module ' + module + ' -library ' + library
-        if ((COMPILER=="MSVC7") and opts.count("DXSDK")): cmd = cmd + ' -I"' + DIRECTXSDK + '/include"'
+        for ver in DXVERSIONS:
+            if ((COMPILER=="MSVC7") and PkgSelected(opts,"DX"+ver)):
+                cmd = cmd + ' -I"' + DIRECTXSDK["DX"+ver] + '/include"'
         for ver in MAYAVERSIONS:
             if ((COMPILER=="MSVC7") and PkgSelected(opts,"MAYA"+ver)):
                 cmd = cmd + ' -I"' + MAYASDK["MAYA"+ver] + '/include"'
@@ -1174,7 +1198,6 @@ def CompileIgateLINUXA(ipath,opts,outd,outc,wobj,src,module,library,files):
         if (building): cmd = cmd + " -DBUILDING_"+building
         if (opts.count("WITHINPANDA")): cmd = cmd + " -DWITHIN_PANDA"
         cmd = cmd + ' -module ' + module + ' -library ' + library
-        if (opts.count("DXSDK")): cmd = cmd + ' -I"' + DIRECTXSDK + '/include"'
         for ver in MAYAVERSIONS:
             if (PkgSelected(opts, "MAYA"+ver)):
                 cmd = cmd + ' -I"' + MAYASDK["MAYA"+ver] + '/include"'
@@ -1310,14 +1333,11 @@ def CompileLinkMSVC7(wdll, wlib, wobj, opts, dll, ldef):
     if (OMIT.count("PYTHON")==0): cmd = cmd + ' /LIBPATH:built/python/libs '
     for x in wobj: cmd = cmd + ' ' + x
     if (wdll[-4:]==".exe"): cmd = cmd + ' panda/src/configfiles/pandaIcon.obj'
-    if (opts.count("D3D8") or opts.count("D3D9") or opts.count("DXDRAW") or opts.count("DXSOUND") or opts.count("DXGUID")):
-        cmd = cmd + ' /LIBPATH:"' + DIRECTXSDK + '/lib/x86"'
-        cmd = cmd + ' /LIBPATH:"' + DIRECTXSDK + '/lib"'
-    if (opts.count("D3D8")):        cmd = cmd + ' d3d8.lib d3dx8.lib dxerr8.lib'
-    if (opts.count("D3D9")):        cmd = cmd + ' d3d9.lib d3dx9.lib dxerr9.lib'
-    if (opts.count("DXDRAW")):      cmd = cmd + ' ddraw.lib'
-    if (opts.count("DXSOUND")):     cmd = cmd + ' dsound.lib'
-    if (opts.count("DXGUID")):      cmd = cmd + ' dxguid.lib'
+    for ver in DXVERSIONS:
+        if (PkgSelected(opts,"DX"+ver)):
+            cmd = cmd + ' /LIBPATH:"' + DIRECTXSDK["DX"+ver] + '/lib/x86"'
+            cmd = cmd + ' /LIBPATH:"' + DIRECTXSDK["DX"+ver] + '/lib"'
+            cmd = cmd + ' d3dVER.lib d3dxVER.lib dxerrVER.lib ddraw.lib dxguid.lib'.replace("VER",ver)
     if (opts.count("WINSOCK")):     cmd = cmd + " wsock32.lib"
     if (opts.count("WINSOCK2")):    cmd = cmd + " wsock32.lib ws2_32.lib"
     if (opts.count("WINCOMCTL")):   cmd = cmd + ' comctl32.lib'
@@ -2296,7 +2316,7 @@ EnqueueIgate(ipath=IPATH, opts=OPTS, outd='libpstatclient.in', obj='libpstatclie
 #
 
 IPATH=['panda/src/gobj']
-OPTS=['BUILDING_PANDA', 'NSPR', 'NVIDIACG']
+OPTS=['BUILDING_PANDA', 'NSPR']
 CopyAllHeaders('panda/src/gobj')
 EnqueueCxx(ipath=IPATH, opts=OPTS, src='gobj_composite1.cxx', obj='gobj_composite1.obj')
 EnqueueCxx(ipath=IPATH, opts=OPTS, src='gobj_composite2.cxx', obj='gobj_composite2.obj')
@@ -2572,7 +2592,7 @@ CopyAllHeaders('panda/src/physics')
 CopyAllHeaders('panda/src/particlesystem')
 IPATH=['panda/metalibs/panda']
 OPTS=['BUILDING_PANDA', 'ZLIB', 'VRPN', 'JPEG', 'PNG', 'TIFF', 'NSPR', 'FREETYPE', 'HELIX', 'FFTW', 'OPENCV',
-      'ADVAPI', 'WINSOCK2', 'WINUSER', 'WINMM', 'NVIDIACG']
+      'ADVAPI', 'WINSOCK2', 'WINUSER', 'WINMM']
 INFILES=['librecorder.in', 'libpgraph.in', 'libgrutil.in', 'libchan.in', 'libpstatclient.in',
          'libchar.in', 'libcollide.in', 'libdevice.in', 'libdgraph.in', 'libdisplay.in', 'libevent.in',
          'libgobj.in', 'libgsgbase.in', 'liblinmath.in', 'libmathutil.in', 'libparametrics.in',
@@ -2760,14 +2780,14 @@ if (sys.platform == "win32"):
 
 if OMIT.count("DX8")==0:
     IPATH=['panda/src/dxgsg8', 'panda/metalibs/pandadx8']
-    OPTS=['BUILDING_PANDADX', 'DXSDK', 'NSPR']
+    OPTS=['BUILDING_PANDADX', 'DX8', 'NSPR']
     CopyAllHeaders('panda/src/dxgsg8')
     CopyAllHeaders('panda/metalibs/pandadx8')
     EnqueueCxx(ipath=IPATH, opts=OPTS, src='dxGraphicsStateGuardian8.cxx', obj='dxgsg8_dxGraphicsStateGuardian8.obj')
     EnqueueCxx(ipath=IPATH, opts=OPTS, src='dxgsg8_composite.cxx', obj='dxgsg8_composite.obj')
     EnqueueCxx(ipath=IPATH, opts=OPTS, src='pandadx8.cxx', obj='pandadx8_pandadx8.obj')
     EnqueueLink(dll='libpandadx8.dll',
-      opts=['ADVAPI', 'WINGDI', 'WINKERNEL', 'WINUSER', 'WINMM', 'DXDRAW', 'DXGUID', 'D3D8', 'NSPR'], obj=[
+      opts=['ADVAPI', 'WINGDI', 'WINKERNEL', 'WINUSER', 'WINMM', 'DX8', 'NSPR'], obj=[
       'pandadx8_pandadx8.obj',
       'dxgsg8_dxGraphicsStateGuardian8.obj',
       'dxgsg8_composite.obj',
@@ -2784,7 +2804,7 @@ if OMIT.count("DX8")==0:
 
 if OMIT.count("DX9")==0:
     IPATH=['panda/src/dxgsg9']
-    OPTS=['BUILDING_PANDADX', 'DXSDK', 'NSPR', 'NVIDIACG', 'CGDX9']
+    OPTS=['BUILDING_PANDADX', 'DX9', 'NSPR', 'NVIDIACG', 'CGDX9']
     CopyAllHeaders('panda/src/dxgsg9')
     EnqueueCxx(ipath=IPATH, opts=OPTS, src='dxGraphicsStateGuardian9.cxx', obj='dxgsg9_dxGraphicsStateGuardian9.obj')
     EnqueueCxx(ipath=IPATH, opts=OPTS, src='dxgsg9_composite.cxx', obj='dxgsg9_composite.obj')
@@ -2792,7 +2812,7 @@ if OMIT.count("DX9")==0:
     CopyAllHeaders('panda/metalibs/pandadx9')
     EnqueueCxx(ipath=IPATH, opts=OPTS, src='pandadx9.cxx', obj='pandadx9_pandadx9.obj')
     EnqueueLink(dll='libpandadx9.dll',
-      opts=['ADVAPI', 'WINGDI', 'WINKERNEL', 'WINUSER', 'WINMM', 'DXDRAW', 'DXGUID', 'D3D9', 'NSPR', 'NVIDIACG', 'CGDX9'], obj=[
+      opts=['ADVAPI', 'WINGDI', 'WINKERNEL', 'WINUSER', 'WINMM', 'DX9', 'NSPR', 'NVIDIACG', 'CGDX9'], obj=[
       'pandadx9_pandadx9.obj',
       'dxgsg9_dxGraphicsStateGuardian9.obj',
       'dxgsg9_composite.obj',

+ 77 - 4
panda/src/glstuff/glShaderContext_src.cxx

@@ -20,6 +20,42 @@
 
 TypeHandle CLP(ShaderContext)::_type_handle;
 
+////////////////////////////////////////////////////////////////////
+//     Function: cg_type_to_panda_type
+//       Access: Public, Static
+//  Description: convert a cg shader-arg type to a panda shader-arg type.
+////////////////////////////////////////////////////////////////////
+static ShaderContext::ShaderArgType
+cg_type_to_panda_type(CGtype n) {
+  switch (n) {
+  case CG_FLOAT1:      return ShaderContext::SAT_float1;
+  case CG_FLOAT2:      return ShaderContext::SAT_float2;
+  case CG_FLOAT3:      return ShaderContext::SAT_float3;
+  case CG_FLOAT4:      return ShaderContext::SAT_float4;
+  case CG_FLOAT4x4:    return ShaderContext::SAT_float4x4;
+  case CG_SAMPLER1D:   return ShaderContext::SAT_sampler1d;
+  case CG_SAMPLER2D:   return ShaderContext::SAT_sampler2d;
+  case CG_SAMPLER3D:   return ShaderContext::SAT_sampler3d;
+  case CG_SAMPLERCUBE: return ShaderContext::SAT_samplercube;
+  default:           return ShaderContext::SAT_unknown;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: cg_dir_to_panda_dir
+//       Access: Public, Static
+//  Description: convert a cg shader-arg type to a panda shader-arg type.
+////////////////////////////////////////////////////////////////////
+static ShaderContext::ShaderArgDir
+cg_dir_to_panda_dir(CGenum n) {
+  switch (n) {
+  case CG_IN:    return ShaderContext::SAD_in;
+  case CG_OUT:   return ShaderContext::SAD_out;
+  case CG_INOUT: return ShaderContext::SAD_inout;
+  default:       return ShaderContext::SAD_unknown;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GLShaderContext::Constructor
 //       Access: Public
@@ -85,6 +121,35 @@ CLP(ShaderContext)(ShaderExpansion *s, GSG *gsg) : ShaderContext(s) {
   GLCAT.error() << s->get_name() << ": unrecognized shader language " << header << "\n";
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Shader::report_cg_compile_errors
+//       Access: Public, Static
+//  Description: Used only after a Cg compile command, to print
+//               out any error messages that may have occurred
+//               during the Cg shader compilation.  The 'file'
+//               is the name of the file containing the Cg code.
+////////////////////////////////////////////////////////////////////
+void CLP(ShaderContext)::
+report_cg_compile_errors(const string &file, CGcontext ctx)
+{
+  CGerror err = cgGetError();
+  if (err != CG_NO_ERROR) {
+    if (err == CG_COMPILER_ERROR) {
+      string listing = cgGetLastListing(ctx);
+      vector_string errlines;
+      tokenize(listing, errlines, "\n");
+      for (int i=0; i<(int)errlines.size(); i++) {
+        string line = trim(errlines[i]);
+        if (line != "") {
+          GLCAT.error() << file << " " << errlines[i] << "\n";
+        }
+      }
+    } else {
+      GLCAT.error() << file << ": " << cgGetErrorString(err) << "\n";
+    }
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GLShaderContext::suggest_cg_profile
 //       Access: Private
@@ -164,13 +229,13 @@ try_cg_compile(ShaderExpansion *s, GSG *gsg)
   _cg_program[0] =
     cgCreateProgram(_cg_context, CG_SOURCE, s->_text.c_str(),
                     _cg_profile[0], "vshader", (const char**)NULL);
-  report_cg_compile_errors(s->get_name(), _cg_context, GLCAT.get_safe_ptr());
+  report_cg_compile_errors(s->get_name(), _cg_context);
 
   cgGetError();
   _cg_program[1] =
     cgCreateProgram(_cg_context, CG_SOURCE, s->_text.c_str(),
                     _cg_profile[1], "fshader", (const char**)NULL);
-  report_cg_compile_errors(s->get_name(), _cg_context, GLCAT.get_safe_ptr());
+  report_cg_compile_errors(s->get_name(), _cg_context);
 
   if ((_cg_program[SHADER_type_vert]==0)||(_cg_program[SHADER_type_frag]==0)) {
     release_resources();
@@ -251,7 +316,7 @@ try_cg_compile(ShaderExpansion *s, GSG *gsg)
       _cg_program[1] =
         cgCreateProgram(_cg_context, CG_OBJECT, result.c_str(),
                         _cg_profile[1], "fshader", (const char**)NULL);
-      report_cg_compile_errors(s->get_name(), _cg_context, GLCAT.get_safe_ptr());
+      report_cg_compile_errors(s->get_name(), _cg_context);
       if (_cg_program[SHADER_type_frag]==0) {
         release_resources();
         return false;
@@ -266,7 +331,15 @@ try_cg_compile(ShaderExpansion *s, GSG *gsg)
     for (parameter = cgGetFirstLeafParameter(_cg_program[progindex],CG_PROGRAM);
          parameter != 0;
          parameter = cgGetNextLeafParameter(parameter)) {
-      success &= compile_cg_parameter(parameter, GLCAT.get_safe_ptr());
+      CGenum vbl = cgGetParameterVariability(parameter);
+      if ((vbl==CG_VARYING)||(vbl==CG_UNIFORM)) {
+        success &= compile_parameter(parameter, 
+                                     cgGetParameterName(parameter),
+                                     cg_type_to_panda_type(cgGetParameterType(parameter)),
+                                     cg_dir_to_panda_dir(cgGetParameterDirection(parameter)),
+                                     (vbl == CG_VARYING),
+                                     GLCAT.get_safe_ptr());
+      }
     }
     if ((progindex == SHADER_type_frag) && (nvtx != _var_spec.size())) {
       GLCAT.error() << "Cannot use vtx parameters in an fshader\n";

+ 1 - 1
panda/src/glstuff/glShaderContext_src.h

@@ -56,10 +56,10 @@ private:
   CGprofile _cg_profile[2];
   CGprogram _cg_program[2];
 
+  void report_cg_compile_errors(const string &file, CGcontext ctx);
   bool try_cg_compile(ShaderExpansion *s, GSG *gsg);
   void suggest_cg_profile(const string &vpro, const string &fpro);
   CGprofile parse_cg_profile(const string &id, bool vertex);
-  void print_cg_compile_errors(const string &file, CGcontext ctx);
 #endif
   
   void release_resources(void);

+ 0 - 1
panda/src/gobj/Sources.pp

@@ -1,6 +1,5 @@
 #define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
                    dtoolutil:c dtoolbase:c dtool:m prc:c
-#define USE_PACKAGES cg
 #define OSX_SYS_LIBS mx
 
 #begin lib_target

+ 151 - 168
panda/src/gobj/shaderContext.cxx

@@ -18,196 +18,169 @@
 
 TypeHandle ShaderContext::_type_handle;
 
-#ifdef HAVE_CG
-#include "Cg/cg.h"
-
-////////////////////////////////////////////////////////////////////
-//     Function: Shader::report_cg_compile_errors
-//       Access: Public, Static
-//  Description: Used only after a Cg compile command, to print
-//               out any error messages that may have occurred
-//               during the Cg shader compilation.  The 'file'
-//               is the name of the file containing the Cg code.
-////////////////////////////////////////////////////////////////////
-void ShaderContext::
-report_cg_compile_errors(const string &file, CGcontext ctx,
-                         NotifyCategory *cat)
-{
-  CGerror err = cgGetError();
-  if (err != CG_NO_ERROR) {
-    if (err == CG_COMPILER_ERROR) {
-      string listing = cgGetLastListing(ctx);
-      vector_string errlines;
-      tokenize(listing, errlines, "\n");
-      for (int i=0; i<(int)errlines.size(); i++) {
-        string line = trim(errlines[i]);
-        if (line != "") {
-          cat->error() << file << " " << errlines[i] << "\n";
-        }
-      }
-    } else {
-      cat->error() << file << ": " << cgGetErrorString(err) << "\n";
-    }
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
-//     Function: Shader::report_cg_parameter_error
+//     Function: Shader::cp_report_error
 //       Access: Public
 //  Description: Generate an error message including a description
-//               of the specified Cg parameter.
+//               of the specified parameter.
 ////////////////////////////////////////////////////////////////////
 void ShaderContext::
-report_cg_parameter_error(CGparameter p, const string &msg)
+cp_report_error(ShaderArgInfo &p, const string &msg)
 {
   string vstr;
-  CGenum v = cgGetParameterVariability(p);
-  if (v == CG_UNIFORM)  vstr = "uniform ";
-  if (v == CG_VARYING)  vstr = "varying ";
-  if (v == CG_CONSTANT) vstr = "const ";
-
-  string dstr;
-  CGenum d = cgGetParameterDirection(p);
-  if (d == CG_IN)    dstr = "in ";
-  if (d == CG_OUT)   dstr = "out ";
-  if (d == CG_INOUT) dstr = "inout ";
-
-  const char *ts = cgGetTypeString(cgGetParameterType(p));
+  if (p._varying) vstr = "varying ";
+  else            vstr = "uniform ";
+
+  string dstr = "unknown ";
+  if (p._direction == SAD_in)    dstr = "in ";
+  if (p._direction == SAD_out)   dstr = "out ";
+  if (p._direction == SAD_inout) dstr = "inout ";
+
+  string tstr = "unknown ";
+  switch (p._type) {
+  case SAT_float1: tstr = "float1 "; break;
+  case SAT_float2: tstr = "float2 "; break;
+  case SAT_float3: tstr = "float3 "; break;
+  case SAT_float4: tstr = "float4 "; break;
+  case SAT_float4x4: tstr = "float4x4 "; break;
+  case SAT_sampler1d: tstr = "sampler1d "; break;
+  case SAT_sampler2d: tstr = "sampler2d "; break;
+  case SAT_sampler3d: tstr = "sampler3d "; break;
+  case SAT_samplercube: tstr = "samplercube "; break;
+  }
 
-  string err;
   string fn = _shader_expansion->get_name();
-  _cg_report_cat->error() << fn << ": " << msg << " (" <<
-    vstr << dstr << ts << " " << cgGetParameterName(p) << ")\n";
+  p._cat->error() << fn << ": " << msg << " (" <<
+    vstr << dstr << tstr << p._name << ")\n";
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: Shader::errchk_cg_parameter_words
+//     Function: Shader::cp_errchk_parameter_words
 //       Access: Public, Static
-//  Description: Make sure the provided Cg parameter contains
+//  Description: Make sure the provided parameter contains
 //               the specified number of words.  If not, print
 //               error message and return false.
 ////////////////////////////////////////////////////////////////////
 bool ShaderContext::
-errchk_cg_parameter_words(CGparameter p, int len)
+cp_errchk_parameter_words(ShaderArgInfo &p, int len)
 {
   vector_string words;
-  tokenize(cgGetParameterName(p), words, "_");
+  tokenize(p._name, words, "_");
   if (words.size() != len) {
-    report_cg_parameter_error(p, "parameter name has wrong number of words");
+    cp_report_error(p, "parameter name has wrong number of words");
     return false;
   }
   return true;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: Shader::errchk_cg_parameter_in
+//     Function: Shader::cp_errchk_parameter_in
 //       Access: Public, Static
-//  Description: Make sure the provided Cg parameter has the
-//               CG_IN direction.  If not, print
+//  Description: Make sure the provided parameter has the
+//               'in' direction.  If not, print
 //               error message and return false.
 ////////////////////////////////////////////////////////////////////
 bool ShaderContext::
-errchk_cg_parameter_in(CGparameter p)
+cp_errchk_parameter_in(ShaderArgInfo &p)
 {
-  if (cgGetParameterDirection(p) != CG_IN) {
-    report_cg_parameter_error(p, "parameter should be declared 'in'");
+  if (p._direction != SAD_in) {
+    cp_report_error(p, "parameter should be declared 'in'");
     return false;
   }
   return true;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: Shader::errchk_cg_parameter_varying
+//     Function: Shader::cp_errchk_parameter_varying
 //       Access: Public, Static
-//  Description: Make sure the provided Cg parameter has the
+//  Description: Make sure the provided parameter has the
 //               correct variance.  If not, print
 //               error message and return false.
 ////////////////////////////////////////////////////////////////////
 bool ShaderContext::
-errchk_cg_parameter_varying(CGparameter p)
+cp_errchk_parameter_varying(ShaderArgInfo &p)
 {
-  if (cgGetParameterVariability(p) != CG_VARYING) {
-    report_cg_parameter_error(p, "parameter should be declared 'varying'");
+  if (!p._varying) {
+    cp_report_error(p, "parameter should be declared 'varying'");
     return false;
   }
   return true;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: Shader::errchk_cg_parameter_uniform
+//     Function: Shader::cp_errchk_parameter_uniform
 //       Access: Public, Static
-//  Description: Make sure the provided Cg parameter has the
+//  Description: Make sure the provided parameter has the
 //               correct variance.  If not, print
 //               error message and return false.
 ////////////////////////////////////////////////////////////////////
 bool ShaderContext::
-errchk_cg_parameter_uniform(CGparameter p)
+cp_errchk_parameter_uniform(ShaderArgInfo &p)
 {
-  if (cgGetParameterVariability(p) != CG_UNIFORM) {
-    report_cg_parameter_error(p, "parameter should be declared 'uniform'");
+  if (p._varying) {
+    cp_report_error(p, "parameter should be declared 'uniform'");
     return false;
   }
   return true;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: Shader::errchk_cg_parameter_float
+//     Function: Shader::cp_errchk_parameter_float
 //       Access: Public, Static
-//  Description: Make sure the provided Cg parameter has
+//  Description: Make sure the provided parameter has
 //               a floating point type.  If not, print
 //               error message and return false.
 ////////////////////////////////////////////////////////////////////
 bool ShaderContext::
-errchk_cg_parameter_float(CGparameter p, int lo, int hi)
+cp_errchk_parameter_float(ShaderArgInfo &p, int lo, int hi)
 {
-  CGtype t = cgGetParameterType(p);
   int nfloat = 0;
-  switch (t) {
-  case CG_FLOAT1: nfloat = 1; break;
-  case CG_FLOAT2: nfloat = 2; break;
-  case CG_FLOAT3: nfloat = 3; break;
-  case CG_FLOAT4: nfloat = 4; break;
-  case CG_FLOAT4x4: nfloat = 16; break;
+  switch (p._type) {
+  case SAT_float1: nfloat = 1; break;
+  case SAT_float2: nfloat = 2; break;
+  case SAT_float3: nfloat = 3; break;
+  case SAT_float4: nfloat = 4; break;
+  case SAT_float4x4: nfloat = 16; break;
   }
   if ((nfloat < lo)||(nfloat > hi)) {
-    report_cg_parameter_error(p, "wrong float-type for parameter");
+    string msg = "wrong type for parameter: should be float";
+    cp_report_error(p, msg);
     return false;
   }
   return true;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: Shader::errchk_cg_parameter_sampler
+//     Function: Shader::cp_errchk_parameter_sampler
 //       Access: Public, Static
-//  Description: Make sure the provided Cg parameter has
+//  Description: Make sure the provided parameter has
 //               a texture type.  If not, print
 //               error message and return false.
 ////////////////////////////////////////////////////////////////////
 bool ShaderContext::
-errchk_cg_parameter_sampler(CGparameter p)
+cp_errchk_parameter_sampler(ShaderArgInfo &p)
 {
-  CGtype t = cgGetParameterType(p);
-  if ((t!=CG_SAMPLER1D)&&
-      (t!=CG_SAMPLER2D)&&
-      (t!=CG_SAMPLER3D)&&
-      (t!=CG_SAMPLERCUBE)) {
-    report_cg_parameter_error(p, "parameter should have a 'sampler' type");
+  if ((p._type!=SAT_sampler1d)&&
+      (p._type!=SAT_sampler2d)&&
+      (p._type!=SAT_sampler3d)&&
+      (p._type!=SAT_samplercube)) {
+    cp_report_error(p, "parameter should have a 'sampler' type");
     return false;
   }
   return true;
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLShaderContext::parse_cg_trans_clause
+//     Function: GLShaderContext::cp_parse_trans_clause
 //       Access: Public
 //  Description: Parses a single clause of a "trans" parameter.
 ////////////////////////////////////////////////////////////////////
 bool ShaderContext::
-parse_cg_trans_clause(CGparameter p, ShaderMatSpec &spec, const vector_string &pieces,
+cp_parse_trans_clause(ShaderArgInfo &p, ShaderMatSpec &spec, const vector_string &pieces,
                       int &next, ShaderMatOp ofop, ShaderMatOp op) {
   if (pieces[next+1]=="of") {
     if (pieces[next+2]=="") {
-      report_cg_parameter_error(p, "'of' should be followed by a name");
+      cp_report_error(p, "'of' should be followed by a name");
       return false;
     }
     if (ofop != SMO_noop) {
@@ -226,41 +199,51 @@ parse_cg_trans_clause(CGparameter p, ShaderMatSpec &spec, const vector_string &p
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: GLShaderContext::compile_cg_parameter
+//     Function: GLShaderContext::compile_parameter
 //       Access: Public
-//  Description: Analyzes a Cg parameter and decides how to
+//  Description: Analyzes a parameter and decides how to
 //               bind the parameter to some part of panda's
-//               internal state.  Updates one of the cg bind
+//               internal state.  Updates one of the bind
 //               arrays to cause the binding to occur.
 //
 //               If there is an error, this routine will append
 //               an error message onto the error messages.
 ////////////////////////////////////////////////////////////////////
 bool ShaderContext::
-compile_cg_parameter(CGparameter p, NotifyCategory *cat)
+compile_parameter(void *reference,
+                  const string   &arg_name,
+                  ShaderArgType   arg_type,
+                  ShaderArgDir    arg_direction,
+                  bool            arg_varying,
+                  NotifyCategory *arg_cat)
 {
-  _cg_report_cat = cat;
-  string pname = cgGetParameterName(p);
-  if (pname.size() == 0) return true;
-  if (pname[0] == '$') return true;
+  ShaderArgInfo p;
+  p._name       = arg_name;
+  p._type       = arg_type;
+  p._direction  = arg_direction;
+  p._varying    = arg_varying;
+  p._cat        = arg_cat;
+
+  if (p._name.size() == 0) return true;
+  if (p._name[0] == '$') return true;
   vector_string pieces;
-  tokenize(pname, pieces, "_");
+  tokenize(p._name, pieces, "_");
 
   if (pieces.size() < 2) {
-    report_cg_parameter_error(p, "invalid parameter name");
+    cp_report_error(p, "invalid parameter name");
     return false;
   }
 
   // Implement vtx parameters - the varying kind.
   
   if (pieces[0] == "vtx") {
-    if ((!errchk_cg_parameter_in(p)) ||
-        (!errchk_cg_parameter_varying(p)) ||
-        (!errchk_cg_parameter_float(p, 1, 4))) {
+    if ((!cp_errchk_parameter_in(p)) ||
+        (!cp_errchk_parameter_varying(p)) ||
+        (!cp_errchk_parameter_float(p, 1, 4))) {
       return false;
     }
     ShaderVarSpec bind;
-    bind._parameter = (void*)p;
+    bind._parameter = reference;
     if (pieces.size() == 2) {
       if (pieces[1]=="position") {
         bind._name = InternalName::get_vertex();
@@ -343,7 +326,7 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
 
   if ((pieces[0] == "mat")||(pieces[0] == "inv")||
       (pieces[0] == "tps")||(pieces[0] == "itp")) {
-    if (!errchk_cg_parameter_words(p, 2)) {
+    if (!cp_errchk_parameter_words(p, 2)) {
       return false;
     }
     string trans = pieces[0];
@@ -356,7 +339,7 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
     } else if (matrix == "modelproj") {
       tokenize("trans_model_to_apiclip", pieces, "_");
     } else {
-      report_cg_parameter_error(p,"unrecognized matrix name");
+      cp_report_error(p,"unrecognized matrix name");
       return false;
     }
     if (trans=="mat") {
@@ -388,12 +371,12 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
       (pieces[0]=="col2")||
       (pieces[0]=="col3")) {
     
-    if ((!errchk_cg_parameter_in(p)) ||
-        (!errchk_cg_parameter_uniform(p)))
+    if ((!cp_errchk_parameter_in(p)) ||
+        (!cp_errchk_parameter_uniform(p)))
       return false;
     
     ShaderMatSpec bind;
-    bind._parameter = (void*)p;
+    bind._parameter = reference;
     bind._trans_dependent = false;
 
     int next = 1;
@@ -411,29 +394,29 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
     else if (pieces[0]=="col2")    bind._piece = SMP_col2;
     else if (pieces[0]=="col3")    bind._piece = SMP_col3;
     if (bind._piece == SMP_whole) {
-      if (!errchk_cg_parameter_float(p, 16, 16)) return false;
+      if (!cp_errchk_parameter_float(p, 16, 16)) return false;
     } else {
-      if (!errchk_cg_parameter_float(p, 4, 4)) return false;
+      if (!cp_errchk_parameter_float(p, 4, 4)) return false;
     }
     
     // Parse the first half of the clause.
     bool ok = true;
     if ((pieces[next]=="")||(pieces[next]=="of")||(pieces[next]=="to")){
-      report_cg_parameter_error(p, "argument missing");
+      cp_report_error(p, "argument missing");
       return false;
     } else if (pieces[next] == "world") {
       bind._opcodes.push_back(SMO_world_to_view);
       next += 1;
     } else if (pieces[next] == "model") {
-      ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_x_to_view, SMO_model_to_view);
+      ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_x_to_view, SMO_model_to_view);
     } else if (pieces[next] == "clip") {
-      ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_clip_x_to_view, SMO_clip_to_view);
+      ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_clip_x_to_view, SMO_clip_to_view);
     } else if (pieces[next] == "view") {
-      ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_x_to_view, SMO_identity);
+      ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_x_to_view, SMO_identity);
     } else if (pieces[next] == "apiview") {
-      ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_apiview_x_to_view, SMO_apiview_to_view);
+      ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_apiview_x_to_view, SMO_apiview_to_view);
     } else if (pieces[next] == "apiclip") {
-      ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_apiclip_x_to_view, SMO_apiclip_to_view);
+      ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_apiclip_x_to_view, SMO_apiclip_to_view);
     } else {
       bind._opcodes.push_back(SMO_view_x_to_view);
       bind._args.push_back(InternalName::make(pieces[next]));
@@ -452,7 +435,7 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
 
     // Check for syntactic well-formed-ness.
     if (pieces[next] != "to") {
-      report_cg_parameter_error(p, "keyword 'to' expected");
+      cp_report_error(p, "keyword 'to' expected");
       return false;
     } else {
       next += 1;
@@ -460,21 +443,21 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
     
     // Parse the second half of the clause.
     if ((pieces[next]=="")||(pieces[next]=="of")||(pieces[next]=="to")){
-      report_cg_parameter_error(p, "argument missing");
+      cp_report_error(p, "argument missing");
       return false;
     } else if (pieces[next] == "world") {
       bind._opcodes.push_back(SMO_view_to_world_C);
       next += 1;
     } else if (pieces[next] == "model") {
-      ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_to_view_x_C, SMO_view_to_model_C);
+      ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_to_view_x_C, SMO_view_to_model_C);
     } else if (pieces[next] == "clip") {
-      ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_to_clip_x_C, SMO_view_to_clip_C);
+      ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_to_clip_x_C, SMO_view_to_clip_C);
     } else if (pieces[next] == "view") {
-      ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_to_view_x_C, SMO_noop);
+      ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_to_view_x_C, SMO_noop);
     } else if (pieces[next] == "apiview") {
-      ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_to_apiview_x_C, SMO_view_to_apiview_C);
+      ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_to_apiview_x_C, SMO_view_to_apiview_C);
     } else if (pieces[next] == "apiclip") {
-      ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_to_apiclip_x_C, SMO_view_to_apiclip_C);
+      ok &= cp_parse_trans_clause(p, bind, pieces, next, SMO_view_to_apiclip_x_C, SMO_view_to_apiclip_C);
     } else {
       bind._opcodes.push_back(SMO_view_to_view_x_C);
       bind._args.push_back(InternalName::make(pieces[next]));
@@ -493,7 +476,7 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
     
     // Check for syntactic well-formed-ness.
     if (pieces[next] != "") {
-      report_cg_parameter_error(p, "end of line expected");
+      cp_report_error(p, "end of line expected");
       return false;
     }
     
@@ -504,32 +487,32 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
   // Keywords to access unusual parameters.
   
   if (pieces[0] == "sys") {
-    if ((!errchk_cg_parameter_words(p,2)) ||
-        (!errchk_cg_parameter_in(p)) ||
-        (!errchk_cg_parameter_uniform(p))) {
+    if ((!cp_errchk_parameter_words(p,2)) ||
+        (!cp_errchk_parameter_in(p)) ||
+        (!cp_errchk_parameter_uniform(p))) {
       return false;
     }
     ShaderMatSpec bind;
-    bind._parameter = (void*)p;
+    bind._parameter = reference;
     bind._trans_dependent = false;
     bind._piece = SMP_row3;
     if (pieces[1] == "pixelsize") {
-      if (!errchk_cg_parameter_float(p, 2, 2)) {
+      if (!cp_errchk_parameter_float(p, 2, 2)) {
         return false;
       }
       bind._opcodes.push_back(SMO_pixel_size);
     } else if (pieces[1] == "windowsize") {
-      if (!errchk_cg_parameter_float(p, 2, 2)) {
+      if (!cp_errchk_parameter_float(p, 2, 2)) {
         return false;
       }
       bind._opcodes.push_back(SMO_window_size);
     } else if (pieces[1] == "cardcenter") {
-      if (!errchk_cg_parameter_float(p, 2, 2)) {
+      if (!cp_errchk_parameter_float(p, 2, 2)) {
         return false;
       }
       bind._opcodes.push_back(SMO_card_center);
     } else {
-      report_cg_parameter_error(p,"unknown system parameter");
+      cp_report_error(p,"unknown system parameter");
       return false;
     }
     _mat_spec.push_back(bind);
@@ -539,25 +522,25 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
   // Keywords to access textures.
   
   if (pieces[0] == "tex") {
-    if ((!errchk_cg_parameter_in(p)) ||
-        (!errchk_cg_parameter_uniform(p)) ||
-        (!errchk_cg_parameter_sampler(p)))
+    if ((!cp_errchk_parameter_in(p)) ||
+        (!cp_errchk_parameter_uniform(p)) ||
+        (!cp_errchk_parameter_sampler(p)))
       return false;
     if ((pieces.size() != 2)&&(pieces.size() != 3)) {
-      report_cg_parameter_error(p, "Invalid parameter name");
+      cp_report_error(p, "Invalid parameter name");
       return false;
     }
     ShaderTexSpec bind;
-    bind._parameter = (void*)p;
+    bind._parameter = reference;
     bind._name = 0;
     bind._stage = atoi(pieces[1].c_str());
-    switch (cgGetParameterType(p)) {
-    case CG_SAMPLER1D:   bind._desired_type = Texture::TT_1d_texture; break;
-    case CG_SAMPLER2D:   bind._desired_type = Texture::TT_2d_texture; break;
-    case CG_SAMPLER3D:   bind._desired_type = Texture::TT_3d_texture; break;
-    case CG_SAMPLERCUBE: bind._desired_type = Texture::TT_cube_map; break;
+    switch (p._type) {
+    case SAT_sampler1d:   bind._desired_type = Texture::TT_1d_texture; break;
+    case SAT_sampler2d:   bind._desired_type = Texture::TT_2d_texture; break;
+    case SAT_sampler3d:   bind._desired_type = Texture::TT_3d_texture; break;
+    case SAT_samplercube: bind._desired_type = Texture::TT_cube_map; break;
     default:
-      report_cg_parameter_error(p, "Invalid type for a tex-parameter");
+      cp_report_error(p, "Invalid type for a tex-parameter");
       return false;
     }
     if (pieces.size()==3) {
@@ -570,14 +553,14 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
   // Keywords to access constants.
 
   if (pieces[0] == "k") {
-    if ((!errchk_cg_parameter_words(p,2)) ||
-        (!errchk_cg_parameter_in(p)) ||
-        (!errchk_cg_parameter_uniform(p)))
+    if ((!cp_errchk_parameter_words(p,2)) ||
+        (!cp_errchk_parameter_in(p)) ||
+        (!cp_errchk_parameter_uniform(p)))
       return false;
-    switch (cgGetParameterType(p)) {
-    case CG_FLOAT4: {
+    switch (p._type) {
+    case SAT_float4: {
       ShaderMatSpec bind;
-      bind._parameter = (void*)p;
+      bind._parameter = reference;
       bind._trans_dependent = false;
       bind._piece = SMP_row3;
       bind._opcodes.push_back(SMO_vec_constant_x);
@@ -585,9 +568,9 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
       _mat_spec.push_back(bind);
       break;
     }
-    case CG_FLOAT4x4: {
+    case SAT_float4x4: {
       ShaderMatSpec bind;
-      bind._parameter = (void*)p;
+      bind._parameter = reference;
       bind._trans_dependent = false;
       bind._piece = SMP_whole;
       bind._opcodes.push_back(SMO_mat_constant_x);
@@ -595,40 +578,40 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
       _mat_spec.push_back(bind);
       break;
     }
-    case CG_SAMPLER1D: {
+    case SAT_sampler1d: {
       ShaderTexSpec bind;
-      bind._parameter = (void*)p;
+      bind._parameter = reference;
       bind._name = InternalName::make(pieces[1]);
       bind._desired_type=Texture::TT_1d_texture;
       _tex_spec.push_back(bind);
       break;
     }
-    case CG_SAMPLER2D: {
+    case SAT_sampler2d: {
       ShaderTexSpec bind;
-      bind._parameter = (void*)p;
+      bind._parameter = reference;
       bind._name = InternalName::make(pieces[1]);
       bind._desired_type=Texture::TT_2d_texture;
       _tex_spec.push_back(bind);
       break;
     }
-    case CG_SAMPLER3D: {
+    case SAT_sampler3d: {
       ShaderTexSpec bind;
-      bind._parameter = (void*)p;
+      bind._parameter = reference;
       bind._name = InternalName::make(pieces[1]);
       bind._desired_type=Texture::TT_3d_texture;
       _tex_spec.push_back(bind);
       break;
     }
-    case CG_SAMPLERCUBE: {
+    case SAT_samplercube: {
       ShaderTexSpec bind;
-      bind._parameter = (void*)p;
+      bind._parameter = reference;
       bind._name = InternalName::make(pieces[1]);
       bind._desired_type = Texture::TT_cube_map;
       _tex_spec.push_back(bind);
       break;
     }
     default:
-      report_cg_parameter_error(p, "Invalid type for a k-parameter");
+      cp_report_error(p, "Invalid type for a k-parameter");
       return false;
     }
     return true;
@@ -644,8 +627,8 @@ compile_cg_parameter(CGparameter p, NotifyCategory *cat)
     return true; // Cg handles this automatically.
   }
 
-  report_cg_parameter_error(p, "unrecognized parameter name");
+  cp_report_error(p, "unrecognized parameter name");
   return false;
 }
 
-#endif // HAVE_CG
+

+ 49 - 22
panda/src/gobj/shaderContext.h

@@ -23,13 +23,6 @@
 #include "internalName.h"
 #include "savedContext.h"
 #include "shaderExpansion.h"
-#ifdef HAVE_CG
-// Instead of including the whole header file, just include these stubs.
-typedef struct _CGcontext *CGcontext;
-typedef struct _CGprogram *CGprogram;
-typedef struct _CGparameter *CGparameter;
-#endif
-
 
 ////////////////////////////////////////////////////////////////////
 //       Class : ShaderContext
@@ -55,6 +48,27 @@ public:
     SHADER_type_frag=1,
     SHADER_type_both=2,
   };
+
+  enum ShaderArgType {
+    SAT_float1,
+    SAT_float2,
+    SAT_float3,
+    SAT_float4,
+    SAT_float4x4,
+    SAT_sampler1d,
+    SAT_sampler2d,
+    SAT_sampler3d,
+    SAT_samplercube,
+    SAT_unknown,
+  };
+
+  enum ShaderArgDir {
+    SAD_in,
+    SAD_out,
+    SAD_inout,
+    SAD_unknown,
+  };
+
   enum ShaderMatOp {
     SMO_identity,
 
@@ -99,6 +113,7 @@ public:
     SMO_transpose,
     SMO_noop,
   };
+
   enum ShaderMatPiece {
     SMP_whole,
     SMP_transpose,
@@ -111,6 +126,7 @@ public:
     SMP_col2,
     SMP_col3,
   };
+
   struct ShaderMatSpec {
     pvector<ShaderMatOp>      _opcodes;
     pvector<PT(InternalName)> _args;
@@ -118,6 +134,7 @@ public:
     bool                      _trans_dependent;
     void                     *_parameter;
   };
+
   struct ShaderTexSpec {
     PT(InternalName)  _name;
     int               _stage;
@@ -125,29 +142,37 @@ public:
     PT(InternalName)  _suffix;
     void             *_parameter;
   };
+
   struct ShaderVarSpec {
     PT(InternalName) _name;
     int              _append_uv;
     void            *_parameter;
   };
 
+  struct ShaderArgInfo {
+    string          _name;
+    ShaderArgType   _type;
+    ShaderArgDir    _direction;
+    bool            _varying;
+    NotifyCategory *_cat;
+  };
+
 protected:
   pvector <ShaderMatSpec> _mat_spec;
   pvector <ShaderTexSpec> _tex_spec;
   pvector <ShaderVarSpec> _var_spec;
   
-#ifdef HAVE_CG
 private:
-  // These functions are only called by 'compile_cg_parameter'
-  NotifyCategory *_cg_report_cat;
-  void report_cg_parameter_error(CGparameter p, const string &msg);
-  bool errchk_cg_parameter_words(CGparameter p, int len);
-  bool errchk_cg_parameter_in(CGparameter p);
-  bool errchk_cg_parameter_varying(CGparameter p);
-  bool errchk_cg_parameter_uniform(CGparameter p);
-  bool errchk_cg_parameter_float(CGparameter p, int lo, int hi);
-  bool errchk_cg_parameter_sampler(CGparameter p);
-  bool parse_cg_trans_clause(CGparameter p,
+  // These functions are only called from compile_parameter.
+
+  void cp_report_error(ShaderArgInfo &arg, const string &msg);
+  bool cp_errchk_parameter_words(ShaderArgInfo &arg, int len);
+  bool cp_errchk_parameter_in(ShaderArgInfo &arg);
+  bool cp_errchk_parameter_varying(ShaderArgInfo &arg);
+  bool cp_errchk_parameter_uniform(ShaderArgInfo &arg);
+  bool cp_errchk_parameter_float(ShaderArgInfo &arg, int lo, int hi);
+  bool cp_errchk_parameter_sampler(ShaderArgInfo &arg);
+  bool cp_parse_trans_clause(ShaderArgInfo &arg,
                              ShaderMatSpec &spec,
                              const vector_string &pieces,
                              int &next,
@@ -155,10 +180,12 @@ private:
                              ShaderMatOp op);
 
 protected:
-  void report_cg_compile_errors(const string &file, CGcontext ctx,
-                                NotifyCategory *cat);
-  bool compile_cg_parameter(CGparameter p, NotifyCategory *cat);
-#endif
+  bool compile_parameter(void *reference,
+                         const string   &arg_name,
+                         ShaderArgType   arg_type,
+                         ShaderArgDir    arg_direction,
+                         bool            arg_varying,
+                         NotifyCategory *arg_cat);
 
 public:
   static TypeHandle get_class_type() {