Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/gpencil/gpencil_paint.c')
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c127
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) {