[Bf-blender-cvs] [2b0ad19dc3f] greasepencil-object: WIP: Add a temp framebuffer to control z-depth
Antonio Vazquez
noreply at git.blender.org
Wed Jun 21 16:53:31 CEST 2017
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. @@
More information about the Bf-blender-cvs
mailing list