diff options
Diffstat (limited to 'source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c')
-rw-r--r-- | source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c | 1021 |
1 files changed, 0 insertions, 1021 deletions
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c deleted file mode 100644 index a2016b9c1e6..00000000000 --- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c +++ /dev/null @@ -1,1021 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008, Blender Foundation - * This is a new part of Blender - */ - -/** \file - * \ingroup draw - */ - -#include "BLI_polyfill_2d.h" -#include "BLI_math_color.h" - -#include "DNA_meshdata_types.h" -#include "DNA_gpencil_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_deform.h" -#include "BKE_gpencil.h" - -#include "DRW_render.h" - -#include "ED_gpencil.h" -#include "ED_view3d.h" - -#include "UI_resources.h" - -#include "gpencil_engine.h" - -/* Helper to add stroke point to vbo */ -static void gpencil_set_stroke_point(GPUVertBuf *vbo, - const bGPDspoint *pt, - int idx, - uint pos_id, - uint color_id, - uint thickness_id, - uint uvdata_id, - short thickness, - const float ink[4]) -{ - - float alpha = ink[3] * pt->strength; - CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f); - float col[4]; - ARRAY_SET_ITEMS(col, ink[0], ink[1], ink[2], alpha); - - GPU_vertbuf_attr_set(vbo, color_id, idx, col); - - /* transfer both values using the same shader variable */ - float uvdata[2] = {pt->uv_fac, pt->uv_rot}; - GPU_vertbuf_attr_set(vbo, uvdata_id, idx, uvdata); - - /* the thickness of the stroke must be affected by zoom, so a pixel scale is calculated */ - float thick = max_ff(pt->pressure * thickness, 1.0f); - GPU_vertbuf_attr_set(vbo, thickness_id, idx, &thick); - - GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x); -} - -/* Helper to add buffer_stroke point to vbo */ -static void gpencil_set_buffer_stroke_point(GPUVertBuf *vbo, - const bGPDspoint *pt, - int idx, - uint pos_id, - uint color_id, - uint thickness_id, - uint uvdata_id, - uint prev_pos_id, - const float ref_pt[3], - short thickness, - const float ink[4]) -{ - - float alpha = ink[3] * pt->strength; - CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f); - float col[4]; - ARRAY_SET_ITEMS(col, ink[0], ink[1], ink[2], alpha); - - GPU_vertbuf_attr_set(vbo, color_id, idx, col); - - /* transfer both values using the same shader variable */ - float uvdata[2] = {pt->uv_fac, pt->uv_rot}; - GPU_vertbuf_attr_set(vbo, uvdata_id, idx, uvdata); - - /* the thickness of the stroke must be affected by zoom, so a pixel scale is calculated */ - float thick = max_ff(pt->pressure * thickness, 1.0f); - GPU_vertbuf_attr_set(vbo, thickness_id, idx, &thick); - - GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x); - /* reference point to follow drawing path */ - GPU_vertbuf_attr_set(vbo, prev_pos_id, idx, ref_pt); -} - -/* Helper to add a new fill point and texture coordinates to vertex buffer */ -static void gpencil_set_fill_point(GPUVertBuf *vbo, - int idx, - bGPDspoint *pt, - const float fcolor[4], - const float uv[2], - uint pos_id, - uint color_id, - uint text_id) -{ - GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x); - GPU_vertbuf_attr_set(vbo, color_id, idx, fcolor); - GPU_vertbuf_attr_set(vbo, text_id, idx, uv); -} - -static void gpencil_vbo_ensure_size(GpencilBatchCacheElem *be, int totvertex) -{ - if (be->vbo->vertex_alloc <= be->vbo_len + totvertex) { - uint newsize = be->vbo->vertex_alloc + - (((totvertex / GPENCIL_VBO_BLOCK_SIZE) + 1) * GPENCIL_VBO_BLOCK_SIZE); - GPU_vertbuf_data_resize(be->vbo, newsize); - } -} - -static void gpencil_elem_format_ensure(GpencilBatchCacheElem *be) -{ - if (be->format == NULL) { - be->format = MEM_callocN(sizeof(GPUVertFormat), __func__); - } -} - -/* create batch geometry data for points stroke shader */ -void gpencil_get_point_geom(GpencilBatchCacheElem *be, - bGPDstroke *gps, - short thickness, - const float ink[4], - const int alignment_mode) -{ - int totvertex = gps->totpoints; - if (be->vbo == NULL) { - gpencil_elem_format_ensure(be); - be->pos_id = GPU_vertformat_attr_add(be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - be->color_id = GPU_vertformat_attr_add(be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - be->thickness_id = GPU_vertformat_attr_add( - be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - be->uvdata_id = GPU_vertformat_attr_add( - be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - be->prev_pos_id = GPU_vertformat_attr_add( - be->format, "prev_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - - be->vbo = GPU_vertbuf_create_with_format(be->format); - GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex); - be->vbo_len = 0; - } - gpencil_vbo_ensure_size(be, totvertex); - - /* draw stroke curve */ - const bGPDspoint *pt = gps->points; - float alpha; - float col[4]; - - for (int i = 0; i < gps->totpoints; i++, pt++) { - /* set point */ - alpha = ink[3] * pt->strength; - CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f); - ARRAY_SET_ITEMS(col, ink[0], ink[1], ink[2], alpha); - - float thick = max_ff(pt->pressure * thickness, 1.0f); - - GPU_vertbuf_attr_set(be->vbo, be->color_id, be->vbo_len, col); - GPU_vertbuf_attr_set(be->vbo, be->thickness_id, be->vbo_len, &thick); - - /* transfer both values using the same shader variable */ - float uvdata[2] = {pt->uv_fac, pt->uv_rot}; - GPU_vertbuf_attr_set(be->vbo, be->uvdata_id, be->vbo_len, uvdata); - - GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x); - - /* use previous point to determine stroke direction */ - bGPDspoint *pt2 = NULL; - float fpt[3]; - if (alignment_mode != GP_STYLE_FOLLOW_PATH) { - /* add small offset to get a vector */ - copy_v3_v3(fpt, &pt->x); - fpt[0] += 0.00001f; - fpt[1] += 0.00001f; - GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt); - } - else { - if (i == 0) { - if (gps->totpoints > 1) { - /* extrapolate a point before first point */ - pt2 = &gps->points[1]; - interp_v3_v3v3(fpt, &pt2->x, &pt->x, 1.5f); - GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt); - } - else { - /* add small offset to get a vector */ - copy_v3_v3(fpt, &pt->x); - fpt[0] += 0.00001f; - fpt[1] += 0.00001f; - GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt); - } - } - else { - pt2 = &gps->points[i - 1]; - GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, &pt2->x); - } - } - be->vbo_len++; - } -} - -/* create batch geometry data for stroke shader */ -void gpencil_get_stroke_geom(struct GpencilBatchCacheElem *be, - bGPDstroke *gps, - short thickness, - const float ink[4]) -{ - bGPDspoint *points = gps->points; - int totpoints = gps->totpoints; - /* if cyclic needs more vertex */ - int cyclic_add = (gps->flag & GP_STROKE_CYCLIC) ? 1 : 0; - int totvertex = totpoints + cyclic_add + 2; - - if (be->vbo == NULL) { - gpencil_elem_format_ensure(be); - be->pos_id = GPU_vertformat_attr_add(be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - be->color_id = GPU_vertformat_attr_add(be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - be->thickness_id = GPU_vertformat_attr_add( - be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - be->uvdata_id = GPU_vertformat_attr_add( - be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - - be->vbo = GPU_vertbuf_create_with_format(be->format); - GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex); - be->vbo_len = 0; - } - gpencil_vbo_ensure_size(be, totvertex); - - /* draw stroke curve */ - const bGPDspoint *pt = points; - for (int i = 0; i < totpoints; i++, pt++) { - /* first point for adjacency (not drawn) */ - if (i == 0) { - if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) { - gpencil_set_stroke_point(be->vbo, - &points[totpoints - 1], - be->vbo_len, - be->pos_id, - be->color_id, - be->thickness_id, - be->uvdata_id, - thickness, - ink); - be->vbo_len++; - } - else { - gpencil_set_stroke_point(be->vbo, - &points[1], - be->vbo_len, - be->pos_id, - be->color_id, - be->thickness_id, - be->uvdata_id, - thickness, - ink); - be->vbo_len++; - } - } - /* set point */ - gpencil_set_stroke_point(be->vbo, - pt, - be->vbo_len, - be->pos_id, - be->color_id, - be->thickness_id, - be->uvdata_id, - thickness, - ink); - be->vbo_len++; - } - - if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) { - /* draw line to first point to complete the cycle */ - gpencil_set_stroke_point(be->vbo, - &points[0], - be->vbo_len, - be->pos_id, - be->color_id, - be->thickness_id, - be->uvdata_id, - thickness, - ink); - be->vbo_len++; - /* now add adjacency point (not drawn) */ - gpencil_set_stroke_point(be->vbo, - &points[1], - be->vbo_len, - be->pos_id, - be->color_id, - be->thickness_id, - be->uvdata_id, - thickness, - ink); - be->vbo_len++; - } - /* last adjacency point (not drawn) */ - else { - gpencil_set_stroke_point(be->vbo, - &points[totpoints - 2], - be->vbo_len, - be->pos_id, - be->color_id, - be->thickness_id, - be->uvdata_id, - thickness, - ink); - be->vbo_len++; - } -} - -/* create batch geometry data for stroke shader */ -void gpencil_get_fill_geom(struct GpencilBatchCacheElem *be, - Object *ob, - bGPDstroke *gps, - const float color[4]) -{ - BLI_assert(gps->totpoints >= 3); - - /* Calculate triangles cache for filling area (must be done only after changes) */ - if ((gps->flag & GP_STROKE_RECALC_GEOMETRY) || (gps->tot_triangles == 0) || - (gps->triangles == NULL)) { - BKE_gpencil_triangulate_stroke_fill((bGPdata *)ob->data, gps); - } - - BLI_assert(gps->tot_triangles >= 1); - int totvertex = gps->tot_triangles * 3; - - if (be->vbo == NULL) { - gpencil_elem_format_ensure(be); - be->pos_id = GPU_vertformat_attr_add(be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - be->color_id = GPU_vertformat_attr_add(be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - be->uvdata_id = GPU_vertformat_attr_add( - be->format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - - be->vbo = GPU_vertbuf_create_with_format(be->format); - GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex); - be->vbo_len = 0; - } - gpencil_vbo_ensure_size(be, totvertex); - - /* Draw all triangles for filling the polygon (cache must be calculated before) */ - bGPDtriangle *stroke_triangle = gps->triangles; - for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) { - for (int j = 0; j < 3; j++) { - gpencil_set_fill_point(be->vbo, - be->vbo_len, - &gps->points[stroke_triangle->verts[j]], - color, - stroke_triangle->uv[j], - be->pos_id, - be->color_id, - be->uvdata_id); - be->vbo_len++; - } - } -} - -/* create batch geometry data for current buffer stroke shader */ -GPUBatch *gpencil_get_buffer_stroke_geom(bGPdata *gpd, short thickness) -{ - const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; - ARegion *region = draw_ctx->region; - RegionView3D *rv3d = draw_ctx->rv3d; - ToolSettings *ts = scene->toolsettings; - Object *ob = draw_ctx->obact; - - tGPspoint *points = gpd->runtime.sbuffer; - int totpoints = gpd->runtime.sbuffer_used; - /* if cyclic needs more vertex */ - int cyclic_add = (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC) ? 1 : 0; - int totvertex = totpoints + cyclic_add + 2; - - static GPUVertFormat format = {0}; - static uint pos_id, color_id, thickness_id, uvdata_id; - if (format.attr_len == 0) { - pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - thickness_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - } - - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, totvertex); - - /* draw stroke curve */ - const tGPspoint *tpt = points; - bGPDspoint pt, pt2, pt3; - int idx = 0; - - /* get origin to reproject point */ - float origin[3]; - bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); - ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin); - - for (int i = 0; i < totpoints; i++, tpt++) { - ED_gpencil_tpoint_to_point(region, origin, tpt, &pt); - ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt); - - /* first point for adjacency (not drawn) */ - if (i == 0) { - if (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC && totpoints > 2) { - ED_gpencil_tpoint_to_point(region, origin, &points[totpoints - 1], &pt2); - gpencil_set_stroke_point(vbo, - &pt2, - idx, - pos_id, - color_id, - thickness_id, - uvdata_id, - thickness, - gpd->runtime.scolor); - idx++; - } - else { - ED_gpencil_tpoint_to_point(region, origin, &points[1], &pt2); - gpencil_set_stroke_point(vbo, - &pt2, - idx, - pos_id, - color_id, - thickness_id, - uvdata_id, - thickness, - gpd->runtime.scolor); - idx++; - } - } - - /* set point */ - gpencil_set_stroke_point( - vbo, &pt, idx, pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); - idx++; - } - - /* last adjacency point (not drawn) */ - if (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC && totpoints > 2) { - /* draw line to first point to complete the cycle */ - ED_gpencil_tpoint_to_point(region, origin, &points[0], &pt2); - gpencil_set_stroke_point( - vbo, &pt2, idx, pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); - idx++; - /* now add adjacency point (not drawn) */ - ED_gpencil_tpoint_to_point(region, origin, &points[1], &pt3); - gpencil_set_stroke_point( - vbo, &pt3, idx, pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); - idx++; - } - /* last adjacency point (not drawn) */ - else { - ED_gpencil_tpoint_to_point(region, origin, &points[totpoints - 2], &pt2); - gpencil_set_stroke_point( - vbo, &pt2, idx, pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor); - idx++; - } - - return GPU_batch_create_ex(GPU_PRIM_LINE_STRIP_ADJ, vbo, NULL, GPU_BATCH_OWNS_VBO); -} - -/* create batch geometry data for current buffer point shader */ -GPUBatch *gpencil_get_buffer_point_geom(bGPdata *gpd, short thickness) -{ - const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; - ARegion *region = draw_ctx->region; - RegionView3D *rv3d = draw_ctx->rv3d; - ToolSettings *ts = scene->toolsettings; - Object *ob = draw_ctx->obact; - - tGPspoint *points = gpd->runtime.sbuffer; - int totpoints = gpd->runtime.sbuffer_used; - - static GPUVertFormat format = {0}; - static uint pos_id, color_id, thickness_id, uvdata_id, prev_pos_id; - if (format.attr_len == 0) { - pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - thickness_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - prev_pos_id = GPU_vertformat_attr_add(&format, "prev_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - } - - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, totpoints); - - /* draw stroke curve */ - const tGPspoint *tpt = points; - bGPDspoint pt; - int idx = 0; - - /* get origin to reproject point */ - float origin[3]; - bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); - ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin); - - for (int i = 0; i < totpoints; i++, tpt++) { - ED_gpencil_tpoint_to_point(region, origin, tpt, &pt); - ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt); - - /* use previous point to determine stroke direction (drawing path) */ - bGPDspoint pt2; - float ref_pt[3]; - - if (i == 0) { - if (totpoints > 1) { - /* extrapolate a point before first point */ - tGPspoint *tpt2 = &points[1]; - ED_gpencil_tpoint_to_point(region, origin, tpt2, &pt2); - ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt2); - - interp_v3_v3v3(ref_pt, &pt2.x, &pt.x, 1.5f); - } - else { - copy_v3_v3(ref_pt, &pt.x); - } - } - else { - tGPspoint *tpt2 = &points[i - 1]; - ED_gpencil_tpoint_to_point(region, origin, tpt2, &pt2); - ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt2); - - copy_v3_v3(ref_pt, &pt2.x); - } - - /* set point */ - gpencil_set_buffer_stroke_point(vbo, - &pt, - idx, - pos_id, - color_id, - thickness_id, - uvdata_id, - prev_pos_id, - ref_pt, - thickness, - gpd->runtime.scolor); - idx++; - } - - return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO); -} - -/* create batch geometry data for current buffer control point shader */ -GPUBatch *gpencil_get_buffer_ctrlpoint_geom(bGPdata *gpd) -{ - bGPDcontrolpoint *cps = gpd->runtime.cp_points; - int totpoints = gpd->runtime.tot_cp_points; - - const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; - ToolSettings *ts = scene->toolsettings; - - if (ts->gp_sculpt.guide.use_guide) { - totpoints++; - } - - static GPUVertFormat format = {0}; - static uint pos_id, color_id, size_id; - if (format.attr_len == 0) { - pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - size_id = GPU_vertformat_attr_add(&format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - } - - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, totpoints); - - int idx = 0; - for (int i = 0; i < gpd->runtime.tot_cp_points; i++) { - bGPDcontrolpoint *cp = &cps[i]; - - GPU_vertbuf_attr_set(vbo, color_id, idx, cp->color); - - /* scale size */ - float size = cp->size * 0.8f; - GPU_vertbuf_attr_set(vbo, size_id, idx, &size); - - GPU_vertbuf_attr_set(vbo, pos_id, idx, &cp->x); - idx++; - } - - if (ts->gp_sculpt.guide.use_guide) { - float size = 10 * 0.8f; - float color[4]; - float position[3]; - if (ts->gp_sculpt.guide.reference_point == GP_GUIDE_REF_CUSTOM) { - UI_GetThemeColor4fv(TH_GIZMO_PRIMARY, color); - copy_v3_v3(position, ts->gp_sculpt.guide.location); - } - else if (ts->gp_sculpt.guide.reference_point == GP_GUIDE_REF_OBJECT && - ts->gp_sculpt.guide.reference_object != NULL) { - UI_GetThemeColor4fv(TH_GIZMO_SECONDARY, color); - copy_v3_v3(position, ts->gp_sculpt.guide.reference_object->loc); - } - else { - UI_GetThemeColor4fv(TH_REDALERT, color); - copy_v3_v3(position, scene->cursor.location); - } - GPU_vertbuf_attr_set(vbo, pos_id, idx, position); - GPU_vertbuf_attr_set(vbo, size_id, idx, &size); - GPU_vertbuf_attr_set(vbo, color_id, idx, color); - } - - return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO); -} - -/* create batch geometry data for current buffer fill shader */ -GPUBatch *gpencil_get_buffer_fill_geom(bGPdata *gpd) -{ - if (gpd == NULL) { - return NULL; - } - - const tGPspoint *points = gpd->runtime.sbuffer; - int totpoints = gpd->runtime.sbuffer_used; - if (totpoints < 3) { - return NULL; - } - - const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; - ARegion *region = draw_ctx->region; - ToolSettings *ts = scene->toolsettings; - Object *ob = draw_ctx->obact; - - /* get origin to reproject point */ - float origin[3]; - bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); - ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin); - - int tot_triangles = totpoints - 2; - /* allocate memory for temporary areas */ - uint(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, __func__); - float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, __func__); - - /* 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(points2d, (uint)totpoints, 0, tmp_triangles); - - static GPUVertFormat format = {0}; - static uint pos_id, color_id; - if (format.attr_len == 0) { - pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - } - - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - - /* draw triangulation data */ - if (tot_triangles > 0) { - GPU_vertbuf_data_alloc(vbo, tot_triangles * 3); - - const tGPspoint *tpt; - bGPDspoint pt; - - int idx = 0; - for (int i = 0; i < tot_triangles; i++) { - for (int j = 0; j < 3; j++) { - tpt = &points[tmp_triangles[i][j]]; - ED_gpencil_tpoint_to_point(region, origin, tpt, &pt); - GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt.x); - GPU_vertbuf_attr_set(vbo, color_id, idx, gpd->runtime.sfill); - idx++; - } - } - } - - /* clear memory */ - if (tmp_triangles) { - MEM_freeN(tmp_triangles); - } - if (points2d) { - MEM_freeN(points2d); - } - - return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); -} - -/* Draw selected verts for strokes being edited */ -void gpencil_get_edit_geom(struct GpencilBatchCacheElem *be, - bGPDstroke *gps, - float alpha, - short dflag) -{ - const DRWContextState *draw_ctx = DRW_context_state_get(); - Object *ob = draw_ctx->obact; - bGPdata *gpd = ob->data; - const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE); - const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); - - int vgindex = ob->actdef - 1; - if (!BLI_findlink(&ob->defbase, vgindex)) { - vgindex = -1; - } - - /* Get size of verts: - * - The selected state needs to be larger than the unselected state so that - * they stand out more. - * - We use the theme setting for size of the unselected verts - */ - float bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE); - float vsize; - if ((int)bsize > 8) { - vsize = 10.0f; - bsize = 8.0f; - } - else { - vsize = bsize + 2; - } - - /* for now, we assume that the base color of the points is not too close to the real color */ - float selectColor[4]; - UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor); - selectColor[3] = alpha; - - float unselectColor[4]; - UI_GetThemeColor3fv(TH_GP_VERTEX, unselectColor); - unselectColor[3] = alpha; - - float linecolor[4]; - copy_v4_v4(linecolor, gpd->line_color); - - if (be->vbo == NULL) { - gpencil_elem_format_ensure(be); - be->pos_id = GPU_vertformat_attr_add(be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - be->color_id = GPU_vertformat_attr_add(be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - be->thickness_id = GPU_vertformat_attr_add( - be->format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - - be->vbo = GPU_vertbuf_create_with_format(be->format); - GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex); - be->vbo_len = 0; - } - gpencil_vbo_ensure_size(be, gps->totpoints); - - /* Draw start and end point differently if enabled stroke direction hint */ - bool show_direction_hint = (dflag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1); - - /* Draw all the stroke points (selected or not) */ - bGPDspoint *pt = gps->points; - MDeformVert *dvert = gps->dvert; - - float fcolor[4]; - float fsize = 0; - for (int i = 0; i < gps->totpoints; i++, pt++) { - /* weight paint */ - if (is_weight_paint) { - float weight = (dvert && dvert->dw && (vgindex > -1)) ? - BKE_defvert_find_weight(dvert, vgindex) : - 0.0f; - float hue = 2.0f * (1.0f - weight) / 3.0f; - hsv_to_rgb(hue, 1.0f, 1.0f, &selectColor[0], &selectColor[1], &selectColor[2]); - selectColor[3] = 1.0f; - copy_v4_v4(fcolor, selectColor); - fsize = vsize; - } - else { - if (show_direction_hint && i == 0) { - /* start point in green bigger */ - ARRAY_SET_ITEMS(fcolor, 0.0f, 1.0f, 0.0f, 1.0f); - fsize = vsize + 4; - } - else if (show_direction_hint && (i == gps->totpoints - 1)) { - /* end point in red smaller */ - ARRAY_SET_ITEMS(fcolor, 1.0f, 0.0f, 0.0f, 1.0f); - fsize = vsize + 1; - } - else if ((!is_multiedit) && (pt->runtime.pt_orig == NULL)) { - ARRAY_SET_ITEMS(fcolor, linecolor[0], linecolor[1], linecolor[2], selectColor[3]); - mul_v4_fl(fcolor, 0.9f); - copy_v4_v4(fcolor, fcolor); - fsize = vsize * 0.8f; - } - else if (pt->flag & GP_SPOINT_SELECT) { - copy_v4_v4(fcolor, selectColor); - fsize = vsize; - } - else { - copy_v4_v4(fcolor, unselectColor); - fsize = bsize; - } - } - - GPU_vertbuf_attr_set(be->vbo, be->color_id, be->vbo_len, fcolor); - GPU_vertbuf_attr_set(be->vbo, be->thickness_id, be->vbo_len, &fsize); - GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x); - be->vbo_len++; - if (gps->dvert != NULL) { - dvert++; - } - } -} - -/* Draw lines for strokes being edited */ -void gpencil_get_edlin_geom(struct GpencilBatchCacheElem *be, - bGPDstroke *gps, - float alpha, - const bool hide_select) -{ - const DRWContextState *draw_ctx = DRW_context_state_get(); - Object *ob = draw_ctx->obact; - bGPdata *gpd = ob->data; - const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE); - - int vgindex = ob->actdef - 1; - if (!BLI_findlink(&ob->defbase, vgindex)) { - vgindex = -1; - } - - float selectColor[4]; - UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor); - selectColor[3] = alpha; - float linecolor[4]; - copy_v4_v4(linecolor, gpd->line_color); - - if (be->vbo == NULL) { - gpencil_elem_format_ensure(be); - be->pos_id = GPU_vertformat_attr_add(be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - be->color_id = GPU_vertformat_attr_add(be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - - be->vbo = GPU_vertbuf_create_with_format(be->format); - GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex); - be->vbo_len = 0; - } - gpencil_vbo_ensure_size(be, gps->totpoints); - - /* Draw all the stroke lines (selected or not) */ - bGPDspoint *pt = gps->points; - MDeformVert *dvert = gps->dvert; - - float fcolor[4]; - for (int i = 0; i < gps->totpoints; i++, pt++) { - /* weight paint */ - if (is_weight_paint) { - float weight = (dvert && dvert->dw && (vgindex > -1)) ? - BKE_defvert_find_weight(dvert, vgindex) : - 0.0f; - float hue = 2.0f * (1.0f - weight) / 3.0f; - hsv_to_rgb(hue, 1.0f, 1.0f, &selectColor[0], &selectColor[1], &selectColor[2]); - selectColor[3] = 1.0f; - copy_v4_v4(fcolor, selectColor); - } - else { - if ((pt->flag & GP_SPOINT_SELECT) && (!hide_select)) { - copy_v4_v4(fcolor, selectColor); - } - else { - copy_v4_v4(fcolor, linecolor); - } - } - - GPU_vertbuf_attr_set(be->vbo, be->color_id, be->vbo_len, fcolor); - GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x); - be->vbo_len++; - - if (gps->dvert != NULL) { - dvert++; - } - } -} - -static void set_grid_point(GPUVertBuf *vbo, - int idx, - const float col_grid[4], - uint pos_id, - uint color_id, - float v1, - float v2, - const int axis) -{ - GPU_vertbuf_attr_set(vbo, color_id, idx, col_grid); - - float pos[3]; - /* Set the grid in the selected axis */ - switch (axis) { - case GP_LOCKAXIS_X: { - ARRAY_SET_ITEMS(pos, 0.0f, v1, v2); - break; - } - case GP_LOCKAXIS_Y: { - ARRAY_SET_ITEMS(pos, v1, 0.0f, v2); - break; - } - case GP_LOCKAXIS_Z: - default: /* view aligned */ - { - ARRAY_SET_ITEMS(pos, v1, v2, 0.0f); - break; - } - } - - GPU_vertbuf_attr_set(vbo, pos_id, idx, pos); -} - -/* Draw grid lines */ -GPUBatch *gpencil_get_grid(Object *ob) -{ - const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; - ToolSettings *ts = scene->toolsettings; - View3D *v3d = draw_ctx->v3d; - bGPdata *gpd = (bGPdata *)ob->data; - const bool do_center = (gpd->grid.lines <= 0) ? false : true; - - float col_grid[4]; - - /* verify we have something to draw and valid values */ - if (gpd->grid.scale[0] == 0.0f) { - gpd->grid.scale[0] = 1.0f; - } - if (gpd->grid.scale[1] == 0.0f) { - gpd->grid.scale[1] = 1.0f; - } - - if (v3d->overlay.gpencil_grid_opacity < 0.1f) { - v3d->overlay.gpencil_grid_opacity = 0.1f; - } - - /* set color */ - copy_v3_v3(col_grid, gpd->grid.color); - col_grid[3] = v3d->overlay.gpencil_grid_opacity; - - const int axis = ts->gp_sculpt.lock_axis; - - const char *grid_unit = NULL; - const int gridlines = (gpd->grid.lines <= 0) ? 1 : gpd->grid.lines; - const float grid_w = gpd->grid.scale[0] * ED_scene_grid_scale(scene, &grid_unit); - const float grid_h = gpd->grid.scale[1] * ED_scene_grid_scale(scene, &grid_unit); - const float space_w = (grid_w / gridlines); - const float space_h = (grid_h / gridlines); - const float offset[2] = {gpd->grid.offset[0], gpd->grid.offset[1]}; - - const uint vertex_len = 2 * (gridlines * 4 + 2); - - static GPUVertFormat format = {0}; - static uint pos_id, color_id; - if (format.attr_len == 0) { - pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - } - - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, vertex_len); - - int idx = 0; - - for (int a = 1; a <= gridlines; a++) { - const float line_w = a * space_w; - const float line_h = a * space_h; - - set_grid_point( - vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], -line_h + offset[1], axis); - idx++; - set_grid_point( - vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], -line_h + offset[1], axis); - idx++; - set_grid_point( - vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], +line_h + offset[1], axis); - idx++; - set_grid_point( - vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], +line_h + offset[1], axis); - idx++; - - set_grid_point( - vbo, idx, col_grid, pos_id, color_id, -line_w + offset[0], -grid_h + offset[1], axis); - idx++; - set_grid_point( - vbo, idx, col_grid, pos_id, color_id, -line_w + offset[0], +grid_h + offset[1], axis); - idx++; - set_grid_point( - vbo, idx, col_grid, pos_id, color_id, +line_w + offset[0], -grid_h + offset[1], axis); - idx++; - set_grid_point( - vbo, idx, col_grid, pos_id, color_id, +line_w + offset[0], +grid_h + offset[1], axis); - idx++; - } - /* center lines */ - if (do_center) { - set_grid_point( - vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], 0.0f + offset[1], axis); - idx++; - set_grid_point( - vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], 0.0f + offset[1], axis); - idx++; - - set_grid_point( - vbo, idx, col_grid, pos_id, color_id, 0.0f + offset[0], -grid_h + offset[1], axis); - idx++; - set_grid_point( - vbo, idx, col_grid, pos_id, color_id, 0.0f + offset[0], +grid_h + offset[1], axis); - idx++; - } - return GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO); -} |