3D View: Support edit-mesh clipping (only verts)

We'll need to replace built-in shaders to add support for clipping.
This commit is contained in:
Campbell Barton 2019-01-22 17:23:24 +11:00
parent ee3c177dd3
commit 0bbca0e221
2 changed files with 68 additions and 18 deletions

View File

@ -35,14 +35,12 @@
#include "draw_mode_engines.h"
extern char datatoc_common_world_clip_lib_glsl[];
extern char datatoc_common_globals_lib_glsl[];
extern char datatoc_edit_lattice_overlay_loosevert_vert_glsl[];
extern char datatoc_edit_lattice_overlay_frag_glsl[];
extern char datatoc_gpu_shader_3D_vert_glsl[];
extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
extern char datatoc_gpu_shader_point_uniform_color_frag_glsl[];
/* *********** LISTS *********** */
/* All lists are per viewport specific datas.
* They are all free when viewport changes engines
@ -91,6 +89,11 @@ typedef struct EDIT_LATTICE_Data {
EDIT_LATTICE_StorageList *stl;
} EDIT_LATTICE_Data;
typedef struct EDIT_LATTICE_Shaders {
GPUShader *wire;
GPUShader *overlay_vert;
} EDIT_LATTICE_Shaders;
/* *********** STATIC *********** */
static struct {
@ -98,9 +101,9 @@ static struct {
* Add sources to source/blender/draw/modes/shaders
* init in EDIT_LATTICE_engine_init();
* free in EDIT_LATTICE_engine_free(); */
GPUShader *wire_sh;
GPUShader *overlay_vert_sh;
/* 0: normal, 1: clipped. */
EDIT_LATTICE_Shaders sh_data[2];
} e_data = {NULL}; /* Engine data */
@ -113,6 +116,14 @@ typedef struct EDIT_LATTICE_PrivateData {
/* *********** FUNCTIONS *********** */
static int EDIT_LATTICE_sh_data_index_from_rv3d(const RegionView3D *rv3d)
{
if (rv3d->rflag & RV3D_CLIPPING) {
return 1;
}
return 0;
}
/* Init Textures, Framebuffers, Storage and Shaders.
* It is called for every frames.
* (Optional) */
@ -139,15 +150,32 @@ static void EDIT_LATTICE_engine_init(void *vedata)
* tex, 2);
*/
if (!e_data.wire_sh) {
e_data.wire_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR);
const DRWContextState *draw_ctx = DRW_context_state_get();
EDIT_LATTICE_Shaders *sh_data = &e_data.sh_data[EDIT_LATTICE_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);
}
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" : "";
if (!sh_data->wire) {
sh_data->wire = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR);
}
if (!e_data.overlay_vert_sh) {
e_data.overlay_vert_sh = DRW_shader_create_with_lib(
datatoc_edit_lattice_overlay_loosevert_vert_glsl, NULL,
datatoc_edit_lattice_overlay_frag_glsl,
datatoc_common_globals_lib_glsl, NULL);
if (!sh_data->overlay_vert) {
sh_data->overlay_vert = DRW_shader_create_from_arrays({
.vert = (const char *[]){
world_clip_lib_or_empty,
datatoc_common_globals_lib_glsl,
datatoc_edit_lattice_overlay_loosevert_vert_glsl,
NULL},
.frag = (const char *[]){
datatoc_common_globals_lib_glsl,
datatoc_edit_lattice_overlay_frag_glsl,
NULL},
.defs = (const char *[]){world_clip_def_or_empty, NULL}});
}
}
@ -158,6 +186,10 @@ static void EDIT_LATTICE_cache_init(void *vedata)
EDIT_LATTICE_PassList *psl = ((EDIT_LATTICE_Data *)vedata)->psl;
EDIT_LATTICE_StorageList *stl = ((EDIT_LATTICE_Data *)vedata)->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
RegionView3D *rv3d = draw_ctx->rv3d;
EDIT_LATTICE_Shaders *sh_data = &e_data.sh_data[EDIT_LATTICE_sh_data_index_from_rv3d(rv3d)];
if (!stl->g_data) {
/* Alloc transient pointers */
stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
@ -167,14 +199,18 @@ static void EDIT_LATTICE_cache_init(void *vedata)
psl->wire_pass = DRW_pass_create(
"Lattice Wire",
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE);
stl->g_data->wire_shgrp = DRW_shgroup_create(e_data.wire_sh, psl->wire_pass);
stl->g_data->wire_shgrp = DRW_shgroup_create(sh_data->wire, psl->wire_pass);
psl->vert_pass = DRW_pass_create(
"Lattice Verts",
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_POINT);
stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.overlay_vert_sh, psl->vert_pass);
stl->g_data->vert_shgrp = DRW_shgroup_create(sh_data->overlay_vert, psl->vert_pass);
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);
}
}
}
@ -249,8 +285,16 @@ static void EDIT_LATTICE_draw_scene(void *vedata)
* Mostly used for freeing shaders */
static void EDIT_LATTICE_engine_free(void)
{
// Currently built-in, dont free
DRW_SHADER_FREE_SAFE(e_data.overlay_vert_sh);
for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
EDIT_LATTICE_Shaders *sh_data = &e_data.sh_data[sh_data_index];
/* Don't free builtins. */
sh_data->wire = NULL;
GPUShader **sh_data_as_array = (GPUShader **)sh_data;
for (int i = 0; i < (sizeof(EDIT_LATTICE_Shaders) / sizeof(GPUShader *)); i++) {
DRW_SHADER_FREE_SAFE(sh_data_as_array[i]);
}
}
}
static const DrawEngineDataSize EDIT_LATTICE_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_LATTICE_Data);

View File

@ -2,6 +2,7 @@
/* Draw Lattice Vertices */
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelMatrix;
uniform vec2 viewportSize;
in vec3 pos;
@ -36,4 +37,9 @@ void main()
gl_PointSize = sizeVertex;
gl_Position = pPos;
#ifdef USE_WORLD_CLIP_PLANES
world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
#endif
}