diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-08-22 19:44:24 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-08-22 20:49:32 +0300 |
commit | 890623f8865a87a9c1a1c78561acfea2a5e43eb1 (patch) | |
tree | f6a144ac3eeb74fe4cc1aed114472e1576f45a36 /source/blender/draw | |
parent | 477b4559ece0d12ec0bab88d317b9fe2e1832417 (diff) |
Object Mode: Add back spot cone display
Diffstat (limited to 'source/blender/draw')
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 81 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.c | 17 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_debug.c | 1 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 47 |
6 files changed, 145 insertions, 4 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 831c9ea33b9..412ad72207e 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -84,7 +84,9 @@ static struct DRWShapeCache { GPUBatch *drw_lamp_area_disk; GPUBatch *drw_lamp_hemi; GPUBatch *drw_lamp_spot; + GPUBatch *drw_lamp_spot_volume; GPUBatch *drw_lamp_spot_square; + GPUBatch *drw_lamp_spot_square_volume; GPUBatch *drw_speaker; GPUBatch *drw_lightprobe_cube; GPUBatch *drw_lightprobe_planar; @@ -1491,7 +1493,6 @@ GPUBatch *DRW_cache_lamp_spot_get(void) negate_v3_v3(neg[i], n[i]); } - /* Position Only 3D format */ static GPUVertFormat format = { 0 }; static struct { uint pos, n1, n2; } attr_id; if (format.attr_len == 0) { @@ -1539,6 +1540,51 @@ GPUBatch *DRW_cache_lamp_spot_get(void) #undef NSEGMENTS } +GPUBatch *DRW_cache_lamp_spot_volume_get(void) +{ +#define NSEGMENTS 32 + if (!SHC.drw_lamp_spot_volume) { + /* a single ring of vertices */ + float p[NSEGMENTS][2]; + for (int i = 0; i < NSEGMENTS; ++i) { + float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS); + p[i][0] = cosf(angle); + p[i][1] = sinf(angle); + } + + static GPUVertFormat format = { 0 }; + static struct { uint pos; } attr_id; + if (format.attr_len == 0) { + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, NSEGMENTS * 3); + + uint v_idx = 0; + for (int i = 0; i < NSEGMENTS; ++i) { + float cv[2], v[3]; + + ARRAY_SET_ITEMS(v, 0.0f, 0.0f, 0.0f); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); + + cv[0] = p[i % NSEGMENTS][0]; + cv[1] = p[i % NSEGMENTS][1]; + ARRAY_SET_ITEMS(v, cv[0], cv[1], -1.0f); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); + + cv[0] = p[(i + 1) % NSEGMENTS][0]; + cv[1] = p[(i + 1) % NSEGMENTS][1]; + ARRAY_SET_ITEMS(v, cv[0], cv[1], -1.0f); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v); + } + + SHC.drw_lamp_spot_volume = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); + } + return SHC.drw_lamp_spot_volume; +#undef NSEGMENTS +} + GPUBatch *DRW_cache_lamp_spot_square_get(void) { if (!SHC.drw_lamp_spot_square) { @@ -1574,6 +1620,39 @@ GPUBatch *DRW_cache_lamp_spot_square_get(void) return SHC.drw_lamp_spot_square; } +GPUBatch *DRW_cache_lamp_spot_square_volume_get(void) +{ + if (!SHC.drw_lamp_spot_square_volume) { + float p[5][3] = {{ 0.0f, 0.0f, 0.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}}; + + uint v_idx = 0; + + /* Position Only 3D format */ + static GPUVertFormat format = { 0 }; + static struct { uint pos; } attr_id; + if (format.attr_len == 0) { + attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, 12); + + /* piramid sides */ + for (int i = 1; i <= 4; ++i) { + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, p[0]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, p[((i + 1) % 4) + 1]); + GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, p[(i % 4) + 1]); + } + + SHC.drw_lamp_spot_square_volume = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO); + } + return SHC.drw_lamp_spot_square_volume; +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index f5f4527ca13..eb75c685ec0 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -91,7 +91,9 @@ struct GPUBatch *DRW_cache_lamp_area_square_get(void); struct GPUBatch *DRW_cache_lamp_area_disk_get(void); struct GPUBatch *DRW_cache_lamp_hemi_get(void); struct GPUBatch *DRW_cache_lamp_spot_get(void); +struct GPUBatch *DRW_cache_lamp_spot_volume_get(void); struct GPUBatch *DRW_cache_lamp_spot_square_get(void); +struct GPUBatch *DRW_cache_lamp_spot_square_volume_get(void); /* Camera */ struct GPUBatch *DRW_cache_camera_get(void); diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index bfcf5f2511d..30b1ebe07cd 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -396,6 +396,23 @@ DRWShadingGroup *shgroup_instance(DRWPass *pass, struct GPUBatch *geom) }); DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_sized); + DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f); + + return grp; +} + +DRWShadingGroup *shgroup_instance_alpha(DRWPass *pass, struct GPUBatch *geom, float alpha) +{ + GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE); + + DRW_shgroup_instance_format(g_formats.instance_sized, { + {"color", DRW_ATTRIB_FLOAT, 4}, + {"size", DRW_ATTRIB_FLOAT, 1}, + {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16} + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_sized); + DRW_shgroup_uniform_float_copy(grp, "alpha", alpha); return grp; } diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index 05c3da9f96c..bab6c67a081 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -120,6 +120,7 @@ struct DRWShadingGroup *shgroup_instance_empty_axes(struct DRWPass *pass, struct struct DRWShadingGroup *shgroup_instance_image_plane(struct DRWPass *pass, struct GPUBatch *geom); struct DRWShadingGroup *shgroup_instance_scaled(struct DRWPass *pass, struct GPUBatch *geom); struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct GPUBatch *geom); +struct DRWShadingGroup *shgroup_instance_alpha(struct DRWPass *pass, struct GPUBatch *geom, float alpha); struct DRWShadingGroup *shgroup_instance_outline(struct DRWPass *pass, struct GPUBatch *geom, int *baseid); struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct GPUBatch *geom); struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct GPUBatch *geom); diff --git a/source/blender/draw/intern/draw_debug.c b/source/blender/draw/intern/draw_debug.c index 8af13d66c28..c748b8fb0d8 100644 --- a/source/blender/draw/intern/draw_debug.c +++ b/source/blender/draw/intern/draw_debug.c @@ -208,6 +208,7 @@ static void drw_debug_draw_spheres(void) GPUBatch *draw_batch = GPU_batch_create(GPU_PRIM_LINES, empty_sphere->verts[0], NULL); GPU_batch_instbuf_set(draw_batch, inst_vbo, true); GPU_batch_program_set_builtin(draw_batch, GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE); + GPU_batch_uniform_1f(draw_batch, "alpha", 1.0f); GPU_batch_draw(draw_batch); GPU_batch_discard(draw_batch); diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index af85cc7bb00..934b9ada99f 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -106,6 +106,7 @@ extern char datatoc_gpu_shader_uniform_color_frag_glsl[]; /* *********** LISTS *********** */ typedef struct OBJECT_PassList { struct DRWPass *non_meshes[2]; + struct DRWPass *spot_shapes[2]; struct DRWPass *ob_center; struct DRWPass *outlines; struct DRWPass *outlines_search; @@ -146,6 +147,7 @@ typedef struct OBJECT_Data { typedef struct OBJECT_ShadingGroupList { /* Reference only */ struct DRWPass *non_meshes; + struct DRWPass *spot_shapes; struct DRWPass *bone_solid; struct DRWPass *bone_outline; struct DRWPass *bone_wire; @@ -209,6 +211,10 @@ typedef struct OBJECT_ShadingGroupList { DRWShadingGroup *lamp_spot_blend; DRWShadingGroup *lamp_spot_pyramid; DRWShadingGroup *lamp_spot_blend_rect; + DRWShadingGroup *lamp_spot_volume; + DRWShadingGroup *lamp_spot_volume_rect; + DRWShadingGroup *lamp_spot_volume_outside; + DRWShadingGroup *lamp_spot_volume_rect_outside; /* Helpers */ DRWShadingGroup *relationship_lines; @@ -1100,8 +1106,7 @@ static void OBJECT_cache_init(void *vedata) DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | - DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_POINT; - state |= DRW_STATE_WIRE; + DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_POINT | DRW_STATE_WIRE; sgl->non_meshes = psl->non_meshes[i] = DRW_pass_create("Non Meshes Pass", state); /* Empties */ @@ -1292,6 +1297,28 @@ static void OBJECT_cache_init(void *vedata) /* TODO port to shader stipple */ geom = DRW_cache_field_cone_limit_get(); sgl->field_cone_limit = shgroup_instance_scaled(sgl->non_meshes, geom); + + /* Spot shapes */ + state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_CULL_FRONT; + sgl->spot_shapes = psl->spot_shapes[i] = DRW_pass_create("Spot Shape Pass", state); + float cone_spot_alpha = 0.5f; + + geom = DRW_cache_lamp_spot_volume_get(); + sgl->lamp_spot_volume = shgroup_instance_alpha(sgl->spot_shapes, geom, cone_spot_alpha); + + geom = DRW_cache_lamp_spot_square_volume_get(); + sgl->lamp_spot_volume_rect = shgroup_instance_alpha(sgl->spot_shapes, geom, cone_spot_alpha); + + cone_spot_alpha = 0.3f; + geom = DRW_cache_lamp_spot_volume_get(); + sgl->lamp_spot_volume_outside = shgroup_instance_alpha(sgl->spot_shapes, geom, cone_spot_alpha); + DRW_shgroup_state_disable(sgl->lamp_spot_volume_outside, DRW_STATE_CULL_FRONT); + DRW_shgroup_state_enable(sgl->lamp_spot_volume_outside, DRW_STATE_CULL_BACK); + + geom = DRW_cache_lamp_spot_square_volume_get(); + sgl->lamp_spot_volume_rect_outside = shgroup_instance_alpha(sgl->spot_shapes, geom, cone_spot_alpha); + DRW_shgroup_state_disable(sgl->lamp_spot_volume_rect_outside, DRW_STATE_CULL_FRONT); + DRW_shgroup_state_enable(sgl->lamp_spot_volume_rect_outside, DRW_STATE_CULL_BACK); } { @@ -1429,8 +1456,9 @@ static void DRW_shgroup_lamp(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLayer else if (la->type == LA_SPOT) { float size[3], sizemat[4][4]; static float one = 1.0f; + float cone_inside[3] = {0.0f, 0.0f, 0.0f}; + float cone_outside[3] = {1.0f, 1.0f, 1.0f}; float blend = 1.0f - pow2f(la->spotblend); - size[0] = size[1] = sinf(la->spotsize * 0.5f) * la->dist; size[2] = cosf(la->spotsize * 0.5f) * la->dist; @@ -1452,6 +1480,12 @@ static void DRW_shgroup_lamp(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLayer if (blend != 0.0f && blend != 1.0f) { DRW_shgroup_call_dynamic_add(sgl->lamp_spot_blend_rect, color, &one, spotblendmat); } + + if (la->mode & LA_SHOW_CONE) { + + DRW_shgroup_call_dynamic_add(sgl->lamp_spot_volume_rect, cone_inside, &one, shapemat); + DRW_shgroup_call_dynamic_add(sgl->lamp_spot_volume_rect_outside, cone_outside, &one, shapemat); + } } else { DRW_shgroup_call_dynamic_add(sgl->lamp_spot_cone, color, shapemat); @@ -1462,6 +1496,11 @@ static void DRW_shgroup_lamp(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLayer if (blend != 0.0f && blend != 1.0f) { DRW_shgroup_call_dynamic_add(sgl->lamp_spot_blend, color, &one, spotblendmat); } + + if (la->mode & LA_SHOW_CONE) { + DRW_shgroup_call_dynamic_add(sgl->lamp_spot_volume, cone_inside, &one, shapemat); + DRW_shgroup_call_dynamic_add(sgl->lamp_spot_volume_outside, cone_outside, &one, shapemat); + } } DRW_shgroup_call_dynamic_add(sgl->lamp_buflimit, color, &la->clipsta, &la->clipend, ob->obmat); @@ -2836,6 +2875,7 @@ static void OBJECT_draw_scene(void *vedata) MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl); /* This needs to be drawn after the oultine */ + DRW_draw_pass(stl->g_data->sgl.spot_shapes); DRW_draw_pass(stl->g_data->sgl.bone_solid); DRW_draw_pass(stl->g_data->sgl.bone_wire); DRW_draw_pass(stl->g_data->sgl.bone_outline); @@ -2927,6 +2967,7 @@ static void OBJECT_draw_scene(void *vedata) GPU_framebuffer_clear_depth(fbl->ghost_fb, 1.0f); } + DRW_draw_pass(stl->g_data->sgl_ghost.spot_shapes); DRW_draw_pass(stl->g_data->sgl_ghost.bone_solid); DRW_draw_pass(stl->g_data->sgl_ghost.bone_wire); DRW_draw_pass(stl->g_data->sgl_ghost.bone_outline); |