OpenSubdiv: More graceful handling of shader compile/linking errors

This commit is contained in:
Sergey Sharybin 2015-09-09 17:27:08 +05:00
parent 4f29613894
commit 145617c5eb
2 changed files with 24 additions and 5 deletions

@ -85,7 +85,7 @@ const struct OpenSubdiv_TopologyRefinerDescr *openSubdiv_getGLMeshTopologyRefine
OpenSubdiv_GLMesh *gl_mesh); OpenSubdiv_GLMesh *gl_mesh);
/* ** Initialize/Deinitialize global OpenGL drawing buffers/GLSL programs ** */ /* ** Initialize/Deinitialize global OpenGL drawing buffers/GLSL programs ** */
void openSubdiv_osdGLDisplayInit(void); bool openSubdiv_osdGLDisplayInit(void);
void openSubdiv_osdGLDisplayDeinit(void); void openSubdiv_osdGLDisplayDeinit(void);
/* ** Evaluator API ** */ /* ** Evaluator API ** */

@ -214,7 +214,7 @@ GLuint compileShader(GLenum shaderType,
fprintf(stderr, "Section: %s\n", sdefine); fprintf(stderr, "Section: %s\n", sdefine);
fprintf(stderr, "Defines: %s\n", define); fprintf(stderr, "Defines: %s\n", define);
fprintf(stderr, "Source: %s\n", sources[2]); fprintf(stderr, "Source: %s\n", sources[2]);
exit(1); return 0;
} }
return shader; return shader;
@ -225,12 +225,21 @@ GLuint linkProgram(const char *define)
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, GLuint vertexShader = compileShader(GL_VERTEX_SHADER,
"VERTEX_SHADER", "VERTEX_SHADER",
define); define);
if (vertexShader == 0) {
return 0;
}
GLuint geometryShader = compileShader(GL_GEOMETRY_SHADER, GLuint geometryShader = compileShader(GL_GEOMETRY_SHADER,
"GEOMETRY_SHADER", "GEOMETRY_SHADER",
define); define);
if (geometryShader == 0) {
return 0;
}
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER,
"FRAGMENT_SHADER", "FRAGMENT_SHADER",
define); define);
if (fragmentShader == 0) {
return 0;
}
GLuint program = glCreateProgram(); GLuint program = glCreateProgram();
@ -279,7 +288,8 @@ GLuint linkProgram(const char *define)
glGetProgramInfoLog(program, sizeof(emsg), 0, emsg); glGetProgramInfoLog(program, sizeof(emsg), 0, emsg);
fprintf(stderr, "Error linking GLSL program : %s\n", emsg); fprintf(stderr, "Error linking GLSL program : %s\n", emsg);
fprintf(stderr, "Defines: %s\n", define); fprintf(stderr, "Defines: %s\n", define);
exit(1); glDeleteProgram(program);
return 0;
} }
glUniformBlockBinding(program, glUniformBlockBinding(program,
@ -363,9 +373,10 @@ void bindProgram(GLMeshInterface * /*mesh*/,
} /* namespace */ } /* namespace */
void openSubdiv_osdGLDisplayInit(void) bool openSubdiv_osdGLDisplayInit(void)
{ {
static bool need_init = true; static bool need_init = true;
static bool init_success = false;
if (need_init) { if (need_init) {
g_flat_fill_solid_program = linkProgram("#define FLAT_SHADING\n"); g_flat_fill_solid_program = linkProgram("#define FLAT_SHADING\n");
g_flat_fill_texture2d_program = linkProgram("#define USE_TEXTURE_2D\n#define FLAT_SHADING\n"); g_flat_fill_texture2d_program = linkProgram("#define USE_TEXTURE_2D\n#define FLAT_SHADING\n");
@ -379,7 +390,13 @@ void openSubdiv_osdGLDisplayInit(void)
sizeof(g_lighting_data), NULL, GL_STATIC_DRAW); sizeof(g_lighting_data), NULL, GL_STATIC_DRAW);
need_init = false; need_init = false;
init_success = g_flat_fill_solid_program != 0 &&
g_flat_fill_texture2d_program != 0 &&
g_smooth_fill_solid_program != 0 &&
g_smooth_fill_texture2d_program != 0 &&
g_wireframe_program;
} }
return init_success;
} }
void openSubdiv_osdGLDisplayDeinit(void) void openSubdiv_osdGLDisplayDeinit(void)
@ -635,7 +652,9 @@ void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh,
(GLMeshInterface *)(gl_mesh->descriptor); (GLMeshInterface *)(gl_mesh->descriptor);
/* Make sure all global invariants are initialized. */ /* Make sure all global invariants are initialized. */
openSubdiv_osdGLDisplayInit(); if (!openSubdiv_osdGLDisplayInit()) {
return;
}
/* Setup GLSL/OpenGL to draw patches in current context. */ /* Setup GLSL/OpenGL to draw patches in current context. */
GLuint program = preapre_patchDraw(mesh, fill_quads != 0); GLuint program = preapre_patchDraw(mesh, fill_quads != 0);