[Bf-blender-cvs] [a56c7a5cac8] greasepencil-object: WIP: Improve offscreen render
Antonio Vazquez
noreply at git.blender.org
Wed Dec 27 17:04:13 CET 2017
Commit: a56c7a5cac84b10fc1969d84689db078dec6c975
Author: Antonio Vazquez
Date: Tue Dec 26 17:58:49 2017 +0100
Branches: greasepencil-object
https://developer.blender.org/rBa56c7a5cac84b10fc1969d84689db078dec6c975
WIP: Improve offscreen render
Now, all the render is done in a image to debug results.
===================================================================
M source/blender/editors/gpencil/gpencil_fill.c
M source/blender/editors/include/ED_gpencil.h
===================================================================
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 70946c71dd2..29a6589a245 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -41,7 +41,9 @@
#include "DNA_windowmanager_types.h"
#include "BKE_main.h"
+#include "BKE_image.h"
#include "BKE_gpencil.h"
+#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_paint.h"
@@ -50,6 +52,10 @@
#include "ED_gpencil.h"
#include "ED_screen.h"
#include "ED_space_api.h"
+#include "ED_view3d.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
#include "GPU_immediate.h"
#include "GPU_draw.h"
@@ -61,11 +67,9 @@
/* 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)
+ const float diff_mat[4][4], bool cyclic, float ink[4])
{
float fpt[3];
- /* red 100% */
- float ink[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
/* if cyclic needs more vertex */
int cyclic_add = (cyclic) ? 1 : 0;
@@ -77,7 +81,7 @@ static void gp_draw_offscreen_stroke(const bGPDspoint *points, int totpoints,
immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
/* draw stroke curve */
- glLineWidth(4.0f);
+ glLineWidth(2.0f);
immBeginAtMost(GWN_PRIM_LINE_STRIP, totpoints + cyclic_add);
const bGPDspoint *pt = points;
@@ -100,31 +104,10 @@ static void gp_draw_offscreen_stroke(const bGPDspoint *points, int totpoints,
immUnbindProgram();
}
- /* draw strokes in offscreen buffer */
-static unsigned char *gp_draw_offscreen_strokes(tGPDfill *tgpf)
+/* loop all layers */
+static void gp_draw_datablock(Scene *scene, Object *ob, bGPdata *gpd, float ink[4])
{
- Scene *scene = tgpf->scene;
- Object *ob = tgpf->ob;
- bGPdata *gpd = (bGPdata *)ob->data;
float diff_mat[4][4];
- if (!gpd) {
- return NULL;
- }
-
- char err_out[256] = "unknown";
- GPUOffScreen *offscreen = GPU_offscreen_create(tgpf->sizex, tgpf->sizey, 0, err_out);
-
- GPU_offscreen_bind(offscreen, true);
-
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- //gpuPushMatrix();
- //gpuLoadMatrix(tgpf->rv3d->viewmat);
-
- //wmOrtho2(0, tgpf->sizex, 0, tgpf->sizey);
- //gpuTranslate2f(tgpf->sizex / 2.0f, tgpf->sizey / 2.0f);
-
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* calculate parent position */
ED_gpencil_parent_location(ob, gpd, gpl, diff_mat);
@@ -152,26 +135,124 @@ static unsigned char *gp_draw_offscreen_strokes(tGPDfill *tgpf)
/* 3D Lines - OpenGL primitives-based */
gp_draw_offscreen_stroke(gps->points, gps->totpoints,
- diff_mat, gps->flag & GP_STROKE_CYCLIC);
+ diff_mat, gps->flag & GP_STROKE_CYCLIC, ink);
}
}
+}
+
+ /* draw strokes in offscreen buffer */
+static void gp_render_offscreen(tGPDfill *tgpf)
+{
+ Scene *scene = tgpf->scene;
+ Object *ob = tgpf->ob;
+ bGPdata *gpd = (bGPdata *)ob->data;
+ const char *viewname = "GP";
+ bool is_ortho = false;
+ float winmat[4][4];
+
+ if (!gpd) {
+ return;
+ }
+
+ char err_out[256] = "unknown";
+ GPUOffScreen *offscreen = GPU_offscreen_create(tgpf->sizex, tgpf->sizey, 0, err_out);
+ GPU_offscreen_bind(offscreen, true);
+ unsigned int flag = IB_rect | IB_rectfloat;
+ ImBuf *ibuf = IMB_allocImBuf(tgpf->sizex, tgpf->sizey, 32, flag);
+
+ /* render 3d view */
+ if (tgpf->rv3d->persp == RV3D_CAMOB && tgpf->v3d->camera) {
+ CameraParams params;
+ Object *camera = BKE_camera_multiview_render(scene, tgpf->v3d->camera, viewname);
+
+ BKE_camera_params_init(¶ms);
+ /* fallback for non camera objects */
+ params.clipsta = tgpf->v3d->near;
+ params.clipend = tgpf->v3d->far;
+ BKE_camera_params_from_object(¶ms, camera);
+ BKE_camera_multiview_params(&scene->r, ¶ms, camera, viewname);
+ BKE_camera_params_compute_viewplane(¶ms, tgpf->sizex, tgpf->sizey, scene->r.xasp, scene->r.yasp);
+ BKE_camera_params_compute_matrix(¶ms);
+
+ is_ortho = params.is_ortho;
+ copy_m4_m4(winmat, params.winmat);
+ }
+ else {
+ rctf viewplane;
+ float clipsta, clipend;
+
+ is_ortho = ED_view3d_viewplane_get(tgpf->v3d, tgpf->rv3d, tgpf->sizex, tgpf->sizey, &viewplane, &clipsta, &clipend, NULL);
+ if (is_ortho) {
+ orthographic_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, -clipend, clipend);
+ }
+ else {
+ perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
+ }
+ }
+
+ /* set temporary new size */
+ int bwinx = tgpf->ar->winx;
+ int bwiny = tgpf->ar->winy;
+ rcti brect = tgpf->ar->winrct;
+
+ tgpf->ar->winx = tgpf->sizex;
+ tgpf->ar->winy = tgpf->sizey;
+ tgpf->ar->winrct.xmin = 0;
+ tgpf->ar->winrct.ymin = 0;
+ tgpf->ar->winrct.xmax = tgpf->sizex;
+ tgpf->ar->winrct.ymax = tgpf->sizey;
+
+ gpuPushProjectionMatrix();
+ gpuLoadIdentity();
+ gpuPushMatrix();
+ gpuLoadIdentity();
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ ED_view3d_update_viewmat(tgpf->eval_ctx, tgpf->scene, tgpf->v3d, tgpf->ar,
+ NULL, winmat, NULL);
+ /* set for opengl */
+ gpuLoadProjectionMatrix(tgpf->rv3d->winmat);
+ gpuLoadMatrix(tgpf->rv3d->viewmat);
+
+ /* draw strokes */
+ float ink[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
+ gp_draw_datablock(scene, ob, gpd, ink);
- //gpuPopMatrix();
+ /* restore size */
+ tgpf->ar->winx = bwinx;
+ tgpf->ar->winy = bwiny;
+ tgpf->ar->winrct = brect;
+
+ gpuPopProjectionMatrix();
+ gpuPopMatrix();
/* read result pixels */
- unsigned char *pixeldata = MEM_mallocN(tgpf->sizex * tgpf->sizey * sizeof(unsigned char) * 4, "gpencil offscreen fill");
- GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, pixeldata);
-
+ //unsigned char *pixeldata = MEM_mallocN(tgpf->sizex * tgpf->sizey * sizeof(unsigned char) * 4, "gpencil offscreen fill");
+ //GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, pixeldata);
+
+ /* create a image to see result of template */
+ if (ibuf->rect_float) {
+ GPU_offscreen_read_pixels(offscreen, GL_FLOAT, ibuf->rect_float);
+ }
+ else if (ibuf->rect) {
+ GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, ibuf->rect);
+ }
+ if (ibuf->rect_float && ibuf->rect) {
+ IMB_rect_from_float(ibuf);
+ }
+
+ tgpf->ima = BKE_image_add_from_imbuf(ibuf, "GP_fill");
+ BKE_image_release_ibuf(tgpf->ima, ibuf, NULL);
+
/* switch back to window-system-provided framebuffer */
GPU_offscreen_unbind(offscreen, true);
GPU_offscreen_free(offscreen);
-
- /* return texture data */
- return pixeldata;
}
/* return pixel data (rgba) at index */
-static unsigned char *get_pixel(unsigned char *pixeldata, int idx)
+static unsigned int *get_pixel(unsigned int *pixeldata, int idx)
{
if (idx >= 0) {
return &pixeldata[idx];
@@ -182,7 +263,7 @@ static unsigned char *get_pixel(unsigned char *pixeldata, int idx)
}
/* set pixel data (rgba) at index */
-static void set_pixel(unsigned char *pixeldata, int idx)
+static void set_pixel(unsigned int *pixeldata, int idx)
{
if (idx >= 0) {
/* enable Green & Alpha channel */
@@ -199,10 +280,16 @@ static void set_pixel(unsigned char *pixeldata, int idx)
* \param tgpf Temporary fill data
* \param pixeldata Array of pixels from offscreen render
*/
-static void gpencil_fill_area(tGPDfill *tgpf, unsigned char *pixeldata)
+static void gpencil_fill_area(tGPDfill *tgpf)
{
- const int maxpixel = (tgpf->sizex * tgpf->sizey * 4) - 4;
- unsigned char *rgba;
+ ImBuf *ibuf;
+ unsigned int *rgba;
+ unsigned int *pixeldata;
+ void *lock;
+
+ ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock);
+ const int maxpixel = (ibuf->x * ibuf->y) - 4;
+ pixeldata = ibuf->rect;
BLI_Stack *stack = BLI_stack_new(sizeof(int), __func__);
@@ -224,6 +311,7 @@ static void gpencil_fill_area(tGPDfill *tgpf, unsigned char *pixeldata)
* | X |
* -----------
*/
+#if 0
while (!BLI_stack_is_empty(stack)) {
int v;
BLI_stack_pop(stack, &v);
@@ -261,18 +349,22 @@ static void gpencil_fill_area(tGPDfill *tgpf, unsigned char *pixeldata)
}
}
+#endif
-#if 0 /* debug code */
- for (int x = 0; x <= maxpixel; x++) {
+//#if 0 /* debug code */
+ for (int x = 0; x < ibuf->x * ibuf->y; x++) {
rgba = get_pixel(pixeldata, x);
if (rgba[3] > 0) {
printf("%d->RGBA(%d, %d, %d, %d)\n", x, rgba[0], rgba[1], rgba[2], rgba[3]);
- set_pixel(pixeldata, x);
+ //set_pixel(pixeldata, x);
}
}
-
printf("\n");
-#endif
+//#endif
+
+ if (ibuf) {
+ BKE_image_release_ibuf(tgpf->ima, ibuf, lock);
+ }
/* free temp stack data*/
BLI_stack_free(stack);
@@ -281,58 +373,24 @@ static void gpencil_fill_area(tGPDfill *tgpf, unsigned char *pixeldata)
/* ----------------------- */
/* Drawing Callbacks */
-/* draw strokes for DEBUG only */
-static void DEBUG_draw_fill(const bContext *UNUSED(C), tGPDfill *tgpf)
+/* draw boundary lines to see fill limits */
+static void gpencil_draw_boundary_lines(const bContext *UNUSED(C), tGPDfill *tgpf)
{
Scene *scene = tgpf->scene;
Object *ob = tgpf->ob;
bGPdata *gpd = (bGPdata *)ob->data;
- float diff_mat[4][4];
if (!gpd) {
return;
}
-
- glEnable(GL_BLEND);
-
- 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);
- }
- }
-
- glDisable(GL_BLEND);
+ float ink[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
+ gp_draw_datablock(scene, ob, gpd, ink);
}
/* Drawing callback for modal operator in 3d mode
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list