[Bf-blender-cvs] [5f527f0885e] greasepencil-object: WIP: Experimental Offscreen buffer for fill

Antonio Vazquez noreply at git.blender.org
Fri Dec 15 18:34:36 CET 2017


Commit: 5f527f0885eff7dc79bde63e64ce1e7e5e8733e1
Author: Antonio Vazquez
Date:   Fri Dec 15 18:34:27 2017 +0100
Branches: greasepencil-object
https://developer.blender.org/rB5f527f0885eff7dc79bde63e64ce1e7e5e8733e1

WIP: Experimental Offscreen buffer for fill

Simple implementation of stroke drawing to texture

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

M	source/blender/editors/gpencil/gpencil_fill.c

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

diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 938918e1bf4..eca85303a0f 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -31,6 +31,7 @@
 
 #include "BLI_utildefines.h"
 #include "BLI_blenlib.h"
+#include "BLI_math.h"
 
 #include "DNA_object_types.h"
 #include "DNA_gpencil_types.h"
@@ -43,9 +44,118 @@
 #include "ED_gpencil.h"
 #include "ED_screen.h"
 
+#include "GPU_immediate.h"
+#include "GPU_draw.h"
+
 #include "WM_api.h"
 #include "WM_types.h"
 
+ /* draw a given stroke in offscreen */
+static void gp_draw_offscreen_stroke(const bGPDspoint *points, int totpoints, 
+	const float diff_mat[4][4], bool cyclic)
+{
+	float fpt[3];
+	float ink[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
+
+	/* if cyclic needs more vertex */
+	int cyclic_add = (cyclic) ? 1 : 0;
+
+	Gwn_VertFormat *format = immVertexFormat();
+	unsigned pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+	unsigned color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+
+	immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+	
+	/* draw stroke curve */
+	glLineWidth(2.0f);
+	immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints + cyclic_add);
+	const bGPDspoint *pt = points;
+
+	for (int i = 0; i < totpoints; i++, pt++) {
+		/* set point */
+		immAttrib4fv(color, ink);
+		mul_v3_m4v3(fpt, diff_mat, &pt->x);
+		immVertex3fv(pos, fpt);
+	}
+
+	if (cyclic && totpoints > 2) {
+		/* draw line to first point to complete the cycle */
+		immAttrib4fv(color, ink);
+		mul_v3_m4v3(fpt, diff_mat, &points->x);
+		immVertex3fv(pos, fpt);
+
+	}
+
+	immEnd();
+	immUnbindProgram();
+}
+
+ /* draw strokes in offscreen buffer */
+static GLubyte *gp_draw_offscreen_strokes(Scene *scene, Object *ob, rcti rect)
+{
+	bGPdata *gpd = (bGPdata *)ob->data;
+	float diff_mat[4][4];
+	GLubyte* data = (GLubyte *)malloc(rect.xmax * rect.ymax * 4 * sizeof(GLubyte));
+	if (!gpd) {
+		return NULL;
+	}
+
+	/* create offscreen framebuffer */
+	GLuint FramebufferId = 0;
+	glGenFramebuffers(1, &FramebufferId);
+	glBindFramebuffer(GL_FRAMEBUFFER, FramebufferId);
+
+	/* create texture */
+	GLuint textureId;
+	glGenTextures(1, &textureId);
+	glBindTexture(GL_TEXTURE_2D, textureId);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rect.xmax, rect.ymax, 0, GL_RGBA, 
+				 GL_UNSIGNED_BYTE, data);
+	/* attach the texture to FBO color attachment point */
+	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
+
+	glBindFramebuffer(GL_FRAMEBUFFER, FramebufferId);
+	glViewport(0, 0, rect.xmax, rect.ymax);
+	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+		/* calculate parent position */
+		ED_gpencil_parent_location(ob, gpd, gpl, diff_mat);
+
+		/* don't draw layer if hidden */
+		if (gpl->flag & GP_LAYER_HIDE)
+			continue;
+
+		/* get frame to draw */
+		bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, CFRA, 0);
+		if (gpf == NULL)
+			continue;
+
+		for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+			/* check if stroke can be drawn */
+			if ((gps->points == NULL) || (gps->totpoints < 2)) {
+				continue;
+			}
+			/* check if the color is visible */
+			PaletteColor *palcolor = gps->palcolor;
+			if ((palcolor == NULL) || (palcolor->flag & PC_COLOR_HIDE))
+			{
+				continue;
+			}
+
+			/* 3D Lines - OpenGL primitives-based */
+			gp_draw_offscreen_stroke(gps->points, gps->totpoints,
+				diff_mat, gps->flag & GP_STROKE_CYCLIC);
+		}
+	}
+	/* switch back to window-system-provided framebuffer */
+	glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+	/* return texture data */
+	return data;
+}
+
 /* check if context is suitable for filling */
 static int gpencil_fill_poll(bContext *C)
 {
@@ -101,6 +211,9 @@ static void gpencil_fill_cancel(bContext *C, wmOperator *op)
 /* events handling during interactive part of operator */
 static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
 {
+	Scene *scene = CTX_data_scene(C);
+	Object *ob = CTX_data_active_object(C);
+
 	int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through */
 	
 	/* we don't pass on key events, GP is used with key-modifiers - prevents Dkey to insert drivers */
@@ -123,6 +236,8 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
 			if ((in_bounds) && (ar->regiontype == RGN_TYPE_WINDOW)) {
 				/* TODO: Add fill code here */
 				printf("(%d, %d) Do all here!\n", event->mval[0], event->mval[1]);
+				gp_draw_offscreen_strokes(scene, ob, region_rect);
+
 				estate = OPERATOR_FINISHED;
 			}
 			else {
@@ -138,7 +253,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
 	switch (estate) {
 		case OPERATOR_FINISHED:
 			gpencil_fill_exit(C, op);
-			WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+			/* TODO: Removed for debug: WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); */
 			break;
 		
 		case OPERATOR_CANCELLED:



More information about the Bf-blender-cvs mailing list