Commit: 2b0ad19dc3fc8a604861a564750c0dcd5f405bde
Author: Antonio Vazquez
Date:   Wed Jun 21 16:53:09 2017 +0200
Branches: greasepencil-object
https://developer.blender.org/rB2b0ad19dc3fc8a604861a564750c0dcd5f405bde

WIP: Add a temp framebuffer to control z-depth

The stroke is rendered to temporary framebuffer and then render again using 
fullscreenquad to add the z-depth.

This cannot be done in one step because the strokes must keep the internal 
layers order without using z-depth values.

Still some problems with z-depth texture.

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

M       source/blender/draw/CMakeLists.txt
M       source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
M       source/blender/draw/engines/gpencil/gpencil_engine.c
M       source/blender/draw/engines/gpencil/gpencil_engine.h
A       source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl

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

diff --git a/source/blender/draw/CMakeLists.txt 
b/source/blender/draw/CMakeLists.txt
index cb098acc6ee..f44ea6d5b11 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -190,6 +190,7 @@ 
data_to_c_simple(engines/gpencil/shaders/gpencil_fill_frag.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/gpencil_stroke_vert.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/gpencil_stroke_geom.glsl SRC)
 data_to_c_simple(engines/gpencil/shaders/gpencil_stroke_frag.glsl SRC)
+data_to_c_simple(engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl SRC)
 
 list(APPEND INC
 )
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c 
b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index 23cffd828a1..c1d6086a186 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -47,6 +47,38 @@
 #define ZFIGHT_INIT -2048
 #define ZFIGHT_STEP 64
 
