[Bf-blender-cvs] [a2dff881403] greasepencil-object: WIP: Add current stroke buffer to drawing manager
Antonio Vazquez
noreply at git.blender.org
Sat Apr 22 12:48:29 CEST 2017
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. @@
More information about the Bf-blender-cvs
mailing list