Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/draw/engines/gpencil
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/draw/engines/gpencil')
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_cache_utils.c510
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c1518
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_utils.c3618
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c1928
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h708
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_render.c567
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_shader_fx.c1877
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl120
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl122
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl46
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl72
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl54
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl69
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl56
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl78
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl130
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_shadow_prepare_frag.glsl105
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_shadow_resolve_frag.glsl30
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl71
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl48
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl6
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl241
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl16
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl44
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl6
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl284
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl6
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl2
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl92
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl186
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl66
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl10
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl92
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl413
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl64
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl88
36 files changed, 6796 insertions, 6547 deletions
diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index 972ada22b50..76ec0a61b8c 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -42,311 +42,317 @@
/* verify if exist a non instanced version of the object */
static bool gpencil_has_noninstanced_object(Object *ob_instance)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- const ViewLayer *view_layer = draw_ctx->view_layer;
- Object *ob = NULL;
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- ob = base->object;
- if (ob->type != OB_GPENCIL) {
- continue;
- }
- /* object must be visible (invisible objects don't create VBO data) */
- if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
- continue;
- }
- /* is not duplicated and the name is equals */
- if ((ob->base_flag & BASE_FROM_DUPLI) == 0) {
- if (STREQ(ob->id.name, ob_instance->id.name)) {
- return true;
- }
- }
- }
-
- return false;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const ViewLayer *view_layer = draw_ctx->view_layer;
+ Object *ob = NULL;
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ ob = base->object;
+ if (ob->type != OB_GPENCIL) {
+ continue;
+ }
+ /* object must be visible (invisible objects don't create VBO data) */
+ if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
+ continue;
+ }
+ /* is not duplicated and the name is equals */
+ if ((ob->base_flag & BASE_FROM_DUPLI) == 0) {
+ if (STREQ(ob->id.name, ob_instance->id.name)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
}
/* add a gpencil object to cache to defer drawing */
-tGPencilObjectCache *gpencil_object_cache_add(
- tGPencilObjectCache *cache_array, Object *ob,
- int *gp_cache_size, int *gp_cache_used)
+tGPencilObjectCache *gpencil_object_cache_add(tGPencilObjectCache *cache_array,
+ Object *ob,
+ int *gp_cache_size,
+ int *gp_cache_used)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- tGPencilObjectCache *cache_elem = NULL;
- RegionView3D *rv3d = draw_ctx->rv3d;
- View3D *v3d = draw_ctx->v3d;
- 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_array == 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_array, sizeof(struct tGPencilObjectCache) * *gp_cache_size);
- }
- cache_array = p;
- }
- /* zero out all pointers */
- cache_elem = &cache_array[*gp_cache_used];
- memset(cache_elem, 0, sizeof(*cache_elem));
-
- cache_elem->ob = ob;
- cache_elem->gpd = (bGPdata *)ob->data;
- cache_elem->name = BKE_id_to_unique_string_key(&ob->id);
-
- copy_v3_v3(cache_elem->loc, ob->obmat[3]);
- copy_m4_m4(cache_elem->obmat, ob->obmat);
- cache_elem->idx = *gp_cache_used;
-
- /* object is duplicated (particle) */
- if (ob->base_flag & BASE_FROM_DUPLI) {
- /* Check if the original object is not in the viewlayer
- * and cannot be managed as dupli. This is slower, but required to keep
- * the particle drawing FPS and display instanced objects in scene
- * without the original object */
- bool has_original = gpencil_has_noninstanced_object(ob);
- cache_elem->is_dup_ob = (has_original) ? ob->base_flag & BASE_FROM_DUPLI : false;
- }
- else {
- cache_elem->is_dup_ob = false;
- }
-
- cache_elem->scale = mat4_to_scale(ob->obmat);
-
- /* save FXs */
- cache_elem->pixfactor = cache_elem->gpd->pixfactor;
- cache_elem->shader_fx = ob->shader_fx;
-
- /* save wire mode (object mode is always primary option) */
- if (ob->dt == OB_WIRE) {
- cache_elem->shading_type[0] = (int)OB_WIRE;
- }
- else {
- if (v3d) {
- cache_elem->shading_type[0] = (int)v3d->shading.type;
- }
- }
-
- /* shgrp array */
- cache_elem->tot_layers = 0;
- int totgpl = BLI_listbase_count(&cache_elem->gpd->layers);
- if (totgpl > 0) {
- cache_elem->shgrp_array = MEM_callocN(sizeof(tGPencilObjectCache_shgrp) * totgpl, __func__);
- }
-
- /* calculate zdepth from point of view */
- float zdepth = 0.0;
- if (rv3d) {
- if (rv3d->is_persp) {
- zdepth = ED_view3d_calc_zfac(rv3d, ob->obmat[3], NULL);
- }
- else {
- zdepth = -dot_v3v3(rv3d->viewinv[2], ob->obmat[3]);
- }
- }
- else {
- /* In render mode, rv3d is not available, so use the distance to camera.
- * The real distance is not important, but the relative distance to the camera plane
- * in order to sort by z_depth of the objects
- */
- float vn[3] = { 0.0f, 0.0f, -1.0f }; /* always face down */
- float plane_cam[4];
- struct Object *camera = draw_ctx->scene->camera;
- if (camera) {
- mul_m4_v3(camera->obmat, vn);
- normalize_v3(vn);
- plane_from_point_normal_v3(plane_cam, camera->loc, vn);
- zdepth = dist_squared_to_plane_v3(ob->obmat[3], plane_cam);
- }
- }
- cache_elem->zdepth = zdepth;
- /* increase slots used in cache */
- (*gp_cache_used)++;
-
- return cache_array;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ tGPencilObjectCache *cache_elem = NULL;
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ View3D *v3d = draw_ctx->v3d;
+ 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_array == 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_array, sizeof(struct tGPencilObjectCache) * *gp_cache_size);
+ }
+ cache_array = p;
+ }
+ /* zero out all pointers */
+ cache_elem = &cache_array[*gp_cache_used];
+ memset(cache_elem, 0, sizeof(*cache_elem));
+
+ cache_elem->ob = ob;
+ cache_elem->gpd = (bGPdata *)ob->data;
+ cache_elem->name = BKE_id_to_unique_string_key(&ob->id);
+
+ copy_v3_v3(cache_elem->loc, ob->obmat[3]);
+ copy_m4_m4(cache_elem->obmat, ob->obmat);
+ cache_elem->idx = *gp_cache_used;
+
+ /* object is duplicated (particle) */
+ if (ob->base_flag & BASE_FROM_DUPLI) {
+ /* Check if the original object is not in the viewlayer
+ * and cannot be managed as dupli. This is slower, but required to keep
+ * the particle drawing FPS and display instanced objects in scene
+ * without the original object */
+ bool has_original = gpencil_has_noninstanced_object(ob);
+ cache_elem->is_dup_ob = (has_original) ? ob->base_flag & BASE_FROM_DUPLI : false;
+ }
+ else {
+ cache_elem->is_dup_ob = false;
+ }
+
+ cache_elem->scale = mat4_to_scale(ob->obmat);
+
+ /* save FXs */
+ cache_elem->pixfactor = cache_elem->gpd->pixfactor;
+ cache_elem->shader_fx = ob->shader_fx;
+
+ /* save wire mode (object mode is always primary option) */
+ if (ob->dt == OB_WIRE) {
+ cache_elem->shading_type[0] = (int)OB_WIRE;
+ }
+ else {
+ if (v3d) {
+ cache_elem->shading_type[0] = (int)v3d->shading.type;
+ }
+ }
+
+ /* shgrp array */
+ cache_elem->tot_layers = 0;
+ int totgpl = BLI_listbase_count(&cache_elem->gpd->layers);
+ if (totgpl > 0) {
+ cache_elem->shgrp_array = MEM_callocN(sizeof(tGPencilObjectCache_shgrp) * totgpl, __func__);
+ }
+
+ /* calculate zdepth from point of view */
+ float zdepth = 0.0;
+ if (rv3d) {
+ if (rv3d->is_persp) {
+ zdepth = ED_view3d_calc_zfac(rv3d, ob->obmat[3], NULL);
+ }
+ else {
+ zdepth = -dot_v3v3(rv3d->viewinv[2], ob->obmat[3]);
+ }
+ }
+ else {
+ /* In render mode, rv3d is not available, so use the distance to camera.
+ * The real distance is not important, but the relative distance to the camera plane
+ * in order to sort by z_depth of the objects
+ */
+ float vn[3] = {0.0f, 0.0f, -1.0f}; /* always face down */
+ float plane_cam[4];
+ struct Object *camera = draw_ctx->scene->camera;
+ if (camera) {
+ mul_m4_v3(camera->obmat, vn);
+ normalize_v3(vn);
+ plane_from_point_normal_v3(plane_cam, camera->loc, vn);
+ zdepth = dist_squared_to_plane_v3(ob->obmat[3], plane_cam);
+ }
+ }
+ cache_elem->zdepth = zdepth;
+ /* increase slots used in cache */
+ (*gp_cache_used)++;
+
+ return cache_array;
}
/* add a shading group to the cache to create later */
-GpencilBatchGroup *gpencil_group_cache_add(
- GpencilBatchGroup *cache_array,
- bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps,
- const short type, const bool onion,
- const int vertex_idx,
- int *grp_size, int *grp_used)
+GpencilBatchGroup *gpencil_group_cache_add(GpencilBatchGroup *cache_array,
+ bGPDlayer *gpl,
+ bGPDframe *gpf,
+ bGPDstroke *gps,
+ const short type,
+ const bool onion,
+ const int vertex_idx,
+ int *grp_size,
+ int *grp_used)
{
- GpencilBatchGroup *cache_elem = NULL;
- GpencilBatchGroup *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 (*grp_used + 1 > *grp_size) {
- if ((*grp_size == 0) || (cache_array == NULL)) {
- p = MEM_callocN(sizeof(struct GpencilBatchGroup) * GPENCIL_GROUPS_BLOCK_SIZE, "GpencilBatchGroup");
- *grp_size = GPENCIL_GROUPS_BLOCK_SIZE;
- }
- else {
- *grp_size += GPENCIL_GROUPS_BLOCK_SIZE;
- p = MEM_recallocN(cache_array, sizeof(struct GpencilBatchGroup) * *grp_size);
- }
- cache_array = p;
- }
- /* zero out all data */
- cache_elem = &cache_array[*grp_used];
- memset(cache_elem, 0, sizeof(*cache_elem));
-
- cache_elem->gpl = gpl;
- cache_elem->gpf = gpf;
- cache_elem->gps = gps;
- cache_elem->type = type;
- cache_elem->onion = onion;
- cache_elem->vertex_idx = vertex_idx;
-
- /* increase slots used in cache */
- (*grp_used)++;
-
- return cache_array;
+ GpencilBatchGroup *cache_elem = NULL;
+ GpencilBatchGroup *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 (*grp_used + 1 > *grp_size) {
+ if ((*grp_size == 0) || (cache_array == NULL)) {
+ p = MEM_callocN(sizeof(struct GpencilBatchGroup) * GPENCIL_GROUPS_BLOCK_SIZE,
+ "GpencilBatchGroup");
+ *grp_size = GPENCIL_GROUPS_BLOCK_SIZE;
+ }
+ else {
+ *grp_size += GPENCIL_GROUPS_BLOCK_SIZE;
+ p = MEM_recallocN(cache_array, sizeof(struct GpencilBatchGroup) * *grp_size);
+ }
+ cache_array = p;
+ }
+ /* zero out all data */
+ cache_elem = &cache_array[*grp_used];
+ memset(cache_elem, 0, sizeof(*cache_elem));
+
+ cache_elem->gpl = gpl;
+ cache_elem->gpf = gpf;
+ cache_elem->gps = gps;
+ cache_elem->type = type;
+ cache_elem->onion = onion;
+ cache_elem->vertex_idx = vertex_idx;
+
+ /* increase slots used in cache */
+ (*grp_used)++;
+
+ return cache_array;
}
/* get current cache data */
static GpencilBatchCache *gpencil_batch_get_element(Object *ob)
{
- return ob->runtime.gpencil_cache;
+ return ob->runtime.gpencil_cache;
}
/* verify if cache is valid */
static bool gpencil_batch_cache_valid(GpencilBatchCache *cache, bGPdata *gpd, int cfra)
{
- bool valid = true;
- if (cache == NULL) {
- return false;
- }
-
- cache->is_editmode = GPENCIL_ANY_EDIT_MODE(gpd);
- if (cfra != cache->cache_frame) {
- valid = false;
- }
- else if (gpd->flag & GP_DATA_CACHE_IS_DIRTY) {
- valid = false;
- }
- else if (gpd->flag & GP_DATA_PYTHON_UPDATED) {
- gpd->flag &= ~GP_DATA_PYTHON_UPDATED;
- valid = false;
- }
- else if (cache->is_editmode) {
- valid = false;
- }
- else if (cache->is_dirty) {
- valid = false;
- }
-
- return valid;
+ bool valid = true;
+ if (cache == NULL) {
+ return false;
+ }
+
+ cache->is_editmode = GPENCIL_ANY_EDIT_MODE(gpd);
+ if (cfra != cache->cache_frame) {
+ valid = false;
+ }
+ else if (gpd->flag & GP_DATA_CACHE_IS_DIRTY) {
+ valid = false;
+ }
+ else if (gpd->flag & GP_DATA_PYTHON_UPDATED) {
+ gpd->flag &= ~GP_DATA_PYTHON_UPDATED;
+ valid = false;
+ }
+ else if (cache->is_editmode) {
+ valid = false;
+ }
+ else if (cache->is_dirty) {
+ valid = false;
+ }
+
+ return valid;
}
/* cache init */
static GpencilBatchCache *gpencil_batch_cache_init(Object *ob, int cfra)
{
- bGPdata *gpd = (bGPdata *)ob->data;
+ bGPdata *gpd = (bGPdata *)ob->data;
- GpencilBatchCache *cache = gpencil_batch_get_element(ob);
+ GpencilBatchCache *cache = gpencil_batch_get_element(ob);
- if (!cache) {
- cache = MEM_callocN(sizeof(*cache), __func__);
- ob->runtime.gpencil_cache = cache;
- }
- else {
- memset(cache, 0, sizeof(*cache));
- }
+ if (!cache) {
+ cache = MEM_callocN(sizeof(*cache), __func__);
+ ob->runtime.gpencil_cache = cache;
+ }
+ else {
+ memset(cache, 0, sizeof(*cache));
+ }
- cache->is_editmode = GPENCIL_ANY_EDIT_MODE(gpd);
+ cache->is_editmode = GPENCIL_ANY_EDIT_MODE(gpd);
- cache->is_dirty = true;
+ cache->is_dirty = true;
- cache->cache_frame = cfra;
+ cache->cache_frame = cfra;
- /* create array of derived frames equal to number of layers */
- cache->tot_layers = BLI_listbase_count(&gpd->layers);
- CLAMP_MIN(cache->tot_layers, 1);
- cache->derived_array = MEM_callocN(sizeof(struct bGPDframe) * cache->tot_layers, "Derived GPF");
+ /* create array of derived frames equal to number of layers */
+ cache->tot_layers = BLI_listbase_count(&gpd->layers);
+ CLAMP_MIN(cache->tot_layers, 1);
+ cache->derived_array = MEM_callocN(sizeof(struct bGPDframe) * cache->tot_layers, "Derived GPF");
- return cache;
+ return cache;
}
/* clear cache */
static void gpencil_batch_cache_clear(GpencilBatchCache *cache)
{
- if (!cache) {
- return;
- }
-
- GPU_BATCH_DISCARD_SAFE(cache->b_stroke.batch);
- GPU_BATCH_DISCARD_SAFE(cache->b_point.batch);
- GPU_BATCH_DISCARD_SAFE(cache->b_fill.batch);
- GPU_BATCH_DISCARD_SAFE(cache->b_edit.batch);
- GPU_BATCH_DISCARD_SAFE(cache->b_edlin.batch);
-
- MEM_SAFE_FREE(cache->b_stroke.batch);
- MEM_SAFE_FREE(cache->b_point.batch);
- MEM_SAFE_FREE(cache->b_fill.batch);
- MEM_SAFE_FREE(cache->b_edit.batch);
- MEM_SAFE_FREE(cache->b_edlin.batch);
-
- MEM_SAFE_FREE(cache->grp_cache);
- cache->grp_size = 0;
- cache->grp_used = 0;
-
- /* clear all frames derived data */
- for (int i = 0; i < cache->tot_layers; i++) {
- bGPDframe *derived_gpf = &cache->derived_array[i];
- BKE_gpencil_free_frame_runtime_data(derived_gpf);
- derived_gpf = NULL;
- }
- cache->tot_layers = 0;
- MEM_SAFE_FREE(cache->derived_array);
+ if (!cache) {
+ return;
+ }
+
+ GPU_BATCH_DISCARD_SAFE(cache->b_stroke.batch);
+ GPU_BATCH_DISCARD_SAFE(cache->b_point.batch);
+ GPU_BATCH_DISCARD_SAFE(cache->b_fill.batch);
+ GPU_BATCH_DISCARD_SAFE(cache->b_edit.batch);
+ GPU_BATCH_DISCARD_SAFE(cache->b_edlin.batch);
+
+ MEM_SAFE_FREE(cache->b_stroke.batch);
+ MEM_SAFE_FREE(cache->b_point.batch);
+ MEM_SAFE_FREE(cache->b_fill.batch);
+ MEM_SAFE_FREE(cache->b_edit.batch);
+ MEM_SAFE_FREE(cache->b_edlin.batch);
+
+ MEM_SAFE_FREE(cache->grp_cache);
+ cache->grp_size = 0;
+ cache->grp_used = 0;
+
+ /* clear all frames derived data */
+ for (int i = 0; i < cache->tot_layers; i++) {
+ bGPDframe *derived_gpf = &cache->derived_array[i];
+ BKE_gpencil_free_frame_runtime_data(derived_gpf);
+ derived_gpf = NULL;
+ }
+ cache->tot_layers = 0;
+ MEM_SAFE_FREE(cache->derived_array);
}
/* get cache */
GpencilBatchCache *gpencil_batch_cache_get(Object *ob, int cfra)
{
- bGPdata *gpd = (bGPdata *)ob->data;
-
- GpencilBatchCache *cache = gpencil_batch_get_element(ob);
- if (!gpencil_batch_cache_valid(cache, gpd, cfra)) {
- if (cache) {
- gpencil_batch_cache_clear(cache);
- }
- return gpencil_batch_cache_init(ob, cfra);
- }
- else {
- return cache;
- }
+ bGPdata *gpd = (bGPdata *)ob->data;
+
+ GpencilBatchCache *cache = gpencil_batch_get_element(ob);
+ if (!gpencil_batch_cache_valid(cache, gpd, cfra)) {
+ if (cache) {
+ gpencil_batch_cache_clear(cache);
+ }
+ return gpencil_batch_cache_init(ob, cfra);
+ }
+ else {
+ return cache;
+ }
}
/* set cache as dirty */
void DRW_gpencil_batch_cache_dirty_tag(bGPdata *gpd)
{
- gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+ gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
}
/* free batch cache */
void DRW_gpencil_batch_cache_free(bGPdata *UNUSED(gpd))
{
- return;
+ return;
}
/* wrapper to clear cache */
void DRW_gpencil_freecache(struct Object *ob)
{
- if ((ob) && (ob->type == OB_GPENCIL)) {
- gpencil_batch_cache_clear(ob->runtime.gpencil_cache);
- MEM_SAFE_FREE(ob->runtime.gpencil_cache);
- bGPdata *gpd = (bGPdata *)ob->data;
- if (gpd) {
- gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
- }
- }
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ gpencil_batch_cache_clear(ob->runtime.gpencil_cache);
+ MEM_SAFE_FREE(ob->runtime.gpencil_cache);
+ bGPdata *gpd = (bGPdata *)ob->data;
+ if (gpd) {
+ gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+ }
+ }
}
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 3bcc963c966..9e71791fbf3 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -34,7 +34,6 @@
#include "DRW_render.h"
-
#include "ED_gpencil.h"
#include "ED_view3d.h"
@@ -43,776 +42,873 @@
#include "gpencil_engine.h"
/* Helper to add stroke point to vbo */
-static void gpencil_set_stroke_point(
- GPUVertBuf *vbo, const bGPDspoint *pt, int idx,
- uint pos_id, uint color_id,
- uint thickness_id, uint uvdata_id, short thickness,
- const float ink[4])
+static void gpencil_set_stroke_point(GPUVertBuf *vbo,
+ const bGPDspoint *pt,
+ int idx,
+ uint pos_id,
+ uint color_id,
+ uint thickness_id,
+ uint uvdata_id,
+ short thickness,
+ const float ink[4])
{
- float alpha = ink[3] * pt->strength;
- CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
- float col[4];
- ARRAY_SET_ITEMS(col, ink[0], ink[1], ink[2], alpha);
+ float alpha = ink[3] * pt->strength;
+ CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
+ float col[4];
+ ARRAY_SET_ITEMS(col, ink[0], ink[1], ink[2], alpha);
- GPU_vertbuf_attr_set(vbo, color_id, idx, col);
+ GPU_vertbuf_attr_set(vbo, color_id, idx, col);
- /* transfer both values using the same shader variable */
- float uvdata[2] = { pt->uv_fac, pt->uv_rot };
- GPU_vertbuf_attr_set(vbo, uvdata_id, idx, uvdata);
+ /* transfer both values using the same shader variable */
+ float uvdata[2] = {pt->uv_fac, pt->uv_rot};
+ GPU_vertbuf_attr_set(vbo, uvdata_id, idx, uvdata);
- /* the thickness of the stroke must be affected by zoom, so a pixel scale is calculated */
- float thick = max_ff(pt->pressure * thickness, 1.0f);
- GPU_vertbuf_attr_set(vbo, thickness_id, idx, &thick);
+ /* the thickness of the stroke must be affected by zoom, so a pixel scale is calculated */
+ float thick = max_ff(pt->pressure * thickness, 1.0f);
+ GPU_vertbuf_attr_set(vbo, thickness_id, idx, &thick);
- GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x);
+ GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x);
}
/* Helper to add a new fill point and texture coordinates to vertex buffer */
-static void gpencil_set_fill_point(
- GPUVertBuf *vbo, int idx, bGPDspoint *pt, const float fcolor[4], float uv[2],
- uint pos_id, uint color_id, uint text_id)
+static void gpencil_set_fill_point(GPUVertBuf *vbo,
+ int idx,
+ bGPDspoint *pt,
+ const float fcolor[4],
+ float uv[2],
+ uint pos_id,
+ uint color_id,
+ uint text_id)
{
- GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x);
- GPU_vertbuf_attr_set(vbo, color_id, idx, fcolor);
- GPU_vertbuf_attr_set(vbo, text_id, idx, uv);
+ GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt->x);
+ GPU_vertbuf_attr_set(vbo, color_id, idx, fcolor);
+ GPU_vertbuf_attr_set(vbo, text_id, idx, uv);
}
static void gpencil_vbo_ensure_size(GpencilBatchCacheElem *be, int totvertex)
{
- if (be->vbo->vertex_alloc <= be->vbo_len + totvertex) {
- uint newsize = be->vbo->vertex_alloc + (((totvertex / GPENCIL_VBO_BLOCK_SIZE) + 1) * GPENCIL_VBO_BLOCK_SIZE);
- GPU_vertbuf_data_resize(be->vbo, newsize);
- }
+ if (be->vbo->vertex_alloc <= be->vbo_len + totvertex) {
+ uint newsize = be->vbo->vertex_alloc +
+ (((totvertex / GPENCIL_VBO_BLOCK_SIZE) + 1) * GPENCIL_VBO_BLOCK_SIZE);
+ GPU_vertbuf_data_resize(be->vbo, newsize);
+ }
}
/* create batch geometry data for points stroke shader */
-void DRW_gpencil_get_point_geom(GpencilBatchCacheElem *be, bGPDstroke *gps, short thickness, const float ink[4])
+void DRW_gpencil_get_point_geom(GpencilBatchCacheElem *be,
+ bGPDstroke *gps,
+ short thickness,
+ const float ink[4])
{
- int totvertex = gps->totpoints;
- if (be->vbo == NULL) {
- be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- be->thickness_id = GPU_vertformat_attr_add(&be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
- be->uvdata_id = GPU_vertformat_attr_add(&be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- be->prev_pos_id = GPU_vertformat_attr_add(&be->format, "prev_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
-
- be->vbo = GPU_vertbuf_create_with_format(&be->format);
- GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
- be->vbo_len = 0;
- }
- gpencil_vbo_ensure_size(be, totvertex);
-
- /* draw stroke curve */
- const bGPDspoint *pt = gps->points;
- float alpha;
- float col[4];
-
- for (int i = 0; i < gps->totpoints; i++, pt++) {
- /* set point */
- alpha = ink[3] * pt->strength;
- CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
- ARRAY_SET_ITEMS(col, ink[0], ink[1], ink[2], alpha);
-
- float thick = max_ff(pt->pressure * thickness, 1.0f);
-
- GPU_vertbuf_attr_set(be->vbo, be->color_id, be->vbo_len, col);
- GPU_vertbuf_attr_set(be->vbo, be->thickness_id, be->vbo_len, &thick);
-
- /* transfer both values using the same shader variable */
- float uvdata[2] = { pt->uv_fac, pt->uv_rot };
- GPU_vertbuf_attr_set(be->vbo, be->uvdata_id, be->vbo_len, uvdata);
-
- GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x);
-
- /* use previous point to determine stroke direction */
- bGPDspoint *pt2 = NULL;
- if (i == 0) {
- if (gps->totpoints > 1) {
- /* extrapolate a point before first point */
- float fpt[3];
- pt2 = &gps->points[1];
- interp_v3_v3v3(fpt, &pt2->x, &pt->x, 1.5f);
- GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt);
- }
- else {
- GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, &pt->x);
- }
- }
- else {
- pt2 = &gps->points[i - 1];
- GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, &pt2->x);
- }
-
- be->vbo_len++;
- }
+ int totvertex = gps->totpoints;
+ if (be->vbo == NULL) {
+ be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ be->thickness_id = GPU_vertformat_attr_add(
+ &be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ be->uvdata_id = GPU_vertformat_attr_add(
+ &be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ be->prev_pos_id = GPU_vertformat_attr_add(
+ &be->format, "prev_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+
+ be->vbo = GPU_vertbuf_create_with_format(&be->format);
+ GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
+ be->vbo_len = 0;
+ }
+ gpencil_vbo_ensure_size(be, totvertex);
+
+ /* draw stroke curve */
+ const bGPDspoint *pt = gps->points;
+ float alpha;
+ float col[4];
+
+ for (int i = 0; i < gps->totpoints; i++, pt++) {
+ /* set point */
+ alpha = ink[3] * pt->strength;
+ CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
+ ARRAY_SET_ITEMS(col, ink[0], ink[1], ink[2], alpha);
+
+ float thick = max_ff(pt->pressure * thickness, 1.0f);
+
+ GPU_vertbuf_attr_set(be->vbo, be->color_id, be->vbo_len, col);
+ GPU_vertbuf_attr_set(be->vbo, be->thickness_id, be->vbo_len, &thick);
+
+ /* transfer both values using the same shader variable */
+ float uvdata[2] = {pt->uv_fac, pt->uv_rot};
+ GPU_vertbuf_attr_set(be->vbo, be->uvdata_id, be->vbo_len, uvdata);
+
+ GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x);
+
+ /* use previous point to determine stroke direction */
+ bGPDspoint *pt2 = NULL;
+ if (i == 0) {
+ if (gps->totpoints > 1) {
+ /* extrapolate a point before first point */
+ float fpt[3];
+ pt2 = &gps->points[1];
+ interp_v3_v3v3(fpt, &pt2->x, &pt->x, 1.5f);
+ GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt);
+ }
+ else {
+ GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, &pt->x);
+ }
+ }
+ else {
+ pt2 = &gps->points[i - 1];
+ GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, &pt2->x);
+ }
+
+ be->vbo_len++;
+ }
}
/* create batch geometry data for stroke shader */
-void DRW_gpencil_get_stroke_geom(struct GpencilBatchCacheElem *be, bGPDstroke *gps, short thickness, const float ink[4])
+void DRW_gpencil_get_stroke_geom(struct GpencilBatchCacheElem *be,
+ bGPDstroke *gps,
+ short thickness,
+ const float ink[4])
{
- bGPDspoint *points = gps->points;
- int totpoints = gps->totpoints;
- /* if cyclic needs more vertex */
- int cyclic_add = (gps->flag & GP_STROKE_CYCLIC) ? 1 : 0;
- int totvertex = totpoints + cyclic_add + 2;
-
- if (be->vbo == NULL) {
- be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- be->thickness_id = GPU_vertformat_attr_add(&be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
- be->uvdata_id = GPU_vertformat_attr_add(&be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- be->vbo = GPU_vertbuf_create_with_format(&be->format);
- GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
- be->vbo_len = 0;
- }
- gpencil_vbo_ensure_size(be, totvertex);
-
- /* draw stroke curve */
- const bGPDspoint *pt = points;
- for (int i = 0; i < totpoints; i++, pt++) {
- /* first point for adjacency (not drawn) */
- if (i == 0) {
- if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) {
- gpencil_set_stroke_point(
- be->vbo, &points[totpoints - 1], be->vbo_len,
- be->pos_id, be->color_id, be->thickness_id, be->uvdata_id, thickness, ink);
- be->vbo_len++;
- }
- else {
- gpencil_set_stroke_point(
- be->vbo, &points[1], be->vbo_len,
- be->pos_id, be->color_id, be->thickness_id, be->uvdata_id, thickness, ink);
- be->vbo_len++;
- }
- }
- /* set point */
- gpencil_set_stroke_point(
- be->vbo, pt, be->vbo_len,
- be->pos_id, be->color_id, be->thickness_id, be->uvdata_id, thickness, ink);
- be->vbo_len++;
- }
-
- if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) {
- /* draw line to first point to complete the cycle */
- gpencil_set_stroke_point(
- be->vbo, &points[0], be->vbo_len,
- be->pos_id, be->color_id, be->thickness_id, be->uvdata_id, thickness, ink);
- be->vbo_len++;
- /* now add adjacency point (not drawn) */
- gpencil_set_stroke_point(
- be->vbo, &points[1], be->vbo_len,
- be->pos_id, be->color_id, be->thickness_id, be->uvdata_id, thickness, ink);
- be->vbo_len++;
- }
- /* last adjacency point (not drawn) */
- else {
- gpencil_set_stroke_point(
- be->vbo, &points[totpoints - 2], be->vbo_len,
- be->pos_id, be->color_id, be->thickness_id, be->uvdata_id, thickness, ink);
- be->vbo_len++;
- }
+ bGPDspoint *points = gps->points;
+ int totpoints = gps->totpoints;
+ /* if cyclic needs more vertex */
+ int cyclic_add = (gps->flag & GP_STROKE_CYCLIC) ? 1 : 0;
+ int totvertex = totpoints + cyclic_add + 2;
+
+ if (be->vbo == NULL) {
+ be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ be->thickness_id = GPU_vertformat_attr_add(
+ &be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ be->uvdata_id = GPU_vertformat_attr_add(
+ &be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ be->vbo = GPU_vertbuf_create_with_format(&be->format);
+ GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
+ be->vbo_len = 0;
+ }
+ gpencil_vbo_ensure_size(be, totvertex);
+
+ /* draw stroke curve */
+ const bGPDspoint *pt = points;
+ for (int i = 0; i < totpoints; i++, pt++) {
+ /* first point for adjacency (not drawn) */
+ if (i == 0) {
+ if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) {
+ gpencil_set_stroke_point(be->vbo,
+ &points[totpoints - 1],
+ be->vbo_len,
+ be->pos_id,
+ be->color_id,
+ be->thickness_id,
+ be->uvdata_id,
+ thickness,
+ ink);
+ be->vbo_len++;
+ }
+ else {
+ gpencil_set_stroke_point(be->vbo,
+ &points[1],
+ be->vbo_len,
+ be->pos_id,
+ be->color_id,
+ be->thickness_id,
+ be->uvdata_id,
+ thickness,
+ ink);
+ be->vbo_len++;
+ }
+ }
+ /* set point */
+ gpencil_set_stroke_point(be->vbo,
+ pt,
+ be->vbo_len,
+ be->pos_id,
+ be->color_id,
+ be->thickness_id,
+ be->uvdata_id,
+ thickness,
+ ink);
+ be->vbo_len++;
+ }
+
+ if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) {
+ /* draw line to first point to complete the cycle */
+ gpencil_set_stroke_point(be->vbo,
+ &points[0],
+ be->vbo_len,
+ be->pos_id,
+ be->color_id,
+ be->thickness_id,
+ be->uvdata_id,
+ thickness,
+ ink);
+ be->vbo_len++;
+ /* now add adjacency point (not drawn) */
+ gpencil_set_stroke_point(be->vbo,
+ &points[1],
+ be->vbo_len,
+ be->pos_id,
+ be->color_id,
+ be->thickness_id,
+ be->uvdata_id,
+ thickness,
+ ink);
+ be->vbo_len++;
+ }
+ /* last adjacency point (not drawn) */
+ else {
+ gpencil_set_stroke_point(be->vbo,
+ &points[totpoints - 2],
+ be->vbo_len,
+ be->pos_id,
+ be->color_id,
+ be->thickness_id,
+ be->uvdata_id,
+ thickness,
+ ink);
+ be->vbo_len++;
+ }
}
/* create batch geometry data for stroke shader */
-void DRW_gpencil_get_fill_geom(struct GpencilBatchCacheElem *be, Object *ob, bGPDstroke *gps, const float color[4])
+void DRW_gpencil_get_fill_geom(struct GpencilBatchCacheElem *be,
+ Object *ob,
+ bGPDstroke *gps,
+ const float color[4])
{
- BLI_assert(gps->totpoints >= 3);
-
- /* Calculate triangles cache for filling area (must be done only after changes) */
- if ((gps->flag & GP_STROKE_RECALC_GEOMETRY) || (gps->tot_triangles == 0) || (gps->triangles == NULL)) {
- DRW_gpencil_triangulate_stroke_fill(ob, gps);
- }
-
- BLI_assert(gps->tot_triangles >= 1);
- int totvertex = gps->tot_triangles * 3;
-
- if (be->vbo == NULL) {
- be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- be->uvdata_id = GPU_vertformat_attr_add(&be->format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- be->vbo = GPU_vertbuf_create_with_format(&be->format);
- GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
- be->vbo_len = 0;
- }
- gpencil_vbo_ensure_size(be, totvertex);
-
- /* Draw all triangles for filling the polygon (cache must be calculated before) */
- bGPDtriangle *stroke_triangle = gps->triangles;
- for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) {
- for (int j = 0; j < 3; j++) {
- gpencil_set_fill_point(
- be->vbo, be->vbo_len, &gps->points[stroke_triangle->verts[j]], color, stroke_triangle->uv[j],
- be->pos_id, be->color_id, be->uvdata_id);
- be->vbo_len++;
- }
- }
+ BLI_assert(gps->totpoints >= 3);
+
+ /* Calculate triangles cache for filling area (must be done only after changes) */
+ if ((gps->flag & GP_STROKE_RECALC_GEOMETRY) || (gps->tot_triangles == 0) ||
+ (gps->triangles == NULL)) {
+ DRW_gpencil_triangulate_stroke_fill(ob, gps);
+ }
+
+ BLI_assert(gps->tot_triangles >= 1);
+ int totvertex = gps->tot_triangles * 3;
+
+ if (be->vbo == NULL) {
+ be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ be->uvdata_id = GPU_vertformat_attr_add(
+ &be->format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ be->vbo = GPU_vertbuf_create_with_format(&be->format);
+ GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
+ be->vbo_len = 0;
+ }
+ gpencil_vbo_ensure_size(be, totvertex);
+
+ /* Draw all triangles for filling the polygon (cache must be calculated before) */
+ bGPDtriangle *stroke_triangle = gps->triangles;
+ for (int i = 0; i < gps->tot_triangles; i++, stroke_triangle++) {
+ for (int j = 0; j < 3; j++) {
+ gpencil_set_fill_point(be->vbo,
+ be->vbo_len,
+ &gps->points[stroke_triangle->verts[j]],
+ color,
+ stroke_triangle->uv[j],
+ be->pos_id,
+ be->color_id,
+ be->uvdata_id);
+ be->vbo_len++;
+ }
+ }
}
/* create batch geometry data for current buffer stroke shader */
GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, short thickness)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- ARegion *ar = draw_ctx->ar;
- RegionView3D *rv3d = draw_ctx->rv3d;
- ToolSettings *ts = scene->toolsettings;
- Object *ob = draw_ctx->obact;
-
- tGPspoint *points = gpd->runtime.sbuffer;
- int totpoints = gpd->runtime.sbuffer_size;
- /* if cyclic needs more vertex */
- int cyclic_add = (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC) ? 1 : 0;
- int totvertex = totpoints + cyclic_add + 2;
-
- static GPUVertFormat format = { 0 };
- static uint pos_id, color_id, thickness_id, uvdata_id;
- if (format.attr_len == 0) {
- pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- thickness_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
- uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- }
-
- GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(vbo, totvertex);
-
- /* draw stroke curve */
- const tGPspoint *tpt = points;
- bGPDspoint pt, pt2, pt3;
- int idx = 0;
-
- /* get origin to reproject point */
- float origin[3];
- bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
- ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin);
-
- for (int i = 0; i < totpoints; i++, tpt++) {
- ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt);
- ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt);
-
- /* first point for adjacency (not drawn) */
- if (i == 0) {
- if (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC && totpoints > 2) {
- ED_gpencil_tpoint_to_point(ar, origin, &points[totpoints - 1], &pt2);
- gpencil_set_stroke_point(
- vbo, &pt2, idx,
- pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
- idx++;
- }
- else {
- ED_gpencil_tpoint_to_point(ar, origin, &points[1], &pt2);
- gpencil_set_stroke_point(
- vbo, &pt2, idx,
- pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
- idx++;
- }
- }
-
- /* set point */
- gpencil_set_stroke_point(
- vbo, &pt, idx,
- pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
- idx++;
- }
-
- /* last adjacency point (not drawn) */
- if (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC && totpoints > 2) {
- /* draw line to first point to complete the cycle */
- ED_gpencil_tpoint_to_point(ar, origin, &points[0], &pt2);
- gpencil_set_stroke_point(
- vbo, &pt2, idx,
- pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
- idx++;
- /* now add adjacency point (not drawn) */
- ED_gpencil_tpoint_to_point(ar, origin, &points[1], &pt3);
- gpencil_set_stroke_point(
- vbo, &pt3, idx,
- pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
- idx++;
- }
- /* last adjacency point (not drawn) */
- else {
- ED_gpencil_tpoint_to_point(ar, origin, &points[totpoints - 2], &pt2);
- gpencil_set_stroke_point(
- vbo, &pt2, idx,
- pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
- idx++;
- }
-
- return GPU_batch_create_ex(GPU_PRIM_LINE_STRIP_ADJ, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ ARegion *ar = draw_ctx->ar;
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ ToolSettings *ts = scene->toolsettings;
+ Object *ob = draw_ctx->obact;
+
+ tGPspoint *points = gpd->runtime.sbuffer;
+ int totpoints = gpd->runtime.sbuffer_size;
+ /* if cyclic needs more vertex */
+ int cyclic_add = (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC) ? 1 : 0;
+ int totvertex = totpoints + cyclic_add + 2;
+
+ static GPUVertFormat format = {0};
+ static uint pos_id, color_id, thickness_id, uvdata_id;
+ if (format.attr_len == 0) {
+ pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ thickness_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ }
+
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, totvertex);
+
+ /* draw stroke curve */
+ const tGPspoint *tpt = points;
+ bGPDspoint pt, pt2, pt3;
+ int idx = 0;
+
+ /* get origin to reproject point */
+ float origin[3];
+ bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
+ ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin);
+
+ for (int i = 0; i < totpoints; i++, tpt++) {
+ ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt);
+ ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt);
+
+ /* first point for adjacency (not drawn) */
+ if (i == 0) {
+ if (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC && totpoints > 2) {
+ ED_gpencil_tpoint_to_point(ar, origin, &points[totpoints - 1], &pt2);
+ gpencil_set_stroke_point(vbo,
+ &pt2,
+ idx,
+ pos_id,
+ color_id,
+ thickness_id,
+ uvdata_id,
+ thickness,
+ gpd->runtime.scolor);
+ idx++;
+ }
+ else {
+ ED_gpencil_tpoint_to_point(ar, origin, &points[1], &pt2);
+ gpencil_set_stroke_point(vbo,
+ &pt2,
+ idx,
+ pos_id,
+ color_id,
+ thickness_id,
+ uvdata_id,
+ thickness,
+ gpd->runtime.scolor);
+ idx++;
+ }
+ }
+
+ /* set point */
+ gpencil_set_stroke_point(
+ vbo, &pt, idx, pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ idx++;
+ }
+
+ /* last adjacency point (not drawn) */
+ if (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC && totpoints > 2) {
+ /* draw line to first point to complete the cycle */
+ ED_gpencil_tpoint_to_point(ar, origin, &points[0], &pt2);
+ gpencil_set_stroke_point(
+ vbo, &pt2, idx, pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ idx++;
+ /* now add adjacency point (not drawn) */
+ ED_gpencil_tpoint_to_point(ar, origin, &points[1], &pt3);
+ gpencil_set_stroke_point(
+ vbo, &pt3, idx, pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ idx++;
+ }
+ /* last adjacency point (not drawn) */
+ else {
+ ED_gpencil_tpoint_to_point(ar, origin, &points[totpoints - 2], &pt2);
+ gpencil_set_stroke_point(
+ vbo, &pt2, idx, pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ idx++;
+ }
+
+ return GPU_batch_create_ex(GPU_PRIM_LINE_STRIP_ADJ, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
/* create batch geometry data for current buffer point shader */
GPUBatch *DRW_gpencil_get_buffer_point_geom(bGPdata *gpd, short thickness)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- ARegion *ar = draw_ctx->ar;
- RegionView3D *rv3d = draw_ctx->rv3d;
- ToolSettings *ts = scene->toolsettings;
- Object *ob = draw_ctx->obact;
-
- tGPspoint *points = gpd->runtime.sbuffer;
- int totpoints = gpd->runtime.sbuffer_size;
-
- static GPUVertFormat format = { 0 };
- static uint pos_id, color_id, thickness_id, uvdata_id;
- if (format.attr_len == 0) {
- pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- thickness_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
- uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- }
-
- GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(vbo, totpoints);
-
- /* draw stroke curve */
- const tGPspoint *tpt = points;
- bGPDspoint pt;
- int idx = 0;
-
- /* get origin to reproject point */
- float origin[3];
- bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
- ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin);
-
- for (int i = 0; i < totpoints; i++, tpt++) {
- ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt);
- ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt);
-
- /* set point */
- gpencil_set_stroke_point(
- vbo, &pt, idx,
- pos_id, color_id, thickness_id, uvdata_id,
- thickness, gpd->runtime.scolor);
- idx++;
- }
-
- return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ ARegion *ar = draw_ctx->ar;
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ ToolSettings *ts = scene->toolsettings;
+ Object *ob = draw_ctx->obact;
+
+ tGPspoint *points = gpd->runtime.sbuffer;
+ int totpoints = gpd->runtime.sbuffer_size;
+
+ static GPUVertFormat format = {0};
+ static uint pos_id, color_id, thickness_id, uvdata_id;
+ if (format.attr_len == 0) {
+ pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ thickness_id = GPU_vertformat_attr_add(&format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uvdata_id = GPU_vertformat_attr_add(&format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ }
+
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, totpoints);
+
+ /* draw stroke curve */
+ const tGPspoint *tpt = points;
+ bGPDspoint pt;
+ int idx = 0;
+
+ /* get origin to reproject point */
+ float origin[3];
+ bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
+ ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin);
+
+ for (int i = 0; i < totpoints; i++, tpt++) {
+ ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt);
+ ED_gp_project_point_to_plane(scene, ob, rv3d, origin, ts->gp_sculpt.lock_axis - 1, &pt);
+
+ /* set point */
+ gpencil_set_stroke_point(
+ vbo, &pt, idx, pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
+ idx++;
+ }
+
+ return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
/* create batch geometry data for current buffer control point shader */
GPUBatch *DRW_gpencil_get_buffer_ctrlpoint_geom(bGPdata *gpd)
{
- bGPDcontrolpoint *cps = gpd->runtime.cp_points;
- int totpoints = gpd->runtime.tot_cp_points;
-
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- ToolSettings *ts = scene->toolsettings;
-
- if (ts->gp_sculpt.guide.use_guide) {
- totpoints++;
- }
-
- static GPUVertFormat format = { 0 };
- static uint pos_id, color_id, size_id;
- if (format.attr_len == 0) {
- pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- size_id = GPU_vertformat_attr_add(&format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
- color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- }
-
- GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(vbo, totpoints);
-
- int idx = 0;
- for (int i = 0; i < gpd->runtime.tot_cp_points; i++) {
- bGPDcontrolpoint *cp = &cps[i];
-
- GPU_vertbuf_attr_set(vbo, color_id, idx, cp->color);
-
- /* scale size */
- float size = cp->size * 0.8f;
- GPU_vertbuf_attr_set(vbo, size_id, idx, &size);
-
- GPU_vertbuf_attr_set(vbo, pos_id, idx, &cp->x);
- idx++;
- }
-
- if (ts->gp_sculpt.guide.use_guide) {
- float size = 10 * 0.8f;
- float color[4];
- float position[3];
- if (ts->gp_sculpt.guide.reference_point == GP_GUIDE_REF_CUSTOM) {
- UI_GetThemeColor4fv(TH_GIZMO_PRIMARY, color);
- copy_v3_v3(position, ts->gp_sculpt.guide.location);
- }
- else if (ts->gp_sculpt.guide.reference_point == GP_GUIDE_REF_OBJECT && ts->gp_sculpt.guide.reference_object != NULL) {
- UI_GetThemeColor4fv(TH_GIZMO_SECONDARY, color);
- copy_v3_v3(position, ts->gp_sculpt.guide.reference_object->loc);
- }
- else {
- UI_GetThemeColor4fv(TH_REDALERT, color);
- copy_v3_v3(position, scene->cursor.location);
- }
- GPU_vertbuf_attr_set(vbo, pos_id, idx, position);
- GPU_vertbuf_attr_set(vbo, size_id, idx, &size);
- GPU_vertbuf_attr_set(vbo, color_id, idx, color);
- }
-
- return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ bGPDcontrolpoint *cps = gpd->runtime.cp_points;
+ int totpoints = gpd->runtime.tot_cp_points;
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ ToolSettings *ts = scene->toolsettings;
+
+ if (ts->gp_sculpt.guide.use_guide) {
+ totpoints++;
+ }
+
+ static GPUVertFormat format = {0};
+ static uint pos_id, color_id, size_id;
+ if (format.attr_len == 0) {
+ pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ size_id = GPU_vertformat_attr_add(&format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ }
+
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, totpoints);
+
+ int idx = 0;
+ for (int i = 0; i < gpd->runtime.tot_cp_points; i++) {
+ bGPDcontrolpoint *cp = &cps[i];
+
+ GPU_vertbuf_attr_set(vbo, color_id, idx, cp->color);
+
+ /* scale size */
+ float size = cp->size * 0.8f;
+ GPU_vertbuf_attr_set(vbo, size_id, idx, &size);
+
+ GPU_vertbuf_attr_set(vbo, pos_id, idx, &cp->x);
+ idx++;
+ }
+
+ if (ts->gp_sculpt.guide.use_guide) {
+ float size = 10 * 0.8f;
+ float color[4];
+ float position[3];
+ if (ts->gp_sculpt.guide.reference_point == GP_GUIDE_REF_CUSTOM) {
+ UI_GetThemeColor4fv(TH_GIZMO_PRIMARY, color);
+ copy_v3_v3(position, ts->gp_sculpt.guide.location);
+ }
+ else if (ts->gp_sculpt.guide.reference_point == GP_GUIDE_REF_OBJECT &&
+ ts->gp_sculpt.guide.reference_object != NULL) {
+ UI_GetThemeColor4fv(TH_GIZMO_SECONDARY, color);
+ copy_v3_v3(position, ts->gp_sculpt.guide.reference_object->loc);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_REDALERT, color);
+ copy_v3_v3(position, scene->cursor.location);
+ }
+ GPU_vertbuf_attr_set(vbo, pos_id, idx, position);
+ GPU_vertbuf_attr_set(vbo, size_id, idx, &size);
+ GPU_vertbuf_attr_set(vbo, color_id, idx, color);
+ }
+
+ return GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
/* create batch geometry data for current buffer fill shader */
GPUBatch *DRW_gpencil_get_buffer_fill_geom(bGPdata *gpd)
{
- if (gpd == NULL) {
- return NULL;
- }
-
- const tGPspoint *points = gpd->runtime.sbuffer;
- int totpoints = gpd->runtime.sbuffer_size;
- if (totpoints < 3) {
- return NULL;
- }
-
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- ARegion *ar = draw_ctx->ar;
- ToolSettings *ts = scene->toolsettings;
- Object *ob = draw_ctx->obact;
-
- /* get origin to reproject point */
- float origin[3];
- bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
- ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin);
-
- int tot_triangles = totpoints - 2;
- /* allocate memory for temporary areas */
- uint (*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, __func__);
- float (*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, __func__);
-
- /* 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(points2d, (uint)totpoints, 0, tmp_triangles);
-
- static GPUVertFormat format = { 0 };
- static uint pos_id, color_id;
- if (format.attr_len == 0) {
- pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- }
-
- GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
-
- /* draw triangulation data */
- if (tot_triangles > 0) {
- GPU_vertbuf_data_alloc(vbo, tot_triangles * 3);
-
- const tGPspoint *tpt;
- bGPDspoint pt;
-
- int idx = 0;
- for (int i = 0; i < tot_triangles; i++) {
- for (int j = 0; j < 3; j++) {
- tpt = &points[tmp_triangles[i][j]];
- ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt);
- GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt.x);
- GPU_vertbuf_attr_set(vbo, color_id, idx, gpd->runtime.sfill);
- idx++;
- }
- }
- }
-
- /* clear memory */
- if (tmp_triangles) {
- MEM_freeN(tmp_triangles);
- }
- if (points2d) {
- MEM_freeN(points2d);
- }
-
- return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ if (gpd == NULL) {
+ return NULL;
+ }
+
+ const tGPspoint *points = gpd->runtime.sbuffer;
+ int totpoints = gpd->runtime.sbuffer_size;
+ if (totpoints < 3) {
+ return NULL;
+ }
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ ARegion *ar = draw_ctx->ar;
+ ToolSettings *ts = scene->toolsettings;
+ Object *ob = draw_ctx->obact;
+
+ /* get origin to reproject point */
+ float origin[3];
+ bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd);
+ ED_gp_get_drawing_reference(scene, ob, gpl, ts->gpencil_v3d_align, origin);
+
+ int tot_triangles = totpoints - 2;
+ /* allocate memory for temporary areas */
+ uint(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, __func__);
+ float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, __func__);
+
+ /* 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(points2d, (uint)totpoints, 0, tmp_triangles);
+
+ static GPUVertFormat format = {0};
+ static uint pos_id, color_id;
+ if (format.attr_len == 0) {
+ pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ }
+
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+
+ /* draw triangulation data */
+ if (tot_triangles > 0) {
+ GPU_vertbuf_data_alloc(vbo, tot_triangles * 3);
+
+ const tGPspoint *tpt;
+ bGPDspoint pt;
+
+ int idx = 0;
+ for (int i = 0; i < tot_triangles; i++) {
+ for (int j = 0; j < 3; j++) {
+ tpt = &points[tmp_triangles[i][j]];
+ ED_gpencil_tpoint_to_point(ar, origin, tpt, &pt);
+ GPU_vertbuf_attr_set(vbo, pos_id, idx, &pt.x);
+ GPU_vertbuf_attr_set(vbo, color_id, idx, gpd->runtime.sfill);
+ idx++;
+ }
+ }
+ }
+
+ /* clear memory */
+ if (tmp_triangles) {
+ MEM_freeN(tmp_triangles);
+ }
+ if (points2d) {
+ MEM_freeN(points2d);
+ }
+
+ return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
/* Draw selected verts for strokes being edited */
-void DRW_gpencil_get_edit_geom(struct GpencilBatchCacheElem *be, bGPDstroke *gps, float alpha, short dflag)
+void DRW_gpencil_get_edit_geom(struct GpencilBatchCacheElem *be,
+ bGPDstroke *gps,
+ float alpha,
+ short dflag)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Object *ob = draw_ctx->obact;
- bGPdata *gpd = ob->data;
- const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE);
-
- int vgindex = ob->actdef - 1;
- if (!BLI_findlink(&ob->defbase, vgindex)) {
- vgindex = -1;
- }
-
- /* Get size of verts:
- * - The selected state needs to be larger than the unselected state so that
- * they stand out more.
- * - We use the theme setting for size of the unselected verts
- */
- float bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE);
- float vsize;
- if ((int)bsize > 8) {
- vsize = 10.0f;
- bsize = 8.0f;
- }
- else {
- vsize = bsize + 2;
- }
-
- /* for now, we assume that the base color of the points is not too close to the real color */
- float selectColor[4];
- UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor);
- selectColor[3] = alpha;
-
- float unselectColor[4];
- UI_GetThemeColor3fv(TH_GP_VERTEX, unselectColor);
- unselectColor[3] = alpha;
-
- if (be->vbo == NULL) {
- be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- be->thickness_id = GPU_vertformat_attr_add(&be->format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
-
- be->vbo = GPU_vertbuf_create_with_format(&be->format);
- GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
- be->vbo_len = 0;
- }
- gpencil_vbo_ensure_size(be, gps->totpoints);
-
- /* Draw start and end point differently if enabled stroke direction hint */
- bool show_direction_hint = (dflag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1);
-
- /* Draw all the stroke points (selected or not) */
- bGPDspoint *pt = gps->points;
- MDeformVert *dvert = gps->dvert;
-
- float fcolor[4];
- float fsize = 0;
- for (int i = 0; i < gps->totpoints; i++, pt++) {
- /* weight paint */
- if (is_weight_paint) {
- float weight = (dvert && dvert->dw && (vgindex > -1)) ? defvert_find_weight(dvert, vgindex) : 0.0f;
- float hue = 2.0f * (1.0f - weight) / 3.0f;
- hsv_to_rgb(hue, 1.0f, 1.0f, &selectColor[0], &selectColor[1], &selectColor[2]);
- selectColor[3] = 1.0f;
- copy_v4_v4(fcolor, selectColor);
- fsize = vsize;
- }
- else {
- if (show_direction_hint && i == 0) {
- /* start point in green bigger */
- ARRAY_SET_ITEMS(fcolor, 0.0f, 1.0f, 0.0f, 1.0f);
- fsize = vsize + 4;
- }
- else if (show_direction_hint && (i == gps->totpoints - 1)) {
- /* end point in red smaller */
- ARRAY_SET_ITEMS(fcolor, 1.0f, 0.0f, 0.0f, 1.0f);
- fsize = vsize + 1;
- }
- else if (pt->flag & GP_SPOINT_SELECT) {
- copy_v4_v4(fcolor, selectColor);
- fsize = vsize;
- }
- else {
- copy_v4_v4(fcolor, unselectColor);
- fsize = bsize;
- }
- }
-
- GPU_vertbuf_attr_set(be->vbo, be->color_id, be->vbo_len, fcolor);
- GPU_vertbuf_attr_set(be->vbo, be->thickness_id, be->vbo_len, &fsize);
- GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x);
- be->vbo_len++;
- if (gps->dvert != NULL) {
- dvert++;
- }
- }
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Object *ob = draw_ctx->obact;
+ bGPdata *gpd = ob->data;
+ const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE);
+
+ int vgindex = ob->actdef - 1;
+ if (!BLI_findlink(&ob->defbase, vgindex)) {
+ vgindex = -1;
+ }
+
+ /* Get size of verts:
+ * - The selected state needs to be larger than the unselected state so that
+ * they stand out more.
+ * - We use the theme setting for size of the unselected verts
+ */
+ float bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE);
+ float vsize;
+ if ((int)bsize > 8) {
+ vsize = 10.0f;
+ bsize = 8.0f;
+ }
+ else {
+ vsize = bsize + 2;
+ }
+
+ /* for now, we assume that the base color of the points is not too close to the real color */
+ float selectColor[4];
+ UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor);
+ selectColor[3] = alpha;
+
+ float unselectColor[4];
+ UI_GetThemeColor3fv(TH_GP_VERTEX, unselectColor);
+ unselectColor[3] = alpha;
+
+ if (be->vbo == NULL) {
+ be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ be->thickness_id = GPU_vertformat_attr_add(
+ &be->format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+
+ be->vbo = GPU_vertbuf_create_with_format(&be->format);
+ GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
+ be->vbo_len = 0;
+ }
+ gpencil_vbo_ensure_size(be, gps->totpoints);
+
+ /* Draw start and end point differently if enabled stroke direction hint */
+ bool show_direction_hint = (dflag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1);
+
+ /* Draw all the stroke points (selected or not) */
+ bGPDspoint *pt = gps->points;
+ MDeformVert *dvert = gps->dvert;
+
+ float fcolor[4];
+ float fsize = 0;
+ for (int i = 0; i < gps->totpoints; i++, pt++) {
+ /* weight paint */
+ if (is_weight_paint) {
+ float weight = (dvert && dvert->dw && (vgindex > -1)) ? defvert_find_weight(dvert, vgindex) :
+ 0.0f;
+ float hue = 2.0f * (1.0f - weight) / 3.0f;
+ hsv_to_rgb(hue, 1.0f, 1.0f, &selectColor[0], &selectColor[1], &selectColor[2]);
+ selectColor[3] = 1.0f;
+ copy_v4_v4(fcolor, selectColor);
+ fsize = vsize;
+ }
+ else {
+ if (show_direction_hint && i == 0) {
+ /* start point in green bigger */
+ ARRAY_SET_ITEMS(fcolor, 0.0f, 1.0f, 0.0f, 1.0f);
+ fsize = vsize + 4;
+ }
+ else if (show_direction_hint && (i == gps->totpoints - 1)) {
+ /* end point in red smaller */
+ ARRAY_SET_ITEMS(fcolor, 1.0f, 0.0f, 0.0f, 1.0f);
+ fsize = vsize + 1;
+ }
+ else if (pt->flag & GP_SPOINT_SELECT) {
+ copy_v4_v4(fcolor, selectColor);
+ fsize = vsize;
+ }
+ else {
+ copy_v4_v4(fcolor, unselectColor);
+ fsize = bsize;
+ }
+ }
+
+ GPU_vertbuf_attr_set(be->vbo, be->color_id, be->vbo_len, fcolor);
+ GPU_vertbuf_attr_set(be->vbo, be->thickness_id, be->vbo_len, &fsize);
+ GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x);
+ be->vbo_len++;
+ if (gps->dvert != NULL) {
+ dvert++;
+ }
+ }
}
/* Draw lines for strokes being edited */
-void DRW_gpencil_get_edlin_geom(struct GpencilBatchCacheElem *be, bGPDstroke *gps, float alpha, short UNUSED(dflag))
+void DRW_gpencil_get_edlin_geom(struct GpencilBatchCacheElem *be,
+ bGPDstroke *gps,
+ float alpha,
+ short UNUSED(dflag))
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Object *ob = draw_ctx->obact;
- bGPdata *gpd = ob->data;
- const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE);
-
- int vgindex = ob->actdef - 1;
- if (!BLI_findlink(&ob->defbase, vgindex)) {
- vgindex = -1;
- }
-
- float selectColor[4];
- UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor);
- selectColor[3] = alpha;
- float linecolor[4];
- copy_v4_v4(linecolor, gpd->line_color);
-
- if (be->vbo == NULL) {
- be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
-
- be->vbo = GPU_vertbuf_create_with_format(&be->format);
- GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
- be->vbo_len = 0;
- }
- gpencil_vbo_ensure_size(be, gps->totpoints);
-
- /* Draw all the stroke lines (selected or not) */
- bGPDspoint *pt = gps->points;
- MDeformVert *dvert = gps->dvert;
-
- float fcolor[4];
- for (int i = 0; i < gps->totpoints; i++, pt++) {
- /* weight paint */
- if (is_weight_paint) {
- float weight = (dvert && dvert->dw && (vgindex > -1)) ? defvert_find_weight(dvert, vgindex) : 0.0f;
- float hue = 2.0f * (1.0f - weight) / 3.0f;
- hsv_to_rgb(hue, 1.0f, 1.0f, &selectColor[0], &selectColor[1], &selectColor[2]);
- selectColor[3] = 1.0f;
- copy_v4_v4(fcolor, selectColor);
- }
- else {
- if (pt->flag & GP_SPOINT_SELECT) {
- copy_v4_v4(fcolor, selectColor);
- }
- else {
- copy_v4_v4(fcolor, linecolor);
- }
- }
-
- GPU_vertbuf_attr_set(be->vbo, be->color_id, be->vbo_len, fcolor);
- GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x);
- be->vbo_len++;
-
- if (gps->dvert != NULL) {
- dvert++;
- }
- }
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Object *ob = draw_ctx->obact;
+ bGPdata *gpd = ob->data;
+ const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE);
+
+ int vgindex = ob->actdef - 1;
+ if (!BLI_findlink(&ob->defbase, vgindex)) {
+ vgindex = -1;
+ }
+
+ float selectColor[4];
+ UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor);
+ selectColor[3] = alpha;
+ float linecolor[4];
+ copy_v4_v4(linecolor, gpd->line_color);
+
+ if (be->vbo == NULL) {
+ be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+
+ be->vbo = GPU_vertbuf_create_with_format(&be->format);
+ GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
+ be->vbo_len = 0;
+ }
+ gpencil_vbo_ensure_size(be, gps->totpoints);
+
+ /* Draw all the stroke lines (selected or not) */
+ bGPDspoint *pt = gps->points;
+ MDeformVert *dvert = gps->dvert;
+
+ float fcolor[4];
+ for (int i = 0; i < gps->totpoints; i++, pt++) {
+ /* weight paint */
+ if (is_weight_paint) {
+ float weight = (dvert && dvert->dw && (vgindex > -1)) ? defvert_find_weight(dvert, vgindex) :
+ 0.0f;
+ float hue = 2.0f * (1.0f - weight) / 3.0f;
+ hsv_to_rgb(hue, 1.0f, 1.0f, &selectColor[0], &selectColor[1], &selectColor[2]);
+ selectColor[3] = 1.0f;
+ copy_v4_v4(fcolor, selectColor);
+ }
+ else {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ copy_v4_v4(fcolor, selectColor);
+ }
+ else {
+ copy_v4_v4(fcolor, linecolor);
+ }
+ }
+
+ GPU_vertbuf_attr_set(be->vbo, be->color_id, be->vbo_len, fcolor);
+ GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x);
+ be->vbo_len++;
+
+ if (gps->dvert != NULL) {
+ dvert++;
+ }
+ }
}
-static void set_grid_point(
- GPUVertBuf *vbo, int idx, float col_grid[4],
- uint pos_id, uint color_id,
- float v1, float v2, const int axis)
+static void set_grid_point(GPUVertBuf *vbo,
+ int idx,
+ float col_grid[4],
+ uint pos_id,
+ uint color_id,
+ float v1,
+ float v2,
+ const int axis)
{
- GPU_vertbuf_attr_set(vbo, color_id, idx, col_grid);
-
- float pos[3];
- /* Set the grid in the selected axis */
- switch (axis) {
- case GP_LOCKAXIS_X:
- {
- ARRAY_SET_ITEMS(pos, 0.0f, v1, v2);
- break;
- }
- case GP_LOCKAXIS_Y:
- {
- ARRAY_SET_ITEMS(pos, v1, 0.0f, v2);
- break;
- }
- case GP_LOCKAXIS_Z:
- default: /* view aligned */
- {
- ARRAY_SET_ITEMS(pos, v1, v2, 0.0f);
- break;
- }
- }
-
- GPU_vertbuf_attr_set(vbo, pos_id, idx, pos);
+ GPU_vertbuf_attr_set(vbo, color_id, idx, col_grid);
+
+ float pos[3];
+ /* Set the grid in the selected axis */
+ switch (axis) {
+ case GP_LOCKAXIS_X: {
+ ARRAY_SET_ITEMS(pos, 0.0f, v1, v2);
+ break;
+ }
+ case GP_LOCKAXIS_Y: {
+ ARRAY_SET_ITEMS(pos, v1, 0.0f, v2);
+ break;
+ }
+ case GP_LOCKAXIS_Z:
+ default: /* view aligned */
+ {
+ ARRAY_SET_ITEMS(pos, v1, v2, 0.0f);
+ break;
+ }
+ }
+
+ GPU_vertbuf_attr_set(vbo, pos_id, idx, pos);
}
/* Draw grid lines */
GPUBatch *DRW_gpencil_get_grid(Object *ob)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- ToolSettings *ts = scene->toolsettings;
- View3D *v3d = draw_ctx->v3d;
- bGPdata *gpd = (bGPdata *)ob->data;
- const bool do_center = (gpd->grid.lines <= 0) ? false : true;
-
- float col_grid[4];
-
- /* verify we have something to draw and valid values */
- if (gpd->grid.scale[0] == 0.0f) {
- gpd->grid.scale[0] = 1.0f;
- }
- if (gpd->grid.scale[1] == 0.0f) {
- gpd->grid.scale[1] = 1.0f;
- }
-
- if (v3d->overlay.gpencil_grid_opacity < 0.1f) {
- v3d->overlay.gpencil_grid_opacity = 0.1f;
- }
-
- /* set color */
- copy_v3_v3(col_grid, gpd->grid.color);
- col_grid[3] = v3d->overlay.gpencil_grid_opacity;
-
- const int axis = ts->gp_sculpt.lock_axis;
-
- const char *grid_unit = NULL;
- const int gridlines = (gpd->grid.lines <= 0) ? 1 : gpd->grid.lines;
- const float grid_w = gpd->grid.scale[0] * ED_scene_grid_scale(scene, &grid_unit);
- const float grid_h = gpd->grid.scale[1] * ED_scene_grid_scale(scene, &grid_unit);
- const float space_w = (grid_w / gridlines);
- const float space_h = (grid_h / gridlines);
- const float offset[2] = { gpd->grid.offset[0], gpd->grid.offset[1] };
-
- const uint vertex_len = 2 * (gridlines * 4 + 2);
-
- static GPUVertFormat format = { 0 };
- static uint pos_id, color_id;
- if (format.attr_len == 0) {
- pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- }
-
- GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(vbo, vertex_len);
-
- int idx = 0;
-
- for (int a = 1; a <= gridlines; a++) {
- const float line_w = a * space_w;
- const float line_h = a * space_h;
-
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], -line_h + offset[1], axis);
- idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], -line_h + offset[1], axis);
- idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], +line_h + offset[1], axis);
- idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], +line_h + offset[1], axis);
- idx++;
-
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, -line_w + offset[0], -grid_h + offset[1], axis);
- idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, -line_w + offset[0], +grid_h + offset[1], axis);
- idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, +line_w + offset[0], -grid_h + offset[1], axis);
- idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, +line_w + offset[0], +grid_h + offset[1], axis);
- idx++;
- }
- /* center lines */
- if (do_center) {
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], 0.0f + offset[1], axis);
- idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], 0.0f + offset[1], axis);
- idx++;
-
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, 0.0f + offset[0], -grid_h + offset[1], axis);
- idx++;
- set_grid_point(vbo, idx, col_grid, pos_id, color_id, 0.0f + offset[0], +grid_h + offset[1], axis);
- idx++;
- }
- return GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ ToolSettings *ts = scene->toolsettings;
+ View3D *v3d = draw_ctx->v3d;
+ bGPdata *gpd = (bGPdata *)ob->data;
+ const bool do_center = (gpd->grid.lines <= 0) ? false : true;
+
+ float col_grid[4];
+
+ /* verify we have something to draw and valid values */
+ if (gpd->grid.scale[0] == 0.0f) {
+ gpd->grid.scale[0] = 1.0f;
+ }
+ if (gpd->grid.scale[1] == 0.0f) {
+ gpd->grid.scale[1] = 1.0f;
+ }
+
+ if (v3d->overlay.gpencil_grid_opacity < 0.1f) {
+ v3d->overlay.gpencil_grid_opacity = 0.1f;
+ }
+
+ /* set color */
+ copy_v3_v3(col_grid, gpd->grid.color);
+ col_grid[3] = v3d->overlay.gpencil_grid_opacity;
+
+ const int axis = ts->gp_sculpt.lock_axis;
+
+ const char *grid_unit = NULL;
+ const int gridlines = (gpd->grid.lines <= 0) ? 1 : gpd->grid.lines;
+ const float grid_w = gpd->grid.scale[0] * ED_scene_grid_scale(scene, &grid_unit);
+ const float grid_h = gpd->grid.scale[1] * ED_scene_grid_scale(scene, &grid_unit);
+ const float space_w = (grid_w / gridlines);
+ const float space_h = (grid_h / gridlines);
+ const float offset[2] = {gpd->grid.offset[0], gpd->grid.offset[1]};
+
+ const uint vertex_len = 2 * (gridlines * 4 + 2);
+
+ static GPUVertFormat format = {0};
+ static uint pos_id, color_id;
+ if (format.attr_len == 0) {
+ pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ color_id = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ }
+
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, vertex_len);
+
+ int idx = 0;
+
+ for (int a = 1; a <= gridlines; a++) {
+ const float line_w = a * space_w;
+ const float line_h = a * space_h;
+
+ set_grid_point(
+ vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], -line_h + offset[1], axis);
+ idx++;
+ set_grid_point(
+ vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], -line_h + offset[1], axis);
+ idx++;
+ set_grid_point(
+ vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], +line_h + offset[1], axis);
+ idx++;
+ set_grid_point(
+ vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], +line_h + offset[1], axis);
+ idx++;
+
+ set_grid_point(
+ vbo, idx, col_grid, pos_id, color_id, -line_w + offset[0], -grid_h + offset[1], axis);
+ idx++;
+ set_grid_point(
+ vbo, idx, col_grid, pos_id, color_id, -line_w + offset[0], +grid_h + offset[1], axis);
+ idx++;
+ set_grid_point(
+ vbo, idx, col_grid, pos_id, color_id, +line_w + offset[0], -grid_h + offset[1], axis);
+ idx++;
+ set_grid_point(
+ vbo, idx, col_grid, pos_id, color_id, +line_w + offset[0], +grid_h + offset[1], axis);
+ idx++;
+ }
+ /* center lines */
+ if (do_center) {
+ set_grid_point(
+ vbo, idx, col_grid, pos_id, color_id, -grid_w + offset[0], 0.0f + offset[1], axis);
+ idx++;
+ set_grid_point(
+ vbo, idx, col_grid, pos_id, color_id, +grid_w + offset[0], 0.0f + offset[1], axis);
+ idx++;
+
+ set_grid_point(
+ vbo, idx, col_grid, pos_id, color_id, 0.0f + offset[0], -grid_h + offset[1], axis);
+ idx++;
+ set_grid_point(
+ vbo, idx, col_grid, pos_id, color_id, 0.0f + offset[0], +grid_h + offset[1], axis);
+ idx++;
+ }
+ return GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
index 8ecee86d92b..320b621f903 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
@@ -61,1010 +61,1060 @@
#define TEXTURE 4
#define PATTERN 5
-#define GP_SET_SRC_GPS(src_gps) if (src_gps) src_gps = src_gps->next
+#define GP_SET_SRC_GPS(src_gps) \
+ if (src_gps) \
+ src_gps = src_gps->next
/* Get number of vertex for using in GPU VBOs */
-static void gpencil_calc_vertex(
- GPENCIL_StorageList *stl, tGPencilObjectCache *cache_ob,
- GpencilBatchCache *cache, bGPdata *gpd,
- int cfra_eval)
+static void gpencil_calc_vertex(GPENCIL_StorageList *stl,
+ tGPencilObjectCache *cache_ob,
+ GpencilBatchCache *cache,
+ bGPdata *gpd,
+ int cfra_eval)
{
- if (!cache->is_dirty) {
- return;
- }
-
- Object *ob = cache_ob->ob;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- const bool main_onion = draw_ctx->v3d != NULL ? (draw_ctx->v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) : true;
- const bool playing = stl->storage->is_playing;
- const bool overlay = draw_ctx->v3d != NULL ? (bool)((draw_ctx->v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
- const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) &&
- overlay && main_onion && DRW_gpencil_onion_active(gpd) && !playing;
-
- const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
- const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
-
- cache_ob->tot_vertex = 0;
- cache_ob->tot_triangles = 0;
-
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- bGPDframe *init_gpf = NULL;
- const bool is_onion = ((do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN));
- if (gpl->flag & GP_LAYER_HIDE) {
- continue;
- }
-
- /* if multiedit or onion skin need to count all frames of the layer */
- if ((is_multiedit) || (is_onion)) {
- init_gpf = gpl->frames.first;
- }
- else {
- /* verify time modifiers */
- if ((time_remap) && (!stl->storage->simplify_modif)) {
- int remap_cfra = BKE_gpencil_time_modifier(
- draw_ctx->depsgraph, draw_ctx->scene, ob, gpl, cfra_eval,
- stl->storage->is_render);
- init_gpf = BKE_gpencil_layer_getframe(gpl, remap_cfra, GP_GETFRAME_USE_PREV);
- }
- else {
- init_gpf = gpl->actframe;
- }
- }
-
- if (init_gpf == NULL) {
- continue;
- }
-
- for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
- for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
- cache_ob->tot_vertex += gps->totpoints + 3;
- cache_ob->tot_triangles += gps->totpoints - 1;
- }
- if ((!is_multiedit) && (!is_onion)) {
- break;
- }
- }
- }
-
- cache->b_fill.tot_vertex = cache_ob->tot_triangles * 3;
- cache->b_stroke.tot_vertex = cache_ob->tot_vertex;
- cache->b_point.tot_vertex = cache_ob->tot_vertex;
- cache->b_edit.tot_vertex = cache_ob->tot_vertex;
- cache->b_edlin.tot_vertex = cache_ob->tot_vertex;
-
- /* some modifiers can change the number of points */
- int factor = 0;
- GpencilModifierData *md;
- for (md = ob->greasepencil_modifiers.first; md; md = md->next) {
- const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
- /* only modifiers that change size */
- if (mti && mti->getDuplicationFactor) {
- factor = mti->getDuplicationFactor(md);
-
- cache->b_fill.tot_vertex *= factor;
- cache->b_stroke.tot_vertex *= factor;
- cache->b_point.tot_vertex *= factor;
- cache->b_edit.tot_vertex *= factor;
- cache->b_edlin.tot_vertex *= factor;
- }
- }
+ if (!cache->is_dirty) {
+ return;
+ }
+
+ Object *ob = cache_ob->ob;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const bool main_onion = draw_ctx->v3d != NULL ?
+ (draw_ctx->v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) :
+ true;
+ const bool playing = stl->storage->is_playing;
+ const bool overlay = draw_ctx->v3d != NULL ?
+ (bool)((draw_ctx->v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) :
+ true;
+ const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && overlay &&
+ main_onion && DRW_gpencil_onion_active(gpd) && !playing;
+
+ const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+
+ cache_ob->tot_vertex = 0;
+ cache_ob->tot_triangles = 0;
+
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ bGPDframe *init_gpf = NULL;
+ const bool is_onion = ((do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN));
+ if (gpl->flag & GP_LAYER_HIDE) {
+ continue;
+ }
+
+ /* if multiedit or onion skin need to count all frames of the layer */
+ if ((is_multiedit) || (is_onion)) {
+ init_gpf = gpl->frames.first;
+ }
+ else {
+ /* verify time modifiers */
+ if ((time_remap) && (!stl->storage->simplify_modif)) {
+ int remap_cfra = BKE_gpencil_time_modifier(
+ draw_ctx->depsgraph, draw_ctx->scene, ob, gpl, cfra_eval, stl->storage->is_render);
+ init_gpf = BKE_gpencil_layer_getframe(gpl, remap_cfra, GP_GETFRAME_USE_PREV);
+ }
+ else {
+ init_gpf = gpl->actframe;
+ }
+ }
+
+ if (init_gpf == NULL) {
+ continue;
+ }
+
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ cache_ob->tot_vertex += gps->totpoints + 3;
+ cache_ob->tot_triangles += gps->totpoints - 1;
+ }
+ if ((!is_multiedit) && (!is_onion)) {
+ break;
+ }
+ }
+ }
+
+ cache->b_fill.tot_vertex = cache_ob->tot_triangles * 3;
+ cache->b_stroke.tot_vertex = cache_ob->tot_vertex;
+ cache->b_point.tot_vertex = cache_ob->tot_vertex;
+ cache->b_edit.tot_vertex = cache_ob->tot_vertex;
+ cache->b_edlin.tot_vertex = cache_ob->tot_vertex;
+
+ /* some modifiers can change the number of points */
+ int factor = 0;
+ GpencilModifierData *md;
+ for (md = ob->greasepencil_modifiers.first; md; md = md->next) {
+ const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
+ /* only modifiers that change size */
+ if (mti && mti->getDuplicationFactor) {
+ factor = mti->getDuplicationFactor(md);
+
+ cache->b_fill.tot_vertex *= factor;
+ cache->b_stroke.tot_vertex *= factor;
+ cache->b_point.tot_vertex *= factor;
+ cache->b_edit.tot_vertex *= factor;
+ cache->b_edlin.tot_vertex *= factor;
+ }
+ }
}
/* Helper for doing all the checks on whether a stroke can be drawn */
-static bool gpencil_can_draw_stroke(
- struct MaterialGPencilStyle *gp_style, const bGPDstroke *gps,
- const bool onion, const bool is_mat_preview)
+static bool gpencil_can_draw_stroke(struct MaterialGPencilStyle *gp_style,
+ const bGPDstroke *gps,
+ const bool onion,
+ const bool is_mat_preview)
{
- /* skip stroke if it doesn't have any valid data */
- if ((gps->points == NULL) || (gps->totpoints < 1) || (gp_style == NULL)) {
- return false;
- }
-
- /* if mat preview render always visible */
- if (is_mat_preview) {
- return true;
- }
-
- /* check if the color is visible */
- if ((gp_style == NULL) ||
- (gp_style->flag & GP_STYLE_COLOR_HIDE) ||
- (onion && (gp_style->flag & GP_STYLE_COLOR_ONIONSKIN)))
- {
- return false;
- }
-
- /* stroke can be drawn */
- return true;
+ /* skip stroke if it doesn't have any valid data */
+ if ((gps->points == NULL) || (gps->totpoints < 1) || (gp_style == NULL)) {
+ return false;
+ }
+
+ /* if mat preview render always visible */
+ if (is_mat_preview) {
+ return true;
+ }
+
+ /* check if the color is visible */
+ if ((gp_style == NULL) || (gp_style->flag & GP_STYLE_COLOR_HIDE) ||
+ (onion && (gp_style->flag & GP_STYLE_COLOR_ONIONSKIN))) {
+ return false;
+ }
+
+ /* stroke can be drawn */
+ return true;
}
/* calc bounding box in 2d using flat projection data */
-static void gpencil_calc_2d_bounding_box(
- const float(*points2d)[2], int totpoints, float minv[2], float maxv[2])
+static void gpencil_calc_2d_bounding_box(const float (*points2d)[2],
+ int totpoints,
+ float minv[2],
+ float maxv[2])
{
- minv[0] = points2d[0][0];
- minv[1] = points2d[0][1];
- maxv[0] = points2d[0][0];
- maxv[1] = points2d[0][1];
-
- for (int i = 1; i < totpoints; i++) {
- /* min */
- if (points2d[i][0] < minv[0]) {
- minv[0] = points2d[i][0];
- }
- if (points2d[i][1] < minv[1]) {
- minv[1] = points2d[i][1];
- }
- /* max */
- if (points2d[i][0] > maxv[0]) {
- maxv[0] = points2d[i][0];
- }
- if (points2d[i][1] > maxv[1]) {
- maxv[1] = points2d[i][1];
- }
- }
- /* use a perfect square */
- if (maxv[0] > maxv[1]) {
- maxv[1] = maxv[0];
- }
- else {
- maxv[0] = maxv[1];
- }
+ minv[0] = points2d[0][0];
+ minv[1] = points2d[0][1];
+ maxv[0] = points2d[0][0];
+ maxv[1] = points2d[0][1];
+
+ for (int i = 1; i < totpoints; i++) {
+ /* min */
+ if (points2d[i][0] < minv[0]) {
+ minv[0] = points2d[i][0];
+ }
+ if (points2d[i][1] < minv[1]) {
+ minv[1] = points2d[i][1];
+ }
+ /* max */
+ if (points2d[i][0] > maxv[0]) {
+ maxv[0] = points2d[i][0];
+ }
+ if (points2d[i][1] > maxv[1]) {
+ maxv[1] = points2d[i][1];
+ }
+ }
+ /* use a perfect square */
+ if (maxv[0] > maxv[1]) {
+ maxv[1] = maxv[0];
+ }
+ else {
+ maxv[0] = maxv[1];
+ }
}
/* calc texture coordinates using flat projected points */
static void gpencil_calc_stroke_fill_uv(
- const float(*points2d)[2], int totpoints, float minv[2], float maxv[2], float(*r_uv)[2])
+ const float (*points2d)[2], int totpoints, float minv[2], float maxv[2], float (*r_uv)[2])
{
- float d[2];
- d[0] = maxv[0] - minv[0];
- d[1] = maxv[1] - minv[1];
- for (int i = 0; i < totpoints; i++) {
- r_uv[i][0] = (points2d[i][0] - minv[0]) / d[0];
- r_uv[i][1] = (points2d[i][1] - minv[1]) / d[1];
- }
+ float d[2];
+ d[0] = maxv[0] - minv[0];
+ d[1] = maxv[1] - minv[1];
+ for (int i = 0; i < totpoints; i++) {
+ r_uv[i][0] = (points2d[i][0] - minv[0]) / d[0];
+ r_uv[i][1] = (points2d[i][1] - minv[1]) / d[1];
+ }
}
/* recalc the internal geometry caches for fill and uvs */
-static void DRW_gpencil_recalc_geometry_caches(
- Object *ob, bGPDlayer *gpl, MaterialGPencilStyle *gp_style, bGPDstroke *gps)
+static void DRW_gpencil_recalc_geometry_caches(Object *ob,
+ bGPDlayer *gpl,
+ MaterialGPencilStyle *gp_style,
+ bGPDstroke *gps)
{
- if (gps->flag & GP_STROKE_RECALC_GEOMETRY) {
- /* Calculate triangles cache for filling area (must be done only after changes) */
- if ((gps->tot_triangles == 0) || (gps->triangles == NULL)) {
- if ((gps->totpoints > 2) &&
- ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
- (gp_style->fill_style > 0) || (gpl->blend_mode != eGplBlendMode_Normal)))
- {
- DRW_gpencil_triangulate_stroke_fill(ob, gps);
- }
- }
-
- /* calc uv data along the stroke */
- ED_gpencil_calc_stroke_uv(ob, gps);
-
- /* clear flag */
- gps->flag &= ~GP_STROKE_RECALC_GEOMETRY;
- }
+ if (gps->flag & GP_STROKE_RECALC_GEOMETRY) {
+ /* Calculate triangles cache for filling area (must be done only after changes) */
+ if ((gps->tot_triangles == 0) || (gps->triangles == NULL)) {
+ if ((gps->totpoints > 2) &&
+ ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0) ||
+ (gpl->blend_mode != eGplBlendMode_Normal))) {
+ DRW_gpencil_triangulate_stroke_fill(ob, gps);
+ }
+ }
+
+ /* calc uv data along the stroke */
+ ED_gpencil_calc_stroke_uv(ob, gps);
+
+ /* clear flag */
+ gps->flag &= ~GP_STROKE_RECALC_GEOMETRY;
+ }
}
-static void set_wireframe_color(
- Object *ob, bGPDlayer *gpl, View3D *v3d,
- GPENCIL_StorageList *stl,
- MaterialGPencilStyle *gp_style, int id, const bool is_fill)
+static void set_wireframe_color(Object *ob,
+ bGPDlayer *gpl,
+ View3D *v3d,
+ GPENCIL_StorageList *stl,
+ MaterialGPencilStyle *gp_style,
+ int id,
+ const bool is_fill)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- World *world = draw_ctx->scene->world;
-
- float color[4];
- if (((gp_style->stroke_rgba[3] < GPENCIL_ALPHA_OPACITY_THRESH) ||
- (((gp_style->flag & GP_STYLE_STROKE_SHOW) == 0))) &&
- (gp_style->fill_rgba[3] >= GPENCIL_ALPHA_OPACITY_THRESH))
- {
- copy_v4_v4(color, gp_style->fill_rgba);
- }
- else {
- copy_v4_v4(color, gp_style->stroke_rgba);
- }
- float alpha = color[3];
-
- /* wire color */
- if ((v3d) && (id > -1)) {
- const char type = (
- (stl->shgroups[id].shading_type[0] == OB_WIRE) ?
- v3d->shading.wire_color_type :
- v3d->shading.color_type);
- /* if fill and wire, use background color */
- if ((is_fill) && (stl->shgroups[id].shading_type[0] == OB_WIRE)) {
- if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_THEME) {
- UI_GetThemeColor4fv(TH_BACK, stl->shgroups[id].wire_color);
- stl->shgroups[id].wire_color[3] = 1.0f;
- }
- else if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) {
- color[0] = world->horr;
- color[1] = world->horg;
- color[2] = world->horb;
- color[3] = 1.0f;
- linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
- }
- else {
- copy_v3_v3(color, v3d->shading.background_color);
- color[3] = 1.0f;
- linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
- }
- return;
- }
-
- /* strokes */
- switch (type) {
- case V3D_SHADING_SINGLE_COLOR:
- {
- if (stl->shgroups[id].shading_type[0] == OB_WIRE) {
- UI_GetThemeColor4fv(TH_WIRE, color);
- }
- else {
- copy_v3_v3(color, v3d->shading.single_color);
- }
- color[3] = alpha;
- linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
- break;
- }
- case V3D_SHADING_OBJECT_COLOR:
- {
- copy_v4_v4(color, ob->color);
- color[3] = alpha;
- linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
- break;
- }
- case V3D_SHADING_RANDOM_COLOR:
- {
- uint gpl_hash = 1;
- uint ob_hash = BLI_ghashutil_strhash_p_murmur(ob->id.name);
- if (gpl) {
- gpl_hash = BLI_ghashutil_strhash_p_murmur(gpl->info);
- }
-
- float hue = BLI_hash_int_01(ob_hash * gpl_hash);
- float hsv[3] = { hue, 0.40f, 0.8f };
- float wire_col[3];
- hsv_to_rgb_v(hsv, &wire_col[0]);
-
- stl->shgroups[id].wire_color[0] = wire_col[0];
- stl->shgroups[id].wire_color[1] = wire_col[1];
- stl->shgroups[id].wire_color[2] = wire_col[2];
- stl->shgroups[id].wire_color[3] = alpha;
- break;
- }
- default:
- {
- copy_v4_v4(stl->shgroups[id].wire_color, color);
- break;
- }
- }
- }
- else {
- copy_v4_v4(stl->shgroups[id].wire_color, color);
- }
-
- /* if solid, the alpha must be set to 1.0 */
- if (stl->shgroups[id].shading_type[0] == OB_SOLID) {
- stl->shgroups[id].wire_color[3] = 1.0f;
- }
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ World *world = draw_ctx->scene->world;
+
+ float color[4];
+ if (((gp_style->stroke_rgba[3] < GPENCIL_ALPHA_OPACITY_THRESH) ||
+ (((gp_style->flag & GP_STYLE_STROKE_SHOW) == 0))) &&
+ (gp_style->fill_rgba[3] >= GPENCIL_ALPHA_OPACITY_THRESH)) {
+ copy_v4_v4(color, gp_style->fill_rgba);
+ }
+ else {
+ copy_v4_v4(color, gp_style->stroke_rgba);
+ }
+ float alpha = color[3];
+
+ /* wire color */
+ if ((v3d) && (id > -1)) {
+ const char type = ((stl->shgroups[id].shading_type[0] == OB_WIRE) ?
+ v3d->shading.wire_color_type :
+ v3d->shading.color_type);
+ /* if fill and wire, use background color */
+ if ((is_fill) && (stl->shgroups[id].shading_type[0] == OB_WIRE)) {
+ if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_THEME) {
+ UI_GetThemeColor4fv(TH_BACK, stl->shgroups[id].wire_color);
+ stl->shgroups[id].wire_color[3] = 1.0f;
+ }
+ else if (v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) {
+ color[0] = world->horr;
+ color[1] = world->horg;
+ color[2] = world->horb;
+ color[3] = 1.0f;
+ linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
+ }
+ else {
+ copy_v3_v3(color, v3d->shading.background_color);
+ color[3] = 1.0f;
+ linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
+ }
+ return;
+ }
+
+ /* strokes */
+ switch (type) {
+ case V3D_SHADING_SINGLE_COLOR: {
+ if (stl->shgroups[id].shading_type[0] == OB_WIRE) {
+ UI_GetThemeColor4fv(TH_WIRE, color);
+ }
+ else {
+ copy_v3_v3(color, v3d->shading.single_color);
+ }
+ color[3] = alpha;
+ linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
+ break;
+ }
+ case V3D_SHADING_OBJECT_COLOR: {
+ copy_v4_v4(color, ob->color);
+ color[3] = alpha;
+ linearrgb_to_srgb_v4(stl->shgroups[id].wire_color, color);
+ break;
+ }
+ case V3D_SHADING_RANDOM_COLOR: {
+ uint gpl_hash = 1;
+ uint ob_hash = BLI_ghashutil_strhash_p_murmur(ob->id.name);
+ if (gpl) {
+ gpl_hash = BLI_ghashutil_strhash_p_murmur(gpl->info);
+ }
+
+ float hue = BLI_hash_int_01(ob_hash * gpl_hash);
+ float hsv[3] = {hue, 0.40f, 0.8f};
+ float wire_col[3];
+ hsv_to_rgb_v(hsv, &wire_col[0]);
+
+ stl->shgroups[id].wire_color[0] = wire_col[0];
+ stl->shgroups[id].wire_color[1] = wire_col[1];
+ stl->shgroups[id].wire_color[2] = wire_col[2];
+ stl->shgroups[id].wire_color[3] = alpha;
+ break;
+ }
+ default: {
+ copy_v4_v4(stl->shgroups[id].wire_color, color);
+ break;
+ }
+ }
+ }
+ else {
+ copy_v4_v4(stl->shgroups[id].wire_color, color);
+ }
+
+ /* if solid, the alpha must be set to 1.0 */
+ if (stl->shgroups[id].shading_type[0] == OB_SOLID) {
+ stl->shgroups[id].wire_color[3] = 1.0f;
+ }
}
/* create shading group for filling */
-static DRWShadingGroup *DRW_gpencil_shgroup_fill_create(
- GPENCIL_e_data *e_data, GPENCIL_Data *vedata, DRWPass *pass,
- GPUShader *shader, Object *ob, bGPdata *gpd, bGPDlayer *gpl,
- MaterialGPencilStyle *gp_style, int id, int shading_type[2])
+static DRWShadingGroup *DRW_gpencil_shgroup_fill_create(GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ DRWPass *pass,
+ GPUShader *shader,
+ Object *ob,
+ bGPdata *gpd,
+ bGPDlayer *gpl,
+ MaterialGPencilStyle *gp_style,
+ int id,
+ int shading_type[2])
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- View3D *v3d = draw_ctx->v3d;
-
- /* e_data.gpencil_fill_sh */
- DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
-
- DRW_shgroup_uniform_vec4(grp, "color2", gp_style->mix_rgba, 1);
-
- /* set style type */
- switch (gp_style->fill_style) {
- case GP_STYLE_FILL_STYLE_SOLID:
- stl->shgroups[id].fill_style = SOLID;
- break;
- case GP_STYLE_FILL_STYLE_GRADIENT:
- if (gp_style->gradient_type == GP_STYLE_GRADIENT_LINEAR) {
- stl->shgroups[id].fill_style = GRADIENT;
- }
- else {
- stl->shgroups[id].fill_style = RADIAL;
- }
- break;
- case GP_STYLE_FILL_STYLE_CHESSBOARD:
- stl->shgroups[id].fill_style = CHESS;
- break;
- case GP_STYLE_FILL_STYLE_TEXTURE:
- if (gp_style->flag & GP_STYLE_FILL_PATTERN) {
- stl->shgroups[id].fill_style = PATTERN;
- }
- else {
- stl->shgroups[id].fill_style = TEXTURE;
- }
- break;
- default:
- stl->shgroups[id].fill_style = GP_STYLE_FILL_STYLE_SOLID;
- break;
- }
- DRW_shgroup_uniform_int(grp, "fill_type", &stl->shgroups[id].fill_style, 1);
-
- DRW_shgroup_uniform_float(grp, "mix_factor", &gp_style->mix_factor, 1);
-
- DRW_shgroup_uniform_float(grp, "gradient_angle", &gp_style->gradient_angle, 1);
- DRW_shgroup_uniform_float(grp, "gradient_radius", &gp_style->gradient_radius, 1);
- DRW_shgroup_uniform_float(grp, "pattern_gridsize", &gp_style->pattern_gridsize, 1);
- DRW_shgroup_uniform_vec2(grp, "gradient_scale", gp_style->gradient_scale, 1);
- DRW_shgroup_uniform_vec2(grp, "gradient_shift", gp_style->gradient_shift, 1);
-
- DRW_shgroup_uniform_float(grp, "texture_angle", &gp_style->texture_angle, 1);
- DRW_shgroup_uniform_vec2(grp, "texture_scale", gp_style->texture_scale, 1);
- DRW_shgroup_uniform_vec2(grp, "texture_offset", gp_style->texture_offset, 1);
- DRW_shgroup_uniform_float(grp, "texture_opacity", &gp_style->texture_opacity, 1);
- DRW_shgroup_uniform_float(grp, "layer_opacity", &gpl->opacity, 1);
-
- stl->shgroups[id].texture_mix = gp_style->flag & GP_STYLE_COLOR_TEX_MIX ? 1 : 0;
- DRW_shgroup_uniform_int(grp, "texture_mix", &stl->shgroups[id].texture_mix, 1);
-
- stl->shgroups[id].texture_flip = gp_style->flag & GP_STYLE_COLOR_FLIP_FILL ? 1 : 0;
- DRW_shgroup_uniform_int(grp, "texture_flip", &stl->shgroups[id].texture_flip, 1);
-
- stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
- DRW_shgroup_uniform_int(grp, "xraymode", &stl->shgroups[id].xray_mode, 1);
- DRW_shgroup_uniform_int(grp, "drawmode", (const int *) &gpd->draw_mode, 1);
-
- /* viewport x-ray */
- stl->shgroups[id].is_xray = (ob->dt == OB_WIRE) ? 1 : stl->storage->is_xray;
- DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
-
- /* shading type */
- stl->shgroups[id].shading_type[0] = GPENCIL_USE_SOLID(stl) ? (int)OB_RENDER : shading_type[0];
- if (v3d) {
- stl->shgroups[id].shading_type[1] = (
- (stl->shgroups[id].shading_type[0] == OB_WIRE) ?
- v3d->shading.wire_color_type :
- v3d->shading.color_type);
- }
-
- DRW_shgroup_uniform_int(grp, "shading_type", &stl->shgroups[id].shading_type[0], 2);
-
- /* wire color */
- set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, true);
- DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
-
- /* image texture */
- if ((gp_style->flag & GP_STYLE_COLOR_TEX_MIX) ||
- (gp_style->fill_style & GP_STYLE_FILL_STYLE_TEXTURE))
- {
- ImBuf *ibuf;
- Image *image = gp_style->ima;
- ImageUser iuser = { NULL };
- void *lock;
-
- iuser.ok = true;
-
- ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
-
- if (ibuf == NULL || ibuf->rect == NULL) {
- BKE_image_release_ibuf(image, ibuf, NULL);
- }
- else {
- GPUTexture *texture = GPU_texture_from_blender(gp_style->ima, &iuser, GL_TEXTURE_2D, true);
- DRW_shgroup_uniform_texture(grp, "myTexture", texture);
-
- stl->shgroups[id].texture_clamp = gp_style->flag & GP_STYLE_COLOR_TEX_CLAMP ? 1 : 0;
- DRW_shgroup_uniform_int(grp, "texture_clamp", &stl->shgroups[id].texture_clamp, 1);
-
- BKE_image_release_ibuf(image, ibuf, NULL);
- }
- }
- else {
- /* if no texture defined, need a blank texture to avoid errors in draw manager */
- DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture);
- stl->shgroups[id].texture_clamp = 0;
- DRW_shgroup_uniform_int(grp, "texture_clamp", &stl->shgroups[id].texture_clamp, 1);
- }
-
- return grp;
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+
+ /* e_data.gpencil_fill_sh */
+ DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
+
+ DRW_shgroup_uniform_vec4(grp, "color2", gp_style->mix_rgba, 1);
+
+ /* set style type */
+ switch (gp_style->fill_style) {
+ case GP_STYLE_FILL_STYLE_SOLID:
+ stl->shgroups[id].fill_style = SOLID;
+ break;
+ case GP_STYLE_FILL_STYLE_GRADIENT:
+ if (gp_style->gradient_type == GP_STYLE_GRADIENT_LINEAR) {
+ stl->shgroups[id].fill_style = GRADIENT;
+ }
+ else {
+ stl->shgroups[id].fill_style = RADIAL;
+ }
+ break;
+ case GP_STYLE_FILL_STYLE_CHESSBOARD:
+ stl->shgroups[id].fill_style = CHESS;
+ break;
+ case GP_STYLE_FILL_STYLE_TEXTURE:
+ if (gp_style->flag & GP_STYLE_FILL_PATTERN) {
+ stl->shgroups[id].fill_style = PATTERN;
+ }
+ else {
+ stl->shgroups[id].fill_style = TEXTURE;
+ }
+ break;
+ default:
+ stl->shgroups[id].fill_style = GP_STYLE_FILL_STYLE_SOLID;
+ break;
+ }
+ DRW_shgroup_uniform_int(grp, "fill_type", &stl->shgroups[id].fill_style, 1);
+
+ DRW_shgroup_uniform_float(grp, "mix_factor", &gp_style->mix_factor, 1);
+
+ DRW_shgroup_uniform_float(grp, "gradient_angle", &gp_style->gradient_angle, 1);
+ DRW_shgroup_uniform_float(grp, "gradient_radius", &gp_style->gradient_radius, 1);
+ DRW_shgroup_uniform_float(grp, "pattern_gridsize", &gp_style->pattern_gridsize, 1);
+ DRW_shgroup_uniform_vec2(grp, "gradient_scale", gp_style->gradient_scale, 1);
+ DRW_shgroup_uniform_vec2(grp, "gradient_shift", gp_style->gradient_shift, 1);
+
+ DRW_shgroup_uniform_float(grp, "texture_angle", &gp_style->texture_angle, 1);
+ DRW_shgroup_uniform_vec2(grp, "texture_scale", gp_style->texture_scale, 1);
+ DRW_shgroup_uniform_vec2(grp, "texture_offset", gp_style->texture_offset, 1);
+ DRW_shgroup_uniform_float(grp, "texture_opacity", &gp_style->texture_opacity, 1);
+ DRW_shgroup_uniform_float(grp, "layer_opacity", &gpl->opacity, 1);
+
+ stl->shgroups[id].texture_mix = gp_style->flag & GP_STYLE_COLOR_TEX_MIX ? 1 : 0;
+ DRW_shgroup_uniform_int(grp, "texture_mix", &stl->shgroups[id].texture_mix, 1);
+
+ stl->shgroups[id].texture_flip = gp_style->flag & GP_STYLE_COLOR_FLIP_FILL ? 1 : 0;
+ DRW_shgroup_uniform_int(grp, "texture_flip", &stl->shgroups[id].texture_flip, 1);
+
+ stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
+ DRW_shgroup_uniform_int(grp, "xraymode", &stl->shgroups[id].xray_mode, 1);
+ DRW_shgroup_uniform_int(grp, "drawmode", (const int *)&gpd->draw_mode, 1);
+
+ /* viewport x-ray */
+ stl->shgroups[id].is_xray = (ob->dt == OB_WIRE) ? 1 : stl->storage->is_xray;
+ DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
+
+ /* shading type */
+ stl->shgroups[id].shading_type[0] = GPENCIL_USE_SOLID(stl) ? (int)OB_RENDER : shading_type[0];
+ if (v3d) {
+ stl->shgroups[id].shading_type[1] = ((stl->shgroups[id].shading_type[0] == OB_WIRE) ?
+ v3d->shading.wire_color_type :
+ v3d->shading.color_type);
+ }
+
+ DRW_shgroup_uniform_int(grp, "shading_type", &stl->shgroups[id].shading_type[0], 2);
+
+ /* wire color */
+ set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, true);
+ DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
+
+ /* image texture */
+ if ((gp_style->flag & GP_STYLE_COLOR_TEX_MIX) ||
+ (gp_style->fill_style & GP_STYLE_FILL_STYLE_TEXTURE)) {
+ ImBuf *ibuf;
+ Image *image = gp_style->ima;
+ ImageUser iuser = {NULL};
+ void *lock;
+
+ iuser.ok = true;
+
+ ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
+
+ if (ibuf == NULL || ibuf->rect == NULL) {
+ BKE_image_release_ibuf(image, ibuf, NULL);
+ }
+ else {
+ GPUTexture *texture = GPU_texture_from_blender(gp_style->ima, &iuser, GL_TEXTURE_2D, true);
+ DRW_shgroup_uniform_texture(grp, "myTexture", texture);
+
+ stl->shgroups[id].texture_clamp = gp_style->flag & GP_STYLE_COLOR_TEX_CLAMP ? 1 : 0;
+ DRW_shgroup_uniform_int(grp, "texture_clamp", &stl->shgroups[id].texture_clamp, 1);
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
+ }
+ }
+ else {
+ /* if no texture defined, need a blank texture to avoid errors in draw manager */
+ DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture);
+ stl->shgroups[id].texture_clamp = 0;
+ DRW_shgroup_uniform_int(grp, "texture_clamp", &stl->shgroups[id].texture_clamp, 1);
+ }
+
+ return grp;
}
/* check if some onion is enabled */
bool DRW_gpencil_onion_active(bGPdata *gpd)
{
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- if (gpl->onion_flag & GP_LAYER_ONIONSKIN) {
- return true;
- }
- }
- return false;
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ if (gpl->onion_flag & GP_LAYER_ONIONSKIN) {
+ return true;
+ }
+ }
+ return false;
}
/* create shading group for strokes */
-DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(
- GPENCIL_e_data *e_data, GPENCIL_Data *vedata, DRWPass *pass, GPUShader *shader, Object *ob,
- bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps,
- MaterialGPencilStyle *gp_style, int id,
- bool onion, const float scale, const int shading_type[2])
+DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ DRWPass *pass,
+ GPUShader *shader,
+ Object *ob,
+ bGPdata *gpd,
+ bGPDlayer *gpl,
+ bGPDstroke *gps,
+ MaterialGPencilStyle *gp_style,
+ int id,
+ bool onion,
+ const float scale,
+ const int shading_type[2])
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- const float *viewport_size = DRW_viewport_size_get();
- const DRWContextState *draw_ctx = DRW_context_state_get();
- View3D *v3d = draw_ctx->v3d;
-
- /* e_data.gpencil_stroke_sh */
- DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
-
- DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1);
-
- DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1);
-
- /* avoid wrong values */
- if ((gpd) && (gpd->pixfactor == 0.0f)) {
- gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
- }
-
- /* object scale and depth */
- if ((ob) && (id > -1)) {
- stl->shgroups[id].obj_scale = scale;
- DRW_shgroup_uniform_float(grp, "objscale", &stl->shgroups[id].obj_scale, 1);
- stl->shgroups[id].keep_size = (int)((gpd) && (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS));
- DRW_shgroup_uniform_int(grp, "keep_size", &stl->shgroups[id].keep_size, 1);
-
- stl->shgroups[id].stroke_style = gp_style->stroke_style;
- stl->shgroups[id].color_type = GPENCIL_COLOR_SOLID;
- if ((gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
- stl->shgroups[id].color_type = GPENCIL_COLOR_TEXTURE;
- if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
- stl->shgroups[id].color_type = GPENCIL_COLOR_PATTERN;
- }
- }
- DRW_shgroup_uniform_int(grp, "color_type", &stl->shgroups[id].color_type, 1);
- DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
-
- stl->shgroups[id].caps_mode[0] = gps->caps[0];
- stl->shgroups[id].caps_mode[1] = gps->caps[1];
- DRW_shgroup_uniform_int(grp, "caps_mode", &stl->shgroups[id].caps_mode[0], 2);
-
- stl->shgroups[id].gradient_f = gps->gradient_f;
- copy_v2_v2(stl->shgroups[id].gradient_s, gps->gradient_s);
- DRW_shgroup_uniform_float(grp, "gradient_f", &stl->shgroups[id].gradient_f, 1);
-
- /* viewport x-ray */
- stl->shgroups[id].is_xray = (ob->dt == OB_WIRE) ? 1 : stl->storage->is_xray;
- DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
-
- stl->shgroups[id].shading_type[0] = (GPENCIL_USE_SOLID(stl) || onion) ? (int)OB_RENDER : shading_type[0];
- if (v3d) {
- stl->shgroups[id].shading_type[1] = (
- (stl->shgroups[id].shading_type[0] == OB_WIRE) ?
- v3d->shading.wire_color_type :
- v3d->shading.color_type);
- }
- DRW_shgroup_uniform_int(grp, "shading_type", &stl->shgroups[id].shading_type[0], 2);
-
- /* wire color */
- set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, false);
- DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
- }
- else {
- stl->storage->obj_scale = 1.0f;
- stl->storage->keep_size = 0;
- stl->storage->pixfactor = GP_DEFAULT_PIX_FACTOR;
- DRW_shgroup_uniform_float(grp, "objscale", &stl->storage->obj_scale, 1);
- DRW_shgroup_uniform_int(grp, "keep_size", &stl->storage->keep_size, 1);
- DRW_shgroup_uniform_int(grp, "color_type", &stl->storage->color_type, 1);
- if (gpd) {
- DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
- }
- else {
- DRW_shgroup_uniform_float(grp, "pixfactor", &stl->storage->pixfactor, 1);
- }
- const int zero[2] = { 0, 0 };
- DRW_shgroup_uniform_int(grp, "caps_mode", &zero[0], 2);
-
- DRW_shgroup_uniform_float(grp, "gradient_f", &stl->storage->gradient_f, 1);
-
- /* viewport x-ray */
- DRW_shgroup_uniform_int(grp, "viewport_xray", &stl->storage->is_xray, 1);
- DRW_shgroup_uniform_int(grp, "shading_type", (const int *)&stl->storage->shade_render, 2);
- }
-
- if ((gpd) && (id > -1)) {
- stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
- DRW_shgroup_uniform_int(grp, "xraymode", &stl->shgroups[id].xray_mode, 1);
- }
- else {
- /* for drawing always on predefined z-depth */
- DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
- }
-
- /* image texture for pattern */
- if ((gp_style) && (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
- ImBuf *ibuf;
- Image *image = gp_style->sima;
- ImageUser iuser = { NULL };
- void *lock;
-
- iuser.ok = true;
-
- ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
-
- if (ibuf == NULL || ibuf->rect == NULL) {
- BKE_image_release_ibuf(image, ibuf, NULL);
- }
- else {
- GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true);
- DRW_shgroup_uniform_texture(grp, "myTexture", texture);
-
- BKE_image_release_ibuf(image, ibuf, NULL);
- }
- }
- else {
- /* if no texture defined, need a blank texture to avoid errors in draw manager */
- DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture);
- }
-
- return grp;
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ const float *viewport_size = DRW_viewport_size_get();
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+
+ /* e_data.gpencil_stroke_sh */
+ DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
+
+ DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1);
+
+ DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1);
+
+ /* avoid wrong values */
+ if ((gpd) && (gpd->pixfactor == 0.0f)) {
+ gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
+ }
+
+ /* object scale and depth */
+ if ((ob) && (id > -1)) {
+ stl->shgroups[id].obj_scale = scale;
+ DRW_shgroup_uniform_float(grp, "objscale", &stl->shgroups[id].obj_scale, 1);
+ stl->shgroups[id].keep_size = (int)((gpd) && (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS));
+ DRW_shgroup_uniform_int(grp, "keep_size", &stl->shgroups[id].keep_size, 1);
+
+ stl->shgroups[id].stroke_style = gp_style->stroke_style;
+ stl->shgroups[id].color_type = GPENCIL_COLOR_SOLID;
+ if ((gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
+ stl->shgroups[id].color_type = GPENCIL_COLOR_TEXTURE;
+ if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
+ stl->shgroups[id].color_type = GPENCIL_COLOR_PATTERN;
+ }
+ }
+ DRW_shgroup_uniform_int(grp, "color_type", &stl->shgroups[id].color_type, 1);
+ DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
+
+ stl->shgroups[id].caps_mode[0] = gps->caps[0];
+ stl->shgroups[id].caps_mode[1] = gps->caps[1];
+ DRW_shgroup_uniform_int(grp, "caps_mode", &stl->shgroups[id].caps_mode[0], 2);
+
+ stl->shgroups[id].gradient_f = gps->gradient_f;
+ copy_v2_v2(stl->shgroups[id].gradient_s, gps->gradient_s);
+ DRW_shgroup_uniform_float(grp, "gradient_f", &stl->shgroups[id].gradient_f, 1);
+
+ /* viewport x-ray */
+ stl->shgroups[id].is_xray = (ob->dt == OB_WIRE) ? 1 : stl->storage->is_xray;
+ DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
+
+ stl->shgroups[id].shading_type[0] = (GPENCIL_USE_SOLID(stl) || onion) ? (int)OB_RENDER :
+ shading_type[0];
+ if (v3d) {
+ stl->shgroups[id].shading_type[1] = ((stl->shgroups[id].shading_type[0] == OB_WIRE) ?
+ v3d->shading.wire_color_type :
+ v3d->shading.color_type);
+ }
+ DRW_shgroup_uniform_int(grp, "shading_type", &stl->shgroups[id].shading_type[0], 2);
+
+ /* wire color */
+ set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, false);
+ DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
+ }
+ else {
+ stl->storage->obj_scale = 1.0f;
+ stl->storage->keep_size = 0;
+ stl->storage->pixfactor = GP_DEFAULT_PIX_FACTOR;
+ DRW_shgroup_uniform_float(grp, "objscale", &stl->storage->obj_scale, 1);
+ DRW_shgroup_uniform_int(grp, "keep_size", &stl->storage->keep_size, 1);
+ DRW_shgroup_uniform_int(grp, "color_type", &stl->storage->color_type, 1);
+ if (gpd) {
+ DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
+ }
+ else {
+ DRW_shgroup_uniform_float(grp, "pixfactor", &stl->storage->pixfactor, 1);
+ }
+ const int zero[2] = {0, 0};
+ DRW_shgroup_uniform_int(grp, "caps_mode", &zero[0], 2);
+
+ DRW_shgroup_uniform_float(grp, "gradient_f", &stl->storage->gradient_f, 1);
+
+ /* viewport x-ray */
+ DRW_shgroup_uniform_int(grp, "viewport_xray", &stl->storage->is_xray, 1);
+ DRW_shgroup_uniform_int(grp, "shading_type", (const int *)&stl->storage->shade_render, 2);
+ }
+
+ if ((gpd) && (id > -1)) {
+ stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
+ DRW_shgroup_uniform_int(grp, "xraymode", &stl->shgroups[id].xray_mode, 1);
+ }
+ else {
+ /* for drawing always on predefined z-depth */
+ DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
+ }
+
+ /* image texture for pattern */
+ if ((gp_style) && (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
+ ImBuf *ibuf;
+ Image *image = gp_style->sima;
+ ImageUser iuser = {NULL};
+ void *lock;
+
+ iuser.ok = true;
+
+ ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
+
+ if (ibuf == NULL || ibuf->rect == NULL) {
+ BKE_image_release_ibuf(image, ibuf, NULL);
+ }
+ else {
+ GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true);
+ DRW_shgroup_uniform_texture(grp, "myTexture", texture);
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
+ }
+ }
+ else {
+ /* if no texture defined, need a blank texture to avoid errors in draw manager */
+ DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture);
+ }
+
+ return grp;
}
/* create shading group for points */
-static DRWShadingGroup *DRW_gpencil_shgroup_point_create(
- GPENCIL_e_data *e_data, GPENCIL_Data *vedata, DRWPass *pass, GPUShader *shader, Object *ob,
- bGPdata *gpd, bGPDlayer *gpl, bGPDstroke *gps,
- MaterialGPencilStyle *gp_style, int id, bool onion,
- const float scale, const int shading_type[2])
+static DRWShadingGroup *DRW_gpencil_shgroup_point_create(GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ DRWPass *pass,
+ GPUShader *shader,
+ Object *ob,
+ bGPdata *gpd,
+ bGPDlayer *gpl,
+ bGPDstroke *gps,
+ MaterialGPencilStyle *gp_style,
+ int id,
+ bool onion,
+ const float scale,
+ const int shading_type[2])
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- const float *viewport_size = DRW_viewport_size_get();
- const DRWContextState *draw_ctx = DRW_context_state_get();
- View3D *v3d = draw_ctx->v3d;
-
- /* e_data.gpencil_stroke_sh */
- DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
-
- DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1);
- DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1);
-
- /* avoid wrong values */
- if ((gpd) && (gpd->pixfactor == 0.0f)) {
- gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
- }
-
- /* object scale and depth */
- if ((ob) && (id > -1)) {
- stl->shgroups[id].obj_scale = scale;
- DRW_shgroup_uniform_float(grp, "objscale", &stl->shgroups[id].obj_scale, 1);
- stl->shgroups[id].keep_size = (int)((gpd) && (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS));
- DRW_shgroup_uniform_int(grp, "keep_size", &stl->shgroups[id].keep_size, 1);
-
- stl->shgroups[id].mode = gp_style->mode;
- stl->shgroups[id].stroke_style = gp_style->stroke_style;
- stl->shgroups[id].color_type = GPENCIL_COLOR_SOLID;
- if ((gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
- stl->shgroups[id].color_type = GPENCIL_COLOR_TEXTURE;
- if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
- stl->shgroups[id].color_type = GPENCIL_COLOR_PATTERN;
- }
- }
- DRW_shgroup_uniform_int(grp, "color_type", &stl->shgroups[id].color_type, 1);
- DRW_shgroup_uniform_int(grp, "mode", &stl->shgroups[id].mode, 1);
- DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
-
- stl->shgroups[id].gradient_f = gps->gradient_f;
- copy_v2_v2(stl->shgroups[id].gradient_s, gps->gradient_s);
- DRW_shgroup_uniform_float(grp, "gradient_f", &stl->shgroups[id].gradient_f, 1);
- DRW_shgroup_uniform_vec2(grp, "gradient_s", stl->shgroups[id].gradient_s, 1);
-
- /* viewport x-ray */
- stl->shgroups[id].is_xray = (ob->dt == OB_WIRE) ? 1 : stl->storage->is_xray;
- DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
-
- stl->shgroups[id].shading_type[0] = (GPENCIL_USE_SOLID(stl) || onion) ? (int)OB_RENDER : shading_type[0];
- if (v3d) {
- stl->shgroups[id].shading_type[1] = (
- (stl->shgroups[id].shading_type[0] == OB_WIRE) ?
- v3d->shading.wire_color_type :
- v3d->shading.color_type);
- }
- DRW_shgroup_uniform_int(grp, "shading_type", &stl->shgroups[id].shading_type[0], 2);
-
- /* wire color */
- set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, false);
- DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
-
- }
- else {
- stl->storage->obj_scale = 1.0f;
- stl->storage->keep_size = 0;
- stl->storage->pixfactor = GP_DEFAULT_PIX_FACTOR;
- stl->storage->mode = gp_style->mode;
- DRW_shgroup_uniform_float(grp, "objscale", &stl->storage->obj_scale, 1);
- DRW_shgroup_uniform_int(grp, "keep_size", &stl->storage->keep_size, 1);
- DRW_shgroup_uniform_int(grp, "color_type", &stl->storage->color_type, 1);
- DRW_shgroup_uniform_int(grp, "mode", &stl->storage->mode, 1);
- if (gpd) {
- DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
- }
- else {
- DRW_shgroup_uniform_float(grp, "pixfactor", &stl->storage->pixfactor, 1);
- }
-
- DRW_shgroup_uniform_float(grp, "gradient_f", &stl->storage->gradient_f, 1);
- DRW_shgroup_uniform_vec2(grp, "gradient_s", stl->storage->gradient_s, 1);
-
- /* viewport x-ray */
- stl->shgroups[id].is_xray = ((ob) && (ob->dt == OB_WIRE)) ? 1 : stl->storage->is_xray;
- DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
- DRW_shgroup_uniform_int(grp, "shading_type", (const int *)&stl->storage->shade_render, 2);
- }
-
- if ((gpd) && (id > -1)) {
- stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
- DRW_shgroup_uniform_int(grp, "xraymode", (const int *)&stl->shgroups[id].xray_mode, 1);
-
- /* lock rotation of dots and boxes */
- stl->shgroups[id].use_follow_path = (gp_style->flag & GP_STYLE_COLOR_LOCK_DOTS) ? 0 : 1;
- DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->shgroups[id].use_follow_path, 1);
- }
- else {
- /* for drawing always on predefined z-depth */
- DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
-
- /* lock rotation of dots and boxes */
- DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->storage->use_follow_path, 1);
- }
-
-
-
- /* image texture */
- if ((gp_style) && (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
- ImBuf *ibuf;
- Image *image = gp_style->sima;
- ImageUser iuser = { NULL };
- void *lock;
-
- iuser.ok = true;
-
- ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
-
- if (ibuf == NULL || ibuf->rect == NULL) {
- BKE_image_release_ibuf(image, ibuf, NULL);
- }
- else {
- GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true);
- DRW_shgroup_uniform_texture(grp, "myTexture", texture);
-
- BKE_image_release_ibuf(image, ibuf, NULL);
- }
- }
- else {
- /* if no texture defined, need a blank texture to avoid errors in draw manager */
- DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture);
- }
-
- return grp;
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ const float *viewport_size = DRW_viewport_size_get();
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+
+ /* e_data.gpencil_stroke_sh */
+ DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
+
+ DRW_shgroup_uniform_vec2(grp, "Viewport", viewport_size, 1);
+ DRW_shgroup_uniform_float(grp, "pixsize", stl->storage->pixsize, 1);
+
+ /* avoid wrong values */
+ if ((gpd) && (gpd->pixfactor == 0.0f)) {
+ gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
+ }
+
+ /* object scale and depth */
+ if ((ob) && (id > -1)) {
+ stl->shgroups[id].obj_scale = scale;
+ DRW_shgroup_uniform_float(grp, "objscale", &stl->shgroups[id].obj_scale, 1);
+ stl->shgroups[id].keep_size = (int)((gpd) && (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS));
+ DRW_shgroup_uniform_int(grp, "keep_size", &stl->shgroups[id].keep_size, 1);
+
+ stl->shgroups[id].mode = gp_style->mode;
+ stl->shgroups[id].stroke_style = gp_style->stroke_style;
+ stl->shgroups[id].color_type = GPENCIL_COLOR_SOLID;
+ if ((gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
+ stl->shgroups[id].color_type = GPENCIL_COLOR_TEXTURE;
+ if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
+ stl->shgroups[id].color_type = GPENCIL_COLOR_PATTERN;
+ }
+ }
+ DRW_shgroup_uniform_int(grp, "color_type", &stl->shgroups[id].color_type, 1);
+ DRW_shgroup_uniform_int(grp, "mode", &stl->shgroups[id].mode, 1);
+ DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
+
+ stl->shgroups[id].gradient_f = gps->gradient_f;
+ copy_v2_v2(stl->shgroups[id].gradient_s, gps->gradient_s);
+ DRW_shgroup_uniform_float(grp, "gradient_f", &stl->shgroups[id].gradient_f, 1);
+ DRW_shgroup_uniform_vec2(grp, "gradient_s", stl->shgroups[id].gradient_s, 1);
+
+ /* viewport x-ray */
+ stl->shgroups[id].is_xray = (ob->dt == OB_WIRE) ? 1 : stl->storage->is_xray;
+ DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
+
+ stl->shgroups[id].shading_type[0] = (GPENCIL_USE_SOLID(stl) || onion) ? (int)OB_RENDER :
+ shading_type[0];
+ if (v3d) {
+ stl->shgroups[id].shading_type[1] = ((stl->shgroups[id].shading_type[0] == OB_WIRE) ?
+ v3d->shading.wire_color_type :
+ v3d->shading.color_type);
+ }
+ DRW_shgroup_uniform_int(grp, "shading_type", &stl->shgroups[id].shading_type[0], 2);
+
+ /* wire color */
+ set_wireframe_color(ob, gpl, v3d, stl, gp_style, id, false);
+ DRW_shgroup_uniform_vec4(grp, "wire_color", stl->shgroups[id].wire_color, 1);
+ }
+ else {
+ stl->storage->obj_scale = 1.0f;
+ stl->storage->keep_size = 0;
+ stl->storage->pixfactor = GP_DEFAULT_PIX_FACTOR;
+ stl->storage->mode = gp_style->mode;
+ DRW_shgroup_uniform_float(grp, "objscale", &stl->storage->obj_scale, 1);
+ DRW_shgroup_uniform_int(grp, "keep_size", &stl->storage->keep_size, 1);
+ DRW_shgroup_uniform_int(grp, "color_type", &stl->storage->color_type, 1);
+ DRW_shgroup_uniform_int(grp, "mode", &stl->storage->mode, 1);
+ if (gpd) {
+ DRW_shgroup_uniform_float(grp, "pixfactor", &gpd->pixfactor, 1);
+ }
+ else {
+ DRW_shgroup_uniform_float(grp, "pixfactor", &stl->storage->pixfactor, 1);
+ }
+
+ DRW_shgroup_uniform_float(grp, "gradient_f", &stl->storage->gradient_f, 1);
+ DRW_shgroup_uniform_vec2(grp, "gradient_s", stl->storage->gradient_s, 1);
+
+ /* viewport x-ray */
+ stl->shgroups[id].is_xray = ((ob) && (ob->dt == OB_WIRE)) ? 1 : stl->storage->is_xray;
+ DRW_shgroup_uniform_int(grp, "viewport_xray", (const int *)&stl->shgroups[id].is_xray, 1);
+ DRW_shgroup_uniform_int(grp, "shading_type", (const int *)&stl->storage->shade_render, 2);
+ }
+
+ if ((gpd) && (id > -1)) {
+ stl->shgroups[id].xray_mode = (ob->dtx & OB_DRAWXRAY) ? GP_XRAY_FRONT : GP_XRAY_3DSPACE;
+ DRW_shgroup_uniform_int(grp, "xraymode", (const int *)&stl->shgroups[id].xray_mode, 1);
+
+ /* lock rotation of dots and boxes */
+ stl->shgroups[id].use_follow_path = (gp_style->flag & GP_STYLE_COLOR_LOCK_DOTS) ? 0 : 1;
+ DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->shgroups[id].use_follow_path, 1);
+ }
+ else {
+ /* for drawing always on predefined z-depth */
+ DRW_shgroup_uniform_int(grp, "xraymode", &stl->storage->xray, 1);
+
+ /* lock rotation of dots and boxes */
+ DRW_shgroup_uniform_int(grp, "use_follow_path", &stl->storage->use_follow_path, 1);
+ }
+
+ /* image texture */
+ if ((gp_style) && (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) && (!onion)) {
+ ImBuf *ibuf;
+ Image *image = gp_style->sima;
+ ImageUser iuser = {NULL};
+ void *lock;
+
+ iuser.ok = true;
+
+ ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
+
+ if (ibuf == NULL || ibuf->rect == NULL) {
+ BKE_image_release_ibuf(image, ibuf, NULL);
+ }
+ else {
+ GPUTexture *texture = GPU_texture_from_blender(gp_style->sima, &iuser, GL_TEXTURE_2D, true);
+ DRW_shgroup_uniform_texture(grp, "myTexture", texture);
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
+ }
+ }
+ else {
+ /* if no texture defined, need a blank texture to avoid errors in draw manager */
+ DRW_shgroup_uniform_texture(grp, "myTexture", e_data->gpencil_blank_texture);
+ }
+
+ return grp;
}
/* add fill vertex info */
-static void gpencil_add_fill_vertexdata(
- GpencilBatchCache *cache,
- Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps,
- float opacity, const float tintcolor[4], const bool onion, const bool custonion)
+static void gpencil_add_fill_vertexdata(GpencilBatchCache *cache,
+ Object *ob,
+ bGPDlayer *gpl,
+ bGPDframe *gpf,
+ bGPDstroke *gps,
+ float opacity,
+ const float tintcolor[4],
+ const bool onion,
+ const bool custonion)
{
- MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
- if (gps->totpoints >= 3) {
- float tfill[4];
- /* set color using material, tint color and opacity */
- interp_v3_v3v3(tfill, gps->runtime.tmp_fill_rgba, tintcolor, tintcolor[3]);
- tfill[3] = gps->runtime.tmp_fill_rgba[3] * opacity;
- if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
- (gp_style->fill_style > 0) ||
- (gpl->blend_mode != eGplBlendMode_Normal))
- {
- if (cache->is_dirty) {
- const float *color;
- if (!onion) {
- color = tfill;
- }
- else {
- if (custonion) {
- color = tintcolor;
- }
- else {
- ARRAY_SET_ITEMS(tfill, UNPACK3(gps->runtime.tmp_fill_rgba), tintcolor[3]);
- color = tfill;
- }
- }
- /* create vertex data */
- const int old_len = cache->b_fill.vbo_len;
- DRW_gpencil_get_fill_geom(&cache->b_fill, ob, gps, color);
-
- /* add to list of groups */
- if (old_len < cache->b_fill.vbo_len) {
- cache->grp_cache = gpencil_group_cache_add(
- cache->grp_cache, gpl, gpf, gps,
- eGpencilBatchGroupType_Fill, onion,
- cache->b_fill.vbo_len,
- &cache->grp_size, &cache->grp_used);
- }
- }
- }
- }
+ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
+ if (gps->totpoints >= 3) {
+ float tfill[4];
+ /* set color using material, tint color and opacity */
+ interp_v3_v3v3(tfill, gps->runtime.tmp_fill_rgba, tintcolor, tintcolor[3]);
+ tfill[3] = gps->runtime.tmp_fill_rgba[3] * opacity;
+ if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > 0) ||
+ (gpl->blend_mode != eGplBlendMode_Normal)) {
+ if (cache->is_dirty) {
+ const float *color;
+ if (!onion) {
+ color = tfill;
+ }
+ else {
+ if (custonion) {
+ color = tintcolor;
+ }
+ else {
+ ARRAY_SET_ITEMS(tfill, UNPACK3(gps->runtime.tmp_fill_rgba), tintcolor[3]);
+ color = tfill;
+ }
+ }
+ /* create vertex data */
+ const int old_len = cache->b_fill.vbo_len;
+ DRW_gpencil_get_fill_geom(&cache->b_fill, ob, gps, color);
+
+ /* add to list of groups */
+ if (old_len < cache->b_fill.vbo_len) {
+ cache->grp_cache = gpencil_group_cache_add(cache->grp_cache,
+ gpl,
+ gpf,
+ gps,
+ eGpencilBatchGroupType_Fill,
+ onion,
+ cache->b_fill.vbo_len,
+ &cache->grp_size,
+ &cache->grp_used);
+ }
+ }
+ }
+ }
}
/* add stroke vertex info */
-static void gpencil_add_stroke_vertexdata(
- GpencilBatchCache *cache,
- Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps,
- const float opacity, const float tintcolor[4], const bool onion,
- const bool custonion)
+static void gpencil_add_stroke_vertexdata(GpencilBatchCache *cache,
+ Object *ob,
+ bGPDlayer *gpl,
+ bGPDframe *gpf,
+ bGPDstroke *gps,
+ const float opacity,
+ const float tintcolor[4],
+ const bool onion,
+ const bool custonion)
{
- float tcolor[4];
- float ink[4];
- short sthickness;
- MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
-
- /* set color using base color, tint color and opacity */
- if (cache->is_dirty) {
- if (!onion) {
- /* if special stroke, use fill color as stroke color */
- if (gps->flag & GP_STROKE_NOFILL) {
- interp_v3_v3v3(tcolor, gps->runtime.tmp_fill_rgba, tintcolor, tintcolor[3]);
- tcolor[3] = gps->runtime.tmp_fill_rgba[3] * opacity;
- }
- else {
- interp_v3_v3v3(tcolor, gps->runtime.tmp_stroke_rgba, tintcolor, tintcolor[3]);
- tcolor[3] = gps->runtime.tmp_stroke_rgba[3] * opacity;
- }
- copy_v4_v4(ink, tcolor);
- }
- else {
- if (custonion) {
- copy_v4_v4(ink, tintcolor);
- }
- else {
- ARRAY_SET_ITEMS(tcolor, UNPACK3(gps->runtime.tmp_stroke_rgba), opacity);
- copy_v4_v4(ink, tcolor);
- }
- }
-
- sthickness = gps->thickness + gpl->line_change;
- CLAMP_MIN(sthickness, 1);
-
- if ((gps->totpoints > 1) && (gp_style->mode == GP_STYLE_MODE_LINE)) {
- /* create vertex data */
- const int old_len = cache->b_stroke.vbo_len;
- DRW_gpencil_get_stroke_geom(&cache->b_stroke, gps, sthickness, ink);
-
- /* add to list of groups */
- if (old_len < cache->b_stroke.vbo_len) {
- cache->grp_cache = gpencil_group_cache_add(
- cache->grp_cache, gpl, gpf, gps,
- eGpencilBatchGroupType_Stroke, onion,
- cache->b_stroke.vbo_len,
- &cache->grp_size, &cache->grp_used);
- }
- }
- else {
- /* create vertex data */
- const int old_len = cache->b_point.vbo_len;
- DRW_gpencil_get_point_geom(&cache->b_point, gps, sthickness, ink);
-
- /* add to list of groups */
- if (old_len < cache->b_point.vbo_len) {
- cache->grp_cache = gpencil_group_cache_add(
- cache->grp_cache, gpl, gpf, gps, eGpencilBatchGroupType_Point, onion,
- cache->b_point.vbo_len,
- &cache->grp_size, &cache->grp_used);
- }
- }
- }
+ float tcolor[4];
+ float ink[4];
+ short sthickness;
+ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
+
+ /* set color using base color, tint color and opacity */
+ if (cache->is_dirty) {
+ if (!onion) {
+ /* if special stroke, use fill color as stroke color */
+ if (gps->flag & GP_STROKE_NOFILL) {
+ interp_v3_v3v3(tcolor, gps->runtime.tmp_fill_rgba, tintcolor, tintcolor[3]);
+ tcolor[3] = gps->runtime.tmp_fill_rgba[3] * opacity;
+ }
+ else {
+ interp_v3_v3v3(tcolor, gps->runtime.tmp_stroke_rgba, tintcolor, tintcolor[3]);
+ tcolor[3] = gps->runtime.tmp_stroke_rgba[3] * opacity;
+ }
+ copy_v4_v4(ink, tcolor);
+ }
+ else {
+ if (custonion) {
+ copy_v4_v4(ink, tintcolor);
+ }
+ else {
+ ARRAY_SET_ITEMS(tcolor, UNPACK3(gps->runtime.tmp_stroke_rgba), opacity);
+ copy_v4_v4(ink, tcolor);
+ }
+ }
+
+ sthickness = gps->thickness + gpl->line_change;
+ CLAMP_MIN(sthickness, 1);
+
+ if ((gps->totpoints > 1) && (gp_style->mode == GP_STYLE_MODE_LINE)) {
+ /* create vertex data */
+ const int old_len = cache->b_stroke.vbo_len;
+ DRW_gpencil_get_stroke_geom(&cache->b_stroke, gps, sthickness, ink);
+
+ /* add to list of groups */
+ if (old_len < cache->b_stroke.vbo_len) {
+ cache->grp_cache = gpencil_group_cache_add(cache->grp_cache,
+ gpl,
+ gpf,
+ gps,
+ eGpencilBatchGroupType_Stroke,
+ onion,
+ cache->b_stroke.vbo_len,
+ &cache->grp_size,
+ &cache->grp_used);
+ }
+ }
+ else {
+ /* create vertex data */
+ const int old_len = cache->b_point.vbo_len;
+ DRW_gpencil_get_point_geom(&cache->b_point, gps, sthickness, ink);
+
+ /* add to list of groups */
+ if (old_len < cache->b_point.vbo_len) {
+ cache->grp_cache = gpencil_group_cache_add(cache->grp_cache,
+ gpl,
+ gpf,
+ gps,
+ eGpencilBatchGroupType_Point,
+ onion,
+ cache->b_point.vbo_len,
+ &cache->grp_size,
+ &cache->grp_used);
+ }
+ }
+ }
}
/* add edit points vertex info */
-static void gpencil_add_editpoints_vertexdata(
- GpencilBatchCache *cache, Object *ob,
- bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps)
+static void gpencil_add_editpoints_vertexdata(GpencilBatchCache *cache,
+ Object *ob,
+ bGPdata *gpd,
+ bGPDlayer *gpl,
+ bGPDframe *gpf,
+ bGPDstroke *gps)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- View3D *v3d = draw_ctx->v3d;
- MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
-
- /* alpha factor for edit points/line to make them more subtle */
- float edit_alpha = v3d->vertex_opacity;
-
- if (GPENCIL_ANY_EDIT_MODE(gpd)) {
- Object *obact = DRW_context_state_get()->obact;
- if ((!obact) || (obact->type != OB_GPENCIL)) {
- return;
- }
- const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE);
-
- if (cache->is_dirty) {
- if ((obact == ob) &&
- ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) &&
- (v3d->gp_flag & V3D_GP_SHOW_EDIT_LINES))
- {
- /* line of the original stroke */
- DRW_gpencil_get_edlin_geom(&cache->b_edlin, gps, edit_alpha, gpd->flag);
-
- /* add to list of groups */
- cache->grp_cache = gpencil_group_cache_add(
- cache->grp_cache, gpl, gpf, gps,
- eGpencilBatchGroupType_Edlin, false,
- cache->b_edlin.vbo_len,
- &cache->grp_size, &cache->grp_used);
- }
- /* edit points */
- if ((gps->flag & GP_STROKE_SELECT) || (is_weight_paint)) {
- if ((gpl->flag & GP_LAYER_UNLOCK_COLOR) || ((gp_style->flag & GP_STYLE_COLOR_LOCKED) == 0)) {
- if (obact == ob) {
- DRW_gpencil_get_edit_geom(&cache->b_edit, gps, edit_alpha, gpd->flag);
-
- /* add to list of groups */
- cache->grp_cache = gpencil_group_cache_add(
- cache->grp_cache, gpl, gpf, gps,
- eGpencilBatchGroupType_Edit, false,
- cache->b_edit.vbo_len,
- &cache->grp_size, &cache->grp_used);
- }
- }
- }
- }
- }
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
+
+ /* alpha factor for edit points/line to make them more subtle */
+ float edit_alpha = v3d->vertex_opacity;
+
+ if (GPENCIL_ANY_EDIT_MODE(gpd)) {
+ Object *obact = DRW_context_state_get()->obact;
+ if ((!obact) || (obact->type != OB_GPENCIL)) {
+ return;
+ }
+ const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE);
+
+ if (cache->is_dirty) {
+ if ((obact == ob) && ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) &&
+ (v3d->gp_flag & V3D_GP_SHOW_EDIT_LINES)) {
+ /* line of the original stroke */
+ DRW_gpencil_get_edlin_geom(&cache->b_edlin, gps, edit_alpha, gpd->flag);
+
+ /* add to list of groups */
+ cache->grp_cache = gpencil_group_cache_add(cache->grp_cache,
+ gpl,
+ gpf,
+ gps,
+ eGpencilBatchGroupType_Edlin,
+ false,
+ cache->b_edlin.vbo_len,
+ &cache->grp_size,
+ &cache->grp_used);
+ }
+ /* edit points */
+ if ((gps->flag & GP_STROKE_SELECT) || (is_weight_paint)) {
+ if ((gpl->flag & GP_LAYER_UNLOCK_COLOR) ||
+ ((gp_style->flag & GP_STYLE_COLOR_LOCKED) == 0)) {
+ if (obact == ob) {
+ DRW_gpencil_get_edit_geom(&cache->b_edit, gps, edit_alpha, gpd->flag);
+
+ /* add to list of groups */
+ cache->grp_cache = gpencil_group_cache_add(cache->grp_cache,
+ gpl,
+ gpf,
+ gps,
+ eGpencilBatchGroupType_Edit,
+ false,
+ cache->b_edit.vbo_len,
+ &cache->grp_size,
+ &cache->grp_used);
+ }
+ }
+ }
+ }
+ }
}
/* main function to draw strokes */
-static void gpencil_draw_strokes(
- GpencilBatchCache *cache, GPENCIL_e_data *e_data, void *vedata, Object *ob,
- bGPdata *gpd, bGPDlayer *gpl, bGPDframe *src_gpf, bGPDframe *derived_gpf,
- const float opacity, const float tintcolor[4],
- const bool custonion, tGPencilObjectCache *cache_ob)
+static void gpencil_draw_strokes(GpencilBatchCache *cache,
+ GPENCIL_e_data *e_data,
+ void *vedata,
+ Object *ob,
+ bGPdata *gpd,
+ bGPDlayer *gpl,
+ bGPDframe *src_gpf,
+ bGPDframe *derived_gpf,
+ const float opacity,
+ const float tintcolor[4],
+ const bool custonion,
+ tGPencilObjectCache *cache_ob)
{
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- View3D *v3d = draw_ctx->v3d;
- bGPDstroke *gps, *src_gps;
- float viewmatrix[4][4];
- const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
- const bool playing = stl->storage->is_playing;
- const bool is_render = (bool)stl->storage->is_render;
- const bool is_mat_preview = (bool)stl->storage->is_mat_preview;
- const bool overlay_multiedit = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_MULTIEDIT_LINES) : true;
-
- /* Get evaluation context */
- /* NOTE: We must check if C is valid, otherwise we get crashes when trying to save files
- * (i.e. the thumbnail offscreen rendering fails)
- */
- Depsgraph *depsgraph = DRW_context_state_get()->depsgraph;
-
- /* get parent matrix and save as static data */
- ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, viewmatrix);
- copy_m4_m4(derived_gpf->runtime.viewmatrix, viewmatrix);
-
- if ((cache_ob != NULL) && (cache_ob->is_dup_ob)) {
- copy_m4_m4(derived_gpf->runtime.viewmatrix, cache_ob->obmat);
- }
-
- /* apply geometry modifiers */
- if ((cache->is_dirty) && (ob->greasepencil_modifiers.first) && (!is_multiedit)) {
- if (!stl->storage->simplify_modif) {
- if (BKE_gpencil_has_geometry_modifiers(ob)) {
- BKE_gpencil_geometry_modifiers(depsgraph, ob, gpl, derived_gpf, stl->storage->is_render);
- }
- }
- }
-
- if (src_gpf) {
- src_gps = src_gpf->strokes.first;
- }
- else {
- src_gps = NULL;
- }
-
- for (gps = derived_gpf->strokes.first; gps; gps = gps->next) {
- MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
-
- /* check if stroke can be drawn */
- if (gpencil_can_draw_stroke(gp_style, gps, false, is_mat_preview) == false) {
- GP_SET_SRC_GPS(src_gps);
- continue;
- }
-
- /* be sure recalc all cache in source stroke to avoid recalculation when frame change
- * and improve fps */
- if (src_gps) {
- DRW_gpencil_recalc_geometry_caches(ob, gpl, gp_style, src_gps);
- }
-
- /* if the fill has any value, it's considered a fill and is not drawn if simplify fill is enabled */
- if ((stl->storage->simplify_fill) &&
- (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_REMOVE_FILL_LINE))
- {
- if ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
- (gp_style->fill_style > GP_STYLE_FILL_STYLE_SOLID) ||
- (gpl->blend_mode != eGplBlendMode_Normal))
- {
- GP_SET_SRC_GPS(src_gps);
- continue;
- }
- }
-
- if ((gpl->actframe->framenum == derived_gpf->framenum) ||
- (!is_multiedit) || (overlay_multiedit))
- {
- /* copy color to temp fields to apply temporal changes in the stroke */
- copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba);
- copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba);
-
- /* apply modifiers (only modify geometry, but not create ) */
- if ((cache->is_dirty) && (ob->greasepencil_modifiers.first) && (!is_multiedit)) {
- if (!stl->storage->simplify_modif) {
- BKE_gpencil_stroke_modifiers(depsgraph, ob, gpl, derived_gpf, gps, stl->storage->is_render);
- }
- }
-
- /* hide any blend layer */
- if ((!stl->storage->simplify_blend) ||
- (gpl->blend_mode == eGplBlendMode_Normal))
- {
- /* fill */
- if ((gp_style->flag & GP_STYLE_FILL_SHOW) &&
- (!stl->storage->simplify_fill) &&
- ((gps->flag & GP_STROKE_NOFILL) == 0))
- {
- gpencil_add_fill_vertexdata(
- cache, ob, gpl, derived_gpf, gps,
- opacity, tintcolor, false, custonion);
- }
- /* stroke */
- /* No fill strokes, must show stroke always */
- if (((gp_style->flag & GP_STYLE_STROKE_SHOW) ||
- (gps->flag & GP_STROKE_NOFILL)) &&
- ((gp_style->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
- (gpl->blend_mode == eGplBlendMode_Normal)))
- {
- /* recalc strokes uv (geometry can be changed by modifiers) */
- if (gps->flag & GP_STROKE_RECALC_GEOMETRY) {
- ED_gpencil_calc_stroke_uv(ob, gps);
- }
-
- gpencil_add_stroke_vertexdata(
- cache, ob, gpl, derived_gpf, gps,
- opacity, tintcolor, false, custonion);
- }
- }
- }
-
- /* edit points (only in edit mode and not play animation not render) */
- if ((draw_ctx->obact == ob) && (src_gps) &&
- (!playing) && (!is_render) && (!cache_ob->is_dup_ob))
- {
- if ((gpl->flag & GP_LAYER_LOCKED) == 0) {
- if (!stl->g_data->shgrps_edit_line) {
- stl->g_data->shgrps_edit_line = DRW_shgroup_create(e_data->gpencil_line_sh, psl->edit_pass);
- }
- if (!stl->g_data->shgrps_edit_point) {
- stl->g_data->shgrps_edit_point = DRW_shgroup_create(e_data->gpencil_edit_point_sh, psl->edit_pass);
- const float *viewport_size = DRW_viewport_size_get();
- DRW_shgroup_uniform_vec2(stl->g_data->shgrps_edit_point, "Viewport", viewport_size, 1);
- }
-
- gpencil_add_editpoints_vertexdata(cache, ob, gpd, gpl, derived_gpf, src_gps);
- }
- }
-
- GP_SET_SRC_GPS(src_gps);
- }
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ View3D *v3d = draw_ctx->v3d;
+ bGPDstroke *gps, *src_gps;
+ float viewmatrix[4][4];
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const bool playing = stl->storage->is_playing;
+ const bool is_render = (bool)stl->storage->is_render;
+ const bool is_mat_preview = (bool)stl->storage->is_mat_preview;
+ const bool overlay_multiedit = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_MULTIEDIT_LINES) : true;
+
+ /* Get evaluation context */
+ /* NOTE: We must check if C is valid, otherwise we get crashes when trying to save files
+ * (i.e. the thumbnail offscreen rendering fails)
+ */
+ Depsgraph *depsgraph = DRW_context_state_get()->depsgraph;
+
+ /* get parent matrix and save as static data */
+ ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, viewmatrix);
+ copy_m4_m4(derived_gpf->runtime.viewmatrix, viewmatrix);
+
+ if ((cache_ob != NULL) && (cache_ob->is_dup_ob)) {
+ copy_m4_m4(derived_gpf->runtime.viewmatrix, cache_ob->obmat);
+ }
+
+ /* apply geometry modifiers */
+ if ((cache->is_dirty) && (ob->greasepencil_modifiers.first) && (!is_multiedit)) {
+ if (!stl->storage->simplify_modif) {
+ if (BKE_gpencil_has_geometry_modifiers(ob)) {
+ BKE_gpencil_geometry_modifiers(depsgraph, ob, gpl, derived_gpf, stl->storage->is_render);
+ }
+ }
+ }
+
+ if (src_gpf) {
+ src_gps = src_gpf->strokes.first;
+ }
+ else {
+ src_gps = NULL;
+ }
+
+ for (gps = derived_gpf->strokes.first; gps; gps = gps->next) {
+ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
+
+ /* check if stroke can be drawn */
+ if (gpencil_can_draw_stroke(gp_style, gps, false, is_mat_preview) == false) {
+ GP_SET_SRC_GPS(src_gps);
+ continue;
+ }
+
+ /* be sure recalc all cache in source stroke to avoid recalculation when frame change
+ * and improve fps */
+ if (src_gps) {
+ DRW_gpencil_recalc_geometry_caches(ob, gpl, gp_style, src_gps);
+ }
+
+ /* if the fill has any value, it's considered a fill and is not drawn if simplify fill is enabled */
+ if ((stl->storage->simplify_fill) &&
+ (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_REMOVE_FILL_LINE)) {
+ if ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
+ (gp_style->fill_style > GP_STYLE_FILL_STYLE_SOLID) ||
+ (gpl->blend_mode != eGplBlendMode_Normal)) {
+ GP_SET_SRC_GPS(src_gps);
+ continue;
+ }
+ }
+
+ if ((gpl->actframe->framenum == derived_gpf->framenum) || (!is_multiedit) ||
+ (overlay_multiedit)) {
+ /* copy color to temp fields to apply temporal changes in the stroke */
+ copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba);
+ copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba);
+
+ /* apply modifiers (only modify geometry, but not create ) */
+ if ((cache->is_dirty) && (ob->greasepencil_modifiers.first) && (!is_multiedit)) {
+ if (!stl->storage->simplify_modif) {
+ BKE_gpencil_stroke_modifiers(
+ depsgraph, ob, gpl, derived_gpf, gps, stl->storage->is_render);
+ }
+ }
+
+ /* hide any blend layer */
+ if ((!stl->storage->simplify_blend) || (gpl->blend_mode == eGplBlendMode_Normal)) {
+ /* fill */
+ if ((gp_style->flag & GP_STYLE_FILL_SHOW) && (!stl->storage->simplify_fill) &&
+ ((gps->flag & GP_STROKE_NOFILL) == 0)) {
+ gpencil_add_fill_vertexdata(
+ cache, ob, gpl, derived_gpf, gps, opacity, tintcolor, false, custonion);
+ }
+ /* stroke */
+ /* No fill strokes, must show stroke always */
+ if (((gp_style->flag & GP_STYLE_STROKE_SHOW) || (gps->flag & GP_STROKE_NOFILL)) &&
+ ((gp_style->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) ||
+ (gpl->blend_mode == eGplBlendMode_Normal))) {
+ /* recalc strokes uv (geometry can be changed by modifiers) */
+ if (gps->flag & GP_STROKE_RECALC_GEOMETRY) {
+ ED_gpencil_calc_stroke_uv(ob, gps);
+ }
+
+ gpencil_add_stroke_vertexdata(
+ cache, ob, gpl, derived_gpf, gps, opacity, tintcolor, false, custonion);
+ }
+ }
+ }
+
+ /* edit points (only in edit mode and not play animation not render) */
+ if ((draw_ctx->obact == ob) && (src_gps) && (!playing) && (!is_render) &&
+ (!cache_ob->is_dup_ob)) {
+ if ((gpl->flag & GP_LAYER_LOCKED) == 0) {
+ if (!stl->g_data->shgrps_edit_line) {
+ stl->g_data->shgrps_edit_line = DRW_shgroup_create(e_data->gpencil_line_sh,
+ psl->edit_pass);
+ }
+ if (!stl->g_data->shgrps_edit_point) {
+ stl->g_data->shgrps_edit_point = DRW_shgroup_create(e_data->gpencil_edit_point_sh,
+ psl->edit_pass);
+ const float *viewport_size = DRW_viewport_size_get();
+ DRW_shgroup_uniform_vec2(stl->g_data->shgrps_edit_point, "Viewport", viewport_size, 1);
+ }
+
+ gpencil_add_editpoints_vertexdata(cache, ob, gpd, gpl, derived_gpf, src_gps);
+ }
+ }
+
+ GP_SET_SRC_GPS(src_gps);
+ }
}
/* get alpha factor for onion strokes */
@@ -1072,847 +1122,919 @@ static void gpencil_get_onion_alpha(float color[4], bGPdata *gpd)
{
#define MIN_ALPHA_VALUE 0.01f
- /* if fade is disabled, opacity is equal in all frames */
- if ((gpd->onion_flag & GP_ONION_FADE) == 0) {
- color[3] = gpd->onion_factor;
- }
- else {
- /* add override opacity factor */
- color[3] += gpd->onion_factor - 0.5f;
- }
+ /* if fade is disabled, opacity is equal in all frames */
+ if ((gpd->onion_flag & GP_ONION_FADE) == 0) {
+ color[3] = gpd->onion_factor;
+ }
+ else {
+ /* add override opacity factor */
+ color[3] += gpd->onion_factor - 0.5f;
+ }
- CLAMP(color[3], MIN_ALPHA_VALUE, 1.0f);
+ CLAMP(color[3], MIN_ALPHA_VALUE, 1.0f);
}
/* function to draw strokes for onion only */
-static void gpencil_draw_onion_strokes(
- GpencilBatchCache *cache, void *vedata, Object *ob,
- bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf,
- const float opacity, const float tintcolor[4], const bool custonion)
+static void gpencil_draw_onion_strokes(GpencilBatchCache *cache,
+ void *vedata,
+ Object *ob,
+ bGPdata *gpd,
+ bGPDlayer *gpl,
+ bGPDframe *gpf,
+ const float opacity,
+ const float tintcolor[4],
+ const bool custonion)
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- Depsgraph *depsgraph = DRW_context_state_get()->depsgraph;
-
- float viewmatrix[4][4];
-
- /* get parent matrix and save as static data */
- ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, viewmatrix);
- copy_m4_m4(gpf->runtime.viewmatrix, viewmatrix);
-
- for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
- MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
- if (gp_style == NULL) {
- continue;
- }
- copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba);
- copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba);
-
- int id = stl->storage->shgroup_id;
- /* check if stroke can be drawn */
- if (gpencil_can_draw_stroke(gp_style, gps, true, false) == false) {
- continue;
- }
- /* limit the number of shading groups */
- if (id >= GPENCIL_MAX_SHGROUPS) {
- continue;
- }
-
- /* stroke */
- gpencil_add_stroke_vertexdata(
- cache, ob, gpl, gpf, gps, opacity, tintcolor,
- true, custonion);
-
- stl->storage->shgroup_id++;
- }
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ Depsgraph *depsgraph = DRW_context_state_get()->depsgraph;
+
+ float viewmatrix[4][4];
+
+ /* get parent matrix and save as static data */
+ ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, viewmatrix);
+ copy_m4_m4(gpf->runtime.viewmatrix, viewmatrix);
+
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
+ if (gp_style == NULL) {
+ continue;
+ }
+ copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba);
+ copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba);
+
+ int id = stl->storage->shgroup_id;
+ /* check if stroke can be drawn */
+ if (gpencil_can_draw_stroke(gp_style, gps, true, false) == false) {
+ continue;
+ }
+ /* limit the number of shading groups */
+ if (id >= GPENCIL_MAX_SHGROUPS) {
+ continue;
+ }
+
+ /* stroke */
+ gpencil_add_stroke_vertexdata(cache, ob, gpl, gpf, gps, opacity, tintcolor, true, custonion);
+
+ stl->storage->shgroup_id++;
+ }
}
/* draw onion-skinning for a layer */
-static void gpencil_draw_onionskins(
- GpencilBatchCache *cache, void *vedata,
- Object *ob, bGPdata *gpd, bGPDlayer *gpl, bGPDframe *gpf)
+static void gpencil_draw_onionskins(GpencilBatchCache *cache,
+ void *vedata,
+ Object *ob,
+ bGPdata *gpd,
+ bGPDlayer *gpl,
+ bGPDframe *gpf)
{
- const float default_color[3] = { UNPACK3(U.gpencil_new_layer_col) };
- const float alpha = 1.0f;
- float color[4];
- int idx;
- float fac = 1.0f;
- int step = 0;
- int mode = 0;
- bool colflag = false;
- bGPDframe *gpf_loop = NULL;
- int last = gpf->framenum;
-
- colflag = (bool)gpd->onion_flag & GP_ONION_GHOST_PREVCOL;
-
- /* -------------------------------
- * 1) Draw Previous Frames First
- * ------------------------------- */
- step = gpd->gstep;
- mode = gpd->onion_mode;
-
- if (gpd->onion_flag & GP_ONION_GHOST_PREVCOL) {
- copy_v3_v3(color, gpd->gcolor_prev);
- }
- else {
- copy_v3_v3(color, default_color);
- }
-
- idx = 0;
- for (bGPDframe *gf = gpf->prev; gf; gf = gf->prev) {
- /* only selected frames */
- if ((mode == GP_ONION_MODE_SELECTED) && ((gf->flag & GP_FRAME_SELECT) == 0)) {
- continue;
- }
- /* absolute range */
- if (mode == GP_ONION_MODE_ABSOLUTE) {
- if ((gpf->framenum - gf->framenum) > step) {
- break;
- }
- }
- /* relative range */
- if (mode == GP_ONION_MODE_RELATIVE) {
- idx++;
- if (idx > step) {
- break;
- }
-
- }
- /* alpha decreases with distance from curframe index */
- if (mode != GP_ONION_MODE_SELECTED) {
- if (mode == GP_ONION_MODE_ABSOLUTE) {
- fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(step + 1));
- }
- else {
- fac = 1.0f - ((float)idx / (float)(step + 1));
- }
- color[3] = alpha * fac * 0.66f;
- }
- else {
- idx++;
- fac = alpha - ((1.1f - (1.0f / (float)idx)) * 0.66f);
- color[3] = fac;
- }
-
- /* if loop option, save the frame to use later */
- if ((mode != GP_ONION_MODE_ABSOLUTE) && (gpd->onion_flag & GP_ONION_LOOP)) {
- gpf_loop = gf;
- }
-
- gpencil_get_onion_alpha(color, gpd);
- gpencil_draw_onion_strokes(cache, vedata, ob, gpd, gpl, gf, color[3], color, colflag);
- }
- /* -------------------------------
- * 2) Now draw next frames
- * ------------------------------- */
- step = gpd->gstep_next;
- mode = gpd->onion_mode;
-
- if (gpd->onion_flag & GP_ONION_GHOST_NEXTCOL) {
- copy_v3_v3(color, gpd->gcolor_next);
- }
- else {
- copy_v3_v3(color, default_color);
- }
-
- idx = 0;
- for (bGPDframe *gf = gpf->next; gf; gf = gf->next) {
- /* only selected frames */
- if ((mode == GP_ONION_MODE_SELECTED) && ((gf->flag & GP_FRAME_SELECT) == 0)) {
- continue;
- }
- /* absolute range */
- if (mode == GP_ONION_MODE_ABSOLUTE) {
- if ((gf->framenum - gpf->framenum) > step) {
- break;
- }
- }
- /* relative range */
- if (mode == GP_ONION_MODE_RELATIVE) {
- idx++;
- if (idx > step) {
- break;
- }
-
- }
- /* alpha decreases with distance from curframe index */
- if (mode != GP_ONION_MODE_SELECTED) {
- if (mode == GP_ONION_MODE_ABSOLUTE) {
- fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(step + 1));
- }
- else {
- fac = 1.0f - ((float)idx / (float)(step + 1));
- }
- color[3] = alpha * fac * 0.66f;
- }
- else {
- idx++;
- fac = alpha - ((1.1f - (1.0f / (float)idx)) * 0.66f);
- color[3] = fac;
- }
-
- gpencil_get_onion_alpha(color, gpd);
- gpencil_draw_onion_strokes(cache, vedata, ob, gpd, gpl, gf, color[3], color, colflag);
- if (last < gf->framenum) {
- last = gf->framenum;
- }
- }
-
- /* Draw first frame in blue for loop mode */
- if ((gpd->onion_flag & GP_ONION_LOOP) && (gpf_loop != NULL)) {
- if ((last == gpf->framenum) || (gpf->next == NULL)) {
- gpencil_get_onion_alpha(color, gpd);
- gpencil_draw_onion_strokes(
- cache, vedata, ob, gpd, gpl,
- gpf_loop, color[3], color, colflag);
- }
- }
+ const float default_color[3] = {UNPACK3(U.gpencil_new_layer_col)};
+ const float alpha = 1.0f;
+ float color[4];
+ int idx;
+ float fac = 1.0f;
+ int step = 0;
+ int mode = 0;
+ bool colflag = false;
+ bGPDframe *gpf_loop = NULL;
+ int last = gpf->framenum;
+
+ colflag = (bool)gpd->onion_flag & GP_ONION_GHOST_PREVCOL;
+
+ /* -------------------------------
+ * 1) Draw Previous Frames First
+ * ------------------------------- */
+ step = gpd->gstep;
+ mode = gpd->onion_mode;
+
+ if (gpd->onion_flag & GP_ONION_GHOST_PREVCOL) {
+ copy_v3_v3(color, gpd->gcolor_prev);
+ }
+ else {
+ copy_v3_v3(color, default_color);
+ }
+
+ idx = 0;
+ for (bGPDframe *gf = gpf->prev; gf; gf = gf->prev) {
+ /* only selected frames */
+ if ((mode == GP_ONION_MODE_SELECTED) && ((gf->flag & GP_FRAME_SELECT) == 0)) {
+ continue;
+ }
+ /* absolute range */
+ if (mode == GP_ONION_MODE_ABSOLUTE) {
+ if ((gpf->framenum - gf->framenum) > step) {
+ break;
+ }
+ }
+ /* relative range */
+ if (mode == GP_ONION_MODE_RELATIVE) {
+ idx++;
+ if (idx > step) {
+ break;
+ }
+ }
+ /* alpha decreases with distance from curframe index */
+ if (mode != GP_ONION_MODE_SELECTED) {
+ if (mode == GP_ONION_MODE_ABSOLUTE) {
+ fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(step + 1));
+ }
+ else {
+ fac = 1.0f - ((float)idx / (float)(step + 1));
+ }
+ color[3] = alpha * fac * 0.66f;
+ }
+ else {
+ idx++;
+ fac = alpha - ((1.1f - (1.0f / (float)idx)) * 0.66f);
+ color[3] = fac;
+ }
+
+ /* if loop option, save the frame to use later */
+ if ((mode != GP_ONION_MODE_ABSOLUTE) && (gpd->onion_flag & GP_ONION_LOOP)) {
+ gpf_loop = gf;
+ }
+
+ gpencil_get_onion_alpha(color, gpd);
+ gpencil_draw_onion_strokes(cache, vedata, ob, gpd, gpl, gf, color[3], color, colflag);
+ }
+ /* -------------------------------
+ * 2) Now draw next frames
+ * ------------------------------- */
+ step = gpd->gstep_next;
+ mode = gpd->onion_mode;
+
+ if (gpd->onion_flag & GP_ONION_GHOST_NEXTCOL) {
+ copy_v3_v3(color, gpd->gcolor_next);
+ }
+ else {
+ copy_v3_v3(color, default_color);
+ }
+
+ idx = 0;
+ for (bGPDframe *gf = gpf->next; gf; gf = gf->next) {
+ /* only selected frames */
+ if ((mode == GP_ONION_MODE_SELECTED) && ((gf->flag & GP_FRAME_SELECT) == 0)) {
+ continue;
+ }
+ /* absolute range */
+ if (mode == GP_ONION_MODE_ABSOLUTE) {
+ if ((gf->framenum - gpf->framenum) > step) {
+ break;
+ }
+ }
+ /* relative range */
+ if (mode == GP_ONION_MODE_RELATIVE) {
+ idx++;
+ if (idx > step) {
+ break;
+ }
+ }
+ /* alpha decreases with distance from curframe index */
+ if (mode != GP_ONION_MODE_SELECTED) {
+ if (mode == GP_ONION_MODE_ABSOLUTE) {
+ fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(step + 1));
+ }
+ else {
+ fac = 1.0f - ((float)idx / (float)(step + 1));
+ }
+ color[3] = alpha * fac * 0.66f;
+ }
+ else {
+ idx++;
+ fac = alpha - ((1.1f - (1.0f / (float)idx)) * 0.66f);
+ color[3] = fac;
+ }
+
+ gpencil_get_onion_alpha(color, gpd);
+ gpencil_draw_onion_strokes(cache, vedata, ob, gpd, gpl, gf, color[3], color, colflag);
+ if (last < gf->framenum) {
+ last = gf->framenum;
+ }
+ }
+
+ /* Draw first frame in blue for loop mode */
+ if ((gpd->onion_flag & GP_ONION_LOOP) && (gpf_loop != NULL)) {
+ if ((last == gpf->framenum) || (gpf->next == NULL)) {
+ gpencil_get_onion_alpha(color, gpd);
+ gpencil_draw_onion_strokes(cache, vedata, ob, gpd, gpl, gpf_loop, color[3], color, colflag);
+ }
+ }
}
static void gpencil_copy_frame(bGPDframe *gpf, bGPDframe *derived_gpf)
{
- derived_gpf->prev = gpf->prev;
- derived_gpf->next = gpf->next;
- derived_gpf->framenum = gpf->framenum;
- derived_gpf->flag = gpf->flag;
- derived_gpf->key_type = gpf->key_type;
- derived_gpf->runtime = gpf->runtime;
- copy_m4_m4(derived_gpf->runtime.viewmatrix, gpf->runtime.viewmatrix);
-
- /* copy strokes */
- BLI_listbase_clear(&derived_gpf->strokes);
- for (bGPDstroke *gps_src = gpf->strokes.first; gps_src; gps_src = gps_src->next) {
- /* make copy of source stroke */
- bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps_src);
- BLI_addtail(&derived_gpf->strokes, gps_dst);
- }
+ derived_gpf->prev = gpf->prev;
+ derived_gpf->next = gpf->next;
+ derived_gpf->framenum = gpf->framenum;
+ derived_gpf->flag = gpf->flag;
+ derived_gpf->key_type = gpf->key_type;
+ derived_gpf->runtime = gpf->runtime;
+ copy_m4_m4(derived_gpf->runtime.viewmatrix, gpf->runtime.viewmatrix);
+
+ /* copy strokes */
+ BLI_listbase_clear(&derived_gpf->strokes);
+ for (bGPDstroke *gps_src = gpf->strokes.first; gps_src; gps_src = gps_src->next) {
+ /* make copy of source stroke */
+ bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps_src);
+ BLI_addtail(&derived_gpf->strokes, gps_dst);
+ }
}
/* Triangulate stroke for high quality fill (this is done only if cache is null or stroke was modified) */
void DRW_gpencil_triangulate_stroke_fill(Object *ob, bGPDstroke *gps)
{
- BLI_assert(gps->totpoints >= 3);
-
- bGPdata *gpd = (bGPdata *)ob->data;
-
- /* allocate memory for temporary areas */
- gps->tot_triangles = gps->totpoints - 2;
- uint(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles, "GP Stroke temp triangulation");
- float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * gps->totpoints, "GP Stroke temp 2d points");
- float(*uv)[2] = MEM_mallocN(sizeof(*uv) * gps->totpoints, "GP Stroke temp 2d uv data");
-
- int direction = 0;
-
- /* convert to 2d and triangulate */
- BKE_gpencil_stroke_2d_flat(gps->points, gps->totpoints, points2d, &direction);
- BLI_polyfill_calc(points2d, (uint)gps->totpoints, direction, tmp_triangles);
-
- /* calc texture coordinates automatically */
- float minv[2];
- float maxv[2];
- /* first needs bounding box data */
- if (gpd->flag & GP_DATA_UV_ADAPTIVE) {
- gpencil_calc_2d_bounding_box(points2d, gps->totpoints, minv, maxv);
- }
- else {
- ARRAY_SET_ITEMS(minv, -1.0f, -1.0f);
- ARRAY_SET_ITEMS(maxv, 1.0f, 1.0f);
- }
-
- /* calc uv data */
- gpencil_calc_stroke_fill_uv(points2d, gps->totpoints, minv, maxv, uv);
-
- /* Number of triangles */
- gps->tot_triangles = gps->totpoints - 2;
- /* save triangulation data in stroke cache */
- if (gps->tot_triangles > 0) {
- if (gps->triangles == NULL) {
- gps->triangles = MEM_callocN(sizeof(*gps->triangles) * gps->tot_triangles, "GP Stroke triangulation");
- }
- else {
- gps->triangles = MEM_recallocN(gps->triangles, sizeof(*gps->triangles) * gps->tot_triangles);
- }
-
- for (int i = 0; i < gps->tot_triangles; i++) {
- bGPDtriangle *stroke_triangle = &gps->triangles[i];
- memcpy(gps->triangles[i].verts, tmp_triangles[i], sizeof(uint[3]));
- /* copy texture coordinates */
- copy_v2_v2(stroke_triangle->uv[0], uv[tmp_triangles[i][0]]);
- copy_v2_v2(stroke_triangle->uv[1], uv[tmp_triangles[i][1]]);
- copy_v2_v2(stroke_triangle->uv[2], uv[tmp_triangles[i][2]]);
- }
- }
- else {
- /* No triangles needed - Free anything allocated previously */
- if (gps->triangles) {
- MEM_freeN(gps->triangles);
- }
-
- gps->triangles = NULL;
- }
-
- /* disable recalculation flag */
- if (gps->flag & GP_STROKE_RECALC_GEOMETRY) {
- gps->flag &= ~GP_STROKE_RECALC_GEOMETRY;
- }
-
- /* clear memory */
- MEM_SAFE_FREE(tmp_triangles);
- MEM_SAFE_FREE(points2d);
- MEM_SAFE_FREE(uv);
+ BLI_assert(gps->totpoints >= 3);
+
+ bGPdata *gpd = (bGPdata *)ob->data;
+
+ /* allocate memory for temporary areas */
+ gps->tot_triangles = gps->totpoints - 2;
+ uint(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->tot_triangles,
+ "GP Stroke temp triangulation");
+ float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * gps->totpoints,
+ "GP Stroke temp 2d points");
+ float(*uv)[2] = MEM_mallocN(sizeof(*uv) * gps->totpoints, "GP Stroke temp 2d uv data");
+
+ int direction = 0;
+
+ /* convert to 2d and triangulate */
+ BKE_gpencil_stroke_2d_flat(gps->points, gps->totpoints, points2d, &direction);
+ BLI_polyfill_calc(points2d, (uint)gps->totpoints, direction, tmp_triangles);
+
+ /* calc texture coordinates automatically */
+ float minv[2];
+ float maxv[2];
+ /* first needs bounding box data */
+ if (gpd->flag & GP_DATA_UV_ADAPTIVE) {
+ gpencil_calc_2d_bounding_box(points2d, gps->totpoints, minv, maxv);
+ }
+ else {
+ ARRAY_SET_ITEMS(minv, -1.0f, -1.0f);
+ ARRAY_SET_ITEMS(maxv, 1.0f, 1.0f);
+ }
+
+ /* calc uv data */
+ gpencil_calc_stroke_fill_uv(points2d, gps->totpoints, minv, maxv, uv);
+
+ /* Number of triangles */
+ gps->tot_triangles = gps->totpoints - 2;
+ /* save triangulation data in stroke cache */
+ if (gps->tot_triangles > 0) {
+ if (gps->triangles == NULL) {
+ gps->triangles = MEM_callocN(sizeof(*gps->triangles) * gps->tot_triangles,
+ "GP Stroke triangulation");
+ }
+ else {
+ gps->triangles = MEM_recallocN(gps->triangles, sizeof(*gps->triangles) * gps->tot_triangles);
+ }
+
+ for (int i = 0; i < gps->tot_triangles; i++) {
+ bGPDtriangle *stroke_triangle = &gps->triangles[i];
+ memcpy(gps->triangles[i].verts, tmp_triangles[i], sizeof(uint[3]));
+ /* copy texture coordinates */
+ copy_v2_v2(stroke_triangle->uv[0], uv[tmp_triangles[i][0]]);
+ copy_v2_v2(stroke_triangle->uv[1], uv[tmp_triangles[i][1]]);
+ copy_v2_v2(stroke_triangle->uv[2], uv[tmp_triangles[i][2]]);
+ }
+ }
+ else {
+ /* No triangles needed - Free anything allocated previously */
+ if (gps->triangles) {
+ MEM_freeN(gps->triangles);
+ }
+
+ gps->triangles = NULL;
+ }
+
+ /* disable recalculation flag */
+ if (gps->flag & GP_STROKE_RECALC_GEOMETRY) {
+ gps->flag &= ~GP_STROKE_RECALC_GEOMETRY;
+ }
+
+ /* clear memory */
+ MEM_SAFE_FREE(tmp_triangles);
+ MEM_SAFE_FREE(points2d);
+ MEM_SAFE_FREE(uv);
}
/* draw stroke in drawing buffer */
-void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, ToolSettings *ts, Object *ob)
+void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data,
+ void *vedata,
+ ToolSettings *ts,
+ Object *ob)
{
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- View3D *v3d = draw_ctx->v3d;
- const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
- Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
- bGPdata *gpd_eval = ob->data;
- /* need the original to avoid cow overhead while drawing */
- bGPdata *gpd = (bGPdata *)DEG_get_original_id(&gpd_eval->id);
-
- MaterialGPencilStyle *gp_style = NULL;
- float obscale = mat4_to_scale(ob->obmat);
-
- /* use the brush material */
- Material *ma = BKE_gpencil_object_material_get_from_brush(ob, brush);
- if (ma != NULL) {
- gp_style = ma->gp_style;
- }
- /* this is not common, but avoid any special situations when brush could be without material */
- if (gp_style == NULL) {
- gp_style = BKE_material_gpencil_settings_get(ob, ob->actcol);
- }
-
- /* drawing strokes */
- /* Check if may need to draw the active stroke cache, only if this layer is the active layer
- * that is being edited. (Stroke buffer is currently stored in gp-data)
- */
- if (gpd->runtime.sbuffer_size > 0) {
- if ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) {
- /* It should also be noted that sbuffer contains temporary point types
- * i.e. tGPspoints NOT bGPDspoints
- */
- short lthick = brush->size * obscale;
-
- /* save gradient info */
- stl->storage->gradient_f = brush->gpencil_settings->gradient_f;
- copy_v2_v2(stl->storage->gradient_s, brush->gpencil_settings->gradient_s);
- stl->storage->use_follow_path = (gp_style->flag & GP_STYLE_COLOR_LOCK_DOTS) ? 0 : 1;
-
- /* if only one point, don't need to draw buffer because the user has no time to see it */
- if (gpd->runtime.sbuffer_size > 1) {
- if ((gp_style) && (gp_style->mode == GP_STYLE_MODE_LINE)) {
- stl->g_data->shgrps_drawing_stroke = DRW_gpencil_shgroup_stroke_create(
- e_data, vedata, psl->drawing_pass, e_data->gpencil_stroke_sh, NULL,
- gpd, NULL, NULL, gp_style, -1,
- false, 1.0f, (const int *)stl->storage->shade_render);
- }
- else {
- stl->g_data->shgrps_drawing_stroke = DRW_gpencil_shgroup_point_create(
- e_data, vedata, psl->drawing_pass, e_data->gpencil_point_sh, NULL,
- gpd, NULL, NULL, gp_style, -1,
- false, 1.0f, (const int *)stl->storage->shade_render);
- }
-
- /* clean previous version of the batch */
- if (stl->storage->buffer_stroke) {
- GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_stroke);
- MEM_SAFE_FREE(e_data->batch_buffer_stroke);
- stl->storage->buffer_stroke = false;
- }
-
- /* use unit matrix because the buffer is in screen space and does not need conversion */
- if (gpd->runtime.mode == GP_STYLE_MODE_LINE) {
- e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_stroke_geom(
- gpd, lthick);
- }
- else {
- e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_point_geom(
- gpd, lthick);
- }
-
- /* buffer strokes, must show stroke always */
- DRW_shgroup_call_add(
- stl->g_data->shgrps_drawing_stroke,
- e_data->batch_buffer_stroke,
- stl->storage->unit_matrix);
-
- if ((gpd->runtime.sbuffer_size >= 3) &&
- (gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) &&
- ((gpd->runtime.sbuffer_sflag & GP_STROKE_NOFILL) == 0) &&
- ((brush->gpencil_settings->flag & GP_BRUSH_DISSABLE_LASSO) == 0) &&
- (gp_style->flag & GP_STYLE_FILL_SHOW))
- {
- /* if not solid, fill is simulated with solid color */
- if (gpd->runtime.bfill_style > 0) {
- gpd->runtime.sfill[3] = 0.5f;
- }
- stl->g_data->shgrps_drawing_fill = DRW_shgroup_create(
- e_data->gpencil_drawing_fill_sh, psl->drawing_pass);
-
- /* clean previous version of the batch */
- if (stl->storage->buffer_fill) {
- GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_fill);
- MEM_SAFE_FREE(e_data->batch_buffer_fill);
- stl->storage->buffer_fill = false;
- }
-
- e_data->batch_buffer_fill = DRW_gpencil_get_buffer_fill_geom(gpd);
- DRW_shgroup_call_add(
- stl->g_data->shgrps_drawing_fill,
- e_data->batch_buffer_fill,
- stl->storage->unit_matrix);
- stl->storage->buffer_fill = true;
- }
- stl->storage->buffer_stroke = true;
- }
- }
- }
-
- /* control points for primitives and speed guide */
- const bool is_cppoint = (gpd->runtime.tot_cp_points > 0);
- const bool is_speed_guide = (ts->gp_sculpt.guide.use_guide && (draw_ctx->object_mode == OB_MODE_PAINT_GPENCIL));
- const bool is_show_gizmo = (((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) && ((v3d->gizmo_flag & V3D_GIZMO_HIDE_TOOL) == 0));
-
- if ((overlay) && (is_cppoint || is_speed_guide) && (is_show_gizmo) &&
- ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0))
- {
- DRWShadingGroup *shgrp = DRW_shgroup_create(
- e_data->gpencil_edit_point_sh, psl->drawing_pass);
- const float *viewport_size = DRW_viewport_size_get();
- DRW_shgroup_uniform_vec2(shgrp, "Viewport", viewport_size, 1);
-
- /* clean previous version of the batch */
- if (stl->storage->buffer_ctrlpoint) {
- GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_ctrlpoint);
- MEM_SAFE_FREE(e_data->batch_buffer_ctrlpoint);
- stl->storage->buffer_ctrlpoint = false;
- }
-
- e_data->batch_buffer_ctrlpoint = DRW_gpencil_get_buffer_ctrlpoint_geom(gpd);
-
- DRW_shgroup_call_add(
- shgrp,
- e_data->batch_buffer_ctrlpoint,
- stl->storage->unit_matrix);
-
- stl->storage->buffer_ctrlpoint = true;
- }
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+ const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
+ Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
+ bGPdata *gpd_eval = ob->data;
+ /* need the original to avoid cow overhead while drawing */
+ bGPdata *gpd = (bGPdata *)DEG_get_original_id(&gpd_eval->id);
+
+ MaterialGPencilStyle *gp_style = NULL;
+ float obscale = mat4_to_scale(ob->obmat);
+
+ /* use the brush material */
+ Material *ma = BKE_gpencil_object_material_get_from_brush(ob, brush);
+ if (ma != NULL) {
+ gp_style = ma->gp_style;
+ }
+ /* this is not common, but avoid any special situations when brush could be without material */
+ if (gp_style == NULL) {
+ gp_style = BKE_material_gpencil_settings_get(ob, ob->actcol);
+ }
+
+ /* drawing strokes */
+ /* Check if may need to draw the active stroke cache, only if this layer is the active layer
+ * that is being edited. (Stroke buffer is currently stored in gp-data)
+ */
+ if (gpd->runtime.sbuffer_size > 0) {
+ if ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) {
+ /* It should also be noted that sbuffer contains temporary point types
+ * i.e. tGPspoints NOT bGPDspoints
+ */
+ short lthick = brush->size * obscale;
+
+ /* save gradient info */
+ stl->storage->gradient_f = brush->gpencil_settings->gradient_f;
+ copy_v2_v2(stl->storage->gradient_s, brush->gpencil_settings->gradient_s);
+ stl->storage->use_follow_path = (gp_style->flag & GP_STYLE_COLOR_LOCK_DOTS) ? 0 : 1;
+
+ /* if only one point, don't need to draw buffer because the user has no time to see it */
+ if (gpd->runtime.sbuffer_size > 1) {
+ if ((gp_style) && (gp_style->mode == GP_STYLE_MODE_LINE)) {
+ stl->g_data->shgrps_drawing_stroke = DRW_gpencil_shgroup_stroke_create(
+ e_data,
+ vedata,
+ psl->drawing_pass,
+ e_data->gpencil_stroke_sh,
+ NULL,
+ gpd,
+ NULL,
+ NULL,
+ gp_style,
+ -1,
+ false,
+ 1.0f,
+ (const int *)stl->storage->shade_render);
+ }
+ else {
+ stl->g_data->shgrps_drawing_stroke = DRW_gpencil_shgroup_point_create(
+ e_data,
+ vedata,
+ psl->drawing_pass,
+ e_data->gpencil_point_sh,
+ NULL,
+ gpd,
+ NULL,
+ NULL,
+ gp_style,
+ -1,
+ false,
+ 1.0f,
+ (const int *)stl->storage->shade_render);
+ }
+
+ /* clean previous version of the batch */
+ if (stl->storage->buffer_stroke) {
+ GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_stroke);
+ MEM_SAFE_FREE(e_data->batch_buffer_stroke);
+ stl->storage->buffer_stroke = false;
+ }
+
+ /* use unit matrix because the buffer is in screen space and does not need conversion */
+ if (gpd->runtime.mode == GP_STYLE_MODE_LINE) {
+ e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_stroke_geom(gpd, lthick);
+ }
+ else {
+ e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_point_geom(gpd, lthick);
+ }
+
+ /* buffer strokes, must show stroke always */
+ DRW_shgroup_call_add(stl->g_data->shgrps_drawing_stroke,
+ e_data->batch_buffer_stroke,
+ stl->storage->unit_matrix);
+
+ if ((gpd->runtime.sbuffer_size >= 3) &&
+ (gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) &&
+ ((gpd->runtime.sbuffer_sflag & GP_STROKE_NOFILL) == 0) &&
+ ((brush->gpencil_settings->flag & GP_BRUSH_DISSABLE_LASSO) == 0) &&
+ (gp_style->flag & GP_STYLE_FILL_SHOW)) {
+ /* if not solid, fill is simulated with solid color */
+ if (gpd->runtime.bfill_style > 0) {
+ gpd->runtime.sfill[3] = 0.5f;
+ }
+ stl->g_data->shgrps_drawing_fill = DRW_shgroup_create(e_data->gpencil_drawing_fill_sh,
+ psl->drawing_pass);
+
+ /* clean previous version of the batch */
+ if (stl->storage->buffer_fill) {
+ GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_fill);
+ MEM_SAFE_FREE(e_data->batch_buffer_fill);
+ stl->storage->buffer_fill = false;
+ }
+
+ e_data->batch_buffer_fill = DRW_gpencil_get_buffer_fill_geom(gpd);
+ DRW_shgroup_call_add(stl->g_data->shgrps_drawing_fill,
+ e_data->batch_buffer_fill,
+ stl->storage->unit_matrix);
+ stl->storage->buffer_fill = true;
+ }
+ stl->storage->buffer_stroke = true;
+ }
+ }
+ }
+
+ /* control points for primitives and speed guide */
+ const bool is_cppoint = (gpd->runtime.tot_cp_points > 0);
+ const bool is_speed_guide = (ts->gp_sculpt.guide.use_guide &&
+ (draw_ctx->object_mode == OB_MODE_PAINT_GPENCIL));
+ const bool is_show_gizmo = (((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) &&
+ ((v3d->gizmo_flag & V3D_GIZMO_HIDE_TOOL) == 0));
+
+ if ((overlay) && (is_cppoint || is_speed_guide) && (is_show_gizmo) &&
+ ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0)) {
+ DRWShadingGroup *shgrp = DRW_shgroup_create(e_data->gpencil_edit_point_sh, psl->drawing_pass);
+ const float *viewport_size = DRW_viewport_size_get();
+ DRW_shgroup_uniform_vec2(shgrp, "Viewport", viewport_size, 1);
+
+ /* clean previous version of the batch */
+ if (stl->storage->buffer_ctrlpoint) {
+ GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_ctrlpoint);
+ MEM_SAFE_FREE(e_data->batch_buffer_ctrlpoint);
+ stl->storage->buffer_ctrlpoint = false;
+ }
+
+ e_data->batch_buffer_ctrlpoint = DRW_gpencil_get_buffer_ctrlpoint_geom(gpd);
+
+ DRW_shgroup_call_add(shgrp, e_data->batch_buffer_ctrlpoint, stl->storage->unit_matrix);
+
+ stl->storage->buffer_ctrlpoint = true;
+ }
}
/* create all missing batches */
static void DRW_gpencil_create_batches(GpencilBatchCache *cache)
{
- if ((cache->b_point.vbo) && (cache->b_point.batch == NULL)) {
- cache->b_point.batch = GPU_batch_create_ex(GPU_PRIM_POINTS, cache->b_point.vbo, NULL, GPU_BATCH_OWNS_VBO);
- }
- if ((cache->b_stroke.vbo) && (cache->b_stroke.batch == NULL)) {
- cache->b_stroke.batch = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP_ADJ, cache->b_stroke.vbo, NULL, GPU_BATCH_OWNS_VBO);
- }
- if ((cache->b_fill.vbo) && (cache->b_fill.batch == NULL)) {
- cache->b_fill.batch = GPU_batch_create_ex(GPU_PRIM_TRIS, cache->b_fill.vbo, NULL, GPU_BATCH_OWNS_VBO);
- }
- if ((cache->b_edit.vbo) && (cache->b_edit.batch == NULL)) {
- cache->b_edit.batch = GPU_batch_create_ex(GPU_PRIM_POINTS, cache->b_edit.vbo, NULL, GPU_BATCH_OWNS_VBO);
- }
- if ((cache->b_edlin.vbo) && (cache->b_edlin.batch == NULL)) {
- cache->b_edlin.batch = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, cache->b_edlin.vbo, NULL, GPU_BATCH_OWNS_VBO);
- }
+ if ((cache->b_point.vbo) && (cache->b_point.batch == NULL)) {
+ cache->b_point.batch = GPU_batch_create_ex(
+ GPU_PRIM_POINTS, cache->b_point.vbo, NULL, GPU_BATCH_OWNS_VBO);
+ }
+ if ((cache->b_stroke.vbo) && (cache->b_stroke.batch == NULL)) {
+ cache->b_stroke.batch = GPU_batch_create_ex(
+ GPU_PRIM_LINE_STRIP_ADJ, cache->b_stroke.vbo, NULL, GPU_BATCH_OWNS_VBO);
+ }
+ if ((cache->b_fill.vbo) && (cache->b_fill.batch == NULL)) {
+ cache->b_fill.batch = GPU_batch_create_ex(
+ GPU_PRIM_TRIS, cache->b_fill.vbo, NULL, GPU_BATCH_OWNS_VBO);
+ }
+ if ((cache->b_edit.vbo) && (cache->b_edit.batch == NULL)) {
+ cache->b_edit.batch = GPU_batch_create_ex(
+ GPU_PRIM_POINTS, cache->b_edit.vbo, NULL, GPU_BATCH_OWNS_VBO);
+ }
+ if ((cache->b_edlin.vbo) && (cache->b_edlin.batch == NULL)) {
+ cache->b_edlin.batch = GPU_batch_create_ex(
+ GPU_PRIM_LINE_STRIP, cache->b_edlin.vbo, NULL, GPU_BATCH_OWNS_VBO);
+ }
}
/* create all shading groups */
-static void DRW_gpencil_shgroups_create(
- GPENCIL_e_data *e_data, void *vedata,
- Object *ob,
- GpencilBatchCache *cache, tGPencilObjectCache *cache_ob)
+static void DRW_gpencil_shgroups_create(GPENCIL_e_data *e_data,
+ void *vedata,
+ Object *ob,
+ GpencilBatchCache *cache,
+ tGPencilObjectCache *cache_ob)
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- bGPdata *gpd = (bGPdata *)ob->data;
- DRWPass *stroke_pass = GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d;
-
- GpencilBatchGroup *elm = NULL;
- DRWShadingGroup *shgrp = NULL;
- tGPencilObjectCache_shgrp *array_elm = NULL;
-
- bGPDlayer *gpl = NULL;
- bGPDlayer *gpl_prev = NULL;
- int idx = 0;
- bool tag_first = false;
-
- int start_stroke = 0;
- int start_point = 0;
- int start_fill = 0;
- int start_edit = 0;
- int start_edlin = 0;
-
- for (int i = 0; i < cache->grp_used; i++) {
- elm = &cache->grp_cache[i];
- array_elm = &cache_ob->shgrp_array[idx];
- const float scale = cache_ob->scale;
-
- /* save last group when change */
- if (gpl_prev == NULL) {
- gpl_prev = elm->gpl;
- tag_first = true;
- }
- else {
- if (elm->gpl != gpl_prev) {
- /* first layer is always blend Normal */
- array_elm->mode = idx == 0 ? eGplBlendMode_Normal: gpl->blend_mode;
- array_elm->end_shgrp = shgrp;
- gpl_prev = elm->gpl;
- tag_first = true;
- idx++;
- }
- }
-
- gpl = elm->gpl;
- bGPDframe *gpf = elm->gpf;
- bGPDstroke *gps = elm->gps;
- MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
- /* if the user switch used material from data to object,
- * the material could not be available */
- if (gp_style == NULL) {
- break;
- }
-
- /* limit the number of shading groups */
- if (i >= GPENCIL_MAX_SHGROUPS) {
- break;
- }
-
- switch (elm->type) {
- case eGpencilBatchGroupType_Stroke:
- {
- const int len = elm->vertex_idx - start_stroke;
-
- shgrp = DRW_gpencil_shgroup_stroke_create(
- e_data, vedata, stroke_pass, e_data->gpencil_stroke_sh,
- ob, gpd, gpl, gps, gp_style, stl->storage->shgroup_id, elm->onion,
- scale, cache_ob->shading_type);
-
- DRW_shgroup_call_range_add(
- shgrp, cache->b_stroke.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix : cache_ob->obmat,
- start_stroke, len);
-
- stl->storage->shgroup_id++;
- start_stroke = elm->vertex_idx;
- break;
- }
- case eGpencilBatchGroupType_Point:
- {
- const int len = elm->vertex_idx - start_point;
-
- shgrp = DRW_gpencil_shgroup_point_create(
- e_data, vedata, stroke_pass, e_data->gpencil_point_sh,
- ob, gpd, gpl, gps, gp_style, stl->storage->shgroup_id, elm->onion,
- scale, cache_ob->shading_type);
-
- DRW_shgroup_call_range_add(
- shgrp, cache->b_point.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix : cache_ob->obmat,
- start_point, len);
-
- stl->storage->shgroup_id++;
- start_point = elm->vertex_idx;
- break;
- }
- case eGpencilBatchGroupType_Fill:
- {
- const int len = elm->vertex_idx - start_fill;
-
- shgrp = DRW_gpencil_shgroup_fill_create(
- e_data, vedata, stroke_pass, e_data->gpencil_fill_sh,
- ob, gpd, gpl, gp_style, stl->storage->shgroup_id,
- cache_ob->shading_type);
-
- DRW_shgroup_call_range_add(
- shgrp, cache->b_fill.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix : cache_ob->obmat,
- start_fill, len);
-
- stl->storage->shgroup_id++;
- start_fill = elm->vertex_idx;
- break;
- }
- case eGpencilBatchGroupType_Edit:
- {
- if (stl->g_data->shgrps_edit_point) {
- const int len = elm->vertex_idx - start_edit;
- /* use always the same group */
- DRW_shgroup_call_range_add(
- stl->g_data->shgrps_edit_point,
- cache->b_edit.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix : cache_ob->obmat,
- start_edit, len);
-
- start_edit = elm->vertex_idx;
- }
- break;
- }
- case eGpencilBatchGroupType_Edlin:
- {
- if (stl->g_data->shgrps_edit_line) {
- const int len = elm->vertex_idx - start_edlin;
- /* use always the same group */
- DRW_shgroup_call_range_add(
- stl->g_data->shgrps_edit_line,
- cache->b_edlin.batch,
- (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix : cache_ob->obmat,
- start_edlin, len);
-
- start_edlin = elm->vertex_idx;
- }
- break;
- }
- default:
- {
- break;
- }
- }
- /* save first group */
- if ((shgrp != NULL) && (tag_first)) {
- array_elm = &cache_ob->shgrp_array[idx];
- array_elm->mode = idx == 0 ? eGplBlendMode_Normal: gpl->blend_mode;
- array_elm->clamp_layer = gpl->flag & GP_LAYER_USE_MASK;
- array_elm->blend_opacity = gpl->opacity;
- array_elm->init_shgrp = shgrp;
- cache_ob->tot_layers++;
-
- tag_first = false;
- }
- }
-
- /* save last group */
- if (shgrp != NULL) {
- array_elm->mode = idx == 0 ? eGplBlendMode_Normal : gpl->blend_mode;
- array_elm->end_shgrp = shgrp;
- }
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ bGPdata *gpd = (bGPdata *)ob->data;
+ DRWPass *stroke_pass = GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d;
+
+ GpencilBatchGroup *elm = NULL;
+ DRWShadingGroup *shgrp = NULL;
+ tGPencilObjectCache_shgrp *array_elm = NULL;
+
+ bGPDlayer *gpl = NULL;
+ bGPDlayer *gpl_prev = NULL;
+ int idx = 0;
+ bool tag_first = false;
+
+ int start_stroke = 0;
+ int start_point = 0;
+ int start_fill = 0;
+ int start_edit = 0;
+ int start_edlin = 0;
+
+ for (int i = 0; i < cache->grp_used; i++) {
+ elm = &cache->grp_cache[i];
+ array_elm = &cache_ob->shgrp_array[idx];
+ const float scale = cache_ob->scale;
+
+ /* save last group when change */
+ if (gpl_prev == NULL) {
+ gpl_prev = elm->gpl;
+ tag_first = true;
+ }
+ else {
+ if (elm->gpl != gpl_prev) {
+ /* first layer is always blend Normal */
+ array_elm->mode = idx == 0 ? eGplBlendMode_Normal : gpl->blend_mode;
+ array_elm->end_shgrp = shgrp;
+ gpl_prev = elm->gpl;
+ tag_first = true;
+ idx++;
+ }
+ }
+
+ gpl = elm->gpl;
+ bGPDframe *gpf = elm->gpf;
+ bGPDstroke *gps = elm->gps;
+ MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1);
+ /* if the user switch used material from data to object,
+ * the material could not be available */
+ if (gp_style == NULL) {
+ break;
+ }
+
+ /* limit the number of shading groups */
+ if (i >= GPENCIL_MAX_SHGROUPS) {
+ break;
+ }
+
+ switch (elm->type) {
+ case eGpencilBatchGroupType_Stroke: {
+ const int len = elm->vertex_idx - start_stroke;
+
+ shgrp = DRW_gpencil_shgroup_stroke_create(e_data,
+ vedata,
+ stroke_pass,
+ e_data->gpencil_stroke_sh,
+ ob,
+ gpd,
+ gpl,
+ gps,
+ gp_style,
+ stl->storage->shgroup_id,
+ elm->onion,
+ scale,
+ cache_ob->shading_type);
+
+ DRW_shgroup_call_range_add(shgrp,
+ cache->b_stroke.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_stroke,
+ len);
+
+ stl->storage->shgroup_id++;
+ start_stroke = elm->vertex_idx;
+ break;
+ }
+ case eGpencilBatchGroupType_Point: {
+ const int len = elm->vertex_idx - start_point;
+
+ shgrp = DRW_gpencil_shgroup_point_create(e_data,
+ vedata,
+ stroke_pass,
+ e_data->gpencil_point_sh,
+ ob,
+ gpd,
+ gpl,
+ gps,
+ gp_style,
+ stl->storage->shgroup_id,
+ elm->onion,
+ scale,
+ cache_ob->shading_type);
+
+ DRW_shgroup_call_range_add(shgrp,
+ cache->b_point.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_point,
+ len);
+
+ stl->storage->shgroup_id++;
+ start_point = elm->vertex_idx;
+ break;
+ }
+ case eGpencilBatchGroupType_Fill: {
+ const int len = elm->vertex_idx - start_fill;
+
+ shgrp = DRW_gpencil_shgroup_fill_create(e_data,
+ vedata,
+ stroke_pass,
+ e_data->gpencil_fill_sh,
+ ob,
+ gpd,
+ gpl,
+ gp_style,
+ stl->storage->shgroup_id,
+ cache_ob->shading_type);
+
+ DRW_shgroup_call_range_add(shgrp,
+ cache->b_fill.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_fill,
+ len);
+
+ stl->storage->shgroup_id++;
+ start_fill = elm->vertex_idx;
+ break;
+ }
+ case eGpencilBatchGroupType_Edit: {
+ if (stl->g_data->shgrps_edit_point) {
+ const int len = elm->vertex_idx - start_edit;
+ /* use always the same group */
+ DRW_shgroup_call_range_add(stl->g_data->shgrps_edit_point,
+ cache->b_edit.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_edit,
+ len);
+
+ start_edit = elm->vertex_idx;
+ }
+ break;
+ }
+ case eGpencilBatchGroupType_Edlin: {
+ if (stl->g_data->shgrps_edit_line) {
+ const int len = elm->vertex_idx - start_edlin;
+ /* use always the same group */
+ DRW_shgroup_call_range_add(stl->g_data->shgrps_edit_line,
+ cache->b_edlin.batch,
+ (!cache_ob->is_dup_ob) ? gpf->runtime.viewmatrix :
+ cache_ob->obmat,
+ start_edlin,
+ len);
+
+ start_edlin = elm->vertex_idx;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ /* save first group */
+ if ((shgrp != NULL) && (tag_first)) {
+ array_elm = &cache_ob->shgrp_array[idx];
+ array_elm->mode = idx == 0 ? eGplBlendMode_Normal : gpl->blend_mode;
+ array_elm->clamp_layer = gpl->flag & GP_LAYER_USE_MASK;
+ array_elm->blend_opacity = gpl->opacity;
+ array_elm->init_shgrp = shgrp;
+ cache_ob->tot_layers++;
+
+ tag_first = false;
+ }
+ }
+
+ /* save last group */
+ if (shgrp != NULL) {
+ array_elm->mode = idx == 0 ? eGplBlendMode_Normal : gpl->blend_mode;
+ array_elm->end_shgrp = shgrp;
+ }
}
/* populate a datablock for multiedit (no onions, no modifiers) */
-void DRW_gpencil_populate_multiedit(
- GPENCIL_e_data *e_data, void *vedata, Object *ob,
- tGPencilObjectCache *cache_ob)
+void DRW_gpencil_populate_multiedit(GPENCIL_e_data *e_data,
+ void *vedata,
+ Object *ob,
+ tGPencilObjectCache *cache_ob)
{
- bGPdata *gpd = (bGPdata *)ob->data;
- bGPDframe *gpf = NULL;
-
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph);
- GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval);
-
- /* check if playing animation */
- const bool playing = stl->storage->is_playing;
-
- /* calc max size of VBOs */
- gpencil_calc_vertex(stl, cache_ob, cache, gpd, cfra_eval);
-
- /* draw strokes */
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- /* don't draw layer if hidden */
- if (gpl->flag & GP_LAYER_HIDE) {
- continue;
- }
-
- /* list of frames to draw */
- if (!playing) {
- for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
- if ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)) {
- gpencil_draw_strokes(
- cache, e_data, vedata, ob, gpd, gpl, gpf, gpf,
- gpl->opacity, gpl->tintcolor, false, cache_ob);
- }
- }
- }
- else {
- gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV);
- if (gpf) {
- gpencil_draw_strokes(
- cache, e_data, vedata, ob, gpd, gpl, gpf, gpf,
- gpl->opacity, gpl->tintcolor, false, cache_ob);
- }
- }
-
- }
-
- /* create batchs and shading groups */
- DRW_gpencil_create_batches(cache);
- DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
-
- cache->is_dirty = false;
+ bGPdata *gpd = (bGPdata *)ob->data;
+ bGPDframe *gpf = NULL;
+
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph);
+ GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval);
+
+ /* check if playing animation */
+ const bool playing = stl->storage->is_playing;
+
+ /* calc max size of VBOs */
+ gpencil_calc_vertex(stl, cache_ob, cache, gpd, cfra_eval);
+
+ /* draw strokes */
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ /* don't draw layer if hidden */
+ if (gpl->flag & GP_LAYER_HIDE) {
+ continue;
+ }
+
+ /* list of frames to draw */
+ if (!playing) {
+ for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)) {
+ gpencil_draw_strokes(cache,
+ e_data,
+ vedata,
+ ob,
+ gpd,
+ gpl,
+ gpf,
+ gpf,
+ gpl->opacity,
+ gpl->tintcolor,
+ false,
+ cache_ob);
+ }
+ }
+ }
+ else {
+ gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV);
+ if (gpf) {
+ gpencil_draw_strokes(cache,
+ e_data,
+ vedata,
+ ob,
+ gpd,
+ gpl,
+ gpf,
+ gpf,
+ gpl->opacity,
+ gpl->tintcolor,
+ false,
+ cache_ob);
+ }
+ }
+ }
+
+ /* create batchs and shading groups */
+ DRW_gpencil_create_batches(cache);
+ DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
+
+ cache->is_dirty = false;
}
/* helper for populate a complete grease pencil datablock */
-void DRW_gpencil_populate_datablock(
- GPENCIL_e_data *e_data, void *vedata,
- Object *ob,
- tGPencilObjectCache *cache_ob)
+void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data,
+ void *vedata,
+ Object *ob,
+ tGPencilObjectCache *cache_ob)
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- const ViewLayer *view_layer = DEG_get_evaluated_view_layer(draw_ctx->depsgraph);
- Scene *scene = draw_ctx->scene;
-
- bGPdata *gpd = (bGPdata *)ob->data;
-
- View3D *v3d = draw_ctx->v3d;
- int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph);
-
- bGPDframe *derived_gpf = NULL;
- const bool main_onion = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) : true;
- const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) &&
- main_onion && DRW_gpencil_onion_active(gpd);
- const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
- const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
-
- float opacity;
- bGPDframe *gpf = NULL;
- bGPDlayer *gpl_active = BKE_gpencil_layer_getactive(gpd);
-
- /* check if playing animation */
- const bool playing = stl->storage->is_playing;
-
- GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval);
-
- /* if object is duplicate, only create shading groups */
- if (cache_ob->is_dup_ob) {
- DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
- return;
- }
-
- /* calc max size of VBOs */
- gpencil_calc_vertex(stl, cache_ob, cache, gpd, cfra_eval);
-
- /* init general modifiers data */
- if (!stl->storage->simplify_modif) {
- if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) {
- BKE_gpencil_lattice_init(ob);
- }
- }
- /* draw normal strokes */
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- /* don't draw layer if hidden */
- if (gpl->flag & GP_LAYER_HIDE) {
- continue;
- }
-
- const bool is_solomode = GPENCIL_PAINT_MODE(gpd) &&
- (!playing) && (!stl->storage->is_render) &&
- (gpl->flag & GP_LAYER_SOLO_MODE);
-
- /* filter view layer to gp layers in the same view layer (for compo) */
- if ((stl->storage->is_render) && (gpl->viewlayername[0] != '\0')) {
- if (!STREQ(view_layer->name, gpl->viewlayername)) {
- continue;
- }
- }
-
- /* remap time */
- int remap_cfra = cfra_eval;
- if ((time_remap) && (!stl->storage->simplify_modif)) {
- remap_cfra = BKE_gpencil_time_modifier(
- draw_ctx->depsgraph, scene, ob, gpl, cfra_eval,
- stl->storage->is_render);
- }
-
- gpf = BKE_gpencil_layer_getframe(gpl, remap_cfra, GP_GETFRAME_USE_PREV);
- if (gpf == NULL) {
- continue;
- }
-
- /* if solo mode, display only frames with keyframe in the current frame */
- if ((is_solomode) && (gpf->framenum != remap_cfra)) {
- continue;
- }
-
- opacity = gpl->opacity;
- /* if pose mode, maybe the overlay to fade geometry is enabled */
- if ((draw_ctx->obact) && (draw_ctx->object_mode == OB_MODE_POSE) &&
- (v3d->overlay.flag & V3D_OVERLAY_BONE_SELECT))
- {
- opacity = opacity * v3d->overlay.xray_alpha_bone;
- }
- /* fade no active layers */
- if ((overlay) && (draw_ctx->object_mode == OB_MODE_PAINT_GPENCIL) &&
- (v3d->gp_flag & V3D_GP_FADE_NOACTIVE_LAYERS) &&
- (draw_ctx->obact) && (draw_ctx->obact == ob) &&
- (gpl != gpl_active))
- {
- opacity = opacity * v3d->overlay.gpencil_fade_layer;
- }
-
- /* create derived frames array data or expand */
- int derived_idx = BLI_findindex(&gpd->layers, gpl);
- derived_gpf = &cache->derived_array[derived_idx];
-
- /* if no derived frame or dirty cache, create a new one */
- if ((derived_gpf == NULL) || (cache->is_dirty)) {
- if (derived_gpf != NULL) {
- /* first clear temp data */
- BKE_gpencil_free_frame_runtime_data(derived_gpf);
- }
- /* create new data (do not assign new memory)*/
- gpencil_copy_frame(gpf, derived_gpf);
- }
-
- /* draw onion skins */
- if (!ID_IS_LINKED(&gpd->id)) {
- if ((do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN) &&
- ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)) &&
- (!cache_ob->is_dup_ob) && (gpd->id.us <= 1))
- {
- if (((!stl->storage->is_render) && (overlay)) ||
- ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)))
- {
- gpencil_draw_onionskins(cache, vedata, ob, gpd, gpl, gpf);
- }
- }
- }
- /* draw normal strokes */
- gpencil_draw_strokes(
- cache, e_data, vedata, ob, gpd, gpl, gpf, derived_gpf,
- opacity, gpl->tintcolor, false, cache_ob);
- }
-
- /* clear any lattice data */
- if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) {
- BKE_gpencil_lattice_clear(ob);
- }
-
- /* create batchs and shading groups */
- DRW_gpencil_create_batches(cache);
- DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
-
- cache->is_dirty = false;
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const ViewLayer *view_layer = DEG_get_evaluated_view_layer(draw_ctx->depsgraph);
+ Scene *scene = draw_ctx->scene;
+
+ bGPdata *gpd = (bGPdata *)ob->data;
+
+ View3D *v3d = draw_ctx->v3d;
+ int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph);
+
+ bGPDframe *derived_gpf = NULL;
+ const bool main_onion = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) : true;
+ const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && main_onion &&
+ DRW_gpencil_onion_active(gpd);
+ const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
+ const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
+
+ float opacity;
+ bGPDframe *gpf = NULL;
+ bGPDlayer *gpl_active = BKE_gpencil_layer_getactive(gpd);
+
+ /* check if playing animation */
+ const bool playing = stl->storage->is_playing;
+
+ GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra_eval);
+
+ /* if object is duplicate, only create shading groups */
+ if (cache_ob->is_dup_ob) {
+ DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
+ return;
+ }
+
+ /* calc max size of VBOs */
+ gpencil_calc_vertex(stl, cache_ob, cache, gpd, cfra_eval);
+
+ /* init general modifiers data */
+ if (!stl->storage->simplify_modif) {
+ if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) {
+ BKE_gpencil_lattice_init(ob);
+ }
+ }
+ /* draw normal strokes */
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ /* don't draw layer if hidden */
+ if (gpl->flag & GP_LAYER_HIDE) {
+ continue;
+ }
+
+ const bool is_solomode = GPENCIL_PAINT_MODE(gpd) && (!playing) && (!stl->storage->is_render) &&
+ (gpl->flag & GP_LAYER_SOLO_MODE);
+
+ /* filter view layer to gp layers in the same view layer (for compo) */
+ if ((stl->storage->is_render) && (gpl->viewlayername[0] != '\0')) {
+ if (!STREQ(view_layer->name, gpl->viewlayername)) {
+ continue;
+ }
+ }
+
+ /* remap time */
+ int remap_cfra = cfra_eval;
+ if ((time_remap) && (!stl->storage->simplify_modif)) {
+ remap_cfra = BKE_gpencil_time_modifier(
+ draw_ctx->depsgraph, scene, ob, gpl, cfra_eval, stl->storage->is_render);
+ }
+
+ gpf = BKE_gpencil_layer_getframe(gpl, remap_cfra, GP_GETFRAME_USE_PREV);
+ if (gpf == NULL) {
+ continue;
+ }
+
+ /* if solo mode, display only frames with keyframe in the current frame */
+ if ((is_solomode) && (gpf->framenum != remap_cfra)) {
+ continue;
+ }
+
+ opacity = gpl->opacity;
+ /* if pose mode, maybe the overlay to fade geometry is enabled */
+ if ((draw_ctx->obact) && (draw_ctx->object_mode == OB_MODE_POSE) &&
+ (v3d->overlay.flag & V3D_OVERLAY_BONE_SELECT)) {
+ opacity = opacity * v3d->overlay.xray_alpha_bone;
+ }
+ /* fade no active layers */
+ if ((overlay) && (draw_ctx->object_mode == OB_MODE_PAINT_GPENCIL) &&
+ (v3d->gp_flag & V3D_GP_FADE_NOACTIVE_LAYERS) && (draw_ctx->obact) &&
+ (draw_ctx->obact == ob) && (gpl != gpl_active)) {
+ opacity = opacity * v3d->overlay.gpencil_fade_layer;
+ }
+
+ /* create derived frames array data or expand */
+ int derived_idx = BLI_findindex(&gpd->layers, gpl);
+ derived_gpf = &cache->derived_array[derived_idx];
+
+ /* if no derived frame or dirty cache, create a new one */
+ if ((derived_gpf == NULL) || (cache->is_dirty)) {
+ if (derived_gpf != NULL) {
+ /* first clear temp data */
+ BKE_gpencil_free_frame_runtime_data(derived_gpf);
+ }
+ /* create new data (do not assign new memory)*/
+ gpencil_copy_frame(gpf, derived_gpf);
+ }
+
+ /* draw onion skins */
+ if (!ID_IS_LINKED(&gpd->id)) {
+ if ((do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN) &&
+ ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)) && (!cache_ob->is_dup_ob) &&
+ (gpd->id.us <= 1)) {
+ if (((!stl->storage->is_render) && (overlay)) ||
+ ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) {
+ gpencil_draw_onionskins(cache, vedata, ob, gpd, gpl, gpf);
+ }
+ }
+ }
+ /* draw normal strokes */
+ gpencil_draw_strokes(cache,
+ e_data,
+ vedata,
+ ob,
+ gpd,
+ gpl,
+ gpf,
+ derived_gpf,
+ opacity,
+ gpl->tintcolor,
+ false,
+ cache_ob);
+ }
+
+ /* clear any lattice data */
+ if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) {
+ BKE_gpencil_lattice_clear(ob);
+ }
+
+ /* create batchs and shading groups */
+ DRW_gpencil_create_batches(cache);
+ DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
+
+ cache->is_dirty = false;
}
void DRW_gpencil_populate_particles(GPENCIL_e_data *e_data, GHash *gh_objects, void *vedata)
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
-
- /* add particles */
- for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
- tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
- if (cache_ob->is_dup_ob) {
- /* reasign duplicate objects because memory for particles is not available
- * and need to use the original datablock and runtime data */
- Object *ob = (Object *)BLI_ghash_lookup(gh_objects, cache_ob->name);
- if (ob) {
- cache_ob->ob = ob;
- cache_ob->gpd = (bGPdata *)ob->data;
- GpencilBatchCache *cache = ob->runtime.gpencil_cache;
- if (cache != NULL) {
- DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
- }
- }
- }
- }
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+
+ /* add particles */
+ for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
+ tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
+ if (cache_ob->is_dup_ob) {
+ /* reasign duplicate objects because memory for particles is not available
+ * and need to use the original datablock and runtime data */
+ Object *ob = (Object *)BLI_ghash_lookup(gh_objects, cache_ob->name);
+ if (ob) {
+ cache_ob->ob = ob;
+ cache_ob->gpd = (bGPdata *)ob->data;
+ GpencilBatchCache *cache = ob->runtime.gpencil_cache;
+ if (cache != NULL) {
+ DRW_gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob);
+ }
+ }
+ }
+ }
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index d1a8f40a428..6fa07245396 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -44,7 +44,6 @@
#include "UI_resources.h"
-
extern char datatoc_gpencil_fill_vert_glsl[];
extern char datatoc_gpencil_fill_frag_glsl[];
extern char datatoc_gpencil_stroke_vert_glsl[];
@@ -70,1054 +69,1023 @@ static GPENCIL_e_data e_data = {NULL}; /* Engine data */
/* create a multisample buffer if not present */
void DRW_gpencil_multisample_ensure(GPENCIL_Data *vedata, int rect_w, int rect_h)
{
- GPENCIL_FramebufferList *fbl = vedata->fbl;
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl;
-
- short samples = stl->storage->multisamples;
-
- if (samples > 0) {
- if (!fbl->multisample_fb) {
- fbl->multisample_fb = GPU_framebuffer_create();
- if (fbl->multisample_fb) {
- if (txl->multisample_color == NULL) {
- txl->multisample_color = GPU_texture_create_2d_multisample(
- rect_w, rect_h, GPU_RGBA16F, NULL, samples, NULL);
- }
- if (txl->multisample_depth == NULL) {
- txl->multisample_depth = GPU_texture_create_2d_multisample(
- rect_w, rect_h, GPU_DEPTH_COMPONENT24, NULL, samples, NULL);
- }
- GPU_framebuffer_ensure_config(
- &fbl->multisample_fb, {
- GPU_ATTACHMENT_TEXTURE(txl->multisample_depth),
- GPU_ATTACHMENT_TEXTURE(txl->multisample_color)
- });
- }
- }
- }
+ GPENCIL_FramebufferList *fbl = vedata->fbl;
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl;
+
+ short samples = stl->storage->multisamples;
+
+ if (samples > 0) {
+ if (!fbl->multisample_fb) {
+ fbl->multisample_fb = GPU_framebuffer_create();
+ if (fbl->multisample_fb) {
+ if (txl->multisample_color == NULL) {
+ txl->multisample_color = GPU_texture_create_2d_multisample(
+ rect_w, rect_h, GPU_RGBA16F, NULL, samples, NULL);
+ }
+ if (txl->multisample_depth == NULL) {
+ txl->multisample_depth = GPU_texture_create_2d_multisample(
+ rect_w, rect_h, GPU_DEPTH_COMPONENT24, NULL, samples, NULL);
+ }
+ GPU_framebuffer_ensure_config(&fbl->multisample_fb,
+ {GPU_ATTACHMENT_TEXTURE(txl->multisample_depth),
+ GPU_ATTACHMENT_TEXTURE(txl->multisample_color)});
+ }
+ }
+ }
}
static void GPENCIL_create_framebuffers(void *vedata)
{
- GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
-
- /* Go full 32bits for rendering */
- eGPUTextureFormat fb_format = DRW_state_is_image_render() ? GPU_RGBA32F : GPU_RGBA16F;
-
- if (DRW_state_is_fbo()) {
- const float *viewport_size = DRW_viewport_size_get();
- const int size[2] = { (int)viewport_size[0], (int)viewport_size[1] };
-
- /* create multiframe framebuffer for AA */
- if ((stl->storage->framebuffer_flag & GP_FRAMEBUFFER_MULTISAMPLE) &&
- (stl->storage->multisamples > 0))
- {
- DRW_gpencil_multisample_ensure(vedata, size[0], size[1]);
- }
-
- /* Framebufers for basic object drawing */
- if (stl->storage->framebuffer_flag & GP_FRAMEBUFFER_BASIC) {
- /* temp textures for ping-pong buffers */
- e_data.temp_depth_tx_a = DRW_texture_pool_query_2d(
- size[0], size[1], GPU_DEPTH_COMPONENT24,
- &draw_engine_gpencil_type);
- e_data.temp_color_tx_a = DRW_texture_pool_query_2d(
- size[0], size[1], fb_format,
- &draw_engine_gpencil_type);
- GPU_framebuffer_ensure_config(
- &fbl->temp_fb_a, {
- GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_a),
- GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_a),
- });
-
- e_data.temp_depth_tx_b = DRW_texture_pool_query_2d(
- size[0], size[1], GPU_DEPTH_COMPONENT24,
- &draw_engine_gpencil_type);
- e_data.temp_color_tx_b = DRW_texture_pool_query_2d(
- size[0], size[1], fb_format,
- &draw_engine_gpencil_type);
- GPU_framebuffer_ensure_config(
- &fbl->temp_fb_b, {
- GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_b),
- GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_b),
- });
-
- /* used for FX effects and Layer blending */
- e_data.temp_depth_tx_fx = DRW_texture_pool_query_2d(
- size[0], size[1], GPU_DEPTH_COMPONENT24,
- &draw_engine_gpencil_type);
- e_data.temp_color_tx_fx = DRW_texture_pool_query_2d(
- size[0], size[1], fb_format,
- &draw_engine_gpencil_type);
- GPU_framebuffer_ensure_config(
- &fbl->temp_fb_fx, {
- GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_fx),
- GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_fx),
- });
- }
-
- /* background framebuffer to speed up drawing process (always 16 bits) */
- if (stl->storage->framebuffer_flag & GP_FRAMEBUFFER_DRAW) {
- e_data.background_depth_tx = DRW_texture_pool_query_2d(
- size[0], size[1], GPU_DEPTH_COMPONENT24,
- &draw_engine_gpencil_type);
- e_data.background_color_tx = DRW_texture_pool_query_2d(
- size[0], size[1], GPU_RGBA32F,
- &draw_engine_gpencil_type);
- GPU_framebuffer_ensure_config(
- &fbl->background_fb, {
- GPU_ATTACHMENT_TEXTURE(e_data.background_depth_tx),
- GPU_ATTACHMENT_TEXTURE(e_data.background_color_tx),
- });
- }
- }
+ GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+
+ /* Go full 32bits for rendering */
+ eGPUTextureFormat fb_format = DRW_state_is_image_render() ? GPU_RGBA32F : GPU_RGBA16F;
+
+ if (DRW_state_is_fbo()) {
+ const float *viewport_size = DRW_viewport_size_get();
+ const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
+
+ /* create multiframe framebuffer for AA */
+ if ((stl->storage->framebuffer_flag & GP_FRAMEBUFFER_MULTISAMPLE) &&
+ (stl->storage->multisamples > 0)) {
+ DRW_gpencil_multisample_ensure(vedata, size[0], size[1]);
+ }
+
+ /* Framebufers for basic object drawing */
+ if (stl->storage->framebuffer_flag & GP_FRAMEBUFFER_BASIC) {
+ /* temp textures for ping-pong buffers */
+ e_data.temp_depth_tx_a = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_gpencil_type);
+ e_data.temp_color_tx_a = DRW_texture_pool_query_2d(
+ size[0], size[1], fb_format, &draw_engine_gpencil_type);
+ GPU_framebuffer_ensure_config(&fbl->temp_fb_a,
+ {
+ GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_a),
+ GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_a),
+ });
+
+ e_data.temp_depth_tx_b = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_gpencil_type);
+ e_data.temp_color_tx_b = DRW_texture_pool_query_2d(
+ size[0], size[1], fb_format, &draw_engine_gpencil_type);
+ GPU_framebuffer_ensure_config(&fbl->temp_fb_b,
+ {
+ GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_b),
+ GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_b),
+ });
+
+ /* used for FX effects and Layer blending */
+ e_data.temp_depth_tx_fx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_gpencil_type);
+ e_data.temp_color_tx_fx = DRW_texture_pool_query_2d(
+ size[0], size[1], fb_format, &draw_engine_gpencil_type);
+ GPU_framebuffer_ensure_config(&fbl->temp_fb_fx,
+ {
+ GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_fx),
+ GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_fx),
+ });
+ }
+
+ /* background framebuffer to speed up drawing process (always 16 bits) */
+ if (stl->storage->framebuffer_flag & GP_FRAMEBUFFER_DRAW) {
+ e_data.background_depth_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_gpencil_type);
+ e_data.background_color_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_RGBA32F, &draw_engine_gpencil_type);
+ GPU_framebuffer_ensure_config(&fbl->background_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(e_data.background_depth_tx),
+ GPU_ATTACHMENT_TEXTURE(e_data.background_color_tx),
+ });
+ }
+ }
}
static void GPENCIL_create_shaders(void)
{
- /* normal fill shader */
- if (!e_data.gpencil_fill_sh) {
- e_data.gpencil_fill_sh = DRW_shader_create(
- datatoc_gpencil_fill_vert_glsl, NULL,
- datatoc_gpencil_fill_frag_glsl, NULL);
- }
-
- /* normal stroke shader using geometry to display lines (line mode) */
- if (!e_data.gpencil_stroke_sh) {
- e_data.gpencil_stroke_sh = DRW_shader_create(
- datatoc_gpencil_stroke_vert_glsl,
- datatoc_gpencil_stroke_geom_glsl,
- datatoc_gpencil_stroke_frag_glsl,
- NULL);
- }
-
- /* dot/rectangle mode for normal strokes using geometry */
- if (!e_data.gpencil_point_sh) {
- e_data.gpencil_point_sh = DRW_shader_create(
- datatoc_gpencil_point_vert_glsl,
- datatoc_gpencil_point_geom_glsl,
- datatoc_gpencil_point_frag_glsl,
- NULL);
- }
- /* used for edit points or strokes with one point only */
- if (!e_data.gpencil_edit_point_sh) {
- e_data.gpencil_edit_point_sh = DRW_shader_create(
- datatoc_gpencil_edit_point_vert_glsl,
- datatoc_gpencil_edit_point_geom_glsl,
- datatoc_gpencil_edit_point_frag_glsl, NULL);
- }
-
- /* used for edit lines for edit modes */
- if (!e_data.gpencil_line_sh) {
- e_data.gpencil_line_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR);
- }
-
- /* used to filling during drawing */
- if (!e_data.gpencil_drawing_fill_sh) {
- e_data.gpencil_drawing_fill_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR);
- }
-
- /* 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);
- }
- if (!e_data.gpencil_simple_fullscreen_sh) {
- e_data.gpencil_simple_fullscreen_sh = DRW_shader_create_fullscreen(datatoc_gpencil_simple_mix_frag_glsl, NULL);
- }
-
- /* blend */
- if (!e_data.gpencil_blend_fullscreen_sh) {
- e_data.gpencil_blend_fullscreen_sh = DRW_shader_create_fullscreen(datatoc_gpencil_blend_frag_glsl, NULL);
- }
-
- /* shaders for use when drawing */
- if (!e_data.gpencil_background_sh) {
- e_data.gpencil_background_sh = DRW_shader_create_fullscreen(datatoc_gpencil_background_frag_glsl, NULL);
- }
- if (!e_data.gpencil_paper_sh) {
- e_data.gpencil_paper_sh = DRW_shader_create_fullscreen(datatoc_gpencil_paper_frag_glsl, NULL);
- }
+ /* normal fill shader */
+ if (!e_data.gpencil_fill_sh) {
+ e_data.gpencil_fill_sh = DRW_shader_create(
+ datatoc_gpencil_fill_vert_glsl, NULL, datatoc_gpencil_fill_frag_glsl, NULL);
+ }
+
+ /* normal stroke shader using geometry to display lines (line mode) */
+ if (!e_data.gpencil_stroke_sh) {
+ e_data.gpencil_stroke_sh = DRW_shader_create(datatoc_gpencil_stroke_vert_glsl,
+ datatoc_gpencil_stroke_geom_glsl,
+ datatoc_gpencil_stroke_frag_glsl,
+ NULL);
+ }
+
+ /* dot/rectangle mode for normal strokes using geometry */
+ if (!e_data.gpencil_point_sh) {
+ e_data.gpencil_point_sh = DRW_shader_create(datatoc_gpencil_point_vert_glsl,
+ datatoc_gpencil_point_geom_glsl,
+ datatoc_gpencil_point_frag_glsl,
+ NULL);
+ }
+ /* used for edit points or strokes with one point only */
+ if (!e_data.gpencil_edit_point_sh) {
+ e_data.gpencil_edit_point_sh = DRW_shader_create(datatoc_gpencil_edit_point_vert_glsl,
+ datatoc_gpencil_edit_point_geom_glsl,
+ datatoc_gpencil_edit_point_frag_glsl,
+ NULL);
+ }
+
+ /* used for edit lines for edit modes */
+ if (!e_data.gpencil_line_sh) {
+ e_data.gpencil_line_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR);
+ }
+
+ /* used to filling during drawing */
+ if (!e_data.gpencil_drawing_fill_sh) {
+ e_data.gpencil_drawing_fill_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR);
+ }
+
+ /* 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);
+ }
+ if (!e_data.gpencil_simple_fullscreen_sh) {
+ e_data.gpencil_simple_fullscreen_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_simple_mix_frag_glsl, NULL);
+ }
+
+ /* blend */
+ if (!e_data.gpencil_blend_fullscreen_sh) {
+ e_data.gpencil_blend_fullscreen_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_blend_frag_glsl, NULL);
+ }
+
+ /* shaders for use when drawing */
+ if (!e_data.gpencil_background_sh) {
+ e_data.gpencil_background_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_background_frag_glsl, NULL);
+ }
+ if (!e_data.gpencil_paper_sh) {
+ e_data.gpencil_paper_sh = DRW_shader_create_fullscreen(datatoc_gpencil_paper_frag_glsl, NULL);
+ }
}
void GPENCIL_engine_init(void *vedata)
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- /* init storage */
- if (!stl->storage) {
- stl->storage = MEM_callocN(sizeof(GPENCIL_Storage), "GPENCIL_Storage");
-
- /* unit matrix */
- unit_m4(stl->storage->unit_matrix);
- stl->storage->shade_render[0] = OB_RENDER;
- stl->storage->shade_render[1] = 0;
- }
-
- stl->storage->multisamples = U.gpencil_multisamples;
-
- /* create shaders */
- GPENCIL_create_shaders();
- GPENCIL_create_fx_shaders(&e_data);
-
- /* blank texture used if no texture defined for fill shader */
- if (!e_data.gpencil_blank_texture) {
- float rect[16][16][4] = {{{0.0f}}};
- e_data.gpencil_blank_texture = DRW_texture_create_2d(16, 16, GPU_RGBA8, DRW_TEX_FILTER, (float *)rect);
- }
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ /* init storage */
+ if (!stl->storage) {
+ stl->storage = MEM_callocN(sizeof(GPENCIL_Storage), "GPENCIL_Storage");
+
+ /* unit matrix */
+ unit_m4(stl->storage->unit_matrix);
+ stl->storage->shade_render[0] = OB_RENDER;
+ stl->storage->shade_render[1] = 0;
+ }
+
+ stl->storage->multisamples = U.gpencil_multisamples;
+
+ /* create shaders */
+ GPENCIL_create_shaders();
+ GPENCIL_create_fx_shaders(&e_data);
+
+ /* blank texture used if no texture defined for fill shader */
+ if (!e_data.gpencil_blank_texture) {
+ float rect[16][16][4] = {{{0.0f}}};
+ e_data.gpencil_blank_texture = DRW_texture_create_2d(
+ 16, 16, GPU_RGBA8, DRW_TEX_FILTER, (float *)rect);
+ }
}
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_point_sh);
- DRW_SHADER_FREE_SAFE(e_data.gpencil_edit_point_sh);
- DRW_SHADER_FREE_SAFE(e_data.gpencil_fullscreen_sh);
- DRW_SHADER_FREE_SAFE(e_data.gpencil_simple_fullscreen_sh);
- DRW_SHADER_FREE_SAFE(e_data.gpencil_blend_fullscreen_sh);
- DRW_SHADER_FREE_SAFE(e_data.gpencil_background_sh);
- DRW_SHADER_FREE_SAFE(e_data.gpencil_paper_sh);
+ /* 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_point_sh);
+ DRW_SHADER_FREE_SAFE(e_data.gpencil_edit_point_sh);
+ DRW_SHADER_FREE_SAFE(e_data.gpencil_fullscreen_sh);
+ DRW_SHADER_FREE_SAFE(e_data.gpencil_simple_fullscreen_sh);
+ DRW_SHADER_FREE_SAFE(e_data.gpencil_blend_fullscreen_sh);
+ DRW_SHADER_FREE_SAFE(e_data.gpencil_background_sh);
+ DRW_SHADER_FREE_SAFE(e_data.gpencil_paper_sh);
- DRW_TEXTURE_FREE_SAFE(e_data.gpencil_blank_texture);
+ DRW_TEXTURE_FREE_SAFE(e_data.gpencil_blank_texture);
- GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_stroke);
- MEM_SAFE_FREE(e_data.batch_buffer_stroke);
+ GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_stroke);
+ MEM_SAFE_FREE(e_data.batch_buffer_stroke);
- GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_fill);
- MEM_SAFE_FREE(e_data.batch_buffer_fill);
+ GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_fill);
+ MEM_SAFE_FREE(e_data.batch_buffer_fill);
- GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_ctrlpoint);
- MEM_SAFE_FREE(e_data.batch_buffer_ctrlpoint);
+ GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_ctrlpoint);
+ MEM_SAFE_FREE(e_data.batch_buffer_ctrlpoint);
- GPU_BATCH_DISCARD_SAFE(e_data.batch_grid);
- MEM_SAFE_FREE(e_data.batch_grid);
+ GPU_BATCH_DISCARD_SAFE(e_data.batch_grid);
+ MEM_SAFE_FREE(e_data.batch_grid);
- /* effects */
- GPENCIL_delete_fx_shaders(&e_data);
+ /* effects */
+ GPENCIL_delete_fx_shaders(&e_data);
}
void GPENCIL_cache_init(void *vedata)
{
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- ToolSettings *ts = scene->toolsettings;
- View3D *v3d = draw_ctx->v3d;
- Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
-
- /* Special handling for when active object is GP object (e.g. for draw mode) */
- Object *obact = draw_ctx->obact;
- bGPdata *obact_gpd = NULL;
- MaterialGPencilStyle *gp_style = NULL;
-
- if (obact && (obact->type == OB_GPENCIL) && (obact->data)) {
- obact_gpd = (bGPdata *)obact->data;
- /* use the brush material */
- Material *ma = BKE_gpencil_object_material_get_from_brush(obact, brush);
- if (ma != NULL) {
- gp_style = ma->gp_style;
- }
- /* this is not common, but avoid any special situations when brush could be without material */
- if (gp_style == NULL) {
- gp_style = BKE_material_gpencil_settings_get(obact, obact->actcol);
- }
- }
-
- if (!stl->g_data) {
- /* Alloc transient pointers */
- stl->g_data = MEM_mallocN(sizeof(g_data), "g_data");
- stl->storage->xray = GP_XRAY_FRONT; /* used for drawing */
- stl->storage->stroke_style = GP_STYLE_STROKE_STYLE_SOLID; /* used for drawing */
- }
- stl->storage->tonemapping = 0;
-
- stl->g_data->shgrps_edit_line = NULL;
- stl->g_data->shgrps_edit_point = NULL;
-
- if (!stl->shgroups) {
- /* Alloc maximum size because count strokes is very slow and can be very complex due onion skinning.
- */
- 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;
- stl->g_data->do_instances = false;
-
- {
- /* Stroke pass 2D */
- psl->stroke_pass_2d = DRW_pass_create(
- "GPencil Stroke Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND);
- stl->storage->shgroup_id = 0;
- /* Stroke pass 3D */
- psl->stroke_pass_3d = DRW_pass_create(
- "GPencil Stroke Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
- stl->storage->shgroup_id = 0;
-
- /* edit pass */
- psl->edit_pass = DRW_pass_create(
- "GPencil Edit Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
-
- /* detect if playing animation */
- if (draw_ctx->evil_C) {
-
- bool playing = ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL;
- if (playing != stl->storage->is_playing) {
- stl->storage->reset_cache = true;
- }
- stl->storage->is_playing = playing;
- }
- else {
- stl->storage->is_playing = false;
- stl->storage->reset_cache = false;
- }
- /* save render state */
- stl->storage->is_render = DRW_state_is_image_render();
- stl->storage->is_mat_preview = (bool)stl->storage->is_render && STREQ(scene->id.name + 2, "preview");
-
- if (obact_gpd) {
- /* for some reason, when press play there is a delay in the animation flag check
- * and this produces errors. To be sure, we set cache as dirty because the frame
- * is changing.
- */
- if (stl->storage->is_playing == true) {
- obact_gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
- }
- /* if render, set as dirty to update all data */
- else if (stl->storage->is_render == true) {
- obact_gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
- }
- }
-
- /* save simplify flags (can change while drawing, so it's better to save) */
- stl->storage->simplify_fill = GP_SIMPLIFY_FILL(scene, stl->storage->is_playing);
- stl->storage->simplify_modif = GP_SIMPLIFY_MODIF(scene, stl->storage->is_playing);
- stl->storage->simplify_fx = GP_SIMPLIFY_FX(scene, stl->storage->is_playing);
- stl->storage->simplify_blend = GP_SIMPLIFY_BLEND(scene, stl->storage->is_playing);
-
- /* xray mode */
- if (v3d) {
- stl->storage->is_xray = XRAY_ACTIVE(v3d);
- }
- else {
- stl->storage->is_xray = 0;
- }
-
- /* save pixsize */
- stl->storage->pixsize = DRW_viewport_pixelsize_get();
- if ((!DRW_state_is_opengl_render()) && (stl->storage->is_render)) {
- stl->storage->pixsize = &stl->storage->render_pixsize;
- }
-
- /* detect if painting session */
- if ((obact_gpd) &&
- (obact_gpd->flag & GP_DATA_STROKE_PAINTMODE) &&
- (stl->storage->is_playing == false))
- {
- /* need the original to avoid cow overhead while drawing */
- bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&obact_gpd->id);
- if (((gpd_orig->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) &&
- (gpd_orig->runtime.sbuffer_size > 0) &&
- ((gpd_orig->flag & GP_DATA_STROKE_POLYGON) == 0) &&
- !DRW_state_is_depth())
- {
- stl->g_data->session_flag |= GP_DRW_PAINT_PAINTING;
- }
- else {
- stl->g_data->session_flag = GP_DRW_PAINT_IDLE;
- }
- }
- else {
- /* if not drawing mode */
- stl->g_data->session_flag = GP_DRW_PAINT_HOLD;
- }
-
- if (gp_style) {
- stl->storage->stroke_style = gp_style->stroke_style;
- stl->storage->color_type = GPENCIL_COLOR_SOLID;
- if (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) {
- stl->storage->color_type = GPENCIL_COLOR_TEXTURE;
- if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
- stl->storage->color_type = GPENCIL_COLOR_PATTERN;
- }
- }
- }
- else {
- stl->storage->stroke_style = GP_STYLE_STROKE_STYLE_SOLID;
- stl->storage->color_type = GPENCIL_COLOR_SOLID;
- }
-
- /* drawing buffer pass for drawing the stroke that is being drawing by the user. The data
- * is stored in sbuffer
- */
- psl->drawing_pass = DRW_pass_create(
- "GPencil Drawing Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
-
- /* full screen pass to combine the result with default framebuffer */
- struct GPUBatch *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_texture_ref(mix_shgrp, "strokeColor", &e_data.input_color_tx);
- DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeDepth", &e_data.input_depth_tx);
- DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1);
- DRW_shgroup_uniform_int(mix_shgrp, "do_select", &stl->storage->do_select_outline, 1);
- DRW_shgroup_uniform_vec4(mix_shgrp, "select_color", stl->storage->select_color, 1);
-
- /* mix pass no blend used to copy between passes. A separated pass is required
- * because if mix_pass is used, the acumulation of blend degrade the colors.
- *
- * This pass is used too to take the snapshot used for background_pass. This image
- * will be used as the background while the user is drawing.
- */
- psl->mix_pass_noblend = DRW_pass_create(
- "GPencil Mix Pass no blend",
- DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
- DRWShadingGroup *mix_shgrp_noblend = DRW_shgroup_create(e_data.gpencil_fullscreen_sh, psl->mix_pass_noblend);
- DRW_shgroup_call_add(mix_shgrp_noblend, quad, NULL);
- DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeColor", &e_data.input_color_tx);
- DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeDepth", &e_data.input_depth_tx);
- DRW_shgroup_uniform_int(mix_shgrp_noblend, "tonemapping", &stl->storage->tonemapping, 1);
- DRW_shgroup_uniform_int(mix_shgrp_noblend, "do_select", &stl->storage->do_select_outline, 1);
- DRW_shgroup_uniform_vec4(mix_shgrp_noblend, "select_color", stl->storage->select_color, 1);
-
- /* Painting session pass (used only to speedup while the user is drawing )
- * This pass is used to show the snapshot of the current grease pencil strokes captured
- * when the user starts to draw (see comments above).
- * In this way, the previous strokes don't need to be redraw and the drawing process
- * is far to agile.
- */
- psl->background_pass = DRW_pass_create(
- "GPencil Background Painting Session Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
- DRWShadingGroup *background_shgrp = DRW_shgroup_create(e_data.gpencil_background_sh, psl->background_pass);
- DRW_shgroup_call_add(background_shgrp, quad, NULL);
- DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeColor", &e_data.background_color_tx);
- DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeDepth", &e_data.background_depth_tx);
-
- /* pass for drawing paper (only if viewport)
- * In render, the v3d is null so the paper is disabled
- * The paper is way to isolate the drawing in complex scene and to have a cleaner
- * drawing area.
- */
- if (v3d) {
- psl->paper_pass = DRW_pass_create(
- "GPencil Paper Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
- DRWShadingGroup *paper_shgrp = DRW_shgroup_create(e_data.gpencil_paper_sh, psl->paper_pass);
- DRW_shgroup_call_add(paper_shgrp, quad, NULL);
- DRW_shgroup_uniform_vec3(paper_shgrp, "color", v3d->shading.background_color, 1);
- DRW_shgroup_uniform_float(paper_shgrp, "opacity", &v3d->overlay.gpencil_paper_opacity, 1);
- }
-
- /* grid pass */
- if (v3d) {
- psl->grid_pass = DRW_pass_create(
- "GPencil Grid Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
- stl->g_data->shgrps_grid = DRW_shgroup_create(e_data.gpencil_line_sh, psl->grid_pass);
- }
-
- /* blend layers pass */
- psl->blend_pass = DRW_pass_create(
- "GPencil Blend Layers Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
- DRWShadingGroup *blend_shgrp = DRW_shgroup_create(e_data.gpencil_blend_fullscreen_sh, psl->blend_pass);
- DRW_shgroup_call_add(blend_shgrp, quad, NULL);
- DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeColor", &e_data.temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeDepth", &e_data.temp_depth_tx_a);
- DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendColor", &e_data.temp_color_tx_fx);
- DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendDepth", &e_data.temp_depth_tx_fx);
- DRW_shgroup_uniform_int(blend_shgrp, "mode", &stl->storage->blend_mode, 1);
- DRW_shgroup_uniform_int(blend_shgrp, "clamp_layer", &stl->storage->clamp_layer, 1);
- DRW_shgroup_uniform_float(blend_shgrp, "blend_opacity", &stl->storage->blend_opacity, 1);
- DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1);
-
- /* create effects passes */
- if (!stl->storage->simplify_fx) {
- GPENCIL_create_fx_passes(psl);
- }
- }
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ ToolSettings *ts = scene->toolsettings;
+ View3D *v3d = draw_ctx->v3d;
+ Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
+
+ /* Special handling for when active object is GP object (e.g. for draw mode) */
+ Object *obact = draw_ctx->obact;
+ bGPdata *obact_gpd = NULL;
+ MaterialGPencilStyle *gp_style = NULL;
+
+ if (obact && (obact->type == OB_GPENCIL) && (obact->data)) {
+ obact_gpd = (bGPdata *)obact->data;
+ /* use the brush material */
+ Material *ma = BKE_gpencil_object_material_get_from_brush(obact, brush);
+ if (ma != NULL) {
+ gp_style = ma->gp_style;
+ }
+ /* this is not common, but avoid any special situations when brush could be without material */
+ if (gp_style == NULL) {
+ gp_style = BKE_material_gpencil_settings_get(obact, obact->actcol);
+ }
+ }
+
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(g_data), "g_data");
+ stl->storage->xray = GP_XRAY_FRONT; /* used for drawing */
+ stl->storage->stroke_style = GP_STYLE_STROKE_STYLE_SOLID; /* used for drawing */
+ }
+ stl->storage->tonemapping = 0;
+
+ stl->g_data->shgrps_edit_line = NULL;
+ stl->g_data->shgrps_edit_point = NULL;
+
+ if (!stl->shgroups) {
+ /* Alloc maximum size because count strokes is very slow and can be very complex due onion skinning.
+ */
+ 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;
+ stl->g_data->do_instances = false;
+
+ {
+ /* Stroke pass 2D */
+ psl->stroke_pass_2d = DRW_pass_create("GPencil Stroke Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
+ DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND);
+ stl->storage->shgroup_id = 0;
+ /* Stroke pass 3D */
+ psl->stroke_pass_3d = DRW_pass_create("GPencil Stroke Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
+ DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
+ stl->storage->shgroup_id = 0;
+
+ /* edit pass */
+ psl->edit_pass = DRW_pass_create("GPencil Edit Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
+
+ /* detect if playing animation */
+ if (draw_ctx->evil_C) {
+
+ bool playing = ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL;
+ if (playing != stl->storage->is_playing) {
+ stl->storage->reset_cache = true;
+ }
+ stl->storage->is_playing = playing;
+ }
+ else {
+ stl->storage->is_playing = false;
+ stl->storage->reset_cache = false;
+ }
+ /* save render state */
+ stl->storage->is_render = DRW_state_is_image_render();
+ stl->storage->is_mat_preview = (bool)stl->storage->is_render &&
+ STREQ(scene->id.name + 2, "preview");
+
+ if (obact_gpd) {
+ /* for some reason, when press play there is a delay in the animation flag check
+ * and this produces errors. To be sure, we set cache as dirty because the frame
+ * is changing.
+ */
+ if (stl->storage->is_playing == true) {
+ obact_gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+ }
+ /* if render, set as dirty to update all data */
+ else if (stl->storage->is_render == true) {
+ obact_gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+ }
+ }
+
+ /* save simplify flags (can change while drawing, so it's better to save) */
+ stl->storage->simplify_fill = GP_SIMPLIFY_FILL(scene, stl->storage->is_playing);
+ stl->storage->simplify_modif = GP_SIMPLIFY_MODIF(scene, stl->storage->is_playing);
+ stl->storage->simplify_fx = GP_SIMPLIFY_FX(scene, stl->storage->is_playing);
+ stl->storage->simplify_blend = GP_SIMPLIFY_BLEND(scene, stl->storage->is_playing);
+
+ /* xray mode */
+ if (v3d) {
+ stl->storage->is_xray = XRAY_ACTIVE(v3d);
+ }
+ else {
+ stl->storage->is_xray = 0;
+ }
+
+ /* save pixsize */
+ stl->storage->pixsize = DRW_viewport_pixelsize_get();
+ if ((!DRW_state_is_opengl_render()) && (stl->storage->is_render)) {
+ stl->storage->pixsize = &stl->storage->render_pixsize;
+ }
+
+ /* detect if painting session */
+ if ((obact_gpd) && (obact_gpd->flag & GP_DATA_STROKE_PAINTMODE) &&
+ (stl->storage->is_playing == false)) {
+ /* need the original to avoid cow overhead while drawing */
+ bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&obact_gpd->id);
+ if (((gpd_orig->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) &&
+ (gpd_orig->runtime.sbuffer_size > 0) &&
+ ((gpd_orig->flag & GP_DATA_STROKE_POLYGON) == 0) && !DRW_state_is_depth()) {
+ stl->g_data->session_flag |= GP_DRW_PAINT_PAINTING;
+ }
+ else {
+ stl->g_data->session_flag = GP_DRW_PAINT_IDLE;
+ }
+ }
+ else {
+ /* if not drawing mode */
+ stl->g_data->session_flag = GP_DRW_PAINT_HOLD;
+ }
+
+ if (gp_style) {
+ stl->storage->stroke_style = gp_style->stroke_style;
+ stl->storage->color_type = GPENCIL_COLOR_SOLID;
+ if (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) {
+ stl->storage->color_type = GPENCIL_COLOR_TEXTURE;
+ if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
+ stl->storage->color_type = GPENCIL_COLOR_PATTERN;
+ }
+ }
+ }
+ else {
+ stl->storage->stroke_style = GP_STYLE_STROKE_STYLE_SOLID;
+ stl->storage->color_type = GPENCIL_COLOR_SOLID;
+ }
+
+ /* drawing buffer pass for drawing the stroke that is being drawing by the user. The data
+ * is stored in sbuffer
+ */
+ psl->drawing_pass = DRW_pass_create("GPencil Drawing Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND |
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
+
+ /* full screen pass to combine the result with default framebuffer */
+ struct GPUBatch *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_texture_ref(mix_shgrp, "strokeColor", &e_data.input_color_tx);
+ DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeDepth", &e_data.input_depth_tx);
+ DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1);
+ DRW_shgroup_uniform_int(mix_shgrp, "do_select", &stl->storage->do_select_outline, 1);
+ DRW_shgroup_uniform_vec4(mix_shgrp, "select_color", stl->storage->select_color, 1);
+
+ /* mix pass no blend used to copy between passes. A separated pass is required
+ * because if mix_pass is used, the acumulation of blend degrade the colors.
+ *
+ * This pass is used too to take the snapshot used for background_pass. This image
+ * will be used as the background while the user is drawing.
+ */
+ psl->mix_pass_noblend = DRW_pass_create("GPencil Mix Pass no blend",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
+ DRW_STATE_DEPTH_LESS);
+ DRWShadingGroup *mix_shgrp_noblend = DRW_shgroup_create(e_data.gpencil_fullscreen_sh,
+ psl->mix_pass_noblend);
+ DRW_shgroup_call_add(mix_shgrp_noblend, quad, NULL);
+ DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeColor", &e_data.input_color_tx);
+ DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeDepth", &e_data.input_depth_tx);
+ DRW_shgroup_uniform_int(mix_shgrp_noblend, "tonemapping", &stl->storage->tonemapping, 1);
+ DRW_shgroup_uniform_int(mix_shgrp_noblend, "do_select", &stl->storage->do_select_outline, 1);
+ DRW_shgroup_uniform_vec4(mix_shgrp_noblend, "select_color", stl->storage->select_color, 1);
+
+ /* Painting session pass (used only to speedup while the user is drawing )
+ * This pass is used to show the snapshot of the current grease pencil strokes captured
+ * when the user starts to draw (see comments above).
+ * In this way, the previous strokes don't need to be redraw and the drawing process
+ * is far to agile.
+ */
+ psl->background_pass = DRW_pass_create("GPencil Background Painting Session Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND |
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ DRWShadingGroup *background_shgrp = DRW_shgroup_create(e_data.gpencil_background_sh,
+ psl->background_pass);
+ DRW_shgroup_call_add(background_shgrp, quad, NULL);
+ DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeColor", &e_data.background_color_tx);
+ DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeDepth", &e_data.background_depth_tx);
+
+ /* pass for drawing paper (only if viewport)
+ * In render, the v3d is null so the paper is disabled
+ * The paper is way to isolate the drawing in complex scene and to have a cleaner
+ * drawing area.
+ */
+ if (v3d) {
+ psl->paper_pass = DRW_pass_create("GPencil Paper Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
+ DRWShadingGroup *paper_shgrp = DRW_shgroup_create(e_data.gpencil_paper_sh, psl->paper_pass);
+ DRW_shgroup_call_add(paper_shgrp, quad, NULL);
+ DRW_shgroup_uniform_vec3(paper_shgrp, "color", v3d->shading.background_color, 1);
+ DRW_shgroup_uniform_float(paper_shgrp, "opacity", &v3d->overlay.gpencil_paper_opacity, 1);
+ }
+
+ /* grid pass */
+ if (v3d) {
+ psl->grid_pass = DRW_pass_create("GPencil Grid Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND |
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
+ stl->g_data->shgrps_grid = DRW_shgroup_create(e_data.gpencil_line_sh, psl->grid_pass);
+ }
+
+ /* blend layers pass */
+ psl->blend_pass = DRW_pass_create("GPencil Blend Layers Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND |
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ DRWShadingGroup *blend_shgrp = DRW_shgroup_create(e_data.gpencil_blend_fullscreen_sh,
+ psl->blend_pass);
+ DRW_shgroup_call_add(blend_shgrp, quad, NULL);
+ DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeColor", &e_data.temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeDepth", &e_data.temp_depth_tx_a);
+ DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendColor", &e_data.temp_color_tx_fx);
+ DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendDepth", &e_data.temp_depth_tx_fx);
+ DRW_shgroup_uniform_int(blend_shgrp, "mode", &stl->storage->blend_mode, 1);
+ DRW_shgroup_uniform_int(blend_shgrp, "clamp_layer", &stl->storage->clamp_layer, 1);
+ DRW_shgroup_uniform_float(blend_shgrp, "blend_opacity", &stl->storage->blend_opacity, 1);
+ DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1);
+
+ /* create effects passes */
+ if (!stl->storage->simplify_fx) {
+ GPENCIL_create_fx_passes(psl);
+ }
+ }
}
static void gpencil_add_draw_data(void *vedata, Object *ob)
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- bGPdata *gpd = (bGPdata *)ob->data;
- const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
-
- int i = stl->g_data->gp_cache_used - 1;
- tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
-
- if (!cache_ob->is_dup_ob) {
- /* fill shading groups */
- if ((!is_multiedit) || (stl->storage->is_render)) {
- DRW_gpencil_populate_datablock(&e_data, vedata, ob, cache_ob);
- }
- else {
- DRW_gpencil_populate_multiedit(&e_data, vedata, ob, cache_ob);
- }
- }
-
- /* FX passses */
- cache_ob->has_fx = false;
- if ((!stl->storage->simplify_fx) &&
- (!ELEM(cache_ob->shading_type[0], OB_WIRE, OB_SOLID)) &&
- (BKE_shaderfx_has_gpencil(ob)))
- {
- cache_ob->has_fx = true;
- if ((!stl->storage->simplify_fx) && (!is_multiedit)) {
- DRW_gpencil_fx_prepare(&e_data, vedata, cache_ob);
- }
- }
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ bGPdata *gpd = (bGPdata *)ob->data;
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+
+ int i = stl->g_data->gp_cache_used - 1;
+ tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
+
+ if (!cache_ob->is_dup_ob) {
+ /* fill shading groups */
+ if ((!is_multiedit) || (stl->storage->is_render)) {
+ DRW_gpencil_populate_datablock(&e_data, vedata, ob, cache_ob);
+ }
+ else {
+ DRW_gpencil_populate_multiedit(&e_data, vedata, ob, cache_ob);
+ }
+ }
+
+ /* FX passses */
+ cache_ob->has_fx = false;
+ if ((!stl->storage->simplify_fx) && (!ELEM(cache_ob->shading_type[0], OB_WIRE, OB_SOLID)) &&
+ (BKE_shaderfx_has_gpencil(ob))) {
+ cache_ob->has_fx = true;
+ if ((!stl->storage->simplify_fx) && (!is_multiedit)) {
+ DRW_gpencil_fx_prepare(&e_data, vedata, cache_ob);
+ }
+ }
}
void GPENCIL_cache_populate(void *vedata, Object *ob)
{
- /* object must be visible */
- if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
- return;
- }
-
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- ToolSettings *ts = scene->toolsettings;
- View3D *v3d = draw_ctx->v3d;
- const View3DCursor *cursor = &scene->cursor;
-
- if (ob->type == OB_GPENCIL && ob->data) {
- bGPdata *gpd = (bGPdata *)ob->data;
-
- /* enable multisample and basic framebuffer creation */
- stl->storage->framebuffer_flag |= GP_FRAMEBUFFER_MULTISAMPLE;
- stl->storage->framebuffer_flag |= GP_FRAMEBUFFER_BASIC;
-
- /* when start/stop animation the cache must be set as dirty to reset all data */
- if (stl->storage->reset_cache) {
- gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
- stl->storage->reset_cache = false;
- }
-
- if ((stl->g_data->session_flag & GP_DRW_PAINT_READY) == 0) {
- /* bound box object are not visible, only external box*/
- if (ob->dt != OB_BOUNDBOX) {
- /* save gp objects for drawing later */
- stl->g_data->gp_object_cache = gpencil_object_cache_add(
- stl->g_data->gp_object_cache, ob,
- &stl->g_data->gp_cache_size, &stl->g_data->gp_cache_used);
-
- /* enable instance loop */
- if (!stl->g_data->do_instances) {
- tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[stl->g_data->gp_cache_used - 1];
- stl->g_data->do_instances = cache_ob->is_dup_ob;
- }
-
- /* load drawing data */
- gpencil_add_draw_data(vedata, ob);
- }
- }
-
- /* draw current painting strokes
- * (only if region is equal to originated paint region)
- *
- * Need to use original data because to use the copy of data, the paint
- * operator must update depsgraph and this makes that first events of the
- * mouse are missed if the datablock is very big due the time required to
- * copy the datablock. The search of the original data is faster than a
- * full datablock copy.
- * Using the original data doesn't require a copy and the feel when drawing
- * is far better.
- */
-
- bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&gpd->id);
- if ((draw_ctx->obact == ob) &&
- ((gpd_orig->runtime.ar == NULL) || (gpd_orig->runtime.ar == draw_ctx->ar)))
- {
- DRW_gpencil_populate_buffer_strokes(&e_data, vedata, ts, ob);
- }
-
- /* grid */
- if ((v3d) &&
- ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) &&
- (v3d->gp_flag & V3D_GP_SHOW_GRID) &&
- (ob->type == OB_GPENCIL) && (ob == draw_ctx->obact) &&
- ((ts->gpencil_v3d_align & GP_PROJECT_DEPTH_VIEW) == 0) &&
- ((ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) == 0))
- {
- GPU_BATCH_DISCARD_SAFE(e_data.batch_grid);
- MEM_SAFE_FREE(e_data.batch_grid);
-
- e_data.batch_grid = DRW_gpencil_get_grid(ob);
-
- /* define grid orientation */
- switch (ts->gp_sculpt.lock_axis) {
- case GP_LOCKAXIS_VIEW:
- {
- /* align always to view */
- invert_m4_m4(stl->storage->grid_matrix, draw_ctx->rv3d->viewmat);
- /* copy ob location */
- copy_v3_v3(stl->storage->grid_matrix[3], ob->obmat[3]);
- break;
- }
- case GP_LOCKAXIS_CURSOR:
- {
- float scale[3] = { 1.0f, 1.0f, 1.0f };
- loc_eul_size_to_mat4(
- stl->storage->grid_matrix,
- cursor->location,
- cursor->rotation_euler,
- scale);
- break;
- }
- default:
- {
- copy_m4_m4(stl->storage->grid_matrix, ob->obmat);
- break;
- }
- }
-
- /* Move the origin to Object or Cursor */
- if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) {
- copy_v3_v3(stl->storage->grid_matrix[3], cursor->location);
- }
- else {
- copy_v3_v3(stl->storage->grid_matrix[3], ob->obmat[3]);
- }
-
- DRW_shgroup_call_add(
- stl->g_data->shgrps_grid,
- e_data.batch_grid,
- stl->storage->grid_matrix);
- }
- }
+ /* object must be visible */
+ if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
+ return;
+ }
+
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ ToolSettings *ts = scene->toolsettings;
+ View3D *v3d = draw_ctx->v3d;
+ const View3DCursor *cursor = &scene->cursor;
+
+ if (ob->type == OB_GPENCIL && ob->data) {
+ bGPdata *gpd = (bGPdata *)ob->data;
+
+ /* enable multisample and basic framebuffer creation */
+ stl->storage->framebuffer_flag |= GP_FRAMEBUFFER_MULTISAMPLE;
+ stl->storage->framebuffer_flag |= GP_FRAMEBUFFER_BASIC;
+
+ /* when start/stop animation the cache must be set as dirty to reset all data */
+ if (stl->storage->reset_cache) {
+ gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+ stl->storage->reset_cache = false;
+ }
+
+ if ((stl->g_data->session_flag & GP_DRW_PAINT_READY) == 0) {
+ /* bound box object are not visible, only external box*/
+ if (ob->dt != OB_BOUNDBOX) {
+ /* save gp objects for drawing later */
+ stl->g_data->gp_object_cache = gpencil_object_cache_add(stl->g_data->gp_object_cache,
+ ob,
+ &stl->g_data->gp_cache_size,
+ &stl->g_data->gp_cache_used);
+
+ /* enable instance loop */
+ if (!stl->g_data->do_instances) {
+ tGPencilObjectCache *cache_ob =
+ &stl->g_data->gp_object_cache[stl->g_data->gp_cache_used - 1];
+ stl->g_data->do_instances = cache_ob->is_dup_ob;
+ }
+
+ /* load drawing data */
+ gpencil_add_draw_data(vedata, ob);
+ }
+ }
+
+ /* draw current painting strokes
+ * (only if region is equal to originated paint region)
+ *
+ * Need to use original data because to use the copy of data, the paint
+ * operator must update depsgraph and this makes that first events of the
+ * mouse are missed if the datablock is very big due the time required to
+ * copy the datablock. The search of the original data is faster than a
+ * full datablock copy.
+ * Using the original data doesn't require a copy and the feel when drawing
+ * is far better.
+ */
+
+ bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&gpd->id);
+ if ((draw_ctx->obact == ob) &&
+ ((gpd_orig->runtime.ar == NULL) || (gpd_orig->runtime.ar == draw_ctx->ar))) {
+ DRW_gpencil_populate_buffer_strokes(&e_data, vedata, ts, ob);
+ }
+
+ /* grid */
+ if ((v3d) && ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (v3d->gp_flag & V3D_GP_SHOW_GRID) &&
+ (ob->type == OB_GPENCIL) && (ob == draw_ctx->obact) &&
+ ((ts->gpencil_v3d_align & GP_PROJECT_DEPTH_VIEW) == 0) &&
+ ((ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) == 0)) {
+ GPU_BATCH_DISCARD_SAFE(e_data.batch_grid);
+ MEM_SAFE_FREE(e_data.batch_grid);
+
+ e_data.batch_grid = DRW_gpencil_get_grid(ob);
+
+ /* define grid orientation */
+ switch (ts->gp_sculpt.lock_axis) {
+ case GP_LOCKAXIS_VIEW: {
+ /* align always to view */
+ invert_m4_m4(stl->storage->grid_matrix, draw_ctx->rv3d->viewmat);
+ /* copy ob location */
+ copy_v3_v3(stl->storage->grid_matrix[3], ob->obmat[3]);
+ break;
+ }
+ case GP_LOCKAXIS_CURSOR: {
+ float scale[3] = {1.0f, 1.0f, 1.0f};
+ loc_eul_size_to_mat4(
+ stl->storage->grid_matrix, cursor->location, cursor->rotation_euler, scale);
+ break;
+ }
+ default: {
+ copy_m4_m4(stl->storage->grid_matrix, ob->obmat);
+ break;
+ }
+ }
+
+ /* Move the origin to Object or Cursor */
+ if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) {
+ copy_v3_v3(stl->storage->grid_matrix[3], cursor->location);
+ }
+ else {
+ copy_v3_v3(stl->storage->grid_matrix[3], ob->obmat[3]);
+ }
+
+ DRW_shgroup_call_add(stl->g_data->shgrps_grid, e_data.batch_grid, stl->storage->grid_matrix);
+ }
+ }
}
void GPENCIL_cache_finish(void *vedata)
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- tGPencilObjectCache *cache_ob = NULL;
- Object *ob = NULL;
-
- /* create data for instances */
- if (stl->g_data->do_instances) {
- GHash *gh_objects = BLI_ghash_str_new(__func__);
- /* create hash of real object (non duplicated) */
- for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
- cache_ob = &stl->g_data->gp_object_cache[i];
- if (!cache_ob->is_dup_ob) {
- ob = cache_ob->ob;
- char *name = BKE_id_to_unique_string_key(&ob->id);
- BLI_ghash_insert(gh_objects, name, cache_ob->ob);
- }
- }
-
- /* draw particles */
- DRW_gpencil_populate_particles(&e_data, gh_objects, vedata);
-
- /* free hash */
- BLI_ghash_free(gh_objects, MEM_freeN, NULL);
- }
-
- if (stl->g_data->session_flag & (GP_DRW_PAINT_IDLE | GP_DRW_PAINT_FILLING)) {
- stl->storage->framebuffer_flag |= GP_FRAMEBUFFER_DRAW;
- }
-
- /* create framebuffers (only for normal drawing) */
- if (!DRW_state_is_select() || !DRW_state_is_depth()) {
- GPENCIL_create_framebuffers(vedata);
- }
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ tGPencilObjectCache *cache_ob = NULL;
+ Object *ob = NULL;
+
+ /* create data for instances */
+ if (stl->g_data->do_instances) {
+ GHash *gh_objects = BLI_ghash_str_new(__func__);
+ /* create hash of real object (non duplicated) */
+ for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
+ cache_ob = &stl->g_data->gp_object_cache[i];
+ if (!cache_ob->is_dup_ob) {
+ ob = cache_ob->ob;
+ char *name = BKE_id_to_unique_string_key(&ob->id);
+ BLI_ghash_insert(gh_objects, name, cache_ob->ob);
+ }
+ }
+
+ /* draw particles */
+ DRW_gpencil_populate_particles(&e_data, gh_objects, vedata);
+
+ /* free hash */
+ BLI_ghash_free(gh_objects, MEM_freeN, NULL);
+ }
+
+ if (stl->g_data->session_flag & (GP_DRW_PAINT_IDLE | GP_DRW_PAINT_FILLING)) {
+ stl->storage->framebuffer_flag |= GP_FRAMEBUFFER_DRAW;
+ }
+
+ /* create framebuffers (only for normal drawing) */
+ if (!DRW_state_is_select() || !DRW_state_is_depth()) {
+ GPENCIL_create_framebuffers(vedata);
+ }
}
/* helper function to sort inverse gpencil objects using qsort */
static int gpencil_object_cache_compare_zdepth(const void *a1, const void *a2)
{
- const tGPencilObjectCache *ps1 = a1, *ps2 = a2;
+ const tGPencilObjectCache *ps1 = a1, *ps2 = a2;
- if (ps1->zdepth < ps2->zdepth) {
- return 1;
- }
- else if (ps1->zdepth > ps2->zdepth) {
- return -1;
- }
+ if (ps1->zdepth < ps2->zdepth) {
+ return 1;
+ }
+ else if (ps1->zdepth > ps2->zdepth) {
+ return -1;
+ }
- return 0;
+ return 0;
}
/* prepare a texture with full viewport screenshot for fast drawing */
-static void gpencil_prepare_fast_drawing(
- GPENCIL_StorageList *stl, DefaultFramebufferList *dfbl,
- GPENCIL_FramebufferList *fbl, DRWPass *pass,
- const float clearcol[4])
+static void gpencil_prepare_fast_drawing(GPENCIL_StorageList *stl,
+ DefaultFramebufferList *dfbl,
+ GPENCIL_FramebufferList *fbl,
+ DRWPass *pass,
+ const float clearcol[4])
{
- if (stl->g_data->session_flag & (GP_DRW_PAINT_IDLE | GP_DRW_PAINT_FILLING)) {
- GPU_framebuffer_bind(fbl->background_fb);
- /* clean only in first loop cycle */
- if (stl->g_data->session_flag & GP_DRW_PAINT_IDLE) {
- GPU_framebuffer_clear_color_depth(fbl->background_fb, clearcol, 1.0f);
- stl->g_data->session_flag = GP_DRW_PAINT_FILLING;
- }
- /* repeat pass to fill temp texture */
- DRW_draw_pass(pass);
- /* set default framebuffer again */
- GPU_framebuffer_bind(dfbl->default_fb);
- }
+ if (stl->g_data->session_flag & (GP_DRW_PAINT_IDLE | GP_DRW_PAINT_FILLING)) {
+ GPU_framebuffer_bind(fbl->background_fb);
+ /* clean only in first loop cycle */
+ if (stl->g_data->session_flag & GP_DRW_PAINT_IDLE) {
+ GPU_framebuffer_clear_color_depth(fbl->background_fb, clearcol, 1.0f);
+ stl->g_data->session_flag = GP_DRW_PAINT_FILLING;
+ }
+ /* repeat pass to fill temp texture */
+ DRW_draw_pass(pass);
+ /* set default framebuffer again */
+ GPU_framebuffer_bind(dfbl->default_fb);
+ }
}
static void gpencil_free_obj_runtime(GPENCIL_StorageList *stl)
{
- if (stl->g_data->gp_object_cache == NULL) {
- return;
- }
-
- /* reset all cache flags */
- for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
- tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
- if (cache_ob) {
- bGPdata *gpd = cache_ob->gpd;
- gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY;
-
- /* free shgrp array */
- cache_ob->tot_layers = 0;
- MEM_SAFE_FREE(cache_ob->name);
- MEM_SAFE_FREE(cache_ob->shgrp_array);
- }
- }
-
- /* free the cache itself */
- MEM_SAFE_FREE(stl->g_data->gp_object_cache);
+ if (stl->g_data->gp_object_cache == NULL) {
+ return;
+ }
+
+ /* reset all cache flags */
+ for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
+ tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
+ if (cache_ob) {
+ bGPdata *gpd = cache_ob->gpd;
+ gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY;
+
+ /* free shgrp array */
+ cache_ob->tot_layers = 0;
+ MEM_SAFE_FREE(cache_ob->name);
+ MEM_SAFE_FREE(cache_ob->shgrp_array);
+ }
+ }
+
+ /* free the cache itself */
+ MEM_SAFE_FREE(stl->g_data->gp_object_cache);
}
-static void gpencil_draw_pass_range(
- GPENCIL_FramebufferList *fbl, GPENCIL_StorageList *stl,
- GPENCIL_PassList *psl, GPENCIL_TextureList *txl,
- GPUFrameBuffer *fb, Object *ob, bGPdata *gpd,
- DRWShadingGroup *init_shgrp, DRWShadingGroup *end_shgrp, bool multi)
+static void gpencil_draw_pass_range(GPENCIL_FramebufferList *fbl,
+ GPENCIL_StorageList *stl,
+ GPENCIL_PassList *psl,
+ GPENCIL_TextureList *txl,
+ GPUFrameBuffer *fb,
+ Object *ob,
+ bGPdata *gpd,
+ DRWShadingGroup *init_shgrp,
+ DRWShadingGroup *end_shgrp,
+ bool multi)
{
- if (init_shgrp == NULL) {
- return;
- }
-
- /* previews don't use AA */
- if ((!stl->storage->is_mat_preview) && (multi)) {
- MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
- }
-
- DRW_draw_pass_subset(
- GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d,
- init_shgrp, end_shgrp);
-
- if ((!stl->storage->is_mat_preview) && (multi)) {
- MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fb, txl);
- }
+ if (init_shgrp == NULL) {
+ return;
+ }
+
+ /* previews don't use AA */
+ if ((!stl->storage->is_mat_preview) && (multi)) {
+ MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
+ }
+
+ DRW_draw_pass_subset(GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d,
+ init_shgrp,
+ end_shgrp);
+
+ if ((!stl->storage->is_mat_preview) && (multi)) {
+ MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fb, txl);
+ }
}
/* draw strokes to use for selection */
static void drw_gpencil_select_render(GPENCIL_StorageList *stl, GPENCIL_PassList *psl)
{
- tGPencilObjectCache *cache_ob;
- tGPencilObjectCache_shgrp *array_elm = NULL;
- DRWShadingGroup *init_shgrp = NULL;
- DRWShadingGroup *end_shgrp = NULL;
-
- /* Draw all pending objects */
- if ((stl->g_data->gp_cache_used > 0) &&
- (stl->g_data->gp_object_cache))
- {
- /* sort by zdepth */
- qsort(stl->g_data->gp_object_cache, stl->g_data->gp_cache_used,
- sizeof(tGPencilObjectCache), gpencil_object_cache_compare_zdepth);
-
- for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
- cache_ob = &stl->g_data->gp_object_cache[i];
- if (cache_ob) {
- Object *ob = cache_ob->ob;
- bGPdata *gpd = cache_ob->gpd;
- init_shgrp = NULL;
- if (cache_ob->tot_layers > 0) {
- for (int e = 0; e < cache_ob->tot_layers; e++) {
- array_elm = &cache_ob->shgrp_array[e];
- if (init_shgrp == NULL) {
- init_shgrp = array_elm->init_shgrp;
- }
- end_shgrp = array_elm->end_shgrp;
- }
- /* draw group */
- DRW_draw_pass_subset(
- GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d,
- init_shgrp, end_shgrp);
- }
- /* the cache must be dirty for next loop */
- gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
- }
- }
- }
+ tGPencilObjectCache *cache_ob;
+ tGPencilObjectCache_shgrp *array_elm = NULL;
+ DRWShadingGroup *init_shgrp = NULL;
+ DRWShadingGroup *end_shgrp = NULL;
+
+ /* Draw all pending objects */
+ if ((stl->g_data->gp_cache_used > 0) && (stl->g_data->gp_object_cache)) {
+ /* sort by zdepth */
+ qsort(stl->g_data->gp_object_cache,
+ stl->g_data->gp_cache_used,
+ sizeof(tGPencilObjectCache),
+ gpencil_object_cache_compare_zdepth);
+
+ for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
+ cache_ob = &stl->g_data->gp_object_cache[i];
+ if (cache_ob) {
+ Object *ob = cache_ob->ob;
+ bGPdata *gpd = cache_ob->gpd;
+ init_shgrp = NULL;
+ if (cache_ob->tot_layers > 0) {
+ for (int e = 0; e < cache_ob->tot_layers; e++) {
+ array_elm = &cache_ob->shgrp_array[e];
+ if (init_shgrp == NULL) {
+ init_shgrp = array_elm->init_shgrp;
+ }
+ end_shgrp = array_elm->end_shgrp;
+ }
+ /* draw group */
+ DRW_draw_pass_subset(GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d :
+ psl->stroke_pass_2d,
+ init_shgrp,
+ end_shgrp);
+ }
+ /* the cache must be dirty for next loop */
+ gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+ }
+ }
+ }
}
/* draw scene */
void GPENCIL_draw_scene(void *ved)
{
- GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
-
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
- DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl;
-
- tGPencilObjectCache *cache_ob;
- tGPencilObjectCache_shgrp *array_elm = NULL;
- DRWShadingGroup *init_shgrp = NULL;
- DRWShadingGroup *end_shgrp = NULL;
-
- const float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
-
- const DRWContextState *draw_ctx = DRW_context_state_get();
- View3D *v3d = draw_ctx->v3d;
- Object *obact = draw_ctx->obact;
- const bool playing = stl->storage->is_playing;
- const bool is_render = stl->storage->is_render;
- bGPdata *gpd_act = (obact) && (obact->type == OB_GPENCIL) ? (bGPdata *)obact->data : NULL;
- const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd_act);
- const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
-
- /* if the draw is for select, do a basic drawing and return */
- if (DRW_state_is_select() || DRW_state_is_depth()) {
- drw_gpencil_select_render(stl, psl);
- /* free memory */
- gpencil_free_obj_runtime(stl);
- return;
- }
-
- /* paper pass to display a comfortable area to draw over complex scenes with geometry */
- if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
- if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) &&
- (v3d->gp_flag & V3D_GP_SHOW_PAPER))
- {
- DRW_draw_pass(psl->paper_pass);
- }
- }
-
- /* if we have a painting session, we use fast viewport drawing method */
- if ((!is_render) && (stl->g_data->session_flag & GP_DRW_PAINT_PAINTING)) {
- GPU_framebuffer_bind(dfbl->default_fb);
-
- MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
- if (obact->dt != OB_BOUNDBOX) {
- DRW_draw_pass(psl->background_pass);
- }
- DRW_draw_pass(psl->drawing_pass);
-
- MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, dfbl->default_fb, txl);
-
- /* free memory */
- gpencil_free_obj_runtime(stl);
-
- /* grid pass */
- if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
- if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) &&
- (v3d->gp_flag & V3D_GP_SHOW_GRID))
- {
- DRW_draw_pass(psl->grid_pass);
- }
- }
- return;
- }
-
- if (DRW_state_is_fbo()) {
-
- /* Draw all pending objects */
- if (stl->g_data->gp_cache_used > 0) {
- /* sort by zdepth */
- qsort(stl->g_data->gp_object_cache, stl->g_data->gp_cache_used,
- sizeof(tGPencilObjectCache), gpencil_object_cache_compare_zdepth);
-
- for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
- cache_ob = &stl->g_data->gp_object_cache[i];
- Object *ob = cache_ob->ob;
- bGPdata *gpd = cache_ob->gpd;
- init_shgrp = NULL;
- /* Render stroke in separated framebuffer */
- GPU_framebuffer_bind(fbl->temp_fb_a);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
-
- /* Stroke Pass:
- * draw only a subset that usually starts with a fill and ends with stroke
- */
- bool use_blend = false;
- if (cache_ob->tot_layers > 0) {
- for (int e = 0; e < cache_ob->tot_layers; e++) {
- bool is_last = e == cache_ob->tot_layers - 1 ? true : false;
- array_elm = &cache_ob->shgrp_array[e];
-
- if (((array_elm->mode == eGplBlendMode_Normal) &&
- (!use_blend) && (!array_elm->clamp_layer)) ||
- (e == 0))
- {
- if (init_shgrp == NULL) {
- init_shgrp = array_elm->init_shgrp;
- }
- end_shgrp = array_elm->end_shgrp;
- }
- else {
- use_blend = true;
- /* draw pending groups */
- gpencil_draw_pass_range(
- fbl, stl, psl, txl, fbl->temp_fb_a,
- ob, gpd, init_shgrp, end_shgrp, is_last);
-
- /* draw current group in separated texture */
- init_shgrp = array_elm->init_shgrp;
- end_shgrp = array_elm->end_shgrp;
-
- GPU_framebuffer_bind(fbl->temp_fb_fx);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
- gpencil_draw_pass_range(
- fbl, stl, psl, txl, fbl->temp_fb_fx,
- ob, gpd, init_shgrp, end_shgrp,
- is_last);
-
- /* Blend A texture and FX texture */
- GPU_framebuffer_bind(fbl->temp_fb_b);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
- stl->storage->blend_mode = array_elm->mode;
- stl->storage->clamp_layer = (int)array_elm->clamp_layer;
- stl->storage->blend_opacity = array_elm->blend_opacity;
- stl->storage->tonemapping = stl->storage->is_render ? 1 : 0;
- DRW_draw_pass(psl->blend_pass);
- stl->storage->tonemapping = 0;
-
- /* Copy B texture to A texture to follow loop */
- e_data.input_depth_tx = e_data.temp_depth_tx_b;
- e_data.input_color_tx = e_data.temp_color_tx_b;
-
- GPU_framebuffer_bind(fbl->temp_fb_a);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
- DRW_draw_pass(psl->mix_pass_noblend);
-
- /* prepare next group */
- init_shgrp = NULL;
- }
- }
- /* last group */
- gpencil_draw_pass_range(
- fbl, stl, psl, txl, fbl->temp_fb_a,
- ob, gpd, init_shgrp, end_shgrp,
- true);
- }
-
- /* Current buffer drawing */
- if ((!is_render) && (cache_ob->is_dup_ob == false)) {
- DRW_draw_pass(psl->drawing_pass);
- }
- /* fx passes */
- if (cache_ob->has_fx == true) {
- stl->storage->tonemapping = 0;
- DRW_gpencil_fx_draw(&e_data, vedata, cache_ob);
- }
-
- e_data.input_depth_tx = e_data.temp_depth_tx_a;
- e_data.input_color_tx = e_data.temp_color_tx_a;
-
- /* Combine with scene buffer */
- if ((!is_render) || (fbl->main == NULL)) {
- GPU_framebuffer_bind(dfbl->default_fb);
- }
- else {
- GPU_framebuffer_bind(fbl->main);
- }
- /* tonemapping */
- stl->storage->tonemapping = stl->storage->is_render ? 1 : 0;
-
- /* active select flag and selection color */
- stl->storage->do_select_outline = (
- (overlay) &&
- (ob->base_flag & BASE_SELECTED) &&
- (ob->mode == OB_MODE_OBJECT) &&
- (!is_render) && (!playing) &&
- (v3d->flag & V3D_SELECT_OUTLINE));
-
- /* if active object is not object mode, disable for all objects */
- if ((draw_ctx->obact) && (draw_ctx->obact->mode != OB_MODE_OBJECT)) {
- stl->storage->do_select_outline = 0;
- }
- UI_GetThemeColorShadeAlpha4fv(
- (ob == draw_ctx->obact) ? TH_ACTIVE : TH_SELECT, 0, -40,
- stl->storage->select_color);
-
- /* draw mix pass */
- DRW_draw_pass(psl->mix_pass);
-
- /* disable select flag */
- stl->storage->do_select_outline = 0;
-
- /* prepare for fast drawing */
- if (!is_render) {
- if (!playing) {
- gpencil_prepare_fast_drawing(stl, dfbl, fbl, psl->mix_pass_noblend, clearcol);
- }
- }
- else {
- /* if render, the cache must be dirty for next loop */
- gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
- }
- }
- /* edit points */
- if ((!is_render) && (!playing) && (is_edit)) {
- DRW_draw_pass(psl->edit_pass);
- }
- }
- /* grid pass */
- if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
- if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) &&
- (v3d->gp_flag & V3D_GP_SHOW_GRID))
- {
- DRW_draw_pass(psl->grid_pass);
- }
- }
- }
- /* free memory */
- gpencil_free_obj_runtime(stl);
-
- /* reset */
- if (DRW_state_is_fbo()) {
- /* attach again default framebuffer */
- if (!is_render) {
- GPU_framebuffer_bind(dfbl->default_fb);
- }
-
- /* the temp texture is ready. Now we can use fast screen drawing */
- if (stl->g_data->session_flag & GP_DRW_PAINT_FILLING) {
- stl->g_data->session_flag = GP_DRW_PAINT_READY;
- }
- }
+ GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl;
+
+ tGPencilObjectCache *cache_ob;
+ tGPencilObjectCache_shgrp *array_elm = NULL;
+ DRWShadingGroup *init_shgrp = NULL;
+ DRWShadingGroup *end_shgrp = NULL;
+
+ const float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+ Object *obact = draw_ctx->obact;
+ const bool playing = stl->storage->is_playing;
+ const bool is_render = stl->storage->is_render;
+ bGPdata *gpd_act = (obact) && (obact->type == OB_GPENCIL) ? (bGPdata *)obact->data : NULL;
+ const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd_act);
+ const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
+
+ /* if the draw is for select, do a basic drawing and return */
+ if (DRW_state_is_select() || DRW_state_is_depth()) {
+ drw_gpencil_select_render(stl, psl);
+ /* free memory */
+ gpencil_free_obj_runtime(stl);
+ return;
+ }
+
+ /* paper pass to display a comfortable area to draw over complex scenes with geometry */
+ if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
+ if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (v3d->gp_flag & V3D_GP_SHOW_PAPER)) {
+ DRW_draw_pass(psl->paper_pass);
+ }
+ }
+
+ /* if we have a painting session, we use fast viewport drawing method */
+ if ((!is_render) && (stl->g_data->session_flag & GP_DRW_PAINT_PAINTING)) {
+ GPU_framebuffer_bind(dfbl->default_fb);
+
+ MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
+ if (obact->dt != OB_BOUNDBOX) {
+ DRW_draw_pass(psl->background_pass);
+ }
+ DRW_draw_pass(psl->drawing_pass);
+
+ MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, dfbl->default_fb, txl);
+
+ /* free memory */
+ gpencil_free_obj_runtime(stl);
+
+ /* grid pass */
+ if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
+ if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (v3d->gp_flag & V3D_GP_SHOW_GRID)) {
+ DRW_draw_pass(psl->grid_pass);
+ }
+ }
+ return;
+ }
+
+ if (DRW_state_is_fbo()) {
+
+ /* Draw all pending objects */
+ if (stl->g_data->gp_cache_used > 0) {
+ /* sort by zdepth */
+ qsort(stl->g_data->gp_object_cache,
+ stl->g_data->gp_cache_used,
+ sizeof(tGPencilObjectCache),
+ gpencil_object_cache_compare_zdepth);
+
+ for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
+ cache_ob = &stl->g_data->gp_object_cache[i];
+ Object *ob = cache_ob->ob;
+ bGPdata *gpd = cache_ob->gpd;
+ init_shgrp = NULL;
+ /* Render stroke in separated framebuffer */
+ GPU_framebuffer_bind(fbl->temp_fb_a);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
+
+ /* Stroke Pass:
+ * draw only a subset that usually starts with a fill and ends with stroke
+ */
+ bool use_blend = false;
+ if (cache_ob->tot_layers > 0) {
+ for (int e = 0; e < cache_ob->tot_layers; e++) {
+ bool is_last = e == cache_ob->tot_layers - 1 ? true : false;
+ array_elm = &cache_ob->shgrp_array[e];
+
+ if (((array_elm->mode == eGplBlendMode_Normal) && (!use_blend) &&
+ (!array_elm->clamp_layer)) ||
+ (e == 0)) {
+ if (init_shgrp == NULL) {
+ init_shgrp = array_elm->init_shgrp;
+ }
+ end_shgrp = array_elm->end_shgrp;
+ }
+ else {
+ use_blend = true;
+ /* draw pending groups */
+ gpencil_draw_pass_range(
+ fbl, stl, psl, txl, fbl->temp_fb_a, ob, gpd, init_shgrp, end_shgrp, is_last);
+
+ /* draw current group in separated texture */
+ init_shgrp = array_elm->init_shgrp;
+ end_shgrp = array_elm->end_shgrp;
+
+ GPU_framebuffer_bind(fbl->temp_fb_fx);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
+ gpencil_draw_pass_range(
+ fbl, stl, psl, txl, fbl->temp_fb_fx, ob, gpd, init_shgrp, end_shgrp, is_last);
+
+ /* Blend A texture and FX texture */
+ GPU_framebuffer_bind(fbl->temp_fb_b);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
+ stl->storage->blend_mode = array_elm->mode;
+ stl->storage->clamp_layer = (int)array_elm->clamp_layer;
+ stl->storage->blend_opacity = array_elm->blend_opacity;
+ stl->storage->tonemapping = stl->storage->is_render ? 1 : 0;
+ DRW_draw_pass(psl->blend_pass);
+ stl->storage->tonemapping = 0;
+
+ /* Copy B texture to A texture to follow loop */
+ e_data.input_depth_tx = e_data.temp_depth_tx_b;
+ e_data.input_color_tx = e_data.temp_color_tx_b;
+
+ GPU_framebuffer_bind(fbl->temp_fb_a);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
+ DRW_draw_pass(psl->mix_pass_noblend);
+
+ /* prepare next group */
+ init_shgrp = NULL;
+ }
+ }
+ /* last group */
+ gpencil_draw_pass_range(
+ fbl, stl, psl, txl, fbl->temp_fb_a, ob, gpd, init_shgrp, end_shgrp, true);
+ }
+
+ /* Current buffer drawing */
+ if ((!is_render) && (cache_ob->is_dup_ob == false)) {
+ DRW_draw_pass(psl->drawing_pass);
+ }
+ /* fx passes */
+ if (cache_ob->has_fx == true) {
+ stl->storage->tonemapping = 0;
+ DRW_gpencil_fx_draw(&e_data, vedata, cache_ob);
+ }
+
+ e_data.input_depth_tx = e_data.temp_depth_tx_a;
+ e_data.input_color_tx = e_data.temp_color_tx_a;
+
+ /* Combine with scene buffer */
+ if ((!is_render) || (fbl->main == NULL)) {
+ GPU_framebuffer_bind(dfbl->default_fb);
+ }
+ else {
+ GPU_framebuffer_bind(fbl->main);
+ }
+ /* tonemapping */
+ stl->storage->tonemapping = stl->storage->is_render ? 1 : 0;
+
+ /* active select flag and selection color */
+ stl->storage->do_select_outline = ((overlay) && (ob->base_flag & BASE_SELECTED) &&
+ (ob->mode == OB_MODE_OBJECT) && (!is_render) &&
+ (!playing) && (v3d->flag & V3D_SELECT_OUTLINE));
+
+ /* if active object is not object mode, disable for all objects */
+ if ((draw_ctx->obact) && (draw_ctx->obact->mode != OB_MODE_OBJECT)) {
+ stl->storage->do_select_outline = 0;
+ }
+ UI_GetThemeColorShadeAlpha4fv(
+ (ob == draw_ctx->obact) ? TH_ACTIVE : TH_SELECT, 0, -40, stl->storage->select_color);
+
+ /* draw mix pass */
+ DRW_draw_pass(psl->mix_pass);
+
+ /* disable select flag */
+ stl->storage->do_select_outline = 0;
+
+ /* prepare for fast drawing */
+ if (!is_render) {
+ if (!playing) {
+ gpencil_prepare_fast_drawing(stl, dfbl, fbl, psl->mix_pass_noblend, clearcol);
+ }
+ }
+ else {
+ /* if render, the cache must be dirty for next loop */
+ gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+ }
+ }
+ /* edit points */
+ if ((!is_render) && (!playing) && (is_edit)) {
+ DRW_draw_pass(psl->edit_pass);
+ }
+ }
+ /* grid pass */
+ if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
+ if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (v3d->gp_flag & V3D_GP_SHOW_GRID)) {
+ DRW_draw_pass(psl->grid_pass);
+ }
+ }
+ }
+ /* free memory */
+ gpencil_free_obj_runtime(stl);
+
+ /* reset */
+ if (DRW_state_is_fbo()) {
+ /* attach again default framebuffer */
+ if (!is_render) {
+ GPU_framebuffer_bind(dfbl->default_fb);
+ }
+
+ /* the temp texture is ready. Now we can use fast screen drawing */
+ if (stl->g_data->session_flag & GP_DRW_PAINT_FILLING) {
+ stl->g_data->session_flag = GP_DRW_PAINT_READY;
+ }
+ }
}
static const DrawEngineDataSize GPENCIL_data_size = DRW_VIEWPORT_DATA_SIZE(GPENCIL_Data);
DrawEngineType draw_engine_gpencil_type = {
- NULL, NULL,
- N_("GpencilMode"),
- &GPENCIL_data_size,
- &GPENCIL_engine_init,
- &GPENCIL_engine_free,
- &GPENCIL_cache_init,
- &GPENCIL_cache_populate,
- &GPENCIL_cache_finish,
- NULL,
- &GPENCIL_draw_scene,
- NULL,
- NULL,
- &GPENCIL_render_to_image,
+ NULL,
+ NULL,
+ N_("GpencilMode"),
+ &GPENCIL_data_size,
+ &GPENCIL_engine_init,
+ &GPENCIL_engine_free,
+ &GPENCIL_cache_init,
+ &GPENCIL_cache_populate,
+ &GPENCIL_cache_finish,
+ NULL,
+ &GPENCIL_draw_scene,
+ NULL,
+ NULL,
+ &GPENCIL_render_to_image,
};
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 5d0d2397f8d..3add2cb0f1b 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -42,376 +42,414 @@ struct tGPspoint;
/* used to expand VBOs. Size has a big impact in the speed */
#define GPENCIL_VBO_BLOCK_SIZE 128
-#define GPENCIL_COLOR_SOLID 0
+#define GPENCIL_COLOR_SOLID 0
#define GPENCIL_COLOR_TEXTURE 1
#define GPENCIL_COLOR_PATTERN 2
#define GP_SIMPLIFY(scene) ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ENABLE))
-#define GP_SIMPLIFY_ONPLAY(playing) (((playing == true) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY)) || ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY) == 0))
-#define GP_SIMPLIFY_FILL(scene, playing) ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FILL)))
-#define GP_SIMPLIFY_MODIF(scene, playing) ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_MODIFIER)))
-#define GP_SIMPLIFY_FX(scene, playing) ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FX)))
-#define GP_SIMPLIFY_BLEND(scene, playing) ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_BLEND)))
+#define GP_SIMPLIFY_ONPLAY(playing) \
+ (((playing == true) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY)) || \
+ ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY) == 0))
+#define GP_SIMPLIFY_FILL(scene, playing) \
+ ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && \
+ (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FILL)))
+#define GP_SIMPLIFY_MODIF(scene, playing) \
+ ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && \
+ (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_MODIFIER)))
+#define GP_SIMPLIFY_FX(scene, playing) \
+ ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && \
+ (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FX)))
+#define GP_SIMPLIFY_BLEND(scene, playing) \
+ ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && \
+ (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_BLEND)))
#define GP_IS_CAMERAVIEW ((rv3d != NULL) && (rv3d->persp == RV3D_CAMOB && v3d->camera))
- /* *********** OBJECTS CACHE *********** */
+/* *********** OBJECTS CACHE *********** */
typedef struct tGPencilObjectCache_shgrp {
- int mode;
- bool clamp_layer;
- float blend_opacity;
- DRWShadingGroup *init_shgrp;
- DRWShadingGroup *end_shgrp;
+ int mode;
+ bool clamp_layer;
+ float blend_opacity;
+ DRWShadingGroup *init_shgrp;
+ DRWShadingGroup *end_shgrp;
} tGPencilObjectCache_shgrp;
- /* used to save gpencil object data for drawing */
+/* used to save gpencil object data for drawing */
typedef struct tGPencilObjectCache {
- struct Object *ob;
- struct bGPdata *gpd;
- int idx; /*original index, can change after sort */
- char *name;
-
- /* effects */
- bool has_fx;
- ListBase shader_fx;
- float pixfactor;
- DRWShadingGroup *fx_wave_sh;
- DRWShadingGroup *fx_blur_sh;
- DRWShadingGroup *fx_colorize_sh;
- DRWShadingGroup *fx_pixel_sh;
- DRWShadingGroup *fx_rim_sh;
- DRWShadingGroup *fx_shadow_sh;
- DRWShadingGroup *fx_glow_sh;
- DRWShadingGroup *fx_swirl_sh;
- DRWShadingGroup *fx_flip_sh;
- DRWShadingGroup *fx_light_sh;
-
- float loc[3];
- float obmat[4][4];
- float zdepth; /* z-depth value to sort gp object */
- bool is_dup_ob; /* flag to tag duplicate objects */
- float scale;
-
- /* shading type */
- int shading_type[2];
-
- /* GPU data size */
- int tot_vertex;
- int tot_triangles;
-
- /* Save shader groups by layer */
- int tot_layers;
- tGPencilObjectCache_shgrp *shgrp_array;
+ struct Object *ob;
+ struct bGPdata *gpd;
+ int idx; /*original index, can change after sort */
+ char *name;
+
+ /* effects */
+ bool has_fx;
+ ListBase shader_fx;
+ float pixfactor;
+ DRWShadingGroup *fx_wave_sh;
+ DRWShadingGroup *fx_blur_sh;
+ DRWShadingGroup *fx_colorize_sh;
+ DRWShadingGroup *fx_pixel_sh;
+ DRWShadingGroup *fx_rim_sh;
+ DRWShadingGroup *fx_shadow_sh;
+ DRWShadingGroup *fx_glow_sh;
+ DRWShadingGroup *fx_swirl_sh;
+ DRWShadingGroup *fx_flip_sh;
+ DRWShadingGroup *fx_light_sh;
+
+ float loc[3];
+ float obmat[4][4];
+ float zdepth; /* z-depth value to sort gp object */
+ bool is_dup_ob; /* flag to tag duplicate objects */
+ float scale;
+
+ /* shading type */
+ int shading_type[2];
+
+ /* GPU data size */
+ int tot_vertex;
+ int tot_triangles;
+
+ /* Save shader groups by layer */
+ int tot_layers;
+ tGPencilObjectCache_shgrp *shgrp_array;
} tGPencilObjectCache;
- /* *********** LISTS *********** */
+/* *********** LISTS *********** */
typedef struct GPENCIL_shgroup {
- int s_clamp;
- int stroke_style;
- int color_type;
- int mode;
- int texture_mix;
- int texture_flip;
- int texture_clamp;
- int fill_style;
- int keep_size;
- int caps_mode[2];
- float obj_scale;
- int xray_mode;
- int use_follow_path;
-
- float gradient_f;
- float gradient_s[2];
-
- /* color of the wireframe */
- float wire_color[4];
- /* shading type and mode */
- int shading_type[2];
- int is_xray;
+ int s_clamp;
+ int stroke_style;
+ int color_type;
+ int mode;
+ int texture_mix;
+ int texture_flip;
+ int texture_clamp;
+ int fill_style;
+ int keep_size;
+ int caps_mode[2];
+ float obj_scale;
+ int xray_mode;
+ int use_follow_path;
+
+ float gradient_f;
+ float gradient_s[2];
+
+ /* color of the wireframe */
+ float wire_color[4];
+ /* shading type and mode */
+ int shading_type[2];
+ int is_xray;
} GPENCIL_shgroup;
typedef struct GPENCIL_Storage {
- int shgroup_id; /* total elements */
- float unit_matrix[4][4];
- int stroke_style;
- int color_type;
- int mode;
- int xray;
- int keep_size;
- float obj_scale;
- float pixfactor;
- bool is_playing;
- bool is_render;
- bool is_mat_preview;
- int is_xray;
- bool reset_cache;
- bool buffer_stroke;
- bool buffer_fill;
- bool buffer_ctrlpoint;
- const float *pixsize;
- float render_pixsize;
- int tonemapping;
- int do_select_outline;
- float select_color[4];
- short multisamples;
-
- short framebuffer_flag; /* flag what framebuffer need to create */
-
- int blend_mode;
- int clamp_layer;
- float blend_opacity;
-
- /* simplify settings*/
- bool simplify_fill;
- bool simplify_modif;
- bool simplify_fx;
- bool simplify_blend;
-
- float gradient_f;
- float gradient_s[2];
- int use_follow_path;
-
- /* Render Matrices and data */
- float persmat[4][4], persinv[4][4];
- float viewmat[4][4], viewinv[4][4];
- float winmat[4][4], wininv[4][4];
- float view_vecs[2][4]; /* vec4[2] */
-
- float grid_matrix[4][4];
- int shade_render[2];
-
- Object *camera; /* camera pointer for render mode */
+ int shgroup_id; /* total elements */
+ float unit_matrix[4][4];
+ int stroke_style;
+ int color_type;
+ int mode;
+ int xray;
+ int keep_size;
+ float obj_scale;
+ float pixfactor;
+ bool is_playing;
+ bool is_render;
+ bool is_mat_preview;
+ int is_xray;
+ bool reset_cache;
+ bool buffer_stroke;
+ bool buffer_fill;
+ bool buffer_ctrlpoint;
+ const float *pixsize;
+ float render_pixsize;
+ int tonemapping;
+ int do_select_outline;
+ float select_color[4];
+ short multisamples;
+
+ short framebuffer_flag; /* flag what framebuffer need to create */
+
+ int blend_mode;
+ int clamp_layer;
+ float blend_opacity;
+
+ /* simplify settings*/
+ bool simplify_fill;
+ bool simplify_modif;
+ bool simplify_fx;
+ bool simplify_blend;
+
+ float gradient_f;
+ float gradient_s[2];
+ int use_follow_path;
+
+ /* Render Matrices and data */
+ float persmat[4][4], persinv[4][4];
+ float viewmat[4][4], viewinv[4][4];
+ float winmat[4][4], wininv[4][4];
+ float view_vecs[2][4]; /* vec4[2] */
+
+ float grid_matrix[4][4];
+ int shade_render[2];
+
+ Object *camera; /* camera pointer for render mode */
} GPENCIL_Storage;
typedef enum eGpencilFramebuffer_Flag {
- GP_FRAMEBUFFER_MULTISAMPLE = (1 << 0),
- GP_FRAMEBUFFER_BASIC = (1 << 1),
- GP_FRAMEBUFFER_DRAW = (1 << 2),
+ GP_FRAMEBUFFER_MULTISAMPLE = (1 << 0),
+ GP_FRAMEBUFFER_BASIC = (1 << 1),
+ GP_FRAMEBUFFER_DRAW = (1 << 2),
} eGpencilFramebuffer_Flag;
typedef struct GPENCIL_StorageList {
- struct GPENCIL_Storage *storage;
- struct g_data *g_data;
- struct GPENCIL_shgroup *shgroups;
+ struct GPENCIL_Storage *storage;
+ struct g_data *g_data;
+ struct GPENCIL_shgroup *shgroups;
} GPENCIL_StorageList;
typedef struct GPENCIL_PassList {
- struct DRWPass *stroke_pass_2d;
- struct DRWPass *stroke_pass_3d;
- struct DRWPass *edit_pass;
- struct DRWPass *drawing_pass;
- struct DRWPass *mix_pass;
- struct DRWPass *mix_pass_noblend;
- struct DRWPass *background_pass;
- struct DRWPass *paper_pass;
- struct DRWPass *grid_pass;
- struct DRWPass *blend_pass;
-
- /* effects */
- struct DRWPass *fx_shader_pass;
- struct DRWPass *fx_shader_pass_blend;
+ struct DRWPass *stroke_pass_2d;
+ struct DRWPass *stroke_pass_3d;
+ struct DRWPass *edit_pass;
+ struct DRWPass *drawing_pass;
+ struct DRWPass *mix_pass;
+ struct DRWPass *mix_pass_noblend;
+ struct DRWPass *background_pass;
+ struct DRWPass *paper_pass;
+ struct DRWPass *grid_pass;
+ struct DRWPass *blend_pass;
+
+ /* effects */
+ struct DRWPass *fx_shader_pass;
+ struct DRWPass *fx_shader_pass_blend;
} GPENCIL_PassList;
typedef struct GPENCIL_FramebufferList {
- struct GPUFrameBuffer *main;
- struct GPUFrameBuffer *temp_fb_a;
- struct GPUFrameBuffer *temp_fb_b;
- struct GPUFrameBuffer *temp_fb_fx;
- struct GPUFrameBuffer *background_fb;
+ struct GPUFrameBuffer *main;
+ struct GPUFrameBuffer *temp_fb_a;
+ struct GPUFrameBuffer *temp_fb_b;
+ struct GPUFrameBuffer *temp_fb_fx;
+ struct GPUFrameBuffer *background_fb;
- struct GPUFrameBuffer *multisample_fb;
+ struct GPUFrameBuffer *multisample_fb;
} GPENCIL_FramebufferList;
typedef struct GPENCIL_TextureList {
- struct GPUTexture *texture;
+ struct GPUTexture *texture;
- /* multisample textures */
- struct GPUTexture *multisample_color;
- struct GPUTexture *multisample_depth;
+ /* multisample textures */
+ struct GPUTexture *multisample_color;
+ struct GPUTexture *multisample_depth;
} GPENCIL_TextureList;
typedef struct GPENCIL_Data {
- void *engine_type; /* Required */
- struct GPENCIL_FramebufferList *fbl;
- struct GPENCIL_TextureList *txl;
- struct GPENCIL_PassList *psl;
- struct GPENCIL_StorageList *stl;
+ void *engine_type; /* Required */
+ struct GPENCIL_FramebufferList *fbl;
+ struct GPENCIL_TextureList *txl;
+ struct GPENCIL_PassList *psl;
+ struct GPENCIL_StorageList *stl;
- /* render textures */
- struct GPUTexture *render_depth_tx;
- struct GPUTexture *render_color_tx;
+ /* render textures */
+ struct GPUTexture *render_depth_tx;
+ struct GPUTexture *render_color_tx;
} GPENCIL_Data;
/* *********** STATIC *********** */
typedef struct g_data {
- struct DRWShadingGroup *shgrps_edit_point;
- struct DRWShadingGroup *shgrps_edit_line;
- struct DRWShadingGroup *shgrps_drawing_stroke;
- struct DRWShadingGroup *shgrps_drawing_fill;
- struct DRWShadingGroup *shgrps_grid;
+ struct DRWShadingGroup *shgrps_edit_point;
+ struct DRWShadingGroup *shgrps_edit_line;
+ struct DRWShadingGroup *shgrps_drawing_stroke;
+ struct DRWShadingGroup *shgrps_drawing_fill;
+ struct DRWShadingGroup *shgrps_grid;
- int gp_cache_used; /* total objects in cache */
- int gp_cache_size; /* size of the cache */
- struct tGPencilObjectCache *gp_object_cache;
+ int gp_cache_used; /* total objects in cache */
+ int gp_cache_size; /* size of the cache */
+ struct tGPencilObjectCache *gp_object_cache;
- int session_flag;
- bool do_instances;
+ int session_flag;
+ bool do_instances;
} g_data; /* Transient data */
/* flags for fast drawing support */
typedef enum eGPsession_Flag {
- GP_DRW_PAINT_HOLD = (1 << 0),
- GP_DRW_PAINT_IDLE = (1 << 1),
- GP_DRW_PAINT_FILLING = (1 << 2),
- GP_DRW_PAINT_READY = (1 << 3),
- GP_DRW_PAINT_PAINTING = (1 << 4),
+ GP_DRW_PAINT_HOLD = (1 << 0),
+ GP_DRW_PAINT_IDLE = (1 << 1),
+ GP_DRW_PAINT_FILLING = (1 << 2),
+ GP_DRW_PAINT_READY = (1 << 3),
+ GP_DRW_PAINT_PAINTING = (1 << 4),
} eGPsession_Flag;
typedef struct GPENCIL_e_data {
- /* general drawing shaders */
- struct GPUShader *gpencil_fill_sh;
- struct GPUShader *gpencil_stroke_sh;
- struct GPUShader *gpencil_point_sh;
- struct GPUShader *gpencil_edit_point_sh;
- struct GPUShader *gpencil_line_sh;
- struct GPUShader *gpencil_drawing_fill_sh;
- struct GPUShader *gpencil_fullscreen_sh;
- struct GPUShader *gpencil_simple_fullscreen_sh;
- struct GPUShader *gpencil_blend_fullscreen_sh;
- struct GPUShader *gpencil_background_sh;
- struct GPUShader *gpencil_paper_sh;
-
- /* effects */
- struct GPUShader *gpencil_fx_blur_sh;
- struct GPUShader *gpencil_fx_colorize_sh;
- struct GPUShader *gpencil_fx_flip_sh;
- struct GPUShader *gpencil_fx_glow_prepare_sh;
- struct GPUShader *gpencil_fx_glow_resolve_sh;
- struct GPUShader *gpencil_fx_light_sh;
- struct GPUShader *gpencil_fx_pixel_sh;
- struct GPUShader *gpencil_fx_rim_prepare_sh;
- struct GPUShader *gpencil_fx_rim_resolve_sh;
- struct GPUShader *gpencil_fx_shadow_prepare_sh;
- struct GPUShader *gpencil_fx_shadow_resolve_sh;
- struct GPUShader *gpencil_fx_swirl_sh;
- struct GPUShader *gpencil_fx_wave_sh;
-
- /* textures */
- struct GPUTexture *background_depth_tx;
- struct GPUTexture *background_color_tx;
-
- struct GPUTexture *gpencil_blank_texture;
-
- /* runtime pointers texture */
- struct GPUTexture *input_depth_tx;
- struct GPUTexture *input_color_tx;
-
- /* working textures */
- struct GPUTexture *temp_color_tx_a;
- struct GPUTexture *temp_depth_tx_a;
-
- struct GPUTexture *temp_color_tx_b;
- struct GPUTexture *temp_depth_tx_b;
-
- struct GPUTexture *temp_color_tx_fx;
- struct GPUTexture *temp_depth_tx_fx;
-
- /* for buffer only one batch is nedeed because the drawing is only of one stroke */
- GPUBatch *batch_buffer_stroke;
- GPUBatch *batch_buffer_fill;
- GPUBatch *batch_buffer_ctrlpoint;
-
- /* grid geometry */
- GPUBatch *batch_grid;
+ /* general drawing shaders */
+ struct GPUShader *gpencil_fill_sh;
+ struct GPUShader *gpencil_stroke_sh;
+ struct GPUShader *gpencil_point_sh;
+ struct GPUShader *gpencil_edit_point_sh;
+ struct GPUShader *gpencil_line_sh;
+ struct GPUShader *gpencil_drawing_fill_sh;
+ struct GPUShader *gpencil_fullscreen_sh;
+ struct GPUShader *gpencil_simple_fullscreen_sh;
+ struct GPUShader *gpencil_blend_fullscreen_sh;
+ struct GPUShader *gpencil_background_sh;
+ struct GPUShader *gpencil_paper_sh;
+
+ /* effects */
+ struct GPUShader *gpencil_fx_blur_sh;
+ struct GPUShader *gpencil_fx_colorize_sh;
+ struct GPUShader *gpencil_fx_flip_sh;
+ struct GPUShader *gpencil_fx_glow_prepare_sh;
+ struct GPUShader *gpencil_fx_glow_resolve_sh;
+ struct GPUShader *gpencil_fx_light_sh;
+ struct GPUShader *gpencil_fx_pixel_sh;
+ struct GPUShader *gpencil_fx_rim_prepare_sh;
+ struct GPUShader *gpencil_fx_rim_resolve_sh;
+ struct GPUShader *gpencil_fx_shadow_prepare_sh;
+ struct GPUShader *gpencil_fx_shadow_resolve_sh;
+ struct GPUShader *gpencil_fx_swirl_sh;
+ struct GPUShader *gpencil_fx_wave_sh;
+
+ /* textures */
+ struct GPUTexture *background_depth_tx;
+ struct GPUTexture *background_color_tx;
+
+ struct GPUTexture *gpencil_blank_texture;
+
+ /* runtime pointers texture */
+ struct GPUTexture *input_depth_tx;
+ struct GPUTexture *input_color_tx;
+
+ /* working textures */
+ struct GPUTexture *temp_color_tx_a;
+ struct GPUTexture *temp_depth_tx_a;
+
+ struct GPUTexture *temp_color_tx_b;
+ struct GPUTexture *temp_depth_tx_b;
+
+ struct GPUTexture *temp_color_tx_fx;
+ struct GPUTexture *temp_depth_tx_fx;
+
+ /* for buffer only one batch is nedeed because the drawing is only of one stroke */
+ GPUBatch *batch_buffer_stroke;
+ GPUBatch *batch_buffer_fill;
+ GPUBatch *batch_buffer_ctrlpoint;
+
+ /* grid geometry */
+ GPUBatch *batch_grid;
} GPENCIL_e_data; /* Engine data */
/* GPUBatch Cache */
typedef struct GpencilBatchCacheElem {
- GPUBatch *batch;
- GPUVertBuf *vbo;
- int vbo_len;
- /* attr ids */
- GPUVertFormat format;
- uint pos_id;
- uint color_id;
- uint thickness_id;
- uint uvdata_id;
- uint prev_pos_id;
-
- /* size for VBO alloc */
- int tot_vertex;
+ GPUBatch *batch;
+ GPUVertBuf *vbo;
+ int vbo_len;
+ /* attr ids */
+ GPUVertFormat format;
+ uint pos_id;
+ uint color_id;
+ uint thickness_id;
+ uint uvdata_id;
+ uint prev_pos_id;
+
+ /* size for VBO alloc */
+ int tot_vertex;
} GpencilBatchCacheElem;
typedef struct GpencilBatchGroup {
- bGPDlayer *gpl; /* reference to original layer */
- bGPDframe *gpf; /* reference to original frame */
- bGPDstroke *gps; /* reference to original stroke */
- short type; /* type of element */
- bool onion; /* the group is part of onion skin */
- int vertex_idx; /* index of vertex data */
+ bGPDlayer *gpl; /* reference to original layer */
+ bGPDframe *gpf; /* reference to original frame */
+ bGPDstroke *gps; /* reference to original stroke */
+ short type; /* type of element */
+ bool onion; /* the group is part of onion skin */
+ int vertex_idx; /* index of vertex data */
} GpencilBatchGroup;
typedef enum GpencilBatchGroup_Type {
- eGpencilBatchGroupType_Stroke = 1,
- eGpencilBatchGroupType_Point = 2,
- eGpencilBatchGroupType_Fill = 3,
- eGpencilBatchGroupType_Edit = 4,
- eGpencilBatchGroupType_Edlin = 5,
+ eGpencilBatchGroupType_Stroke = 1,
+ eGpencilBatchGroupType_Point = 2,
+ eGpencilBatchGroupType_Fill = 3,
+ eGpencilBatchGroupType_Edit = 4,
+ eGpencilBatchGroupType_Edlin = 5,
} GpencilBatchGroup_Type;
typedef struct GpencilBatchCache {
- GpencilBatchCacheElem b_stroke;
- GpencilBatchCacheElem b_point;
- GpencilBatchCacheElem b_fill;
- GpencilBatchCacheElem b_edit;
- GpencilBatchCacheElem b_edlin;
-
- /* settings to determine if cache is invalid */
- bool is_dirty;
- bool is_editmode;
- int cache_frame;
-
- /* data with the shading groups */
- int grp_used; /* total groups in arrays */
- int grp_size; /* max size of the array */
- struct GpencilBatchGroup *grp_cache; /* array of elements */
-
- int tot_layers;
- struct bGPDframe *derived_array; /* runtime data created by modifiers */
+ GpencilBatchCacheElem b_stroke;
+ GpencilBatchCacheElem b_point;
+ GpencilBatchCacheElem b_fill;
+ GpencilBatchCacheElem b_edit;
+ GpencilBatchCacheElem b_edlin;
+
+ /* settings to determine if cache is invalid */
+ bool is_dirty;
+ bool is_editmode;
+ int cache_frame;
+
+ /* data with the shading groups */
+ int grp_used; /* total groups in arrays */
+ int grp_size; /* max size of the array */
+ struct GpencilBatchGroup *grp_cache; /* array of elements */
+
+ int tot_layers;
+ struct bGPDframe *derived_array; /* runtime data created by modifiers */
} GpencilBatchCache;
/* general drawing functions */
-struct DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(
- struct GPENCIL_e_data *e_data, struct GPENCIL_Data *vedata, struct DRWPass *pass, struct GPUShader *shader,
- struct Object *ob, struct bGPdata *gpd,
- struct bGPDlayer *gpl, struct bGPDstroke *gps,
- struct MaterialGPencilStyle *gp_style, int id, bool onion,
- const float scale, const int shading_type[2]);
-void DRW_gpencil_populate_datablock(
- struct GPENCIL_e_data *e_data, void *vedata,
- struct Object *ob, struct tGPencilObjectCache *cache_ob);
-void DRW_gpencil_populate_buffer_strokes(
- struct GPENCIL_e_data *e_data, void *vedata, struct ToolSettings *ts, struct Object *ob);
-void DRW_gpencil_populate_multiedit(
- struct GPENCIL_e_data *e_data, void *vedata,
- struct Object *ob, struct tGPencilObjectCache *cache_ob);
+struct DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(struct GPENCIL_e_data *e_data,
+ struct GPENCIL_Data *vedata,
+ struct DRWPass *pass,
+ struct GPUShader *shader,
+ struct Object *ob,
+ struct bGPdata *gpd,
+ struct bGPDlayer *gpl,
+ struct bGPDstroke *gps,
+ struct MaterialGPencilStyle *gp_style,
+ int id,
+ bool onion,
+ const float scale,
+ const int shading_type[2]);
+void DRW_gpencil_populate_datablock(struct GPENCIL_e_data *e_data,
+ void *vedata,
+ struct Object *ob,
+ struct tGPencilObjectCache *cache_ob);
+void DRW_gpencil_populate_buffer_strokes(struct GPENCIL_e_data *e_data,
+ void *vedata,
+ struct ToolSettings *ts,
+ struct Object *ob);
+void DRW_gpencil_populate_multiedit(struct GPENCIL_e_data *e_data,
+ void *vedata,
+ struct Object *ob,
+ struct tGPencilObjectCache *cache_ob);
void DRW_gpencil_triangulate_stroke_fill(struct Object *ob, struct bGPDstroke *gps);
-void DRW_gpencil_populate_particles(struct GPENCIL_e_data *e_data, struct GHash *gh_objects, void *vedata);
+void DRW_gpencil_populate_particles(struct GPENCIL_e_data *e_data,
+ struct GHash *gh_objects,
+ void *vedata);
void DRW_gpencil_multisample_ensure(struct GPENCIL_Data *vedata, int rect_w, int rect_h);
/* create geometry functions */
-void DRW_gpencil_get_point_geom(struct GpencilBatchCacheElem *be, struct bGPDstroke *gps, short thickness, const float ink[4]);
-void DRW_gpencil_get_stroke_geom(struct GpencilBatchCacheElem *be, struct bGPDstroke *gps, short thickness, const float ink[4]);
-void DRW_gpencil_get_fill_geom(struct GpencilBatchCacheElem *be, struct Object *ob, struct bGPDstroke *gps, const float color[4]);
-void DRW_gpencil_get_edit_geom(struct GpencilBatchCacheElem *be, struct bGPDstroke *gps, float alpha, short dflag);
-void DRW_gpencil_get_edlin_geom(struct GpencilBatchCacheElem *be, struct bGPDstroke *gps, float alpha, short dflag);
+void DRW_gpencil_get_point_geom(struct GpencilBatchCacheElem *be,
+ struct bGPDstroke *gps,
+ short thickness,
+ const float ink[4]);
+void DRW_gpencil_get_stroke_geom(struct GpencilBatchCacheElem *be,
+ struct bGPDstroke *gps,
+ short thickness,
+ const float ink[4]);
+void DRW_gpencil_get_fill_geom(struct GpencilBatchCacheElem *be,
+ struct Object *ob,
+ struct bGPDstroke *gps,
+ const float color[4]);
+void DRW_gpencil_get_edit_geom(struct GpencilBatchCacheElem *be,
+ struct bGPDstroke *gps,
+ float alpha,
+ short dflag);
+void DRW_gpencil_get_edlin_geom(struct GpencilBatchCacheElem *be,
+ struct bGPDstroke *gps,
+ float alpha,
+ short dflag);
struct GPUBatch *DRW_gpencil_get_buffer_stroke_geom(struct bGPdata *gpd, short thickness);
struct GPUBatch *DRW_gpencil_get_buffer_fill_geom(struct bGPdata *gpd);
@@ -420,19 +458,23 @@ struct GPUBatch *DRW_gpencil_get_buffer_ctrlpoint_geom(struct bGPdata *gpd);
struct GPUBatch *DRW_gpencil_get_grid(Object *ob);
/* object cache functions */
-struct tGPencilObjectCache *gpencil_object_cache_add(
- struct tGPencilObjectCache *cache_array, struct Object *ob,
- int *gp_cache_size, int *gp_cache_used);
+struct tGPencilObjectCache *gpencil_object_cache_add(struct tGPencilObjectCache *cache_array,
+ struct Object *ob,
+ int *gp_cache_size,
+ int *gp_cache_used);
bool DRW_gpencil_onion_active(struct bGPdata *gpd);
/* shading groups cache functions */
-struct GpencilBatchGroup *gpencil_group_cache_add(
- struct GpencilBatchGroup *cache_array,
- struct bGPDlayer *gpl, struct bGPDframe *gpf, struct bGPDstroke *gps,
- const short type, const bool onion,
- const int vertex_idx,
- int *grp_size, int *grp_used);
+struct GpencilBatchGroup *gpencil_group_cache_add(struct GpencilBatchGroup *cache_array,
+ struct bGPDlayer *gpl,
+ struct bGPDframe *gpf,
+ struct bGPDstroke *gps,
+ const short type,
+ const bool onion,
+ const int vertex_idx,
+ int *grp_size,
+ int *grp_used);
/* geometry batch cache functions */
struct GpencilBatchCache *gpencil_batch_cache_get(struct Object *ob, int cfra);
@@ -442,12 +484,12 @@ void GPENCIL_create_fx_shaders(struct GPENCIL_e_data *e_data);
void GPENCIL_delete_fx_shaders(struct GPENCIL_e_data *e_data);
void GPENCIL_create_fx_passes(struct GPENCIL_PassList *psl);
-void DRW_gpencil_fx_prepare(
- struct GPENCIL_e_data *e_data, struct GPENCIL_Data *vedata,
- struct tGPencilObjectCache *cache_ob);
-void DRW_gpencil_fx_draw(
- struct GPENCIL_e_data *e_data, struct GPENCIL_Data *vedata,
- struct tGPencilObjectCache *cache_ob);
+void DRW_gpencil_fx_prepare(struct GPENCIL_e_data *e_data,
+ struct GPENCIL_Data *vedata,
+ struct tGPencilObjectCache *cache_ob);
+void DRW_gpencil_fx_draw(struct GPENCIL_e_data *e_data,
+ struct GPENCIL_Data *vedata,
+ struct tGPencilObjectCache *cache_ob);
/* main functions */
void GPENCIL_engine_init(void *vedata);
@@ -457,33 +499,41 @@ void GPENCIL_cache_finish(void *vedata);
void GPENCIL_draw_scene(void *vedata);
/* render */
-void GPENCIL_render_init(struct GPENCIL_Data *ved, struct RenderEngine *engine, struct Depsgraph *depsgraph);
-void GPENCIL_render_to_image(void *vedata, struct RenderEngine *engine, struct RenderLayer *render_layer, const rcti *rect);
+void GPENCIL_render_init(struct GPENCIL_Data *ved,
+ struct RenderEngine *engine,
+ struct Depsgraph *depsgraph);
+void GPENCIL_render_to_image(void *vedata,
+ struct RenderEngine *engine,
+ struct RenderLayer *render_layer,
+ const rcti *rect);
/* Use of multisample framebuffers. */
-#define MULTISAMPLE_GP_SYNC_ENABLE(lvl, fbl) { \
- if ((lvl > 0) && (fbl->multisample_fb != NULL)) { \
- DRW_stats_query_start("GP Multisample Blit"); \
- GPU_framebuffer_bind(fbl->multisample_fb); \
- GPU_framebuffer_clear_color_depth(fbl->multisample_fb, (const float[4]){0.0f}, 1.0f); \
- DRW_stats_query_end(); \
- } \
-} ((void)0)
-
-#define MULTISAMPLE_GP_SYNC_DISABLE(lvl, fbl, fb, txl) { \
- if ((lvl > 0) && (fbl->multisample_fb != NULL)) { \
- DRW_stats_query_start("GP Multisample Resolve"); \
- GPU_framebuffer_bind(fb); \
- DRW_multisamples_resolve(txl->multisample_depth, txl->multisample_color, true); \
- DRW_stats_query_end(); \
- } \
-} ((void)0)
+#define MULTISAMPLE_GP_SYNC_ENABLE(lvl, fbl) \
+ { \
+ if ((lvl > 0) && (fbl->multisample_fb != NULL)) { \
+ DRW_stats_query_start("GP Multisample Blit"); \
+ GPU_framebuffer_bind(fbl->multisample_fb); \
+ GPU_framebuffer_clear_color_depth(fbl->multisample_fb, (const float[4]){0.0f}, 1.0f); \
+ DRW_stats_query_end(); \
+ } \
+ } \
+ ((void)0)
+
+#define MULTISAMPLE_GP_SYNC_DISABLE(lvl, fbl, fb, txl) \
+ { \
+ if ((lvl > 0) && (fbl->multisample_fb != NULL)) { \
+ DRW_stats_query_start("GP Multisample Resolve"); \
+ GPU_framebuffer_bind(fb); \
+ DRW_multisamples_resolve(txl->multisample_depth, txl->multisample_color, true); \
+ DRW_stats_query_end(); \
+ } \
+ } \
+ ((void)0)
#define GPENCIL_3D_DRAWMODE(ob, gpd) \
- ((gpd) && (gpd->draw_mode == GP_DRAWMODE_3D) && \
- ((ob->dtx & OB_DRAWXRAY) == 0))
+ ((gpd) && (gpd->draw_mode == GP_DRAWMODE_3D) && ((ob->dtx & OB_DRAWXRAY) == 0))
#define GPENCIL_USE_SOLID(stl) \
- ((stl) && ((stl->storage->is_render) || (stl->storage->is_mat_preview)))
+ ((stl) && ((stl->storage->is_render) || (stl->storage->is_mat_preview)))
#endif /* __GPENCIL_ENGINE_H__ */
diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c
index 45fef77cbac..282c4ca3a77 100644
--- a/source/blender/draw/engines/gpencil/gpencil_render.c
+++ b/source/blender/draw/engines/gpencil/gpencil_render.c
@@ -16,7 +16,7 @@
* Copyright 2017, Blender Foundation.
*/
- /** \file
+/** \file
* \ingroup draw
*/
#include "BLI_rect.h"
@@ -35,322 +35,345 @@
#include "gpencil_engine.h"
- /* Get pixel size for render
+/* Get pixel size for render
* This function uses the same calculation used for viewport, because if use
* camera pixelsize, the result is not correct.
*/
static float get_render_pixelsize(float persmat[4][4], int winx, int winy)
{
- float v1[3], v2[3];
- float len_px, len_sc;
+ float v1[3], v2[3];
+ float len_px, len_sc;
- v1[0] = persmat[0][0];
- v1[1] = persmat[1][0];
- v1[2] = persmat[2][0];
+ v1[0] = persmat[0][0];
+ v1[1] = persmat[1][0];
+ v1[2] = persmat[2][0];
- v2[0] = persmat[0][1];
- v2[1] = persmat[1][1];
- v2[2] = persmat[2][1];
+ v2[0] = persmat[0][1];
+ v2[1] = persmat[1][1];
+ v2[2] = persmat[2][1];
- len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
- len_sc = (float)MAX2(winx, winy);
+ len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
+ len_sc = (float)MAX2(winx, winy);
- return len_px / len_sc;
+ return len_px / len_sc;
}
/* init render data */
void GPENCIL_render_init(GPENCIL_Data *ved, RenderEngine *engine, struct Depsgraph *depsgraph)
{
- GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
- GPENCIL_StorageList *stl = vedata->stl;
- GPENCIL_FramebufferList *fbl = vedata->fbl;
-
- Scene *scene = DEG_get_evaluated_scene(depsgraph);
- const float *viewport_size = DRW_viewport_size_get();
- const int size[2] = { (int)viewport_size[0], (int)viewport_size[1] };
-
- /* In render mode the default framebuffer is not generated
- * because there is no viewport. So we need to manually create one
- * NOTE : use 32 bit format for precision in render mode.
- */
- /* create multiframe framebuffer for AA */
- if (U.gpencil_multisamples > 0) {
- int rect_w = (int)viewport_size[0];
- int rect_h = (int)viewport_size[1];
- DRW_gpencil_multisample_ensure(vedata, rect_w, rect_h);
- }
-
- vedata->render_depth_tx = DRW_texture_pool_query_2d(
- size[0], size[1], GPU_DEPTH_COMPONENT24,
- &draw_engine_gpencil_type);
- vedata->render_color_tx = DRW_texture_pool_query_2d(
- size[0], size[1], GPU_RGBA32F,
- &draw_engine_gpencil_type);
- GPU_framebuffer_ensure_config(
- &fbl->main, {
- GPU_ATTACHMENT_TEXTURE(vedata->render_depth_tx),
- GPU_ATTACHMENT_TEXTURE(vedata->render_color_tx)
- });
-
- /* Alloc transient data. */
- if (!stl->g_data) {
- stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
- }
-
- /* Set the pers & view matrix. */
- struct Object *camera = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
- float frame = BKE_scene_frame_get(scene);
- RE_GetCameraWindow(engine->re, camera, frame, stl->storage->winmat);
- RE_GetCameraModelMatrix(engine->re, camera, stl->storage->viewinv);
-
- invert_m4_m4(stl->storage->viewmat, stl->storage->viewinv);
- mul_m4_m4m4(stl->storage->persmat, stl->storage->winmat, stl->storage->viewmat);
- invert_m4_m4(stl->storage->persinv, stl->storage->persmat);
- invert_m4_m4(stl->storage->wininv, stl->storage->winmat);
-
- DRW_viewport_matrix_override_set(stl->storage->persmat, DRW_MAT_PERS);
- DRW_viewport_matrix_override_set(stl->storage->persinv, DRW_MAT_PERSINV);
- DRW_viewport_matrix_override_set(stl->storage->winmat, DRW_MAT_WIN);
- DRW_viewport_matrix_override_set(stl->storage->wininv, DRW_MAT_WININV);
- DRW_viewport_matrix_override_set(stl->storage->viewmat, DRW_MAT_VIEW);
- DRW_viewport_matrix_override_set(stl->storage->viewinv, DRW_MAT_VIEWINV);
-
- /* calculate pixel size for render */
- stl->storage->render_pixsize = get_render_pixelsize(stl->storage->persmat, viewport_size[0], viewport_size[1]);
- /* INIT CACHE */
- GPENCIL_cache_init(vedata);
+ GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
+ GPENCIL_StorageList *stl = vedata->stl;
+ GPENCIL_FramebufferList *fbl = vedata->fbl;
+
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ const float *viewport_size = DRW_viewport_size_get();
+ const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
+
+ /* In render mode the default framebuffer is not generated
+ * because there is no viewport. So we need to manually create one
+ * NOTE : use 32 bit format for precision in render mode.
+ */
+ /* create multiframe framebuffer for AA */
+ if (U.gpencil_multisamples > 0) {
+ int rect_w = (int)viewport_size[0];
+ int rect_h = (int)viewport_size[1];
+ DRW_gpencil_multisample_ensure(vedata, rect_w, rect_h);
+ }
+
+ vedata->render_depth_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_gpencil_type);
+ vedata->render_color_tx = DRW_texture_pool_query_2d(
+ size[0], size[1], GPU_RGBA32F, &draw_engine_gpencil_type);
+ GPU_framebuffer_ensure_config(&fbl->main,
+ {GPU_ATTACHMENT_TEXTURE(vedata->render_depth_tx),
+ GPU_ATTACHMENT_TEXTURE(vedata->render_color_tx)});
+
+ /* Alloc transient data. */
+ if (!stl->g_data) {
+ stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
+ }
+
+ /* Set the pers & view matrix. */
+ struct Object *camera = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
+ float frame = BKE_scene_frame_get(scene);
+ RE_GetCameraWindow(engine->re, camera, frame, stl->storage->winmat);
+ RE_GetCameraModelMatrix(engine->re, camera, stl->storage->viewinv);
+
+ invert_m4_m4(stl->storage->viewmat, stl->storage->viewinv);
+ mul_m4_m4m4(stl->storage->persmat, stl->storage->winmat, stl->storage->viewmat);
+ invert_m4_m4(stl->storage->persinv, stl->storage->persmat);
+ invert_m4_m4(stl->storage->wininv, stl->storage->winmat);
+
+ DRW_viewport_matrix_override_set(stl->storage->persmat, DRW_MAT_PERS);
+ DRW_viewport_matrix_override_set(stl->storage->persinv, DRW_MAT_PERSINV);
+ DRW_viewport_matrix_override_set(stl->storage->winmat, DRW_MAT_WIN);
+ DRW_viewport_matrix_override_set(stl->storage->wininv, DRW_MAT_WININV);
+ DRW_viewport_matrix_override_set(stl->storage->viewmat, DRW_MAT_VIEW);
+ DRW_viewport_matrix_override_set(stl->storage->viewinv, DRW_MAT_VIEWINV);
+
+ /* calculate pixel size for render */
+ stl->storage->render_pixsize = get_render_pixelsize(
+ stl->storage->persmat, viewport_size[0], viewport_size[1]);
+ /* INIT CACHE */
+ GPENCIL_cache_init(vedata);
}
/* render all objects and select only grease pencil */
-static void GPENCIL_render_cache(
- void *vedata, struct Object *ob,
- struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph))
+static void GPENCIL_render_cache(void *vedata,
+ struct Object *ob,
+ struct RenderEngine *UNUSED(engine),
+ struct Depsgraph *UNUSED(depsgraph))
{
- if (ob && ob->type == OB_GPENCIL) {
- if (DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF) {
- GPENCIL_cache_populate(vedata, ob);
- }
- }
+ if (ob && ob->type == OB_GPENCIL) {
+ if (DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF) {
+ GPENCIL_cache_populate(vedata, ob);
+ }
+ }
}
/* TODO: Reuse Eevee code in shared module instead to duplicate here */
-static void GPENCIL_render_update_viewvecs(float invproj[4][4], float winmat[4][4], float(*r_viewvecs)[4])
+static void GPENCIL_render_update_viewvecs(float invproj[4][4],
+ float winmat[4][4],
+ float (*r_viewvecs)[4])
{
- /* view vectors for the corners of the view frustum.
- * Can be used to recreate the world space position easily */
- float view_vecs[4][4] = {
- {-1.0f, -1.0f, -1.0f, 1.0f},
- {1.0f, -1.0f, -1.0f, 1.0f},
- {-1.0f, 1.0f, -1.0f, 1.0f},
- {-1.0f, -1.0f, 1.0f, 1.0f}
- };
-
- /* convert the view vectors to view space */
- const bool is_persp = (winmat[3][3] == 0.0f);
- for (int i = 0; i < 4; i++) {
- mul_project_m4_v3(invproj, view_vecs[i]);
- /* normalized trick see:
- * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
- if (is_persp) {
- /* Divide XY by Z. */
- mul_v2_fl(view_vecs[i], 1.0f / view_vecs[i][2]);
- }
- }
-
- /**
- * If ortho : view_vecs[0] is the near-bottom-left corner of the frustum and
- * view_vecs[1] is the vector going from the near-bottom-left corner to
- * the far-top-right corner.
- * If Persp : view_vecs[0].xy and view_vecs[1].xy are respectively the bottom-left corner
- * when Z = 1, and top-left corner if Z = 1.
- * view_vecs[0].z the near clip distance and view_vecs[1].z is the (signed)
- * distance from the near plane to the far clip plane.
- */
- copy_v4_v4(r_viewvecs[0], view_vecs[0]);
-
- /* we need to store the differences */
- r_viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0];
- r_viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
- r_viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2];
+ /* view vectors for the corners of the view frustum.
+ * Can be used to recreate the world space position easily */
+ float view_vecs[4][4] = {{-1.0f, -1.0f, -1.0f, 1.0f},
+ {1.0f, -1.0f, -1.0f, 1.0f},
+ {-1.0f, 1.0f, -1.0f, 1.0f},
+ {-1.0f, -1.0f, 1.0f, 1.0f}};
+
+ /* convert the view vectors to view space */
+ const bool is_persp = (winmat[3][3] == 0.0f);
+ for (int i = 0; i < 4; i++) {
+ mul_project_m4_v3(invproj, view_vecs[i]);
+ /* normalized trick see:
+ * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+ if (is_persp) {
+ /* Divide XY by Z. */
+ mul_v2_fl(view_vecs[i], 1.0f / view_vecs[i][2]);
+ }
+ }
+
+ /**
+ * If ortho : view_vecs[0] is the near-bottom-left corner of the frustum and
+ * view_vecs[1] is the vector going from the near-bottom-left corner to
+ * the far-top-right corner.
+ * If Persp : view_vecs[0].xy and view_vecs[1].xy are respectively the bottom-left corner
+ * when Z = 1, and top-left corner if Z = 1.
+ * view_vecs[0].z the near clip distance and view_vecs[1].z is the (signed)
+ * distance from the near plane to the far clip plane.
+ */
+ copy_v4_v4(r_viewvecs[0], view_vecs[0]);
+
+ /* we need to store the differences */
+ r_viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0];
+ r_viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
+ r_viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2];
}
/* Update view_vecs */
static void GPENCIL_render_update_vecs(GPENCIL_Data *vedata)
{
- GPENCIL_StorageList *stl = vedata->stl;
+ GPENCIL_StorageList *stl = vedata->stl;
- float invproj[4][4], winmat[4][4];
- DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
- DRW_viewport_matrix_get(invproj, DRW_MAT_WININV);
+ float invproj[4][4], winmat[4][4];
+ DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
+ DRW_viewport_matrix_get(invproj, DRW_MAT_WININV);
- /* this is separated to keep function equal to Eevee for future reuse of same code */
- GPENCIL_render_update_viewvecs(invproj, winmat, stl->storage->view_vecs);
+ /* this is separated to keep function equal to Eevee for future reuse of same code */
+ GPENCIL_render_update_viewvecs(invproj, winmat, stl->storage->view_vecs);
}
/* read z-depth render result */
-static void GPENCIL_render_result_z(struct RenderLayer *rl, const char *viewname, GPENCIL_Data *vedata, const rcti *rect)
+static void GPENCIL_render_result_z(struct RenderLayer *rl,
+ const char *viewname,
+ GPENCIL_Data *vedata,
+ const rcti *rect)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
- GPENCIL_StorageList *stl = vedata->stl;
-
- if ((view_layer->passflag & SCE_PASS_Z) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
-
- GPU_framebuffer_read_depth(vedata->fbl->main, rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), rp->rect);
-
- bool is_persp = DRW_viewport_is_persp_get();
-
- GPENCIL_render_update_vecs(vedata);
-
- /* Convert ogl depth [0..1] to view Z [near..far] */
- for (int i = 0; i < BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect); i++) {
- if (rp->rect[i] == 1.0f) {
- rp->rect[i] = 1e10f; /* Background */
- }
- else {
- if (is_persp) {
- rp->rect[i] = rp->rect[i] * 2.0f - 1.0f;
- rp->rect[i] = stl->storage->winmat[3][2] / (rp->rect[i] + stl->storage->winmat[2][2]);
- }
- else {
- rp->rect[i] = -stl->storage->view_vecs[0][2] + rp->rect[i] * -stl->storage->view_vecs[1][2];
- }
- }
- }
- }
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+ GPENCIL_StorageList *stl = vedata->stl;
+
+ if ((view_layer->passflag & SCE_PASS_Z) != 0) {
+ RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
+
+ GPU_framebuffer_read_depth(vedata->fbl->main,
+ rect->xmin,
+ rect->ymin,
+ BLI_rcti_size_x(rect),
+ BLI_rcti_size_y(rect),
+ rp->rect);
+
+ bool is_persp = DRW_viewport_is_persp_get();
+
+ GPENCIL_render_update_vecs(vedata);
+
+ /* Convert ogl depth [0..1] to view Z [near..far] */
+ for (int i = 0; i < BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect); i++) {
+ if (rp->rect[i] == 1.0f) {
+ rp->rect[i] = 1e10f; /* Background */
+ }
+ else {
+ if (is_persp) {
+ rp->rect[i] = rp->rect[i] * 2.0f - 1.0f;
+ rp->rect[i] = stl->storage->winmat[3][2] / (rp->rect[i] + stl->storage->winmat[2][2]);
+ }
+ else {
+ rp->rect[i] = -stl->storage->view_vecs[0][2] +
+ rp->rect[i] * -stl->storage->view_vecs[1][2];
+ }
+ }
+ }
+ }
}
/* read combined render result */
-static void GPENCIL_render_result_combined(struct RenderLayer *rl, const char *viewname, GPENCIL_Data *vedata, const rcti *rect)
+static void GPENCIL_render_result_combined(struct RenderLayer *rl,
+ const char *viewname,
+ GPENCIL_Data *vedata,
+ const rcti *rect)
{
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname);
- GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
-
- GPU_framebuffer_bind(fbl->main);
- GPU_framebuffer_read_color(vedata->fbl->main, rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), 4, 0, rp->rect);
+ RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname);
+ GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
+
+ GPU_framebuffer_bind(fbl->main);
+ GPU_framebuffer_read_color(vedata->fbl->main,
+ rect->xmin,
+ rect->ymin,
+ BLI_rcti_size_x(rect),
+ BLI_rcti_size_y(rect),
+ 4,
+ 0,
+ rp->rect);
}
/* helper to blend pixels */
static void blend_pixel(float top_color[4], float bottom_color[4], float dst_color[4])
{
- float alpha = top_color[3];
+ float alpha = top_color[3];
- /* use blend: GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA */
- dst_color[0] = (top_color[0] * alpha) + (bottom_color[0] * (1.0f - alpha));
- dst_color[1] = (top_color[1] * alpha) + (bottom_color[1] * (1.0f - alpha));
- dst_color[2] = (top_color[2] * alpha) + (bottom_color[2] * (1.0f - alpha));
+ /* use blend: GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA */
+ dst_color[0] = (top_color[0] * alpha) + (bottom_color[0] * (1.0f - alpha));
+ dst_color[1] = (top_color[1] * alpha) + (bottom_color[1] * (1.0f - alpha));
+ dst_color[2] = (top_color[2] * alpha) + (bottom_color[2] * (1.0f - alpha));
}
/* render grease pencil to image */
-void GPENCIL_render_to_image(void *vedata, RenderEngine *engine, struct RenderLayer *render_layer, const rcti *rect)
+void GPENCIL_render_to_image(void *vedata,
+ RenderEngine *engine,
+ struct RenderLayer *render_layer,
+ const rcti *rect)
{
- const char *viewname = RE_GetActiveRenderView(engine->re);
- const DRWContextState *draw_ctx = DRW_context_state_get();
- int imgsize = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
-
- /* save previous render data */
- RenderPass *rpass_color_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
- RenderPass *rpass_depth_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_Z, viewname);
- float *src_rect_color_data = NULL;
- float *src_rect_depth_data = NULL;
- if ((rpass_color_src) && (rpass_depth_src) && (rpass_color_src->rect) && (rpass_depth_src->rect)) {
- src_rect_color_data = MEM_dupallocN(rpass_color_src->rect);
- src_rect_depth_data = MEM_dupallocN(rpass_depth_src->rect);
- }
- else {
- /* TODO: put this message in a better place */
- printf("Warning: To render grease pencil, enable Combined and Z passes.\n");
- }
-
- GPENCIL_engine_init(vedata);
- GPENCIL_render_init(vedata, engine, draw_ctx->depsgraph);
-
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- Object *camera = DEG_get_evaluated_object(draw_ctx->depsgraph, RE_GetCamera(engine->re));
- stl->storage->camera = camera; /* save current camera */
-
- GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
- if (fbl->main) {
- GPU_framebuffer_texture_attach(fbl->main, ((GPENCIL_Data *)vedata)->render_depth_tx, 0, 0);
- GPU_framebuffer_texture_attach(fbl->main, ((GPENCIL_Data *)vedata)->render_color_tx, 0, 0);
- /* clean first time the buffer */
- float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
- GPU_framebuffer_bind(fbl->main);
- GPU_framebuffer_clear_color_depth(fbl->main, clearcol, 1.0f);
- }
-
- /* loop all objects and draw */
- DRW_render_object_iter(vedata, engine, draw_ctx->depsgraph, GPENCIL_render_cache);
-
- GPENCIL_cache_finish(vedata);
- GPENCIL_draw_scene(vedata);
-
- /* combined data */
- GPENCIL_render_result_combined(render_layer, viewname, vedata, rect);
- /* z-depth data */
- GPENCIL_render_result_z(render_layer, viewname, vedata, rect);
-
- /* detach textures */
- if (fbl->main) {
- GPU_framebuffer_texture_detach(fbl->main, ((GPENCIL_Data *)vedata)->render_depth_tx);
- GPU_framebuffer_texture_detach(fbl->main, ((GPENCIL_Data *)vedata)->render_color_tx);
- }
-
- /* merge previous render image with new GP image */
- if (src_rect_color_data) {
- RenderPass *rpass_color_gp = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
- RenderPass *rpass_depth_gp = RE_pass_find_by_name(render_layer, RE_PASSNAME_Z, viewname);
- float *gp_rect_color_data = rpass_color_gp->rect;
- float *gp_rect_depth_data = rpass_depth_gp->rect;
- float *gp_pixel_rgba;
- float *gp_pixel_depth;
- float *src_pixel_rgba;
- float *src_pixel_depth;
-
- for (int i = 0; i < imgsize; i++) {
- gp_pixel_rgba = &gp_rect_color_data[i * 4];
- gp_pixel_depth = &gp_rect_depth_data[i];
-
- src_pixel_rgba = &src_rect_color_data[i * 4];
- src_pixel_depth = &src_rect_depth_data[i];
-
- /* check grease pencil render transparency */
- if (gp_pixel_rgba[3] > 0.0f) {
- if (src_pixel_rgba[3] > 0.0f) {
- /* check z-depth */
- if (gp_pixel_depth[0] > src_pixel_depth[0]) {
- /* copy source z-depth */
- gp_pixel_depth[0] = src_pixel_depth[0];
- /* blend object on top */
- if (src_pixel_rgba[3] < 1.0f) {
- blend_pixel(src_pixel_rgba, gp_pixel_rgba, gp_pixel_rgba);
- }
- else {
- copy_v4_v4(gp_pixel_rgba, src_pixel_rgba);
- }
- }
- else {
- /* blend gp render */
- if (gp_pixel_rgba[3] < 1.0f) {
- /* premult alpha factor to remove double blend effects */
- mul_v3_fl(gp_pixel_rgba, 1.0f / gp_pixel_rgba[3]);
-
- blend_pixel(gp_pixel_rgba, src_pixel_rgba, gp_pixel_rgba);
-
- gp_pixel_rgba[3] = gp_pixel_rgba[3] > src_pixel_rgba[3] ? gp_pixel_rgba[3] : src_pixel_rgba[3];
- }
- }
- }
- }
- else {
- copy_v4_v4(gp_pixel_rgba, src_pixel_rgba);
- gp_pixel_depth[0] = src_pixel_depth[0];
- }
- }
-
- /* free memory */
- MEM_SAFE_FREE(src_rect_color_data);
- MEM_SAFE_FREE(src_rect_depth_data);
- }
+ const char *viewname = RE_GetActiveRenderView(engine->re);
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ int imgsize = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
+
+ /* save previous render data */
+ RenderPass *rpass_color_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
+ RenderPass *rpass_depth_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_Z, viewname);
+ float *src_rect_color_data = NULL;
+ float *src_rect_depth_data = NULL;
+ if ((rpass_color_src) && (rpass_depth_src) && (rpass_color_src->rect) &&
+ (rpass_depth_src->rect)) {
+ src_rect_color_data = MEM_dupallocN(rpass_color_src->rect);
+ src_rect_depth_data = MEM_dupallocN(rpass_depth_src->rect);
+ }
+ else {
+ /* TODO: put this message in a better place */
+ printf("Warning: To render grease pencil, enable Combined and Z passes.\n");
+ }
+
+ GPENCIL_engine_init(vedata);
+ GPENCIL_render_init(vedata, engine, draw_ctx->depsgraph);
+
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ Object *camera = DEG_get_evaluated_object(draw_ctx->depsgraph, RE_GetCamera(engine->re));
+ stl->storage->camera = camera; /* save current camera */
+
+ GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
+ if (fbl->main) {
+ GPU_framebuffer_texture_attach(fbl->main, ((GPENCIL_Data *)vedata)->render_depth_tx, 0, 0);
+ GPU_framebuffer_texture_attach(fbl->main, ((GPENCIL_Data *)vedata)->render_color_tx, 0, 0);
+ /* clean first time the buffer */
+ float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ GPU_framebuffer_bind(fbl->main);
+ GPU_framebuffer_clear_color_depth(fbl->main, clearcol, 1.0f);
+ }
+
+ /* loop all objects and draw */
+ DRW_render_object_iter(vedata, engine, draw_ctx->depsgraph, GPENCIL_render_cache);
+
+ GPENCIL_cache_finish(vedata);
+ GPENCIL_draw_scene(vedata);
+
+ /* combined data */
+ GPENCIL_render_result_combined(render_layer, viewname, vedata, rect);
+ /* z-depth data */
+ GPENCIL_render_result_z(render_layer, viewname, vedata, rect);
+
+ /* detach textures */
+ if (fbl->main) {
+ GPU_framebuffer_texture_detach(fbl->main, ((GPENCIL_Data *)vedata)->render_depth_tx);
+ GPU_framebuffer_texture_detach(fbl->main, ((GPENCIL_Data *)vedata)->render_color_tx);
+ }
+
+ /* merge previous render image with new GP image */
+ if (src_rect_color_data) {
+ RenderPass *rpass_color_gp = RE_pass_find_by_name(
+ render_layer, RE_PASSNAME_COMBINED, viewname);
+ RenderPass *rpass_depth_gp = RE_pass_find_by_name(render_layer, RE_PASSNAME_Z, viewname);
+ float *gp_rect_color_data = rpass_color_gp->rect;
+ float *gp_rect_depth_data = rpass_depth_gp->rect;
+ float *gp_pixel_rgba;
+ float *gp_pixel_depth;
+ float *src_pixel_rgba;
+ float *src_pixel_depth;
+
+ for (int i = 0; i < imgsize; i++) {
+ gp_pixel_rgba = &gp_rect_color_data[i * 4];
+ gp_pixel_depth = &gp_rect_depth_data[i];
+
+ src_pixel_rgba = &src_rect_color_data[i * 4];
+ src_pixel_depth = &src_rect_depth_data[i];
+
+ /* check grease pencil render transparency */
+ if (gp_pixel_rgba[3] > 0.0f) {
+ if (src_pixel_rgba[3] > 0.0f) {
+ /* check z-depth */
+ if (gp_pixel_depth[0] > src_pixel_depth[0]) {
+ /* copy source z-depth */
+ gp_pixel_depth[0] = src_pixel_depth[0];
+ /* blend object on top */
+ if (src_pixel_rgba[3] < 1.0f) {
+ blend_pixel(src_pixel_rgba, gp_pixel_rgba, gp_pixel_rgba);
+ }
+ else {
+ copy_v4_v4(gp_pixel_rgba, src_pixel_rgba);
+ }
+ }
+ else {
+ /* blend gp render */
+ if (gp_pixel_rgba[3] < 1.0f) {
+ /* premult alpha factor to remove double blend effects */
+ mul_v3_fl(gp_pixel_rgba, 1.0f / gp_pixel_rgba[3]);
+
+ blend_pixel(gp_pixel_rgba, src_pixel_rgba, gp_pixel_rgba);
+
+ gp_pixel_rgba[3] = gp_pixel_rgba[3] > src_pixel_rgba[3] ? gp_pixel_rgba[3] :
+ src_pixel_rgba[3];
+ }
+ }
+ }
+ }
+ else {
+ copy_v4_v4(gp_pixel_rgba, src_pixel_rgba);
+ gp_pixel_depth[0] = src_pixel_depth[0];
+ }
+ }
+
+ /* free memory */
+ MEM_SAFE_FREE(src_rect_color_data);
+ MEM_SAFE_FREE(src_rect_depth_data);
+ }
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index a2632c47e7e..b133d9310b0 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -49,28 +49,25 @@ extern char datatoc_gpencil_fx_wave_frag_glsl[];
/* verify if this fx is active */
static bool effect_is_active(bGPdata *gpd, ShaderFxData *fx, bool is_render)
{
- if (fx == NULL) {
- return false;
- }
-
- if (gpd == NULL) {
- return false;
- }
-
- bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd);
- if (((fx->mode & eShaderFxMode_Editmode) == 0) &&
- (is_edit) && (!is_render))
- {
- return false;
- }
-
- if (((fx->mode & eShaderFxMode_Realtime) && (is_render == false)) ||
- ((fx->mode & eShaderFxMode_Render) && (is_render == true)))
- {
- return true;
- }
-
- return false;
+ if (fx == NULL) {
+ return false;
+ }
+
+ if (gpd == NULL) {
+ return false;
+ }
+
+ bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd);
+ if (((fx->mode & eShaderFxMode_Editmode) == 0) && (is_edit) && (!is_render)) {
+ return false;
+ }
+
+ if (((fx->mode & eShaderFxMode_Realtime) && (is_render == false)) ||
+ ((fx->mode & eShaderFxMode_Render) && (is_render == true))) {
+ return true;
+ }
+
+ return false;
}
/**
@@ -81,60 +78,60 @@ static bool effect_is_active(bGPdata *gpd, ShaderFxData *fx, bool is_render)
*/
static bool get_normal_vector(bGPdata *gpd, float r_point[3], float r_normal[3])
{
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- if (gpl->flag & GP_LAYER_HIDE) {
- continue;
- }
-
- /* get frame */
- bGPDframe *gpf = gpl->actframe;
- if (gpf == NULL) {
- continue;
- }
- for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
- if (gps->totpoints >= 3) {
- bGPDspoint *pt = &gps->points[0];
- BKE_gpencil_stroke_normal(gps, r_normal);
- /* in some weird situations, the normal cannot be calculated, so try next stroke */
- if ((r_normal[0] != 0.0f) || (r_normal[1] != 0.0f) || (r_normal[2] != 0.0f)) {
- copy_v3_v3(r_point, &pt->x);
- return true;
- }
- }
- }
- }
-
- return false;
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ if (gpl->flag & GP_LAYER_HIDE) {
+ continue;
+ }
+
+ /* get frame */
+ bGPDframe *gpf = gpl->actframe;
+ if (gpf == NULL) {
+ continue;
+ }
+ for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+ if (gps->totpoints >= 3) {
+ bGPDspoint *pt = &gps->points[0];
+ BKE_gpencil_stroke_normal(gps, r_normal);
+ /* in some weird situations, the normal cannot be calculated, so try next stroke */
+ if ((r_normal[0] != 0.0f) || (r_normal[1] != 0.0f) || (r_normal[2] != 0.0f)) {
+ copy_v3_v3(r_point, &pt->x);
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
}
/* helper to get near and far depth of field values */
static void GPENCIL_dof_nearfar(Object *camera, float coc, float nearfar[2])
{
- if (camera == NULL) {
- return;
- }
-
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- Camera *cam = (Camera *)camera->data;
-
- float fstop = cam->gpu_dof.fstop;
- float focus_dist = BKE_camera_object_dof_distance(camera);
- float focal_len = cam->lens;
-
- /* this is factor that converts to the scene scale. focal length and sensor are expressed in mm
- * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though
- * because the shader reads coordinates in world space, which is in blender units.
- * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */
- float scale = (scene->unit.system) ? scene->unit.scale_length : 1.0f;
- float scale_camera = 0.001f / scale;
- /* we want radius here for the aperture number */
- float aperture_scaled = 0.5f * scale_camera * focal_len / fstop;
- float focal_len_scaled = scale_camera * focal_len;
-
- float hyperfocal = (focal_len_scaled * focal_len_scaled) / (aperture_scaled * coc);
- nearfar[0] = (hyperfocal * focus_dist) / (hyperfocal + focal_len);
- nearfar[1] = (hyperfocal * focus_dist) / (hyperfocal - focal_len);
+ if (camera == NULL) {
+ return;
+ }
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ Camera *cam = (Camera *)camera->data;
+
+ float fstop = cam->gpu_dof.fstop;
+ float focus_dist = BKE_camera_object_dof_distance(camera);
+ float focal_len = cam->lens;
+
+ /* this is factor that converts to the scene scale. focal length and sensor are expressed in mm
+ * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though
+ * because the shader reads coordinates in world space, which is in blender units.
+ * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */
+ float scale = (scene->unit.system) ? scene->unit.scale_length : 1.0f;
+ float scale_camera = 0.001f / scale;
+ /* we want radius here for the aperture number */
+ float aperture_scaled = 0.5f * scale_camera * focal_len / fstop;
+ float focal_len_scaled = scale_camera * focal_len;
+
+ float hyperfocal = (focal_len_scaled * focal_len_scaled) / (aperture_scaled * coc);
+ nearfar[0] = (hyperfocal * focus_dist) / (hyperfocal + focal_len);
+ nearfar[1] = (hyperfocal * focus_dist) / (hyperfocal - focal_len);
}
/* **************** Shader Effects ***************************** */
@@ -143,514 +140,499 @@ static void GPENCIL_dof_nearfar(Object *camera, float coc, float nearfar[2])
* The effect is done using two shading groups because is faster to apply horizontal
* and vertical in different operations.
*/
-static void DRW_gpencil_fx_blur(
- ShaderFxData *fx, int ob_idx, GPENCIL_e_data *e_data,
- GPENCIL_Data *vedata, tGPencilObjectCache *cache)
+static void DRW_gpencil_fx_blur(ShaderFxData *fx,
+ int ob_idx,
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ tGPencilObjectCache *cache)
{
- if (fx == NULL) {
- return;
- }
-
- BlurShaderFxData *fxd = (BlurShaderFxData *)fx;
-
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- View3D *v3d = draw_ctx->v3d;
- RegionView3D *rv3d = draw_ctx->rv3d;
- DRWShadingGroup *fx_shgrp;
- bGPdata *gpd = cache->gpd;
- copy_v3_v3(fxd->runtime.loc, cache->loc);
-
- fxd->blur[0] = fxd->radius[0];
- fxd->blur[1] = fxd->radius[1];
-
- /* init weight */
- if (fxd->flag & FX_BLUR_DOF_MODE) {
- /* viewport and opengl render */
- Object *camera = NULL;
- if (rv3d) {
- if (rv3d->persp == RV3D_CAMOB) {
- camera = v3d->camera;
- }
- }
- else {
- camera = stl->storage->camera;
- }
-
- if (camera) {
- float nearfar[2];
- GPENCIL_dof_nearfar(camera, fxd->coc, nearfar);
- float zdepth = stl->g_data->gp_object_cache[ob_idx].zdepth;
- /* the object is on focus area */
- if ((zdepth >= nearfar[0]) && (zdepth <= nearfar[1])) {
- fxd->blur[0] = 0;
- fxd->blur[1] = 0;
- }
- else {
- float f;
- if (zdepth < nearfar[0]) {
- f = nearfar[0] - zdepth;
- }
- else {
- f = zdepth - nearfar[1];
- }
- fxd->blur[0] = f;
- fxd->blur[1] = f;
- CLAMP2(&fxd->blur[0], 0, fxd->radius[0]);
- }
- }
- else {
- /* if not camera view, the blur is disabled */
- fxd->blur[0] = 0;
- fxd->blur[1] = 0;
- }
- }
-
- GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
-
- fx_shgrp = DRW_shgroup_create(
- e_data->gpencil_fx_blur_sh,
- psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
- DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
-
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
-
- fxd->runtime.fx_sh = fx_shgrp;
+ if (fx == NULL) {
+ return;
+ }
+
+ BlurShaderFxData *fxd = (BlurShaderFxData *)fx;
+
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ DRWShadingGroup *fx_shgrp;
+ bGPdata *gpd = cache->gpd;
+ copy_v3_v3(fxd->runtime.loc, cache->loc);
+
+ fxd->blur[0] = fxd->radius[0];
+ fxd->blur[1] = fxd->radius[1];
+
+ /* init weight */
+ if (fxd->flag & FX_BLUR_DOF_MODE) {
+ /* viewport and opengl render */
+ Object *camera = NULL;
+ if (rv3d) {
+ if (rv3d->persp == RV3D_CAMOB) {
+ camera = v3d->camera;
+ }
+ }
+ else {
+ camera = stl->storage->camera;
+ }
+
+ if (camera) {
+ float nearfar[2];
+ GPENCIL_dof_nearfar(camera, fxd->coc, nearfar);
+ float zdepth = stl->g_data->gp_object_cache[ob_idx].zdepth;
+ /* the object is on focus area */
+ if ((zdepth >= nearfar[0]) && (zdepth <= nearfar[1])) {
+ fxd->blur[0] = 0;
+ fxd->blur[1] = 0;
+ }
+ else {
+ float f;
+ if (zdepth < nearfar[0]) {
+ f = nearfar[0] - zdepth;
+ }
+ else {
+ f = zdepth - nearfar[1];
+ }
+ fxd->blur[0] = f;
+ fxd->blur[1] = f;
+ CLAMP2(&fxd->blur[0], 0, fxd->radius[0]);
+ }
+ }
+ else {
+ /* if not camera view, the blur is disabled */
+ fxd->blur[0] = 0;
+ fxd->blur[1] = 0;
+ }
+ }
+
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_blur_sh, psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+ DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
+ DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
+
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+
+ fxd->runtime.fx_sh = fx_shgrp;
}
/* Colorize FX */
-static void DRW_gpencil_fx_colorize(
- ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata)
+static void DRW_gpencil_fx_colorize(ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata)
{
- if (fx == NULL) {
- return;
- }
- ColorizeShaderFxData *fxd = (ColorizeShaderFxData *)fx;
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- DRWShadingGroup *fx_shgrp;
-
- GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
- fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_colorize_sh, psl->fx_shader_pass);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
- DRW_shgroup_uniform_vec4(fx_shgrp, "low_color", &fxd->low_color[0], 1);
- DRW_shgroup_uniform_vec4(fx_shgrp, "high_color", &fxd->high_color[0], 1);
- DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "factor", &fxd->factor, 1);
-
- fxd->runtime.fx_sh = fx_shgrp;
+ if (fx == NULL) {
+ return;
+ }
+ ColorizeShaderFxData *fxd = (ColorizeShaderFxData *)fx;
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ DRWShadingGroup *fx_shgrp;
+
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_colorize_sh, psl->fx_shader_pass);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+ DRW_shgroup_uniform_vec4(fx_shgrp, "low_color", &fxd->low_color[0], 1);
+ DRW_shgroup_uniform_vec4(fx_shgrp, "high_color", &fxd->high_color[0], 1);
+ DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "factor", &fxd->factor, 1);
+
+ fxd->runtime.fx_sh = fx_shgrp;
}
/* Flip FX */
-static void DRW_gpencil_fx_flip(
- ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata)
+static void DRW_gpencil_fx_flip(ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata)
{
- if (fx == NULL) {
- return;
- }
- FlipShaderFxData *fxd = (FlipShaderFxData *)fx;
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- DRWShadingGroup *fx_shgrp;
-
- fxd->flipmode = 100;
- /* the number works as bit flag */
- if (fxd->flag & FX_FLIP_HORIZONTAL) {
- fxd->flipmode += 10;
- }
- if (fxd->flag & FX_FLIP_VERTICAL) {
- fxd->flipmode += 1;
- }
-
- GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
- fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_flip_sh, psl->fx_shader_pass);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
- DRW_shgroup_uniform_int(fx_shgrp, "flipmode", &fxd->flipmode, 1);
-
- DRW_shgroup_uniform_vec2(fx_shgrp, "wsize", DRW_viewport_size_get(), 1);
-
- fxd->runtime.fx_sh = fx_shgrp;
+ if (fx == NULL) {
+ return;
+ }
+ FlipShaderFxData *fxd = (FlipShaderFxData *)fx;
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ DRWShadingGroup *fx_shgrp;
+
+ fxd->flipmode = 100;
+ /* the number works as bit flag */
+ if (fxd->flag & FX_FLIP_HORIZONTAL) {
+ fxd->flipmode += 10;
+ }
+ if (fxd->flag & FX_FLIP_VERTICAL) {
+ fxd->flipmode += 1;
+ }
+
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_flip_sh, psl->fx_shader_pass);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+ DRW_shgroup_uniform_int(fx_shgrp, "flipmode", &fxd->flipmode, 1);
+
+ DRW_shgroup_uniform_vec2(fx_shgrp, "wsize", DRW_viewport_size_get(), 1);
+
+ fxd->runtime.fx_sh = fx_shgrp;
}
/* Light FX */
-static void DRW_gpencil_fx_light(
- ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
- tGPencilObjectCache *cache)
+static void DRW_gpencil_fx_light(ShaderFxData *fx,
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ tGPencilObjectCache *cache)
{
- if (fx == NULL) {
- return;
- }
- LightShaderFxData *fxd = (LightShaderFxData *)fx;
-
- if (fxd->object == NULL) {
- return;
- }
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- DRWShadingGroup *fx_shgrp;
-
- GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
- fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_light_sh, psl->fx_shader_pass);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
-
- DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
-
- /* location of the light using obj location as origin */
- copy_v3_v3(fxd->loc, fxd->object->obmat[3]);
-
- /* Calc distance to strokes plane
- * The w component of location is used to transfer the distance to drawing plane
- */
- float r_point[3], r_normal[3];
- float r_plane[4];
- bGPdata *gpd = cache->gpd;
- if (!get_normal_vector(gpd, r_point, r_normal)) {
- return;
- }
- mul_mat3_m4_v3(cache->obmat, r_normal); /* only rotation component */
- plane_from_point_normal_v3(r_plane, r_point, r_normal);
- float dt = dist_to_plane_v3(fxd->object->obmat[3], r_plane);
- fxd->loc[3] = dt; /* use last element to save it */
-
- DRW_shgroup_uniform_vec4(fx_shgrp, "loc", &fxd->loc[0], 1);
-
- DRW_shgroup_uniform_float(fx_shgrp, "energy", &fxd->energy, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "ambient", &fxd->ambient, 1);
-
- DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
-
- fxd->runtime.fx_sh = fx_shgrp;
+ if (fx == NULL) {
+ return;
+ }
+ LightShaderFxData *fxd = (LightShaderFxData *)fx;
+
+ if (fxd->object == NULL) {
+ return;
+ }
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ DRWShadingGroup *fx_shgrp;
+
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_light_sh, psl->fx_shader_pass);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+
+ DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
+
+ /* location of the light using obj location as origin */
+ copy_v3_v3(fxd->loc, fxd->object->obmat[3]);
+
+ /* Calc distance to strokes plane
+ * The w component of location is used to transfer the distance to drawing plane
+ */
+ float r_point[3], r_normal[3];
+ float r_plane[4];
+ bGPdata *gpd = cache->gpd;
+ if (!get_normal_vector(gpd, r_point, r_normal)) {
+ return;
+ }
+ mul_mat3_m4_v3(cache->obmat, r_normal); /* only rotation component */
+ plane_from_point_normal_v3(r_plane, r_point, r_normal);
+ float dt = dist_to_plane_v3(fxd->object->obmat[3], r_plane);
+ fxd->loc[3] = dt; /* use last element to save it */
+
+ DRW_shgroup_uniform_vec4(fx_shgrp, "loc", &fxd->loc[0], 1);
+
+ DRW_shgroup_uniform_float(fx_shgrp, "energy", &fxd->energy, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "ambient", &fxd->ambient, 1);
+
+ DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+
+ fxd->runtime.fx_sh = fx_shgrp;
}
/* Pixelate FX */
-static void DRW_gpencil_fx_pixel(
- ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
- tGPencilObjectCache *cache)
+static void DRW_gpencil_fx_pixel(ShaderFxData *fx,
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ tGPencilObjectCache *cache)
{
- if (fx == NULL) {
- return;
- }
- PixelShaderFxData *fxd = (PixelShaderFxData *)fx;
-
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- DRWShadingGroup *fx_shgrp;
- bGPdata *gpd = cache->gpd;
- copy_v3_v3(fxd->runtime.loc, cache->loc);
-
- fxd->size[2] = (int)fxd->flag & FX_PIXEL_USE_LINES;
-
- GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
- fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_pixel_sh, psl->fx_shader_pass);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
- DRW_shgroup_uniform_int(fx_shgrp, "size", &fxd->size[0], 3);
- DRW_shgroup_uniform_vec4(fx_shgrp, "color", &fxd->rgba[0], 1);
-
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
-
- fxd->runtime.fx_sh = fx_shgrp;
+ if (fx == NULL) {
+ return;
+ }
+ PixelShaderFxData *fxd = (PixelShaderFxData *)fx;
+
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ DRWShadingGroup *fx_shgrp;
+ bGPdata *gpd = cache->gpd;
+ copy_v3_v3(fxd->runtime.loc, cache->loc);
+
+ fxd->size[2] = (int)fxd->flag & FX_PIXEL_USE_LINES;
+
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_pixel_sh, psl->fx_shader_pass);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+ DRW_shgroup_uniform_int(fx_shgrp, "size", &fxd->size[0], 3);
+ DRW_shgroup_uniform_vec4(fx_shgrp, "color", &fxd->rgba[0], 1);
+
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+
+ fxd->runtime.fx_sh = fx_shgrp;
}
/* Rim FX */
-static void DRW_gpencil_fx_rim(
- ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
- tGPencilObjectCache *cache)
+static void DRW_gpencil_fx_rim(ShaderFxData *fx,
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ tGPencilObjectCache *cache)
{
- if (fx == NULL) {
- return;
- }
- RimShaderFxData *fxd = (RimShaderFxData *)fx;
- bGPdata *gpd = cache->gpd;
-
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- DRWShadingGroup *fx_shgrp;
-
- GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
- copy_v3_v3(fxd->runtime.loc, cache->loc);
-
- /* prepare pass */
- fx_shgrp = DRW_shgroup_create(
- e_data->gpencil_fx_rim_prepare_sh,
- psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
- DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
-
- DRW_shgroup_uniform_int(fx_shgrp, "offset", &fxd->offset[0], 2);
- DRW_shgroup_uniform_vec3(fx_shgrp, "rim_color", &fxd->rim_rgb[0], 1);
- DRW_shgroup_uniform_vec3(fx_shgrp, "mask_color", &fxd->mask_rgb[0], 1);
-
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
-
- fxd->runtime.fx_sh = fx_shgrp;
-
- /* blur pass */
- fx_shgrp = DRW_shgroup_create(
- e_data->gpencil_fx_blur_sh,
- psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
- DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
-
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
-
- fxd->runtime.fx_sh_b = fx_shgrp;
-
- /* resolve pass */
- fx_shgrp = DRW_shgroup_create(
- e_data->gpencil_fx_rim_resolve_sh,
- psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeRim", &e_data->temp_color_tx_fx);
- DRW_shgroup_uniform_vec3(fx_shgrp, "mask_color", &fxd->mask_rgb[0], 1);
- DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1);
-
- fxd->runtime.fx_sh_c = fx_shgrp;
+ if (fx == NULL) {
+ return;
+ }
+ RimShaderFxData *fxd = (RimShaderFxData *)fx;
+ bGPdata *gpd = cache->gpd;
+
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ DRWShadingGroup *fx_shgrp;
+
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ copy_v3_v3(fxd->runtime.loc, cache->loc);
+
+ /* prepare pass */
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_rim_prepare_sh, psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+ DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
+
+ DRW_shgroup_uniform_int(fx_shgrp, "offset", &fxd->offset[0], 2);
+ DRW_shgroup_uniform_vec3(fx_shgrp, "rim_color", &fxd->rim_rgb[0], 1);
+ DRW_shgroup_uniform_vec3(fx_shgrp, "mask_color", &fxd->mask_rgb[0], 1);
+
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+
+ fxd->runtime.fx_sh = fx_shgrp;
+
+ /* blur pass */
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_blur_sh, psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
+ DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
+ DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
+
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+
+ fxd->runtime.fx_sh_b = fx_shgrp;
+
+ /* resolve pass */
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_rim_resolve_sh, psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeRim", &e_data->temp_color_tx_fx);
+ DRW_shgroup_uniform_vec3(fx_shgrp, "mask_color", &fxd->mask_rgb[0], 1);
+ DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1);
+
+ fxd->runtime.fx_sh_c = fx_shgrp;
}
/* Shadow FX */
-static void DRW_gpencil_fx_shadow(
- ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
- tGPencilObjectCache *cache)
+static void DRW_gpencil_fx_shadow(ShaderFxData *fx,
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ tGPencilObjectCache *cache)
{
- if (fx == NULL) {
- return;
- }
- ShadowShaderFxData *fxd = (ShadowShaderFxData *)fx;
- if ((!fxd->object) && (fxd->flag & FX_SHADOW_USE_OBJECT)) {
- fxd->runtime.fx_sh = NULL;
- fxd->runtime.fx_sh_b = NULL;
- fxd->runtime.fx_sh_c = NULL;
- return;
- }
-
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- DRWShadingGroup *fx_shgrp;
- bGPdata *gpd = cache->gpd;
- copy_v3_v3(fxd->runtime.loc, cache->loc);
-
- GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
- /* prepare pass */
- fx_shgrp = DRW_shgroup_create(
- e_data->gpencil_fx_shadow_prepare_sh,
- psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
- DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
-
- DRW_shgroup_uniform_int(fx_shgrp, "offset", &fxd->offset[0], 2);
- DRW_shgroup_uniform_float(fx_shgrp, "scale", &fxd->scale[0], 2);
- DRW_shgroup_uniform_float(fx_shgrp, "rotation", &fxd->rotation, 1);
- DRW_shgroup_uniform_vec4(fx_shgrp, "shadow_color", &fxd->shadow_rgba[0], 1);
-
- if ((fxd->object) && (fxd->flag & FX_SHADOW_USE_OBJECT)) {
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->object->obmat[3], 1);
- }
- else {
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
- }
-
- const int nowave = -1;
- if (fxd->flag & FX_SHADOW_USE_WAVE) {
- DRW_shgroup_uniform_int(fx_shgrp, "orientation", &fxd->orientation, 1);
- }
- else {
- DRW_shgroup_uniform_int(fx_shgrp, "orientation", &nowave, 1);
- }
- DRW_shgroup_uniform_float(fx_shgrp, "amplitude", &fxd->amplitude, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "period", &fxd->period, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "phase", &fxd->phase, 1);
-
- DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
-
- fxd->runtime.fx_sh = fx_shgrp;
-
- /* blur pass */
- fx_shgrp = DRW_shgroup_create(
- e_data->gpencil_fx_blur_sh,
- psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
- DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
-
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
-
- fxd->runtime.fx_sh_b = fx_shgrp;
-
- /* resolve pass */
- fx_shgrp = DRW_shgroup_create(
- e_data->gpencil_fx_shadow_resolve_sh,
- psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "shadowColor", &e_data->temp_color_tx_fx);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "shadowDepth", &e_data->temp_depth_tx_fx);
-
- fxd->runtime.fx_sh_c = fx_shgrp;
+ if (fx == NULL) {
+ return;
+ }
+ ShadowShaderFxData *fxd = (ShadowShaderFxData *)fx;
+ if ((!fxd->object) && (fxd->flag & FX_SHADOW_USE_OBJECT)) {
+ fxd->runtime.fx_sh = NULL;
+ fxd->runtime.fx_sh_b = NULL;
+ fxd->runtime.fx_sh_c = NULL;
+ return;
+ }
+
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ DRWShadingGroup *fx_shgrp;
+ bGPdata *gpd = cache->gpd;
+ copy_v3_v3(fxd->runtime.loc, cache->loc);
+
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ /* prepare pass */
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_shadow_prepare_sh, psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+ DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
+
+ DRW_shgroup_uniform_int(fx_shgrp, "offset", &fxd->offset[0], 2);
+ DRW_shgroup_uniform_float(fx_shgrp, "scale", &fxd->scale[0], 2);
+ DRW_shgroup_uniform_float(fx_shgrp, "rotation", &fxd->rotation, 1);
+ DRW_shgroup_uniform_vec4(fx_shgrp, "shadow_color", &fxd->shadow_rgba[0], 1);
+
+ if ((fxd->object) && (fxd->flag & FX_SHADOW_USE_OBJECT)) {
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->object->obmat[3], 1);
+ }
+ else {
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
+ }
+
+ const int nowave = -1;
+ if (fxd->flag & FX_SHADOW_USE_WAVE) {
+ DRW_shgroup_uniform_int(fx_shgrp, "orientation", &fxd->orientation, 1);
+ }
+ else {
+ DRW_shgroup_uniform_int(fx_shgrp, "orientation", &nowave, 1);
+ }
+ DRW_shgroup_uniform_float(fx_shgrp, "amplitude", &fxd->amplitude, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "period", &fxd->period, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "phase", &fxd->phase, 1);
+
+ DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+
+ fxd->runtime.fx_sh = fx_shgrp;
+
+ /* blur pass */
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_blur_sh, psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
+ DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
+ DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
+
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+
+ fxd->runtime.fx_sh_b = fx_shgrp;
+
+ /* resolve pass */
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_shadow_resolve_sh, psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "shadowColor", &e_data->temp_color_tx_fx);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "shadowDepth", &e_data->temp_depth_tx_fx);
+
+ fxd->runtime.fx_sh_c = fx_shgrp;
}
/* Glow FX */
-static void DRW_gpencil_fx_glow(
- ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
- tGPencilObjectCache *cache)
+static void DRW_gpencil_fx_glow(ShaderFxData *fx,
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ tGPencilObjectCache *cache)
{
- if (fx == NULL) {
- return;
- }
- GlowShaderFxData *fxd = (GlowShaderFxData *)fx;
- bGPdata *gpd = cache->gpd;
- copy_v3_v3(fxd->runtime.loc, cache->loc);
-
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- DRWShadingGroup *fx_shgrp;
-
- GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
- /* prepare pass */
- fx_shgrp = DRW_shgroup_create(
- e_data->gpencil_fx_glow_prepare_sh,
- psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
-
- DRW_shgroup_uniform_vec3(fx_shgrp, "glow_color", &fxd->glow_color[0], 1);
- DRW_shgroup_uniform_vec3(fx_shgrp, "select_color", &fxd->select_color[0], 1);
- DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "threshold", &fxd->threshold, 1);
-
- fxd->runtime.fx_sh = fx_shgrp;
-
- /* blur pass */
- fx_shgrp = DRW_shgroup_create(
- e_data->gpencil_fx_blur_sh,
- psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
- DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
-
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
-
- fxd->runtime.fx_sh_b = fx_shgrp;
-
- /* resolve pass */
- fx_shgrp = DRW_shgroup_create(
- e_data->gpencil_fx_glow_resolve_sh,
- psl->fx_shader_pass_blend);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "glowColor", &e_data->temp_color_tx_fx);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "glowDepth", &e_data->temp_depth_tx_fx);
-
- /* reuse field */
- DRW_shgroup_uniform_int(fx_shgrp, "alpha_mode", &fxd->blur[1], 1);
-
- fxd->runtime.fx_sh_c = fx_shgrp;
+ if (fx == NULL) {
+ return;
+ }
+ GlowShaderFxData *fxd = (GlowShaderFxData *)fx;
+ bGPdata *gpd = cache->gpd;
+ copy_v3_v3(fxd->runtime.loc, cache->loc);
+
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ DRWShadingGroup *fx_shgrp;
+
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ /* prepare pass */
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_glow_prepare_sh, psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+
+ DRW_shgroup_uniform_vec3(fx_shgrp, "glow_color", &fxd->glow_color[0], 1);
+ DRW_shgroup_uniform_vec3(fx_shgrp, "select_color", &fxd->select_color[0], 1);
+ DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "threshold", &fxd->threshold, 1);
+
+ fxd->runtime.fx_sh = fx_shgrp;
+
+ /* blur pass */
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_blur_sh, psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
+ DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
+ DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
+
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+
+ fxd->runtime.fx_sh_b = fx_shgrp;
+
+ /* resolve pass */
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_glow_resolve_sh, psl->fx_shader_pass_blend);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "glowColor", &e_data->temp_color_tx_fx);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "glowDepth", &e_data->temp_depth_tx_fx);
+
+ /* reuse field */
+ DRW_shgroup_uniform_int(fx_shgrp, "alpha_mode", &fxd->blur[1], 1);
+
+ fxd->runtime.fx_sh_c = fx_shgrp;
}
/* Swirl FX */
-static void DRW_gpencil_fx_swirl(
- ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
- tGPencilObjectCache *cache)
+static void DRW_gpencil_fx_swirl(ShaderFxData *fx,
+ GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ tGPencilObjectCache *cache)
{
- if (fx == NULL) {
- return;
- }
- SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx;
- if (fxd->object == NULL) {
- return;
- }
+ if (fx == NULL) {
+ return;
+ }
+ SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx;
+ if (fxd->object == NULL) {
+ return;
+ }
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- DRWShadingGroup *fx_shgrp;
- bGPdata *gpd = cache->gpd;
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ DRWShadingGroup *fx_shgrp;
+ bGPdata *gpd = cache->gpd;
- fxd->transparent = (int)fxd->flag & FX_SWIRL_MAKE_TRANSPARENT;
+ fxd->transparent = (int)fxd->flag & FX_SWIRL_MAKE_TRANSPARENT;
- GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
- fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_swirl_sh, psl->fx_shader_pass);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+ fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_swirl_sh, psl->fx_shader_pass);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
- DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
+ DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->object->obmat[3], 1);
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->object->obmat[3], 1);
- DRW_shgroup_uniform_int(fx_shgrp, "radius", &fxd->radius, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "angle", &fxd->angle, 1);
- DRW_shgroup_uniform_int(fx_shgrp, "transparent", &fxd->transparent, 1);
+ DRW_shgroup_uniform_int(fx_shgrp, "radius", &fxd->radius, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "angle", &fxd->angle, 1);
+ DRW_shgroup_uniform_int(fx_shgrp, "transparent", &fxd->transparent, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
- fxd->runtime.fx_sh = fx_shgrp;
+ fxd->runtime.fx_sh = fx_shgrp;
}
/* Wave Distorsion FX */
-static void DRW_gpencil_fx_wave(
- ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata)
+static void DRW_gpencil_fx_wave(ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata)
{
- if (fx == NULL) {
- return;
- }
-
- WaveShaderFxData *fxd = (WaveShaderFxData *)fx;
-
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
-
- DRWShadingGroup *fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_wave_sh, psl->fx_shader_pass);
- DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
- DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
- DRW_shgroup_uniform_float(fx_shgrp, "amplitude", &fxd->amplitude, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "period", &fxd->period, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "phase", &fxd->phase, 1);
- DRW_shgroup_uniform_int(fx_shgrp, "orientation", &fxd->orientation, 1);
- DRW_shgroup_uniform_vec2(fx_shgrp, "wsize", DRW_viewport_size_get(), 1);
-
- fxd->runtime.fx_sh = fx_shgrp;
+ if (fx == NULL) {
+ return;
+ }
+
+ WaveShaderFxData *fxd = (WaveShaderFxData *)fx;
+
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
+
+ DRWShadingGroup *fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_wave_sh, psl->fx_shader_pass);
+ DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
+ DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
+ DRW_shgroup_uniform_float(fx_shgrp, "amplitude", &fxd->amplitude, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "period", &fxd->period, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "phase", &fxd->phase, 1);
+ DRW_shgroup_uniform_int(fx_shgrp, "orientation", &fxd->orientation, 1);
+ DRW_shgroup_uniform_vec2(fx_shgrp, "wsize", DRW_viewport_size_get(), 1);
+
+ fxd->runtime.fx_sh = fx_shgrp;
}
/* ************************************************************** */
@@ -658,484 +640,443 @@ static void DRW_gpencil_fx_wave(
/* create all FX shaders */
void GPENCIL_create_fx_shaders(GPENCIL_e_data *e_data)
{
- /* fx shaders (all in screen space) */
- if (!e_data->gpencil_fx_blur_sh) {
- e_data->gpencil_fx_blur_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_blur_frag_glsl, NULL);
- }
- if (!e_data->gpencil_fx_colorize_sh) {
- e_data->gpencil_fx_colorize_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_colorize_frag_glsl, NULL);
- }
- if (!e_data->gpencil_fx_flip_sh) {
- e_data->gpencil_fx_flip_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_flip_frag_glsl, NULL);
- }
- if (!e_data->gpencil_fx_light_sh) {
- e_data->gpencil_fx_light_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_light_frag_glsl, NULL);
- }
- if (!e_data->gpencil_fx_pixel_sh) {
- e_data->gpencil_fx_pixel_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_pixel_frag_glsl, NULL);
- }
- if (!e_data->gpencil_fx_rim_prepare_sh) {
- e_data->gpencil_fx_rim_prepare_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_rim_prepare_frag_glsl, NULL);
-
- e_data->gpencil_fx_rim_resolve_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_rim_resolve_frag_glsl, NULL);
- }
- if (!e_data->gpencil_fx_shadow_prepare_sh) {
- e_data->gpencil_fx_shadow_prepare_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_shadow_prepare_frag_glsl, NULL);
-
- e_data->gpencil_fx_shadow_resolve_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_shadow_resolve_frag_glsl, NULL);
- }
- if (!e_data->gpencil_fx_glow_prepare_sh) {
- e_data->gpencil_fx_glow_prepare_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_glow_prepare_frag_glsl, NULL);
-
- e_data->gpencil_fx_glow_resolve_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_glow_resolve_frag_glsl, NULL);
- }
- if (!e_data->gpencil_fx_swirl_sh) {
- e_data->gpencil_fx_swirl_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_swirl_frag_glsl, NULL);
- }
- if (!e_data->gpencil_fx_wave_sh) {
- e_data->gpencil_fx_wave_sh = DRW_shader_create_fullscreen(
- datatoc_gpencil_fx_wave_frag_glsl, NULL);
- }
+ /* fx shaders (all in screen space) */
+ if (!e_data->gpencil_fx_blur_sh) {
+ e_data->gpencil_fx_blur_sh = DRW_shader_create_fullscreen(datatoc_gpencil_fx_blur_frag_glsl,
+ NULL);
+ }
+ if (!e_data->gpencil_fx_colorize_sh) {
+ e_data->gpencil_fx_colorize_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_fx_colorize_frag_glsl, NULL);
+ }
+ if (!e_data->gpencil_fx_flip_sh) {
+ e_data->gpencil_fx_flip_sh = DRW_shader_create_fullscreen(datatoc_gpencil_fx_flip_frag_glsl,
+ NULL);
+ }
+ if (!e_data->gpencil_fx_light_sh) {
+ e_data->gpencil_fx_light_sh = DRW_shader_create_fullscreen(datatoc_gpencil_fx_light_frag_glsl,
+ NULL);
+ }
+ if (!e_data->gpencil_fx_pixel_sh) {
+ e_data->gpencil_fx_pixel_sh = DRW_shader_create_fullscreen(datatoc_gpencil_fx_pixel_frag_glsl,
+ NULL);
+ }
+ if (!e_data->gpencil_fx_rim_prepare_sh) {
+ e_data->gpencil_fx_rim_prepare_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_fx_rim_prepare_frag_glsl, NULL);
+
+ e_data->gpencil_fx_rim_resolve_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_fx_rim_resolve_frag_glsl, NULL);
+ }
+ if (!e_data->gpencil_fx_shadow_prepare_sh) {
+ e_data->gpencil_fx_shadow_prepare_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_fx_shadow_prepare_frag_glsl, NULL);
+
+ e_data->gpencil_fx_shadow_resolve_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_fx_shadow_resolve_frag_glsl, NULL);
+ }
+ if (!e_data->gpencil_fx_glow_prepare_sh) {
+ e_data->gpencil_fx_glow_prepare_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_fx_glow_prepare_frag_glsl, NULL);
+
+ e_data->gpencil_fx_glow_resolve_sh = DRW_shader_create_fullscreen(
+ datatoc_gpencil_fx_glow_resolve_frag_glsl, NULL);
+ }
+ if (!e_data->gpencil_fx_swirl_sh) {
+ e_data->gpencil_fx_swirl_sh = DRW_shader_create_fullscreen(datatoc_gpencil_fx_swirl_frag_glsl,
+ NULL);
+ }
+ if (!e_data->gpencil_fx_wave_sh) {
+ e_data->gpencil_fx_wave_sh = DRW_shader_create_fullscreen(datatoc_gpencil_fx_wave_frag_glsl,
+ NULL);
+ }
}
/* free FX shaders */
void GPENCIL_delete_fx_shaders(GPENCIL_e_data *e_data)
{
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_blur_sh);
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_colorize_sh);
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_flip_sh);
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_light_sh);
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_pixel_sh);
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_rim_prepare_sh);
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_rim_resolve_sh);
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_shadow_prepare_sh);
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_shadow_resolve_sh);
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_glow_prepare_sh);
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_glow_resolve_sh);
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_swirl_sh);
- DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_wave_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_blur_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_colorize_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_flip_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_light_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_pixel_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_rim_prepare_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_rim_resolve_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_shadow_prepare_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_shadow_resolve_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_glow_prepare_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_glow_resolve_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_swirl_sh);
+ DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_wave_sh);
}
/* create all passes used by FX */
void GPENCIL_create_fx_passes(GPENCIL_PassList *psl)
{
- psl->fx_shader_pass = DRW_pass_create(
- "GPencil Shader FX Pass",
- DRW_STATE_WRITE_COLOR |
- DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
- psl->fx_shader_pass_blend = DRW_pass_create(
- "GPencil Shader FX Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND |
- DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+ psl->fx_shader_pass = DRW_pass_create("GPencil Shader FX Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
+ DRW_STATE_DEPTH_LESS);
+ psl->fx_shader_pass_blend = DRW_pass_create("GPencil Shader FX Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND |
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
}
-
/* prepare fx shading groups */
-void DRW_gpencil_fx_prepare(
- GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
- tGPencilObjectCache *cache_ob)
+void DRW_gpencil_fx_prepare(GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ tGPencilObjectCache *cache_ob)
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- const bool wiremode = (bool)(cache_ob->shading_type[0] == OB_WIRE);
-
- int ob_idx = cache_ob->idx;
-
- if ((wiremode) || (cache_ob->shader_fx.first == NULL)) {
- return;
- }
- /* loop FX */
- for (ShaderFxData *fx = cache_ob->shader_fx.first; fx; fx = fx->next) {
- if (effect_is_active(cache_ob->gpd, fx, stl->storage->is_render)) {
- switch (fx->type) {
- case eShaderFxType_Blur:
- DRW_gpencil_fx_blur(fx, ob_idx, e_data, vedata, cache_ob);
- break;
- case eShaderFxType_Colorize:
- DRW_gpencil_fx_colorize(fx, e_data, vedata);
- break;
- case eShaderFxType_Flip:
- DRW_gpencil_fx_flip(fx, e_data, vedata);
- break;
- case eShaderFxType_Light:
- DRW_gpencil_fx_light(fx, e_data, vedata, cache_ob);
- break;
- case eShaderFxType_Pixel:
- DRW_gpencil_fx_pixel(fx, e_data, vedata, cache_ob);
- break;
- case eShaderFxType_Rim:
- DRW_gpencil_fx_rim(fx, e_data, vedata, cache_ob);
- break;
- case eShaderFxType_Shadow:
- DRW_gpencil_fx_shadow(fx, e_data, vedata, cache_ob);
- break;
- case eShaderFxType_Glow:
- DRW_gpencil_fx_glow(fx, e_data, vedata, cache_ob);
- break;
- case eShaderFxType_Swirl:
- DRW_gpencil_fx_swirl(fx, e_data, vedata, cache_ob);
- break;
- case eShaderFxType_Wave:
- DRW_gpencil_fx_wave(fx, e_data, vedata);
- break;
- default:
- break;
- }
- }
- }
-
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ const bool wiremode = (bool)(cache_ob->shading_type[0] == OB_WIRE);
+
+ int ob_idx = cache_ob->idx;
+
+ if ((wiremode) || (cache_ob->shader_fx.first == NULL)) {
+ return;
+ }
+ /* loop FX */
+ for (ShaderFxData *fx = cache_ob->shader_fx.first; fx; fx = fx->next) {
+ if (effect_is_active(cache_ob->gpd, fx, stl->storage->is_render)) {
+ switch (fx->type) {
+ case eShaderFxType_Blur:
+ DRW_gpencil_fx_blur(fx, ob_idx, e_data, vedata, cache_ob);
+ break;
+ case eShaderFxType_Colorize:
+ DRW_gpencil_fx_colorize(fx, e_data, vedata);
+ break;
+ case eShaderFxType_Flip:
+ DRW_gpencil_fx_flip(fx, e_data, vedata);
+ break;
+ case eShaderFxType_Light:
+ DRW_gpencil_fx_light(fx, e_data, vedata, cache_ob);
+ break;
+ case eShaderFxType_Pixel:
+ DRW_gpencil_fx_pixel(fx, e_data, vedata, cache_ob);
+ break;
+ case eShaderFxType_Rim:
+ DRW_gpencil_fx_rim(fx, e_data, vedata, cache_ob);
+ break;
+ case eShaderFxType_Shadow:
+ DRW_gpencil_fx_shadow(fx, e_data, vedata, cache_ob);
+ break;
+ case eShaderFxType_Glow:
+ DRW_gpencil_fx_glow(fx, e_data, vedata, cache_ob);
+ break;
+ case eShaderFxType_Swirl:
+ DRW_gpencil_fx_swirl(fx, e_data, vedata, cache_ob);
+ break;
+ case eShaderFxType_Wave:
+ DRW_gpencil_fx_wave(fx, e_data, vedata);
+ break;
+ default:
+ break;
+ }
+ }
+ }
}
/* helper to draw one FX pass and do ping-pong copy */
-static void gpencil_draw_fx_pass(
- GPENCIL_e_data *e_data,
- GPENCIL_PassList *psl,
- GPENCIL_FramebufferList *fbl,
- DRWShadingGroup *shgrp, bool blend)
+static void gpencil_draw_fx_pass(GPENCIL_e_data *e_data,
+ GPENCIL_PassList *psl,
+ GPENCIL_FramebufferList *fbl,
+ DRWShadingGroup *shgrp,
+ bool blend)
{
- if (shgrp == NULL) {
- return;
- }
-
- const float clearcol[4] = {0.0f};
- GPU_framebuffer_bind(fbl->temp_fb_b);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
-
- /* draw effect pass in temp texture (B) using as source the previous image
- * existing in the other temp texture (A) */
- if (!blend) {
- DRW_draw_pass_subset(psl->fx_shader_pass, shgrp, shgrp);
- }
- else {
- DRW_draw_pass_subset(psl->fx_shader_pass_blend, shgrp, shgrp);
- }
-
- /* copy pass from b to a for ping-pong frame buffers */
- e_data->input_depth_tx = e_data->temp_depth_tx_b;
- e_data->input_color_tx = e_data->temp_color_tx_b;
-
- GPU_framebuffer_bind(fbl->temp_fb_a);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
- DRW_draw_pass(psl->mix_pass_noblend);
+ if (shgrp == NULL) {
+ return;
+ }
+
+ const float clearcol[4] = {0.0f};
+ GPU_framebuffer_bind(fbl->temp_fb_b);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
+
+ /* draw effect pass in temp texture (B) using as source the previous image
+ * existing in the other temp texture (A) */
+ if (!blend) {
+ DRW_draw_pass_subset(psl->fx_shader_pass, shgrp, shgrp);
+ }
+ else {
+ DRW_draw_pass_subset(psl->fx_shader_pass_blend, shgrp, shgrp);
+ }
+
+ /* copy pass from b to a for ping-pong frame buffers */
+ e_data->input_depth_tx = e_data->temp_depth_tx_b;
+ e_data->input_color_tx = e_data->temp_color_tx_b;
+
+ GPU_framebuffer_bind(fbl->temp_fb_a);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
+ DRW_draw_pass(psl->mix_pass_noblend);
}
/* helper to manage gaussian blur passes */
-static void draw_gpencil_blur_passes(
- GPENCIL_e_data *e_data,
- GPENCIL_Data *vedata,
- BlurShaderFxData *fxd)
+static void draw_gpencil_blur_passes(GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ BlurShaderFxData *fxd)
{
- if (fxd->runtime.fx_sh == NULL) {
- return;
- }
-
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
- DRWShadingGroup *shgrp = fxd->runtime.fx_sh;
- int samples = fxd->samples;
-
- float bx = fxd->blur[0];
- float by = fxd->blur[1];
-
- /* the blur is done in two steps (Hor/Ver) because is faster and
- * gets better result
- *
- * samples could be 0 and disable de blur effects because sometimes
- * is easier animate the number of samples only, instead to animate the
- * hide/unhide and the number of samples to make some effects.
- */
- for (int b = 0; b < samples; b++) {
- /* horizontal */
- if (bx > 0) {
- fxd->blur[0] = bx;
- fxd->blur[1] = 0;
- gpencil_draw_fx_pass(e_data, psl, fbl, shgrp, true);
- }
- /* vertical */
- if (by > 0) {
- fxd->blur[0] = 0;
- fxd->blur[1] = by;
- gpencil_draw_fx_pass(e_data, psl, fbl, shgrp, true);
- }
- }
+ if (fxd->runtime.fx_sh == NULL) {
+ return;
+ }
+
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
+ DRWShadingGroup *shgrp = fxd->runtime.fx_sh;
+ int samples = fxd->samples;
+
+ float bx = fxd->blur[0];
+ float by = fxd->blur[1];
+
+ /* the blur is done in two steps (Hor/Ver) because is faster and
+ * gets better result
+ *
+ * samples could be 0 and disable de blur effects because sometimes
+ * is easier animate the number of samples only, instead to animate the
+ * hide/unhide and the number of samples to make some effects.
+ */
+ for (int b = 0; b < samples; b++) {
+ /* horizontal */
+ if (bx > 0) {
+ fxd->blur[0] = bx;
+ fxd->blur[1] = 0;
+ gpencil_draw_fx_pass(e_data, psl, fbl, shgrp, true);
+ }
+ /* vertical */
+ if (by > 0) {
+ fxd->blur[0] = 0;
+ fxd->blur[1] = by;
+ gpencil_draw_fx_pass(e_data, psl, fbl, shgrp, true);
+ }
+ }
}
/* blur intermediate pass */
-static void draw_gpencil_midpass_blur(
- GPENCIL_Data *vedata,
- ShaderFxData_Runtime *runtime)
+static void draw_gpencil_midpass_blur(GPENCIL_Data *vedata, ShaderFxData_Runtime *runtime)
{
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
- const float clearcol[4] = {0.0f};
-
- GPU_framebuffer_bind(fbl->temp_fb_b);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
- DRW_draw_pass_subset(
- psl->fx_shader_pass_blend,
- runtime->fx_sh_b, runtime->fx_sh_b);
-
- /* copy pass from b for ping-pong frame buffers */
- GPU_framebuffer_bind(fbl->temp_fb_fx);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
- DRW_draw_pass(psl->mix_pass_noblend);
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
+ const float clearcol[4] = {0.0f};
+
+ GPU_framebuffer_bind(fbl->temp_fb_b);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
+ DRW_draw_pass_subset(psl->fx_shader_pass_blend, runtime->fx_sh_b, runtime->fx_sh_b);
+
+ /* copy pass from b for ping-pong frame buffers */
+ GPU_framebuffer_bind(fbl->temp_fb_fx);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
+ DRW_draw_pass(psl->mix_pass_noblend);
}
/* do blur of mid passes */
-static void draw_gpencil_do_blur(
- GPENCIL_e_data *e_data,
- GPENCIL_Data *vedata,
- ShaderFxData_Runtime *runtime,
- int samples, int bx, int by, int blur[2])
+static void draw_gpencil_do_blur(GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ ShaderFxData_Runtime *runtime,
+ int samples,
+ int bx,
+ int by,
+ int blur[2])
{
- e_data->input_depth_tx = e_data->temp_depth_tx_b;
- e_data->input_color_tx = e_data->temp_color_tx_b;
-
- if ((samples > 0) && ((bx > 0) || (by > 0))) {
- for (int x = 0; x < samples; x++) {
-
- /* horizontal */
- blur[0] = bx;
- blur[1] = 0;
- draw_gpencil_midpass_blur(vedata, runtime);
-
- /* Vertical */
- blur[0] = 0;
- blur[1] = by;
- draw_gpencil_midpass_blur(vedata, runtime);
-
- blur[0] = bx;
- blur[1] = by;
- }
- }
+ e_data->input_depth_tx = e_data->temp_depth_tx_b;
+ e_data->input_color_tx = e_data->temp_color_tx_b;
+
+ if ((samples > 0) && ((bx > 0) || (by > 0))) {
+ for (int x = 0; x < samples; x++) {
+
+ /* horizontal */
+ blur[0] = bx;
+ blur[1] = 0;
+ draw_gpencil_midpass_blur(vedata, runtime);
+
+ /* Vertical */
+ blur[0] = 0;
+ blur[1] = by;
+ draw_gpencil_midpass_blur(vedata, runtime);
+
+ blur[0] = bx;
+ blur[1] = by;
+ }
+ }
}
/* helper to draw RIM passes */
-static void draw_gpencil_rim_passes(
- GPENCIL_e_data *e_data,
- GPENCIL_Data *vedata,
- RimShaderFxData *fxd)
+static void draw_gpencil_rim_passes(GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ RimShaderFxData *fxd)
{
- if (fxd->runtime.fx_sh_b == NULL) {
- return;
- }
-
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
-
- const float clearcol[4] = {0.0f};
-
- /* prepare mask */
- GPU_framebuffer_bind(fbl->temp_fb_fx);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
- DRW_draw_pass_subset(
- psl->fx_shader_pass_blend,
- fxd->runtime.fx_sh, fxd->runtime.fx_sh);
-
- /* blur rim */
- draw_gpencil_do_blur(
- e_data, vedata, &fxd->runtime,
- fxd->samples,
- fxd->blur[0], fxd->blur[1],
- &fxd->blur[0]);
-
- /* resolve */
- GPU_framebuffer_bind(fbl->temp_fb_b);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
- DRW_draw_pass_subset(
- psl->fx_shader_pass_blend,
- fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c);
-
- /* copy pass from b to a for ping-pong frame buffers */
- e_data->input_depth_tx = e_data->temp_depth_tx_b;
- e_data->input_color_tx = e_data->temp_color_tx_b;
-
- GPU_framebuffer_bind(fbl->temp_fb_a);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
- DRW_draw_pass(psl->mix_pass_noblend);
+ if (fxd->runtime.fx_sh_b == NULL) {
+ return;
+ }
+
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
+
+ const float clearcol[4] = {0.0f};
+
+ /* prepare mask */
+ GPU_framebuffer_bind(fbl->temp_fb_fx);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
+ DRW_draw_pass_subset(psl->fx_shader_pass_blend, fxd->runtime.fx_sh, fxd->runtime.fx_sh);
+
+ /* blur rim */
+ draw_gpencil_do_blur(
+ e_data, vedata, &fxd->runtime, fxd->samples, fxd->blur[0], fxd->blur[1], &fxd->blur[0]);
+
+ /* resolve */
+ GPU_framebuffer_bind(fbl->temp_fb_b);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
+ DRW_draw_pass_subset(psl->fx_shader_pass_blend, fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c);
+
+ /* copy pass from b to a for ping-pong frame buffers */
+ e_data->input_depth_tx = e_data->temp_depth_tx_b;
+ e_data->input_color_tx = e_data->temp_color_tx_b;
+
+ GPU_framebuffer_bind(fbl->temp_fb_a);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
+ DRW_draw_pass(psl->mix_pass_noblend);
}
/* helper to draw SHADOW passes */
-static void draw_gpencil_shadow_passes(
- GPENCIL_e_data *e_data,
- GPENCIL_Data *vedata,
- ShadowShaderFxData *fxd)
+static void draw_gpencil_shadow_passes(GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ ShadowShaderFxData *fxd)
{
- if (fxd->runtime.fx_sh_b == NULL) {
- return;
- }
-
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
- const float clearcol[4] = {0.0f};
-
- /* prepare shadow */
- GPU_framebuffer_bind(fbl->temp_fb_fx);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
- DRW_draw_pass_subset(
- psl->fx_shader_pass_blend,
- fxd->runtime.fx_sh, fxd->runtime.fx_sh);
-
- /* blur shadow */
- draw_gpencil_do_blur(
- e_data, vedata, &fxd->runtime,
- fxd->samples,
- fxd->blur[0], fxd->blur[1],
- &fxd->blur[0]);
-
- /* resolve */
- GPU_framebuffer_bind(fbl->temp_fb_b);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
- DRW_draw_pass_subset(
- psl->fx_shader_pass_blend,
- fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c);
-
- /* copy pass from b to a for ping-pong frame buffers */
- e_data->input_depth_tx = e_data->temp_depth_tx_b;
- e_data->input_color_tx = e_data->temp_color_tx_b;
-
- GPU_framebuffer_bind(fbl->temp_fb_a);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
- DRW_draw_pass(psl->mix_pass_noblend);
+ if (fxd->runtime.fx_sh_b == NULL) {
+ return;
+ }
+
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
+ const float clearcol[4] = {0.0f};
+
+ /* prepare shadow */
+ GPU_framebuffer_bind(fbl->temp_fb_fx);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
+ DRW_draw_pass_subset(psl->fx_shader_pass_blend, fxd->runtime.fx_sh, fxd->runtime.fx_sh);
+
+ /* blur shadow */
+ draw_gpencil_do_blur(
+ e_data, vedata, &fxd->runtime, fxd->samples, fxd->blur[0], fxd->blur[1], &fxd->blur[0]);
+
+ /* resolve */
+ GPU_framebuffer_bind(fbl->temp_fb_b);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
+ DRW_draw_pass_subset(psl->fx_shader_pass_blend, fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c);
+
+ /* copy pass from b to a for ping-pong frame buffers */
+ e_data->input_depth_tx = e_data->temp_depth_tx_b;
+ e_data->input_color_tx = e_data->temp_color_tx_b;
+
+ GPU_framebuffer_bind(fbl->temp_fb_a);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
+ DRW_draw_pass(psl->mix_pass_noblend);
}
/* helper to draw GLOW passes */
-static void draw_gpencil_glow_passes(
- GPENCIL_e_data *e_data,
- GPENCIL_Data *vedata,
- GlowShaderFxData *fxd)
+static void draw_gpencil_glow_passes(GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ GlowShaderFxData *fxd)
{
- if (fxd->runtime.fx_sh_b == NULL) {
- return;
- }
-
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
-
- const float clearcol[4] = {0.0f};
-
- /* prepare glow */
- GPU_framebuffer_bind(fbl->temp_fb_fx);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
- DRW_draw_pass_subset(
- psl->fx_shader_pass_blend,
- fxd->runtime.fx_sh, fxd->runtime.fx_sh);
-
- /* blur glow */
- draw_gpencil_do_blur(
- e_data, vedata, &fxd->runtime,
- fxd->samples,
- fxd->blur[0], fxd->blur[0],
- &fxd->blur[0]);
-
- /* resolve */
- GPU_framebuffer_bind(fbl->temp_fb_b);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
-
- /* reuses blur field to keep alpha mode */
- fxd->blur[1] = (fxd->flag & FX_GLOW_USE_ALPHA) ? 1 : 0;
-
- DRW_draw_pass_subset(
- psl->fx_shader_pass_blend,
- fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c);
-
- /* copy pass from b to a for ping-pong frame buffers */
- e_data->input_depth_tx = e_data->temp_depth_tx_b;
- e_data->input_color_tx = e_data->temp_color_tx_b;
-
- GPU_framebuffer_bind(fbl->temp_fb_a);
- GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
- DRW_draw_pass(psl->mix_pass_noblend);
+ if (fxd->runtime.fx_sh_b == NULL) {
+ return;
+ }
+
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
+
+ const float clearcol[4] = {0.0f};
+
+ /* prepare glow */
+ GPU_framebuffer_bind(fbl->temp_fb_fx);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
+ DRW_draw_pass_subset(psl->fx_shader_pass_blend, fxd->runtime.fx_sh, fxd->runtime.fx_sh);
+
+ /* blur glow */
+ draw_gpencil_do_blur(
+ e_data, vedata, &fxd->runtime, fxd->samples, fxd->blur[0], fxd->blur[0], &fxd->blur[0]);
+
+ /* resolve */
+ GPU_framebuffer_bind(fbl->temp_fb_b);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
+
+ /* reuses blur field to keep alpha mode */
+ fxd->blur[1] = (fxd->flag & FX_GLOW_USE_ALPHA) ? 1 : 0;
+
+ DRW_draw_pass_subset(psl->fx_shader_pass_blend, fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c);
+
+ /* copy pass from b to a for ping-pong frame buffers */
+ e_data->input_depth_tx = e_data->temp_depth_tx_b;
+ e_data->input_color_tx = e_data->temp_color_tx_b;
+
+ GPU_framebuffer_bind(fbl->temp_fb_a);
+ GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
+ DRW_draw_pass(psl->mix_pass_noblend);
}
/* apply all object fx effects */
-void DRW_gpencil_fx_draw(
- GPENCIL_e_data *e_data,
- GPENCIL_Data *vedata, tGPencilObjectCache *cache_ob)
+void DRW_gpencil_fx_draw(GPENCIL_e_data *e_data,
+ GPENCIL_Data *vedata,
+ tGPencilObjectCache *cache_ob)
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
- GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
-
- /* loop FX modifiers */
- for (ShaderFxData *fx = cache_ob->shader_fx.first; fx; fx = fx->next) {
- if (effect_is_active(cache_ob->gpd, fx, stl->storage->is_render)) {
- switch (fx->type) {
-
- case eShaderFxType_Blur:
- {
- BlurShaderFxData *fxd = (BlurShaderFxData *)fx;
- draw_gpencil_blur_passes(e_data, vedata, fxd);
- break;
- }
- case eShaderFxType_Colorize:
- {
- ColorizeShaderFxData *fxd = (ColorizeShaderFxData *)fx;
- gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
- break;
- }
- case eShaderFxType_Flip:
- {
- FlipShaderFxData *fxd = (FlipShaderFxData *)fx;
- gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
- break;
- }
- case eShaderFxType_Light:
- {
- LightShaderFxData *fxd = (LightShaderFxData *)fx;
- gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
- break;
- }
- case eShaderFxType_Pixel:
- {
- PixelShaderFxData *fxd = (PixelShaderFxData *)fx;
- gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
- break;
- }
- case eShaderFxType_Rim:
- {
- RimShaderFxData *fxd = (RimShaderFxData *)fx;
- draw_gpencil_rim_passes(e_data, vedata, fxd);
- break;
- }
- case eShaderFxType_Shadow:
- {
- ShadowShaderFxData *fxd = (ShadowShaderFxData *)fx;
- draw_gpencil_shadow_passes(e_data, vedata, fxd);
- break;
- }
- case eShaderFxType_Glow:
- {
- GlowShaderFxData *fxd = (GlowShaderFxData *)fx;
- draw_gpencil_glow_passes(e_data, vedata, fxd);
- break;
- }
- case eShaderFxType_Swirl:
- {
- SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx;
- gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
- break;
- }
- case eShaderFxType_Wave:
- {
- WaveShaderFxData *fxd = (WaveShaderFxData *)fx;
- gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
- break;
- }
- default:
- break;
- }
- }
- }
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
+ GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
+
+ /* loop FX modifiers */
+ for (ShaderFxData *fx = cache_ob->shader_fx.first; fx; fx = fx->next) {
+ if (effect_is_active(cache_ob->gpd, fx, stl->storage->is_render)) {
+ switch (fx->type) {
+
+ case eShaderFxType_Blur: {
+ BlurShaderFxData *fxd = (BlurShaderFxData *)fx;
+ draw_gpencil_blur_passes(e_data, vedata, fxd);
+ break;
+ }
+ case eShaderFxType_Colorize: {
+ ColorizeShaderFxData *fxd = (ColorizeShaderFxData *)fx;
+ gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
+ break;
+ }
+ case eShaderFxType_Flip: {
+ FlipShaderFxData *fxd = (FlipShaderFxData *)fx;
+ gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
+ break;
+ }
+ case eShaderFxType_Light: {
+ LightShaderFxData *fxd = (LightShaderFxData *)fx;
+ gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
+ break;
+ }
+ case eShaderFxType_Pixel: {
+ PixelShaderFxData *fxd = (PixelShaderFxData *)fx;
+ gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
+ break;
+ }
+ case eShaderFxType_Rim: {
+ RimShaderFxData *fxd = (RimShaderFxData *)fx;
+ draw_gpencil_rim_passes(e_data, vedata, fxd);
+ break;
+ }
+ case eShaderFxType_Shadow: {
+ ShadowShaderFxData *fxd = (ShadowShaderFxData *)fx;
+ draw_gpencil_shadow_passes(e_data, vedata, fxd);
+ break;
+ }
+ case eShaderFxType_Glow: {
+ GlowShaderFxData *fxd = (GlowShaderFxData *)fx;
+ draw_gpencil_glow_passes(e_data, vedata, fxd);
+ break;
+ }
+ case eShaderFxType_Swirl: {
+ SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx;
+ gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
+ break;
+ }
+ case eShaderFxType_Wave: {
+ WaveShaderFxData *fxd = (WaveShaderFxData *)fx;
+ gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl
index cd348a477a1..0f64f54c67b 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl
@@ -8,7 +8,7 @@ uniform vec2 Viewport;
uniform int blur[2];
uniform vec3 loc;
-uniform float pixsize; /* rv3d->pixsize */
+uniform float pixsize; /* rv3d->pixsize */
uniform float pixfactor;
float defaultpixsize = pixsize * (1000.0 / pixfactor);
@@ -18,66 +18,68 @@ out vec4 FragColor;
float get_zdepth(ivec2 poxy)
{
- /* if outside viewport set as infinite depth */
- if ((poxy.x < 0) || (poxy.x > Viewport.x)) {
- return 1.0f;
- }
- if ((poxy.y < 0) || (poxy.y > Viewport.y)) {
- return 1.0f;
- }
-
- float zdepth = texelFetch(strokeDepth, poxy, 0).r;
- return zdepth;
+ /* if outside viewport set as infinite depth */
+ if ((poxy.x < 0) || (poxy.x > Viewport.x)) {
+ return 1.0f;
+ }
+ if ((poxy.y < 0) || (poxy.y > Viewport.y)) {
+ return 1.0f;
+ }
+
+ float zdepth = texelFetch(strokeDepth, poxy, 0).r;
+ return zdepth;
}
void main()
{
- ivec2 uv = ivec2(gl_FragCoord.xy);
-
- vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
-
- float dx = (ProjectionMatrix[3][3] == 0.0) ? (noffset[0] / (nloc.z * defaultpixsize)) : (noffset[0] / defaultpixsize);
- float dy = (ProjectionMatrix[3][3] == 0.0) ? (noffset[1] / (nloc.z * defaultpixsize)) : (noffset[1] / defaultpixsize);
-
- /* round to avoid shift when add more samples */
- dx = floor(dx) + 1.0;
- dy = floor(dy) + 1.0;
-
- /* apply blurring, using a 9-tap filter with predefined gaussian weights */
- /* depth (get the value of the surrounding pixels) */
- float outdepth = get_zdepth(ivec2(uv.x, uv.y));
- for (int x = -1; x < 2; x++) {
- for (int y = -1; y < 2; y++) {
- float depth = get_zdepth(ivec2(uv.x + x * dx, uv.y + y * dy));
- if (depth < outdepth) {
- outdepth = depth;
- break;
- }
- }
- }
- gl_FragDepth = outdepth;
-
- /* color */
- vec4 outcolor = vec4(0.0);
- outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y + 1.0 * dy), 0) * 0.0947416;
- outcolor += texelFetch(strokeColor, ivec2(uv.x - 0.0 * dx, uv.y + 1.0 * dy), 0) * 0.118318;
- outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y + 1.0 * dy), 0) * 0.0947416;
- outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y + 0.0 * dy), 0) * 0.118318;
-
- outcolor += texelFetch(strokeColor, ivec2(uv.x, uv.y), 0) * 0.147761;
-
- outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y + 0.0 * dy), 0) * 0.118318;
- outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y - 1.0 * dy), 0) * 0.0947416;
- outcolor += texelFetch(strokeColor, ivec2(uv.x + 0.0 * dx, uv.y - 1.0 * dy), 0) * 0.118318;
- outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y - 1.0 * dy), 0) * 0.0947416;
-
- FragColor = clamp(outcolor, 0, 1.0);
-
- /* discar extreme values */
- if (outcolor.a < 0.02f) {
- discard;
- }
- if ((outdepth <= 0.000001) || (outdepth >= 0.999999)){
- discard;
- }
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+
+ vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
+
+ float dx = (ProjectionMatrix[3][3] == 0.0) ? (noffset[0] / (nloc.z * defaultpixsize)) :
+ (noffset[0] / defaultpixsize);
+ float dy = (ProjectionMatrix[3][3] == 0.0) ? (noffset[1] / (nloc.z * defaultpixsize)) :
+ (noffset[1] / defaultpixsize);
+
+ /* round to avoid shift when add more samples */
+ dx = floor(dx) + 1.0;
+ dy = floor(dy) + 1.0;
+
+ /* apply blurring, using a 9-tap filter with predefined gaussian weights */
+ /* depth (get the value of the surrounding pixels) */
+ float outdepth = get_zdepth(ivec2(uv.x, uv.y));
+ for (int x = -1; x < 2; x++) {
+ for (int y = -1; y < 2; y++) {
+ float depth = get_zdepth(ivec2(uv.x + x * dx, uv.y + y * dy));
+ if (depth < outdepth) {
+ outdepth = depth;
+ break;
+ }
+ }
+ }
+ gl_FragDepth = outdepth;
+
+ /* color */
+ vec4 outcolor = vec4(0.0);
+ outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y + 1.0 * dy), 0) * 0.0947416;
+ outcolor += texelFetch(strokeColor, ivec2(uv.x - 0.0 * dx, uv.y + 1.0 * dy), 0) * 0.118318;
+ outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y + 1.0 * dy), 0) * 0.0947416;
+ outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y + 0.0 * dy), 0) * 0.118318;
+
+ outcolor += texelFetch(strokeColor, ivec2(uv.x, uv.y), 0) * 0.147761;
+
+ outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y + 0.0 * dy), 0) * 0.118318;
+ outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y - 1.0 * dy), 0) * 0.0947416;
+ outcolor += texelFetch(strokeColor, ivec2(uv.x + 0.0 * dx, uv.y - 1.0 * dy), 0) * 0.118318;
+ outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y - 1.0 * dy), 0) * 0.0947416;
+
+ FragColor = clamp(outcolor, 0, 1.0);
+
+ /* discar extreme values */
+ if (outcolor.a < 0.02f) {
+ discard;
+ }
+ if ((outdepth <= 0.000001) || (outdepth >= 0.999999)) {
+ discard;
+ }
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl
index fb44b18cc86..52f42d30d06 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl
@@ -8,79 +8,75 @@ uniform float factor;
out vec4 FragColor;
-#define MODE_GRAYSCALE 0
-#define MODE_SEPIA 1
-#define MODE_DUOTONE 2
-#define MODE_CUSTOM 3
+#define MODE_GRAYSCALE 0
+#define MODE_SEPIA 1
+#define MODE_DUOTONE 2
+#define MODE_CUSTOM 3
#define MODE_TRANSPARENT 4
float get_luminance(vec4 color)
{
- float lum = (color.r * 0.2126) + (color.g * 0.7152) + (color.b * 0.723);
- return lum;
+ float lum = (color.r * 0.2126) + (color.g * 0.7152) + (color.b * 0.723);
+ return lum;
}
void main()
{
- ivec2 uv = ivec2(gl_FragCoord.xy);
+ ivec2 uv = ivec2(gl_FragCoord.xy);
- float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
- vec4 src_pixel= texelFetch(strokeColor, uv.xy, 0);
- float luminance = get_luminance(src_pixel);
- vec4 outcolor;
+ float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
+ vec4 src_pixel = texelFetch(strokeColor, uv.xy, 0);
+ float luminance = get_luminance(src_pixel);
+ vec4 outcolor;
- /* is transparent */
- if (src_pixel.a == 0.0f) {
- discard;
- }
+ /* is transparent */
+ if (src_pixel.a == 0.0f) {
+ discard;
+ }
- switch(mode) {
- case MODE_GRAYSCALE:
- {
- outcolor = vec4(luminance, luminance, luminance, src_pixel.a);
- break;
- }
- case MODE_SEPIA:
- {
- float Red = (src_pixel.r * 0.393) + (src_pixel.g * 0.769) + (src_pixel.b * 0.189);
- float Green = (src_pixel.r * 0.349) + (src_pixel.g * 0.686) + (src_pixel.b * 0.168);
- float Blue = (src_pixel.r * 0.272) + (src_pixel.g * 0.534) + (src_pixel.b * 0.131);
- outcolor = vec4(Red, Green, Blue, src_pixel.a);
- break;
- }
- case MODE_DUOTONE:
- {
- if (luminance <= factor) {
- outcolor = low_color;
- }
- else {
- outcolor = high_color;
- }
- break;
- }
- case MODE_CUSTOM:
- {
- /* if below umbral, force custom color */
- if (luminance <= factor) {
- outcolor = low_color;
- }
- else {
- outcolor = vec4(luminance * low_color.r, luminance * low_color.b, luminance * low_color.b, src_pixel.a);
- }
- break;
- }
- case MODE_TRANSPARENT:
- {
- outcolor = vec4(src_pixel.rgb, src_pixel.a * factor);
- break;
- }
- default:
- {
- outcolor = src_pixel;
- }
+ switch (mode) {
+ case MODE_GRAYSCALE: {
+ outcolor = vec4(luminance, luminance, luminance, src_pixel.a);
+ break;
+ }
+ case MODE_SEPIA: {
+ float Red = (src_pixel.r * 0.393) + (src_pixel.g * 0.769) + (src_pixel.b * 0.189);
+ float Green = (src_pixel.r * 0.349) + (src_pixel.g * 0.686) + (src_pixel.b * 0.168);
+ float Blue = (src_pixel.r * 0.272) + (src_pixel.g * 0.534) + (src_pixel.b * 0.131);
+ outcolor = vec4(Red, Green, Blue, src_pixel.a);
+ break;
+ }
+ case MODE_DUOTONE: {
+ if (luminance <= factor) {
+ outcolor = low_color;
+ }
+ else {
+ outcolor = high_color;
+ }
+ break;
+ }
+ case MODE_CUSTOM: {
+ /* if below umbral, force custom color */
+ if (luminance <= factor) {
+ outcolor = low_color;
+ }
+ else {
+ outcolor = vec4(luminance * low_color.r,
+ luminance * low_color.b,
+ luminance * low_color.b,
+ src_pixel.a);
+ }
+ break;
+ }
+ case MODE_TRANSPARENT: {
+ outcolor = vec4(src_pixel.rgb, src_pixel.a * factor);
+ break;
+ }
+ default: {
+ outcolor = src_pixel;
+ }
+ }
- }
-
- gl_FragDepth = stroke_depth;
- FragColor = outcolor;
+ gl_FragDepth = stroke_depth;
+ FragColor = outcolor;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl
index 43589461cd1..2cd77007b36 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl
@@ -7,31 +7,31 @@ uniform int flipmode;
void main()
{
- vec2 mode = vec2(0,0);
- /* horz. */
- if (flipmode >= 110) {
- mode[0] = 1;
- }
- /* vert. */
- if ((flipmode == 101) || (flipmode == 111)) {
- mode[1] = 1;
- }
+ vec2 mode = vec2(0, 0);
+ /* horz. */
+ if (flipmode >= 110) {
+ mode[0] = 1;
+ }
+ /* vert. */
+ if ((flipmode == 101) || (flipmode == 111)) {
+ mode[1] = 1;
+ }
- vec2 uv = vec2(gl_FragCoord.xy);
- float stroke_depth;
- vec4 outcolor;
+ vec2 uv = vec2(gl_FragCoord.xy);
+ float stroke_depth;
+ vec4 outcolor;
- if (mode[0] > 0) {
- uv.x = wsize.x - uv.x;
- }
- if (mode[1] > 0) {
- uv.y = wsize.y - uv.y;
- }
+ if (mode[0] > 0) {
+ uv.x = wsize.x - uv.x;
+ }
+ if (mode[1] > 0) {
+ uv.y = wsize.y - uv.y;
+ }
- ivec2 iuv = ivec2(uv.x, uv.y);
- stroke_depth = texelFetch(strokeDepth, iuv, 0).r;
- outcolor = texelFetch(strokeColor, iuv, 0);
+ ivec2 iuv = ivec2(uv.x, uv.y);
+ stroke_depth = texelFetch(strokeDepth, iuv, 0).r;
+ outcolor = texelFetch(strokeColor, iuv, 0);
- gl_FragDepth = stroke_depth;
- FragColor = outcolor;
+ gl_FragDepth = stroke_depth;
+ FragColor = outcolor;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl
index 9cdcad3e486..676b9b05db9 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_prepare_frag.glsl
@@ -14,55 +14,55 @@ uniform int mode;
out vec4 FragColor;
-#define MODE_LUMINANCE 0
-#define MODE_COLOR 1
+#define MODE_LUMINANCE 0
+#define MODE_COLOR 1
/* calc luminance */
-float luma( vec3 color ) {
- /* the color is linear, so do not apply tonemapping */
- return (color.r + color.g + color.b) / 3.0;
+float luma(vec3 color)
+{
+ /* the color is linear, so do not apply tonemapping */
+ return (color.r + color.g + color.b) / 3.0;
}
bool check_color(vec3 color_a, vec3 color_b)
{
- /* need round the number to avoid precision errors */
- if ((floor(color_a.r * 100) == floor(color_b.r * 100)) &&
- (floor(color_a.g * 100) == floor(color_b.g * 100)) &&
- (floor(color_a.b * 100) == floor(color_b.b * 100)))
- {
- return true;
- }
+ /* need round the number to avoid precision errors */
+ if ((floor(color_a.r * 100) == floor(color_b.r * 100)) &&
+ (floor(color_a.g * 100) == floor(color_b.g * 100)) &&
+ (floor(color_a.b * 100) == floor(color_b.b * 100))) {
+ return true;
+ }
- return false;
+ return false;
}
void main()
{
- vec2 uv = vec2(gl_FragCoord.xy);
+ vec2 uv = vec2(gl_FragCoord.xy);
- float stroke_depth = texelFetch(strokeDepth, ivec2(uv.xy), 0).r;
- vec4 src_pixel= texelFetch(strokeColor, ivec2(uv.xy), 0);
- vec4 outcolor;
+ float stroke_depth = texelFetch(strokeDepth, ivec2(uv.xy), 0).r;
+ vec4 src_pixel = texelFetch(strokeColor, ivec2(uv.xy), 0);
+ vec4 outcolor;
- /* is transparent */
- if (src_pixel.a == 0.0f) {
- discard;
- }
+ /* is transparent */
+ if (src_pixel.a == 0.0f) {
+ discard;
+ }
- if (mode == MODE_LUMINANCE) {
- if (luma(src_pixel.rgb) < threshold) {
- discard;
- }
- }
- else if (mode == MODE_COLOR) {
- if (!check_color(src_pixel.rgb, select_color.rgb)) {
- discard;
- }
- }
- else {
- discard;
- }
+ if (mode == MODE_LUMINANCE) {
+ if (luma(src_pixel.rgb) < threshold) {
+ discard;
+ }
+ }
+ else if (mode == MODE_COLOR) {
+ if (!check_color(src_pixel.rgb, select_color.rgb)) {
+ discard;
+ }
+ }
+ else {
+ discard;
+ }
- gl_FragDepth = stroke_depth;
- FragColor = vec4(glow_color.rgb, 1.0);
+ gl_FragDepth = stroke_depth;
+ FragColor = vec4(glow_color.rgb, 1.0);
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl
index 5bff7a20523..e2aceb9eefe 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_glow_resolve_frag.glsl
@@ -11,36 +11,36 @@ out vec4 FragColor;
void main()
{
- vec4 outcolor;
- ivec2 uv = ivec2(gl_FragCoord.xy);
+ vec4 outcolor;
+ ivec2 uv = ivec2(gl_FragCoord.xy);
- float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
- vec4 src_pixel= texelFetch(strokeColor, uv.xy, 0);
- vec4 glow_pixel= texelFetch(glowColor, uv.xy, 0);
- float glow_depth = texelFetch(glowDepth, uv.xy, 0).r;
+ float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
+ vec4 src_pixel = texelFetch(strokeColor, uv.xy, 0);
+ vec4 glow_pixel = texelFetch(glowColor, uv.xy, 0);
+ float glow_depth = texelFetch(glowDepth, uv.xy, 0).r;
- if (alpha_mode == 0) {
- outcolor = src_pixel + glow_pixel;
- }
- else {
- if ((src_pixel.a < 0.1) || (glow_pixel.a < 0.1)) {
- outcolor = src_pixel + glow_pixel;
- }
- else {
- outcolor = src_pixel;
- }
- }
+ if (alpha_mode == 0) {
+ outcolor = src_pixel + glow_pixel;
+ }
+ else {
+ if ((src_pixel.a < 0.1) || (glow_pixel.a < 0.1)) {
+ outcolor = src_pixel + glow_pixel;
+ }
+ else {
+ outcolor = src_pixel;
+ }
+ }
- if (src_pixel.a < glow_pixel.a) {
- gl_FragDepth = glow_depth;
- }
- else {
- gl_FragDepth = stroke_depth;
- }
+ if (src_pixel.a < glow_pixel.a) {
+ gl_FragDepth = glow_depth;
+ }
+ else {
+ gl_FragDepth = stroke_depth;
+ }
- if (outcolor.a < 0.001) {
- discard;
- }
+ if (outcolor.a < 0.001) {
+ discard;
+ }
- FragColor = outcolor;
+ FragColor = outcolor;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl
index c12dd223ebe..a5c321c20c1 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl
@@ -8,62 +8,63 @@ uniform vec4 loc;
uniform float energy;
uniform float ambient;
-uniform float pixsize; /* rv3d->pixsize */
+uniform float pixsize; /* rv3d->pixsize */
uniform float pixfactor;
out vec4 FragColor;
float defaultpixsize = pixsize * (1000.0 / pixfactor);
-#define height loc.w
+#define height loc.w
/* project 3d point to 2d on screen space */
vec2 toScreenSpace(vec4 vertex)
{
- /* need to calculate ndc because this is not done by vertex shader */
- vec3 ndc = vec3(vertex).xyz / vertex.w;
+ /* need to calculate ndc because this is not done by vertex shader */
+ vec3 ndc = vec3(vertex).xyz / vertex.w;
- vec2 sc;
- sc.x = ((ndc.x + 1.0) / 2.0) * Viewport.x;
- sc.y = ((ndc.y + 1.0) / 2.0) * Viewport.y;
+ vec2 sc;
+ sc.x = ((ndc.x + 1.0) / 2.0) * Viewport.x;
+ sc.y = ((ndc.y + 1.0) / 2.0) * Viewport.y;
- return sc;
+ return sc;
}
void main()
{
- float stroke_depth;
- vec4 objcolor;
+ float stroke_depth;
+ vec4 objcolor;
- vec4 light_loc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
- vec2 light2d = toScreenSpace(light_loc);
+ vec4 light_loc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
+ vec2 light2d = toScreenSpace(light_loc);
- /* calc pixel scale */
- float pxscale = (ProjectionMatrix[3][3] == 0.0) ? (10.0 / (light_loc.z * defaultpixsize)) : (10.0 / defaultpixsize);
- pxscale = max(pxscale, 0.000001);
+ /* calc pixel scale */
+ float pxscale = (ProjectionMatrix[3][3] == 0.0) ? (10.0 / (light_loc.z * defaultpixsize)) :
+ (10.0 / defaultpixsize);
+ pxscale = max(pxscale, 0.000001);
- /* the height over plane is received in the w component of the loc
- * and needs a factor to adapt to pixels
- */
- float peak = height * 10.0 * pxscale;
- vec3 light3d = vec3(light2d.x, light2d.y, peak);
+ /* the height over plane is received in the w component of the loc
+ * and needs a factor to adapt to pixels
+ */
+ float peak = height * 10.0 * pxscale;
+ vec3 light3d = vec3(light2d.x, light2d.y, peak);
- vec2 uv = vec2(gl_FragCoord.xy);
- vec3 frag_loc = vec3(uv.x, uv.y, 0);
- vec3 norm = vec3(0, 0, 1.0); /* always z-up */
+ vec2 uv = vec2(gl_FragCoord.xy);
+ vec3 frag_loc = vec3(uv.x, uv.y, 0);
+ vec3 norm = vec3(0, 0, 1.0); /* always z-up */
- ivec2 iuv = ivec2(uv.x, uv.y);
- stroke_depth = texelFetch(strokeDepth, iuv, 0).r;
- objcolor = texelFetch(strokeColor, iuv, 0);
+ ivec2 iuv = ivec2(uv.x, uv.y);
+ stroke_depth = texelFetch(strokeDepth, iuv, 0).r;
+ objcolor = texelFetch(strokeColor, iuv, 0);
- /* diffuse light */
- vec3 lightdir = normalize(light3d - frag_loc);
- float diff = max(dot(norm, lightdir), 0.0);
- float dist = length(light3d - frag_loc) / pxscale;
- float factor = diff * ((energy * 100.0) / (dist * dist));
+ /* diffuse light */
+ vec3 lightdir = normalize(light3d - frag_loc);
+ float diff = max(dot(norm, lightdir), 0.0);
+ float dist = length(light3d - frag_loc) / pxscale;
+ float factor = diff * ((energy * 100.0) / (dist * dist));
- vec3 result = factor * max(ambient, 0.1) * vec3(objcolor);
+ vec3 result = factor * max(ambient, 0.1) * vec3(objcolor);
- gl_FragDepth = stroke_depth;
- FragColor = vec4(result.r, result.g, result.b, objcolor.a);
+ gl_FragDepth = stroke_depth;
+ FragColor = vec4(result.r, result.g, result.b, objcolor.a);
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl
index eb5596c639a..46b3c4286b4 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl
@@ -8,7 +8,7 @@ uniform int size[3];
uniform vec4 color;
uniform vec3 loc;
-uniform float pixsize; /* rv3d->pixsize */
+uniform float pixsize; /* rv3d->pixsize */
uniform float pixfactor;
out vec4 FragColor;
@@ -20,30 +20,32 @@ vec2 nsize = max(vec2(size[0], size[1]), 3.0);
/* This pixelation shader is a modified version of original Geeks3d.com code */
void main()
{
- vec2 uv = vec2(gl_FragCoord.xy);
- vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
-
- float dx = (ProjectionMatrix[3][3] == 0.0) ? (nsize[0] / (nloc.z * defaultpixsize)) : (nsize[0] / defaultpixsize);
- float dy = (ProjectionMatrix[3][3] == 0.0) ? (nsize[1] / (nloc.z * defaultpixsize)) : (nsize[1] / defaultpixsize);
-
- dx = max(abs(dx), 3.0);
- dy = max(abs(dy), 3.0);
-
- vec2 coord = vec2(dx * floor(uv.x / dx), dy * floor(uv.y / dy));
-
- float stroke_depth = texelFetch(strokeDepth, ivec2(coord), 0).r;
- vec4 outcolor = texelFetch(strokeColor, ivec2(coord), 0);
-
- if (uselines == 1) {
- float difx = uv.x - (floor(uv.x / nsize[0]) * nsize[0]);
- if ((difx == 0.5) && (outcolor.a > 0)) {
- outcolor = color;
- }
- float dify = uv.y - (floor(uv.y / nsize[1]) * nsize[1]);
- if ((dify == 0.5) && (outcolor.a > 0)) {
- outcolor = color;
- }
- }
- gl_FragDepth = stroke_depth;
- FragColor = outcolor;
+ vec2 uv = vec2(gl_FragCoord.xy);
+ vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
+
+ float dx = (ProjectionMatrix[3][3] == 0.0) ? (nsize[0] / (nloc.z * defaultpixsize)) :
+ (nsize[0] / defaultpixsize);
+ float dy = (ProjectionMatrix[3][3] == 0.0) ? (nsize[1] / (nloc.z * defaultpixsize)) :
+ (nsize[1] / defaultpixsize);
+
+ dx = max(abs(dx), 3.0);
+ dy = max(abs(dy), 3.0);
+
+ vec2 coord = vec2(dx * floor(uv.x / dx), dy * floor(uv.y / dy));
+
+ float stroke_depth = texelFetch(strokeDepth, ivec2(coord), 0).r;
+ vec4 outcolor = texelFetch(strokeColor, ivec2(coord), 0);
+
+ if (uselines == 1) {
+ float difx = uv.x - (floor(uv.x / nsize[0]) * nsize[0]);
+ if ((difx == 0.5) && (outcolor.a > 0)) {
+ outcolor = color;
+ }
+ float dify = uv.y - (floor(uv.y / nsize[1]) * nsize[1]);
+ if ((dify == 0.5) && (outcolor.a > 0)) {
+ outcolor = color;
+ }
+ }
+ gl_FragDepth = stroke_depth;
+ FragColor = outcolor;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl
index 2321429fbf1..2a17e573978 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl
@@ -13,7 +13,7 @@ uniform vec3 rim_color;
uniform vec3 mask_color;
uniform vec3 loc;
-uniform float pixsize; /* rv3d->pixsize */
+uniform float pixsize; /* rv3d->pixsize */
uniform float pixfactor;
float defaultpixsize = pixsize * (1000.0 / pixfactor);
@@ -23,41 +23,43 @@ out vec4 FragColor;
void main()
{
- vec2 uv = vec2(gl_FragCoord.xy);
- vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
-
- float dx = (ProjectionMatrix[3][3] == 0.0) ? (noffset[0] / (nloc.z * defaultpixsize)) : (noffset[0] / defaultpixsize);
- float dy = (ProjectionMatrix[3][3] == 0.0) ? (noffset[1] / (nloc.z * defaultpixsize)) : (noffset[1] / defaultpixsize);
-
- float stroke_depth = texelFetch(strokeDepth, ivec2(uv.xy), 0).r;
- vec4 src_pixel= texelFetch(strokeColor, ivec2(uv.xy), 0);
- vec4 offset_pixel= texelFetch(strokeColor, ivec2(uv.x - dx, uv.y - dy), 0);
- vec4 outcolor;
-
- /* is transparent */
- if (src_pixel.a == 0.0f) {
- discard;
- }
- /* check inside viewport */
- else if ((uv.x - dx < 0) || (uv.x - dx > Viewport[0])) {
- discard;
- }
- else if ((uv.y - dy < 0) || (uv.y - dy > Viewport[1])) {
- discard;
- }
- /* pixel is equal to mask color, keep */
- else if (src_pixel.rgb == mask_color.rgb) {
- discard;
- }
- else {
- if ((src_pixel.a > 0) && (offset_pixel.a > 0)) {
- discard;
- }
- else {
- outcolor = vec4(rim_color, 1.0);
- }
- }
-
- gl_FragDepth = stroke_depth;
- FragColor = outcolor;
+ vec2 uv = vec2(gl_FragCoord.xy);
+ vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
+
+ float dx = (ProjectionMatrix[3][3] == 0.0) ? (noffset[0] / (nloc.z * defaultpixsize)) :
+ (noffset[0] / defaultpixsize);
+ float dy = (ProjectionMatrix[3][3] == 0.0) ? (noffset[1] / (nloc.z * defaultpixsize)) :
+ (noffset[1] / defaultpixsize);
+
+ float stroke_depth = texelFetch(strokeDepth, ivec2(uv.xy), 0).r;
+ vec4 src_pixel = texelFetch(strokeColor, ivec2(uv.xy), 0);
+ vec4 offset_pixel = texelFetch(strokeColor, ivec2(uv.x - dx, uv.y - dy), 0);
+ vec4 outcolor;
+
+ /* is transparent */
+ if (src_pixel.a == 0.0f) {
+ discard;
+ }
+ /* check inside viewport */
+ else if ((uv.x - dx < 0) || (uv.x - dx > Viewport[0])) {
+ discard;
+ }
+ else if ((uv.y - dy < 0) || (uv.y - dy > Viewport[1])) {
+ discard;
+ }
+ /* pixel is equal to mask color, keep */
+ else if (src_pixel.rgb == mask_color.rgb) {
+ discard;
+ }
+ else {
+ if ((src_pixel.a > 0) && (offset_pixel.a > 0)) {
+ discard;
+ }
+ else {
+ outcolor = vec4(rim_color, 1.0);
+ }
+ }
+
+ gl_FragDepth = stroke_depth;
+ FragColor = outcolor;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl
index 0a7eb65d564..fa010baa32f 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl
@@ -10,89 +10,89 @@ uniform int mode;
out vec4 FragColor;
-#define MODE_NORMAL 0
-#define MODE_OVERLAY 1
-#define MODE_ADD 2
-#define MODE_SUB 3
+#define MODE_NORMAL 0
+#define MODE_OVERLAY 1
+#define MODE_ADD 2
+#define MODE_SUB 3
#define MODE_MULTIPLY 4
-#define MODE_DIVIDE 5
+#define MODE_DIVIDE 5
float overlay_color(float a, float b)
{
- float rtn;
- if (a < 0.5) {
- rtn = 2.0 * a * b;
- }
- else {
- rtn = 1.0 - 2.0 * (1.0 - a) * (1.0 - b);
- }
+ float rtn;
+ if (a < 0.5) {
+ rtn = 2.0 * a * b;
+ }
+ else {
+ rtn = 1.0 - 2.0 * (1.0 - a) * (1.0 - b);
+ }
- return rtn;
+ return rtn;
}
vec4 get_blend_color(int mode, vec4 src_color, vec4 mix_color)
{
- vec4 outcolor;
- if (mode == MODE_NORMAL) {
- outcolor = mix_color;
- }
- else if (mode == MODE_OVERLAY) {
- outcolor.r = overlay_color(src_color.r, mix_color.r);
- outcolor.g = overlay_color(src_color.g, mix_color.g);
- outcolor.b = overlay_color(src_color.b, mix_color.b);
- }
- else if (mode == MODE_ADD){
- outcolor = src_color + mix_color;
- }
- else if (mode == MODE_SUB){
- outcolor = src_color - mix_color;
- }
- else if (mode == MODE_MULTIPLY) {
- outcolor = src_color * mix_color;
- }
- else if (mode == MODE_DIVIDE) {
- outcolor = src_color / mix_color;
- }
- else {
- outcolor = mix_color;
- }
+ vec4 outcolor;
+ if (mode == MODE_NORMAL) {
+ outcolor = mix_color;
+ }
+ else if (mode == MODE_OVERLAY) {
+ outcolor.r = overlay_color(src_color.r, mix_color.r);
+ outcolor.g = overlay_color(src_color.g, mix_color.g);
+ outcolor.b = overlay_color(src_color.b, mix_color.b);
+ }
+ else if (mode == MODE_ADD) {
+ outcolor = src_color + mix_color;
+ }
+ else if (mode == MODE_SUB) {
+ outcolor = src_color - mix_color;
+ }
+ else if (mode == MODE_MULTIPLY) {
+ outcolor = src_color * mix_color;
+ }
+ else if (mode == MODE_DIVIDE) {
+ outcolor = src_color / mix_color;
+ }
+ else {
+ outcolor = mix_color;
+ }
- /* use always the alpha of source color */
+ /* use always the alpha of source color */
- outcolor.a = src_color.a;
- /* use alpha to calculate the weight of the mixed color */
- outcolor = mix(src_color, outcolor, mix_color.a);
+ outcolor.a = src_color.a;
+ /* use alpha to calculate the weight of the mixed color */
+ outcolor = mix(src_color, outcolor, mix_color.a);
- return outcolor;
+ return outcolor;
}
void main()
{
- ivec2 uv = ivec2(gl_FragCoord.xy);
+ ivec2 uv = ivec2(gl_FragCoord.xy);
- float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
- vec4 src_pixel= texelFetch(strokeColor, uv.xy, 0);
- vec4 rim_pixel= texelFetch(strokeRim, uv.xy, 0);
+ float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
+ vec4 src_pixel = texelFetch(strokeColor, uv.xy, 0);
+ vec4 rim_pixel = texelFetch(strokeRim, uv.xy, 0);
- vec4 outcolor = src_pixel;
+ vec4 outcolor = src_pixel;
- /* is transparent */
- if (src_pixel.a == 0.0f) {
- discard;
- }
- /* pixel is equal to mask color, keep */
- else if (src_pixel.rgb == mask_color.rgb) {
- outcolor = src_pixel;
- }
- else {
- if (rim_pixel.a == 0.0f) {
- outcolor = src_pixel;
- }
- else {
- outcolor = get_blend_color(mode, src_pixel, rim_pixel);
- }
- }
+ /* is transparent */
+ if (src_pixel.a == 0.0f) {
+ discard;
+ }
+ /* pixel is equal to mask color, keep */
+ else if (src_pixel.rgb == mask_color.rgb) {
+ outcolor = src_pixel;
+ }
+ else {
+ if (rim_pixel.a == 0.0f) {
+ outcolor = src_pixel;
+ }
+ else {
+ outcolor = get_blend_color(mode, src_pixel, rim_pixel);
+ }
+ }
- gl_FragDepth = stroke_depth;
- FragColor = outcolor;
+ gl_FragDepth = stroke_depth;
+ FragColor = outcolor;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_shadow_prepare_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_shadow_prepare_frag.glsl
index 8bb92f69723..d2e20feae18 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_shadow_prepare_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_shadow_prepare_frag.glsl
@@ -19,7 +19,7 @@ uniform float phase;
uniform int orientation;
uniform vec3 loc;
-uniform float pixsize; /* rv3d->pixsize */
+uniform float pixsize; /* rv3d->pixsize */
uniform float pixfactor;
#define M_PI 3.1415926535897932384626433832795
@@ -37,61 +37,62 @@ out vec4 FragColor;
/* project 3d point to 2d on screen space */
vec2 toScreenSpace(vec4 vertex)
{
- /* need to calculate ndc because this is not done by vertex shader */
- vec3 ndc = vec3(vertex).xyz / vertex.w;
+ /* need to calculate ndc because this is not done by vertex shader */
+ vec3 ndc = vec3(vertex).xyz / vertex.w;
- vec2 sc;
- sc.x = ((ndc.x + 1.0) / 2.0) * Viewport.x;
- sc.y = ((ndc.y + 1.0) / 2.0) * Viewport.y;
+ vec2 sc;
+ sc.x = ((ndc.x + 1.0) / 2.0) * Viewport.x;
+ sc.y = ((ndc.y + 1.0) / 2.0) * Viewport.y;
- return sc;
+ return sc;
}
void main()
{
- vec2 uv = vec2(gl_FragCoord.xy);
- vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
- vec2 loc2d = toScreenSpace(nloc);
-
- float dx = (ProjectionMatrix[3][3] == 0.0) ? (noffset[0] / (nloc.z * defaultpixsize)) : (noffset[0] / defaultpixsize);
- float dy = (ProjectionMatrix[3][3] == 0.0) ? (noffset[1] / (nloc.z * defaultpixsize)) : (noffset[1] / defaultpixsize);
-
-
- /* move point to new coords system */
- vec2 tpos = vec2(uv.x, uv.y) - loc2d;
-
- /* rotation */
- if (rotation != 0) {
- vec2 rotpoint = vec2((tpos.x * cosv) - (tpos.y * sinv), (tpos.x * sinv) + (tpos.y * cosv));
- tpos = rotpoint;
- }
-
- /* apply offset */
- tpos = vec2(tpos.x - dx, tpos.y - dy);
-
- /* apply scale */
- tpos.x *= 1.0 / scale[0];
- tpos.y *= 1.0 / scale[1];
-
- /* back to original coords system */
- vec2 texpos = tpos + loc2d;
-
- /* wave */
- if (orientation == HORIZONTAL) {
- float pval = (uv.x * M_PI) / Viewport[0];
- texpos.y += amplitude * sin((period * pval) + phase);
- }
- else if (orientation == VERTICAL){
- float pval = (uv.y * M_PI) / Viewport[1];
- texpos.x += amplitude * sin((period * pval) + phase);
- }
-
- vec4 src_pixel = texelFetch(strokeColor, ivec2(texpos.x, texpos.y), 0);
- /* is transparent */
- if (src_pixel.a == 0.0f) {
- discard;
- }
-
- gl_FragDepth = texelFetch(strokeDepth, ivec2(texpos.x, texpos.y), 0).r;
- FragColor = shadow_color;
+ vec2 uv = vec2(gl_FragCoord.xy);
+ vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
+ vec2 loc2d = toScreenSpace(nloc);
+
+ float dx = (ProjectionMatrix[3][3] == 0.0) ? (noffset[0] / (nloc.z * defaultpixsize)) :
+ (noffset[0] / defaultpixsize);
+ float dy = (ProjectionMatrix[3][3] == 0.0) ? (noffset[1] / (nloc.z * defaultpixsize)) :
+ (noffset[1] / defaultpixsize);
+
+ /* move point to new coords system */
+ vec2 tpos = vec2(uv.x, uv.y) - loc2d;
+
+ /* rotation */
+ if (rotation != 0) {
+ vec2 rotpoint = vec2((tpos.x * cosv) - (tpos.y * sinv), (tpos.x * sinv) + (tpos.y * cosv));
+ tpos = rotpoint;
+ }
+
+ /* apply offset */
+ tpos = vec2(tpos.x - dx, tpos.y - dy);
+
+ /* apply scale */
+ tpos.x *= 1.0 / scale[0];
+ tpos.y *= 1.0 / scale[1];
+
+ /* back to original coords system */
+ vec2 texpos = tpos + loc2d;
+
+ /* wave */
+ if (orientation == HORIZONTAL) {
+ float pval = (uv.x * M_PI) / Viewport[0];
+ texpos.y += amplitude * sin((period * pval) + phase);
+ }
+ else if (orientation == VERTICAL) {
+ float pval = (uv.y * M_PI) / Viewport[1];
+ texpos.x += amplitude * sin((period * pval) + phase);
+ }
+
+ vec4 src_pixel = texelFetch(strokeColor, ivec2(texpos.x, texpos.y), 0);
+ /* is transparent */
+ if (src_pixel.a == 0.0f) {
+ discard;
+ }
+
+ gl_FragDepth = texelFetch(strokeDepth, ivec2(texpos.x, texpos.y), 0).r;
+ FragColor = shadow_color;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_shadow_resolve_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_shadow_resolve_frag.glsl
index 0343d0d42fc..3ef11008adf 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_shadow_resolve_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_shadow_resolve_frag.glsl
@@ -10,23 +10,23 @@ out vec4 FragColor;
void main()
{
- ivec2 uv = ivec2(gl_FragCoord.xy);
+ ivec2 uv = ivec2(gl_FragCoord.xy);
- float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
- float shadow_depth = texelFetch(shadowDepth, uv.xy, 0).r;
- vec4 stroke_pixel= texelFetch(strokeColor, uv.xy, 0);
- vec4 shadow_pixel= texelFetch(shadowColor, uv.xy, 0);
+ float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
+ float shadow_depth = texelFetch(shadowDepth, uv.xy, 0).r;
+ vec4 stroke_pixel = texelFetch(strokeColor, uv.xy, 0);
+ vec4 shadow_pixel = texelFetch(shadowColor, uv.xy, 0);
- /* copy original pixel */
- vec4 outcolor = stroke_pixel;
- float outdepth = stroke_depth;
+ /* copy original pixel */
+ vec4 outcolor = stroke_pixel;
+ float outdepth = stroke_depth;
- /* if stroke is not on top, copy shadow */
- if ((stroke_pixel.a <= 0.2) && (shadow_pixel.a > 0.0)) {
- outcolor = shadow_pixel;
- outdepth = shadow_depth;
- }
+ /* if stroke is not on top, copy shadow */
+ if ((stroke_pixel.a <= 0.2) && (shadow_pixel.a > 0.0)) {
+ outcolor = shadow_pixel;
+ outdepth = shadow_depth;
+ }
- gl_FragDepth = outdepth;
- FragColor = outcolor;
+ gl_FragDepth = outdepth;
+ FragColor = outcolor;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl
index 92485987c93..b226d4f93bc 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl
@@ -10,7 +10,7 @@ uniform int radius;
uniform float angle;
uniform int transparent;
-uniform float pixsize; /* rv3d->pixsize */
+uniform float pixsize; /* rv3d->pixsize */
uniform float pixfactor;
out vec4 FragColor;
@@ -20,50 +20,51 @@ float defaultpixsize = pixsize * (1000.0 / pixfactor);
/* project 3d point to 2d on screen space */
vec2 toScreenSpace(vec4 vertex)
{
- /* need to calculate ndc because this is not done by vertex shader */
- vec3 ndc = vec3(vertex).xyz / vertex.w;
+ /* need to calculate ndc because this is not done by vertex shader */
+ vec3 ndc = vec3(vertex).xyz / vertex.w;
- vec2 sc;
- sc.x = ((ndc.x + 1.0) / 2.0) * Viewport.x;
- sc.y = ((ndc.y + 1.0) / 2.0) * Viewport.y;
+ vec2 sc;
+ sc.x = ((ndc.x + 1.0) / 2.0) * Viewport.x;
+ sc.y = ((ndc.y + 1.0) / 2.0) * Viewport.y;
- return sc;
+ return sc;
}
/* This swirl shader is a modified version of original Geeks3d.com code */
void main()
{
- vec2 uv = vec2(gl_FragCoord.xy);
- float stroke_depth;
- vec4 outcolor;
+ vec2 uv = vec2(gl_FragCoord.xy);
+ float stroke_depth;
+ vec4 outcolor;
- vec4 center3d = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
- vec2 center = toScreenSpace(center3d);
- vec2 tc = uv - center;
+ vec4 center3d = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
+ vec2 center = toScreenSpace(center3d);
+ vec2 tc = uv - center;
- float dist = length(tc);
- float pxradius = (ProjectionMatrix[3][3] == 0.0) ? (radius / (loc.z * defaultpixsize)) : (radius / defaultpixsize);
- pxradius = max(pxradius, 1);
+ float dist = length(tc);
+ float pxradius = (ProjectionMatrix[3][3] == 0.0) ? (radius / (loc.z * defaultpixsize)) :
+ (radius / defaultpixsize);
+ pxradius = max(pxradius, 1);
- if (dist <= pxradius) {
- float percent = (pxradius - dist) / pxradius;
- float theta = percent * percent * angle * 8.0;
- float s = sin(theta);
- float c = cos(theta);
- tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c)));
- tc += center;
+ if (dist <= pxradius) {
+ float percent = (pxradius - dist) / pxradius;
+ float theta = percent * percent * angle * 8.0;
+ float s = sin(theta);
+ float c = cos(theta);
+ tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c)));
+ tc += center;
- stroke_depth = texelFetch(strokeDepth, ivec2(tc), 0).r;
- outcolor = texelFetch(strokeColor, ivec2(tc), 0);
- }
- else {
- if (transparent == 1) {
- discard;
- }
- stroke_depth = texelFetch(strokeDepth, ivec2(uv), 0).r;
- outcolor = texelFetch(strokeColor, ivec2(uv), 0);
- }
+ stroke_depth = texelFetch(strokeDepth, ivec2(tc), 0).r;
+ outcolor = texelFetch(strokeColor, ivec2(tc), 0);
+ }
+ else {
+ if (transparent == 1) {
+ discard;
+ }
+ stroke_depth = texelFetch(strokeDepth, ivec2(uv), 0).r;
+ outcolor = texelFetch(strokeColor, ivec2(uv), 0);
+ }
- gl_FragDepth = stroke_depth;
- FragColor = outcolor;
+ gl_FragDepth = stroke_depth;
+ FragColor = outcolor;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl
index 04ab1557d07..0a5df9f6d77 100644
--- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl
@@ -17,28 +17,28 @@ uniform vec2 wsize;
void main()
{
- vec4 outcolor;
- ivec2 uv = ivec2(gl_FragCoord.xy);
- float stroke_depth;
-
- float value;
- if (orientation == HORIZONTAL) {
- float pval = (uv.x * M_PI) / wsize[0];
- value = amplitude * sin((period * pval) + phase);
- outcolor = texelFetch(strokeColor, ivec2(uv.x, uv.y + value), 0);
- stroke_depth = texelFetch(strokeDepth, ivec2(uv.x, uv.y + value), 0).r;
- }
- else {
- float pval = (uv.y * M_PI) / wsize[1];
- value = amplitude * sin((period * pval) + phase);
- outcolor = texelFetch(strokeColor, ivec2(uv.x + value, uv.y), 0);
- stroke_depth = texelFetch(strokeDepth, ivec2(uv.x + value, uv.y), 0).r;
- }
-
- FragColor = outcolor;
- gl_FragDepth = stroke_depth;
-
- if (outcolor.a < 0.02f) {
- discard;
- }
+ vec4 outcolor;
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+ float stroke_depth;
+
+ float value;
+ if (orientation == HORIZONTAL) {
+ float pval = (uv.x * M_PI) / wsize[0];
+ value = amplitude * sin((period * pval) + phase);
+ outcolor = texelFetch(strokeColor, ivec2(uv.x, uv.y + value), 0);
+ stroke_depth = texelFetch(strokeDepth, ivec2(uv.x, uv.y + value), 0).r;
+ }
+ else {
+ float pval = (uv.y * M_PI) / wsize[1];
+ value = amplitude * sin((period * pval) + phase);
+ outcolor = texelFetch(strokeColor, ivec2(uv.x + value, uv.y), 0);
+ stroke_depth = texelFetch(strokeDepth, ivec2(uv.x + value, uv.y), 0).r;
+ }
+
+ FragColor = outcolor;
+ gl_FragDepth = stroke_depth;
+
+ if (outcolor.a < 0.02f) {
+ discard;
+ }
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl
index cbd7a461dd3..18803bfa3fa 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl
@@ -5,8 +5,8 @@ uniform sampler2D strokeDepth;
void main()
{
- ivec2 uv = ivec2(gl_FragCoord.xy);
+ ivec2 uv = ivec2(gl_FragCoord.xy);
- gl_FragDepth = texelFetch(strokeDepth, uv, 0).r;
- FragColor = texelFetch(strokeColor, uv, 0);
+ gl_FragDepth = texelFetch(strokeDepth, uv, 0).r;
+ FragColor = texelFetch(strokeColor, uv, 0);
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl
index fdaad9890a0..0482ea50916 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl
@@ -14,144 +14,145 @@ uniform int tonemapping;
#define ON 1
#define OFF 0
-#define MODE_NORMAL 0
-#define MODE_OVERLAY 1
-#define MODE_ADD 2
-#define MODE_SUB 3
+#define MODE_NORMAL 0
+#define MODE_OVERLAY 1
+#define MODE_ADD 2
+#define MODE_SUB 3
#define MODE_MULTIPLY 4
-#define MODE_DIVIDE 5
+#define MODE_DIVIDE 5
float overlay_color(float a, float b)
{
- float rtn;
- if (a < 0.5) {
- rtn = 2.0 * a * b;
- }
- else {
- rtn = 1.0 - 2.0 * (1.0 - a) * (1.0 - b);
- }
-
- return rtn;
+ float rtn;
+ if (a < 0.5) {
+ rtn = 2.0 * a * b;
+ }
+ else {
+ rtn = 1.0 - 2.0 * (1.0 - a) * (1.0 - b);
+ }
+
+ return rtn;
}
vec4 get_blend_color(int mode, vec4 src_color, vec4 blend_color)
{
- vec4 mix_color = blend_color;
- vec4 outcolor;
-
- if (mix_color.a == 0) {
- outcolor = src_color;
- }
- else if (mode == MODE_OVERLAY) {
- mix_color.rgb = mix_color.rgb * mix_color.a * blend_opacity;
- outcolor.r = overlay_color(src_color.r, mix_color.r);
- outcolor.g = overlay_color(src_color.g, mix_color.g);
- outcolor.b = overlay_color(src_color.b, mix_color.b);
- outcolor.a = src_color.a;
- }
- else if (mode == MODE_ADD){
- mix_color.rgb = mix_color.rgb * mix_color.a * blend_opacity;
- outcolor = src_color + mix_color;
- outcolor.a = src_color.a;
- }
- else if (mode == MODE_SUB){
- outcolor = src_color - mix_color;
- outcolor.a = clamp(src_color.a - (mix_color.a * blend_opacity), 0.0, 1.0);
- }
- else if (mode == MODE_MULTIPLY) {
- /* interpolate between 1 and color using opacity */
- mix_color.rgb = mix(vec3(1,1,1), mix_color.rgb * mix_color.a, blend_opacity);
- outcolor = src_color * mix_color;
- outcolor.a = src_color.a;
- }
- else if (mode == MODE_DIVIDE) {
- mix_color.rgb = mix_color.rgb * mix_color.a * blend_opacity;
- outcolor = src_color / mix_color;
- outcolor.a = src_color.a;
- }
- else {
- outcolor = mix_color * blend_opacity;;
- outcolor.a = src_color.a;
- }
-
- return outcolor;
+ vec4 mix_color = blend_color;
+ vec4 outcolor;
+
+ if (mix_color.a == 0) {
+ outcolor = src_color;
+ }
+ else if (mode == MODE_OVERLAY) {
+ mix_color.rgb = mix_color.rgb * mix_color.a * blend_opacity;
+ outcolor.r = overlay_color(src_color.r, mix_color.r);
+ outcolor.g = overlay_color(src_color.g, mix_color.g);
+ outcolor.b = overlay_color(src_color.b, mix_color.b);
+ outcolor.a = src_color.a;
+ }
+ else if (mode == MODE_ADD) {
+ mix_color.rgb = mix_color.rgb * mix_color.a * blend_opacity;
+ outcolor = src_color + mix_color;
+ outcolor.a = src_color.a;
+ }
+ else if (mode == MODE_SUB) {
+ outcolor = src_color - mix_color;
+ outcolor.a = clamp(src_color.a - (mix_color.a * blend_opacity), 0.0, 1.0);
+ }
+ else if (mode == MODE_MULTIPLY) {
+ /* interpolate between 1 and color using opacity */
+ mix_color.rgb = mix(vec3(1, 1, 1), mix_color.rgb * mix_color.a, blend_opacity);
+ outcolor = src_color * mix_color;
+ outcolor.a = src_color.a;
+ }
+ else if (mode == MODE_DIVIDE) {
+ mix_color.rgb = mix_color.rgb * mix_color.a * blend_opacity;
+ outcolor = src_color / mix_color;
+ outcolor.a = src_color.a;
+ }
+ else {
+ outcolor = mix_color * blend_opacity;
+ ;
+ outcolor.a = src_color.a;
+ }
+
+ return outcolor;
}
float linearrgb_to_srgb(float c)
{
- if (c < 0.0031308) {
- return (c < 0.0) ? 0.0 : c * 12.92;
- }
- else {
- return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
- }
+ if (c < 0.0031308) {
+ return (c < 0.0) ? 0.0 : c * 12.92;
+ }
+ else {
+ return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
+ }
}
vec4 tone(vec4 stroke_color)
{
- if (tonemapping == 1) {
- vec4 color = vec4(0, 0, 0, stroke_color.a);
- color.r = linearrgb_to_srgb(stroke_color.r);
- color.g = linearrgb_to_srgb(stroke_color.g);
- color.b = linearrgb_to_srgb(stroke_color.b);
- return color;
- }
- else {
- return stroke_color;
- }
+ if (tonemapping == 1) {
+ vec4 color = vec4(0, 0, 0, stroke_color.a);
+ color.r = linearrgb_to_srgb(stroke_color.r);
+ color.g = linearrgb_to_srgb(stroke_color.g);
+ color.b = linearrgb_to_srgb(stroke_color.b);
+ return color;
+ }
+ else {
+ return stroke_color;
+ }
}
void main()
{
- vec4 outcolor;
- ivec2 uv = ivec2(gl_FragCoord.xy);
- vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba;
- float stroke_depth = texelFetch(strokeDepth, uv, 0).r;
-
- vec4 mix_color = texelFetch(blendColor, uv, 0).rgba;
- float mix_depth = texelFetch(blendDepth, uv, 0).r;
-
- /* premult alpha factor to remove double blend effects */
- if (stroke_color.a > 0) {
- stroke_color = vec4(vec3(stroke_color.rgb / stroke_color.a), stroke_color.a);
- }
- if (mix_color.a > 0) {
- mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
- }
-
- /* Normal mode */
- if (mode == MODE_NORMAL) {
- if (stroke_color.a > 0) {
- if (mix_color.a > 0) {
- FragColor = vec4(mix(stroke_color.rgb, mix_color.rgb, mix_color.a), stroke_color.a);
- gl_FragDepth = mix_depth;
- }
- else {
- FragColor = stroke_color;
- gl_FragDepth = stroke_depth;
- }
- }
- else {
- if (clamp_layer == ON) {
- discard;
- }
- else {
- FragColor = mix_color;
- gl_FragDepth = mix_depth;
- }
- }
- FragColor = tone(FragColor);
- return;
- }
-
- /* if not using mask, return mix color */
- if ((stroke_color.a == 0) && (clamp_layer == OFF)) {
- FragColor = tone(mix_color);
- gl_FragDepth = mix_depth;
- return;
- }
-
- /* apply blend mode */
- FragColor = tone(get_blend_color(mode, stroke_color, mix_color));
- gl_FragDepth = stroke_depth;
+ vec4 outcolor;
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+ vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba;
+ float stroke_depth = texelFetch(strokeDepth, uv, 0).r;
+
+ vec4 mix_color = texelFetch(blendColor, uv, 0).rgba;
+ float mix_depth = texelFetch(blendDepth, uv, 0).r;
+
+ /* premult alpha factor to remove double blend effects */
+ if (stroke_color.a > 0) {
+ stroke_color = vec4(vec3(stroke_color.rgb / stroke_color.a), stroke_color.a);
+ }
+ if (mix_color.a > 0) {
+ mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
+ }
+
+ /* Normal mode */
+ if (mode == MODE_NORMAL) {
+ if (stroke_color.a > 0) {
+ if (mix_color.a > 0) {
+ FragColor = vec4(mix(stroke_color.rgb, mix_color.rgb, mix_color.a), stroke_color.a);
+ gl_FragDepth = mix_depth;
+ }
+ else {
+ FragColor = stroke_color;
+ gl_FragDepth = stroke_depth;
+ }
+ }
+ else {
+ if (clamp_layer == ON) {
+ discard;
+ }
+ else {
+ FragColor = mix_color;
+ gl_FragDepth = mix_depth;
+ }
+ }
+ FragColor = tone(FragColor);
+ return;
+ }
+
+ /* if not using mask, return mix color */
+ if ((stroke_color.a == 0) && (clamp_layer == OFF)) {
+ FragColor = tone(mix_color);
+ gl_FragDepth = mix_depth;
+ return;
+ }
+
+ /* apply blend mode */
+ FragColor = tone(get_blend_color(mode, stroke_color, mix_color));
+ gl_FragDepth = stroke_depth;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl
index b3bd8e488f2..6a2a4f68dc9 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl
@@ -4,14 +4,14 @@ out vec4 fragColor;
void main()
{
- vec2 centered = mTexCoord - vec2(0.5);
- float dist_squared = dot(centered, centered);
- const float rad_squared = 0.25;
+ vec2 centered = mTexCoord - vec2(0.5);
+ float dist_squared = dot(centered, centered);
+ const float rad_squared = 0.25;
- // round point with jaggy edges
- if (dist_squared > rad_squared) {
- discard;
- }
+ // round point with jaggy edges
+ if (dist_squared > rad_squared) {
+ discard;
+ }
- fragColor = mColor;
+ fragColor = mColor;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl
index 0d2da00db66..b5d0a5bce71 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl
@@ -13,36 +13,36 @@ out vec2 mTexCoord;
/* project 3d point to 2d on screen space */
vec2 toScreenSpace(vec4 vertex)
{
- return vec2(vertex.xy / vertex.w) * Viewport;
+ return vec2(vertex.xy / vertex.w) * Viewport;
}
void main(void)
{
- vec4 P0 = gl_in[0].gl_Position;
- vec2 sp0 = toScreenSpace(P0);
+ vec4 P0 = gl_in[0].gl_Position;
+ vec2 sp0 = toScreenSpace(P0);
- float size = finalThickness[0];
+ float size = finalThickness[0];
- /* generate the triangle strip */
- mTexCoord = vec2(0, 1);
- mColor = finalColor[0];
- gl_Position = vec4(vec2(sp0.x - size, sp0.y + size) / Viewport, 0, 1.0);
- EmitVertex();
+ /* generate the triangle strip */
+ mTexCoord = vec2(0, 1);
+ mColor = finalColor[0];
+ gl_Position = vec4(vec2(sp0.x - size, sp0.y + size) / Viewport, 0, 1.0);
+ EmitVertex();
- mTexCoord = vec2(0, 0);
- mColor = finalColor[0];
- gl_Position = vec4(vec2(sp0.x - size, sp0.y - size) / Viewport, 0, 1.0);
- EmitVertex();
+ mTexCoord = vec2(0, 0);
+ mColor = finalColor[0];
+ gl_Position = vec4(vec2(sp0.x - size, sp0.y - size) / Viewport, 0, 1.0);
+ EmitVertex();
- mTexCoord = vec2(1, 1);
- mColor = finalColor[0];
- gl_Position = vec4(vec2(sp0.x + size, sp0.y + size) / Viewport, 0, 1.0);
- EmitVertex();
+ mTexCoord = vec2(1, 1);
+ mColor = finalColor[0];
+ gl_Position = vec4(vec2(sp0.x + size, sp0.y + size) / Viewport, 0, 1.0);
+ EmitVertex();
- mTexCoord = vec2(1, 0);
- mColor = finalColor[0];
- gl_Position = vec4(vec2(sp0.x + size, sp0.y - size) / Viewport, 0, 1.0);
- EmitVertex();
+ mTexCoord = vec2(1, 0);
+ mColor = finalColor[0];
+ gl_Position = vec4(vec2(sp0.x + size, sp0.y - size) / Viewport, 0, 1.0);
+ EmitVertex();
- EndPrimitive();
+ EndPrimitive();
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl
index 77fdf58bea0..eea28755ae6 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl
@@ -9,7 +9,7 @@ out float finalThickness;
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 );
- finalColor = color;
- finalThickness = size;
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ finalColor = color;
+ finalThickness = size;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
index 7f3bbf17222..632c63a39aa 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
@@ -39,146 +39,172 @@ uniform vec4 wire_color;
#define GP_DRAWMODE_2D 0
#define GP_DRAWMODE_3D 1
-#define OB_WIRE 2
+#define OB_WIRE 2
#define OB_SOLID 3
-#define V3D_SHADING_MATERIAL_COLOR 0
-#define V3D_SHADING_TEXTURE_COLOR 3
+#define V3D_SHADING_MATERIAL_COLOR 0
+#define V3D_SHADING_TEXTURE_COLOR 3
in vec4 finalColor;
in vec2 texCoord_interp;
out vec4 fragColor;
#define texture2D texture
-void set_color(in vec4 color, in vec4 color2, in vec4 tcolor, in float mixv, in float factor,
- in int tmix, in int flip, out vec4 ocolor)
+void set_color(in vec4 color,
+ in vec4 color2,
+ in vec4 tcolor,
+ in float mixv,
+ in float factor,
+ in int tmix,
+ in int flip,
+ out vec4 ocolor)
{
- /* full color A */
- if (mixv == 1.0) {
- if (tmix == 1) {
- ocolor = (flip == 0) ? color : tcolor;
- }
- else {
- ocolor = (flip == 0) ? color : color2;
- }
- }
- /* full color B */
- else if (mixv == 0.0) {
- if (tmix == 1) {
- ocolor = (flip == 0) ? tcolor : color;
- }
- else {
- ocolor = (flip == 0) ? color2 : color;
- }
- }
- /* mix of colors */
- else {
- if (tmix == 1) {
- ocolor = (flip == 0) ? mix(color, tcolor, factor) : mix(tcolor, color, factor);
- }
- else {
- ocolor = (flip == 0) ? mix(color, color2, factor) : mix(color2, color, factor);
- }
- }
- ocolor.a *= layer_opacity;
+ /* full color A */
+ if (mixv == 1.0) {
+ if (tmix == 1) {
+ ocolor = (flip == 0) ? color : tcolor;
+ }
+ else {
+ ocolor = (flip == 0) ? color : color2;
+ }
+ }
+ /* full color B */
+ else if (mixv == 0.0) {
+ if (tmix == 1) {
+ ocolor = (flip == 0) ? tcolor : color;
+ }
+ else {
+ ocolor = (flip == 0) ? color2 : color;
+ }
+ }
+ /* mix of colors */
+ else {
+ if (tmix == 1) {
+ ocolor = (flip == 0) ? mix(color, tcolor, factor) : mix(tcolor, color, factor);
+ }
+ else {
+ ocolor = (flip == 0) ? mix(color, color2, factor) : mix(color2, color, factor);
+ }
+ }
+ ocolor.a *= layer_opacity;
}
void main()
{
- vec2 t_center = vec2(0.5, 0.5);
- mat2 matrot_tex = mat2(cos(texture_angle), -sin(texture_angle), sin(texture_angle), cos(texture_angle));
- vec2 rot_tex = (matrot_tex * (texCoord_interp - t_center)) + t_center + texture_offset;
- vec4 tmp_color;
- tmp_color = (texture_clamp == 0) ? texture2D(myTexture, rot_tex * texture_scale) : texture2D(myTexture, clamp(rot_tex * texture_scale, 0.0, 1.0));
- vec4 text_color = vec4(tmp_color[0], tmp_color[1], tmp_color[2], tmp_color[3] * texture_opacity);
- vec4 chesscolor;
-
- /* wireframe with x-ray discard */
- if ((viewport_xray == 1) && (shading_type[0] == OB_WIRE)) {
- discard;
- }
-
- /* solid fill */
- if (fill_type == SOLID) {
- fragColor = finalColor;
- }
- else {
- vec2 center = vec2(0.5, 0.5) + gradient_shift;
- mat2 matrot = mat2(cos(gradient_angle), -sin(gradient_angle), sin(gradient_angle), cos(gradient_angle));
- vec2 rot = (((matrot * (texCoord_interp - center)) + center) * gradient_scale) + gradient_shift;
- /* gradient */
- if (fill_type == GRADIENT) {
- set_color(finalColor, color2, text_color, mix_factor, rot.x - mix_factor + 0.5, texture_mix, texture_flip, fragColor);
- }
- /* radial gradient */
- if (fill_type == RADIAL) {
- float in_rad = gradient_radius * mix_factor;
- float ex_rad = gradient_radius - in_rad;
- float intensity = 0;
- float distance = length((center - texCoord_interp) * gradient_scale);
- if (distance > gradient_radius) {
- discard;
- }
- if (distance > in_rad) {
- intensity = clamp(((distance - in_rad) / ex_rad), 0.0, 1.0);
- }
- set_color(finalColor, color2, text_color, mix_factor, intensity, texture_mix, texture_flip, fragColor);
- }
- /* chessboard */
- if (fill_type == CHESS) {
- vec2 pos = rot / pattern_gridsize;
- if ((fract(pos.x) < 0.5 && fract(pos.y) < 0.5) || (fract(pos.x) > 0.5 && fract(pos.y) > 0.5)) {
- chesscolor = (texture_flip == 0) ? finalColor : color2;
- }
- else {
- chesscolor = (texture_flip == 0) ? color2 : finalColor;
- }
- /* mix with texture */
- fragColor = (texture_mix == 1) ? mix(chesscolor, text_color, mix_factor) : chesscolor;
- fragColor.a *= layer_opacity;
- }
- /* texture */
- if (fill_type == TEXTURE) {
- fragColor = (texture_mix == 1) ? mix(text_color, finalColor, mix_factor) : text_color;
- fragColor.a *= layer_opacity;
- }
- /* pattern */
- if (fill_type == PATTERN) {
- fragColor = finalColor;
- fragColor.a = min(text_color.a, finalColor.a) * layer_opacity;
- }
- }
-
- /* set zdepth */
- if (xraymode == GP_XRAY_FRONT) {
- gl_FragDepth = 0.000001;
- }
- else if (xraymode == GP_XRAY_3DSPACE) {
- /* if 3D mode, move slightly the fill to avoid z-fighting between stroke and fill on same stroke */
- if (drawmode == GP_DRAWMODE_3D) {
- gl_FragDepth = gl_FragCoord.z * 1.0001;
- }
- else {
- gl_FragDepth = gl_FragCoord.z;
- }
- }
- else {
- gl_FragDepth = 0.000001;
- }
-
- /* if wireframe override colors */
- if (shading_type[0] == OB_WIRE) {
- fragColor = wire_color;
- }
-
- /* for solid override color */
- if (shading_type[0] == OB_SOLID) {
- if ((shading_type[1] != V3D_SHADING_MATERIAL_COLOR) && (shading_type[1] != V3D_SHADING_TEXTURE_COLOR)) {
- fragColor = wire_color;
- }
- if (viewport_xray == 1) {
- fragColor.a *= 0.5;
- }
- }
-
+ vec2 t_center = vec2(0.5, 0.5);
+ mat2 matrot_tex = mat2(
+ cos(texture_angle), -sin(texture_angle), sin(texture_angle), cos(texture_angle));
+ vec2 rot_tex = (matrot_tex * (texCoord_interp - t_center)) + t_center + texture_offset;
+ vec4 tmp_color;
+ tmp_color = (texture_clamp == 0) ?
+ texture2D(myTexture, rot_tex * texture_scale) :
+ texture2D(myTexture, clamp(rot_tex * texture_scale, 0.0, 1.0));
+ vec4 text_color = vec4(tmp_color[0], tmp_color[1], tmp_color[2], tmp_color[3] * texture_opacity);
+ vec4 chesscolor;
+
+ /* wireframe with x-ray discard */
+ if ((viewport_xray == 1) && (shading_type[0] == OB_WIRE)) {
+ discard;
+ }
+
+ /* solid fill */
+ if (fill_type == SOLID) {
+ fragColor = finalColor;
+ }
+ else {
+ vec2 center = vec2(0.5, 0.5) + gradient_shift;
+ mat2 matrot = mat2(
+ cos(gradient_angle), -sin(gradient_angle), sin(gradient_angle), cos(gradient_angle));
+ vec2 rot = (((matrot * (texCoord_interp - center)) + center) * gradient_scale) +
+ gradient_shift;
+ /* gradient */
+ if (fill_type == GRADIENT) {
+ set_color(finalColor,
+ color2,
+ text_color,
+ mix_factor,
+ rot.x - mix_factor + 0.5,
+ texture_mix,
+ texture_flip,
+ fragColor);
+ }
+ /* radial gradient */
+ if (fill_type == RADIAL) {
+ float in_rad = gradient_radius * mix_factor;
+ float ex_rad = gradient_radius - in_rad;
+ float intensity = 0;
+ float distance = length((center - texCoord_interp) * gradient_scale);
+ if (distance > gradient_radius) {
+ discard;
+ }
+ if (distance > in_rad) {
+ intensity = clamp(((distance - in_rad) / ex_rad), 0.0, 1.0);
+ }
+ set_color(finalColor,
+ color2,
+ text_color,
+ mix_factor,
+ intensity,
+ texture_mix,
+ texture_flip,
+ fragColor);
+ }
+ /* chessboard */
+ if (fill_type == CHESS) {
+ vec2 pos = rot / pattern_gridsize;
+ if ((fract(pos.x) < 0.5 && fract(pos.y) < 0.5) ||
+ (fract(pos.x) > 0.5 && fract(pos.y) > 0.5)) {
+ chesscolor = (texture_flip == 0) ? finalColor : color2;
+ }
+ else {
+ chesscolor = (texture_flip == 0) ? color2 : finalColor;
+ }
+ /* mix with texture */
+ fragColor = (texture_mix == 1) ? mix(chesscolor, text_color, mix_factor) : chesscolor;
+ fragColor.a *= layer_opacity;
+ }
+ /* texture */
+ if (fill_type == TEXTURE) {
+ fragColor = (texture_mix == 1) ? mix(text_color, finalColor, mix_factor) : text_color;
+ fragColor.a *= layer_opacity;
+ }
+ /* pattern */
+ if (fill_type == PATTERN) {
+ fragColor = finalColor;
+ fragColor.a = min(text_color.a, finalColor.a) * layer_opacity;
+ }
+ }
+
+ /* set zdepth */
+ if (xraymode == GP_XRAY_FRONT) {
+ gl_FragDepth = 0.000001;
+ }
+ else if (xraymode == GP_XRAY_3DSPACE) {
+ /* if 3D mode, move slightly the fill to avoid z-fighting between stroke and fill on same stroke */
+ if (drawmode == GP_DRAWMODE_3D) {
+ gl_FragDepth = gl_FragCoord.z * 1.0001;
+ }
+ else {
+ gl_FragDepth = gl_FragCoord.z;
+ }
+ }
+ else {
+ gl_FragDepth = 0.000001;
+ }
+
+ /* if wireframe override colors */
+ if (shading_type[0] == OB_WIRE) {
+ fragColor = wire_color;
+ }
+
+ /* for solid override color */
+ if (shading_type[0] == OB_SOLID) {
+ if ((shading_type[1] != V3D_SHADING_MATERIAL_COLOR) &&
+ (shading_type[1] != V3D_SHADING_TEXTURE_COLOR)) {
+ fragColor = wire_color;
+ }
+ if (viewport_xray == 1) {
+ fragColor.a *= 0.5;
+ }
+ }
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl
index 52da354a562..d71f57eb98c 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl
@@ -8,7 +8,7 @@ out vec2 texCoord_interp;
void main(void)
{
- gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 );
- finalColor = color;
- texCoord_interp = texCoord;
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ finalColor = color;
+ texCoord_interp = texCoord;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl
index c2e3f787bec..3c1424f98ff 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl
@@ -5,5 +5,5 @@ out vec4 FragColor;
void main()
{
- FragColor = vec4(color, opacity);
+ FragColor = vec4(color, opacity);
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl
index ca8c888fe21..c8af822bc9e 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl
@@ -11,62 +11,62 @@ out vec4 fragColor;
#define texture2D texture
-#define GPENCIL_MODE_LINE 0
-#define GPENCIL_MODE_DOTS 1
-#define GPENCIL_MODE_BOX 2
+#define GPENCIL_MODE_LINE 0
+#define GPENCIL_MODE_DOTS 1
+#define GPENCIL_MODE_BOX 2
/* keep this list synchronized with list in gpencil_engine.h */
-#define GPENCIL_COLOR_SOLID 0
+#define GPENCIL_COLOR_SOLID 0
#define GPENCIL_COLOR_TEXTURE 1
#define GPENCIL_COLOR_PATTERN 2
/* Function to check the point inside ellipse */
-float checkpoint(vec2 pt, vec2 radius)
-{
- float p = (pow(pt.x, 2) / pow(radius.x, 2)) + (pow(pt.y, 2) / pow(radius.y, 2));
-
- return p;
-}
+float checkpoint(vec2 pt, vec2 radius)
+{
+ float p = (pow(pt.x, 2) / pow(radius.x, 2)) + (pow(pt.y, 2) / pow(radius.y, 2));
+
+ return p;
+}
void main()
{
- vec2 centered = mTexCoord - vec2(0.5);
- float ellip = checkpoint(centered, vec2(gradient_s / 2.0));
+ vec2 centered = mTexCoord - vec2(0.5);
+ float ellip = checkpoint(centered, vec2(gradient_s / 2.0));
+
+ if (mode != GPENCIL_MODE_BOX) {
+ if (ellip > 1.0) {
+ discard;
+ }
+ }
+
+ vec4 tmp_color = texture2D(myTexture, mTexCoord);
- if (mode != GPENCIL_MODE_BOX) {
- if (ellip > 1.0) {
- discard;
- }
- }
+ /* Solid */
+ if (color_type == GPENCIL_COLOR_SOLID) {
+ fragColor = mColor;
+ }
+ /* texture */
+ if (color_type == GPENCIL_COLOR_TEXTURE) {
+ fragColor = texture2D(myTexture, mTexCoord);
+ /* mult both alpha factor to use strength factor with texture */
+ fragColor.a = min(fragColor.a * mColor.a, fragColor.a);
+ }
+ /* pattern */
+ if (color_type == GPENCIL_COLOR_PATTERN) {
+ vec4 text_color = texture2D(myTexture, mTexCoord);
+ fragColor = mColor;
+ /* mult both alpha factor to use strength factor with color alpha limit */
+ fragColor.a = min(text_color.a * mColor.a, mColor.a);
+ }
- vec4 tmp_color = texture2D(myTexture, mTexCoord);
+ if ((mode == GPENCIL_MODE_DOTS) && (gradient_f < 1.0)) {
+ float dist = length(centered) * 2;
+ float decay = dist * (1.0 - gradient_f) * fragColor.a;
+ fragColor.a = clamp(fragColor.a - decay, 0.0, 1.0);
+ fragColor.a = fragColor.a * (1.0 - ellip);
+ }
- /* Solid */
- if (color_type == GPENCIL_COLOR_SOLID) {
- fragColor = mColor;
- }
- /* texture */
- if (color_type == GPENCIL_COLOR_TEXTURE) {
- fragColor = texture2D(myTexture, mTexCoord);
- /* mult both alpha factor to use strength factor with texture */
- fragColor.a = min(fragColor.a * mColor.a, fragColor.a);
- }
- /* pattern */
- if (color_type == GPENCIL_COLOR_PATTERN) {
- vec4 text_color = texture2D(myTexture, mTexCoord);
- fragColor = mColor;
- /* mult both alpha factor to use strength factor with color alpha limit */
- fragColor.a = min(text_color.a * mColor.a, mColor.a);
- }
-
- if ((mode == GPENCIL_MODE_DOTS) && (gradient_f < 1.0)) {
- float dist = length(centered) * 2;
- float decay = dist * (1.0 - gradient_f) * fragColor.a;
- fragColor.a = clamp(fragColor.a - decay, 0.0, 1.0);
- fragColor.a = fragColor.a * (1.0 - ellip);
- }
-
- if(fragColor.a < 0.0035) {
- discard;
- }
+ if (fragColor.a < 0.0035) {
+ discard;
+ }
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
index 32aaa057298..2fb48ac5147 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
@@ -17,124 +17,124 @@ out vec2 mTexCoord;
#define GP_XRAY_FRONT 0
#define GP_XRAY_3DSPACE 1
-#define M_PI 3.14159265358979323846 /* pi */
-#define M_2PI 6.28318530717958647692 /* 2*pi */
-#define FALSE 0
+#define M_PI 3.14159265358979323846 /* pi */
+#define M_2PI 6.28318530717958647692 /* 2*pi */
+#define FALSE 0
/* project 3d point to 2d on screen space */
vec2 toScreenSpace(vec4 vertex)
{
- return vec2(vertex.xy / vertex.w) * Viewport;
+ return vec2(vertex.xy / vertex.w) * Viewport;
}
/* get zdepth value */
float getZdepth(vec4 point)
{
- if (xraymode == GP_XRAY_FRONT) {
- return 0.000001;
- }
- if (xraymode == GP_XRAY_3DSPACE) {
- return (point.z / point.w);
- }
-
- /* in front by default */
- return 0.000001;
+ if (xraymode == GP_XRAY_FRONT) {
+ return 0.000001;
+ }
+ if (xraymode == GP_XRAY_3DSPACE) {
+ return (point.z / point.w);
+ }
+
+ /* in front by default */
+ return 0.000001;
}
vec2 rotateUV(vec2 uv, float angle)
{
- /* translate center of rotation to the center of texture */
- vec2 new_uv = uv - vec2(0.5f, 0.5f);
- vec2 rot_uv;
- rot_uv.x = new_uv.x * cos(angle) - new_uv.y * sin(angle);
- rot_uv.y = new_uv.y * cos(angle) + new_uv.x * sin(angle);
- return rot_uv + vec2(0.5f, 0.5f);
+ /* translate center of rotation to the center of texture */
+ vec2 new_uv = uv - vec2(0.5f, 0.5f);
+ vec2 rot_uv;
+ rot_uv.x = new_uv.x * cos(angle) - new_uv.y * sin(angle);
+ rot_uv.y = new_uv.y * cos(angle) + new_uv.x * sin(angle);
+ return rot_uv + vec2(0.5f, 0.5f);
}
vec2 rotatePoint(vec2 center, vec2 point, float angle)
{
- /* translate center of rotation to the center */
- vec2 new_point = point - center;
- vec2 rot_point;
- rot_point.x = new_point.x * cos(angle) - new_point.y * sin(angle);
- rot_point.y = new_point.y * cos(angle) + new_point.x * sin(angle);
- return rot_point + center;
+ /* translate center of rotation to the center */
+ vec2 new_point = point - center;
+ vec2 rot_point;
+ rot_point.x = new_point.x * cos(angle) - new_point.y * sin(angle);
+ rot_point.y = new_point.y * cos(angle) + new_point.x * sin(angle);
+ return rot_point + center;
}
/* Calculate angle of the stroke using previous point as reference.
* The angle is calculated using the x axis (1, 0) as 0 degrees */
float getAngle(vec2 pt0, vec2 pt1)
{
- /* do not rotate one point only (no reference to rotate) */
- if (pt0 == pt1) {
- return 0.0;
- }
-
- if (use_follow_path == FALSE) {
- return 0.0;
- }
-
- /* default horizontal line (x-axis) in screen space */
- vec2 v0 = vec2(1.0, 0.0);
-
- /* vector of direction */
- vec2 vn = vec2(normalize(pt1 - pt0));
-
- /* angle signed (function ported from angle_signed_v2v2) */
- float perp_dot = (v0[1] * vn[0]) - (v0[0] * vn[1]);
- float angle = atan(perp_dot, dot(v0, vn));
-
- /* get full circle rotation */
- if (angle > 0.0) {
- angle = M_PI + (M_PI - angle);
- }
- else {
- angle *= -1.0;
- }
-
- return angle;
+ /* do not rotate one point only (no reference to rotate) */
+ if (pt0 == pt1) {
+ return 0.0;
+ }
+
+ if (use_follow_path == FALSE) {
+ return 0.0;
+ }
+
+ /* default horizontal line (x-axis) in screen space */
+ vec2 v0 = vec2(1.0, 0.0);
+
+ /* vector of direction */
+ vec2 vn = vec2(normalize(pt1 - pt0));
+
+ /* angle signed (function ported from angle_signed_v2v2) */
+ float perp_dot = (v0[1] * vn[0]) - (v0[0] * vn[1]);
+ float angle = atan(perp_dot, dot(v0, vn));
+
+ /* get full circle rotation */
+ if (angle > 0.0) {
+ angle = M_PI + (M_PI - angle);
+ }
+ else {
+ angle *= -1.0;
+ }
+
+ return angle;
}
void main(void)
{
- /* receive points */
- vec4 P0 = gl_in[0].gl_Position;
- vec2 sp0 = toScreenSpace(P0);
-
- vec4 P1 = finalprev_pos[0];
- vec2 sp1 = toScreenSpace(P1);
- vec2 point;
-
- float size = finalThickness[0];
- vec2 center = vec2(sp0.x, sp0.y);
-
- /* get angle of stroke to rotate texture */
- float angle = getAngle(sp0, sp1);
-
- /* generate the triangle strip */
- mTexCoord = rotateUV(vec2(0, 1), finaluvdata[0].y);
- mColor = finalColor[0];
- point = rotatePoint(center, vec2(sp0.x - size, sp0.y + size), angle);
- gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
- EmitVertex();
-
- mTexCoord = rotateUV(vec2(0, 0), finaluvdata[0].y);
- mColor = finalColor[0];
- point = rotatePoint(center, vec2(sp0.x - size, sp0.y - size), angle);
- gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
- EmitVertex();
-
- mTexCoord = rotateUV(vec2(1, 1), finaluvdata[0].y);
- mColor = finalColor[0];
- point = rotatePoint(center, vec2(sp0.x + size, sp0.y + size), angle);
- gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
- EmitVertex();
-
- mTexCoord = rotateUV(vec2(1, 0), finaluvdata[0].y);
- mColor = finalColor[0];
- point = rotatePoint(center, vec2(sp0.x + size, sp0.y - size), angle);
- gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
- EmitVertex();
-
- EndPrimitive();
+ /* receive points */
+ vec4 P0 = gl_in[0].gl_Position;
+ vec2 sp0 = toScreenSpace(P0);
+
+ vec4 P1 = finalprev_pos[0];
+ vec2 sp1 = toScreenSpace(P1);
+ vec2 point;
+
+ float size = finalThickness[0];
+ vec2 center = vec2(sp0.x, sp0.y);
+
+ /* get angle of stroke to rotate texture */
+ float angle = getAngle(sp0, sp1);
+
+ /* generate the triangle strip */
+ mTexCoord = rotateUV(vec2(0, 1), finaluvdata[0].y);
+ mColor = finalColor[0];
+ point = rotatePoint(center, vec2(sp0.x - size, sp0.y + size), angle);
+ gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
+ EmitVertex();
+
+ mTexCoord = rotateUV(vec2(0, 0), finaluvdata[0].y);
+ mColor = finalColor[0];
+ point = rotatePoint(center, vec2(sp0.x - size, sp0.y - size), angle);
+ gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
+ EmitVertex();
+
+ mTexCoord = rotateUV(vec2(1, 1), finaluvdata[0].y);
+ mColor = finalColor[0];
+ point = rotatePoint(center, vec2(sp0.x + size, sp0.y + size), angle);
+ gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
+ EmitVertex();
+
+ mTexCoord = rotateUV(vec2(1, 0), finaluvdata[0].y);
+ mColor = finalColor[0];
+ point = rotatePoint(center, vec2(sp0.x + size, sp0.y - size), angle);
+ gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
+ EmitVertex();
+
+ EndPrimitive();
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
index 7deca544176..92c9acf1f2a 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
@@ -1,7 +1,7 @@
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ProjectionMatrix;
-uniform float pixsize; /* rv3d->pixsize */
+uniform float pixsize; /* rv3d->pixsize */
uniform int keep_size;
uniform float objscale;
uniform float pixfactor;
@@ -22,42 +22,44 @@ out vec4 finalprev_pos;
#define TRUE 1
-#define OB_WIRE 2
+#define OB_WIRE 2
#define OB_SOLID 3
-#define V3D_SHADING_MATERIAL_COLOR 0
-#define V3D_SHADING_TEXTURE_COLOR 3
+#define V3D_SHADING_MATERIAL_COLOR 0
+#define V3D_SHADING_TEXTURE_COLOR 3
float defaultpixsize = pixsize * (1000.0 / pixfactor);
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
- finalprev_pos = ModelViewProjectionMatrix * vec4(prev_pos, 1.0);
- finalColor = color;
-
- if (keep_size == TRUE) {
- finalThickness = thickness;
- }
- else {
- float size = (ProjectionMatrix[3][3] == 0.0) ? (thickness / (gl_Position.z * defaultpixsize)) : (thickness / defaultpixsize);
- finalThickness = max(size * objscale, 4.0); /* minimum 4 pixels */
- }
-
- /* for wireframe override size and color */
- if (shading_type[0] == OB_WIRE) {
- finalThickness = 2.0;
- finalColor = wire_color;
- }
- /* for solid override color */
- if (shading_type[0] == OB_SOLID) {
- if ((shading_type[1] != V3D_SHADING_MATERIAL_COLOR) && (shading_type[1] != V3D_SHADING_TEXTURE_COLOR)) {
- finalColor = wire_color;
- }
- if (viewport_xray == 1) {
- finalColor.a *= 0.5;
- }
- }
-
- finaluvdata = uvdata;
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ finalprev_pos = ModelViewProjectionMatrix * vec4(prev_pos, 1.0);
+ finalColor = color;
+
+ if (keep_size == TRUE) {
+ finalThickness = thickness;
+ }
+ else {
+ float size = (ProjectionMatrix[3][3] == 0.0) ? (thickness / (gl_Position.z * defaultpixsize)) :
+ (thickness / defaultpixsize);
+ finalThickness = max(size * objscale, 4.0); /* minimum 4 pixels */
+ }
+
+ /* for wireframe override size and color */
+ if (shading_type[0] == OB_WIRE) {
+ finalThickness = 2.0;
+ finalColor = wire_color;
+ }
+ /* for solid override color */
+ if (shading_type[0] == OB_SOLID) {
+ if ((shading_type[1] != V3D_SHADING_MATERIAL_COLOR) &&
+ (shading_type[1] != V3D_SHADING_TEXTURE_COLOR)) {
+ finalColor = wire_color;
+ }
+ if (viewport_xray == 1) {
+ finalColor.a *= 0.5;
+ }
+ }
+
+ finaluvdata = uvdata;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl
index dd54e38c3d0..2f4429a858f 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl
@@ -6,10 +6,10 @@ uniform sampler2D strokeColor;
uniform sampler2D strokeDepth;
void main()
{
- ivec2 uv = ivec2(gl_FragCoord.xy);
- float stroke_depth = texelFetch(strokeDepth, uv, 0).r;
- vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba;
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+ float stroke_depth = texelFetch(strokeDepth, uv, 0).r;
+ vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba;
- FragColor = stroke_color;
- gl_FragDepth = stroke_depth;
+ FragColor = stroke_color;
+ gl_FragDepth = stroke_depth;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl
index a49a6e84f17..35d07306361 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl
@@ -12,7 +12,7 @@ out vec4 fragColor;
#define texture2D texture
/* keep this list synchronized with list in gpencil_engine.h */
-#define GPENCIL_COLOR_SOLID 0
+#define GPENCIL_COLOR_SOLID 0
#define GPENCIL_COLOR_TEXTURE 1
#define GPENCIL_COLOR_PATTERN 2
@@ -20,53 +20,53 @@ out vec4 fragColor;
void main()
{
-
- vec4 tColor = vec4(mColor);
- /* if uvfac[1] == 1, then encap */
- if (uvfac[1] == ENDCAP) {
- vec2 center = vec2(uvfac[0], 0.5);
- float dist = length(mTexCoord - center);
- if (dist > 0.50) {
- discard;
- }
- }
- /* Solid */
- if (color_type == GPENCIL_COLOR_SOLID) {
- fragColor = tColor;
- }
- /* texture for endcaps */
- vec4 text_color;
- if (uvfac[1] == ENDCAP) {
- text_color = texture2D(myTexture, vec2(mTexCoord.x, mTexCoord.y));
- }
- else {
- text_color = texture2D(myTexture, mTexCoord);
- }
+ vec4 tColor = vec4(mColor);
+ /* if uvfac[1] == 1, then encap */
+ if (uvfac[1] == ENDCAP) {
+ vec2 center = vec2(uvfac[0], 0.5);
+ float dist = length(mTexCoord - center);
+ if (dist > 0.50) {
+ discard;
+ }
+ }
+ /* Solid */
+ if (color_type == GPENCIL_COLOR_SOLID) {
+ fragColor = tColor;
+ }
- /* texture */
- if (color_type == GPENCIL_COLOR_TEXTURE) {
- fragColor = text_color;
- /* mult both alpha factor to use strength factor */
- fragColor.a = min(fragColor.a * tColor.a, fragColor.a);
- }
- /* pattern */
- if (color_type == GPENCIL_COLOR_PATTERN) {
- fragColor = tColor;
- /* mult both alpha factor to use strength factor with color alpha limit */
- fragColor.a = min(text_color.a * tColor.a, tColor.a);
- }
+ /* texture for endcaps */
+ vec4 text_color;
+ if (uvfac[1] == ENDCAP) {
+ text_color = texture2D(myTexture, vec2(mTexCoord.x, mTexCoord.y));
+ }
+ else {
+ text_color = texture2D(myTexture, mTexCoord);
+ }
- /* gradient */
- /* keep this disabled while the line glitch bug exists
- if (gradient_f < 1.0) {
- float d = abs(mTexCoord.y - 0.5) * (1.1 - gradient_f);
- float alpha = 1.0 - clamp((fragColor.a - (d * 2.0)), 0.03, 1.0);
- fragColor.a = smoothstep(fragColor.a, 0.0, alpha);
-
- }
- */
+ /* texture */
+ if (color_type == GPENCIL_COLOR_TEXTURE) {
+ fragColor = text_color;
+ /* mult both alpha factor to use strength factor */
+ fragColor.a = min(fragColor.a * tColor.a, fragColor.a);
+ }
+ /* pattern */
+ if (color_type == GPENCIL_COLOR_PATTERN) {
+ fragColor = tColor;
+ /* mult both alpha factor to use strength factor with color alpha limit */
+ fragColor.a = min(text_color.a * tColor.a, tColor.a);
+ }
- if(fragColor.a < 0.0035)
- discard;
+ /* gradient */
+ /* keep this disabled while the line glitch bug exists
+ if (gradient_f < 1.0) {
+ float d = abs(mTexCoord.y - 0.5) * (1.1 - gradient_f);
+ float alpha = 1.0 - clamp((fragColor.a - (d * 2.0)), 0.03, 1.0);
+ fragColor.a = smoothstep(fragColor.a, 0.0, alpha);
+
+ }
+ */
+
+ if (fragColor.a < 0.0035)
+ discard;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl
index aa38ff26a62..7e62d6f0d64 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl
@@ -19,7 +19,7 @@ out vec2 uvfac;
#define GP_XRAY_3DSPACE 1
/* keep this list synchronized with list in gpencil_engine.h */
-#define GPENCIL_COLOR_SOLID 0
+#define GPENCIL_COLOR_SOLID 0
#define GPENCIL_COLOR_TEXTURE 1
#define GPENCIL_COLOR_PATTERN 2
@@ -28,222 +28,229 @@ out vec2 uvfac;
/* project 3d point to 2d on screen space */
vec2 toScreenSpace(vec4 vertex)
{
- return vec2(vertex.xy / vertex.w) * Viewport;
+ return vec2(vertex.xy / vertex.w) * Viewport;
}
/* get zdepth value */
float getZdepth(vec4 point)
{
- if (xraymode == GP_XRAY_FRONT) {
- return 0.000001;
- }
- if (xraymode == GP_XRAY_3DSPACE) {
- return (point.z / point.w);
- }
-
- /* in front by default */
- return 0.000001;
+ if (xraymode == GP_XRAY_FRONT) {
+ return 0.000001;
+ }
+ if (xraymode == GP_XRAY_3DSPACE) {
+ return (point.z / point.w);
+ }
+
+ /* in front by default */
+ return 0.000001;
}
/* check equality but with a small tolerance */
bool is_equal(vec4 p1, vec4 p2)
{
- float limit = 0.0001;
- float x = abs(p1.x - p2.x);
- float y = abs(p1.y - p2.y);
- float z = abs(p1.z - p2.z);
+ float limit = 0.0001;
+ float x = abs(p1.x - p2.x);
+ float y = abs(p1.y - p2.y);
+ float z = abs(p1.z - p2.z);
- if ((x < limit) && (y < limit) && (z < limit)) {
- return true;
- }
+ if ((x < limit) && (y < limit) && (z < limit)) {
+ return true;
+ }
- return false;
+ return false;
}
void main(void)
{
- float MiterLimit = 0.75;
- uvfac = vec2(0.0, 0.0);
-
- /* receive 4 points */
- vec4 P0 = gl_in[0].gl_Position;
- vec4 P1 = gl_in[1].gl_Position;
- vec4 P2 = gl_in[2].gl_Position;
- vec4 P3 = gl_in[3].gl_Position;
-
- /* get the four vertices passed to the shader */
- vec2 sp0 = toScreenSpace(P0); // start of previous segment
- vec2 sp1 = toScreenSpace(P1); // end of previous segment, start of current segment
- vec2 sp2 = toScreenSpace(P2); // end of current segment, start of next segment
- vec2 sp3 = toScreenSpace(P3); // end of next segment
-
- /* culling outside viewport */
- vec2 area = Viewport * 4.0;
- if (sp1.x < -area.x || sp1.x > area.x) return;
- if (sp1.y < -area.y || sp1.y > area.y) return;
- if (sp2.x < -area.x || sp2.x > area.x) return;
- if (sp2.y < -area.y || sp2.y > area.y) return;
-
- /* culling behind camera */
- if (P1.w < 0 || P2.w < 0) return;
-
- /* determine the direction of each of the 3 segments (previous, current, next) */
- vec2 v0 = normalize(sp1 - sp0);
- vec2 v1 = normalize(sp2 - sp1);
- vec2 v2 = normalize(sp3 - sp2);
-
- /* determine the normal of each of the 3 segments (previous, current, next) */
- vec2 n0 = vec2(-v0.y, v0.x);
- vec2 n1 = vec2(-v1.y, v1.x);
- vec2 n2 = vec2(-v2.y, v2.x);
-
- /* determine miter lines by averaging the normals of the 2 segments */
- vec2 miter_a = normalize(n0 + n1); // miter at start of current segment
- vec2 miter_b = normalize(n1 + n2); // miter at end of current segment
-
- /* determine the length of the miter by projecting it onto normal and then inverse it */
- float an1 = dot(miter_a, n1);
- float bn1 = dot(miter_b, n2);
- if (an1 == 0) an1 = 1;
- if (bn1 == 0) bn1 = 1;
- float length_a = finalThickness[1] / an1;
- float length_b = finalThickness[2] / bn1;
- if (length_a <= 0.0) length_a = 0.01;
- if (length_b <= 0.0) length_b = 0.01;
-
- /* prevent excessively long miters at sharp corners */
- if (dot(v0, v1) < -MiterLimit) {
- miter_a = n1;
- length_a = finalThickness[1];
-
- /* close the gap */
- if (dot(v0, n1) > 0) {
- mTexCoord = vec2(0, 0);
- mColor = finalColor[1];
- gl_Position = vec4((sp1 + finalThickness[1] * n0) / Viewport, getZdepth(P1), 1.0);
- EmitVertex();
-
- mTexCoord = vec2(0, 0);
- mColor = finalColor[1];
- gl_Position = vec4((sp1 + finalThickness[1] * n1) / Viewport, getZdepth(P1), 1.0);
- EmitVertex();
-
- mTexCoord = vec2(0, 0.5);
- mColor = finalColor[1];
- gl_Position = vec4(sp1 / Viewport, getZdepth(P1), 1.0);
- EmitVertex();
-
- EndPrimitive();
- }
- else {
- mTexCoord = vec2(0, 1);
- mColor = finalColor[1];
- gl_Position = vec4((sp1 - finalThickness[1] * n1) / Viewport, getZdepth(P1), 1.0);
- EmitVertex();
-
- mTexCoord = vec2(0, 1);
- mColor = finalColor[1];
- gl_Position = vec4((sp1 - finalThickness[1] * n0) / Viewport, getZdepth(P1), 1.0);
- EmitVertex();
-
- mTexCoord = vec2(0, 0.5);
- mColor = finalColor[1];
- gl_Position = vec4(sp1 / Viewport, getZdepth(P1), 1.0);
- EmitVertex();
-
- EndPrimitive();
- }
- }
-
- if (dot(v1, v2) < -MiterLimit) {
- miter_b = n1;
- length_b = finalThickness[2];
- }
-
- /* generate the start endcap */
- if ((caps_mode[0] != GPENCIL_FLATCAP) && is_equal(P0,P2))
- {
- vec4 cap_color = finalColor[1];
-
- mTexCoord = vec2(2.0, 0.5);
- mColor = cap_color;
- vec2 svn1 = normalize(sp1 - sp2) * length_a * 4.0;
- uvfac = vec2(0.0, 1.0);
- gl_Position = vec4((sp1 + svn1) / Viewport, getZdepth(P1), 1.0);
- EmitVertex();
-
- mTexCoord = vec2(0.0, -0.5);
- mColor = cap_color;
- uvfac = vec2(0.0, 1.0);
- gl_Position = vec4((sp1 - (length_a * 2.0) * miter_a) / Viewport, getZdepth(P1), 1.0);
- EmitVertex();
-
- mTexCoord = vec2(0.0, 1.5);
- mColor = cap_color;
- uvfac = vec2(0.0, 1.0);
- gl_Position = vec4((sp1 + (length_a * 2.0) * miter_a) / Viewport, getZdepth(P1), 1.0);
- EmitVertex();
- }
-
- float y_a = 0.0;
- float y_b = 1.0;
-
- /* invert uv (vertical) */
- if (finaluvdata[2].x > 1.0) {
- if ((finaluvdata[1].y != 0.0) && (finaluvdata[2].y != 0.0)) {
- float d = ceil(finaluvdata[2].x) - 1.0;
- if (floor(d / 2.0) == (d / 2.0)) {
- y_a = 1.0;
- y_b = 0.0;
- }
- }
- }
- /* generate the triangle strip */
- uvfac = vec2(0.0, 0.0);
- mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(0, 0) : vec2(finaluvdata[1].x, y_a);
- mColor = finalColor[1];
- gl_Position = vec4((sp1 + length_a * miter_a) / Viewport, getZdepth(P1), 1.0);
- EmitVertex();
-
- mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(0, 1) : vec2(finaluvdata[1].x, y_b);
- mColor = finalColor[1];
- gl_Position = vec4((sp1 - length_a * miter_a) / Viewport, getZdepth(P1), 1.0);
- EmitVertex();
-
- mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(1, 0) : vec2(finaluvdata[2].x, y_a);
- mColor = finalColor[2];
- gl_Position = vec4((sp2 + length_b * miter_b) / Viewport, getZdepth(P2), 1.0);
- EmitVertex();
-
- mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(1, 1) : vec2(finaluvdata[2].x, y_b);
- mColor = finalColor[2];
- gl_Position = vec4((sp2 - length_b * miter_b) / Viewport, getZdepth(P2), 1.0);
- EmitVertex();
-
- /* generate the end endcap */
- if ((caps_mode[1] != GPENCIL_FLATCAP) && is_equal(P1,P3) && (finaluvdata[2].x > 0))
- {
- vec4 cap_color = finalColor[2];
-
- mTexCoord = vec2(finaluvdata[2].x, 1.5);
- mColor = cap_color;
- uvfac = vec2(finaluvdata[2].x, 1.0);
- gl_Position = vec4((sp2 + (length_b * 2.0) * miter_b) / Viewport, getZdepth(P2), 1.0);
- EmitVertex();
-
- mTexCoord = vec2(finaluvdata[2].x, -0.5);
- mColor = cap_color;
- uvfac = vec2(finaluvdata[2].x, 1.0);
- gl_Position = vec4((sp2 - (length_b * 2.0) * miter_b) / Viewport, getZdepth(P2), 1.0);
- EmitVertex();
-
- mTexCoord = vec2(finaluvdata[2].x + 2, 0.5);
- mColor = cap_color;
- uvfac = vec2(finaluvdata[2].x, 1.0);
- vec2 svn2 = normalize(sp2 - sp1) * length_b * 4.0;
- gl_Position = vec4((sp2 + svn2) / Viewport, getZdepth(P2), 1.0);
- EmitVertex();
- }
-
- EndPrimitive();
+ float MiterLimit = 0.75;
+ uvfac = vec2(0.0, 0.0);
+
+ /* receive 4 points */
+ vec4 P0 = gl_in[0].gl_Position;
+ vec4 P1 = gl_in[1].gl_Position;
+ vec4 P2 = gl_in[2].gl_Position;
+ vec4 P3 = gl_in[3].gl_Position;
+
+ /* get the four vertices passed to the shader */
+ vec2 sp0 = toScreenSpace(P0); // start of previous segment
+ vec2 sp1 = toScreenSpace(P1); // end of previous segment, start of current segment
+ vec2 sp2 = toScreenSpace(P2); // end of current segment, start of next segment
+ vec2 sp3 = toScreenSpace(P3); // end of next segment
+
+ /* culling outside viewport */
+ vec2 area = Viewport * 4.0;
+ if (sp1.x < -area.x || sp1.x > area.x)
+ return;
+ if (sp1.y < -area.y || sp1.y > area.y)
+ return;
+ if (sp2.x < -area.x || sp2.x > area.x)
+ return;
+ if (sp2.y < -area.y || sp2.y > area.y)
+ return;
+
+ /* culling behind camera */
+ if (P1.w < 0 || P2.w < 0)
+ return;
+
+ /* determine the direction of each of the 3 segments (previous, current, next) */
+ vec2 v0 = normalize(sp1 - sp0);
+ vec2 v1 = normalize(sp2 - sp1);
+ vec2 v2 = normalize(sp3 - sp2);
+
+ /* determine the normal of each of the 3 segments (previous, current, next) */
+ vec2 n0 = vec2(-v0.y, v0.x);
+ vec2 n1 = vec2(-v1.y, v1.x);
+ vec2 n2 = vec2(-v2.y, v2.x);
+
+ /* determine miter lines by averaging the normals of the 2 segments */
+ vec2 miter_a = normalize(n0 + n1); // miter at start of current segment
+ vec2 miter_b = normalize(n1 + n2); // miter at end of current segment
+
+ /* determine the length of the miter by projecting it onto normal and then inverse it */
+ float an1 = dot(miter_a, n1);
+ float bn1 = dot(miter_b, n2);
+ if (an1 == 0)
+ an1 = 1;
+ if (bn1 == 0)
+ bn1 = 1;
+ float length_a = finalThickness[1] / an1;
+ float length_b = finalThickness[2] / bn1;
+ if (length_a <= 0.0)
+ length_a = 0.01;
+ if (length_b <= 0.0)
+ length_b = 0.01;
+
+ /* prevent excessively long miters at sharp corners */
+ if (dot(v0, v1) < -MiterLimit) {
+ miter_a = n1;
+ length_a = finalThickness[1];
+
+ /* close the gap */
+ if (dot(v0, n1) > 0) {
+ mTexCoord = vec2(0, 0);
+ mColor = finalColor[1];
+ gl_Position = vec4((sp1 + finalThickness[1] * n0) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0, 0);
+ mColor = finalColor[1];
+ gl_Position = vec4((sp1 + finalThickness[1] * n1) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0, 0.5);
+ mColor = finalColor[1];
+ gl_Position = vec4(sp1 / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ EndPrimitive();
+ }
+ else {
+ mTexCoord = vec2(0, 1);
+ mColor = finalColor[1];
+ gl_Position = vec4((sp1 - finalThickness[1] * n1) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0, 1);
+ mColor = finalColor[1];
+ gl_Position = vec4((sp1 - finalThickness[1] * n0) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0, 0.5);
+ mColor = finalColor[1];
+ gl_Position = vec4(sp1 / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ EndPrimitive();
+ }
+ }
+
+ if (dot(v1, v2) < -MiterLimit) {
+ miter_b = n1;
+ length_b = finalThickness[2];
+ }
+
+ /* generate the start endcap */
+ if ((caps_mode[0] != GPENCIL_FLATCAP) && is_equal(P0, P2)) {
+ vec4 cap_color = finalColor[1];
+
+ mTexCoord = vec2(2.0, 0.5);
+ mColor = cap_color;
+ vec2 svn1 = normalize(sp1 - sp2) * length_a * 4.0;
+ uvfac = vec2(0.0, 1.0);
+ gl_Position = vec4((sp1 + svn1) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0.0, -0.5);
+ mColor = cap_color;
+ uvfac = vec2(0.0, 1.0);
+ gl_Position = vec4((sp1 - (length_a * 2.0) * miter_a) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0.0, 1.5);
+ mColor = cap_color;
+ uvfac = vec2(0.0, 1.0);
+ gl_Position = vec4((sp1 + (length_a * 2.0) * miter_a) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+ }
+
+ float y_a = 0.0;
+ float y_b = 1.0;
+
+ /* invert uv (vertical) */
+ if (finaluvdata[2].x > 1.0) {
+ if ((finaluvdata[1].y != 0.0) && (finaluvdata[2].y != 0.0)) {
+ float d = ceil(finaluvdata[2].x) - 1.0;
+ if (floor(d / 2.0) == (d / 2.0)) {
+ y_a = 1.0;
+ y_b = 0.0;
+ }
+ }
+ }
+ /* generate the triangle strip */
+ uvfac = vec2(0.0, 0.0);
+ mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(0, 0) : vec2(finaluvdata[1].x, y_a);
+ mColor = finalColor[1];
+ gl_Position = vec4((sp1 + length_a * miter_a) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(0, 1) : vec2(finaluvdata[1].x, y_b);
+ mColor = finalColor[1];
+ gl_Position = vec4((sp1 - length_a * miter_a) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(1, 0) : vec2(finaluvdata[2].x, y_a);
+ mColor = finalColor[2];
+ gl_Position = vec4((sp2 + length_b * miter_b) / Viewport, getZdepth(P2), 1.0);
+ EmitVertex();
+
+ mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(1, 1) : vec2(finaluvdata[2].x, y_b);
+ mColor = finalColor[2];
+ gl_Position = vec4((sp2 - length_b * miter_b) / Viewport, getZdepth(P2), 1.0);
+ EmitVertex();
+
+ /* generate the end endcap */
+ if ((caps_mode[1] != GPENCIL_FLATCAP) && is_equal(P1, P3) && (finaluvdata[2].x > 0)) {
+ vec4 cap_color = finalColor[2];
+
+ mTexCoord = vec2(finaluvdata[2].x, 1.5);
+ mColor = cap_color;
+ uvfac = vec2(finaluvdata[2].x, 1.0);
+ gl_Position = vec4((sp2 + (length_b * 2.0) * miter_b) / Viewport, getZdepth(P2), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(finaluvdata[2].x, -0.5);
+ mColor = cap_color;
+ uvfac = vec2(finaluvdata[2].x, 1.0);
+ gl_Position = vec4((sp2 - (length_b * 2.0) * miter_b) / Viewport, getZdepth(P2), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(finaluvdata[2].x + 2, 0.5);
+ mColor = cap_color;
+ uvfac = vec2(finaluvdata[2].x, 1.0);
+ vec2 svn2 = normalize(sp2 - sp1) * length_b * 4.0;
+ gl_Position = vec4((sp2 + svn2) / Viewport, getZdepth(P2), 1.0);
+ EmitVertex();
+ }
+
+ EndPrimitive();
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl
index 62740f37ae8..946b39c006a 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl
@@ -1,7 +1,7 @@
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ProjectionMatrix;
-uniform float pixsize; /* rv3d->pixsize */
+uniform float pixsize; /* rv3d->pixsize */
uniform int keep_size;
uniform float objscale;
uniform float pixfactor;
@@ -20,41 +20,43 @@ out vec2 finaluvdata;
#define TRUE 1
-#define OB_WIRE 2
+#define OB_WIRE 2
#define OB_SOLID 3
-#define V3D_SHADING_MATERIAL_COLOR 0
-#define V3D_SHADING_TEXTURE_COLOR 3
+#define V3D_SHADING_MATERIAL_COLOR 0
+#define V3D_SHADING_TEXTURE_COLOR 3
float defaultpixsize = pixsize * (1000.0 / pixfactor);
void main(void)
{
- gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 );
- finalColor = color;
-
- if (keep_size == TRUE) {
- finalThickness = thickness;
- }
- else {
- float size = (ProjectionMatrix[3][3] == 0.0) ? (thickness / (gl_Position.z * defaultpixsize)) : (thickness / defaultpixsize);
- finalThickness = max(size * objscale, 1.0);
- }
-
- /* for wireframe override size and color */
- if (shading_type[0] == OB_WIRE) {
- finalThickness = 1.0;
- finalColor = wire_color;
- }
- /* for solid override color */
- if (shading_type[0] == OB_SOLID) {
- if ((shading_type[1] != V3D_SHADING_MATERIAL_COLOR) && (shading_type[1] != V3D_SHADING_TEXTURE_COLOR)) {
- finalColor = wire_color;
- }
- if (viewport_xray == 1) {
- finalColor.a *= 0.5;
- }
- }
-
- finaluvdata = uvdata;
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+ finalColor = color;
+
+ if (keep_size == TRUE) {
+ finalThickness = thickness;
+ }
+ else {
+ float size = (ProjectionMatrix[3][3] == 0.0) ? (thickness / (gl_Position.z * defaultpixsize)) :
+ (thickness / defaultpixsize);
+ finalThickness = max(size * objscale, 1.0);
+ }
+
+ /* for wireframe override size and color */
+ if (shading_type[0] == OB_WIRE) {
+ finalThickness = 1.0;
+ finalColor = wire_color;
+ }
+ /* for solid override color */
+ if (shading_type[0] == OB_SOLID) {
+ if ((shading_type[1] != V3D_SHADING_MATERIAL_COLOR) &&
+ (shading_type[1] != V3D_SHADING_TEXTURE_COLOR)) {
+ finalColor = wire_color;
+ }
+ if (viewport_xray == 1) {
+ finalColor.a *= 0.5;
+ }
+ }
+
+ finaluvdata = uvdata;
}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl
index a32fd87a446..be645548402 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl
@@ -10,65 +10,65 @@ uniform int do_select;
float srgb_to_linearrgb(float c)
{
- if (c < 0.04045) {
- return (c < 0.0) ? 0.0 : c * (1.0 / 12.92);
- }
- else {
- return pow((c + 0.055) * (1.0 / 1.055), 2.4);
- }
+ if (c < 0.04045) {
+ return (c < 0.0) ? 0.0 : c * (1.0 / 12.92);
+ }
+ else {
+ return pow((c + 0.055) * (1.0 / 1.055), 2.4);
+ }
}
float linearrgb_to_srgb(float c)
{
- if (c < 0.0031308) {
- return (c < 0.0) ? 0.0 : c * 12.92;
- }
- else {
- return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
- }
+ if (c < 0.0031308) {
+ return (c < 0.0) ? 0.0 : c * 12.92;
+ }
+ else {
+ return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
+ }
}
bool check_borders(ivec2 uv, int size)
{
- for (int x = -size; x <= size; x++) {
- for (int y = -size; y <= size; y++) {
- vec4 stroke_color = texelFetch(strokeColor, ivec2(uv.x + x, uv.y + y), 0).rgba;
- if (stroke_color.a > 0) {
- return true;
- }
- }
- }
+ for (int x = -size; x <= size; x++) {
+ for (int y = -size; y <= size; y++) {
+ vec4 stroke_color = texelFetch(strokeColor, ivec2(uv.x + x, uv.y + y), 0).rgba;
+ if (stroke_color.a > 0) {
+ return true;
+ }
+ }
+ }
- return false;
+ return false;
}
void main()
{
- ivec2 uv = ivec2(gl_FragCoord.xy);
- float stroke_depth = texelFetch(strokeDepth, uv, 0).r;
- vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba;
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+ float stroke_depth = texelFetch(strokeDepth, uv, 0).r;
+ vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba;
- /* premult alpha factor to remove double blend effects */
- if (stroke_color.a > 0) {
- stroke_color = vec4(vec3(stroke_color.rgb / stroke_color.a), stroke_color.a);
- }
+ /* premult alpha factor to remove double blend effects */
+ if (stroke_color.a > 0) {
+ stroke_color = vec4(vec3(stroke_color.rgb / stroke_color.a), stroke_color.a);
+ }
- /* apply color correction for render only */
- if (tonemapping == 1) {
- stroke_color.r = srgb_to_linearrgb(stroke_color.r);
- stroke_color.g = srgb_to_linearrgb(stroke_color.g);
- stroke_color.b = srgb_to_linearrgb(stroke_color.b);
- }
+ /* apply color correction for render only */
+ if (tonemapping == 1) {
+ stroke_color.r = srgb_to_linearrgb(stroke_color.r);
+ stroke_color.g = srgb_to_linearrgb(stroke_color.g);
+ stroke_color.b = srgb_to_linearrgb(stroke_color.b);
+ }
- FragColor = clamp(stroke_color, 0.0, 1.0);
- gl_FragDepth = clamp(stroke_depth, 0.0, 1.0);
+ FragColor = clamp(stroke_color, 0.0, 1.0);
+ gl_FragDepth = clamp(stroke_depth, 0.0, 1.0);
- if (do_select == 1) {
- if (stroke_color.a == 0) {
- if (check_borders(uv, 2)) {
- FragColor = select_color;
- gl_FragDepth = 0.000001;
- }
- }
- }
+ if (do_select == 1) {
+ if (stroke_color.a == 0) {
+ if (check_borders(uv, 2)) {
+ FragColor = select_color;
+ gl_FragDepth = 0.000001;
+ }
+ }
+ }
}