Browse Source

Added code so that one can recommend a profile from inside a shader

Josh Yelon 20 years ago
parent
commit
777cad2e50

+ 1 - 1
doc/makepanda/config.in

@@ -11,7 +11,7 @@ load-display pandagl
 
 
 # These control the placement and size of the default rendering window.
 # These control the placement and size of the default rendering window.
 
 
-win-origin 100 0
+win-origin 50 50
 win-size 800 600
 win-size 800 600
 
 
 # Uncomment this line if you want to run Panda fullscreen instead of
 # Uncomment this line if you want to run Panda fullscreen instead of

+ 21 - 22
doc/makepanda/makepanda.py

@@ -46,7 +46,6 @@ MAXSDK = {}
 MAXSDKCS = {}
 MAXSDKCS = {}
 PYTHONSDK=0
 PYTHONSDK=0
 STARTTIME=time.time()
 STARTTIME=time.time()
-BUILTANYTHING=0
 SLAVEFILE=0
 SLAVEFILE=0
 DEPENDENCYQUEUE=[]
 DEPENDENCYQUEUE=[]
 FILEDATECACHE = {}
 FILEDATECACHE = {}
@@ -623,10 +622,10 @@ if (OMIT.count("HELIX")==0):
 #
 #
 ##########################################################################################
 ##########################################################################################
 
 
-if (OMIT.count("OPENCV")==0):
-    WARNINGS.append("OPENCV doesn't work yet")
-    WARNINGS.append("I have automatically added this command-line option: --no-opencv")
-    OMIT.append("OPENCV")
+#if (OMIT.count("OPENCV")==0):
+#    WARNINGS.append("OPENCV doesn't work yet")
+#    WARNINGS.append("I have automatically added this command-line option: --no-opencv")
+#    OMIT.append("OPENCV")
 
 
 ##########################################################################################
 ##########################################################################################
 #
 #
@@ -989,6 +988,8 @@ def CompileCxxMSVC7(wobj,fullsrc,ipath,opts):
     if (opts.count("WITHINPANDA")): cmd = cmd + ' /DWITHIN_PANDA'
     if (opts.count("WITHINPANDA")): cmd = cmd + ' /DWITHIN_PANDA'
     if (opts.count("MSFORSCOPE")==0): cmd = cmd + ' /Zc:forScope'
     if (opts.count("MSFORSCOPE")==0): cmd = cmd + ' /Zc:forScope'
     if (opts.count("USEPTMALLOC2")): cmd = cmd + ' /DUSE_MEMORY_PTMALLOC2'
     if (opts.count("USEPTMALLOC2")): cmd = cmd + ' /DUSE_MEMORY_PTMALLOC2'
+    if (opts.count("USEDLMALLOC")): cmd = cmd + ' /DUSE_MEMORY_DLMALLOC'
+    if (opts.count("USEMALLOC")): cmd = cmd + ' /DUSE_MEMORY_MALLOC'
     optlevel = getoptlevel(opts,OPTIMIZE)
     optlevel = getoptlevel(opts,OPTIMIZE)
     if (optlevel==1): cmd = cmd + " /MD /Zi /RTCs /GS"
     if (optlevel==1): cmd = cmd + " /MD /Zi /RTCs /GS"
     if (optlevel==2): cmd = cmd + " /MD /Zi "
     if (optlevel==2): cmd = cmd + " /MD /Zi "
@@ -1045,16 +1046,17 @@ def EnqueueCxx(obj=0,src=0,ipath=[],opts=[],xdep=[]):
 ########################################################################
 ########################################################################
 
 
 def CompileBisonMSVC7(pre, dsth, dstc, wobj, ipath, opts, src):
 def CompileBisonMSVC7(pre, dsth, dstc, wobj, ipath, opts, src):
