mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
Fix crash when cleaning up GLSL shader
This commit is contained in:
parent
99df904c89
commit
ab2737ac1a
@ -28,8 +28,7 @@ valid() {
|
|||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
if (_cg_context) return true;
|
if (_cg_context) return true;
|
||||||
#endif
|
#endif
|
||||||
if (_shader->get_language() == Shader::SL_GLSL &&
|
if (_shader->get_language() == Shader::SL_GLSL && _glsl_program != 0) {
|
||||||
_shader->_glsl_program != 0) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -33,6 +33,10 @@ TypeHandle CLP(ShaderContext)::_type_handle;
|
|||||||
CLP(ShaderContext)::
|
CLP(ShaderContext)::
|
||||||
CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
||||||
_last_gsg = gsg;
|
_last_gsg = gsg;
|
||||||
|
_glsl_program = 0;
|
||||||
|
_glsl_vshader = 0;
|
||||||
|
_glsl_fshader = 0;
|
||||||
|
_glsl_gshader = 0;
|
||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
_cg_context = 0;
|
_cg_context = 0;
|
||||||
if (s->get_language() == Shader::SL_Cg) {
|
if (s->get_language() == Shader::SL_Cg) {
|
||||||
@ -93,24 +97,25 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
|
|||||||
|
|
||||||
if (s->get_language() == Shader::SL_GLSL) {
|
if (s->get_language() == Shader::SL_GLSL) {
|
||||||
// We compile and analyze the shader here, instead of in shader.cxx, to avoid gobj getting a dependency on GL stuff.
|
// We compile and analyze the shader here, instead of in shader.cxx, to avoid gobj getting a dependency on GL stuff.
|
||||||
if (s->_glsl_program == 0) {
|
if (_glsl_program == 0) {
|
||||||
if (!glsl_compile_shader(gsg)) {
|
if (!glsl_compile_shader(gsg)) {
|
||||||
release_resources(gsg);
|
release_resources(gsg);
|
||||||
s->_error_flag = true;
|
s->_error_flag = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
s->_glsl_parameter_map.clear();
|
// Analyze the uniforms and put them in _glsl_parameter_map
|
||||||
|
if (s->_glsl_parameter_map.size() == 0) {
|
||||||
int seqno = 0, texunitno = 0;
|
int seqno = 0, texunitno = 0;
|
||||||
int num_uniforms, uniform_maxlength;
|
int num_uniforms, uniform_maxlength;
|
||||||
gsg->_glGetProgramiv(s->_glsl_program, GL_ACTIVE_UNIFORMS, &num_uniforms);
|
gsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_UNIFORMS, &num_uniforms);
|
||||||
gsg->_glGetProgramiv(s->_glsl_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniform_maxlength);
|
gsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniform_maxlength);
|
||||||
for (int i = 0; i < num_uniforms; ++i) {
|
for (int i = 0; i < num_uniforms; ++i) {
|
||||||
int param_size;
|
int param_size;
|
||||||
GLenum param_type;
|
GLenum param_type;
|
||||||
char param_name[uniform_maxlength];
|
char param_name[uniform_maxlength];
|
||||||
gsg->_glGetActiveUniform(_shader->_glsl_program, i, uniform_maxlength, NULL, ¶m_size, ¶m_type, param_name);
|
gsg->_glGetActiveUniform(_glsl_program, i, uniform_maxlength, NULL, ¶m_size, ¶m_type, param_name);
|
||||||
GLint p = gsg->_glGetUniformLocation(_shader->_glsl_program, param_name);
|
GLint p = gsg->_glGetUniformLocation(_glsl_program, param_name);
|
||||||
if (p > -1) {
|
if (p > -1) {
|
||||||
Shader::ShaderArgId arg_id;
|
Shader::ShaderArgId arg_id;
|
||||||
arg_id._name = param_name;
|
arg_id._name = param_name;
|
||||||
@ -259,24 +264,24 @@ release_resources(const GSG *gsg) {
|
|||||||
if (!gsg) {
|
if (!gsg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_shader->_glsl_program != 0) {
|
if (_glsl_program != 0) {
|
||||||
if (!_shader->_glsl_vshader != 0) {
|
if (!_glsl_vshader != 0) {
|
||||||
gsg->_glDetachShader(_shader->_glsl_program, _shader->_glsl_vshader);
|
gsg->_glDetachShader(_glsl_program, _glsl_vshader);
|
||||||
gsg->_glDeleteShader(_shader->_glsl_vshader);
|
gsg->_glDeleteShader(_glsl_vshader);
|
||||||
_shader->_glsl_vshader = 0;
|
_glsl_vshader = 0;
|
||||||
}
|
}
|
||||||
if (!_shader->_glsl_fshader != 0) {
|
if (!_glsl_fshader != 0) {
|
||||||
gsg->_glDetachShader(_shader->_glsl_program, _shader->_glsl_fshader);
|
gsg->_glDetachShader(_glsl_program, _glsl_fshader);
|
||||||
gsg->_glDeleteShader(_shader->_glsl_fshader);
|
gsg->_glDeleteShader(_glsl_fshader);
|
||||||
_shader->_glsl_fshader = 0;
|
_glsl_fshader = 0;
|
||||||
}
|
}
|
||||||
if (!_shader->_glsl_gshader != 0) {
|
if (!_glsl_gshader != 0) {
|
||||||
gsg->_glDetachShader(_shader->_glsl_program, _shader->_glsl_gshader);
|
gsg->_glDetachShader(_glsl_program, _glsl_gshader);
|
||||||
gsg->_glDeleteShader(_shader->_glsl_gshader);
|
gsg->_glDeleteShader(_glsl_gshader);
|
||||||
_shader->_glsl_gshader = 0;
|
_glsl_gshader = 0;
|
||||||
}
|
}
|
||||||
gsg->_glDeleteProgram(_shader->_glsl_program);
|
gsg->_glDeleteProgram(_glsl_program);
|
||||||
_shader->_glsl_program = 0;
|
_glsl_program = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +315,7 @@ bind(GSG *gsg) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (_shader->get_language() == Shader::SL_GLSL && !_shader->get_error_flag()) {
|
if (_shader->get_language() == Shader::SL_GLSL && !_shader->get_error_flag()) {
|
||||||
gsg->_glUseProgram(_shader->_glsl_program);
|
gsg->_glUseProgram(_glsl_program);
|
||||||
}
|
}
|
||||||
if (glGetError() != GL_NO_ERROR) {
|
if (glGetError() != GL_NO_ERROR) {
|
||||||
GLCAT.error() << "GL error in ShaderContext::bind\n";
|
GLCAT.error() << "GL error in ShaderContext::bind\n";
|
||||||
@ -789,48 +794,48 @@ glsl_compile_shader(GSG *gsg) {
|
|||||||
// Terribly hacky. I hope this will go away when we
|
// Terribly hacky. I hope this will go away when we
|
||||||
// add support for separated shader programs later.
|
// add support for separated shader programs later.
|
||||||
|
|
||||||
_shader->_glsl_program = gsg->_glCreateProgram();
|
_glsl_program = gsg->_glCreateProgram();
|
||||||
if (!_shader->_glsl_program) return false;
|
if (!_glsl_program) return false;
|
||||||
|
|
||||||
if (_shader->_text.find("vshader") != -1) {
|
if (_shader->_text.find("vshader") != -1) {
|
||||||
_shader->_glsl_vshader = glsl_compile_entry_point(gsg, "vshader", Shader::ST_VERTEX);
|
_glsl_vshader = glsl_compile_entry_point(gsg, "vshader", Shader::ST_VERTEX);
|
||||||
if (!_shader->_glsl_vshader) return false;
|
if (!_glsl_vshader) return false;
|
||||||
gsg->_glAttachShader(_shader->_glsl_program, _shader->_glsl_vshader);
|
gsg->_glAttachShader(_glsl_program, _glsl_vshader);
|
||||||
} else {
|
} else {
|
||||||
GLCAT.warning() << "Could not locate function 'vshader' in shader text!\n";
|
GLCAT.warning() << "Could not locate function 'vshader' in shader text!\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_shader->_text.find("fshader") != -1) {
|
if (_shader->_text.find("fshader") != -1) {
|
||||||
_shader->_glsl_fshader = glsl_compile_entry_point(gsg, "fshader", Shader::ST_FRAGMENT);
|
_glsl_fshader = glsl_compile_entry_point(gsg, "fshader", Shader::ST_FRAGMENT);
|
||||||
if (!_shader->_glsl_fshader) return false;
|
if (!_glsl_fshader) return false;
|
||||||
gsg->_glAttachShader(_shader->_glsl_program, _shader->_glsl_fshader);
|
gsg->_glAttachShader(_glsl_program, _glsl_fshader);
|
||||||
} else {
|
} else {
|
||||||
GLCAT.warning() << "Could not locate function 'fshader' in shader text!\n";
|
GLCAT.warning() << "Could not locate function 'fshader' in shader text!\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_shader->_text.find("gshader") != -1) {
|
if (_shader->_text.find("gshader") != -1) {
|
||||||
_shader->_glsl_gshader = glsl_compile_entry_point(gsg, "gshader", Shader::ST_GEOMETRY);
|
_glsl_gshader = glsl_compile_entry_point(gsg, "gshader", Shader::ST_GEOMETRY);
|
||||||
if (!_shader->_glsl_gshader) return false;
|
if (!_glsl_gshader) return false;
|
||||||
gsg->_glAttachShader(_shader->_glsl_program, _shader->_glsl_gshader);
|
gsg->_glAttachShader(_glsl_program, _glsl_gshader);
|
||||||
}
|
}
|
||||||
|
|
||||||
gsg->_glLinkProgram(_shader->_glsl_program);
|
gsg->_glLinkProgram(_glsl_program);
|
||||||
|
|
||||||
int status;
|
int status;
|
||||||
gsg->_glGetProgramiv(_shader->_glsl_program, GL_LINK_STATUS, &status);
|
gsg->_glGetProgramiv(_glsl_program, GL_LINK_STATUS, &status);
|
||||||
if (status != GL_TRUE) {
|
if (status != GL_TRUE) {
|
||||||
GLCAT.error() << "An error occurred while linking shader program!\n";
|
GLCAT.error() << "An error occurred while linking shader program!\n";
|
||||||
glsl_report_program_errors(gsg, _shader->_glsl_program);
|
glsl_report_program_errors(gsg, _glsl_program);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There might be warnings. Only report them for one shader program.
|
// There might be warnings. Only report them for one shader program.
|
||||||
if (_shader->_glsl_vshader != 0) {
|
if (_glsl_vshader != 0) {
|
||||||
glsl_report_shader_errors(gsg, _shader->_glsl_vshader);
|
glsl_report_shader_errors(gsg, _glsl_vshader);
|
||||||
} else if (_shader->_glsl_fshader != 0) {
|
} else if (_glsl_fshader != 0) {
|
||||||
glsl_report_shader_errors(gsg, _shader->_glsl_fshader);
|
glsl_report_shader_errors(gsg, _glsl_fshader);
|
||||||
} else if (_shader->_glsl_gshader != 0) {
|
} else if (_glsl_gshader != 0) {
|
||||||
glsl_report_shader_errors(gsg, _shader->_glsl_gshader);
|
glsl_report_shader_errors(gsg, _glsl_gshader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glGetError() != GL_NO_ERROR) {
|
if (glGetError() != GL_NO_ERROR) {
|
||||||
|
@ -62,6 +62,11 @@ private:
|
|||||||
void cg_report_errors();
|
void cg_report_errors();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
GLuint _glsl_program;
|
||||||
|
GLuint _glsl_vshader;
|
||||||
|
GLuint _glsl_fshader;
|
||||||
|
GLuint _glsl_gshader;
|
||||||
|
|
||||||
int _stage_offset;
|
int _stage_offset;
|
||||||
// Avoid using this! It merely exists so the
|
// Avoid using this! It merely exists so the
|
||||||
// destructor has access to the extension functions.
|
// destructor has access to the extension functions.
|
||||||
|
@ -1589,10 +1589,6 @@ Shader(const Filename &filename, const string &text, const ShaderLanguage &lang)
|
|||||||
_language(lang)
|
_language(lang)
|
||||||
{
|
{
|
||||||
_error_flag = false;
|
_error_flag = false;
|
||||||
_glsl_program = 0;
|
|
||||||
_glsl_vshader = 0;
|
|
||||||
_glsl_fshader = 0;
|
|
||||||
_glsl_gshader = 0;
|
|
||||||
|
|
||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
_cg_context = 0;
|
_cg_context = 0;
|
||||||
|
@ -281,10 +281,6 @@ public:
|
|||||||
void clear_parameters();
|
void clear_parameters();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned int _glsl_program;
|
|
||||||
unsigned int _glsl_vshader;
|
|
||||||
unsigned int _glsl_fshader;
|
|
||||||
unsigned int _glsl_gshader;
|
|
||||||
pvector<int> _glsl_parameter_map;
|
pvector<int> _glsl_parameter_map;
|
||||||
|
|
||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
|
Loading…
x
Reference in New Issue
Block a user