diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 780200588c..f6f07fd53b 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -358,7 +358,7 @@ rebuild_bitplanes() { int update; update = false; - for (int f = 0; f < 6; f++) { + for (int f = 0; f < 6; f++) { if (_cubemap_fbo [f] == 0) { glgsg->_glGenFramebuffers(1, &_cubemap_fbo [f]); update = true; @@ -369,7 +369,7 @@ rebuild_bitplanes() { } } - if (update) { + if (update) { int color_attachment = GL_COLOR_ATTACHMENT0_EXT; for (int i=0; ibind_fbo(_cubemap_fbo [f]); glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, color_attachment, GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index df02a377d4..f50fdb548c 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -834,36 +834,29 @@ reset() { if (basic_shaders_only) { _shader_caps._active_vprofile = (int)CG_PROFILE_ARBVP1; _shader_caps._active_fprofile = (int)CG_PROFILE_ARBFP1; - _shader_caps._active_gprofile = (int)0; // No geometry shader if only using basic + _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN; // No geometry shader if only using basic } else { _shader_caps._active_vprofile = (int)cgGLGetLatestProfile(CG_GL_VERTEX); _shader_caps._active_fprofile = (int)cgGLGetLatestProfile(CG_GL_FRAGMENT); -#ifdef CG_CL_GEOMETRY _shader_caps._active_gprofile = (int)cgGLGetLatestProfile(CG_GL_GEOMETRY); -#else - _shader_caps._active_gprofile = (int)0; -#endif } _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VP40; _shader_caps._ultimate_fprofile = (int)CG_PROFILE_FP40; -#ifdef CG_PROFILE_GPU_CP _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GPU_GP; -#else - _shader_caps._ultimate_gprofile = (int)0; -#endif + _glBindProgram = (PFNGLBINDPROGRAMARBPROC) get_extension_func(GLPREFIX_QUOTED, "BindProgramARB"); // Bug workaround for radeons. // For some reason, OSX reports to have this extension too, // even when there's no ATI card, resulting in cgc not being // able to find the hint. So, I've disabled the hack there. -#ifndef IS_OSX +#ifndef __APPLE__ if (_shader_caps._active_fprofile == CG_PROFILE_ARBFP1) { if (has_extension("GL_ATI_draw_buffers")) { _shader_caps._bug_list.insert(Shader::SBUG_ati_draw_buffers); } } -#endif // IS_OSX +#endif // __APPLE__ } #endif // HAVE_CG diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 0cf60ad5de..cc2f860520 100755 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -57,39 +57,39 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) { // Load the program. - cgGLLoadProgram(_cg_vprogram); - CGerror verror = cgGetError(); - if (verror != CG_NO_ERROR) { - const char *str = (const char *)GLP(GetString)(GL_PROGRAM_ERROR_STRING_ARB); - GLCAT.error() << "Could not load Cg vertex program:" << s->get_filename() << " (" << - cgGetProfileString(cgGetProgramProfile(_cg_vprogram)) << " " << str << ")\n"; - release_resources(gsg); + if (_cg_vprogram != 0) { + cgGLLoadProgram(_cg_vprogram); + CGerror verror = cgGetError(); + if (verror != CG_NO_ERROR) { + const char *str = (const char *)GLP(GetString)(GL_PROGRAM_ERROR_STRING_ARB); + GLCAT.error() << "Could not load Cg vertex program:" << s->get_filename(Shader::ST_vertex) << " (" << + cgGetProfileString(cgGetProgramProfile(_cg_vprogram)) << " " << str << ")\n"; + release_resources(gsg); + } } - cgGLLoadProgram(_cg_fprogram); - CGerror ferror = cgGetError(); - if (ferror != CG_NO_ERROR) { - const char *str = (const char *)GLP(GetString)(GL_PROGRAM_ERROR_STRING_ARB); - GLCAT.error() << "Could not load Cg fragment program:" << s->get_filename() << " (" << - cgGetProfileString(cgGetProgramProfile(_cg_fprogram)) << " " << str << ")\n"; - release_resources(gsg); + + if (_cg_fprogram != 0) { + cgGLLoadProgram(_cg_fprogram); + CGerror ferror = cgGetError(); + if (ferror != CG_NO_ERROR) { + const char *str = (const char *)GLP(GetString)(GL_PROGRAM_ERROR_STRING_ARB); + GLCAT.error() << "Could not load Cg fragment program:" << s->get_filename(Shader::ST_fragment) << " (" << + cgGetProfileString(cgGetProgramProfile(_cg_fprogram)) << " " << str << ")\n"; + release_resources(gsg); + } } - gsg->report_my_gl_errors(); + if (_cg_gprogram != 0) { cgGLLoadProgram(_cg_gprogram); - if (GLCAT.is_debug()) { - GLCAT.debug() - << "Loaded geom prog: " << _cg_gprogram << "\n"; - } - CGerror gerror = cgGetError(); if (gerror != CG_NO_ERROR) { const char *str = (const char *)GLP(GetString)(GL_PROGRAM_ERROR_STRING_ARB); - GLCAT.error() << "Could not load Cg geometry program:" << s->get_filename() << " (" << + GLCAT.error() << "Could not load Cg geometry program:" << s->get_filename(Shader::ST_geometry) << " (" << cgGetProfileString(cgGetProgramProfile(_cg_gprogram)) << " " << str << ")\n"; release_resources(gsg); } - gsg->report_my_gl_errors(); } + gsg->report_my_gl_errors(); } #endif @@ -416,10 +416,14 @@ bind(GSG *gsg, bool reissue_parameters) { #ifdef HAVE_CG if (_cg_context != 0) { // Bind the shaders. - cgGLEnableProfile(cgGetProgramProfile(_cg_vprogram)); - cgGLBindProgram(_cg_vprogram); - cgGLEnableProfile(cgGetProgramProfile(_cg_fprogram)); - cgGLBindProgram(_cg_fprogram); + if (_cg_vprogram != 0) { + cgGLEnableProfile(cgGetProgramProfile(_cg_vprogram)); + cgGLBindProgram(_cg_vprogram); + } + if (_cg_fprogram != 0) { + cgGLEnableProfile(cgGetProgramProfile(_cg_fprogram)); + cgGLBindProgram(_cg_fprogram); + } if (_cg_gprogram != 0) { cgGLEnableProfile(cgGetProgramProfile(_cg_gprogram)); cgGLBindProgram(_cg_gprogram); @@ -443,8 +447,12 @@ unbind(GSG *gsg) { #ifdef HAVE_CG if (_cg_context != 0) { - cgGLDisableProfile(cgGetProgramProfile(_cg_vprogram)); - cgGLDisableProfile(cgGetProgramProfile(_cg_fprogram)); + if (_cg_vprogram != 0) { + cgGLDisableProfile(cgGetProgramProfile(_cg_vprogram)); + } + if (_cg_fprogram != 0) { + cgGLDisableProfile(cgGetProgramProfile(_cg_fprogram)); + } if (_cg_gprogram != 0) { cgGLDisableProfile(cgGetProgramProfile(_cg_gprogram)); } @@ -835,7 +843,7 @@ void CLP(ShaderContext):: cg_report_errors() { CGerror err = cgGetError(); if (err != CG_NO_ERROR) { - GLCAT.error() << _shader->get_filename() << " " << cgGetErrorString(err) << "\n"; + GLCAT.error() << cgGetErrorString(err) << "\n"; } } #endif diff --git a/panda/src/gobj/shader.I b/panda/src/gobj/shader.I index 15e7104662..c5d431ce76 100755 --- a/panda/src/gobj/shader.I +++ b/panda/src/gobj/shader.I @@ -153,8 +153,10 @@ operator == (const ShaderCaps &other) const { #ifdef HAVE_CG if ((_active_vprofile != other._active_vprofile) || (_active_fprofile != other._active_fprofile) || + (_active_gprofile != other._active_gprofile) || (_ultimate_vprofile != other._ultimate_vprofile) || - (_ultimate_fprofile != other._ultimate_fprofile)) { + (_ultimate_fprofile != other._ultimate_fprofile) || + (_ultimate_gprofile != other._ultimate_gprofile)) { return false; } #endif diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 2770ae74ee..29fd521c5b 100755 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -1229,17 +1229,30 @@ cg_compile_shader(const ShaderCaps &caps) { if (!_text->_separate || !_text->_vertex.empty()) { _cg_vprogram = cg_compile_entry_point("vshader", caps, ST_vertex); + if (_cg_vprogram == 0) { + cg_release_resources(); + return false; + } } if (!_text->_separate || !_text->_fragment.empty()) { _cg_fprogram = cg_compile_entry_point("fshader", caps, ST_fragment); + if (_cg_fprogram == 0) { + cg_release_resources(); + return false; + } } if ((_text->_separate && !_text->_geometry.empty()) || (!_text->_separate && _text->_shared.find("gshader") != -1)) { _cg_gprogram = cg_compile_entry_point("gshader", caps, ST_geometry); + if (_cg_gprogram == 0) { + cg_release_resources(); + return false; + } } - if ((_cg_vprogram == 0)||(_cg_fprogram == 0)) { + if (_cg_vprogram == 0 && _cg_fprogram == 0 && _cg_gprogram == 0) { + gobj_cat.error() << "Shader must at least have one program!\n"; cg_release_resources(); return false; } @@ -1253,7 +1266,7 @@ cg_compile_shader(const ShaderCaps &caps) { // Description: //////////////////////////////////////////////////////////////////// bool Shader:: -cg_analyze_entry_point(CGprogram prog, ShaderType type /*bool fshader*/) { // CG2 CHANGE +cg_analyze_entry_point(CGprogram prog, ShaderType type) { CGparameter parameter; bool success = true; for (parameter = cgGetFirstLeafParameter(prog, CG_PROGRAM); @@ -1265,7 +1278,7 @@ cg_analyze_entry_point(CGprogram prog, ShaderType type /*bool fshader*/) { // C ShaderArgId id; id._name = cgGetParameterName(parameter); - id._type = type; // CG2 CHANGE + id._type = type; id._seqno = -1; success &= compile_parameter(id, cg_parameter_type(parameter), @@ -1317,10 +1330,12 @@ cg_analyze_shader(const ShaderCaps &caps) { return false; } - if (!cg_analyze_entry_point(_cg_fprogram, ST_fragment)) { - cg_release_resources(); - clear_parameters(); - return false; + if (_cg_fprogram != 0) { + if (!cg_analyze_entry_point(_cg_fprogram, ST_fragment)) { + cg_release_resources(); + clear_parameters(); + return false; + } } if (_var_spec.size() != 0) { @@ -1330,10 +1345,12 @@ cg_analyze_shader(const ShaderCaps &caps) { return false; } - if (!cg_analyze_entry_point(_cg_vprogram, ST_vertex)) { - cg_release_resources(); - clear_parameters(); - return false; + if (_cg_vprogram != 0) { + if (!cg_analyze_entry_point(_cg_vprogram, ST_vertex)) { + cg_release_resources(); + clear_parameters(); + return false; + } } if (_cg_gprogram != 0) { @@ -1362,16 +1379,16 @@ cg_analyze_shader(const ShaderCaps &caps) { const char *pixel_program; const char *geometry_program; - vertex_program = cgGetProgramString (_cg_vprogram, CG_COMPILED_PROGRAM); - pixel_program = cgGetProgramString (_cg_fprogram, CG_COMPILED_PROGRAM); + if (_cg_vprogram != 0) { + vertex_program = cgGetProgramString (_cg_vprogram, CG_COMPILED_PROGRAM); + gobj_cat.debug() << vertex_program << "\n"; + } + if (_cg_fprogram != 0) { + pixel_program = cgGetProgramString (_cg_fprogram, CG_COMPILED_PROGRAM); + gobj_cat.debug() << pixel_program << "\n"; + } if (_cg_gprogram != 0) { geometry_program = cgGetProgramString (_cg_gprogram, CG_COMPILED_PROGRAM); - } - - gobj_cat.debug() << vertex_program << "\n"; - gobj_cat.debug() << pixel_program << "\n"; - - if (_cg_gprogram != 0) { gobj_cat.debug() << geometry_program << "\n"; } } @@ -1492,7 +1509,7 @@ cg_compile_for(const ShaderCaps &caps, CGcontext &ctx, CGprogram &vprogram, CGprogram &fprogram, - CGprogram &gprogram, // CG2 CHANGE + CGprogram &gprogram, pvector &map) { // Initialize the return values to empty. @@ -1500,7 +1517,7 @@ cg_compile_for(const ShaderCaps &caps, ctx = 0; vprogram = 0; fprogram = 0; - gprogram = 0; // CG2 CHANGE + gprogram = 0; map.clear(); @@ -1515,13 +1532,31 @@ cg_compile_for(const ShaderCaps &caps, // If the compile routine used the ultimate profile instead of the // active one, it means the active one isn't powerful enough to // compile the shader. - // This does not apply when a custom profile is set. - if ((_cg_vprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_vprogram) != caps._active_vprofile) || - (_cg_fprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_fprogram) != caps._active_fprofile)) { - gobj_cat.error() << "Cg program too complex for driver: " - << get_filename() << ". Try choosing a different profile.\n"; - return false; + if (_filename->_separate) { + if (_cg_vprogram != 0 && _cg_vprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_vprogram) != caps._active_vprofile) { + gobj_cat.error() << "Cg vprogram too complex for driver: " + << get_filename(ST_vertex) << ". Try choosing a different profile.\n"; + return false; + } + if (_cg_fprogram != 0 && _cg_fprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_fprogram) != caps._active_fprofile) { + gobj_cat.error() << "Cg fprogram too complex for driver: " + << get_filename(ST_fragment) << ". Try choosing a different profile.\n"; + return false; + } + if (_cg_gprogram != 0 && _cg_gprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_gprogram) != caps._active_gprofile) { + gobj_cat.error() << "Cg gprogram too complex for driver: " + << get_filename(ST_geometry) << ". Try choosing a different profile.\n"; + return false; + } + } else { + if ((_cg_vprogram != 0 && _cg_vprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_vprogram) != caps._active_vprofile) || + (_cg_fprogram != 0 && _cg_fprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_fprogram) != caps._active_fprofile) || + (_cg_gprogram != 0 && _cg_gprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_gprogram) != caps._active_gprofile)) { + gobj_cat.error() << "Cg program too complex for driver: " + << get_filename() << ". Try choosing a different profile.\n"; + return false; + } } // Build a parameter map. @@ -1561,12 +1596,12 @@ cg_compile_for(const ShaderCaps &caps, ctx = _cg_context; vprogram = _cg_vprogram; fprogram = _cg_fprogram; - gprogram = _cg_gprogram; // CG2 CHANGE + gprogram = _cg_gprogram; _cg_context = 0; _cg_vprogram = 0; _cg_fprogram = 0; - _cg_gprogram = 0; // CG2 CHANGE + _cg_gprogram = 0; _cg_last_caps.clear(); @@ -1594,11 +1629,11 @@ Shader(CPT(ShaderFile) filename, CPT(ShaderFile) text, const ShaderLanguage &lan _cg_context = 0; _cg_vprogram = 0; _cg_fprogram = 0; - _cg_gprogram = 0; // CG2 CHANGE + _cg_gprogram = 0; _cg_vprofile = CG_PROFILE_UNKNOWN; _cg_fprofile = CG_PROFILE_UNKNOWN; _cg_gprofile = CG_PROFILE_UNKNOWN; - if (_default_caps._ultimate_vprofile == 0) { + if (_default_caps._ultimate_vprofile == 0 || _default_caps._ultimate_vprofile == CG_PROFILE_UNKNOWN) { _default_caps._active_vprofile = CG_PROFILE_UNKNOWN; _default_caps._active_fprofile = CG_PROFILE_UNKNOWN; _default_caps._ultimate_vprofile = cgGetProfile("glslv"); @@ -1614,8 +1649,7 @@ Shader(CPT(ShaderFile) filename, CPT(ShaderFile) text, const ShaderLanguage &lan parse_line(header, true, true); if (header == "//Cg") { _language = SL_Cg; - } - if (header == "//GLSL") { + } else if (header == "//GLSL") { _language = SL_GLSL; } } @@ -1680,7 +1714,6 @@ cg_get_profile_from_header(ShaderCaps& caps) { if ((int)buf.find("gp4vp") >= 0) caps._active_vprofile = cgGetProfile("gp4vp"); - // older if ((int)buf.find("glslv") >= 0) caps._active_vprofile = cgGetProfile("glslv"); @@ -1708,11 +1741,13 @@ cg_get_profile_from_header(ShaderCaps& caps) { if ((int)buf.find("vs_3_0") >= 0) caps._active_vprofile = cgGetProfile("vs_3_0"); + if ((int)buf.find("vs_4_0") >= 0) + caps._active_vprofile = cgGetProfile("vs_4_0"); + // Scan the line for known cg2 fragment program profiles if ((int)buf.find("gp4fp") >= 0) caps._active_fprofile = cgGetProfile("gp4fp"); - // older if ((int)buf.find("glslf") >= 0) caps._active_fprofile = cgGetProfile("glslf"); @@ -1746,9 +1781,18 @@ cg_get_profile_from_header(ShaderCaps& caps) { if ((int)buf.find("ps_3_0") >= 0) caps._active_fprofile = cgGetProfile("ps_3_0"); + if ((int)buf.find("ps_4_0") >= 0) + caps._active_fprofile = cgGetProfile("ps_4_0"); + // Scan the line for known cg2 geometry program profiles if ((int)buf.find("gp4gp") >= 0) caps._active_gprofile = cgGetProfile("gp4gp"); + + if ((int)buf.find("glslg") >= 0) + caps._active_gprofile = cgGetProfile("glslg"); + + if ((int)buf.find("gs_4_0") >= 0) + caps._active_gprofile = cgGetProfile("gs_4_0"); } } while(_parse > lastParse); @@ -2116,17 +2160,14 @@ release_all() { void Shader::ShaderCaps:: clear() { _supports_glsl = false; - + #ifdef HAVE_CG - _active_vprofile = 0; - _active_fprofile = 0; - _ultimate_vprofile = 0; - _ultimate_fprofile = 0; - - // BEGIN CG2 CHANGE - _active_gprofile = 0; - _ultimate_gprofile = 0; - // END CG2 CHANGE + _active_vprofile = CG_PROFILE_UNKNOWN; + _active_fprofile = CG_PROFILE_UNKNOWN; + _active_gprofile = CG_PROFILE_UNKNOWN; + _ultimate_vprofile = CG_PROFILE_UNKNOWN; + _ultimate_fprofile = CG_PROFILE_UNKNOWN; + _ultimate_gprofile = CG_PROFILE_UNKNOWN; #endif }