Fix #33371: blender freezing in material draw mode.

When FBO failed in a particular way it could cause the opengl draw buffer to be
set wrong, effectively disabling all opengl drawing. The FBO error was caused
by cycles GLSL materials with no nodes that would still use blender internal
materials, which caused issues with lamp shadow buffers FBO.

This also fixes a GLSL refresh issue when switching render engines.
This commit is contained in:
Brecht Van Lommel 2012-12-03 08:31:16 +00:00
parent 0526fcf13f
commit 94f85c3c72
3 changed files with 35 additions and 2 deletions

@ -156,12 +156,16 @@ void ED_render_engine_changed(Main *bmain)
/* on changing the render engine type, clear all running render engines */
bScreen *sc;
ScrArea *sa;
Scene *scene;
for (sc = bmain->screen.first; sc; sc = sc->id.next)
for (sa = sc->areabase.first; sa; sa = sa->next)
ED_render_engine_area_exit(sa);
RE_FreePersistentData();
for (scene = bmain->scene.first; scene; scene = scene->id.next)
ED_render_id_flush_update(bmain, &scene->id);
}
/***************************** Updates ***********************************

@ -253,6 +253,9 @@ static void GPU_print_framebuffer_error(GLenum status, char err_out[256])
switch (status) {
case GL_FRAMEBUFFER_COMPLETE_EXT:
break;
case GL_INVALID_OPERATION:
err= "Invalid operation";
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
err= "Incomplete attachment";
break;
@ -754,6 +757,7 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err
{
GLenum status;
GLenum attachment;
GLenum error;
if (tex->depth)
attachment = GL_DEPTH_ATTACHMENT_EXT;
@ -766,6 +770,14 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
tex->target, tex->bindcode, 0);
error = glGetError();
if (error == GL_INVALID_OPERATION) {
GPU_framebuffer_restore();
GPU_print_framebuffer_error(error, err_out);
return 0;
}
if (tex->depth) {
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);

@ -1497,6 +1497,16 @@ static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
return shr.combined;
}
static GPUNodeLink *gpu_material_diffuse_bsdf(GPUMaterial *mat, Material *ma)
{
static float roughness = 0.0f;
GPUNodeLink *outlink;
GPU_link(mat, "node_bsdf_diffuse", GPU_uniform(&ma->r), GPU_uniform(&roughness), GPU_builtin(GPU_VIEW_NORMAL), &outlink);
return outlink;
}
GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
{
GPUMaterial *mat;
@ -1516,8 +1526,15 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
ntreeGPUMaterialNodes(ma->nodetree, mat);
}
else {
/* create material */
outlink = GPU_blender_material(mat, ma);
if(BKE_scene_use_new_shading_nodes(scene)) {
/* create simple diffuse material instead of nodes */
outlink = gpu_material_diffuse_bsdf(mat, ma);
}
else {
/* create blender material */
outlink = GPU_blender_material(mat, ma);
}
GPU_material_output_link(mat, outlink);
}