Commit: a2dff881403ea6a9e695027ee92317a9d1ec9599
Author: Antonio Vazquez
Date:   Sat Apr 22 12:48:07 2017 +0200
Branches: greasepencil-object
https://developer.blender.org/rBa2dff881403ea6a9e695027ee92317a9d1ec9599

WIP: Add current stroke buffer to drawing manager

Pending to solve the error for first stroke before frame is created

===================================================================

M       source/blender/draw/engines/gpencil/gpencil_draw.c
M       source/blender/draw/engines/gpencil/gpencil_mode.c
M       source/blender/draw/engines/gpencil/gpencil_mode.h

===================================================================

diff --git a/source/blender/draw/engines/gpencil/gpencil_draw.c 
b/source/blender/draw/engines/gpencil/gpencil_draw.c
index c52d4ded62d..b4f45767f6b 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw.c
@@ -31,6 +31,8 @@
 #include "BLI_polyfill2d.h"
 
 #include "DNA_gpencil_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_view3d_types.h"
 
 #include "BKE_gpencil.h"
 #include "BKE_action.h"
@@ -41,6 +43,7 @@
 #include "GPU_draw.h"
 
 #include "ED_gpencil.h"
+#include "ED_view3d.h"
 
 #include "UI_resources.h"
 
@@ -59,7 +62,7 @@ static void gpencil_set_stroke_point(VertexBuffer *vbo, const 
bGPDspoint *pt, in
 
        float thick = max_ff(pt->pressure * thickness, 1.0f);
        VertexBuffer_set_attrib(vbo, thickness_id, idx, &thick);
-
+       
        copy_v3_v3(fpt, &pt->x);
        if (inverse) {
                mul_v3_fl(fpt, -1.0f);
@@ -118,6 +121,182 @@ Batch *gpencil_get_stroke_geom(bGPDstroke *gps, short 
thickness, const float ink
        return Batch_create(PRIM_LINE_STRIP_ADJACENCY, vbo, NULL);
 }
 
+/* helper to convert 2d to 3d for simple drawing buffer */
+static void gpencil_stroke_convertcoords(Scene *scene, ARegion *ar, ScrArea 
*sa, tGPspoint *point2D, float out[3], float *depth)
+{
+       float mval_f[2] = { point2D->x, point2D->y };
+       float mval_prj[2];
+       float rvec[3], dvec[3];
+       float zfac;
+
+       /* Current method just converts each point in screen-coordinates to
+       * 3D-coordinates using the 3D-cursor as reference.
+       */
+       View3D *v3d = sa->spacedata.first;
+       const float *cursor = ED_view3d_cursor3d_get(scene, v3d);
+       copy_v3_v3(rvec, cursor);
+
+       zfac = ED_view3d_calc_zfac(ar->regiondata, rvec, NULL);
+
+       if (ED_view3d_project_float_global(ar, rvec, mval_prj, 
V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+               sub_v2_v2v2(mval_f, mval_prj, mval_f);
+               ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
+               sub_v3_v3v3(out, rvec, dvec);
+       }
+       else {
+               zero_v3(out);
+       }
+}
+
+/* create batch geometry data for current buffer stroke shader */
+Batch *gpencil_get_buffer_stroke_geom(bGPdata *gpd, short thickness)
+{
+       const struct bContext *C = DRW_get_context();
+       Scene *scene = CTX_data_scene(C);
+       ScrArea *sa = CTX_wm_area(C);
+       ARegion *ar = CTX_wm_region(C);
+
+       tGPspoint *points = gpd->sbuffer;
+       int totpoints = gpd->sbuffer_size;
+
+       static VertexFormat format = { 0 };
+       static unsigned int pos_id, color_id, thickness_id;
+       if (format.attrib_ct == 0) {
+               pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, 
KEEP_FLOAT);
+               color_id = VertexFormat_add_attrib(&format, "color", COMP_F32, 
4, KEEP_FLOAT);
+               thickness_id = VertexFormat_add_attrib(&format, "thickness", 
COMP_F32, 1, KEEP_FLOAT);
+       }
+
+       VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+       VertexBuffer_allocate_data(vbo, totpoints + 2);
+
+       /* draw stroke curve */
+       const tGPspoint *tpt = points;
+       bGPDspoint pt;
+       int idx = 0;
+       float p3d[3];
+
+       float viewinvmat[4][4];
+       DRW_viewport_matrix_get(viewinvmat, DRW_MAT_VIEWINV);
+
+       for (int i = 0; i < totpoints; i++, tpt++) {
+               /* need conversion to 3d format */
+               gpencil_stroke_convertcoords(scene, ar, sa, tpt, p3d, NULL);
+               copy_v3_v3(&pt.x, p3d);
+               pt.pressure = tpt->pressure;
+               pt.strength = tpt->strength;
+
+               /* first point for adjacency (not drawn) */
+               if (i == 0) {
+                       gpencil_set_stroke_point(vbo, &pt, idx, pos_id, 
color_id, thickness_id, thickness, gpd->scolor, true);
+                       ++idx;
+               }
+               /* set point */
+               gpencil_set_stroke_point(vbo, &pt, idx, pos_id, color_id, 
thickness_id, thickness, gpd->scolor, false);
+               ++idx;
+       }
+
+       /* last adjacency point (not drawn) */
+       gpencil_set_stroke_point(vbo, &pt, idx, pos_id, color_id, thickness_id, 
thickness, gpd->scolor, true);
+
+       return Batch_create(PRIM_LINE_STRIP_ADJACENCY, vbo, NULL);
+}
+
+/* create batch geometry data for current buffer fill shader */
+Batch *gpencil_get_buffer_fill_geom(const tGPspoint *points, int totpoints, 
float ink[4])
+{
+       if (totpoints < 3) {
+               return NULL;
+       }
+
+       const struct bContext *C = DRW_get_context();
+       Scene *scene = CTX_data_scene(C);
+       ScrArea *sa = CTX_wm_area(C);
+       ARegion *ar = CTX_wm_region(C);
+
+       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);
+
+       static VertexFormat format = { 0 };
+       static unsigned int pos_id, color_id;
+       if (format.attrib_ct == 0) {
+               pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, 
KEEP_FLOAT);
+               color_id = VertexFormat_add_attrib(&format, "color", COMP_F32, 
4, KEEP_FLOAT);
+       }
+
+       VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+
+       /* draw triangulation data */
+       if (tot_triangles > 0) {
+               VertexBuffer_allocate_data(vbo, tot_triangles * 3);
+
+               const tGPspoint *tpt;
+               bGPDspoint pt;
+
+               int idx = 0;
+               float p3d[3];
+               for (int i = 0; i < tot_triangles; i++) {
+                       /* vertex 1 */
+                       tpt = &points[tmp_triangles[i][0]];
+                       /* need conversion to 3d format */
+                       gpencil_stroke_convertcoords(scene, ar, sa, tpt, p3d, 
NULL);
+                       copy_v3_v3(&pt.x, p3d);
+                       pt.pressure = tpt->pressure;
+                       pt.strength = tpt->strength;
+
+                       VertexBuffer_set_attrib(vbo, pos_id, idx, &pt.x);
+                       VertexBuffer_set_attrib(vbo, color_id, idx, ink);
+                       ++idx;
+                       /* vertex 2 */
+                       tpt = &points[tmp_triangles[i][1]];
+                       /* need conversion to 3d format */
+                       gpencil_stroke_convertcoords(scene, ar, sa, tpt, p3d, 
NULL);
+                       copy_v3_v3(&pt.x, p3d);
+                       pt.pressure = tpt->pressure;
+                       pt.strength = tpt->strength;
+
+                       VertexBuffer_set_attrib(vbo, pos_id, idx, &pt.x);
+                       VertexBuffer_set_attrib(vbo, color_id, idx, ink);
+                       ++idx;
+                       /* vertex 3 */
+                       tpt = &points[tmp_triangles[i][2]];
+                       /* need conversion to 3d format */
+                       gpencil_stroke_convertcoords(scene, ar, sa, tpt, p3d, 
NULL);
+                       copy_v3_v3(&pt.x, p3d);
+                       pt.pressure = tpt->pressure;
+                       pt.strength = tpt->strength;
+
+                       VertexBuffer_set_attrib(vbo, pos_id, idx, &pt.x);
+                       VertexBuffer_set_attrib(vbo, color_id, idx, ink);
+                       ++idx;
+               }
+       }
+
+       /* clear memory */
+       if (tmp_triangles) {
+               MEM_freeN(tmp_triangles);
+       }
+       if (points2d) {
+               MEM_freeN(points2d);
+       }
+
+       return Batch_create(PRIM_TRIANGLES, vbo, NULL);
+}
+
+
 /* Helper for doing all the checks on whether a stroke can be drawn */
 bool gpencil_can_draw_stroke(const bGPDstroke *gps)
 {
diff --git a/source/blender/draw/engines/gpencil/gpencil_mode.c 
b/source/blender/draw/engines/gpencil/gpencil_mode.c
index 1ce7189b313..2c03df791f1 100644
--- a/source/blender/draw/engines/gpencil/gpencil_mode.c
+++ b/source/blender/draw/engines/gpencil/gpencil_mode.c
@@ -69,6 +69,7 @@ typedef struct GPENCIL_PassList {
        struct DRWPass *stroke_pass;
        struct DRWPass *fill_pass;
        struct DRWPass *edit_pass;
+       struct DRWPass *drawing_pass;
 } GPENCIL_PassList;
 
 /* keep it under MAX_BUFFERS */
@@ -92,13 +93,17 @@ typedef struct GPENCIL_Data {
 /* *********** STATIC *********** */
 typedef struct g_data{
        DRWShadingGroup *shgrps_edit_volumetric;
+       DRWShadingGroup *shgrps_drawing_stroke;
+       DRWShadingGroup *shgrps_drawing_fill;
 } g_data; /* Transient data */
 
 static struct {
        struct GPUShader *gpencil_fill_sh;
        struct GPUShader *gpencil_stroke_sh;
-       struct GPUShader *gpencil_point_sh;
+       struct GPUShader *gpencil_stroke_2D_sh;
        struct GPUShader *gpencil_volumetric_sh;
+       struct GPUShader *gpencil_drawing_point_sh;
+       struct GPUShader *gpencil_drawing_fill_sh;
 } e_data = {NULL}; /* Engine data */
 
 /* *********** FUNCTIONS *********** */
@@ -116,10 +121,13 @@ static void GPENCIL_engine_init(void *vedata)
                                                                                
                 datatoc_gpencil_stroke_geom_glsl,
                                                                                
                 datatoc_gpencil_stroke_frag_glsl,
                                                                                
                 NULL);
-       e_data.gpencil_point_sh = 
GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
 
        e_data.gpencil_volumetric_sh = 
GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
 
+       e_data.gpencil_drawing_point_sh = 
GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
+
+       e_data.gpencil_drawing_fill_sh = 
GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR);
+
        if (!stl->storage) {
                stl->storage = MEM_callocN(sizeof(GPENCIL_Storage), 
"GPENCIL_Storage");
        }