+ /* allocate cache to store GP objects */
+tGPencilObjectCache *gpencil_object_cache_allocate(tGPencilObjectCache *cache, 
int *gp_cache_size, int *gp_cache_used)
+{
+       tGPencilObjectCache *p = NULL;
+
+       /* By default a cache is created with one block with a predefined 
number of free slots,
+       if the size is not enough, the cache is reallocated adding a new block 
of free slots.
+       This is done in order to keep cache small */
+       if (*gp_cache_used + 1 > *gp_cache_size) {
+               if ((*gp_cache_size == 0) || (cache == NULL)) {
+                       p = MEM_callocN(sizeof(struct tGPencilObjectCache) * 
GP_CACHE_BLOCK_SIZE, "tGPencilObjectCache");
+                       *gp_cache_size = GP_CACHE_BLOCK_SIZE;
+               }
+               else {
+                       *gp_cache_size += GP_CACHE_BLOCK_SIZE;
+                       p = MEM_recallocN(cache, sizeof(struct 
tGPencilObjectCache) * *gp_cache_size);
+               }
+               cache = p;
+       }
+       return cache;
+}
+
+/* add a gpencil object to cache to defer drawing */
+void gpencil_object_cache_add(tGPencilObjectCache *cache, Object *ob, int 
*gp_cache_used)
+{
+       /* save object */
+       cache[*gp_cache_used].ob = ob;
+
+       /* increase slots used in cache */
+       ++*gp_cache_used;
+}
+
 /* verify if cache is valid */
 static bool gpencil_batch_cache_valid(bGPdata *gpd, int cfra)
 {
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c 
b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 6cfdac4b45e..1c0512f88ae 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -31,6 +31,8 @@
 #include "DNA_gpencil_types.h"
 #include "DNA_view3d_types.h"
 
+#include "draw_mode_engines.h"
+
 #include "gpencil_engine.h"
 
 extern char datatoc_gpencil_fill_vert_glsl[];
@@ -38,6 +40,7 @@ extern char datatoc_gpencil_fill_frag_glsl[];
 extern char datatoc_gpencil_stroke_vert_glsl[];
 extern char datatoc_gpencil_stroke_geom_glsl[];
 extern char datatoc_gpencil_stroke_frag_glsl[];
+extern char datatoc_gpencil_zdepth_mix_frag_glsl[];
 
 /* *********** STATIC *********** */
 static GPENCIL_e_data e_data = {NULL}; /* Engine data */
@@ -47,6 +50,19 @@ static GPENCIL_e_data e_data = {NULL}; /* Engine data */
 static void GPENCIL_engine_init(void *vedata)
 {
        GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+       GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
+
+       const float *viewport_size = DRW_viewport_size_get();
+
+       DRWFboTexture tex_color[2] = {{
+                       &e_data.temp_fbcolor_depth_tx, DRW_TEX_DEPTH_24, 
DRW_TEX_TEMP },
+                       { &e_data.temp_fbcolor_color_tx, DRW_TEX_RGBA_8, 
DRW_TEX_FILTER | DRW_TEX_TEMP }
+       };
+       /* init temp framebuffer */
+       DRW_framebuffer_init(
+               &fbl->temp_color_fb, &draw_engine_gpencil_type,
+               (int)viewport_size[0], (int)viewport_size[1],
+               tex_color, ARRAY_SIZE(tex_color));
 
        /* normal fill shader */
        if (!e_data.gpencil_fill_sh) {
@@ -85,6 +101,7 @@ static void GPENCIL_engine_free(void)
        /* only free custom shaders, builtin shaders are freed in blender close 
*/
        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_fullscreen_sh);
 }
 
 static void GPENCIL_cache_init(void *vedata)
@@ -99,7 +116,6 @@ static void GPENCIL_cache_init(void *vedata)
        if (!stl->g_data) {
                /* Alloc transient pointers */
                stl->g_data = MEM_mallocN(sizeof(g_data), "g_data");
-               stl->g_data->scene_draw = false;
                stl->storage->xray = GP_XRAY_FRONT; /* used for drawing */
        }
        if (!stl->shgroups) {
@@ -110,22 +126,40 @@ static void GPENCIL_cache_init(void *vedata)
                 */
                stl->shgroups = MEM_mallocN(sizeof(GPENCIL_shgroup) * 
GPENCIL_MAX_SHGROUPS, "GPENCIL_shgroup");
        }
+       
+       /* init gp objects cache */
+       stl->g_data->gp_cache_used = 0;
+       stl->g_data->gp_cache_size = 0;
+       stl->g_data->gp_object_cache = NULL;
+
+       /* full screen for mix zdepth*/
+       if (!e_data.gpencil_fullscreen_sh) {
+               e_data.gpencil_fullscreen_sh = 
DRW_shader_create_fullscreen(datatoc_gpencil_zdepth_mix_frag_glsl, NULL);
+       }
+
        {
                /* Stroke pass */
-               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | 
DRW_STATE_DEPTH_LESS;
-               psl->stroke_pass = DRW_pass_create("Gpencil Stroke Pass", 
state);
+               psl->stroke_pass = DRW_pass_create("Gpencil Stroke Pass", 
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND);
                stl->storage->pal_id = 0;
                stl->g_data->shgrps_point_volumetric = 
DRW_gpencil_shgroup_point_volumetric_create(psl->stroke_pass, 
e_data.gpencil_volumetric_sh);
 
-               state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND;
                /* edit pass */
-               psl->edit_pass = DRW_pass_create("Gpencil Edit Pass", state);
+               psl->edit_pass = DRW_pass_create("Gpencil Edit Pass", 
DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
                stl->g_data->shgrps_edit_volumetric = 
DRW_gpencil_shgroup_edit_volumetric_create(psl->edit_pass, 
e_data.gpencil_volumetric_sh);
 
                /* drawing buffer pass */
-               psl->drawing_pass = DRW_pass_create("Gpencil Drawing Pass", 
state);
+               psl->drawing_pass = DRW_pass_create("Gpencil Drawing Pass", 
DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
                stl->g_data->shgrps_drawing_stroke = 
DRW_gpencil_shgroup_stroke_create(vedata, psl->drawing_pass, 
e_data.gpencil_stroke_sh, NULL, NULL, -1);
                stl->g_data->shgrps_drawing_fill = 
DRW_gpencil_shgroup_drawing_fill_create(psl->drawing_pass, 
e_data.gpencil_drawing_fill_sh);
+
+               /* we need a full screen pass to combine the result of zdepth */
+               struct Batch *quad = DRW_cache_fullscreen_quad_get();
+
+               psl->mix_pass = DRW_pass_create("GPencil Mix Pass", 
DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | 
DRW_STATE_DEPTH_LESS);
+               DRWShadingGroup *mix_shgrp = 
DRW_shgroup_create(e_data.gpencil_fullscreen_sh, psl->mix_pass);
+               DRW_shgroup_call_add(mix_shgrp, quad, NULL);
+               DRW_shgroup_uniform_buffer(mix_shgrp, "strokeColor", 
&e_data.temp_fbcolor_color_tx);
+               DRW_shgroup_uniform_buffer(mix_shgrp, "strokeDepth", 
&e_data.temp_fbcolor_depth_tx);
        }
 }
 
@@ -136,39 +170,73 @@ static void GPENCIL_cache_populate(void *vedata, Object 
*ob)
        Scene *scene = draw_ctx->scene;
        ToolSettings *ts = scene->toolsettings;
 
-       /* scene datablock (only once) */
-       if (stl->g_data->scene_draw == false) {
-               stl->g_data->scene_draw = true;
-               if (scene && scene->gpd) {
-                       if (G.debug_value == 668) {
-                               printf("GPENCIL_cache_populate: Scene\n");
-                       }
-                       DRW_gpencil_populate_datablock(&e_data, vedata, scene, 
NULL, ts, scene->gpd);
-               }
-       }
        /* object datablock (this is not draw now) */
        if (ob->type == OB_GPENCIL && ob->gpd) {
                if (G.debug_value == 668) {
                        printf("GPENCIL_cache_populate: Object\n");
                }
-               DRW_gpencil_populate_datablock(&e_data, vedata, scene, ob, ts, 
ob->gpd);
+               /* allocate memory for saving gp objects */
+               stl->g_data->gp_object_cache = 
gpencil_object_cache_allocate(stl->g_data->gp_object_cache, 
&stl->g_data->gp_cache_size, &stl->g_data->gp_cache_used);
+               /* add for drawing later */
+               gpencil_object_cache_add(stl->g_data->gp_object_cache, ob, 
&stl->g_data->gp_cache_used);
        }
 }
 
 static void GPENCIL_cache_finish(void *vedata)
 {
-       GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
-       stl->g_data->scene_draw = false;
+       return;
 }
 
 static void GPENCIL_draw_scene(void *vedata)
 {
+       GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+       const DRWContextState *draw_ctx = DRW_context_state_get();
+       Scene *scene = draw_ctx->scene;
+       ToolSettings *ts = scene->toolsettings;
+
        GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+       GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
+       DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+       DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+       float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+
+       /* Draw all pending objects */
+       if (stl->g_data->gp_cache_used > 0) {
+               
+               /* attach temp textures */
+               DRW_framebuffer_texture_attach(fbl->temp_color_fb, 
e_data.temp_fbcolor_depth_tx, 0, 0);
+               DRW_framebuffer_texture_attach(fbl->temp_color_fb, 
e_data.temp_fbcolor_color_tx, 0, 0);
+
+               for (int i = 0; i < stl->g_data->gp_cache_used; ++i) {
+                       Object *ob = stl->g_data->gp_object_cache[i].ob;
+                       /* fill shading groups */
+                       DRW_gpencil_populate_datablock(&e_data, vedata, scene, 
ob, ts, ob->gpd);
+
+                       /* Render stroke in separated framebuffer */
+                       DRW_framebuffer_bind(fbl->temp_color_fb);
+                       DRW_framebuffer_clear(true, true, false, clearcol, 
1.0f);
+
+                       /* Stroke Pass: DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND 
| DRW_STATE_WRITE_DEPTH */
+                       DRW_draw_pass(psl->stroke_pass);
+
+                       /* Combine with scene buffer */
+                       DRW_framebuffer_bind(dfbl->default_fb);
+                       
+                       /* Mix Pass: DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | 
DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS */
+                       DRW_draw_pass(psl->mix_pass);
+
+                       /* edit points */
+                       DRW_draw_pass(psl->edit_pass);
+                       /* current drawing buffer */
+                       DRW_draw_pass(psl->drawing_pass);
 
-       DRW_draw_pass(psl->stroke_pass);
-       DRW_draw_pass(psl->edit_pass);
-       /* current buffer */
-       DRW_draw_pass(psl->drawing_pass);
+               }
+               /* detach temp textures */
+               DRW_framebuffer_texture_detach(e_data.temp_fbcolor_depth_tx);
+               DRW_framebuffer_texture_detach(e_data.temp_fbcolor_color_tx);
+       }
+       /* free memory */
+       MEM_SAFE_FREE(stl->g_data->gp_object_cache);
 }
 
 static const DrawEngineDataSize GPENCIL_data_size = DRW_VIEWPORT_DATA_SIZE(

@@ 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