diff options
Diffstat (limited to 'source/blender/editors/gpencil')
-rw-r--r-- | source/blender/editors/gpencil/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/gpencil/drawgpencil.c | 934 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_brush.c | 26 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_convert.c | 46 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_edit.c | 12 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_ops.c | 22 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_paint.c | 84 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_utils.c | 20 |
8 files changed, 567 insertions, 578 deletions
diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt index 3d5317b2ebd..587c25031ab 100644 --- a/source/blender/editors/gpencil/CMakeLists.txt +++ b/source/blender/editors/gpencil/CMakeLists.txt @@ -24,6 +24,7 @@ set(INC ../../blenkernel ../../blenlib ../../blentranslation + ../../depsgraph ../../imbuf ../../gpu ../../makesdna diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 338fac03fef..a30cb578046 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -60,9 +60,11 @@ #include "WM_api.h" -#include "BIF_gl.h" #include "BIF_glutil.h" +#include "GPU_immediate.h" +#include "GPU_draw.h" + #include "ED_gpencil.h" #include "ED_screen.h" #include "ED_view3d.h" @@ -92,38 +94,105 @@ typedef enum eDrawStrokeFlags { /* thickness above which we should use special drawing */ +#if 0 #define GP_DRAWTHICKNESS_SPECIAL 3 +#endif + +/* conversion utility (float --> normalized unsigned byte) */ +#define F2UB(x) (unsigned char)(255.0f * x) /* ----- Tool Buffer Drawing ------ */ -/* helper function to set color of buffer point */ -static void gp_set_tpoint_color(tGPspoint *pt, float ink[4]) +/* helper functions to set color of buffer point */ + +static void gp_set_tpoint_varying_color(const tGPspoint *pt, const float ink[4], unsigned attrib_id) { float alpha = ink[3] * pt->strength; CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f); - glColor4f(ink[0], ink[1], ink[2], alpha); + immAttrib4ub(attrib_id, F2UB(ink[0]), F2UB(ink[1]), F2UB(ink[2]), F2UB(alpha)); } -/* helper function to set color of point */ -static void gp_set_point_color(bGPDspoint *pt, float ink[4]) +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); - glColor4f(ink[0], ink[1], ink[2], alpha); + immUniformColor3fvAlpha(ink, alpha); } -/* helper function to set color and point */ -static void gp_set_color_and_tpoint(tGPspoint *pt, float ink[4]) +static void gp_set_point_varying_color(const bGPDspoint *pt, const float ink[4], unsigned attrib_id) { - gp_set_tpoint_color(pt, ink); - glVertex2iv(&pt->x); + float alpha = ink[3] * pt->strength; + CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f); + immAttrib4ub(attrib_id, F2UB(ink[0]), F2UB(ink[1]), F2UB(ink[2]), F2UB(alpha)); +} + +/* draw fills for buffer stroke */ +static void gp_draw_stroke_buffer_fill(const tGPspoint *points, int totpoints, float ink[4]) +{ + if (totpoints < 3) { + return; + } + int tot_triangles = totpoints - 2; + /* allocate memory for temporary areas */ + unsigned int(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, "GP Stroke buffer temp triangulation"); + float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, "GP Stroke buffer temp 2d points"); + + /* Convert points to array and triangulate + * Here a cache is not used because while drawing the information changes all the time, so the cache + * would be recalculated constantly, so it is better to do direct calculation for each function call + */ + for (int i = 0; i < totpoints; i++) { + const tGPspoint *pt = &points[i]; + points2d[i][0] = pt->x; + points2d[i][1] = pt->y; + } + BLI_polyfill_calc((const float(*)[2])points2d, (unsigned int)totpoints, 0, (unsigned int(*)[3])tmp_triangles); + + /* draw triangulation data */ + if (tot_triangles > 0) { + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + + immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); + + /* Draw all triangles for filling the polygon */ + immBegin(GWN_PRIM_TRIS, tot_triangles * 3); + /* TODO: use batch instead of immediate mode, to share vertices */ + + const tGPspoint *pt; + for (int i = 0; i < tot_triangles; i++) { + /* vertex 1 */ + pt = &points[tmp_triangles[i][0]]; + gp_set_tpoint_varying_color(pt, ink, color); + immVertex2iv(pos, &pt->x); + /* vertex 2 */ + pt = &points[tmp_triangles[i][1]]; + gp_set_tpoint_varying_color(pt, ink, color); + immVertex2iv(pos, &pt->x); + /* vertex 3 */ + pt = &points[tmp_triangles[i][2]]; + gp_set_tpoint_varying_color(pt, ink, color); + immVertex2iv(pos, &pt->x); + } + + immEnd(); + immUnbindProgram(); + } + + /* clear memory */ + if (tmp_triangles) { + MEM_freeN(tmp_triangles); + } + if (points2d) { + MEM_freeN(points2d); + } } /* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */ -static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickness, - short dflag, short sflag, float ink[4]) +static void gp_draw_stroke_buffer(const tGPspoint *points, int totpoints, short thickness, + short dflag, short sflag, float ink[4], float fill_ink[4]) { - tGPspoint *pt; - int i; + int draw_points = 0; /* error checking */ if ((points == NULL) || (totpoints <= 0)) @@ -133,58 +202,86 @@ static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickn if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D)) return; + if (sflag & GP_STROKE_ERASER) { + /* don't draw stroke at all! */ + return; + } + + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT); + unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + + const tGPspoint *pt = points; + if (totpoints == 1) { /* if drawing a single point, draw it larger */ glPointSize((float)(thickness + 2) * points->pressure); - glBegin(GL_POINTS); - - gp_set_color_and_tpoint(points, ink); - glEnd(); - } - else if (sflag & GP_STROKE_ERASER) { - /* don't draw stroke at all! */ + immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR); + immBegin(GWN_PRIM_POINTS, 1); + gp_set_tpoint_varying_color(pt, ink, color); + immVertex2iv(pos, &pt->x); } else { float oldpressure = points[0].pressure; /* draw stroke curve */ - if (G.debug & G_DEBUG) setlinestyle(2); - glLineWidth(max_ff(oldpressure * thickness, 1.0)); - glBegin(GL_LINE_STRIP); + immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); + immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints); - for (i = 0, pt = points; i < totpoints && pt; i++, pt++) { + /* TODO: implement this with a geometry shader to draw one continuous tapered stroke */ + + for (int i = 0; i < totpoints; i++, pt++) { /* if there was a significant pressure change, stop the curve, change the thickness of the stroke, * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP) */ if (fabsf(pt->pressure - oldpressure) > 0.2f) { - glEnd(); + /* need to have 2 points to avoid immEnd assert error */ + if (draw_points < 2) { + gp_set_tpoint_varying_color(pt - 1, ink, color); + immVertex2iv(pos, &(pt - 1)->x); + } + + immEnd(); + draw_points = 0; + glLineWidth(max_ff(pt->pressure * thickness, 1.0f)); - glBegin(GL_LINE_STRIP); + immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints - i + 1); /* need to roll-back one point to ensure that there are no gaps in the stroke */ if (i != 0) { - gp_set_color_and_tpoint((pt - 1), ink); + gp_set_tpoint_varying_color(pt - 1, ink, color); + immVertex2iv(pos, &(pt - 1)->x); + ++draw_points; } - /* now the point we want... */ - gp_set_color_and_tpoint(pt, ink); - - oldpressure = pt->pressure; - } - else { - gp_set_color_and_tpoint(pt, ink); + oldpressure = pt->pressure; /* reset our threshold */ } + + /* now the point we want */ + gp_set_tpoint_varying_color(pt, ink, color); + immVertex2iv(pos, &pt->x); + ++draw_points; + } + /* need to have 2 points to avoid immEnd assert error */ + if (draw_points < 2) { + gp_set_tpoint_varying_color(pt - 1, ink, color); + immVertex2iv(pos, &(pt - 1)->x); } - glEnd(); + } + + immEnd(); + immUnbindProgram(); - if (G.debug & G_DEBUG) setlinestyle(0); + // draw fill + if (fill_ink[3] > GPENCIL_ALPHA_OPACITY_THRESH) { + gp_draw_stroke_buffer_fill(points, totpoints, fill_ink); } } /* --------- 2D Stroke Drawing Helpers --------- */ /* change in parameter list */ -static void gp_calc_2d_stroke_fxy(float pt[3], short sflag, int offsx, int offsy, int winx, int winy, float r_co[2]) +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]; @@ -210,15 +307,9 @@ static void gp_calc_2d_stroke_fxy(float pt[3], short sflag, int offsx, int offsy /* draw a 2D buffer stroke in "volumetric" style * NOTE: the stroke buffer doesn't have any coordinate offsets/transforms */ -static void gp_draw_stroke_volumetric_buffer(tGPspoint *points, int totpoints, short thickness, - short dflag, short UNUSED(sflag), float ink[4]) +static void gp_draw_stroke_volumetric_buffer(const tGPspoint *points, int totpoints, short thickness, + short dflag, const float ink[4]) { - GLUquadricObj *qobj = gluNewQuadric(); - float modelview[4][4]; - - tGPspoint *pt; - int i; - /* error checking */ if ((points == NULL) || (totpoints <= 0)) return; @@ -227,152 +318,96 @@ static void gp_draw_stroke_volumetric_buffer(tGPspoint *points, int totpoints, s if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D)) return; - /* get basic matrix - should be camera space (i.e "identity") */ - glGetFloatv(GL_MODELVIEW_MATRIX, (float *)modelview); - - /* draw points */ - glPushMatrix(); + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + unsigned int size = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); + unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); - for (i = 0, pt = points; i < totpoints; i++, pt++) { - /* set the transformed position */ - // TODO: scale should change based on zoom level, which requires proper translation mult too! - modelview[3][0] = pt->x; - modelview[3][1] = pt->y; + immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR); + GPU_enable_program_point_size(); + immBegin(GWN_PRIM_POINTS, totpoints); - glLoadMatrixf((float *)modelview); - - /* draw the disk using the current state... */ - gp_set_tpoint_color(pt, ink); - gluDisk(qobj, 0.0, pt->pressure * thickness, 32, 1); - - - modelview[3][0] = modelview[3][1] = 0.0f; + const tGPspoint *pt = points; + for (int i = 0; i < totpoints; i++, pt++) { + gp_set_tpoint_varying_color(pt, ink, color); + immAttrib1f(size, pt->pressure * thickness); /* TODO: scale based on view transform (zoom level) */ + immVertex2f(pos, pt->x, pt->y); } - glPopMatrix(); - gluDeleteQuadric(qobj); + immEnd(); + immUnbindProgram(); + GPU_disable_program_point_size(); } /* draw a 2D strokes in "volumetric" style */ -static void gp_draw_stroke_volumetric_2d(bGPDspoint *points, int totpoints, short thickness, - short dflag, short sflag, +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, - float diff_mat[4][4], float ink[4]) + const float diff_mat[4][4], const float ink[4]) { - GLUquadricObj *qobj = gluNewQuadric(); - float modelview[4][4]; - float baseloc[3]; - float scalefac = 1.0f; - - bGPDspoint *pt; - int i; - float fpt[3]; - - /* HACK: We need a scale factor for the drawing in the image editor, - * which seems to use 1 unit as it's maximum size, whereas everything - * else assumes 1 unit = 1 pixel. Otherwise, we only get a massive blob. - */ - if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) { - scalefac = 0.001f; - } - - /* get basic matrix */ - glGetFloatv(GL_MODELVIEW_MATRIX, (float *)modelview); - copy_v3_v3(baseloc, modelview[3]); - - /* draw points */ - glPushMatrix(); - - for (i = 0, pt = points; i < totpoints; i++, pt++) { - /* color of point */ - gp_set_point_color(pt, ink); - - /* set the transformed position */ + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + unsigned int size = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); + unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + + immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR); + GPU_enable_program_point_size(); + immBegin(GWN_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); - translate_m4(modelview, co[0], co[1], 0.0f); - - glLoadMatrixf((float *)modelview); - - /* draw the disk using the current state... */ - gluDisk(qobj, 0.0, pt->pressure * thickness * scalefac, 32, 1); - /* restore matrix */ - copy_v3_v3(modelview[3], baseloc); + gp_set_point_varying_color(pt, ink, color); + immAttrib1f(size, pt->pressure * thickness); /* TODO: scale based on view transform */ + immVertex2f(pos, co[0], co[1]); } - glPopMatrix(); - gluDeleteQuadric(qobj); + immEnd(); + immUnbindProgram(); + GPU_disable_program_point_size(); } /* draw a 3D stroke in "volumetric" style */ static void gp_draw_stroke_volumetric_3d( - bGPDspoint *points, int totpoints, short thickness, - short UNUSED(dflag), short UNUSED(sflag), float diff_mat[4][4], float ink[4]) + const bGPDspoint *points, int totpoints, short thickness, + const float ink[4]) { - GLUquadricObj *qobj = gluNewQuadric(); - - float base_modelview[4][4], modelview[4][4]; - float base_loc[3]; - - bGPDspoint *pt; - int i; - float fpt[3]; - - /* Get the basic modelview matrix we use for performing calculations */ - glGetFloatv(GL_MODELVIEW_MATRIX, (float *)base_modelview); - copy_v3_v3(base_loc, base_modelview[3]); - - /* Create the basic view-aligned billboard matrix we're going to actually draw qobj with: - * - We need to knock out the rotation so that we are - * simply left with a camera-facing billboard - * - The scale factors here are chosen so that the thickness - * is relatively reasonable. Otherwise, it gets far too - * large! - */ - scale_m4_fl(modelview, 0.1f); - - /* draw each point as a disk... */ - glPushMatrix(); - - for (i = 0, pt = points; i < totpoints && pt; i++, pt++) { - /* color of point */ - gp_set_point_color(pt, ink); - - mul_v3_m4v3(fpt, diff_mat, &pt->x); - - /* apply translation to base_modelview, so that the translated point is put in the right place */ - translate_m4(base_modelview, fpt[0], fpt[1], fpt[2]); - - /* copy the translation component to the billboard matrix we're going to use, - * then reset the base matrix to the original values so that we can do the same - * for the next point without accumulation/pollution effects - */ - copy_v3_v3(modelview[3], base_modelview[3]); /* copy offset value */ - copy_v3_v3(base_modelview[3], base_loc); /* restore */ - - /* apply our billboard matrix for drawing... */ - glLoadMatrixf((float *)modelview); - - /* draw the disk using the current state... */ - gluDisk(qobj, 0.0, pt->pressure * thickness, 32, 1); + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + unsigned int size = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); + unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + + immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR); + GPU_enable_program_point_size(); + immBegin(GWN_PRIM_POINTS, totpoints); + + const bGPDspoint *pt = points; + for (int i = 0; i < totpoints && pt; i++, pt++) { + gp_set_point_varying_color(pt, ink, color); + immAttrib1f(size, pt->pressure * thickness); /* TODO: scale based on view transform */ + immVertex3fv(pos, &pt->x); /* we can adjust size in vertex shader based on view/projection! */ } - glPopMatrix(); - gluDeleteQuadric(qobj); + immEnd(); + immUnbindProgram(); + GPU_disable_program_point_size(); } /* --------------- Stroke Fills ----------------- */ /* Get points of stroke always flat to view not affected by camera view or view position */ -static void gp_stroke_2d_flat(bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction) +static void gp_stroke_2d_flat(const bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction) { - bGPDspoint *pt0 = &points[0]; - bGPDspoint *pt1 = &points[1]; - bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)]; + const bGPDspoint *pt0 = &points[0]; + const bGPDspoint *pt1 = &points[1]; + const bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)]; float locx[3]; float locy[3]; @@ -397,7 +432,7 @@ static void gp_stroke_2d_flat(bGPDspoint *points, int totpoints, float(*points2d /* Get all points in local space */ for (int i = 0; i < totpoints; i++) { - bGPDspoint *pt = &points[i]; + const bGPDspoint *pt = &points[i]; float loc[3]; /* Get local space using first point as origin */ @@ -440,8 +475,7 @@ static void gp_triangulate_stroke_fill(bGPDstroke *gps) } for (int i = 0; i < gps->tot_triangles; i++) { - bGPDtriangle *stroke_triangle = &gps->triangles[i]; - memcpy(stroke_triangle->verts, tmp_triangles[i], sizeof(uint[3])); + memcpy(gps->triangles[i].verts, tmp_triangles[i], sizeof(uint[3])); } } else { @@ -466,78 +500,64 @@ static void gp_triangulate_stroke_fill(bGPDstroke *gps) /* draw fills for shapes */ static void gp_draw_stroke_fill( bGPdata *gpd, bGPDstroke *gps, - int offsx, int offsy, int winx, int winy, float diff_mat[4][4]) + int offsx, int offsy, int winx, int winy, const float diff_mat[4][4], const float color[4]) { - bGPDpalettecolor *palcolor; - int i; float fpt[3]; BLI_assert(gps->totpoints >= 3); - palcolor = ED_gpencil_stroke_getcolor(gpd, gps); + bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps); /* Triangulation fill if high quality flag is enabled */ if (palcolor->flag & PC_COLOR_HQ_FILL) { - bGPDtriangle *stroke_triangle; - bGPDspoint *pt; - /* Calculate triangles cache for filling area (must be done only after changes) */ if ((gps->flag & GP_STROKE_RECALC_CACHES) || (gps->tot_triangles == 0) || (gps->triangles == NULL)) { gp_triangulate_stroke_fill(gps); } - /* Draw all triangles for filling the polygon (cache must be calculated before) */ BLI_assert(gps->tot_triangles >= 1); - glBegin(GL_TRIANGLES); + + unsigned int pos; + if (gps->flag & GP_STROKE_3DSPACE) { + pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + } + else { + pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + } + + immUniformColor4fv(color); + + /* Draw all triangles for filling the polygon (cache must be calculated before) */ + immBegin(GWN_PRIM_TRIS, gps->tot_triangles * 3); + /* TODO: use batch instead of immediate mode, to share vertices */ + + bGPDtriangle *stroke_triangle = gps->triangles; + bGPDspoint *pt; + if (gps->flag & GP_STROKE_3DSPACE) { - for (i = 0, stroke_triangle = gps->triangles; i < gps->tot_triangles; i++, stroke_triangle++) { + for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) { for (int j = 0; j < 3; j++) { pt = &gps->points[stroke_triangle->verts[j]]; mul_v3_m4v3(fpt, diff_mat, &pt->x); - glVertex3fv(fpt); + immVertex3fv(pos, fpt); } } } else { - for (i = 0, stroke_triangle = gps->triangles; i < gps->tot_triangles; i++, stroke_triangle++) { + for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) { for (int j = 0; j < 3; j++) { float co[2]; pt = &gps->points[stroke_triangle->verts[j]]; mul_v3_m4v3(fpt, diff_mat, &pt->x); gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co); - glVertex2fv(co); + immVertex3fv(pos, fpt); } } } - glEnd(); - } - else { - /* As an initial implementation, we use the OpenGL filled polygon drawing - * here since it's the easiest option to implement for this case. It does - * come with limitations (notably for concave shapes), though it shouldn't - * be much of an issue in most cases. - * - * We keep this legacy implementation around despite now having the high quality - * fills, as this is necessary for keeping everything working nicely for files - * created using old versions of Blender which may have depended on the artifacts - * the old fills created. - */ - bGPDspoint *pt; - - glBegin(GL_POLYGON); - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if (gps->flag & GP_STROKE_3DSPACE) { - mul_v3_m4v3(fpt, diff_mat, &pt->x); - glVertex3fv(fpt); - } - else { - float co[2]; - mul_v3_m4v3(fpt, diff_mat, &pt->x); - gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co); - glVertex2fv(co); - } - } - glEnd(); + immEnd(); + immUnbindProgram(); } } @@ -545,131 +565,134 @@ static void gp_draw_stroke_fill( /* draw a given stroke - just a single dot (only one point) */ static void gp_draw_stroke_point( - bGPDspoint *points, short thickness, short dflag, short sflag, - int offsx, int offsy, int winx, int winy, float diff_mat[4][4], float ink[4]) + 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]) { - float fpt[3]; - bGPDspoint *pt = &points[0]; - - /* color of point */ - gp_set_point_color(pt, ink); - - /* set point thickness (since there's only one of these) */ - glPointSize((float)(thickness + 2) * points->pressure); + const bGPDspoint *pt = points; /* get final position using parent matrix */ + float fpt[3]; mul_v3_m4v3(fpt, diff_mat, &pt->x); - /* draw point */ + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + if (sflag & GP_STROKE_3DSPACE) { - glBegin(GL_POINTS); - glVertex3fv(fpt); - glEnd(); + immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); } else { - float co[2]; + immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); - /* get coordinates of point */ + /* 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); + } - /* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, simple dot looks ok - * - also mandatory in if Image Editor 'image-based' dot - */ - if ((thickness < GP_DRAWTHICKNESS_SPECIAL) || - ((dflag & GP_DRAWDATA_IEDITHACK) && (sflag & GP_STROKE_2DSPACE))) - { - glBegin(GL_POINTS); - glVertex2fv(co); - glEnd(); - } - else { - /* draw filled circle as is done in circf (but without the matrix push/pops which screwed things up) */ - GLUquadricObj *qobj = gluNewQuadric(); - - gluQuadricDrawStyle(qobj, GLU_FILL); + gp_set_point_uniform_color(pt, ink); + /* set point thickness (since there's only one of these) */ + immUniform1f("size", (float)(thickness + 2) * pt->pressure); - /* need to translate drawing position, but must reset after too! */ - glTranslate2fv(co); - gluDisk(qobj, 0.0, thickness, 32, 1); - glTranslatef(-co[0], -co[1], 0.0); + immBegin(GWN_PRIM_POINTS, 1); + immVertex3fv(pos, fpt); + immEnd(); - gluDeleteQuadric(qobj); - } - } + immUnbindProgram(); } /* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */ -static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness, bool debug, - short UNUSED(sflag), float diff_mat[4][4], float ink[4], bool cyclic) +static void gp_draw_stroke_3d(const bGPDspoint *points, int totpoints, short thickness, bool UNUSED(debug), + short UNUSED(sflag), const float diff_mat[4][4], const float ink[4], bool cyclic) { - bGPDspoint *pt, *pt2; float curpressure = points[0].pressure; - int i; float fpt[3]; float cyclic_fpt[3]; + int draw_points = 0; + + /* if cyclic needs one vertex more */ + int cyclic_add = 0; + if (cyclic) { + ++cyclic_add; + } + + + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + + immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR); + + /* TODO: implement this with a geometry shader to draw one continuous tapered stroke */ /* draw stroke curve */ glLineWidth(max_ff(curpressure * thickness, 1.0f)); - glBegin(GL_LINE_STRIP); - for (i = 0, pt = points; i < totpoints && pt; i++, pt++) { - gp_set_point_color(pt, ink); + immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints + cyclic_add); + const bGPDspoint *pt = points; + for (int i = 0; i < totpoints; i++, pt++) { + gp_set_point_varying_color(pt, ink, color); /* if there was a significant pressure change, stop the curve, change the thickness of the stroke, * and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP) * Note: we want more visible levels of pressures when thickness is bigger. */ if (fabsf(pt->pressure - curpressure) > 0.2f / (float)thickness) { - glEnd(); + /* if the pressure changes before get at least 2 vertices, need to repeat last point to avoid assert in immEnd() */ + if (draw_points < 2) { + const bGPDspoint *pt2 = pt - 1; + mul_v3_m4v3(fpt, diff_mat, &pt2->x); + immVertex3fv(pos, fpt); + } + immEnd(); + draw_points = 0; + curpressure = pt->pressure; glLineWidth(max_ff(curpressure * thickness, 1.0f)); - glBegin(GL_LINE_STRIP); + immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints - i + 1 + cyclic_add); /* need to roll-back one point to ensure that there are no gaps in the stroke */ if (i != 0) { - pt2 = pt - 1; + const bGPDspoint *pt2 = pt - 1; mul_v3_m4v3(fpt, diff_mat, &pt2->x); - glVertex3fv(fpt); + gp_set_point_varying_color(pt2, ink, color); + immVertex3fv(pos, fpt); + ++draw_points; } - - /* now the point we want... */ - mul_v3_m4v3(fpt, diff_mat, &pt->x); - glVertex3fv(fpt); - } - else { - mul_v3_m4v3(fpt, diff_mat, &pt->x); - glVertex3fv(fpt); } - /* saves first point to use in cyclic */ - if (i == 0) { + + /* now the point we want */ + mul_v3_m4v3(fpt, diff_mat, &pt->x); + immVertex3fv(pos, fpt); + ++draw_points; + + if (cyclic && i == 0) { + /* save first point to use in cyclic */ copy_v3_v3(cyclic_fpt, fpt); } } - /* if cyclic draw line to first point */ + if (cyclic) { - glVertex3fv(cyclic_fpt); + /* draw line to first point to complete the cycle */ + immVertex3fv(pos, cyclic_fpt); + ++draw_points; } - glEnd(); - - /* draw debug points of curve on top? */ - /* XXX: for now, we represent "selected" strokes in the same way as debug, which isn't used anymore */ - if (debug) { - glPointSize((float)(thickness + 2)); - - glBegin(GL_POINTS); - for (i = 0, pt = points; i < totpoints && pt; i++, pt++) { - mul_v3_m4v3(fpt, diff_mat, &pt->x); - glVertex3fv(fpt); - } - glEnd(); + /* if less of two points, need to repeat last point to avoid assert in immEnd() */ + if (draw_points < 2) { + const bGPDspoint *pt2 = pt - 1; + mul_v3_m4v3(fpt, diff_mat, &pt2->x); + gp_set_point_varying_color(pt2, ink, color); + immVertex3fv(pos, fpt); } + + immEnd(); + immUnbindProgram(); } /* ----- Fancy 2D-Stroke Drawing ------ */ /* draw a given stroke in 2d */ -static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag, - bool debug, int offsx, int offsy, int winx, int winy, float diff_mat[4][4], float ink[4]) +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; @@ -680,18 +703,24 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness scalefac = 0.001f; } - /* tessellation code - draw stroke as series of connected quads with connection + /* 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 */ { - bGPDspoint *pt1, *pt2; + const bGPDspoint *pt1, *pt2; float s0[2], s1[2]; /* segment 'center' points */ float pm[2]; /* normal from previous segment. */ int i; float fpt[3]; - glShadeModel(GL_FLAT); - glBegin(GL_QUADS); + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); + + immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); + immBegin(GWN_PRIM_TRI_STRIP, totpoints * 2 + 4); /* get x and y coordinates from first point */ mul_v3_m4v3(fpt, diff_mat, &points->x); @@ -718,7 +747,7 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness pthick = (pt1->pressure * thickness * scalefac); /* color of point */ - gp_set_point_color(pt1, ink); + gp_set_point_varying_color(pt1, ink, color); /* if the first segment, start of segment is segment's normal */ if (i == 0) { @@ -735,8 +764,9 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness t1[0] = sc[0] + mt[0]; t1[1] = sc[1] + mt[1]; - glVertex2fv(t0); - glVertex2fv(t1); + /* First two points of cap. */ + immVertex2fv(pos, t0); + immVertex2fv(pos, t1); /* calculate points for start of segment */ mt[0] = m2[0] * pthick; @@ -747,11 +777,9 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness t1[0] = s0[0] + mt[0]; t1[1] = s0[1] + mt[1]; - /* draw this line twice (first to finish off start cap, then for stroke) */ - glVertex2fv(t1); - glVertex2fv(t0); - glVertex2fv(t0); - glVertex2fv(t1); + /* Last two points of start cap (and first two points of first segment). */ + immVertex2fv(pos, t0); + immVertex2fv(pos, t1); } /* if not the first segment, use bisector of angle between segments */ else { @@ -783,11 +811,9 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness t1[0] = s0[0] + mt[0]; t1[1] = s0[1] + mt[1]; - /* draw this line twice (once for end of current segment, and once for start of next) */ - glVertex2fv(t1); - glVertex2fv(t0); - glVertex2fv(t0); - glVertex2fv(t1); + /* Last two points of previous segment, and first two points of current segment. */ + immVertex2fv(pos, t0); + immVertex2fv(pos, t1); } /* if last segment, also draw end of segment (defined as segment's normal) */ @@ -796,7 +822,7 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness pthick = (pt2->pressure * thickness * scalefac); /* color of point */ - gp_set_point_color(pt2, ink); + gp_set_point_varying_color(pt2, ink, color); /* calculate points for end of segment */ mt[0] = m2[0] * pthick; @@ -807,12 +833,9 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness t1[0] = s1[0] + mt[0]; t1[1] = s1[1] + mt[1]; - /* draw this line twice (once for end of stroke, and once for endcap)*/ - glVertex2fv(t1); - glVertex2fv(t0); - glVertex2fv(t0); - glVertex2fv(t1); - + /* Last two points of last segment (and first two points of end cap). */ + immVertex2fv(pos, t0); + immVertex2fv(pos, t1); /* draw end cap as last step * - make points slightly closer to center (about halfway across) @@ -827,8 +850,9 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness t1[0] = sc[0] + mt[0]; t1[1] = sc[1] + mt[1]; - glVertex2fv(t1); - glVertex2fv(t0); + /* Last two points of end cap. */ + immVertex2fv(pos, t0); + immVertex2fv(pos, t1); } /* store computed point2 coordinates as point1 ones of next segment. */ @@ -837,26 +861,8 @@ static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness copy_v2_v2(pm, m2); } - glEnd(); - glShadeModel(GL_SMOOTH); - } - - /* draw debug points of curve on top? (original stroke points) */ - if (debug) { - bGPDspoint *pt; - int i; - float fpt[3]; - - glPointSize((float)(thickness_s + 2)); - - glBegin(GL_POINTS); - for (i = 0, pt = points; i < totpoints && pt; i++, pt++) { - float co[2]; - mul_v3_m4v3(fpt, diff_mat, &pt->x); - gp_calc_2d_stroke_fxy(fpt, sflag, offsx, offsy, winx, winy, co); - glVertex2fv(co); - } - glEnd(); + immEnd(); + immUnbindProgram(); } } @@ -884,7 +890,6 @@ static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag) if (!(dflag & GP_DRAWDATA_ONLYI2D) && (gps->flag & GP_STROKE_2DIMAGE)) return false; - /* skip stroke if it doesn't have any valid data */ if ((gps->points == NULL) || (gps->totpoints < 1)) return false; @@ -895,17 +900,18 @@ static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag) /* draw a set of strokes */ static void gp_draw_strokes( - bGPdata *gpd, bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag, + bGPdata *gpd, const bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag, bool debug, short lthick, const float opacity, const float tintcolor[4], - const bool onion, const bool custonion, float diff_mat[4][4]) + const bool onion, const bool custonion, const float diff_mat[4][4]) { - bGPDstroke *gps; float tcolor[4]; float tfill[4]; short sthickness; float ink[4]; - for (gps = gpf->strokes.first; gps; gps = gps->next) { + GPU_enable_program_point_size(); + + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { /* check if stroke can be drawn */ if (gp_can_draw_stroke(gps, dflag) == false) { continue; @@ -923,6 +929,10 @@ static void gp_draw_strokes( /* calculate thickness */ sthickness = gps->thickness + lthick; + if (sthickness <= 0) { + continue; + } + /* check which stroke-drawer to use */ if (dflag & GP_DRAWDATA_ONLY3D) { const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY); @@ -936,10 +946,6 @@ static void gp_draw_strokes( /* first arg is normally rv3d->dist, but this isn't * available here and seems to work quite well without */ bglPolygonOffset(1.0f, 1.0f); -#if 0 - glEnable(GL_POLYGON_OFFSET_LINE); - glPolygonOffset(-1.0f, -1.0f); -#endif } /* 3D Fill */ @@ -949,19 +955,20 @@ static void gp_draw_strokes( interp_v3_v3v3(tfill, palcolor->fill, tintcolor, tintcolor[3]); tfill[3] = palcolor->fill[3] * opacity; if (tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) { + const float *color; if (!onion) { - glColor4fv(tfill); + color = tfill; } else { if (custonion) { - glColor4fv(tintcolor); + color = tintcolor; } else { ARRAY_SET_ITEMS(tfill, UNPACK3(palcolor->fill), tintcolor[3]); - glColor4fv(tfill); + color = tfill; } } - gp_draw_stroke_fill(gpd, gps, offsx, offsy, winx, winy, diff_mat); + gp_draw_stroke_fill(gpd, gps, offsx, offsy, winx, winy, diff_mat, color); } } @@ -983,7 +990,7 @@ static void gp_draw_strokes( } if (palcolor->flag & PC_COLOR_VOLUMETRIC) { /* volumetric stroke drawing */ - gp_draw_stroke_volumetric_3d(gps->points, gps->totpoints, sthickness, dflag, gps->flag, diff_mat, ink); + gp_draw_stroke_volumetric_3d(gps->points, gps->totpoints, sthickness, ink); } else { /* 3D Lines - OpenGL primitives-based */ @@ -1001,10 +1008,6 @@ static void gp_draw_strokes( glDisable(GL_DEPTH_TEST); bglPolygonOffset(0.0, 0.0); -#if 0 - glDisable(GL_POLYGON_OFFSET_LINE); - glPolygonOffset(0, 0); -#endif } } else { @@ -1014,20 +1017,21 @@ static void gp_draw_strokes( interp_v3_v3v3(tfill, palcolor->fill, tintcolor, tintcolor[3]); tfill[3] = palcolor->fill[3] * opacity; if (tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) { + const float *color; if (!onion) { - glColor4fv(tfill); + color = tfill; } else { if (custonion) { - glColor4fv(tintcolor); + color = tintcolor; } else { ARRAY_SET_ITEMS(tfill, palcolor->fill[0], palcolor->fill[1], palcolor->fill[2], tintcolor[3]); - glColor4fv(tfill); + color = tfill; } } - gp_draw_stroke_fill(gpd, gps, offsx, offsy, winx, winy, diff_mat); + gp_draw_stroke_fill(gpd, gps, offsx, offsy, winx, winy, diff_mat, color); } } @@ -1065,15 +1069,15 @@ static void gp_draw_strokes( } } } + + GPU_disable_program_point_size(); } /* Draw selected verts for strokes being edited */ static void gp_draw_strokes_edit( - bGPdata *gpd, bGPDframe *gpf, int offsx, int offsy, int winx, int winy, short dflag, - short lflag, float diff_mat[4][4], float alpha) + bGPdata *gpd, const bGPDframe *gpf, int offsx, int offsy, int winx, int winy, short dflag, + short lflag, const float diff_mat[4][4], float alpha) { - bGPDstroke *gps; - /* if alpha 0 do not draw */ if (alpha == 0.0f) return; @@ -1091,21 +1095,13 @@ static void gp_draw_strokes_edit( /* first arg is normally rv3d->dist, but this isn't * available here and seems to work quite well without */ bglPolygonOffset(1.0f, 1.0f); -#if 0 - glEnable(GL_POLYGON_OFFSET_LINE); - glPolygonOffset(-1.0f, -1.0f); -#endif } } + GPU_enable_program_point_size(); /* draw stroke verts */ - for (gps = gpf->strokes.first; gps; gps = gps->next) { - bGPDspoint *pt; - float vsize, bsize; - int i; - float fpt[3]; - + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { /* check if stroke can be drawn */ if (gp_can_draw_stroke(gps, dflag) == false) continue; @@ -1135,7 +1131,8 @@ static void gp_draw_strokes_edit( * they stand out more. * - We use the theme setting for size of the unselected verts */ - bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE); + float bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE); + float vsize; if ((int)bsize > 8) { vsize = 10.0f; bsize = 8.0f; @@ -1144,81 +1141,75 @@ static void gp_draw_strokes_edit( vsize = bsize + 2; } - /* First Pass: Draw all the verts (i.e. these become the unselected state) */ /* for now, we assume that the base color of the points is not too close to the real color */ /* set color using palette */ bGPDpalettecolor *palcolor = ED_gpencil_stroke_getcolor(gpd, gps); - glColor3fv(palcolor->color); - glPointSize(bsize); + float selectColor[4]; + UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor); + selectColor[3] = alpha; + + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos; /* specified later */ + unsigned int size = GWN_vertformat_attr_add(format, "size", GWN_COMP_F32, 1, GWN_FETCH_FLOAT); + unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + + if (gps->flag & GP_STROKE_3DSPACE) { + pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR); + } + else { + pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR); + } + + immBegin(GWN_PRIM_POINTS, gps->totpoints); + + /* Draw start and end point differently if enabled stroke direction hint */ + bool show_direction_hint = (gpd->flag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1); + + /* Draw all the stroke points (selected or not) */ + bGPDspoint *pt = gps->points; + float fpt[3]; + for (int i = 0; i < gps->totpoints; i++, pt++) { + /* size and color first */ + if (show_direction_hint && i == 0) { + /* start point in green bigger */ + immAttrib3f(color, 0.0f, 1.0f, 0.0f); + immAttrib1f(size, vsize + 4); + } + else if (show_direction_hint && (i == gps->totpoints - 1)) { + /* end point in red smaller */ + immAttrib3f(color, 1.0f, 0.0f, 0.0f); + immAttrib1f(size, vsize + 1); + } + else if (pt->flag & GP_SPOINT_SELECT) { + immAttrib3fv(color, selectColor); + immAttrib1f(size, vsize); + } + else { + immAttrib3fv(color, palcolor->color); + immAttrib1f(size, bsize); + } - glBegin(GL_POINTS); - for (i = 0, pt = gps->points; i < gps->totpoints && pt; i++, pt++) { + /* then position */ if (gps->flag & GP_STROKE_3DSPACE) { mul_v3_m4v3(fpt, diff_mat, &pt->x); - glVertex3fv(fpt); + immVertex3fv(pos, fpt); } else { float co[2]; mul_v3_m4v3(fpt, diff_mat, &pt->x); gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co); - glVertex2fv(co); + immVertex2fv(pos, co); } } - glEnd(); - - /* Second Pass: Draw only verts which are selected */ - float curColor[4]; - UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, curColor); - glColor4f(curColor[0], curColor[1], curColor[2], alpha); - - glPointSize(vsize); - - glBegin(GL_POINTS); - for (i = 0, pt = gps->points; i < gps->totpoints && pt; i++, pt++) { - if (pt->flag & GP_SPOINT_SELECT) { - if (gps->flag & GP_STROKE_3DSPACE) { - mul_v3_m4v3(fpt, diff_mat, &pt->x); - glVertex3fv(fpt); - } - else { - float co[2]; - - mul_v3_m4v3(fpt, diff_mat, &pt->x); - gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co); - glVertex2fv(co); - } - } - } - glEnd(); - - /* Draw start and end point if enabled stroke direction hint */ - if ((gpd->flag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1)) { - bGPDspoint *p; - - glPointSize(vsize + 4); - glBegin(GL_POINTS); - - /* start point in green bigger */ - glColor3f(0.0f, 1.0f, 0.0f); - p = &gps->points[0]; - mul_v3_m4v3(fpt, diff_mat, &p->x); - glVertex3fv(fpt); - glEnd(); - - /* end point in red smaller */ - glPointSize(vsize + 1); - glBegin(GL_POINTS); - - glColor3f(1.0f, 0.0f, 0.0f); - p = &gps->points[gps->totpoints - 1]; - mul_v3_m4v3(fpt, diff_mat, &p->x); - glVertex3fv(fpt); - glEnd(); - } + immEnd(); + immUnbindProgram(); } + GPU_disable_program_point_size(); /* clear depth mask */ if (dflag & GP_DRAWDATA_ONLY3D) { @@ -1239,8 +1230,8 @@ static void gp_draw_strokes_edit( /* draw onion-skinning for a layer */ static void gp_draw_onionskins( - bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf, int offsx, int offsy, int winx, int winy, - int UNUSED(cfra), int dflag, bool debug, float diff_mat[4][4]) + bGPdata *gpd, const bGPDlayer *gpl, const bGPDframe *gpf, int offsx, int offsy, int winx, int winy, + int UNUSED(cfra), int dflag, bool debug, const float diff_mat[4][4]) { const float default_color[3] = {UNPACK3(U.gpencil_new_layer_col)}; const float alpha = 1.0f; @@ -1255,15 +1246,12 @@ static void gp_draw_onionskins( } if (gpl->gstep > 0) { - bGPDframe *gf; - float fac; - /* draw previous frames first */ - for (gf = gpf->prev; gf; gf = gf->prev) { + for (bGPDframe *gf = gpf->prev; gf; gf = gf->prev) { /* check if frame is drawable */ if ((gpf->framenum - gf->framenum) <= gpl->gstep) { /* alpha decreases with distance from curframe index */ - fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1)); + float fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1)); color[3] = alpha * fac * 0.66f; gp_draw_strokes(gpd, gf, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, 1.0f, color, true, gpl->flag & GP_LAYER_GHOST_PREVCOL, diff_mat); @@ -1284,7 +1272,6 @@ static void gp_draw_onionskins( /* don't draw - disabled */ } - /* 2) Now draw next frames */ if (gpl->flag & GP_LAYER_GHOST_NEXTCOL) { copy_v3_v3(color, gpl->gcolor_next); @@ -1294,15 +1281,12 @@ static void gp_draw_onionskins( } if (gpl->gstep_next > 0) { - bGPDframe *gf; - float fac; - /* now draw next frames */ - for (gf = gpf->next; gf; gf = gf->next) { + for (bGPDframe *gf = gpf->next; gf; gf = gf->next) { /* check if frame is drawable */ if ((gf->framenum - gpf->framenum) <= gpl->gstep_next) { /* alpha decreases with distance from curframe index */ - fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep_next + 1)); + float fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep_next + 1)); color[3] = alpha * fac * 0.66f; gp_draw_strokes(gpd, gf, offsx, offsy, winx, winy, dflag, debug, gpl->thickness, 1.0f, color, true, gpl->flag & GP_LAYER_GHOST_NEXTCOL, diff_mat); @@ -1322,7 +1306,6 @@ static void gp_draw_onionskins( else { /* don't draw - disabled */ } - } /* draw interpolate strokes (used only while operator is running) */ @@ -1360,18 +1343,16 @@ void ED_gp_draw_interpolation(tGPDinterpolate *tgpi, const int type) /* loop over gpencil data layers, drawing them */ static void gp_draw_data_layers( - bGPDbrush *brush, float alpha, bGPdata *gpd, + const bGPDbrush *brush, float alpha, bGPdata *gpd, int offsx, int offsy, int winx, int winy, int cfra, int dflag) { - bGPDlayer *gpl; float diff_mat[4][4]; - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - bGPDframe *gpf; + for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { /* calculate parent position */ ED_gpencil_parent_location(gpl, diff_mat); - bool debug = (gpl->flag & GP_LAYER_DRAWDEBUG) ? true : false; + bool debug = (gpl->flag & GP_LAYER_DRAWDEBUG); short lthick = brush->thickness + gpl->thickness; /* don't draw layer if hidden */ @@ -1379,7 +1360,7 @@ static void gp_draw_data_layers( continue; /* get frame to draw */ - gpf = BKE_gpencil_layer_getframe(gpl, cfra, 0); + bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra, 0); if (gpf == NULL) continue; @@ -1447,9 +1428,6 @@ static void gp_draw_data_layers( if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) && (gpf->flag & GP_FRAME_PAINT)) { - /* Set color for drawing buffer stroke - since this may not be set yet */ - // glColor4fv(gpl->color); - /* Buffer stroke needs to be drawn with a different linestyle * to help differentiate them from normal strokes. * @@ -1458,17 +1436,17 @@ static void gp_draw_data_layers( */ if (gpd->sflag & PC_COLOR_VOLUMETRIC) { gp_draw_stroke_volumetric_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, - dflag, gpd->sbuffer_sflag, gpd->scolor); + dflag, gpd->scolor); } else { - gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, gpd->scolor); + gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, gpd->scolor, gpd->sfill); } } } } /* draw a short status message in the top-right corner */ -static void gp_draw_status_text(bGPdata *gpd, ARegion *ar) +static void gp_draw_status_text(const bGPdata *gpd, ARegion *ar) { rcti rect; @@ -1483,15 +1461,16 @@ static void gp_draw_status_text(bGPdata *gpd, ARegion *ar) if (gpd->flag & GP_DATA_STROKE_EDITMODE) { const char *printable = IFACE_("GPencil Stroke Editing"); float printable_size[2]; - int xco, yco; - BLF_width_and_height_default(printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]); + int font_id = BLF_default(); + + BLF_width_and_height(font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]); - xco = (rect.xmax - U.widget_unit) - (int)printable_size[0]; - yco = (rect.ymax - U.widget_unit); + int xco = (rect.xmax - U.widget_unit) - (int)printable_size[0]; + int yco = (rect.ymax - U.widget_unit); /* text label */ - UI_ThemeColor(TH_TEXT_HI); + UI_FontThemeColor(font_id, TH_TEXT_HI); #ifdef WITH_INTERNATIONAL BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX); #else @@ -1500,7 +1479,7 @@ static void gp_draw_status_text(bGPdata *gpd, ARegion *ar) /* grease pencil icon... */ // XXX: is this too intrusive? - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); xco -= U.widget_unit; @@ -1514,12 +1493,9 @@ static void gp_draw_status_text(bGPdata *gpd, ARegion *ar) /* draw grease-pencil datablock */ static void gp_draw_data( - bGPDbrush *brush, float alpha, bGPdata *gpd, + const bGPDbrush *brush, float alpha, bGPdata *gpd, int offsx, int offsy, int winx, int winy, int cfra, int dflag) { - /* reset line drawing style (in case previous user didn't reset) */ - setlinestyle(0); - /* turn on smooth lines (i.e. anti-aliasing) */ glEnable(GL_LINE_SMOOTH); @@ -1538,9 +1514,6 @@ static void gp_draw_data( /* turn off alpha blending, then smooth lines */ glDisable(GL_BLEND); // alpha blending glDisable(GL_LINE_SMOOTH); // smooth lines - - /* restore initial gl conditions */ - glColor4f(0, 0, 0, 1); } /* if we have strokes for scenes (3d view)/clips (movie clip editor) @@ -1601,11 +1574,11 @@ void ED_gpencil_draw_2dimage(const bContext *C) ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); - bGPdata *gpd; + int offsx, offsy, sizex, sizey; int dflag = GP_DRAWDATA_NOSTATUS; - gpd = ED_gpencil_data_get_active(C); // XXX + bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX if (gpd == NULL) return; /* calculate rect */ @@ -1613,7 +1586,6 @@ void ED_gpencil_draw_2dimage(const bContext *C) case SPACE_IMAGE: /* image */ case SPACE_CLIP: /* clip */ { - /* just draw using standard scaling (settings here are currently ignored anyways) */ /* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */ offsx = 0; @@ -1657,26 +1629,24 @@ void ED_gpencil_draw_2dimage(const bContext *C) dflag |= GP_DRAWDATA_NO_ONIONS; } - /* draw it! */ gp_draw_data_all(scene, gpd, offsx, offsy, sizex, sizey, CFRA, dflag, sa->spacetype); } /* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly - * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, - * second time with onlyv2d=0 for screen-aligned strokes */ + * Note: this gets called twice - first time with onlyv2d=true to draw 'canvas' strokes, + * second time with onlyv2d=false for screen-aligned strokes */ void ED_gpencil_draw_view2d(const bContext *C, bool onlyv2d) { wmWindowManager *wm = CTX_wm_manager(C); ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); - bGPdata *gpd; int dflag = 0; /* check that we have grease-pencil stuff to draw */ if (sa == NULL) return; - gpd = ED_gpencil_data_get_active(C); // XXX + bGPdata *gpd = ED_gpencil_data_get_active(C); // XXX if (gpd == NULL) return; /* special hack for Image Editor */ @@ -1691,30 +1661,35 @@ void ED_gpencil_draw_view2d(const bContext *C, bool onlyv2d) gp_draw_data_all(scene, gpd, 0, 0, ar->winx, ar->winy, CFRA, dflag, sa->spacetype); /* draw status text (if in screen/pixel-space) */ - if (onlyv2d == false) { + if (!onlyv2d) { gp_draw_status_text(gpd, ar); } } /* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly - * Note: this gets called twice - first time with only3d=1 to draw 3d-strokes, - * second time with only3d=0 for screen-aligned strokes */ -void ED_gpencil_draw_view3d(wmWindowManager *wm, Scene *scene, View3D *v3d, ARegion *ar, bool only3d) + * Note: this gets called twice - first time with only3d=true to draw 3d-strokes, + * second time with only3d=false for screen-aligned strokes */ +void ED_gpencil_draw_view3d(wmWindowManager *wm, + Scene *scene, + ViewLayer *view_layer, + struct Depsgraph *depsgraph, + View3D *v3d, + ARegion *ar, + bool only3d) { - bGPdata *gpd; int dflag = 0; RegionView3D *rv3d = ar->regiondata; int offsx, offsy, winx, winy; /* check that we have grease-pencil stuff to draw */ - gpd = ED_gpencil_data_get_active_v3d(scene, v3d); + bGPdata *gpd = ED_gpencil_data_get_active_v3d(scene, view_layer); if (gpd == NULL) return; /* when rendering to the offscreen buffer we don't want to * deal with the camera border, otherwise map the coords to the camera border. */ if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) { rctf rectf; - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &rectf, true); /* no shift */ + ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &rectf, true); /* no shift */ offsx = round_fl_to_int(rectf.xmin); offsy = round_fl_to_int(rectf.ymin); @@ -1751,7 +1726,6 @@ void ED_gpencil_draw_view3d(wmWindowManager *wm, Scene *scene, View3D *v3d, AReg /* draw it! */ gp_draw_data_all(scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype); - } void ED_gpencil_draw_ex(Scene *scene, bGPdata *gpd, int winx, int winy, const int cfra, const char spacetype) diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c index c35b64de991..c2e532be0b3 100644 --- a/source/blender/editors/gpencil/gpencil_brush.c +++ b/source/blender/editors/gpencil/gpencil_brush.c @@ -74,8 +74,8 @@ #include "ED_screen.h" #include "ED_view3d.h" -#include "BIF_gl.h" -#include "BIF_glutil.h" +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" #include "gpencil_intern.h" @@ -404,7 +404,7 @@ static void gp_brush_grab_calc_dvec(tGP_BrushEditData *gso) if (gso->sa->spacetype == SPACE_VIEW3D) { View3D *v3d = gso->sa->spacedata.first; RegionView3D *rv3d = gso->ar->regiondata; - float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d); + float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d)->location; float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL); float mval_f[2]; @@ -504,7 +504,7 @@ static void gp_brush_calc_midpoint(tGP_BrushEditData *gso) */ View3D *v3d = gso->sa->spacedata.first; RegionView3D *rv3d = gso->ar->regiondata; - float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d); + float *rvec = ED_view3d_cursor3d_get(gso->scene, v3d)->location; float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL); float mval_f[2] = {UNPACK2(gso->mval)}; @@ -980,26 +980,26 @@ static void gp_brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customda GP_EditBrush_Data *brush = gpsculpt_get_brush(CTX_data_scene(C)); if (brush) { - glPushMatrix(); - - glTranslatef((float)x, (float)y, 0.0f); + Gwn_VertFormat *format = immVertexFormat(); + unsigned int 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); /* Inner Ring: Light color for action of the brush */ /* TODO: toggle between add and remove? */ - glColor4ub(255, 255, 255, 200); - glutil_draw_lined_arc(0.0, M_PI * 2.0, brush->size, 40); + immUniformColor4ub(255, 255, 255, 200); + imm_draw_circle_wire_2d(pos, x, y, brush->size, 40); /* Outer Ring: Dark color for contrast on light backgrounds (e.g. gray on white) */ - glColor3ub(30, 30, 30); - glutil_draw_lined_arc(0.0, M_PI * 2.0, brush->size + 1, 40); + immUniformColor3ub(30, 30, 30); + imm_draw_circle_wire_2d(pos, x, y, brush->size + 1, 40); + + immUnbindProgram(); glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); - - glPopMatrix(); } } diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index 67d3272a90d..dfaa1420d68 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -48,6 +48,7 @@ #include "DNA_anim_types.h" #include "DNA_curve_types.h" +#include "DNA_group_types.h" #include "DNA_object_types.h" #include "DNA_node_types.h" #include "DNA_scene_types.h" @@ -55,13 +56,15 @@ #include "DNA_space_types.h" #include "DNA_view3d_types.h" #include "DNA_gpencil_types.h" +#include "DNA_workspace_types.h" +#include "BKE_collection.h" #include "BKE_context.h" #include "BKE_curve.h" -#include "BKE_depsgraph.h" #include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_gpencil.h" +#include "BKE_layer.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_object.h" @@ -70,6 +73,8 @@ #include "BKE_screen.h" #include "BKE_tracking.h" +#include "DEG_depsgraph.h" + #include "UI_interface.h" #include "WM_api.h" @@ -173,7 +178,7 @@ static void gp_strokepoint_convertcoords( copy_v3_v3(p3d, &pt->x); } else { - const float *fp = ED_view3d_cursor3d_get(scene, v3d); + const float *fp = ED_view3d_cursor3d_get(scene, v3d)->location; float mvalf[2]; /* get screen coordinate */ @@ -369,7 +374,7 @@ static void gp_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd, RNG *rn } } -static void gp_stroke_path_animation_add_keyframes(ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, +static void gp_stroke_path_animation_add_keyframes(Depsgraph *depsgraph, ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, Curve *cu, tGpTimingData *gtd, RNG *rng, const float time_range, const int nbr_gaps, const float tot_gaps_time) { @@ -418,7 +423,7 @@ static void gp_stroke_path_animation_add_keyframes(ReportList *reports, PointerR if ((cfra - last_valid_time) < MIN_TIME_DELTA) { cfra = last_valid_time + MIN_TIME_DELTA; } - insert_keyframe_direct(reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST); + insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST); last_valid_time = cfra; } else if (G.debug & G_DEBUG) { @@ -430,7 +435,7 @@ static void gp_stroke_path_animation_add_keyframes(ReportList *reports, PointerR if ((cfra - last_valid_time) < MIN_TIME_DELTA) { cfra = last_valid_time + MIN_TIME_DELTA; } - insert_keyframe_direct(reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST); + insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST); last_valid_time = cfra; } else { @@ -438,7 +443,7 @@ static void gp_stroke_path_animation_add_keyframes(ReportList *reports, PointerR * and also far enough from (not yet added!) end_stroke keyframe! */ if ((cfra - last_valid_time) > MIN_TIME_DELTA && (end_stroke_time - cfra) > MIN_TIME_DELTA) { - insert_keyframe_direct(reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_BREAKDOWN, INSERTKEY_FAST); + insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_BREAKDOWN, INSERTKEY_FAST); last_valid_time = cfra; } else if (G.debug & G_DEBUG) { @@ -451,6 +456,7 @@ static void gp_stroke_path_animation_add_keyframes(ReportList *reports, PointerR static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu, tGpTimingData *gtd) { + Depsgraph *depsgraph = CTX_data_depsgraph(C); Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); bAction *act; @@ -493,7 +499,7 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu cu->ctime = 0.0f; cfra = (float)gtd->start_frame; - insert_keyframe_direct(reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST); + insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST); cu->ctime = cu->pathlen; if (gtd->realtime) { @@ -502,7 +508,7 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu else { cfra = (float)gtd->end_frame; } - insert_keyframe_direct(reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST); + insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST); } else { /* Use actual recorded timing! */ @@ -528,7 +534,7 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu printf("GP Stroke Path Conversion: Starting keying!\n"); } - gp_stroke_path_animation_add_keyframes(reports, ptr, prop, fcu, cu, gtd, rng, time_range, + gp_stroke_path_animation_add_keyframes(depsgraph, reports, ptr, prop, fcu, cu, gtd, rng, time_range, nbr_gaps, tot_gaps_time); BLI_rng_free(rng); @@ -548,7 +554,7 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); /* send updates */ - DAG_id_tag_update(&cu->id, 0); + DEG_id_tag_update(&cu->id, 0); } #undef MIN_TIME_DELTA @@ -1110,7 +1116,8 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect) /* for camera view set the subrect */ if (rv3d->persp == RV3D_CAMOB) { Scene *scene = CTX_data_scene(C); - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, subrect, true); /* no shift */ + Depsgraph *depsgraph = CTX_data_depsgraph(C); + ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, subrect, true); /* no shift */ return 1; } } @@ -1123,14 +1130,15 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG const bool norm_weights, const float rad_fac, const bool link_strokes, tGpTimingData *gtd) { struct Main *bmain = CTX_data_main(C); - View3D *v3d = CTX_wm_view3d(C); /* may be NULL */ Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + Collection *collection = CTX_data_collection(C); bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0); bGPDstroke *gps, *prev_gps = NULL; Object *ob; Curve *cu; Nurb *nu = NULL; - Base *base_orig = BASACT, *base_new = NULL; + Base *base_new = NULL; float minmax_weights[2] = {1.0f, 0.0f}; /* camera framing */ @@ -1154,7 +1162,8 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG */ ob = BKE_object_add_only_object(bmain, OB_CURVE, gpl->info); cu = ob->data = BKE_curve_add(bmain, gpl->info, OB_CURVE); - base_new = BKE_scene_base_add(scene, ob); + BKE_collection_object_add(bmain, collection, ob); + base_new = BKE_view_layer_base_find(view_layer, ob); cu->flag |= CU_3D; @@ -1218,8 +1227,8 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG } /* set the layer and select */ - base_new->lay = ob->lay = base_orig ? base_orig->lay : BKE_screen_view3d_layer_active(v3d, scene); - base_new->flag = ob->flag = base_new->flag | SELECT; + base_new->flag |= SELECT; + BKE_scene_object_base_flag_sync_from_base(base_new); } /* --- */ @@ -1289,6 +1298,7 @@ static int gp_convert_poll(bContext *C) bGPDframe *gpf = NULL; ScrArea *sa = CTX_wm_area(C); Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); /* only if the current view is 3D View, if there's valid data (i.e. at least one stroke!), * and if we are not in edit mode! @@ -1297,7 +1307,7 @@ static int gp_convert_poll(bContext *C) (gpl = BKE_gpencil_layer_getactive(gpd)) && (gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0)) && (gpf->strokes.first) && - (scene->obedit == NULL)); + (OBEDIT_FROM_VIEW_LAYER(view_layer) == NULL)); } static int gp_convert_layer_exec(bContext *C, wmOperator *op) @@ -1444,7 +1454,7 @@ static void gp_convert_ui(bContext *C, wmOperator *op) RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); /* Main auto-draw call */ - uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, '\0'); + uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false); } void GPENCIL_OT_convert(wmOperatorType *ot) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index cdd8d571400..45caadf3742 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -79,6 +79,8 @@ #include "ED_view3d.h" #include "ED_space_api.h" +#include "DEG_depsgraph.h" + #include "gpencil_intern.h" /* ************************************************ */ @@ -1463,7 +1465,7 @@ static int gp_snap_to_cursor(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); const bool use_offset = RNA_boolean_get(op->ptr, "use_offset"); - const float *cursor_global = ED_view3d_cursor3d_get(scene, v3d); + const float *cursor_global = ED_view3d_cursor3d_get(scene, v3d)->location; for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { /* only editable and visible layers are considered */ @@ -1550,7 +1552,7 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); - float *cursor = ED_view3d_cursor3d_get(scene, v3d); + float *cursor = ED_view3d_cursor3d_get(scene, v3d)->location; float centroid[3] = {0.0f}; float min[3], max[3]; size_t count = 0; @@ -1605,7 +1607,7 @@ static int gp_snap_cursor_to_sel(bContext *C, wmOperator *UNUSED(op)) } } - if (v3d->around == V3D_AROUND_CENTER_MEAN && count) { + if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_MEAN && count) { mul_v3_fl(centroid, 1.0f / (float)count); copy_v3_v3(cursor, centroid); } @@ -2099,7 +2101,6 @@ static int gp_strokes_reproject_poll(bContext *C) static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); GP_SpaceConversion gsc = {NULL}; eGP_ReprojectModes mode = RNA_boolean_get(op->ptr, "type"); @@ -2109,8 +2110,9 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op) /* init autodist for geometry projection */ if (mode == GP_REPROJECT_SURFACE) { + struct Depsgraph *depsgraph = CTX_data_depsgraph(C); view3d_region_operator_needs_opengl(CTX_wm_window(C), gsc.ar); - ED_view3d_autodist_init(bmain, scene, gsc.ar, CTX_wm_view3d(C), 0); + ED_view3d_autodist_init(depsgraph, gsc.ar, CTX_wm_view3d(C), 0); } // TODO: For deforming geometry workflow, create new frames? diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c index 84a106856b3..cb6ccc8d8ef 100644 --- a/source/blender/editors/gpencil/gpencil_ops.c +++ b/source/blender/editors/gpencil/gpencil_ops.c @@ -290,28 +290,6 @@ static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf) /* Move to Layer */ WM_keymap_add_item(keymap, "GPENCIL_OT_move_to_layer", MKEY, KM_PRESS, 0, 0); - /* Select drawing brush using index */ - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", ONEKEY, KM_PRESS, 0, 0); - RNA_int_set(kmi->ptr, "index", 0); - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", TWOKEY, KM_PRESS, 0, 0); - RNA_int_set(kmi->ptr, "index", 1); - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", THREEKEY, KM_PRESS, 0, 0); - RNA_int_set(kmi->ptr, "index", 2); - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", FOURKEY, KM_PRESS, 0, 0); - RNA_int_set(kmi->ptr, "index", 3); - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", FIVEKEY, KM_PRESS, 0, 0); - RNA_int_set(kmi->ptr, "index", 4); - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", SIXKEY, KM_PRESS, 0, 0); - RNA_int_set(kmi->ptr, "index", 5); - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", SEVENKEY, KM_PRESS, 0, 0); - RNA_int_set(kmi->ptr, "index", 6); - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", EIGHTKEY, KM_PRESS, 0, 0); - RNA_int_set(kmi->ptr, "index", 7); - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", NINEKEY, KM_PRESS, 0, 0); - RNA_int_set(kmi->ptr, "index", 8); - kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_brush_select", ZEROKEY, KM_PRESS, 0, 0); - RNA_int_set(kmi->ptr, "index", 9); - /* Transform Tools */ kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", GKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 0d4c8e383de..437d5cef6f8 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 */ @@ -233,7 +238,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 */ @@ -482,7 +487,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; @@ -640,7 +646,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 +681,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) { @@ -1240,9 +1247,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); } } @@ -1397,6 +1403,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); @@ -1551,6 +1558,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; @@ -1601,7 +1609,7 @@ static void gp_session_cleanup(tGPsdata *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; @@ -1730,7 +1738,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; } } @@ -1808,7 +1816,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 */ @@ -1848,26 +1856,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); - glColor4ub(255, 100, 100, 20); - glutil_draw_filled_arc(0.0, M_PI * 2.0, p->radius, 40); + immUnbindProgram(); - setlinestyle(6); + immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); - glColor4ub(255, 100, 100, 200); - glutil_draw_lined_arc(0.0, M_PI * 2.0, p->radius, 40); + float viewport_size[4]; + glGetFloatv(GL_VIEWPORT, viewport_size); + immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); + + 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(); } } @@ -1958,7 +1979,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; @@ -2035,7 +2056,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) { @@ -2057,7 +2078,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... */ @@ -2090,7 +2111,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; @@ -2195,7 +2216,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 */ @@ -2207,6 +2228,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"); */ @@ -2244,7 +2266,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); } } @@ -2259,7 +2281,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; @@ -2318,7 +2340,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 { @@ -2359,7 +2381,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; @@ -2650,7 +2672,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) { diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 0a35dd90f02..f6d72d9e575 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -66,6 +66,8 @@ #include "ED_clip.h" #include "ED_view3d.h" +#include "DEG_depsgraph.h" + #include "gpencil_intern.h" /* ******************************************************** */ @@ -203,15 +205,15 @@ bGPdata *ED_gpencil_data_get_active(const bContext *C) /* -------------------------------------------------------- */ // XXX: this should be removed... We really shouldn't duplicate logic like this! -bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, View3D *v3d) +bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, ViewLayer *view_layer) { - Base *base = scene->basact; + Base *base = view_layer->basact; bGPdata *gpd = NULL; /* We have to make sure active object is actually visible and selected, else we must use default scene gpd, * to be consistent with ED_gpencil_data_get_active's behavior. */ - if (base && TESTBASE(v3d, base)) { + if (base && TESTBASE(base)) { gpd = base->object->gpd; } return gpd ? gpd : scene->gpd; @@ -521,7 +523,6 @@ bGPDpalettecolor *ED_gpencil_stroke_getcolor(bGPdata *gpd, bGPDstroke *gps) */ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc) { - Main *bmain = CTX_data_main(C); ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); @@ -538,6 +539,7 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc) if (sa->spacetype == SPACE_VIEW3D) { wmWindow *win = CTX_wm_window(C); Scene *scene = CTX_data_scene(C); + struct Depsgraph *depsgraph = CTX_data_depsgraph(C); View3D *v3d = (View3D *)CTX_wm_space_data(C); RegionView3D *rv3d = ar->regiondata; @@ -545,11 +547,11 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc) view3d_operator_needs_opengl(C); view3d_region_operator_needs_opengl(win, ar); - ED_view3d_autodist_init(bmain, scene, ar, v3d, 0); + ED_view3d_autodist_init(depsgraph, ar, v3d, 0); /* for camera view set the subrect */ if (rv3d->persp == RV3D_CAMOB) { - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &r_gsc->subrect_data, true); /* no shift */ + ED_view3d_calc_camera_border(scene, CTX_data_depsgraph(C), ar, v3d, rv3d, &r_gsc->subrect_data, true); /* no shift */ r_gsc->subrect = &r_gsc->subrect_data; } } @@ -744,7 +746,7 @@ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, Scene *scene, const float screen { View3D *v3d = gsc->sa->spacedata.first; RegionView3D *rv3d = gsc->ar->regiondata; - float *rvec = ED_view3d_cursor3d_get(scene, v3d); + float *rvec = ED_view3d_cursor3d_get(scene, v3d)->location; float ref[3] = {rvec[0], rvec[1], rvec[2]}; float zfac = ED_view3d_calc_zfac(rv3d, rvec, NULL); @@ -914,8 +916,8 @@ bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf) ptc = &gps->points[after]; /* the optimal value is the corresponding to the interpolation of the pressure - * at the distance of point b - */ + * at the distance of point b + */ float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x); float optimal = (1.0f - fac) * pta->pressure + fac * ptc->pressure; |