From 777cad2e5001f13c97e078c70d536c450a660e7f Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Thu, 13 Oct 2005 20:09:40 +0000 Subject: [PATCH] Added code so that one can recommend a profile from inside a shader --- doc/makepanda/config.in | 2 +- doc/makepanda/makepanda.py | 43 +++-- doc/makepanda/makepanda71.vcproj | 2 +- panda/src/glstuff/glShaderContext_src.cxx | 194 +++++++++++++++++----- panda/src/glstuff/glShaderContext_src.h | 5 +- 5 files changed, 176 insertions(+), 70 deletions(-) diff --git a/doc/makepanda/config.in b/doc/makepanda/config.in index 6aa6cde19a..7a21ef06cf 100755 --- a/doc/makepanda/config.in +++ b/doc/makepanda/config.in @@ -11,7 +11,7 @@ load-display pandagl # These control the placement and size of the default rendering window. -win-origin 100 0 +win-origin 50 50 win-size 800 600 # Uncomment this line if you want to run Panda fullscreen instead of diff --git a/doc/makepanda/makepanda.py b/doc/makepanda/makepanda.py index eb663bd1f6..1029fd85b8 100755 --- a/doc/makepanda/makepanda.py +++ b/doc/makepanda/makepanda.py @@ -46,7 +46,6 @@ MAXSDK = {} MAXSDKCS = {} PYTHONSDK=0 STARTTIME=time.time() -BUILTANYTHING=0 SLAVEFILE=0 DEPENDENCYQUEUE=[] 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("MSFORSCOPE")==0): cmd = cmd + ' /Zc:forScope' 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) if (optlevel==1): cmd = cmd + " /MD /Zi /RTCs /GS" 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): -# 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) 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) 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): 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: oscmd("built/bin/egg2bam -pr " + preconv + " -o " + bam + " " + egg) @@ -1939,8 +1942,8 @@ IPATH=['dtool/src/dtoolbase'] OPTS=['BUILDING_DTOOL', 'NSPR', 'OPT3'] EnqueueCxx(ipath=IPATH, opts=OPTS, src='indent.cxx', obj='dtoolbase_indent.obj') 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') else: OPTS.append("USEMALLOC") @@ -4514,7 +4517,6 @@ def AllSourcesReady(task, pending): return 1 def ParallelMake(tasklist): - global BUILTANYTHING # Read the slave-file. slaves = [] if (SLAVEFILE!=0): @@ -4549,7 +4551,6 @@ def ParallelMake(tasklist): if (tasksqueued < len(slaves)*3) & (AllSourcesReady(task, pending)): if (older(task[2], task[3])): tasksqueued += 1 - BUILTANYTHING=1 taskqueue.put(task) else: for target in task[2]: @@ -4573,10 +4574,8 @@ def ParallelMake(tasklist): exit("Dependency problem - task unsatisfied: "+str(tasklist[0][2])) def SequentialMake(tasklist): - global BUILTANYTHING for task in tasklist: if (older(task[2], task[3])): - BUILTANYTHING=1 apply(task[0], task[1]) for target in task[2]: updatefiledate(target) @@ -4640,7 +4639,7 @@ def MakeInstallerNSIS(file,fullname,smdirectory,installdir): os.remove("nsis-output.exe") psource=os.path.abspath(".") panda=os.path.abspath("built") - cmd="thirdparty/win-nsis/makensis.exe /V2 " + cmd="thirdparty/win-nsis/makensis /V2 " cmd=cmd+'/DCOMPRESSOR="'+COMPRESSOR+'" ' cmd=cmd+'/DNAME="'+fullname+'" ' cmd=cmd+'/DSMDIRECTORY="'+smdirectory+'" ' @@ -4717,7 +4716,7 @@ Description: The panda3D free 3D engine oscmd("rm -rf debtmp") -if ((BUILTANYTHING)&(INSTALLER != 0)): +if (INSTALLER != 0): if (sys.platform == "win32"): MakeInstallerNSIS("Panda3D-"+VERSION+".exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION) elif (sys.platform == "linux2") and (os.path.isfile("/usr/bin/dpkg-deb")): diff --git a/doc/makepanda/makepanda71.vcproj b/doc/makepanda/makepanda71.vcproj index eb1ee2a0c4..e689dc1006 100755 --- a/doc/makepanda/makepanda71.vcproj +++ b/doc/makepanda/makepanda71.vcproj @@ -18,7 +18,7 @@ + Output="..\built\bin\test_interrogate.exe"/> diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 0da1c46364..06e2004472 100755 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -31,13 +31,13 @@ CLP(ShaderContext)(ShaderExpansion *s) : ShaderContext(s) { #ifdef HAVE_CGGL _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_frag] = (CGprogram)0; - + if (header == "//Cg") { - + // Create the Cg context. _cg_context = cgCreateContext(); if (_cg_context == 0) { release_resources(); @@ -45,50 +45,36 @@ CLP(ShaderContext)(ShaderExpansion *s) : ShaderContext(s) { return; } - _cg_profile[SHADER_type_vert] = cgGLGetLatestProfile(CG_GL_VERTEX); - _cg_profile[SHADER_type_frag] = cgGLGetLatestProfile(CG_GL_FRAGMENT); + // 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]); + } + } + + // 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); + } + if (_cg_profile[SHADER_type_frag] == CG_PROFILE_UNKNOWN) { + _cg_profile[SHADER_type_frag] = cgGLGetLatestProfile(CG_GL_FRAGMENT); + } + + // 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(); - cerr << "Cg not supported by this video card II\n"; + cerr << "Cg not supported by this video card.\n"; return; } - 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; - } - - 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; - } - - 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; } #endif @@ -96,6 +82,124 @@ CLP(ShaderContext)(ShaderExpansion *s) : ShaderContext(s) { 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_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 // Access: Public @@ -631,7 +735,7 @@ errchk_cg_output(CGparameter p, const string &msg) string err; string fn = _shader_expansion->get_name(); 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++) { string line = trim(errlines[i]); if (line != "") { - cerr << file << " " << errlines[i] << "\n"; + _cg_errors += file + " " + errlines[i] + "\n"; } } } else { - cerr << file << ": " << cgGetErrorString(err) << "\n"; + _cg_errors += file + ": " + cgGetErrorString(err) + "\n"; } } } diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h index 150a96c5df..b5828634b8 100755 --- a/panda/src/glstuff/glShaderContext_src.h +++ b/panda/src/glstuff/glShaderContext_src.h @@ -81,6 +81,7 @@ private: CGcontext _cg_context; CGprofile _cg_profile[2]; CGprogram _cg_program[2]; + string _cg_errors; // These arrays contain lists of "bindings." They // tell us how to fill the shader's input parameters. @@ -92,9 +93,11 @@ private: vector _cg_parameter_bind; vector _cg_varying; + bool try_cg_compile(ShaderExpansion *s); void bind_cg_transform(const ShaderTransBind &stb, 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 errchk_cg_parameter_words(CGparameter p, int len); bool errchk_cg_parameter_direction(CGparameter p, CGenum dir);