-#   CopyFile(".", "thirdparty/win-util/bison.simple")
-    oscmd('thirdparty/win-util/bison -y -d -o built/tmp/y_tab.c -p '+pre+' '+src)
-    CopyFile(dstc, "built/tmp/y_tab.c")
-    CopyFile(dsth, "built/tmp/y_tab.h")
+    ifile = os.path.basename(src)
+    oscmd('thirdparty/win-util/bison -y -d -obuilt/tmp/'+ifile+'.c -p '+pre+' '+src)
+    CopyFile(dstc, "built/tmp/"+ifile+".c")
+    CopyFile(dsth, "built/tmp/"+ifile+".h")
     CompileCxxMSVC7(wobj,dstc,ipath,opts)
     CompileCxxMSVC7(wobj,dstc,ipath,opts)
 
 
 def CompileBisonLINUXA(pre, dsth, dstc, wobj, ipath, opts, src):
 def CompileBisonLINUXA(pre, dsth, dstc, wobj, ipath, opts, src):
-    oscmd("bison -y -d -o built/tmp/y.tab.c -p "+pre+" "+src)
-    CopyFile(dstc, "built/tmp/y.tab.c")
-    CopyFile(dsth, "built/tmp/y.tab.h")
+    ifile = os.path.basename(src)
+    oscmd("bison -y -d -obuilt/tmp/"+src+".c -p "+pre+" "+src)
+    CopyFile(dstc, "built/tmp/"+ifile+".c")
+    CopyFile(dsth, "built/tmp/"+ifile+".h")
     CompileCxxLINUXA(wobj,dstc,ipath,opts)
     CompileCxxLINUXA(wobj,dstc,ipath,opts)
 
 
 def EnqueueBison(ipath=0,opts=0,pre=0,obj=0,dsth=0,src=0):
 def EnqueueBison(ipath=0,opts=0,pre=0,obj=0,dsth=0,src=0):
@@ -1461,8 +1463,9 @@ def EnqueueLink(dll=0, obj=[], opts=[], xdep=[], ldef=0):
 
 
 def CompileBam(preconv, bam, egg):
 def CompileBam(preconv, bam, egg):
     if (egg[-4:] == ".flt"):
     if (egg[-4:] == ".flt"):
-        oscmd("built/bin/flt2egg -pr " + preconv + " -o built/tmp/tmp.egg" + " " + egg)
-        oscmd("built/bin/egg2bam -o " + bam + " built/tmp/tmp.egg")
+        ifile = os.path.basename(egg)
+        oscmd("built/bin/flt2egg -pr " + preconv + " -o built/tmp/"+ifile+".egg" + " " + egg)
+        oscmd("built/bin/egg2bam -o " + bam + " built/tmp/"+ifile+".egg")
     else:
     else:
         oscmd("built/bin/egg2bam -pr " + preconv + " -o " + bam + " " + egg)
         oscmd("built/bin/egg2bam -pr " + preconv + " -o " + bam + " " + egg)
 
 
@@ -1939,8 +1942,8 @@ IPATH=['dtool/src/dtoolbase']
 OPTS=['BUILDING_DTOOL', 'NSPR', 'OPT3']
 OPTS=['BUILDING_DTOOL', 'NSPR', 'OPT3']
 EnqueueCxx(ipath=IPATH, opts=OPTS, src='indent.cxx',    obj='dtoolbase_indent.obj')
 EnqueueCxx(ipath=IPATH, opts=OPTS, src='indent.cxx',    obj='dtoolbase_indent.obj')
 if (sys.platform == "win32"):
 if (sys.platform == "win32"):
-    OPTS.append("USEPTMALLOC2")
-    EnqueueCxx(ipath=IPATH, opts=OPTS, src='ptmalloc2_smp.c', obj='dtoolbase_allocator.obj')
+    OPTS.append("USEDLMALLOC")
+    EnqueueCxx(ipath=IPATH, opts=OPTS, src='dlmalloc.c', obj='dtoolbase_allocator.obj')
     EnqueueCxx(ipath=IPATH, opts=OPTS, src='dtoolbase.cxx', obj='dtoolbase_dtoolbase.obj')
     EnqueueCxx(ipath=IPATH, opts=OPTS, src='dtoolbase.cxx', obj='dtoolbase_dtoolbase.obj')
 else:
 else:
     OPTS.append("USEMALLOC")
     OPTS.append("USEMALLOC")
@@ -4514,7 +4517,6 @@ def AllSourcesReady(task, pending):
     return 1
     return 1
 
 
 def ParallelMake(tasklist):
 def ParallelMake(tasklist):