@@ -130,6 +138,7 @@ static void GPENCIL_engine_free(void)
 {
        DRW_SHADER_FREE_SAFE(e_data.gpencil_fill_sh);
        DRW_SHADER_FREE_SAFE(e_data.gpencil_stroke_sh);
+       DRW_SHADER_FREE_SAFE(e_data.gpencil_stroke_2D_sh);
 }
 
 /* create shading group for filling */
@@ -192,6 +201,25 @@ static DRWShadingGroup 
*GPENCIL_shgroup_edit_volumetric_create(GPENCIL_Data *ved
        return grp;
 }
 
+/* create shading group for drawing strokes */
+static DRWShadingGroup *GPENCIL_shgroup_drawing_stroke_create(GPENCIL_Data 
*vedata, DRWPass *pass, PaletteColor *palcolor)
+{
+       GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+
+       DRWShadingGroup *grp = DRW_shgroup_create(e_data.gpencil_stroke_sh, 
pass);
+       DRW_shgroup_uniform_vec2(grp, "Viewport", DRW_viewport_size_get(), 1);
+       return grp;
+}
+
+/* create shading group for drawing fill */
+static DRWShadingGroup *GPENCIL_shgroup_drawing_fill_create(GPENCIL_Data 
*vedata, DRWPass *pass, PaletteColor *palcolor)
+{
+       GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+
+       DRWShadingGroup *grp = 
DRW_shgroup_create(e_data.gpencil_drawing_fill_sh, pass);
+       return grp;
+}
+
 static void GPENCIL_cache_init(void *vedata)
 {
        GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
@@ -202,6 +230,7 @@ static void GPENCIL_cache_init(void *vedata)
        const struct bContext *C = DRW_get_context();
        Scene *scene = CTX_data_scene(C);
        Scene

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to