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-01-22 14:20:19 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-01-22 14:22:20 +0300
commit585e4848e145e5345d08bc7c97d8a7ae34bc2bb0 (patch)
treecb5e7373f73437ccc36ddb6c0b27eeb9e69ae106 /source/blender/draw/modes/paint_weight_mode.c
parent9c61107ba53b6b6728a7e1282503f5e4ee9781cd (diff)
3D View: Support vert & weight paint mask clipping
Diffstat (limited to 'source/blender/draw/modes/paint_weight_mode.c')
-rw-r--r--source/blender/draw/modes/paint_weight_mode.c106
1 files changed, 75 insertions, 31 deletions
diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c
index 87e832ef585..7ba4e70acb9 100644
--- a/source/blender/draw/modes/paint_weight_mode.c
+++ b/source/blender/draw/modes/paint_weight_mode.c
@@ -40,6 +40,8 @@
#include "DEG_depsgraph_query.h"
+extern char datatoc_common_world_clip_lib_glsl[];
+
extern char datatoc_paint_face_vert_glsl[];
extern char datatoc_paint_weight_vert_glsl[];
extern char datatoc_paint_weight_frag_glsl[];
@@ -71,13 +73,18 @@ typedef struct PAINT_WEIGHT_Data {
PAINT_WEIGHT_StorageList *stl;
} PAINT_WEIGHT_Data;
+typedef struct PAINT_WEIGHT_Shaders {
+ struct GPUShader *weight_face;
+ struct GPUShader *wire_overlay;
+ struct GPUShader *face_overlay;
+ struct GPUShader *vert_overlay;
+} PAINT_WEIGHT_Shaders;
+
/* *********** STATIC *********** */
static struct {
- struct GPUShader *weight_face_shader;
- struct GPUShader *wire_overlay_shader;
- struct GPUShader *face_overlay_shader;
- struct GPUShader *vert_overlay_shader;
+ PAINT_WEIGHT_Shaders sh_data[2];
+
int actdef;
} e_data = {NULL}; /* Engine data */
@@ -90,27 +97,47 @@ typedef struct PAINT_WEIGHT_PrivateData {
/* *********** FUNCTIONS *********** */
+static int PAINT_WEIGHT_sh_data_index_from_rv3d(const RegionView3D *rv3d)
+{
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ return 1;
+ }
+ return 0;
+}
+
static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata))
{
- if (!e_data.weight_face_shader) {
- e_data.weight_face_shader = DRW_shader_create_with_lib(
- datatoc_paint_weight_vert_glsl, NULL,
- datatoc_paint_weight_frag_glsl,
- datatoc_common_globals_lib_glsl, NULL);
-
- e_data.wire_overlay_shader = DRW_shader_create_with_lib(
- datatoc_paint_wire_vert_glsl, NULL,
- datatoc_paint_wire_frag_glsl,
- datatoc_common_globals_lib_glsl, "#define WEIGHT_MODE\n");
-
- e_data.face_overlay_shader = DRW_shader_create(
- datatoc_paint_face_vert_glsl, NULL,
- datatoc_gpu_shader_uniform_color_frag_glsl, NULL);
-
- e_data.vert_overlay_shader = DRW_shader_create_with_lib(
- datatoc_paint_wire_vert_glsl, NULL,
- datatoc_paint_vert_frag_glsl,
- datatoc_common_globals_lib_glsl, NULL);
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ PAINT_WEIGHT_Shaders *sh_data = &e_data.sh_data[PAINT_WEIGHT_sh_data_index_from_rv3d(draw_ctx->rv3d)];
+ const bool is_clip = (draw_ctx->rv3d->rflag & RV3D_CLIPPING) != 0;
+
+ if (is_clip) {
+ DRW_state_clip_planes_set_from_rv3d(draw_ctx->rv3d);
+ }
+
+ if (!sh_data->weight_face) {
+ const char *world_clip_lib_or_empty = is_clip ? datatoc_common_world_clip_lib_glsl : "";
+ const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
+
+ sh_data->weight_face = DRW_shader_create_from_arrays({
+ .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_weight_vert_glsl, NULL},
+ .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_paint_weight_frag_glsl, NULL},
+ .defs = (const char *[]){world_clip_def_or_empty, NULL}});
+
+ sh_data->wire_overlay = DRW_shader_create_from_arrays({
+ .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_wire_vert_glsl, NULL},
+ .frag = (const char *[]){datatoc_paint_wire_frag_glsl, NULL},
+ .defs = (const char *[]){world_clip_def_or_empty, "#define WEIGHT_MODE\n", NULL}});
+
+ sh_data->face_overlay = DRW_shader_create_from_arrays({
+ .vert = (const char *[]){world_clip_lib_or_empty, datatoc_paint_face_vert_glsl, NULL},
+ .frag = (const char *[]){datatoc_gpu_shader_uniform_color_frag_glsl, NULL},
+ .defs = (const char *[]){world_clip_def_or_empty, NULL}});
+
+ sh_data->vert_overlay = DRW_shader_create_from_arrays({
+ .vert = (const char *[]){world_clip_lib_or_empty, datatoc_common_globals_lib_glsl, datatoc_paint_wire_vert_glsl, NULL},
+ .frag = (const char *[]){datatoc_common_globals_lib_glsl, datatoc_paint_vert_frag_glsl, NULL},
+ .defs = (const char *[]){world_clip_def_or_empty, NULL}});
}
}
@@ -120,6 +147,8 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
const View3D *v3d = draw_ctx->v3d;
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ PAINT_WEIGHT_Shaders *sh_data = &e_data.sh_data[PAINT_WEIGHT_sh_data_index_from_rv3d(rv3d)];
if (!stl->g_data) {
/* Alloc transient pointers */
@@ -132,13 +161,16 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
"Weight Pass",
DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_MULTIPLY);
- stl->g_data->fweights_shgrp = DRW_shgroup_create(e_data.weight_face_shader, psl->weight_faces);
+ stl->g_data->fweights_shgrp = DRW_shgroup_create(sh_data->weight_face, psl->weight_faces);
DRW_shgroup_uniform_bool_copy(stl->g_data->fweights_shgrp, "drawContours", (v3d->overlay.wpaint_flag & V3D_OVERLAY_WPAINT_CONTOURS) != 0);
DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "opacity", &v3d->overlay.weight_paint_mode_opacity, 1);
DRW_shgroup_uniform_texture(stl->g_data->fweights_shgrp, "colorramp", G_draw.weight_ramp);
DRW_shgroup_uniform_block(stl->g_data->fweights_shgrp, "globalsBlock", G_draw.block_ubo);
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->fweights_shgrp, rv3d);
+ }
}
{
@@ -146,8 +178,11 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
"Wire Pass",
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_OFFSET_NEGATIVE);
- stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay);
+ stl->g_data->lwire_shgrp = DRW_shgroup_create(sh_data->wire_overlay, psl->wire_overlay);
DRW_shgroup_uniform_block(stl->g_data->lwire_shgrp, "globalsBlock", G_draw.block_ubo);
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->lwire_shgrp, rv3d);
+ }
}
{
@@ -155,10 +190,13 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
"Face Mask Pass",
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
- stl->g_data->face_shgrp = DRW_shgroup_create(e_data.face_overlay_shader, psl->face_overlay);
+ stl->g_data->face_shgrp = DRW_shgroup_create(sh_data->face_overlay, psl->face_overlay);
static float col[4] = {1.0f, 1.0f, 1.0f, 0.2f};
DRW_shgroup_uniform_vec4(stl->g_data->face_shgrp, "color", col, 1);
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->face_shgrp, rv3d);
+ }
}
{
@@ -166,8 +204,11 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
"Vert Mask Pass",
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_OFFSET_NEGATIVE);
- stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.vert_overlay_shader, psl->vert_overlay);
+ stl->g_data->vert_shgrp = DRW_shgroup_create(sh_data->vert_overlay, psl->vert_overlay);
DRW_shgroup_uniform_block(stl->g_data->vert_shgrp, "globalsBlock", G_draw.block_ubo);
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ DRW_shgroup_world_clip_planes_from_rv3d(stl->g_data->vert_shgrp, rv3d);
+ }
}
}
@@ -219,10 +260,13 @@ static void PAINT_WEIGHT_draw_scene(void *vedata)
static void PAINT_WEIGHT_engine_free(void)
{
- DRW_SHADER_FREE_SAFE(e_data.weight_face_shader);
- DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader);
- DRW_SHADER_FREE_SAFE(e_data.vert_overlay_shader);
- DRW_SHADER_FREE_SAFE(e_data.face_overlay_shader);
+ for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
+ PAINT_WEIGHT_Shaders *sh_data = &e_data.sh_data[sh_data_index];
+ GPUShader **sh_data_as_array = (GPUShader **)sh_data;
+ for (int i = 0; i < (sizeof(PAINT_WEIGHT_Shaders) / sizeof(GPUShader *)); i++) {
+ DRW_SHADER_FREE_SAFE(sh_data_as_array[i]);
+ }
+ }
}
static const DrawEngineDataSize PAINT_WEIGHT_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_WEIGHT_Data);