-    global BUILTANYTHING
     # Read the slave-file.
     # Read the slave-file.
     slaves = []
     slaves = []
     if (SLAVEFILE!=0):
     if (SLAVEFILE!=0):
@@ -4549,7 +4551,6 @@ def ParallelMake(tasklist):
                 if (tasksqueued < len(slaves)*3) & (AllSourcesReady(task, pending)):
                 if (tasksqueued < len(slaves)*3) & (AllSourcesReady(task, pending)):
                     if (older(task[2], task[3])):
                     if (older(task[2], task[3])):
                         tasksqueued += 1
                         tasksqueued += 1
-                        BUILTANYTHING=1
                         taskqueue.put(task)
                         taskqueue.put(task)
                     else:
                     else:
                         for target in task[2]:
                         for target in task[2]:
@@ -4573,10 +4574,8 @@ def ParallelMake(tasklist):
         exit("Dependency problem - task unsatisfied: "+str(tasklist[0][2]))
         exit("Dependency problem - task unsatisfied: "+str(tasklist[0][2]))
 
 
 def SequentialMake(tasklist):
 def SequentialMake(tasklist):
-    global BUILTANYTHING
     for task in tasklist:
     for task in tasklist:
         if (older(task[2], task[3])):
         if (older(task[2], task[3])):
-            BUILTANYTHING=1
             apply(task[0], task[1])
             apply(task[0], task[1])
             for target in task[2]:
             for target in task[2]:
                 updatefiledate(target)
                 updatefiledate(target)
@@ -4640,7 +4639,7 @@ def MakeInstallerNSIS(file,fullname,smdirectory,installdir):
         os.remove("nsis-output.exe")
         os.remove("nsis-output.exe")
     psource=os.path.abspath(".")
     psource=os.path.abspath(".")
     panda=os.path.abspath("built")
     panda=os.path.abspath("built")
-    cmd="thirdparty/win-nsis/makensis.exe /V2 "
+    cmd="thirdparty/win-nsis/makensis /V2 "
     cmd=cmd+'/DCOMPRESSOR="'+COMPRESSOR+'" '
     cmd=cmd+'/DCOMPRESSOR="'+COMPRESSOR+'" '
     cmd=cmd+'/DNAME="'+fullname+'" '
     cmd=cmd+'/DNAME="'+fullname+'" '
     cmd=cmd+'/DSMDIRECTORY="'+smdirectory+'" '
     cmd=cmd+'/DSMDIRECTORY="'+smdirectory+'" '
@@ -4717,7 +4716,7 @@ Description: The panda3D free 3D engine
     oscmd("rm -rf debtmp")
     oscmd("rm -rf debtmp")
 
 
 
 
