diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2015-03-20 18:56:12 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2015-03-20 18:56:12 +0300 |
commit | 77a4d705c7fe8bafd3dd891905dddceea2e5b314 (patch) | |
tree | 9e0a669e355b34338425221b7b447f2f8ede3eb2 /source | |
parent | f808f36c12317219669f9572712fc5dd485251e7 (diff) | |
parent | b9dc4f851bd01a5ca5c7019ea7ef2356d010be5f (diff) |
Merge branch 'master' into temp-ghash-setops
Diffstat (limited to 'source')
17 files changed, 156 insertions, 157 deletions
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index c2158f02ae3..8074182c395 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -90,7 +90,7 @@ EditBone *ED_armature_edit_bone_add_primitive(Object *obedit_arm, float length, bArmature *arm = obedit_arm->data; EditBone *bone; - ED_armature_deselect_all(obedit_arm, 0); + ED_armature_deselect_all(obedit_arm); /* Create a bone */ bone = ED_armature_edit_bone_add(arm, "Bone"); @@ -145,7 +145,7 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op)) to_root = 1; } - ED_armature_deselect_all(obedit, 0); + ED_armature_deselect_all(obedit); /* we re-use code for mirror editing... */ flipbone = NULL; @@ -914,7 +914,7 @@ static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op) mul_m3_m3m3(totmat, obmat, viewmat); invert_m3_m3(imat, totmat); - ED_armature_deselect_all(obedit, 0); + ED_armature_deselect_all(obedit); /* Create a bone */ bone = ED_armature_edit_bone_add(obedit->data, name); diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 88c52989c07..29b7872f304 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -578,6 +578,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); ListBase points = {NULL, NULL}; + EditBone *newbone = NULL; int count; /* sanity checks */ @@ -610,94 +611,97 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) float curs[3]; /* Get Points - selected joint */ - ebp = (EditBonePoint *)points.first; + ebp = points.first; /* Get points - cursor (tail) */ invert_m4_m4(obedit->imat, obedit->obmat); mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)); /* Create a bone */ - /* newbone = */ add_points_bone(obedit, ebp->vec, curs); + newbone = add_points_bone(obedit, ebp->vec, curs); } else if (count == 2) { - EditBonePoint *ebp, *ebp2; + EditBonePoint *ebp_a, *ebp_b; float head[3], tail[3]; short headtail = 0; /* check that the points don't belong to the same bone */ - ebp = (EditBonePoint *)points.first; - ebp2 = ebp->next; + ebp_a = (EditBonePoint *)points.first; + ebp_b = ebp_a->next; - if ((ebp->head_owner == ebp2->tail_owner) && (ebp->head_owner != NULL)) { - BKE_report(op->reports, RPT_ERROR, "Same bone selected..."); - BLI_freelistN(&points); - return OPERATOR_CANCELLED; - } - if ((ebp->tail_owner == ebp2->head_owner) && (ebp->tail_owner != NULL)) { + if (((ebp_a->head_owner == ebp_b->tail_owner) && (ebp_a->head_owner != NULL)) || + ((ebp_a->tail_owner == ebp_b->head_owner) && (ebp_a->tail_owner != NULL))) + { BKE_report(op->reports, RPT_ERROR, "Same bone selected..."); BLI_freelistN(&points); return OPERATOR_CANCELLED; } /* find which one should be the 'head' */ - if ((ebp->head_owner && ebp2->head_owner) || (ebp->tail_owner && ebp2->tail_owner)) { - /* rule: whichever one is closer to 3d-cursor */ - float curs[3]; - float vecA[3], vecB[3]; - float distA, distB; - - /* get cursor location */ - invert_m4_m4(obedit->imat, obedit->obmat); - mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)); - - /* get distances */ - sub_v3_v3v3(vecA, ebp->vec, curs); - sub_v3_v3v3(vecB, ebp2->vec, curs); - distA = len_v3(vecA); - distB = len_v3(vecB); - - /* compare distances - closer one therefore acts as direction for bone to go */ - headtail = (distA < distB) ? 2 : 1; + if ((ebp_a->head_owner && ebp_b->head_owner) || (ebp_a->tail_owner && ebp_b->tail_owner)) { + /* use active, nice predictable */ + if (arm->act_edbone && ELEM(arm->act_edbone, ebp_a->head_owner, ebp_a->tail_owner)) { + headtail = 1; + } + else if (arm->act_edbone && ELEM(arm->act_edbone, ebp_b->head_owner, ebp_b->tail_owner)) { + headtail = 2; + } + else { + /* rule: whichever one is closer to 3d-cursor */ + float curs[3]; + float dist_sq_a, dist_sq_b; + + /* get cursor location */ + invert_m4_m4(obedit->imat, obedit->obmat); + mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)); + + /* get distances */ + dist_sq_a = len_squared_v3v3(ebp_a->vec, curs); + dist_sq_b = len_squared_v3v3(ebp_b->vec, curs); + + /* compare distances - closer one therefore acts as direction for bone to go */ + headtail = (dist_sq_a < dist_sq_b) ? 2 : 1; + } } - else if (ebp->head_owner) { + else if (ebp_a->head_owner) { headtail = 1; } - else if (ebp2->head_owner) { + else if (ebp_b->head_owner) { headtail = 2; } /* assign head/tail combinations */ if (headtail == 2) { - copy_v3_v3(head, ebp->vec); - copy_v3_v3(tail, ebp2->vec); + copy_v3_v3(head, ebp_a->vec); + copy_v3_v3(tail, ebp_b->vec); } else if (headtail == 1) { - copy_v3_v3(head, ebp2->vec); - copy_v3_v3(tail, ebp->vec); + copy_v3_v3(head, ebp_b->vec); + copy_v3_v3(tail, ebp_a->vec); } /* add new bone and parent it to the appropriate end */ if (headtail) { - EditBone *newbone = add_points_bone(obedit, head, tail); + newbone = add_points_bone(obedit, head, tail); /* do parenting (will need to set connected flag too) */ if (headtail == 2) { /* ebp tail or head - tail gets priority */ - if (ebp->tail_owner) - newbone->parent = ebp->tail_owner; + if (ebp_a->tail_owner) + newbone->parent = ebp_a->tail_owner; else - newbone->parent = ebp->head_owner; + newbone->parent = ebp_a->head_owner; } else { - /* ebp2 tail or head - tail gets priority */ - if (ebp2->tail_owner) - newbone->parent = ebp2->tail_owner; + /* ebp_b tail or head - tail gets priority */ + if (ebp_b->tail_owner) + newbone->parent = ebp_b->tail_owner; else - newbone->parent = ebp2->head_owner; + newbone->parent = ebp_b->head_owner; } /* don't set for bone connecting two head points of bones */ - if (ebp->tail_owner || ebp2->tail_owner) { + if (ebp_a->tail_owner || ebp_b->tail_owner) { newbone->flag |= BONE_CONNECTED; } } @@ -708,6 +712,12 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) BLI_freelistN(&points); return OPERATOR_CANCELLED; } + + if (newbone) { + ED_armature_deselect_all(obedit); + arm->act_edbone = newbone; + newbone->flag |= BONE_TIPSEL; + } /* updates */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit); diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index 5061ba9a812..720b9b7821a 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -388,61 +388,14 @@ static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2], return NULL; } - - -/* toggle==0: deselect - * toggle==1: swap (based on test) - * toggle==2: swap (no test), CURRENTLY UNUSED - */ -void ED_armature_deselect_all(Object *obedit, int toggle) +void ED_armature_deselect_all(Object *obedit) { bArmature *arm = obedit->data; - EditBone *eBone; - int sel = 1; - - if (toggle == 1) { - /* Determine if there are any selected bones - * and therefore whether we are selecting or deselecting */ - for (eBone = arm->edbo->first; eBone; eBone = eBone->next) { - // if (arm->layer & eBone->layer) { - if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) { - sel = 0; - break; - } - // } - } - } - else { - sel = toggle; - } + EditBone *ebone; - /* Set the flags */ - for (eBone = arm->edbo->first; eBone; eBone = eBone->next) { - if (sel == 2) { - /* invert selection of bone */ - if (EBONE_VISIBLE(arm, eBone)) { - eBone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - if (arm->act_edbone == eBone) - arm->act_edbone = NULL; - } - } - else if (sel == 1) { - /* select bone */ - if (EBONE_VISIBLE(arm, eBone)) { - eBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - if (eBone->parent) - eBone->parent->flag |= (BONE_TIPSEL); - } - } - else { - /* deselect bone */ - eBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - if (arm->act_edbone == eBone) - arm->act_edbone = NULL; - } + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } - - ED_armature_sync_selection(arm->edbo); } void ED_armature_deselect_all_visible(Object *obedit) @@ -489,8 +442,9 @@ bool mouse_armature(bContext *C, const int mval[2], bool extend, bool deselect, nearBone = get_nearest_editbonepoint(&vc, mval, arm->edbo, 1, &selmask); if (nearBone) { - if (!extend && !deselect && !toggle) - ED_armature_deselect_all(obedit, 0); + if (!extend && !deselect && !toggle) { + ED_armature_deselect_all(obedit); + } /* by definition the non-root connected bones have no root point drawn, * so a root selection needs to be delivered to the parent tip */ diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index b08cc12dc3e..da756422bdb 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -119,7 +119,7 @@ void ED_keymap_armature(struct wmKeyConfig *keyconf); void ED_armature_from_edit(struct bArmature *arm); void ED_armature_to_edit(struct bArmature *arm); void ED_armature_edit_free(struct bArmature *arm); -void ED_armature_deselect_all(struct Object *obedit, int toggle); +void ED_armature_deselect_all(struct Object *obedit); void ED_armature_deselect_all_visible(struct Object *obedit); int ED_do_pose_selectbuffer(struct Scene *scene, struct Base *base, unsigned int *buffer, diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index d03f3c157a9..517cf64214c 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -106,9 +106,10 @@ static void draw_render_info(const bContext *C, if (re) { int total_tiles; + bool need_free_tiles; rcti *tiles; - RE_engine_get_current_tiles(re, &total_tiles, &tiles); + tiles = RE_engine_get_current_tiles(re, &total_tiles, &need_free_tiles); if (total_tiles) { int i, x, y; @@ -133,7 +134,9 @@ static void draw_render_info(const bContext *C, glaDrawBorderCorners(tile, zoomx, zoomy); } - MEM_freeN(tiles); + if (need_free_tiles) { + MEM_freeN(tiles); + } glPopMatrix(); } diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 730ee02f448..6050b66fdb7 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -618,7 +618,7 @@ static eOLDrawState tree_element_active_ebone( if (set != OL_SETSEL_NONE) { if (set == OL_SETSEL_NORMAL) { if (!(ebone->flag & BONE_HIDDEN_A)) { - ED_armature_deselect_all(scene->obedit, 0); // deselect + ED_armature_deselect_all(scene->obedit); tree_element_active_ebone__sel(C, scene, arm, ebone, true); status = OL_DRAWSEL_NORMAL; } diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index aed1a88938a..401711e84e5 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -184,7 +184,7 @@ int GPU_offscreen_height(const GPUOffScreen *ofs); * - only for fragment shaders now * - must call texture bind before setting a texture as uniform! */ -GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const char *geocode, const char *libcode, const char *defines); +GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const char *geocode, const char *libcode, const char *defines, int input, int output, int number); void GPU_shader_free(GPUShader *shader); void GPU_shader_bind(GPUShader *shader); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index fcfb68d4629..113ed8e341c 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -1419,7 +1419,7 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, /* generate code and compile with opengl */ fragmentcode = code_generate_fragment(nodes, outlink->output); vertexcode = code_generate_vertex(nodes, type); - shader = GPU_shader_create(vertexcode, fragmentcode, NULL, glsl_material_library, NULL); + shader = GPU_shader_create(vertexcode, fragmentcode, NULL, glsl_material_library, NULL, 0, 0, 0); /* failed? */ if (!shader) { diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c index bfa938d0fed..96de0db0acb 100644 --- a/source/blender/gpu/intern/gpu_compositing.c +++ b/source/blender/gpu/intern/gpu_compositing.c @@ -50,7 +50,7 @@ #include "GPU_extensions.h" #include "GPU_compositing.h" -#include "GL/glew.h" +#include "GPU_glew.h" #include "MEM_guardedalloc.h" @@ -114,6 +114,8 @@ struct GPUFX { /* we have a stencil, restore the previous state */ bool restore_stencil; + + unsigned int vbuffer; }; #if 0 @@ -177,6 +179,14 @@ GPUFX *GPU_fx_compositor_create(void) { GPUFX *fx = MEM_callocN(sizeof(GPUFX), "GPUFX compositor"); + if (GLEW_ARB_vertex_buffer_object) { + glGenBuffersARB(1, &fx->vbuffer); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, fx->vbuffer); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, 16 * sizeof(float), NULL, GL_STATIC_DRAW); + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, 8 * sizeof(float), fullscreencos); + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 8 * sizeof(float), 8 * sizeof(float), fullscreenuvs); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } return fx; } @@ -265,6 +275,8 @@ static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo) void GPU_fx_compositor_destroy(GPUFX *fx) { cleanup_fx_gl_data(fx, true); + if (GLEW_ARB_vertex_buffer_object) + glDeleteBuffersARB(1, &fx->vbuffer); MEM_freeN(fx); } @@ -583,8 +595,9 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx) glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); /* set up quad buffer */ - glVertexPointer(2, GL_FLOAT, 0, fullscreencos); - glTexCoordPointer(2, GL_FLOAT, 0, fullscreenuvs); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, fx->vbuffer); + glVertexPointer(2, GL_FLOAT, 0, NULL); + glTexCoordPointer(2, GL_FLOAT, 0, ((GLubyte *)NULL + 8 * sizeof(float))); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -613,6 +626,7 @@ void GPU_fx_compositor_XRay_resolve(GPUFX *fx) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -649,8 +663,9 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str target = fx->color_buffer_sec; /* set up quad buffer */ - glVertexPointer(2, GL_FLOAT, 0, fullscreencos); - glTexCoordPointer(2, GL_FLOAT, 0, fullscreenuvs); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, fx->vbuffer); + glVertexPointer(2, GL_FLOAT, 0, NULL); + glTexCoordPointer(2, GL_FLOAT, 0, ((GLubyte *)NULL + 8 * sizeof(float))); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -793,6 +808,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str glDisableClientState(GL_TEXTURE_COORD_ARRAY); GPU_shader_unbind(); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); return false; } @@ -862,7 +878,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str color_uniform = GPU_shader_get_uniform(dof_shader_pass2, "colorbuffer"); coc_uniform = GPU_shader_get_uniform(dof_shader_pass2, "cocbuffer"); select_uniform = GPU_shader_get_uniform(dof_shader_pass2, "layerselection"); - dof_uniform = GPU_shader_get_uniform(dof_shader_pass1, "dof_params"); + dof_uniform = GPU_shader_get_uniform(dof_shader_pass2, "dof_params"); GPU_shader_bind(dof_shader_pass2); @@ -882,13 +898,14 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_far_blur, 0, NULL); GPU_texture_bind_as_framebuffer(fx->dof_far_blur); + glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); /* have to clear the buffer unfortunately */ glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); /* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */ - glDrawArraysInstancedEXT(GL_POINTS, 0, 1, fx->dof_downsampled_w * fx->dof_downsampled_h); + glDrawArraysInstancedARB(GL_POINTS, 0, 1, fx->dof_downsampled_w * fx->dof_downsampled_h); GPU_texture_unbind(fx->dof_half_downsampled_far); GPU_framebuffer_texture_detach(fx->dof_far_blur); @@ -905,7 +922,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str /* have to clear the buffer unfortunately */ glClear(GL_COLOR_BUFFER_BIT); /* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */ - glDrawArraysInstancedEXT(GL_POINTS, 0, 1, fx->dof_downsampled_w * fx->dof_downsampled_h); + glDrawArraysInstancedARB(GL_POINTS, 0, 1, fx->dof_downsampled_w * fx->dof_downsampled_h); /* disable bindings */ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -931,8 +948,8 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str color_uniform = GPU_shader_get_uniform(dof_shader_pass3, "colorbuffer"); far_uniform = GPU_shader_get_uniform(dof_shader_pass3, "farbuffer"); near_uniform = GPU_shader_get_uniform(dof_shader_pass3, "nearbuffer"); - viewvecs_uniform = GPU_shader_get_uniform(dof_shader_pass1, "viewvecs"); - depth_uniform = GPU_shader_get_uniform(dof_shader_pass1, "depthbuffer"); + viewvecs_uniform = GPU_shader_get_uniform(dof_shader_pass3, "viewvecs"); + depth_uniform = GPU_shader_get_uniform(dof_shader_pass3, "depthbuffer"); GPU_shader_bind(dof_shader_pass3); @@ -951,7 +968,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str GPU_texture_bind(fx->depth_buffer, numslots++); GPU_texture_filter_mode(fx->depth_buffer, false, false); - GPU_shader_uniform_texture(dof_shader_pass1, depth_uniform, fx->depth_buffer); + GPU_shader_uniform_texture(dof_shader_pass3, depth_uniform, fx->depth_buffer); GPU_texture_bind(src, numslots++); GPU_shader_uniform_texture(dof_shader_pass3, color_uniform, src); @@ -1002,6 +1019,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str glDisableClientState(GL_TEXTURE_COORD_ARRAY); GPU_shader_unbind(); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); return false; } @@ -1230,6 +1248,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); GPU_shader_unbind(); diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index 24b54a3af37..b4ffc978d11 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -289,7 +289,7 @@ bool GPU_geometry_shader_support(void) bool GPU_instanced_drawing_support(void) { - return GLEW_EXT_draw_instanced; + return GLEW_ARB_draw_instanced; } int GPU_color_depth(void) @@ -1456,7 +1456,7 @@ static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH]) if (GPU_instanced_drawing_support()) { strcat(defines, "#extension GL_EXT_gpu_shader4: enable\n"); - strcat(defines, "#extension GL_EXT_draw_instanced: enable\n"); + strcat(defines, "#extension GL_ARB_draw_instanced: enable\n"); } } @@ -1478,7 +1478,7 @@ static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH]) return; } -GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const char *geocode, const char *libcode, const char *defines) +GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const char *geocode, const char *libcode, const char *defines, int input, int output, int number) { GLint status; GLcharARB log[5000]; @@ -1577,7 +1577,6 @@ GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const source[num_source++] = standard_defines; if (defines) source[num_source++] = defines; - if (libcode) source[num_source++] = libcode; source[num_source++] = geocode; glAttachObjectARB(shader->object, shader->geometry); @@ -1593,6 +1592,8 @@ GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const GPU_shader_free(shader); return NULL; } + + GPU_shader_geometry_stage_primitive_io(shader, input, output, number); } @@ -1732,9 +1733,6 @@ void GPU_shader_geometry_stage_primitive_io(GPUShader *shader, int input, int ou glProgramParameteriEXT(shader->object, GL_GEOMETRY_INPUT_TYPE_EXT, input); glProgramParameteriEXT(shader->object, GL_GEOMETRY_OUTPUT_TYPE_EXT, output); glProgramParameteriEXT(shader->object, GL_GEOMETRY_VERTICES_OUT_EXT, number); - - /* relink so settings can take effect (sucks but should only be done right after compilation so...) */ - glLinkProgramARB(shader->object); } void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUTexture *tex) @@ -1784,12 +1782,12 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) switch (shader) { case GPU_SHADER_VSM_STORE: if (!GG.shaders.vsm_store) - GG.shaders.vsm_store = GPU_shader_create(datatoc_gpu_shader_vsm_store_vert_glsl, datatoc_gpu_shader_vsm_store_frag_glsl, NULL, NULL, NULL); + GG.shaders.vsm_store = GPU_shader_create(datatoc_gpu_shader_vsm_store_vert_glsl, datatoc_gpu_shader_vsm_store_frag_glsl, NULL, NULL, NULL, 0, 0, 0); retval = GG.shaders.vsm_store; break; case GPU_SHADER_SEP_GAUSSIAN_BLUR: if (!GG.shaders.sep_gaussian_blur) - GG.shaders.sep_gaussian_blur = GPU_shader_create(datatoc_gpu_shader_sep_gaussian_blur_vert_glsl, datatoc_gpu_shader_sep_gaussian_blur_frag_glsl, NULL, NULL, NULL); + GG.shaders.sep_gaussian_blur = GPU_shader_create(datatoc_gpu_shader_sep_gaussian_blur_vert_glsl, datatoc_gpu_shader_sep_gaussian_blur_frag_glsl, NULL, NULL, NULL, 0, 0, 0); retval = GG.shaders.sep_gaussian_blur; break; } @@ -1822,56 +1820,53 @@ GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp) switch(effects) { case GPU_SHADER_FX_SSAO: - GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_ssao_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines); + GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_ssao_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0); break; case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE: strcat(defines, "#define FIRST_PASS\n"); - GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines); + GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0); break; case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO: strcat(defines, "#define SECOND_PASS\n"); - GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines); + GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0); break; case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE: strcat(defines, "#define THIRD_PASS\n"); - GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines); + GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0); break; case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR: strcat(defines, "#define FOURTH_PASS\n"); - GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines); + GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0); break; case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE: strcat(defines, "#define FIFTH_PASS\n"); - GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines); + GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0); break; case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_ONE: strcat(defines, "#define FIRST_PASS\n"); - GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines); + GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0); break; case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_TWO: strcat(defines, "#define SECOND_PASS\n"); - shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, datatoc_gpu_shader_fx_dof_hq_geo_glsl, datatoc_gpu_shader_fx_lib_glsl, defines); - - if (shader) { - GG.shaders.fx_shaders[offset] = shader; - GPU_shader_geometry_stage_primitive_io(shader, GL_POINTS, GL_TRIANGLE_STRIP, 4); - } + shader = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, datatoc_gpu_shader_fx_dof_hq_geo_glsl, datatoc_gpu_shader_fx_lib_glsl, + defines, GL_POINTS, GL_TRIANGLE_STRIP, 4); + GG.shaders.fx_shaders[offset] = shader; break; case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_THREE: strcat(defines, "#define THIRD_PASS\n"); - GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines); + GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_hq_vert_glsl, datatoc_gpu_shader_fx_dof_hq_frag_glsl, NULL, datatoc_gpu_shader_fx_lib_glsl, defines, 0, 0, 0); break; case GPU_SHADER_FX_DEPTH_RESOLVE: - GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, NULL, defines); + GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, NULL, defines, 0, 0, 0); } } diff --git a/source/blender/gpu/intern/gpu_simple_shader.c b/source/blender/gpu/intern/gpu_simple_shader.c index 60d4a2f2875..b439a37f3c3 100644 --- a/source/blender/gpu/intern/gpu_simple_shader.c +++ b/source/blender/gpu/intern/gpu_simple_shader.c @@ -152,7 +152,7 @@ static GPUShader *gpu_simple_shader(int options) datatoc_gpu_shader_simple_vert_glsl, datatoc_gpu_shader_simple_frag_glsl, NULL, - NULL, defines); + NULL, defines, 0, 0, 0); if (shader) { /* set texture map to first texture unit */ diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl index e2d3ab36ec8..8c2aff45679 100644 --- a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_frag.glsl @@ -102,7 +102,7 @@ void accumulate_pass(void) { if (dof_params.w == 0.0) r = 1.0; else - r = cos(M_PI / dof_params.w) / (cos(theta - (2.0 * M_PI / dof_params.w) * floor((dof_params.w * theta + M_PI) / (2 * M_PI)))); + r = cos(M_PI / dof_params.w) / (cos(theta - (2.0 * M_PI / dof_params.w) * floor((dof_params.w * theta + M_PI) / (2.0 * M_PI)))); if (dot(particlecoord, particlecoord) > r * r) discard; @@ -124,7 +124,7 @@ void final_pass(void) { vec4 farcolor = texture2D(farbuffer, uvcoord); float farweight = farcolor.a; - if (farweight > 0) + if (farweight > 0.0) farcolor /= farweight; vec4 nearcolor = texture2D(nearbuffer, uvcoord); @@ -138,7 +138,7 @@ void final_pass(void) { farweight = mix(1.0, farweight, mixfac); float nearweight = nearcolor.a; - if (nearweight > 0) { + if (nearweight > 0.0) { nearcolor /= nearweight; } diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl index e8c505bd15f..09a0c75facc 100644 --- a/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_hq_vert.glsl @@ -27,11 +27,11 @@ void vert_dof_downsample() /* geometry shading pass, calculate a texture coordinate based on the indexed id */ void vert_dof_coc_scatter_pass() { - vec2 pixel = vec2(1.0 / float(rendertargetdim.x), 1.0 / float(rendertargetdim.y)); + vec2 pixel = vec2(rendertargetdim.x, rendertargetdim.y); /* some math to get the target pixel */ int row = gl_InstanceID / rendertargetdim.x; int column = gl_InstanceID % rendertargetdim.x; - uvcoord = vec2(column, row) * pixel + 0.5 * pixel; + uvcoord = (vec2(column, row) + vec2(0.5)) / pixel; vec2 pos = uvcoord * 2.0 - vec2(1.0); gl_Position = vec4(pos.x, pos.y, 0.0, 1.0); diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 5edf970c129..bc4c4c54f17 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -159,7 +159,7 @@ void RE_engines_exit(void); RenderEngineType *RE_engines_find(const char *idname); -void RE_engine_get_current_tiles(struct Render *re, int *total_tiles_r, rcti **tiles_r); +rcti* RE_engine_get_current_tiles(struct Render *re, int *total_tiles_r, bool *needs_free_r); struct RenderData *RE_engine_get_render_data(struct Render *re); void RE_bake_engine_set_engine_parameters(struct Render *re, struct Main *bmain, struct Scene *scene); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 8d92fb9eec9..a53ff302475 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -194,6 +194,7 @@ struct Render struct Object *camera_override; unsigned int lay, layer_override; + ThreadRWMutex partsmutex; ListBase parts; /* render engine */ diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 4e63a9918e1..c66b9c2ce0d 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -368,23 +368,31 @@ void RE_engine_set_error_message(RenderEngine *engine, const char *msg) } } -void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r) +rcti* RE_engine_get_current_tiles(Render *re, int *total_tiles_r, bool *r_needs_free) { + static rcti tiles_static[BLENDER_MAX_THREADS]; + const int allocation_step = BLENDER_MAX_THREADS; RenderPart *pa; int total_tiles = 0; - rcti *tiles = NULL; - int allocation_size = 0, allocation_step = BLENDER_MAX_THREADS; + rcti *tiles = tiles_static; + int allocation_size = BLENDER_MAX_THREADS; + + BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_READ); if (re->engine && (re->engine->flag & RE_ENGINE_HIGHLIGHT_TILES) == 0) { *total_tiles_r = 0; - *tiles_r = NULL; - return; + BLI_rw_mutex_unlock(&re->partsmutex); + *r_needs_free = false; + return NULL; } for (pa = re->parts.first; pa; pa = pa->next) { if (pa->status == PART_STATUS_IN_PROGRESS) { if (total_tiles >= allocation_size) { - if (tiles == NULL) + /* Just in case we're using crazy network rendering with more + * slaves as BLENDER_MAX_THREADS. + */ + if (tiles == tiles_static) tiles = MEM_mallocN(allocation_step * sizeof(rcti), "current engine tiles"); else tiles = MEM_reallocN(tiles, (total_tiles + allocation_step) * sizeof(rcti)); @@ -404,9 +412,9 @@ void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r) total_tiles++; } } - + BLI_rw_mutex_unlock(&re->partsmutex); *total_tiles_r = total_tiles; - *tiles_r = tiles; + return tiles; } RenderData *RE_engine_get_render_data(Render *re) @@ -478,6 +486,8 @@ bool RE_bake_engine( engine->tile_y = 0; engine->flag &= ~RE_ENGINE_RENDERING; + BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE); + /* re->engine becomes zero if user changed active render engine during render */ if (!persistent_data || !re->engine) { RE_engine_free(engine); @@ -485,6 +495,7 @@ bool RE_bake_engine( } RE_parts_free(re); + BLI_rw_mutex_unlock(&re->partsmutex); if (BKE_reports_contain(re->reports, RPT_ERROR)) G.is_break = true; @@ -663,6 +674,8 @@ int RE_engine_render(Render *re, int do_all) render_result_free_list(&engine->fullresult, engine->fullresult.first); + BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE); + /* re->engine becomes zero if user changed active render engine during render */ if (!persistent_data || !re->engine) { RE_engine_free(engine); @@ -682,6 +695,7 @@ int RE_engine_render(Render *re, int do_all) } RE_parts_free(re); + BLI_rw_mutex_unlock(&re->partsmutex); if (BKE_reports_contain(re->reports, RPT_ERROR)) G.is_break = true; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 21ca7924fa0..b397db7c31b 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -385,6 +385,7 @@ Render *RE_NewRender(const char *name) BLI_addtail(&RenderGlobal.renderlist, re); BLI_strncpy(re->name, name, RE_MAXNAME); BLI_rw_mutex_init(&re->resultmutex); + BLI_rw_mutex_init(&re->partsmutex); re->eval_ctx = MEM_callocN(sizeof(EvaluationContext), "re->eval_ctx"); re->eval_ctx->mode = DAG_EVAL_RENDER; } @@ -423,6 +424,7 @@ void RE_FreeRender(Render *re) RE_engine_free(re->engine); BLI_rw_mutex_end(&re->resultmutex); + BLI_rw_mutex_end(&re->partsmutex); BLI_freelistN(&re->r.layers); @@ -1268,8 +1270,9 @@ static void threaded_tile_processor(Render *re) /* unset threadsafety */ g_break = 0; - + BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE); RE_parts_free(re); + BLI_rw_mutex_unlock(&re->partsmutex); re->viewplane = viewplane; /* restore viewplane, modified by pano render */ } |