diff options
Diffstat (limited to 'source/blender/editors/gpencil/gpencil_paint.c')
-rw-r--r-- | source/blender/editors/gpencil/gpencil_paint.c | 127 |
1 files changed, 82 insertions, 45 deletions
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 2471ba76ae2..c8f1901d075 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -69,15 +69,19 @@ #include "ED_view3d.h" #include "ED_clip.h" -#include "BIF_gl.h" #include "BIF_glutil.h" +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" + #include "RNA_access.h" #include "RNA_define.h" #include "WM_api.h" #include "WM_types.h" +#include "DEG_depsgraph.h" + #include "gpencil_intern.h" /* ******************************************* */ @@ -114,6 +118,7 @@ typedef enum eGPencil_PaintFlags { typedef struct tGPsdata { Main *bmain; Scene *scene; /* current scene from context */ + struct Depsgraph *depsgraph; wmWindow *win; /* window where painting originated */ ScrArea *sa; /* area where painting originated */ @@ -164,6 +169,8 @@ typedef struct tGPsdata { short straight[2]; /* 1: line horizontal, 2: line vertical, other: not defined, second element position */ int lock_axis; /* lock drawing to one axis */ + RNG *rng; + short keymodifier; /* key used for invoking the operator */ } tGPsdata; @@ -233,7 +240,7 @@ static bool gpencil_project_check(tGPsdata *p) static void gp_get_3d_reference(tGPsdata *p, float vec[3]) { View3D *v3d = p->sa->spacedata.first; - const float *fp = ED_view3d_cursor3d_get(p->scene, v3d); + const float *fp = ED_view3d_cursor3d_get(p->scene, v3d)->location; /* the reference point used depends on the owner... */ #if 0 /* XXX: disabled for now, since we can't draw relative to the owner yet */ @@ -403,7 +410,8 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3] } /* apply jitter to stroke */ -static void gp_brush_jitter(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const int mval[2], int r_mval[2]) +static void gp_brush_jitter( + bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const int mval[2], int r_mval[2], RNG *rng) { float pressure = pt->pressure; float tmp_pressure = pt->pressure; @@ -412,7 +420,7 @@ static void gp_brush_jitter(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const tmp_pressure = curvef * brush->draw_sensitivity; } const float exfactor = (brush->draw_jitter + 2.0f) * (brush->draw_jitter + 2.0f); /* exponential value */ - const float fac = BLI_frand() * exfactor * tmp_pressure; + const float fac = BLI_rng_get_float(rng) * exfactor * tmp_pressure; /* Jitter is applied perpendicular to the mouse movement vector (2D space) */ float mvec[2], svec[2]; /* mouse movement in ints -> floats */ @@ -429,7 +437,7 @@ static void gp_brush_jitter(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const svec[0] = -mvec[1]; svec[1] = mvec[0]; /* scale the displacement by the random, and apply */ - if (BLI_frand() > 0.5f) { + if (BLI_rng_get_float(rng) > 0.5f) { mul_v2_fl(svec, -fac); } else { @@ -482,7 +490,8 @@ static void gp_brush_angle(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const } /* add current stroke-point to buffer (returns whether point was successfully added) */ -static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure, double curtime) +static short gp_stroke_addpoint( + tGPsdata *p, const int mval[2], float pressure, double curtime) { bGPdata *gpd = p->gpd; bGPDbrush *brush = p->brush; @@ -544,7 +553,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure, /* Apply jitter to position */ if (brush->draw_jitter > 0.0f) { int r_mval[2]; - gp_brush_jitter(gpd, brush, pt, mval, r_mval); + gp_brush_jitter(gpd, brush, pt, mval, r_mval, p->rng); copy_v2_v2_int(&pt->x, r_mval); } else { @@ -554,11 +563,11 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure, if ((brush->draw_random_press > 0.0f) && (brush->flag & GP_BRUSH_USE_RANDOM_PRESSURE)) { float curvef = curvemapping_evaluateF(brush->cur_sensitivity, 0, pressure); float tmp_pressure = curvef * brush->draw_sensitivity; - if (BLI_frand() > 0.5f) { - pt->pressure -= tmp_pressure * brush->draw_random_press * BLI_frand(); + if (BLI_rng_get_float(p->rng) > 0.5f) { + pt->pressure -= tmp_pressure * brush->draw_random_press * BLI_rng_get_float(p->rng); } else { - pt->pressure += tmp_pressure * brush->draw_random_press * BLI_frand(); + pt->pressure += tmp_pressure * brush->draw_random_press * BLI_rng_get_float(p->rng); } CLAMP(pt->pressure, GPENCIL_STRENGTH_MIN, 1.0f); } @@ -582,11 +591,11 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure, /* apply randomness to color strength */ if ((brush->draw_random_press > 0.0f) && (brush->flag & GP_BRUSH_USE_RANDOM_STRENGTH)) { - if (BLI_frand() > 0.5f) { - pt->strength -= pt->strength * brush->draw_random_press * BLI_frand(); + if (BLI_rng_get_float(p->rng) > 0.5f) { + pt->strength -= pt->strength * brush->draw_random_press * BLI_rng_get_float(p->rng); } else { - pt->strength += pt->strength * brush->draw_random_press * BLI_frand(); + pt->strength += pt->strength * brush->draw_random_press * BLI_rng_get_float(p->rng); } CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); } @@ -640,7 +649,8 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure, View3D *v3d = p->sa->spacedata.first; view3d_region_operator_needs_opengl(p->win, p->ar); - ED_view3d_autodist_init(p->bmain, p->scene, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); + ED_view3d_autodist_init( + p->depsgraph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); } /* convert screen-coordinates to appropriate coordinates (and store them) */ @@ -674,7 +684,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure, /* simplify a stroke (in buffer) before storing it * - applies a reverse Chaikin filter - * - code adapted from etch-a-ton branch (editarmature_sketch.c) + * - code adapted from etch-a-ton branch */ static void gp_stroke_simplify(tGPsdata *p) { @@ -971,7 +981,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) } /* apply randomness to stroke */ if (brush->draw_random_sub > 0.0f) { - gp_randomize_stroke(gps, brush); + gp_randomize_stroke(gps, brush, p->rng); } /* smooth stroke after subdiv - only if there's something to do @@ -1240,9 +1250,8 @@ static void gp_stroke_doeraser(tGPsdata *p) if (p->sa->spacetype == SPACE_VIEW3D) { if (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH) { View3D *v3d = p->sa->spacedata.first; - view3d_region_operator_needs_opengl(p->win, p->ar); - ED_view3d_autodist_init(p->bmain, p->scene, p->ar, v3d, 0); + ED_view3d_autodist_init(p->depsgraph, p->ar, v3d, 0); } } @@ -1398,6 +1407,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p) /* pass on current scene and window */ p->bmain = CTX_data_main(C); p->scene = CTX_data_scene(C); + p->depsgraph = CTX_data_depsgraph(C); p->win = CTX_wm_window(C); unit_m4(p->imat); @@ -1552,6 +1562,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p) bGPDpalettecolor *palcolor = p->palettecolor; bGPdata *pdata = p->gpd; copy_v4_v4(pdata->scolor, palcolor->color); + copy_v4_v4(pdata->sfill, palcolor->fill); pdata->sflag = palcolor->flag; /* lock axis */ p->lock_axis = ts->gp_sculpt.lock_axis; @@ -1575,6 +1586,11 @@ static tGPsdata *gp_session_initpaint(bContext *C) */ p->radius = U.gp_eraser; + /* Random generator, only init once. */ + uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); + rng_seed ^= GET_UINT_FROM_POINTER(p); + p->rng = BLI_rng_new(rng_seed); + /* return context data for running paint operator */ return p; } @@ -1601,8 +1617,17 @@ static void gp_session_cleanup(tGPsdata *p) p->inittime = 0.0; } +static void gp_session_free(tGPsdata *p) +{ + if (p->rng != NULL) { + BLI_rng_free(p->rng); + } + MEM_freeN(p); +} + + /* init new stroke */ -static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode) +static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Depsgraph *depsgraph) { Scene *scene = p->scene; ToolSettings *ts = scene->toolsettings; @@ -1731,7 +1756,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode) /* for camera view set the subrect */ if (rv3d->persp == RV3D_CAMOB) { - ED_view3d_calc_camera_border(p->scene, p->ar, v3d, rv3d, &p->subrect_data, true); /* no shift */ + ED_view3d_calc_camera_border(p->scene, depsgraph, p->ar, v3d, rv3d, &p->subrect_data, true); /* no shift */ p->subrect = &p->subrect_data; } } @@ -1809,7 +1834,7 @@ static void gp_paint_strokeend(tGPsdata *p) /* need to restore the original projection settings before packing up */ view3d_region_operator_needs_opengl(p->win, p->ar); - ED_view3d_autodist_init(p->bmain, p->scene, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); + ED_view3d_autodist_init(p->depsgraph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0); } /* check if doing eraser or not */ @@ -1849,26 +1874,39 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr) tGPsdata *p = (tGPsdata *)p_ptr; if (p->paintmode == GP_PAINTMODE_ERASER) { - glPushMatrix(); - - glTranslatef((float)x, (float)y, 0.0f); + Gwn_VertFormat *format = immVertexFormat(); + const uint shdr_pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + immUniformColor4ub(255, 100, 100, 20); + imm_draw_circle_fill_2d(shdr_pos, x, y, p->radius, 40); + + immUnbindProgram(); - glColor4ub(255, 100, 100, 20); - glutil_draw_filled_arc(0.0, M_PI * 2.0, p->radius, 40); + immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); - setlinestyle(6); + float viewport_size[4]; + glGetFloatv(GL_VIEWPORT, viewport_size); + immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); - glColor4ub(255, 100, 100, 200); - glutil_draw_lined_arc(0.0, M_PI * 2.0, p->radius, 40); + immUniformColor4f(1.0f, 0.39f, 0.39f, 0.78f); + immUniform1i("num_colors", 0); /* "simple" mode */ + immUniform1f("dash_width", 12.0f); + immUniform1f("dash_factor", 0.5f); + + imm_draw_circle_wire_2d(shdr_pos, x, y, p->radius, + /* XXX Dashed shader gives bad results with sets of small segments currently, + * temp hack around the issue. :( */ + max_ii(8, p->radius / 2)); /* was fixed 40 */ + + immUnbindProgram(); - setlinestyle(0); glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); - - glPopMatrix(); } } @@ -1928,9 +1966,7 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op) /* cleanup */ gp_paint_cleanup(p); gp_session_cleanup(p); - - /* finally, free the temp data */ - MEM_freeN(p); + gp_session_free(p); } op->customdata = NULL; @@ -1959,7 +1995,7 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event) } /* init painting data */ - gp_paint_initstroke(p, paintmode); + gp_paint_initstroke(p, paintmode, CTX_data_depsgraph(C)); if (p->status == GP_STATUS_ERROR) { gpencil_draw_exit(C, op); return 0; @@ -2036,7 +2072,7 @@ static void gpencil_draw_status_indicators(tGPsdata *p) /* ------------------------------- */ /* create a new stroke point at the point indicated by the painting context */ -static void gpencil_draw_apply(wmOperator *op, tGPsdata *p) +static void gpencil_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgraph) { /* handle drawing/erasing -> test for erasing first */ if (p->paintmode == GP_PAINTMODE_ERASER) { @@ -2058,7 +2094,7 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p) /* finish off old stroke */ gp_paint_strokeend(p); /* And start a new one!!! Else, projection errors! */ - gp_paint_initstroke(p, p->paintmode); + gp_paint_initstroke(p, p->paintmode, depsgraph); /* start a new stroke, starting from previous point */ /* XXX Must manually reset inittime... */ @@ -2091,7 +2127,7 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p) } /* handle draw event */ -static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event) +static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event, Depsgraph *depsgraph) { tGPsdata *p = op->customdata; PointerRNA itemptr; @@ -2196,7 +2232,7 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event) RNA_float_set(&itemptr, "time", p->curtime - p->inittime); /* apply the current latest drawing point */ - gpencil_draw_apply(op, p); + gpencil_draw_apply(op, p, depsgraph); /* force refresh */ ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */ @@ -2208,6 +2244,7 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event) static int gpencil_draw_exec(bContext *C, wmOperator *op) { tGPsdata *p = NULL; + Depsgraph *depsgraph = CTX_data_depsgraph(C); /* printf("GPencil - Starting Re-Drawing\n"); */ @@ -2245,7 +2282,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op) if ((p->flags & GP_PAINTFLAG_FIRSTRUN) == 0) { /* TODO: both of these ops can set error-status, but we probably don't need to worry */ gp_paint_strokeend(p); - gp_paint_initstroke(p, p->paintmode); + gp_paint_initstroke(p, p->paintmode, depsgraph); } } @@ -2260,7 +2297,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op) } /* apply this data as necessary now (as per usual) */ - gpencil_draw_apply(op, p); + gpencil_draw_apply(op, p, depsgraph); } RNA_END; @@ -2319,7 +2356,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event p->status = GP_STATUS_PAINTING; /* handle the initial drawing - i.e. for just doing a simple dot */ - gpencil_draw_apply_event(op, event); + gpencil_draw_apply_event(op, event, CTX_data_depsgraph(C)); op->flag |= OP_IS_MODAL_CURSOR_REGION; } else { @@ -2360,7 +2397,7 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op) * it'd be nice to allow changing paint-mode when in sketching-sessions */ if (gp_session_initdata(C, p)) - gp_paint_initstroke(p, p->paintmode); + gp_paint_initstroke(p, p->paintmode, CTX_data_depsgraph(C)); if (p->status != GP_STATUS_ERROR) { p->status = GP_STATUS_PAINTING; @@ -2651,7 +2688,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event) if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) || (p->flags & GP_PAINTFLAG_FIRSTRUN)) { /* handle drawing event */ /* printf("\t\tGP - add point\n"); */ - gpencil_draw_apply_event(op, event); + gpencil_draw_apply_event(op, event, CTX_data_depsgraph(C)); /* finish painting operation if anything went wrong just now */ if (p->status == GP_STATUS_ERROR) { |