Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / sculpt_paint / paint_stroke.c
index acd62cb936e31f43ca85e832f1529795da0839cd..21afb9493305f53d2d8057316ffdccf09a21fbcb 100644 (file)
@@ -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;
+
+               unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+               immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+               immUniformColor4ubv(paint->paint_cursor_col);
+
+               immBegin(GWN_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 = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_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_getf(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(GWN_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();
 
-       glDisable(GL_BLEND);
-       glDisable(GL_LINE_SMOOTH);
+       immUnbindProgram();
+
+       GPU_line_smooth(false);
 }
 
 static bool paint_tool_require_location(Brush *brush, ePaintMode mode)
@@ -382,17 +410,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();
+                                              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();
+                                                  brush->mask_mtex.random_angle * BLI_rng_get_float(stroke->rng);
                }
        }
 
@@ -772,6 +807,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);