-if ((BUILTANYTHING)&(INSTALLER != 0)):
+if (INSTALLER != 0):
     if (sys.platform == "win32"):
     if (sys.platform == "win32"):
         MakeInstallerNSIS("Panda3D-"+VERSION+".exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION)
         MakeInstallerNSIS("Panda3D-"+VERSION+".exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION)
     elif (sys.platform == "linux2") and (os.path.isfile("/usr/bin/dpkg-deb")):
     elif (sys.platform == "linux2") and (os.path.isfile("/usr/bin/dpkg-deb")):

+ 1 - 1
doc/makepanda/makepanda71.vcproj

@@ -18,7 +18,7 @@
 			<Tool
 			<Tool
 				Name="VCNMakeTool"
 				Name="VCNMakeTool"
 				BuildCommandLine="cd .. &amp; makepanda\makepanda --everything"
 				BuildCommandLine="cd .. &amp; makepanda\makepanda --everything"
-				Output="..\built\python\python.exe"/>
+				Output="..\built\bin\test_interrogate.exe"/>
 		</Configuration>
 		</Configuration>
 	</Configurations>
 	</Configurations>
 	<References>
 	<References>

+ 147 - 43
panda/src/glstuff/glShaderContext_src.cxx

@@ -31,13 +31,13 @@ CLP(ShaderContext)(ShaderExpansion *s) : ShaderContext(s) {
   
   
 #ifdef HAVE_CGGL
 #ifdef HAVE_CGGL
   _cg_context = (CGcontext)0;
   _cg_context = (CGcontext)0;
-  _cg_profile[SHADER_type_vert] = (CGprofile)0;
-  _cg_profile[SHADER_type_frag] = (CGprofile)0;
+  _cg_profile[SHADER_type_vert] = CG_PROFILE_UNKNOWN;
+  _cg_profile[SHADER_type_frag] = CG_PROFILE_UNKNOWN;
   _cg_program[SHADER_type_vert] = (CGprogram)0;
   _cg_program[SHADER_type_vert] = (CGprogram)0;
   _cg_program[SHADER_type_frag] = (CGprogram)0;
   _cg_program[SHADER_type_frag] = (CGprogram)0;
-
+  
   if (header == "//Cg") {
   if (header == "//Cg") {
-
+    // Create the Cg context.
     _cg_context = cgCreateContext();
     _cg_context = cgCreateContext();
     if (_cg_context == 0) {
     if (_cg_context == 0) {
       release_resources();
       release_resources();
@@ -45,50 +45,36 @@ CLP(ShaderContext)(ShaderExpansion *s) : ShaderContext(s) {
       return;
       return;
     }
     }
     
     
-    _cg_profile[SHADER_type_vert] = cgGLGetLatestProfile(CG_GL_VERTEX);
-    _cg_profile[SHADER_type_frag] = cgGLGetLatestProfile(CG_GL_FRAGMENT);
-    if ((_cg_profile[SHADER_type_vert] == CG_PROFILE_UNKNOWN)||
-        (_cg_profile[SHADER_type_frag] == CG_PROFILE_UNKNOWN)) {
-      release_resources();
-      cerr << "Cg not supported by this video card II\n";
-      return;
+    // Parse any directives in the source.
+    string directive;
+    while (!s->parse_eof()) {
+      s->parse_line(directive, true, true);
+      vector_string pieces;
+      tokenize(directive, pieces, " \t");
+      if ((pieces.size()==4)&&(pieces[0]=="//Cg")&&(pieces[1]=="profile")) {
+        suggest_cg_profile(pieces[2], pieces[3]);
+      }
     }
     }
     
     
-    cgGetError();
-    _cg_program[0] =
-      cgCreateProgram(_cg_context, CG_SOURCE, s->_text.c_str(),
-                      _cg_profile[0], "vshader", (const char**)NULL);
-    print_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);
-    print_cg_compile_errors(s->get_name(), _cg_context);
-
-    if ((_cg_program[SHADER_type_vert]==0)||(_cg_program[SHADER_type_frag]==0)) {
-      release_resources();
-      return;
+    // Select a profile if no preferred profile specified in the source.
+    if (_cg_profile[SHADER_type_vert] == CG_PROFILE_UNKNOWN) {
+      _cg_profile[SHADER_type_vert] = cgGLGetLatestProfile(CG_GL_VERTEX);
     }
     }
-
-    bool success = true;
-    CGparameter parameter;
-    for (int progindex=0; progindex<2; progindex++) {
-      for (parameter = cgGetFirstLeafParameter(_cg_program[progindex],CG_PROGRAM);
-           parameter != 0;
-           parameter = cgGetNextLeafParameter(parameter)) {
-        success &= compile_cg_parameter(parameter);
-      }
+    if (_cg_profile[SHADER_type_frag] == CG_PROFILE_UNKNOWN) {
+      _cg_profile[SHADER_type_frag] = cgGLGetLatestProfile(CG_GL_FRAGMENT);
     }
     }
-    if (!success) {
+    
+    // If we still haven't chosen a profile, give up.
+    if ((_cg_profile[SHADER_type_vert] == CG_PROFILE_UNKNOWN)||
+        (_cg_profile[SHADER_type_frag] == CG_PROFILE_UNKNOWN)) {
       release_resources();
       release_resources();
+      cerr << "Cg not supported by this video card.\n";
       return;
       return;
     }
     }
-        
-    cgGLLoadProgram(_cg_program[SHADER_type_vert]);
-    cgGLLoadProgram(_cg_program[SHADER_type_frag]);
     
     
-    cerr << s->get_name() << ": compiled ok.\n";
+    // Compile the program.
+    try_cg_compile(s);
+    cerr << _cg_errors;
     return;
     return;
   }
   }
 #endif
 #endif
@@ -96,6 +82,124 @@ CLP(ShaderContext)(ShaderExpansion *s) : ShaderContext(s) {
   cerr << s->get_name() << ": unrecognized shader language " << header << "\n";
   cerr << s->get_name() << ": unrecognized shader language " << header << "\n";
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GLShaderContext::suggest_cg_profile
+//       Access: Private
+//  Description: xyz
+////////////////////////////////////////////////////////////////////
+#ifdef HAVE_CGGL
+void CLP(ShaderContext)::
+suggest_cg_profile(const string &vpro, const string &fpro)
+{
+  // If a good profile has already been suggested, ignore suggestion.
+  if ((_cg_profile[SHADER_type_vert] != CG_PROFILE_UNKNOWN)||
+      (_cg_profile[SHADER_type_frag] != CG_PROFILE_UNKNOWN)) {
+    return;
+  }
+  
+  // Parse the suggestion. If not parseable, print error and ignore.
+  _cg_profile[SHADER_type_vert] = parse_cg_profile(vpro, true);
+  _cg_profile[SHADER_type_frag] = parse_cg_profile(fpro, false);
+  if ((_cg_profile[SHADER_type_vert] == CG_PROFILE_UNKNOWN)||
+      (_cg_profile[SHADER_type_frag] == CG_PROFILE_UNKNOWN)) {
+    cerr << "Cg: unrecognized profile name: " << vpro << " " << fpro << "\n";
+    _cg_profile[SHADER_type_vert] = CG_PROFILE_UNKNOWN;
+    _cg_profile[SHADER_type_frag] = CG_PROFILE_UNKNOWN;
+    return;
+  }
+
+  // If the suggestion is parseable, but not supported, ignore silently.
+  if ((!cgGLIsProfileSupported(_cg_profile[SHADER_type_vert]))||
+      (!cgGLIsProfileSupported(_cg_profile[SHADER_type_frag]))) {
+    _cg_profile[SHADER_type_vert] = CG_PROFILE_UNKNOWN;
+    _cg_profile[SHADER_type_frag] = CG_PROFILE_UNKNOWN;
+    return;
+  }
+}
+#endif
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLShaderContext::parse_cg_profile
+//       Access: Private
+//  Description: xyz
+////////////////////////////////////////////////////////////////////
+#ifdef HAVE_CGGL
+CGprofile CLP(ShaderContext)::
+parse_cg_profile(const string &id, bool vertex)
+{
+  int nvprofiles = 4;
+  int nfprofiles = 4;
+  CGprofile vprofiles[] = { CG_PROFILE_ARBVP1, CG_PROFILE_VP20, CG_PROFILE_VP30, CG_PROFILE_VP40 };
+  CGprofile fprofiles[] = { CG_PROFILE_ARBFP1, CG_PROFILE_FP20, CG_PROFILE_FP30, CG_PROFILE_FP40 };
+  if (vertex) {
+    for (int i=0; i<nvprofiles; i++) {
+      if (id == cgGetProfileString(vprofiles[i])) {
+        return vprofiles[i];
+      }
+    }
+  } else {
+    for (int i=0; i<nfprofiles; i++) {
+      if (id == cgGetProfileString(fprofiles[i])) {
+        return fprofiles[i];
+      }
+    }
+  }
+  return CG_PROFILE_UNKNOWN;
+}
+#endif HAVE_CGGL
+
+////////////////////////////////////////////////////////////////////
+//     Function: GLShaderContext::try_cg_compile
+//       Access: Private
+//  Description: xyz
+////////////////////////////////////////////////////////////////////
+#ifdef HAVE_CGGL
+bool CLP(ShaderContext)::
+try_cg_compile(ShaderExpansion *s)
+{
+  _cg_errors = "";
+  
+  cgGetError();
+  _cg_program[0] =
+    cgCreateProgram(_cg_context, CG_SOURCE, s->_text.c_str(),
+                    _cg_profile[0], "vshader", (const char**)NULL);
+  print_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);
+  print_cg_compile_errors(s->get_name(), _cg_context);
+  
+  if ((_cg_program[SHADER_type_vert]==0)||(_cg_program[SHADER_type_frag]==0)) {
+    release_resources();
+    return false;
+  }
+  
+  bool success = true;
+  CGparameter parameter;
+  for (int progindex=0; progindex<2; progindex++) {
+    for (parameter = cgGetFirstLeafParameter(_cg_program[progindex],CG_PROGRAM);
+         parameter != 0;
+         parameter = cgGetNextLeafParameter(parameter)) {
+      success &= compile_cg_parameter(parameter);
+    }
+  }
+  if (!success) {
+    release_resources();
+    return false;
+  }
+  
+  cgGLLoadProgram(_cg_program[SHADER_type_vert]);
+  cgGLLoadProgram(_cg_program[SHADER_type_frag]);
+  
+  _cg_errors = s->get_name() + ": compiled to "
+    + cgGetProfileString(_cg_profile[SHADER_type_vert]) + " "
+    + cgGetProfileString(_cg_profile[SHADER_type_frag]) + "\n";
+  return true;
+}
+#endif
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GLShaderContext::Destructor
 //     Function: GLShaderContext::Destructor
 //       Access: Public
 //       Access: Public
@@ -631,7 +735,7 @@ errchk_cg_output(CGparameter p, const string &msg)
   string err;
   string err;
   string fn = _shader_expansion->get_name();
   string fn = _shader_expansion->get_name();
   err = fn + ": " + msg + " (" + vstr + dstr + ts + " " + cgGetParameterName(p) + ")\n";
   err = fn + ": " + msg + " (" + vstr + dstr + ts + " " + cgGetParameterName(p) + ")\n";
-  cerr << err << "\n";
+  _cg_errors = _cg_errors + err + "\n";
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -654,11 +758,11 @@ print_cg_compile_errors(const string &file, CGcontext ctx)
       for (int i=0; i<(int)errlines.size(); i++) {
       for (int i=0; i<(int)errlines.size(); i++) {
         string line = trim(errlines[i]);
         string line = trim(errlines[i]);
         if (line != "") {
         if (line != "") {
-          cerr << file << " " << errlines[i] << "\n";
+          _cg_errors += file + " " + errlines[i] + "\n";
         }
         }
       }
       }
     } else {
     } else {
-      cerr << file << ": " << cgGetErrorString(err) << "\n";
+      _cg_errors += file + ": " + cgGetErrorString(err) + "\n";
     }
     }
   }
   }
 }
 }

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

