diff options
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 5 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 42 |
2 files changed, 47 insertions, 0 deletions
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index e49a6ab7926..3ea46531379 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -249,6 +249,7 @@ typedef enum { DRW_STATE_BLEND = (1 << 13), DRW_STATE_ADDITIVE = (1 << 14), DRW_STATE_MULTIPLY = (1 << 15), + DRW_STATE_CLIP_PLANES = (1 << 16), DRW_STATE_WRITE_STENCIL_SELECT = (1 << 27), DRW_STATE_WRITE_STENCIL_ACTIVE = (1 << 28), @@ -363,8 +364,12 @@ void DRW_draw_region_engine_info(void); void DRW_state_reset_ex(DRWState state); void DRW_state_reset(void); + void DRW_state_invert_facing(void); +void DRW_state_clip_planes_add(float plane_eq[4]); +void DRW_state_clip_planes_reset(void); + /* Selection */ void DRW_select_load_id(unsigned int id); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 90a3aaa84d5..d44cc14c1ba 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -95,6 +95,7 @@ #define MAX_ATTRIB_NAME 32 #define MAX_PASS_NAME 32 +#define MAX_CLIP_PLANES 6 /* GL_MAX_CLIP_PLANES is at least 6 */ /* Use draw manager to call GPU_select, see: DRW_draw_select_loop */ #define USE_GPU_SELECT @@ -174,6 +175,7 @@ struct DRWInterface { int camtexfac; int orcotexfac; int eye; + int clipplanes; /* Textures */ int tex_bind; /* next texture binding point */ /* UBO */ @@ -292,6 +294,10 @@ static struct DRWGlobalState { GLenum backface, frontface; + /* Clip planes */ + int num_clip_planes; + float clip_planes_eq[MAX_CLIP_PLANES][4]; + struct { unsigned int is_select : 1; unsigned int is_depth : 1; @@ -585,6 +591,7 @@ static DRWInterface *DRW_interface_create(GPUShader *shader) interface->camtexfac = GPU_shader_get_uniform(shader, "CameraTexCoFactors"); interface->orcotexfac = GPU_shader_get_uniform(shader, "OrcoTexCoFactors[0]"); interface->eye = GPU_shader_get_uniform(shader, "eye"); + interface->clipplanes = GPU_shader_get_uniform(shader, "ClipPlanes[0]"); interface->instance_count = 0; interface->attribs_count = 0; interface->attribs_stride = 0; @@ -1412,6 +1419,23 @@ static void DRW_state_set(DRWState state) } } + /* Clip Planes */ + { + int test; + if ((test = CHANGED_TO(DRW_STATE_CLIP_PLANES))) { + if (test == 1) { + for (int i = 0; i < DST.num_clip_planes; ++i) { + glEnable(GL_CLIP_DISTANCE0 + i); + } + } + else { + for (int i = 0; i < MAX_CLIP_PLANES; ++i) { + glDisable(GL_CLIP_DISTANCE0 + i); + } + } + } + } + /* Line Stipple */ { int test; @@ -1632,6 +1656,9 @@ static void draw_geometry_prepare( if (interface->eye != -1) { GPU_shader_uniform_vector(shgroup->shader, interface->eye, 3, 1, (float *)eye); } + if (interface->clipplanes != -1) { + GPU_shader_uniform_vector(shgroup->shader, interface->clipplanes, 4, DST.num_clip_planes, (float *)DST.clip_planes_eq); + } } static void draw_geometry_execute(DRWShadingGroup *shgroup, Batch *geom) @@ -1910,6 +1937,21 @@ void DRW_state_invert_facing(void) glFrontFace(DST.frontface); } +/** + * This only works if DRWPasses have been tagged with DRW_STATE_CLIP_PLANES, + * and if the shaders have support for it (see usage of gl_ClipDistance). + * Be sure to call DRW_state_clip_planes_reset() after you finish drawing. + **/ +void DRW_state_clip_planes_add(float plane_eq[4]) +{ + copy_v4_v4(DST.clip_planes_eq[DST.num_clip_planes++], plane_eq); +} + +void DRW_state_clip_planes_reset(void) +{ + DST.num_clip_planes = 0; +} + /** \} */ |