diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_stroke.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_stroke.c | 125 |
1 files changed, 85 insertions, 40 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index de804677de9..b5d68786664 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -38,6 +38,8 @@ #include "BLI_rand.h" #include "BLI_listbase.h" +#include "PIL_time.h" + #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_brush_types.h" @@ -51,6 +53,7 @@ #include "BKE_curve.h" #include "BKE_colortools.h" #include "BKE_image.h" +#include "BKE_mesh.h" #include "WM_api.h" #include "WM_types.h" @@ -58,7 +61,8 @@ #include "BIF_gl.h" #include "BIF_glutil.h" -#include "GPU_basic_shader.h" +#include "GPU_immediate.h" +#include "GPU_state.h" #include "ED_screen.h" #include "ED_view3d.h" @@ -85,6 +89,7 @@ typedef struct PaintStroke { void *mode_data; void *stroke_cursor; wmTimer *timer; + struct RNG *rng; /* Cached values */ ViewContext vc; @@ -145,13 +150,27 @@ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata PaintStroke *stroke = customdata; if (stroke && brush) { - glEnable(GL_LINE_SMOOTH); - glEnable(GL_BLEND); - glColor4ubv(paint->paint_cursor_col); - sdrawline(x, y, (int)stroke->last_mouse_position[0], - (int)stroke->last_mouse_position[1]); - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); + GPU_line_smooth(true); + GPU_blend(true); + + ARegion *ar = stroke->vc.ar; + + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4ubv(paint->paint_cursor_col); + + immBegin(GPU_PRIM_LINES, 2); + immVertex2f(pos, x, y); + immVertex2f(pos, + stroke->last_mouse_position[0] + ar->winrct.xmin, + stroke->last_mouse_position[1] + ar->winrct.ymin); + + immEnd(); + + immUnbindProgram(); + + GPU_blend(false); + GPU_line_smooth(false); } } @@ -160,38 +179,47 @@ static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata) Paint *paint = BKE_paint_get_active_from_context(C); PaintStroke *stroke = customdata; - glEnable(GL_LINE_SMOOTH); - glEnable(GL_BLEND); + GPU_line_smooth(true); - GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE); - GPU_basic_shader_line_stipple(3, 0xAAAA); - GPU_basic_shader_line_width(3.0); + uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - glColor4ub(0, 0, 0, paint->paint_cursor_col[3]); - if (stroke->constrain_line) { - sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1], - stroke->constrained_pos[0], stroke->constrained_pos[1]); - } - else { - sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1], - x, y); - } + immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); + + float viewport_size[4]; + GPU_viewport_size_get_f(viewport_size); + immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); + + immUniform1i("colors_len", 2); /* "advanced" mode */ + const float alpha = (float)paint->paint_cursor_col[3] / 255.0f; + immUniformArray4fv("colors", (float *)(float[][4]){{0.0f, 0.0f, 0.0f, alpha}, {1.0f, 1.0f, 1.0f, alpha}}, 2); + immUniform1f("dash_width", 6.0f); + + immBegin(GPU_PRIM_LINES, 2); + + ARegion *ar = stroke->vc.ar; - glColor4ub(255, 255, 255, paint->paint_cursor_col[3]); - GPU_basic_shader_line_width(1.0); if (stroke->constrain_line) { - sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1], - stroke->constrained_pos[0], stroke->constrained_pos[1]); + immVertex2f(shdr_pos, + stroke->last_mouse_position[0] + ar->winrct.xmin, + stroke->last_mouse_position[1] + ar->winrct.ymin); + + immVertex2f(shdr_pos, + stroke->constrained_pos[0] + ar->winrct.xmin, + stroke->constrained_pos[1] + ar->winrct.ymin); } else { - sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1], - x, y); + immVertex2f(shdr_pos, + stroke->last_mouse_position[0] + ar->winrct.xmin, + stroke->last_mouse_position[1] + ar->winrct.ymin); + + immVertex2f(shdr_pos, x, y); } - GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE); + immEnd(); + + immUnbindProgram(); - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); + GPU_line_smooth(false); } static bool paint_tool_require_location(Brush *brush, ePaintMode mode) @@ -383,19 +411,24 @@ static bool paint_brush_update( } } + if ((do_random || do_random_mask) && stroke->rng == NULL) { + /* Lazy initialization. */ + uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); + rng_seed ^= (uint)GET_INT_FROM_POINTER(brush); + stroke->rng = BLI_rng_new(rng_seed); + } + if (do_random) { if (brush->mtex.brush_angle_mode & MTEX_ANGLE_RANDOM) { - ups->brush_rotation += ( - -brush->mtex.random_angle / 2.0f + - brush->mtex.random_angle * BLI_frand()); + ups->brush_rotation += -brush->mtex.random_angle / 2.0f + + brush->mtex.random_angle * BLI_rng_get_float(stroke->rng); } } if (do_random_mask) { if (brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RANDOM) { - ups->brush_rotation_sec += ( - -brush->mask_mtex.random_angle / 2.0f + - brush->mask_mtex.random_angle * BLI_frand()); + ups->brush_rotation_sec += -brush->mask_mtex.random_angle / 2.0f + + brush->mask_mtex.random_angle * BLI_rng_get_float(stroke->rng); } } @@ -788,6 +821,10 @@ static void stroke_done(struct bContext *C, struct wmOperator *op) stroke->timer); } + if (stroke->rng) { + BLI_rng_free(stroke->rng); + } + if (stroke->stroke_cursor) WM_paint_cursor_end(CTX_wm_manager(C), stroke->stroke_cursor); @@ -1353,7 +1390,15 @@ bool paint_poll(bContext *C) ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); - return p && ob && BKE_paint_brush(p) && - (sa && ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) && - (ar && ar->regiontype == RGN_TYPE_WINDOW); + if (p && ob && BKE_paint_brush(p) && + (sa && ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) && + (ar && ar->regiontype == RGN_TYPE_WINDOW)) + { + /* Check the current tool is a brush. */ + bToolRef *tref = sa->runtime.tool; + if (tref && tref->runtime && tref->runtime->data_block[0]) { + return true; + } + } + return false; } |