@@ -81,6 +81,7 @@ private:
   CGcontext _cg_context;
   CGcontext _cg_context;
   CGprofile _cg_profile[2];
   CGprofile _cg_profile[2];
   CGprogram _cg_program[2];
   CGprogram _cg_program[2];
+  string    _cg_errors;
   
   
   // These arrays contain lists of "bindings." They
   // These arrays contain lists of "bindings." They
   // tell us how to fill the shader's input parameters.
   // tell us how to fill the shader's input parameters.
@@ -92,9 +93,11 @@ private:
   vector <ShaderTransBind> _cg_parameter_bind;
   vector <ShaderTransBind> _cg_parameter_bind;
   vector <ShaderVarying> _cg_varying;
   vector <ShaderVarying> _cg_varying;
   
   
+  bool try_cg_compile(ShaderExpansion *s);
   void bind_cg_transform(const ShaderTransBind &stb,
   void bind_cg_transform(const ShaderTransBind &stb,
                          CLP(GraphicsStateGuardian) *gsg);
                          CLP(GraphicsStateGuardian) *gsg);
-  
+  void suggest_cg_profile(const string &vpro, const string &fpro);
+  CGprofile parse_cg_profile(const string &id, bool vertex);
   bool compile_cg_parameter(CGparameter p);
   bool compile_cg_parameter(CGparameter p);
   bool errchk_cg_parameter_words(CGparameter p, int len);
   bool errchk_cg_parameter_words(CGparameter p, int len);
   bool errchk_cg_parameter_direction(CGparameter p, CGenum dir);
   bool errchk_cg_parameter_direction(CGparameter p, CGenum dir);