DrwManager: Add support for Custom Clipping Planes

This commit is contained in:
Clément Foucault
2017-06-16 14:23:30 +02:00
parent 9a040fa3d4
commit 9a5cb2e6f8
2 changed files with 47 additions and 0 deletions

View File

@@ -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);

View File

@@ -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;
}
/** \} */