diff options
author | Julian Eisel <julian@blender.org> | 2020-06-05 14:09:31 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-06-05 14:09:31 +0300 |
commit | 920a58d9b6d667894cf166cbbd25e4c2fbd238ea (patch) | |
tree | 7ca5a9da640753b5e070c439ac3bdd14dfad92cf /source/blender/editors/gpencil/drawgpencil.c | |
parent | c94b6209861ca7cc3985b53474feed7d94c0221a (diff) | |
parent | a1d55bdd530390e58c51abe9707b8d3b0ae3e861 (diff) |
Merge branch 'master' into wm-drag-drop-rewritewm-drag-drop-rewrite
Diffstat (limited to 'source/blender/editors/gpencil/drawgpencil.c')
-rw-r--r-- | source/blender/editors/gpencil/drawgpencil.c | 534 |
1 files changed, 1 insertions, 533 deletions
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 896ef7a9ad3..6d41e9bddbe 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -114,13 +114,6 @@ typedef enum eDrawStrokeFlags { /* ----- Tool Buffer Drawing ------ */ /* helper functions to set color of buffer point */ -static void gp_set_point_uniform_color(const bGPDspoint *pt, const float ink[4]) -{ - float alpha = ink[3] * pt->strength; - CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f); - immUniformColor3fvAlpha(ink, alpha); -} - static void gp_set_point_varying_color(const bGPDspoint *pt, const float ink[4], uint attr_id, @@ -134,74 +127,8 @@ static void gp_set_point_varying_color(const bGPDspoint *pt, immAttr4ub(attr_id, F2UB(ink[0]), F2UB(ink[1]), F2UB(ink[2]), F2UB(alpha)); } -/* --------- 2D Stroke Drawing Helpers --------- */ -/* change in parameter list */ -static void gp_calc_2d_stroke_fxy( - const float pt[3], short sflag, int offsx, int offsy, int winx, int winy, float r_co[2]) -{ - if (sflag & GP_STROKE_2DSPACE) { - r_co[0] = pt[0]; - r_co[1] = pt[1]; - } - else if (sflag & GP_STROKE_2DIMAGE) { - const float x = (float)((pt[0] * winx) + offsx); - const float y = (float)((pt[1] * winy) + offsy); - - r_co[0] = x; - r_co[1] = y; - } - else { - const float x = (float)(pt[0] / 100 * winx) + offsx; - const float y = (float)(pt[1] / 100 * winy) + offsy; - - r_co[0] = x; - r_co[1] = y; - } -} /* ----------- Volumetric Strokes --------------- */ -/* draw a 2D strokes in "volumetric" style */ -static void gp_draw_stroke_volumetric_2d(const bGPDspoint *points, - int totpoints, - short thickness, - short UNUSED(dflag), - short sflag, - int offsx, - int offsy, - int winx, - int winy, - const float diff_mat[4][4], - const float ink[4]) -{ - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - uint color = GPU_vertformat_attr_add( - format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR); - GPU_program_point_size(true); - immBegin(GPU_PRIM_POINTS, totpoints); - - const bGPDspoint *pt = points; - for (int i = 0; i < totpoints; i++, pt++) { - /* transform position to 2D */ - float co[2]; - float fpt[3]; - - mul_v3_m4v3(fpt, diff_mat, &pt->x); - gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, co); - - gp_set_point_varying_color(pt, ink, color, false); - immAttr1f(size, pt->pressure * thickness); /* TODO: scale based on view transform */ - immVertex2f(pos, co[0], co[1]); - } - - immEnd(); - immUnbindProgram(); - GPU_program_point_size(false); -} - /* draw a 3D stroke in "volumetric" style */ static void gp_draw_stroke_volumetric_3d(const bGPDspoint *points, int totpoints, @@ -232,136 +159,8 @@ static void gp_draw_stroke_volumetric_3d(const bGPDspoint *points, GPU_program_point_size(false); } -/* --------------- Stroke Fills ----------------- */ -/* add a new fill point and texture coordinates to vertex buffer */ -static void gp_add_filldata_tobuffer(const bGPDspoint *pt, - uint pos, - uint texcoord, - short flag, - int offsx, - int offsy, - int winx, - int winy, - const float diff_mat[4][4]) -{ - float fpt[3]; - float co[2]; - - mul_v3_m4v3(fpt, diff_mat, &pt->x); - /* if 2d, need conversion */ - if (!(flag & GP_STROKE_3DSPACE)) { - gp_calc_2d_stroke_fxy(fpt, flag, offsx, offsy, winx, winy, co); - copy_v2_v2(fpt, co); - fpt[2] = 0.0f; /* 2d always is z=0.0f */ - } - - immAttr2f(texcoord, pt->uv_fill[0], pt->uv_fill[1]); /* texture coordinates */ - immVertex3fv(pos, fpt); /* position */ -} - -/* draw fills for shapes */ -static void gp_draw_stroke_fill(bGPdata *gpd, - bGPDstroke *gps, - int offsx, - int offsy, - int winx, - int winy, - const float diff_mat[4][4], - const float color[4]) -{ - BLI_assert(gps->totpoints >= 3); - BLI_assert(gps->tot_triangles >= 1); - const bool use_mat = (gpd->mat != NULL); - - Material *ma = (use_mat) ? gpd->mat[gps->mat_nr] : BKE_material_default_gpencil(); - MaterialGPencilStyle *gp_style = (ma) ? ma->gp_style : NULL; - - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_GPENCIL_FILL); - - immUniformColor4fv(color); - immUniform4fv("color2", gp_style->mix_rgba); - immUniform1i("fill_type", gp_style->fill_style); - immUniform1f("mix_factor", gp_style->mix_factor); - - immUniform1f("texture_angle", gp_style->texture_angle); - immUniform2fv("texture_scale", gp_style->texture_scale); - immUniform2fv("texture_offset", gp_style->texture_offset); - immUniform1f("texture_opacity", gp_style->texture_opacity); - immUniform1i("t_mix", (gp_style->flag & GP_MATERIAL_FILL_TEX_MIX) != 0); - immUniform1i("t_flip", (gp_style->flag & GP_MATERIAL_FLIP_FILL) != 0); - - /* Draw all triangles for filling the polygon (cache must be calculated before) */ - immBegin(GPU_PRIM_TRIS, gps->tot_triangles * 3); - /* TODO: use batch instead of immediate mode, to share vertices */ - - const bGPDtriangle *stroke_triangle = gps->triangles; - for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) { - for (int j = 0; j < 3; j++) { - gp_add_filldata_tobuffer(&gps->points[stroke_triangle->verts[j]], - pos, - texcoord, - gps->flag, - offsx, - offsy, - winx, - winy, - diff_mat); - } - } - - immEnd(); - immUnbindProgram(); -} - /* ----- Existing Strokes Drawing (3D and Point) ------ */ -/* draw a given stroke - just a single dot (only one point) */ -static void gp_draw_stroke_point(const bGPDspoint *points, - short thickness, - short UNUSED(dflag), - short sflag, - int offsx, - int offsy, - int winx, - int winy, - const float diff_mat[4][4], - const float ink[4]) -{ - const bGPDspoint *pt = points; - - /* get final position using parent matrix */ - float fpt[3]; - mul_v3_m4v3(fpt, diff_mat, &pt->x); - - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - - if (sflag & GP_STROKE_3DSPACE) { - immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); - } - else { - immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); - - /* get 2D coordinates of point */ - float co[3] = {0.0f}; - gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, co); - copy_v3_v3(fpt, co); - } - - gp_set_point_uniform_color(pt, ink); - /* set point thickness (since there's only one of these) */ - immUniform1f("size", (float)(thickness + 2) * pt->pressure); - - immBegin(GPU_PRIM_POINTS, 1); - immVertex3fv(pos, fpt); - immEnd(); - - immUnbindProgram(); -} - /* draw a given stroke in 3d (i.e. in 3d-space) */ static void gp_draw_stroke_3d(tGPDdraw *tgpw, short thickness, const float ink[4], bool cyclic) { @@ -454,200 +253,6 @@ static void gp_draw_stroke_3d(tGPDdraw *tgpw, short thickness, const float ink[4 immUnbindProgram(); } -/* ----- Fancy 2D-Stroke Drawing ------ */ - -/* draw a given stroke in 2d */ -static void gp_draw_stroke_2d(const bGPDspoint *points, - int totpoints, - short thickness_s, - short dflag, - short sflag, - bool UNUSED(debug), - int offsx, - int offsy, - int winx, - int winy, - const float diff_mat[4][4], - const float ink[4]) -{ - /* otherwise thickness is twice that of the 3D view */ - float thickness = (float)thickness_s * 0.5f; - - /* strokes in Image Editor need a scale factor, since units there are not pixels! */ - float scalefac = 1.0f; - if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) { - scalefac = 0.001f; - } - - /* TODO: fancy++ with the magic of shaders */ - - /* tessellation code - draw stroke as series of connected quads (triangle strips in fact) - * with connection edges rotated to minimize shrinking artifacts, and rounded endcaps. - */ - { - const bGPDspoint *pt1, *pt2; - float s0[2], s1[2]; /* segment 'center' points */ - float pm[2]; /* normal from previous segment. */ - int i; - float fpt[3]; - - GPUVertFormat *format = immVertexFormat(); - const struct { - uint pos, color; - } attr_id = { - .pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT), - .color = GPU_vertformat_attr_add( - format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT), - }; - - immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - immBegin(GPU_PRIM_TRI_STRIP, totpoints * 2 + 4); - - /* get x and y coordinates from first point */ - mul_v3_m4v3(fpt, diff_mat, &points->x); - gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, s0); - - for (i = 0, pt1 = points, pt2 = points + 1; i < (totpoints - 1); i++, pt1++, pt2++) { - float t0[2], t1[2]; /* tessellated coordinates */ - float m1[2], m2[2]; /* gradient and normal */ - float mt[2], sc[2]; /* gradient for thickness, point for end-cap */ - float pthick; /* thickness at segment point */ - - /* Get x and y coordinates from point2 - * (point1 has already been computed in previous iteration). */ - mul_v3_m4v3(fpt, diff_mat, &pt2->x); - gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, s1); - - /* calculate gradient and normal - 'angle'=(ny/nx) */ - m1[1] = s1[1] - s0[1]; - m1[0] = s1[0] - s0[0]; - normalize_v2(m1); - m2[1] = -m1[0]; - m2[0] = m1[1]; - - /* always use pressure from first point here */ - pthick = (pt1->pressure * thickness * scalefac); - - /* color of point */ - gp_set_point_varying_color(pt1, ink, attr_id.color, false); - - /* if the first segment, start of segment is segment's normal */ - if (i == 0) { - /* draw start cap first - * - make points slightly closer to center (about halfway across) - */ - mt[0] = m2[0] * pthick * 0.5f; - mt[1] = m2[1] * pthick * 0.5f; - sc[0] = s0[0] - (m1[0] * pthick * 0.75f); - sc[1] = s0[1] - (m1[1] * pthick * 0.75f); - - t0[0] = sc[0] - mt[0]; - t0[1] = sc[1] - mt[1]; - t1[0] = sc[0] + mt[0]; - t1[1] = sc[1] + mt[1]; - - /* First two points of cap. */ - immVertex2fv(attr_id.pos, t0); - immVertex2fv(attr_id.pos, t1); - - /* calculate points for start of segment */ - mt[0] = m2[0] * pthick; - mt[1] = m2[1] * pthick; - - t0[0] = s0[0] - mt[0]; - t0[1] = s0[1] - mt[1]; - t1[0] = s0[0] + mt[0]; - t1[1] = s0[1] + mt[1]; - - /* Last two points of start cap (and first two points of first segment). */ - immVertex2fv(attr_id.pos, t0); - immVertex2fv(attr_id.pos, t1); - } - /* if not the first segment, use bisector of angle between segments */ - else { - float mb[2]; /* bisector normal */ - float athick, dfac; /* actual thickness, difference between thicknesses */ - - /* calculate gradient of bisector (as average of normals) */ - mb[0] = (pm[0] + m2[0]) / 2; - mb[1] = (pm[1] + m2[1]) / 2; - normalize_v2(mb); - - /* calculate gradient to apply - * - as basis, use just pthick * bisector gradient - * - if cross-section not as thick as it should be, add extra padding to fix it - */ - mt[0] = mb[0] * pthick; - mt[1] = mb[1] * pthick; - athick = len_v2(mt); - dfac = pthick - (athick * 2); - - if (((athick * 2.0f) < pthick) && (IS_EQF(athick, pthick) == 0)) { - mt[0] += (mb[0] * dfac); - mt[1] += (mb[1] * dfac); - } - - /* calculate points for start of segment */ - t0[0] = s0[0] - mt[0]; - t0[1] = s0[1] - mt[1]; - t1[0] = s0[0] + mt[0]; - t1[1] = s0[1] + mt[1]; - - /* Last two points of previous segment, and first two points of current segment. */ - immVertex2fv(attr_id.pos, t0); - immVertex2fv(attr_id.pos, t1); - } - - /* if last segment, also draw end of segment (defined as segment's normal) */ - if (i == totpoints - 2) { - /* for once, we use second point's pressure (otherwise it won't be drawn) */ - pthick = (pt2->pressure * thickness * scalefac); - - /* color of point */ - gp_set_point_varying_color(pt2, ink, attr_id.color, false); - - /* calculate points for end of segment */ - mt[0] = m2[0] * pthick; - mt[1] = m2[1] * pthick; - - t0[0] = s1[0] - mt[0]; - t0[1] = s1[1] - mt[1]; - t1[0] = s1[0] + mt[0]; - t1[1] = s1[1] + mt[1]; - - /* Last two points of last segment (and first two points of end cap). */ - immVertex2fv(attr_id.pos, t0); - immVertex2fv(attr_id.pos, t1); - - /* draw end cap as last step - * - make points slightly closer to center (about halfway across) - */ - mt[0] = m2[0] * pthick * 0.5f; - mt[1] = m2[1] * pthick * 0.5f; - sc[0] = s1[0] + (m1[0] * pthick * 0.75f); - sc[1] = s1[1] + (m1[1] * pthick * 0.75f); - - t0[0] = sc[0] - mt[0]; - t0[1] = sc[1] - mt[1]; - t1[0] = sc[0] + mt[0]; - t1[1] = sc[1] + mt[1]; - - /* Last two points of end cap. */ - immVertex2fv(attr_id.pos, t0); - immVertex2fv(attr_id.pos, t1); - } - - /* store computed point2 coordinates as point1 ones of next segment. */ - copy_v2_v2(s0, s1); - /* store stroke's 'natural' normal for next stroke to use */ - copy_v2_v2(pm, m2); - } - - immEnd(); - immUnbindProgram(); - } -} - /* ----- Strokes Drawing ------ */ /* Helper for doing all the checks on whether a stroke can be drawn */ @@ -691,7 +296,6 @@ static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag) static void gp_draw_strokes(tGPDdraw *tgpw) { float tcolor[4]; - float tfill[4]; short sthickness; float ink[4]; const bool is_unique = (tgpw->gps != NULL); @@ -748,37 +352,6 @@ static void gp_draw_strokes(tGPDdraw *tgpw) bglPolygonOffset(1.0f, 1.0f); } - /* 3D Fill */ - // if ((dflag & GP_DRAWDATA_FILL) && (gps->totpoints >= 3)) { - if ((gps->totpoints >= 3) && (tgpw->disable_fill != 1)) { - /* set color using material, tint color and opacity */ - interp_v3_v3v3(tfill, gp_style->fill_rgba, tgpw->tintcolor, tgpw->tintcolor[3]); - tfill[3] = gp_style->fill_rgba[3] * tgpw->opacity; - if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0)) { - const float *color; - if (!tgpw->onion) { - color = tfill; - } - else { - if (tgpw->custonion) { - color = tgpw->tintcolor; - } - else { - ARRAY_SET_ITEMS(tfill, UNPACK3(gp_style->fill_rgba), tgpw->tintcolor[3]); - color = tfill; - } - } - gp_draw_stroke_fill(tgpw->gpd, - gps, - tgpw->offsx, - tgpw->offsy, - tgpw->winx, - tgpw->winy, - tgpw->diff_mat, - color); - } - } - /* 3D Stroke */ /* set color using material tint color and opacity */ if (!tgpw->onion) { @@ -811,21 +384,7 @@ static void gp_draw_strokes(tGPDdraw *tgpw) } else { /* 3D Lines - OpenGL primitives-based */ - if (gps->totpoints == 1) { - if (tgpw->disable_fill != 1) { - gp_draw_stroke_point(gps->points, - sthickness, - tgpw->dflag, - gps->flag, - tgpw->offsx, - tgpw->offsy, - tgpw->winx, - tgpw->winy, - tgpw->diff_mat, - ink); - } - } - else { + if (gps->totpoints > 1) { tgpw->gps = gps; gp_draw_stroke_3d(tgpw, sthickness, ink, gps->flag & GP_STROKE_CYCLIC); } @@ -837,97 +396,6 @@ static void gp_draw_strokes(tGPDdraw *tgpw) bglPolygonOffset(0.0, 0.0); } } - else { - /* 2D - Fill */ - if (gps->totpoints >= 3) { - /* set color using material, tint color and opacity */ - interp_v3_v3v3(tfill, gp_style->fill_rgba, tgpw->tintcolor, tgpw->tintcolor[3]); - tfill[3] = gp_style->fill_rgba[3] * tgpw->opacity; - if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0)) { - const float *color; - if (!tgpw->onion) { - color = tfill; - } - else { - if (tgpw->custonion) { - color = tgpw->tintcolor; - } - else { - ARRAY_SET_ITEMS(tfill, UNPACK3(gp_style->fill_rgba), tgpw->tintcolor[3]); - color = tfill; - } - } - gp_draw_stroke_fill(tgpw->gpd, - gps, - tgpw->offsx, - tgpw->offsy, - tgpw->winx, - tgpw->winy, - tgpw->diff_mat, - color); - } - } - - /* 2D Strokes... */ - /* set color using material, tint color and opacity */ - if (!tgpw->onion) { - interp_v3_v3v3(tcolor, gp_style->stroke_rgba, tgpw->tintcolor, tgpw->tintcolor[3]); - tcolor[3] = gp_style->stroke_rgba[3] * tgpw->opacity; - copy_v4_v4(ink, tcolor); - } - else { - if (tgpw->custonion) { - copy_v4_v4(ink, tgpw->tintcolor); - } - else { - ARRAY_SET_ITEMS(tcolor, UNPACK3(gp_style->stroke_rgba), tgpw->opacity); - copy_v4_v4(ink, tcolor); - } - } - if (gp_style->mode == GP_MATERIAL_MODE_DOT) { - /* blob/disk-based "volumetric" drawing */ - gp_draw_stroke_volumetric_2d(gps->points, - gps->totpoints, - sthickness, - tgpw->dflag, - gps->flag, - tgpw->offsx, - tgpw->offsy, - tgpw->winx, - tgpw->winy, - tgpw->diff_mat, - ink); - } - else { - /* normal 2D strokes */ - if (gps->totpoints == 1) { - gp_draw_stroke_point(gps->points, - sthickness, - tgpw->dflag, - gps->flag, - tgpw->offsx, - tgpw->offsy, - tgpw->winx, - tgpw->winy, - tgpw->diff_mat, - ink); - } - else { - gp_draw_stroke_2d(gps->points, - gps->totpoints, - sthickness, - tgpw->dflag, - gps->flag, - false, - tgpw->offsx, - tgpw->offsy, - tgpw->winx, - tgpw->winy, - tgpw->diff_mat, - ink); - } - } - } /* if only one stroke, exit from loop */ if (is_unique) { break; |